index.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <template>
  2. <div>
  3. <div class="mx-6 mb-2">
  4. <TimeLine :data="timeLineData" @hover="callHover" @icon="callIcon">
  5. <template #head>
  6. <transition class="animate__animated animate__slideInLeft">
  7. <div class="timeline-outer" v-if="timeOuter">
  8. <div class="timeline-outer_item" @click="handleAdd"> 新建透析处方模板 </div>
  9. </div>
  10. </transition>
  11. </template>
  12. </TimeLine>
  13. </div>
  14. <FormDrawer @register="registerDrawer" @success="callSuccess" />
  15. </div>
  16. </template>
  17. <script setup lang="ts">
  18. import { ref, reactive, onUnmounted } from 'vue';
  19. import TimeLine from '/@/components/XTTimeLine/src/TimeLine.vue';
  20. import { onMounted } from 'vue';
  21. import dayjs from 'dayjs';
  22. import { listDictModelBatch } from '/@/api/common';
  23. import { formatDictValue } from '/@/utils';
  24. //
  25. import FormDrawer from './FormDrawer.vue';
  26. import { useDrawer } from '@/components/Drawer';
  27. import { archivesFormulaTemplateQueryList } from '@/api/biz/archives/formulaTemplateApi';
  28. const props = defineProps({
  29. info: {
  30. type: Object,
  31. default: () => {},
  32. },
  33. });
  34. const bizDictOptions = reactive<any>({});
  35. const timeLineData = ref([]);
  36. const timeOuter = ref(false);
  37. onMounted(async () => {
  38. const res = await listDictModelBatch(bizDictData.value.map(ele => ele.dictCode));
  39. for (const i in res) {
  40. const filter = bizDictData.value.filter(ele => ele.dictCode == i)[0];
  41. bizDictOptions[filter.key] = res[i];
  42. }
  43. console.log('🚀 ~ file: index.vue:47 ~ onMounted ~ bizDictOptions:', bizDictOptions);
  44. // console.log('🚀 ~ file: index.vue:96 ~ onMounted ~ res:', res);
  45. await getData();
  46. });
  47. const [registerDrawer, { openDrawer }] = useDrawer();
  48. const bizDictData = ref([
  49. // 透析模式
  50. { key: 'dt', dictCode: 'dt' },
  51. // 通路类型
  52. { key: 'type', dictCode: 'va_type' },
  53. ]);
  54. async function getData() {
  55. const res = await archivesFormulaTemplateQueryList(props.info?.id);
  56. console.log('🚀 ~ file: index.vue:105 ~ getData ~ res:', res);
  57. timeLineData.value = res.map(ele => {
  58. const innerData = {
  59. id: ele.id,
  60. title: '基本信息',
  61. icon: 'icon-xt-edit_default',
  62. type: 'basic',
  63. data: [
  64. { field: 'vascularAccess', label: '血管通路', value: '', dict: true },
  65. { field: 'dryWeight', label: '干体重 (kg)', value: '', prefix: 'vitals' },
  66. { field: 'oh', label: 'OH值 (kg)', value: '', prefix: 'vitals' },
  67. { field: 'v', label: 'V值 (kg)', value: '', prefix: 'vitals' },
  68. { field: 'firstDose', label: '首剂 (mg)', value: '', prefix: 'anticoagulant' },
  69. { field: 'appendDose', label: '追加 (mg)', value: '', prefix: 'anticoagulant' },
  70. { field: 'type', label: '抗凝方式', value: '', span: 12, prefix: 'anticoagulant' },
  71. { field: 'suppliesTemplate', label: '耗材使用', value: '', span: 24 },
  72. { field: 'dialysisTime', label: '透析时长 (h)', value: '', prefix: 'dialysisParam' },
  73. { field: 'flowRate', label: '流量 (ml/min)', value: '', prefix: 'dialysisParam' },
  74. { field: 'temperature', label: '湿度 (℃)', value: '', prefix: 'dialysisParam' },
  75. { field: 'bloodFlow', label: '血流量 (ml/min)', value: '', prefix: 'dialysisParam' },
  76. { field: 'k', label: 'K (mmolL)', value: '', prefix: 'dialysisParam' },
  77. { field: 'na', label: 'Na (mmolL)', value: '', prefix: 'dialysisParam' },
  78. { field: 'ca', label: 'Ca (mmolL)', value: '', prefix: 'dialysisParam' },
  79. { field: 'hco', label: '碳酸氢根 (mmolL)', value: '', prefix: 'dialysisParam' },
  80. { field: 'mg', label: 'Mg (mmolL)', value: '', prefix: 'dialysisParam' },
  81. { field: 'cl', label: 'Cl (mmolL)', value: '', prefix: 'dialysisParam' },
  82. { field: 'glucose', label: '葡萄糖 (mmolL)', value: '', prefix: 'dialysisParam' },
  83. ],
  84. };
  85. innerData.title = formatDictValue(bizDictOptions.dt, ele.dialysisType);
  86. console.log('🚀 ~ file: index.vue:114 ~ getData ~ innerData:', innerData);
  87. innerData.type = ele.dialysisType;
  88. innerData.data = innerData.data.map(eleC => {
  89. if (eleC.dict) {
  90. if (eleC.field == 'vascularAccess') {
  91. eleC.value = formatDictValue(bizDictOptions['type'], ele[eleC.field]);
  92. } else {
  93. eleC.value = formatDictValue(bizDictOptions[eleC.field], ele[eleC.field]);
  94. }
  95. } else if (eleC.prefix) {
  96. eleC.value = ele[eleC.prefix][eleC.field];
  97. } else if (eleC.field == 'suppliesTemplate') {
  98. eleC.value = ele[eleC.field]
  99. ?.map(eleS => {
  100. return `${eleS.name}-${eleS.type ? eleS.type + '-' : ''}${eleS.count}个`;
  101. })
  102. .join('; ');
  103. } else {
  104. eleC.value = ele[eleC.field];
  105. }
  106. return eleC;
  107. });
  108. return {
  109. id: ele.id,
  110. dot: ele.updatorName,
  111. date: dayjs(ele.enactedTime).format('YYYY-MM-DD'),
  112. cnt: innerData,
  113. };
  114. });
  115. console.log('🚀 ~ file: index.vue:168 ~ getData ~ timeLineData.value :', timeLineData.value);
  116. }
  117. function handleAdd() {
  118. const info = {
  119. ...props.info,
  120. patientBasicId: props.info.id,
  121. };
  122. console.log('🚀 ~ file: index.vue:205 ~ handleAdd ~ data:', info);
  123. openDrawer(true, {
  124. isUpdate: false,
  125. record: { ...info },
  126. });
  127. }
  128. onUnmounted(() => {
  129. timeOuter.value = false;
  130. });
  131. // 回调
  132. function callSuccess(data) {
  133. console.log('🚀 ~ file: index.vue:212 ~ callSuccess ~ data:', data);
  134. }
  135. function callHover() {
  136. timeOuter.value = true;
  137. }
  138. function callIcon(data) {
  139. const info = {
  140. ...props.info,
  141. patientBasicId: props.info.id,
  142. };
  143. openDrawer(true, {
  144. isUpdate: true,
  145. record: { ...info, ...data },
  146. });
  147. }
  148. </script>
  149. <style lang="less" scoped>
  150. .timeline-outer {
  151. display: flex;
  152. margin-left: 20px;
  153. transition: all 0.3s ease-in-out;
  154. &_item {
  155. padding: 0 30px;
  156. height: 40px;
  157. line-height: 40px;
  158. border-radius: 30px;
  159. color: #fff;
  160. background: #0075ff;
  161. margin-right: 20px;
  162. cursor: pointer;
  163. letter-spacing: 2px;
  164. }
  165. }
  166. ::v-deep(.ant-picker) {
  167. width: 100%;
  168. }
  169. .ant-dropdown-link {
  170. display: block;
  171. margin-right: 16px;
  172. background: #fff;
  173. border-radius: 50%;
  174. width: 32px;
  175. height: 32px;
  176. text-align: center;
  177. line-height: 32px;
  178. cursor: pointer;
  179. &:last-child {
  180. margin-right: 0;
  181. }
  182. &:hover {
  183. color: #0075ff;
  184. }
  185. }
  186. </style>