page-flow-test.component.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. import { Component } from '@angular/core';
  2. import { ModalController } from '@ionic/angular/standalone';
  3. import { IonicModule } from '@ionic/angular';
  4. import { FlowExecutor } from '../lib/flow.executor';
  5. import { MockProgressTask, MockRetryTask, MockSuccessTask } from './mock-tasks/mock-tasks';
  6. import { FlowDisplayComponent } from '../lib/flow-display/flow-display.component';
  7. import { TriageResultComponent } from './consult-tasks/triage-result/triage-result.component';
  8. import { TriageTask } from './consult-tasks/consult-tasks';
  9. import { SymptomInputModalComponent } from './consult-tasks/symptom-input/symptom-input.modal';
  10. import { getUserForm } from '../lib/tasks/task-user-form/get-user-form';
  11. import { JobIntentionTask, UserBasicInfoTask, UserInterestsTask } from './job-workflow/task.job';
  12. import { TaskUserForm } from '../lib/tasks/task-user-form/task-user-form';
  13. import { TaskCompletionJson } from '../lib/tasks/task-completion-json/task-completion-json';
  14. import { TaskCompletionText } from '../lib/tasks/task-completion-text/task-completion-text';
  15. @Component({
  16. selector: 'app-page-flow-test',
  17. templateUrl: './page-flow-test.component.html',
  18. styleUrls: ['./page-flow-test.component.scss'],
  19. imports: [
  20. IonicModule,
  21. FlowDisplayComponent,
  22. TriageResultComponent,
  23. SymptomInputModalComponent
  24. ],
  25. standalone: true,
  26. })
  27. export class PageFlowTestComponent {
  28. private executor = new FlowExecutor(3, true);
  29. constructor(
  30. private modalCtrl: ModalController
  31. ) {
  32. }
  33. async getForm() {
  34. const fieldList = [
  35. { type: "String", key: "name", name: "姓名", required: true },
  36. { type: "String", key: "mobile", name: "手机", required: true },
  37. {
  38. type: "Radio", key: "gender", name: "性别", required: false, options: [
  39. { label: "男", value: "male" },
  40. { label: "女", value: "female" }
  41. ]
  42. }
  43. ];
  44. try {
  45. const result = await getUserForm({ modalCtrl: this.modalCtrl, fieldList });
  46. console.log('Collected data:', result);
  47. return result;
  48. } catch (error) {
  49. console.error('Form error:', error);
  50. return null;
  51. }
  52. }
  53. async consultWorkflow() {
  54. const tasks = [
  55. // 描述病情任务(用户信息采集)
  56. new TaskUserForm({
  57. title: '病情描述',
  58. modalCtrl: this.modalCtrl,
  59. fieldList: [
  60. {
  61. type: "String",
  62. key: "userDesc",
  63. name: "病情描述",
  64. required: true,
  65. placeholder: "请详细描述您的症状、持续时间和不适感"
  66. },
  67. {
  68. type: "String",
  69. key: "duration",
  70. name: "持续时间",
  71. required: false,
  72. placeholder: "例如:3天、2周等"
  73. },
  74. {
  75. type: "Radio",
  76. key: "painLevel",
  77. name: "疼痛程度",
  78. required: false,
  79. options: [
  80. { label: "无疼痛", value: "none" },
  81. { label: "轻度", value: "mild" },
  82. { label: "中度", value: "moderate" },
  83. { label: "重度", value: "severe" }
  84. ]
  85. }
  86. ],
  87. initialData: {}
  88. }),
  89. // 智能分诊任务(AI分析)
  90. new TaskCompletionJson({
  91. title: '智能分诊',
  92. promptTemplate: `您是一名专业的分诊护士,根据患者描述推荐最合适的科室。严格按照以下JSON格式返回:
  93. {
  94. "department": "科室名称",
  95. "reason": "分诊理由(50字以内)"
  96. }
  97. 患者主诉:{{userDesc}}
  98. 持续时间:{{duration}}
  99. 疼痛程度:{{painLevel}}`,
  100. input: [
  101. { name: 'userDesc', type: 'string', required: true },
  102. { name: 'duration', type: 'string', required: false },
  103. { name: 'painLevel', type: 'string', required: false }
  104. ],
  105. output: [
  106. { name: 'department', type: 'string', required: true },
  107. { name: 'reason', type: 'string' }
  108. ]
  109. }),
  110. // 2. 问诊信息收集
  111. new TaskUserForm({
  112. title: '详细问诊',
  113. modalCtrl: this.modalCtrl,
  114. fieldList: [
  115. {
  116. type: "TextArea", key: "symptoms", name: "详细症状", required: true,
  117. placeholder: "请详细描述您的症状、部位、性质和变化情况"
  118. },
  119. { type: "String", key: "medicalHistory", name: "既往病史", required: false },
  120. { type: "String", key: "allergies", name: "过敏史", required: false },
  121. { type: "String", key: "medications", name: "当前用药", required: false },
  122. {
  123. type: "Radio", key: "needTests", name: "是否需要检查", required: true,
  124. options: [
  125. { label: "需要", value: true },
  126. { label: "不需要", value: false }
  127. ]
  128. }
  129. ],
  130. initialData: {}
  131. }),
  132. // 3. 检查建议生成(条件性任务)
  133. new TaskCompletionText({
  134. title: '检查建议',
  135. promptTemplate: `作为专业医生,根据以下问诊信息为患者推荐适当的检查项目:
  136. 症状描述:{{symptoms}}
  137. 既往病史:{{medicalHistory || '无'}}
  138. 过敏史:{{allergies || '无'}}
  139. 当前用药:{{medications || '无'}}
  140. 请列出建议的检查项目,说明每项检查的目的,并用通俗语言解释检查过程。`,
  141. outputProperty: "testRecommendations",
  142. inputVariables: ["symptoms", "medicalHistory", "allergies", "medications"],
  143. modelOptions: {
  144. temperature: 0.3,
  145. maxTokens: 300
  146. }
  147. }),
  148. new TaskUserForm({
  149. title: '检查结果录入',
  150. modalCtrl: this.modalCtrl,
  151. fieldList: [
  152. {
  153. type: "TextArea",
  154. key: "testResults",
  155. name: "检查结果",
  156. required: true,
  157. placeholder: "请粘贴或输入您的检查报告结果(包括各项指标和参考值)"
  158. },
  159. {
  160. type: "DatePicker",
  161. key: "testDate",
  162. name: "检查日期",
  163. required: true,
  164. default: new Date()
  165. }
  166. ]
  167. }),
  168. // 4. 诊断与处方生成
  169. new TaskCompletionJson({
  170. title: '诊断与处方',
  171. promptTemplate: `作为主治医生,请根据以下信息给出诊断结果和治疗方案:
  172. ## 患者信息
  173. 主诉:{{userDesc}}
  174. 详细症状:{{symptoms}}
  175. {{#if medicalHistory}}既往病史:{{medicalHistory}}{{/if}}
  176. {{#if allergies}}过敏史:{{allergies}}{{/if}}
  177. {{#if medications}}当前用药:{{medications}}{{/if}}
  178. ## 检查信息
  179. 检查日期:{{testDate}}
  180. 检查结果:{{testResults}}
  181. 请按照以下JSON格式返回...`, // 保持原有JSON格式要求
  182. input: [
  183. { name: 'userDesc', type: 'string', required: true },
  184. { name: 'symptoms', type: 'string', required: true },
  185. { name: 'medicalHistory', type: 'string', required: false },
  186. { name: 'allergies', type: 'string', required: false },
  187. { name: 'medications', type: 'string', required: false },
  188. { name: 'testResults', type: 'string', required: false }
  189. ],
  190. output: [
  191. { name: 'diagnosis', type: 'string', required: true },
  192. { name: 'treatmentPlan', type: 'string', required: true },
  193. { name: 'medications', type: 'array', required: false },
  194. { name: 'followUp', type: 'string', required: false },
  195. { name: 'notes', type: 'string', required: false }
  196. ],
  197. modelOptions: {
  198. temperature: 0.1, // 低随机性确保医疗准确性
  199. maxTokens: 500
  200. }
  201. }),
  202. // 5. 患者教育材料生成(可选任务)
  203. new TaskCompletionText({
  204. title: '患者教育',
  205. promptTemplate: `根据以下诊断和治疗方案,生成患者友好的教育材料:
  206. 诊断:{{diagnosis}}
  207. 治疗方案:{{treatmentPlan}}
  208. 用药指导:{{#each medications}}- {{this.name}}: {{this.dosage}}, 用药{{this.duration}}{{/each}}
  209. 请用通俗易懂的语言解释:
  210. 1. 疾病的基本知识
  211. 2. 为什么需要这个治疗方案
  212. 3. 用药注意事项
  213. 4. 日常生活建议
  214. 5. 何时需要紧急就医`,
  215. outputProperty: "patientEducation",
  216. inputVariables: ["diagnosis", "treatmentPlan", "medications"],
  217. modelOptions: {
  218. temperature: 0.5, // 中等随机性使语言更自然
  219. maxTokens: 600
  220. }
  221. })
  222. ];
  223. // 创建工作流
  224. const workflow = {
  225. title: '门诊问诊工作流',
  226. desc: '1.导诊',
  227. taskList: tasks
  228. };
  229. this.executor.setWorkflow(workflow);
  230. const modal = await this.modalCtrl.create({
  231. component: FlowDisplayComponent,
  232. componentProps: { executor: this.executor }
  233. });
  234. await modal.present();
  235. await this.executor.start();
  236. }
  237. async jobWorkflow() {
  238. // 创建工作流
  239. const workflow = {
  240. title: '求职信息收集',
  241. desc: '请填写您的求职相关信息',
  242. taskList: [
  243. new UserBasicInfoTask(this.modalCtrl),
  244. new JobIntentionTask(this.modalCtrl),
  245. // new UserInterestsTask(this.modalCtrl)
  246. ]
  247. };
  248. this.executor.setWorkflow(workflow);
  249. const modal = await this.modalCtrl.create({
  250. component: FlowDisplayComponent,
  251. componentProps: { executor: this.executor }
  252. });
  253. await modal.present();
  254. await this.executor.start();
  255. }
  256. async startWorkflow() {
  257. // 创建工作流
  258. const workflow = {
  259. title: '示例工作流',
  260. desc: '演示工作流执行过程',
  261. taskList: [
  262. new MockSuccessTask(),
  263. new MockRetryTask(),
  264. new MockProgressTask()
  265. ]
  266. };
  267. this.executor.setWorkflow(workflow);
  268. const modal = await this.modalCtrl.create({
  269. component: FlowDisplayComponent,
  270. componentProps: { executor: this.executor }
  271. });
  272. await modal.present();
  273. await this.executor.start();
  274. }
  275. // 问诊任务
  276. async startTriage() {
  277. this.executor.setWorkflow({
  278. title: '医疗分诊流程',
  279. taskList: [new TriageTask({ modalCtrl: this.modalCtrl })]
  280. });
  281. this.executor.taskSuccess$.subscribe(task => {
  282. if (task instanceof TriageTask) {
  283. this.showTriageResult(task);
  284. }
  285. });
  286. await this.executor.start();
  287. }
  288. private async showTriageResult(task: TriageTask) {
  289. const modal = await this.modalCtrl.create({
  290. component: TriageResultComponent,
  291. componentProps: {
  292. symptom: task.getData('symptomDescription'),
  293. department: task.getData('department'),
  294. reason: task.getData('triageReason')
  295. }
  296. });
  297. await modal.present();
  298. }
  299. }