model.prescription.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import {findArray, stringToArray, tryRun} from '@/tool';
  2. export class ReasonableSafeMedicine {
  3. constructor(sort = ReasonableSafeMedicine.sort) {
  4. this.sort = sort;
  5. }
  6. analysis(medicines) { return ReasonableSafeMedicine.analysis(medicines, {sort: this.sort}); }
  7. static config = [
  8. {field: 'rs@10.1', key: 'lowDose', name: '剂量偏低', highlight: {value: true}},
  9. {field: 'rs@10.2', key: 'overDose', name: '剂量偏高', highlight: {value: true}},
  10. {field: 'rs@10', key: '', name: '超剂量药品', highlight: {value: true}},
  11. {field: 'rs@02', key: 'taboo', name: '慎忌禁用药'},
  12. {field: 'rs@03', key: 'pregnantTaboo', name: '孕妇慎忌禁'},
  13. {field: 'rs@04', key: 'diet', name: '服药饮食禁忌'},
  14. {field: 'rs@05', key: 'toxicity', name: '药物毒性说明', highlight: {label: true}},
  15. {field: 'rs@06', key: 'disSyn', name: '病证用药禁忌'},
  16. {field: 'rs@07', key: 'sbf', name: '十八反', highlight: {label: true}},
  17. {field: 'rs@08', key: 'sjw', name: '十九畏', highlight: {label: true}},
  18. {field: 'rs@09', key: 'by', name: '用药不宜'},
  19. {field: 'rs@00', key: 'prepare', name: '炮制品'},
  20. ];
  21. static sort = '10,2,3,4,5,6,7,8,9';
  22. /**
  23. * 解析药品的合理安全用药数据
  24. * @param medicines 药品
  25. * @param {object} [config] 配置信息
  26. * @param {string} [config.filter] 过滤规则
  27. * @param {string} [config.sort] 排序规则
  28. * @return {Readonly<{
  29. * [key: string]: { name: string; collection: Set<string>; gather: Set<string>; highlight?: {label: boolean; value: boolean;} }
  30. * toString(): string
  31. * }>}
  32. */
  33. static analysis(medicines, config = {}) {
  34. const sort = stringToArray(config.filter || config.sort || this.sort);
  35. const data = {
  36. * [Symbol.iterator]() { for (const key of sort) if (this[key]) yield this[key]; },
  37. sign() {
  38. const gather = new Set()
  39. for (const item of this) item.gather.forEach(value => gather.add(value));
  40. return Array.from(gather);
  41. },
  42. toString() {
  43. const parse = (value, highlight) => {
  44. const match = value.match(/^(.+?)(\d+(?:\.\d+)?[克Gg]?|反|畏|不宜与)?[((]([\s\S]*)[))]$/);
  45. if (!match) return value;
  46. const [_, prefix = value, dosage, suffix] = match;
  47. return [
  48. `<span class="${highlight.label && 'highlight'}">${prefix}</span>`,
  49. dosage ? `<span>${dosage}</span>` : '',
  50. suffix ? `<span class="${highlight.value && 'highlight'}">(${suffix})</span>` : '',
  51. ].filter(Boolean).join(' ');
  52. };
  53. let html = ``;
  54. for (const {name, highlight = {}, collection} of this) {
  55. html += `
  56. <div class="item">
  57. <div class="label">${name}:</div>
  58. ${Array.from(collection, item => `
  59. <div class="value">${parse(item, highlight)}</div>
  60. `).join('')}
  61. </div>
  62. `;
  63. }
  64. return html;
  65. },
  66. };
  67. Object.defineProperty(data, 'sign', {enumerable: false, writable: true, configurable: true});
  68. Object.defineProperty(data, 'toString', {enumerable: false, writable: true, configurable: true});
  69. const append = (key, value, id) => {
  70. if (!value) return '';
  71. const config = findArray(this.config, ['field', `rs@${key}`]);
  72. if (config) {
  73. const child = data[+key] || (data[+key] = {...config, collection: new Set(), gather: new Set()});
  74. stringToArray(value, '|', (v) => child.collection.add(v));
  75. if (id) child.gather.add(id);
  76. }
  77. };
  78. for (const medicine of medicines) {
  79. for (const field of Object.keys(medicine)) {
  80. const match = field.match(/rs@(\d+)(?:\.(\d+))?$/);
  81. if (!match) continue;
  82. const [_, category, subcategory] = match;
  83. append(category, medicine[field], medicine.matid);
  84. if (subcategory) append(`${category}.${subcategory}`, medicine[field], medicine.matid);
  85. }
  86. }
  87. return Object.freeze(data);
  88. }
  89. }