# @afyadigital/rx-engine 中文文档

规范地址：https://npmcn.com/package/%40afyadigital/rx-engine/

版本：4\.9\.0
npm 元数据更新时间：2026-10-19T19:42:11.129Z
中文译文更新时间：2026-11-06T20:01:43.605Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40afyadigital/rx-engine
原文对照：https://npmcn.com/package/%40afyadigital/rx-engine/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：55.1 kB，53 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：3 个
- 首次发布：2021-06-22T02:36:04.383Z
- 最新版本发布：2026-10-19T19:42:10.911Z
- 近 30 天下载量：2406（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：51（近 12 个月 5 个）

## 中文简介

Afya 数字处方引擎

## 安装

```sh
npm install @afyadigital/rx-engine
```

也可以使用：`pnpm add @afyadigital/rx-engine`、`yarn add @afyadigital/rx-engine`、`bun add @afyadigital/rx-engine`

## README

# Afya 数字: 处方引擎

消费图书馆 **Afya 数字处方引擎** - 前端整合

上一版本状态 :

| 版本 | 状态 |
| --- | --- |
| `1.x` | _已贬值_ |
| `2.x` | _已贬值_ |
| `3.x` | _已贬值_ |

## 安装

```bash
# npm
npm install @afyadigital/rx-engine --save

# yarn
yarn add @afyadigital/rx-engine

#pnpm
pnpm add @afyadigital/rx-engine
```

## API 密码

### `render`

渲染 RX 引擎 App, 给定配置对象

#### `EngineConfiguration` 对象

| 财产 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `target` | `string` | \- 说吧 | 用于渲染应用程序的目标元素选择器 |
| `auth` | 对象 `{ token }` | \- 说吧 | 认证信息对象 |
| `auth.token` | `string` | \- 说吧 | 物理符号(\*) |
| `initialValue` | 对象 `{ appointment, patient, medications }` | \- 说吧 | 应用程序初始化时使用的信息 |
| `initialValue.appointment` | 对象 `{ id }` | \- 说吧 | 指定信息对象 |
| `initialValue.appointment.id` | `string` | \- 说吧 | 在主机应用程序上指定 id |
| `initialValue.patient` | 对象 `{ id, name, address }` | \- 说吧 | 病人信息对象( 可选) |
| `initialValue.patient.id` | `string` | \- 说吧 | 主机应用程序上的患者 ID |
| `initialValue.patient.name` | `string` | \- 说吧 | 主机应用程序上的病人名 |
| `initialValue.patient.civilName` | `string` | \- 说吧 | 主机申请上的病人民事姓名 |
| `initialValue.patient.address` | `string` | \- 说吧 | 病人在主机应用程序上的完整地址(可选),免费文本. 衍生自 `serviceAddress` 省略时 |
| `initialValue.patient.serviceAddress` | 对象 `{ address, number, neighborhood, city, state, zipCode, complement }` | \- 说吧 | 患者结构地址(可选)\*\* |
| `initialValue.patient.serviceAddress.address` | `string` | \- 说吧 | 街道名称,最多512个字符 |
| `initialValue.patient.serviceAddress.number` | `string` | \- 说吧 | 街道号码,最多20个字符 |
| `initialValue.patient.serviceAddress.neighborhood` | `string` | \- 说吧 | 邻居,最多100个字符 |
| `initialValue.patient.serviceAddress.city` | `string` | \- 说吧 | 城市,最多64个字符 |
| `initialValue.patient.serviceAddress.state` | `string` | \- 说吧 | 状态,一个有效的UF(两个字母)——外壳已正常化 |
| `initialValue.patient.serviceAddress.zipCode` | `string` | \- 说吧 | Zip 代码 (CEP), 八位数字 — 面具被自动取出 |
| `initialValue.patient.serviceAddress.complement` | `string` | \- 说吧 | 地址补充(可选),最多100个字符 |
| `initialValue.patient.phone` | `string` | \- 说吧 | 病人在主机应用程序上的电话(可选),长度为11位数 |
| `initialValue.patient.email` | `string` | \- 说吧 | 主机应用程序上的病人电子邮件( 可选) |
| `initialValue.patient.cpf` | `string` | \- 说吧 | 主机应用程序上的病人 cpf( 可选) |
| `initialValue.patient.height` | `string` | \- 说吧 | 主机应用时病人身高(可选),以厘米计(厘米) |
| `initialValue.patient.weight` | `string` | \- 说吧 | 病人对主机应用的重量(可选),单位:公斤(公斤) |
| `initialValue.patient.motherName` | `string` | \- 说吧 | 主机申请时的病人母亲姓名( 可选) |
| `initialValue.patient.birthdate` | `string` | \- 说吧 | 患者出生日期(可选择),ISO 8601日历日 `YYYY-MM-DD` (例如:. `1990-05-20`(\*\*\*) 国家 |
| `initialValue.patient.sex` | `'M' | 'F'` | \- 说吧 | 患者生理性(可选择性), `M` 为男性和 `F` 妇女(\*\*\*) |
| `initialValue.medications` | 对象矩阵 `[{ type, title, patientInstruction, printType }]` | \- 说吧 | 药品信息对象 |
| `initialValue.medications[<index>].type` | `string` | \- 说吧 | 药物类型(例如:产品、物质或免费Text) |
| `initialValue.medications[<index>].id` | `string` | \- 说吧 | 外部伙伴发送的药品代号( 如果类型是免费的, 可选择) |
| `initialValue.medications[<index>].title` | `string` | \- 说吧 | 外部合作伙伴发送的药品名称 |
| `initialValue.medications[<index>].patientInstruction` | `string` | \- 说吧 | 外部伙伴发给病人的药品说明书 |
| `initialValue.medications[<index>].printType` | `string` | \- 说吧 | 伴侣提供的药物处方类型(例如:简单、特殊和抗微生物) |
| `initialValue.medications[<index>].quantity` | `string` | \- 说吧 | 外部(可选)伙伴发送的药品数量 |
| `initialValue.medications[<index>].unit` | `string` | \- 说吧 | 外部(可选)伙伴发送的药品数量单位 |
| `initialValue.medications[<index>].subtitle` | `string` | \- 说吧 | 外部合作伙伴发送的药材字幕(如果类型是产品就需要) |
| `initialValue.medications[<index>].description` | `string` | \- 说吧 | 外部伙伴发送的药物说明(如果类型是产品就需要) |
| `initialValue.medications[<index>].laboratoryName` | `string` | \- 说吧 | 外部伙伴发送的药物实验室(如果类型是产品,就需要) |
| `initialValue.medications[<index>].category` | `string` | \- 说吧 | 外部伙伴发送的药物类别(如果类型是产品就需要) |
| `initialValue.medications[<index>].maxPrice` | `string` | \- 说吧 | 外部伙伴发出的最大药价(如果类型是产品就需要) |
| `initialValue.medications[<index>].available` | `string` | \- 说吧 | 伙伴发送的药品供应量(如果类型是产品,则需要) |

> \* 拿到医生的认证信 [通过我们的活体](https://api.dev.afya-digital.com/docs/index.html#/partner/post_partner_orgs_physicians_login)

> 页:1 `serviceAddress` 要求发布受管制的处方(`special`, (中文(简体) ), `antimicrobial` 和RDC 1.000/2025所述内容。 每一个领域,但是 `complement` 强制:不完整 `serviceAddress` 医生必须在引擎上填写地址。 何时 `address` 不发送,它是从 `serviceAddress`。 。 。 .

> 页:1 `sex` 财务报告和审定财务报表 `birthdate` 为: **没有** 由 lib 翻译 : 它只会验证它们,并按发送的方式转发它们. 不发送 `male`编号 :`female` 或小写 `m`编号 :`f` ——一个无效值被以警告而忽略,医生在引擎上填写.

示例

```ts
/** Create a configuration to render the Prescription Engine */

// AppEnvOptions = 'production' | 'development'

const appEnv = "development";

const config: EngineConfig = {
  // target element selector. example: <div id="rx-engine"></div>
  target: `#rx-engine`,
  // physician authentication token
  auth: { token: 'jwt-token' },
  initialValue: {
    appointment: {
      id: '123'
    }
    // patient identification and name to create a prescription with
    patient: {
      id: '123',
      name: 'Jhon Doe',
      civilName: 'Jhonnie',
      address: 'Foo Bar',
      serviceAddress: {
        address: 'Praça da Sé',
        number: '100',
        neighborhood: 'Sé',
        city: 'São Paulo',
        state: 'SP',
        zipCode: '01001000',
        complement: 'Apto 42'
      },
      phone: '45999999999',
      email: 'patient@email.com',
      cpf: '682.733.635-20',
      height: "179",
      weight: "90",
      motherName: 'Jhoana Doe',
      birthdate: '1990-05-20',
      sex: 'F'
    },
    // medications that could be imported from an external partner
    medications: [
      {
        type: 'freeText',
        title: 'Test Med',
        patientInstruction: '1 pill every morning for 10 days';
        printType: 'simple';
      }
    ]
  },
}

/** Render it on your target element */

render(config, env)
```

#### `Patient` 对象

病人送来了 `initialValue.patient`数字 :

```ts
type Patient = {
  id: string;
  name: string;
  cpf?: string;
  civilName?: string;
  motherName?: string;
  address?: string;
  serviceAddress?: ServiceAddress;
  email?: string;
  phone?: string;
  weight?: string;
  height?: string;
  /** ISO 8601 calendar day, `YYYY-MM-DD` (e.g. `1990-05-20`) */
  birthdate?: string;
  /** Closed dictionary: `M` for male, `F` for female */
  sex?: 'M' | 'F';
};
```

### `unmount`

清理先前挂载的应用程序和收听器

```ts
unmount();
```

### `events`

API 这样你就可以从处方应用程序注册到事件. 确保 `render` 该应用程序在订阅事件之前.

| 名称 | 说明 | 有效载数 |
| --- | --- | --- |
| `'app:init'` | 应用程序初始化 | _无效_ |
| `'app:revokedToken'` | 医生证书过期/无效时 | _无效_ |
| `'prescription:saved'` | 当用户保存处方时 | _`SavedPrescriptionEventPayload`_ |
| `'prescription:itemAdded'` | 当用户在处方中添加其他项目时 | _`PrescriptionItemEventPayload`_ |
| `'printConfig:saved'` | 当用户保存打印配置 | _`SavedPrintConfigEventPayload`_ |

```ts
type FreeTextItem = {
  title: string;
  patientInstruction: string;
  quantity: number;
  unit: string;
};

type MedicationItem = FreeTextItem & {
  id: string;
};

type PrescriptionItemEventPayload = {
  type: 'product' | 'substance' | 'freeText';
  origin: 'user' | 'integration';
  data: FreeTextItem | MedicationItem;
};
```

示例

```tsx
import { events } from '@afyadigital/rx-engine'

const doSomething = (prescriptionItem) => { ... }

// register a callback function to an event
events.listen('prescription:itemAdded', doSomething)

// remove an event listener
events.remove('prescription:itemAdded', doSomething)

// remove all listeners
events.cleanup()
```

```ts
type ServiceAddress = {
  address: string;
  number: string;
  neighborhood: string;
  city: string;
  state: string;
  zipCode: string;
  complement?: string;
};

type Patient = {
  name: string;
  externalId: string;
  address?: string;
  serviceAddress?: ServiceAddress;
  phone?: string;
  email?: string;
  cpf?: string;
  height?: string;
  weight?: string;
  motherName?: string;
};

type UserInput = {
  patientInstruction: string;
  quantity?: number;
  unit?: string;
  printType: PrintTypeEnum; // simple | special | antimicrobial
};

type FreeText = {
  type: 'freeText';
  title: string;
} & UserInput;

type Product = {
  type: 'product';
  id: string;
  title: string;
  subtitle: string;
  description: string;
  laboratoryName: string;
  category: string;
  maxPrice: string;
  available: boolean;
} & UserInput;

type Substance = {
  type: 'substance';
  id: string;
  title: string;
} & UserInput;

type PrescriptionItem = FreeText | Product | Substance;

export type Exam = {
  id: string;
  code: string;
  term: string;
};

export type PrescritableExam = {
  quantity: number;
  type: string;
  exam: Exam;
};

export type ExamPage = {
  items: PrescritableExam[];
  clinicalIndication?: string;
};

export type VaccineBase = {
  title: string;
  patientInstruction: string;
  quantity: number;
};

export type VaccineProduct = {
  id: string;
  type: 'product';
} & VaccineBase;

export type VaccineFreeText = {
  type: 'freeText';
} & VaccineBase;

export type Vaccine = VaccineProduct | VaccineFreeText;

export type VaccinePage = {
  items: Vaccine[];
};

export type Lme = {
  patient: {
    fullName: string;
    height: string;
    isCapable: boolean;
    mothersName: string;
    weight: string;
    responsibleName?: string;
    filledBy: {
      responsible:
        | 'patient'
        | 'patientMother'
        | 'responsible'
        | 'physician'
        | 'other';
      name?: string;
      cpf?: string;
    };
    skinColor: 'branca' | 'preta' | 'parda' | 'amarela' | 'indigena';
    ethnicity?: string;
    document: {
      type: 'cpf' | 'cns';
      value: string;
    };
    email: string;
    phone: string;
  };
  org: {
    cnes: string;
    name: string;
  };
  physician: {
    name: string;
    cns: string;
  };
  treatments: LmeTreatment[];
};

export type LmeTreatment = {
  id: string;
  cid10: string;
  diagnostic: string;
  solicitationDate: string;
  anamnese: string;
  exams: {
    id: string;
    term: string;
    code: string;
    type: string;
    quantity: number;
  }[];
  medications: {
    months: string[];
    name: string;
    id: string;
    type: string;
  }[];

  onTreatment: boolean;
  treatmentReport?: string;

  pdfUrl: string; // LME prescription pdf
  examUrl?: string; // prescription pdf for all exams
  protocols?: string[]; // terms prescriptions
  prescriptions?: {
    // LME medications prescriptions
    simple: LmeMedicationPrescription;
    special: LmeMedicationPrescription[];
    antimicrobial: LmeMedicationPrescription[];
  };
};

export type LmeMedicationPrescription = {
  id: string;
  pdfUrl: string;
  prescriptionDate: string;
  quantity: number;
  medications: string[];
};

export type SavedPrescriptionEventPayload = {
  id: string;
  patient: Patient;
  issuedAt?: string;
  items: PrescriptionItem[];
  exams: ExamPage[];
  vaccines: VaccinePage[];
  pdfUrl?: string;
  lme?: Lme;
};
```

### `commands`

引擎应用初始化后( 请检查 `'app:init'` 您可以在引擎上发送事件.

#### `addPrescriptionItem(item: PrescriptionItem)` :在处方中添加项目.

```ts
type ItemFreeText = {
  title: string;
  type: 'freeText';
  patientInstruction: string;
  quantity: number;
  unit: string;
};

type ItemMedication = {
  id: string;
  type: 'product' | 'substance';
  patientInstruction: string;
  quantity: number;
  unit: string;
};

export type PrescriptionItem = ItemFreeText | ItemMedication;
```

用法示例:

```tsx
import { commands, events } from '@afyadigital/rx-engine';

const onInit = async () => {
  await commands.addPrescriptionItem({
    title: 'Paracetamol',
    type: 'freeText',
    patientInstruction: 'tomar 2x ao dia com intervalo de 4 horas',
    quantity: 2,
    unit: 'comprimidos',
  });
};

events.listen('app:init', onInit);
```

#### `savePrescriptionItem(item: SaveItemMedication)` : 在处方中添加项目或保存以添加到下个处方 .

```ts
export type SaveItemMedication = {
  id: string;
  type: 'product' | 'substance';
  patientInstruction: string;
  quantity: number;
  highlight: {
    title: string;
    subtitle?: string;
  };
  unit: {
    singular: string;
    plural: string;
  };
  title: string;
  subtitle: string;
  description: string;
  laboratoryName: string;
  category: string;
  maxPrice: string;
  available: string | boolean;
  listType: string;
  prescriptionType: string;
  ean1: string;
};
```

用法示例:

```tsx
import { commands, events } from '@afyadigital/rx-engine';

const onInit = async () => {
  commands.savePrescriptionItem({
    id: '11a111bc-de12-461b-b0fe-62e7a8f83cb0',
    highlight: {
      title: '<mark>Neosaldina</mark>',
    },
    unit: {
      singular: 'comprimido',
      plural: 'comprimidos',
    },
    type: 'product',
    title: 'Neosaldina',
    subtitle: 'Comprimido revestido • 60 un',
    description:
      'Dipirona 300 mg + Mucato de Isometepteno 30 mg + Cafeína 30 mg',
    laboratoryName: 'Takeda',
    category: 'Referência',
    maxPrice: '60,03',
    available: true,
    listType: '',
    prescriptionType: '',
    ean1: '7896641810985',
    patientInstruction: '',
    quantity: 0,
  });
};

events.listen('app:init', onInit);
```

#### `updateToken(token: string)` : 更新医生代号

用法示例:

```ts
import { commands, events } from '@afyadigital/rx-engine';

events.listen('revokedToken', async () => {
  const token = await getPhysicianToken(); // check physician login below*

  await commands.updateToken(token);
});
```

\* 联合国[医生登录](https://api.dev.afya-digital.com/docs/index.html#/partner/post_partner_orgs_physicians_login)

#### `updateFullScreen(isFullScreen: boolean)` : 更新引擎全屏状态

用法示例:

```ts
import { commands } from '@afyadigital/rx-engine';

await commands.updateFullScreen(true);
```

#### `searchPrescriptionItem(term: string)` :按术语搜索处方项目.

用法示例:

```ts
import { commands } from '@afyadigital/rx-engine';

await commands.searchPrescriptionItem('aspirina');
```

### `trackUserActivity(click: TrackUserActivityEvent)`: 来自用户源的触发事件

```ts
enum TrackActivityClickEnum {
  MenuPep = 'menuPep',
}

type TrackUserActivityEvent = {
  click: TrackActivityClickEnum;
};
```

用法示例:

```tsx
import { commands } from '@afyadigital/rx-engine'

const handleClick = () => {
  commands.trackUserActivity({ click: TrackActivityClickEnum.MenuPep })
}

return (
  <MenuItem>
    <Button onClick={handleClick}>Prescrição</Button>
  </MenuItem>
)
```

## 重复模拟示例

```jsx
import { useEffect } from 'react'
import { render, unmount } from '@afyadigital/rx-engine'
import type { EngineConfig } from '@afyadigital/rx-engine'

const TARGET_ID = 'rx-engine-container'

function AfyaPrescription() {
  useEffect(() => {
    const config: EngineConfig = {
      target: `#${TARGET_ID}`,
      auth: { token: 'physician-auth-token' },
      initialValue: {
        patient: {
          id: '123',
          name: 'Jhon Doe',
          civilName: 'Jonnie',
          address: 'Foo Bar',
          serviceAddress: {
            address: 'Praça da Sé',
            number: '100',
            neighborhood: 'Sé',
            city: 'São Paulo',
            state: 'SP',
            zipCode: '01001000',
          },
          phone: '45999999999',
          email: 'patient@email.com',
          cpf: '682.733.635-20',
          height: '179',
          weight: '90',
          motherName: 'Jhoana Doe',
          birthdate: '1990-05-20',
          sex: 'F',
        },
      },
    }

    render(config)

    return () => unmount()
  }, [])

  return <div id={TARGET_ID} />
}
```

## 常见问题

### @afyadigital/rx-engine 是什么？

Afya 数字处方引擎

### 如何安装 @afyadigital/rx-engine？

在项目目录运行 npm install @afyadigital/rx-engine，或使用 pnpm add / yarn add / bun add。

### @afyadigital/rx-engine 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @afyadigital/rx-engine 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @afyadigital/rx-engine 可以商用吗？

@afyadigital/rx-engine 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @afyadigital/rx-engine 的下载量有多少？

根据 npm 官方下载统计，@afyadigital/rx-engine 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,406 次，日均约 80 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @afyadigital/rx-engine 还在维护吗？

最新版本 4\.9\.0 发布于 2026/10/20（19 天前）；至今共发布 51 个版本，其中过去 12 个月发布了 5 个；首次发布于 2021/06/22。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

