StepPage.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <script setup lang="ts">
  2. import { useStepStore } from '@/stores';
  3. import { useRequest } from 'alova/client';
  4. import { getDataMethod } from '@/api/pda.api.ts';
  5. import { defaultMenus } from '@/model/menu.model.ts';
  6. import { tryOnBeforeMount, tryOnUnmounted } from '@vueuse/core';
  7. const router = useRouter();
  8. const route = useRoute();
  9. const stepStore = useStepStore();
  10. const { dataset } = storeToRefs(stepStore);
  11. const navTitle = computed(() => defaultMenus.find((menu) => menu.path === `/step/${route.params.mode}`)?.name ?? import.meta.env.SIX_TITLE);
  12. const tabTitle = computed(() => navTitle.value?.replace('管理', '确认'));
  13. const tabIndex = ref(0);
  14. const loaded = computed(() => !!data.value?.no);
  15. const readonly = ref(false);
  16. const keyword = ref<string>(dataset.value?.no ?? '');
  17. const ignoreParentScanner = ref(false);
  18. provide('ignoreParentScanner', ignoreParentScanner);
  19. let onCleanup = () => {};
  20. tryOnBeforeMount(() => {
  21. if (window.bridge) {
  22. onCleanup = window.bridge.addEventListener('scan', event => {
  23. const detail = event.detail;
  24. if ( detail.code !== 0 || detail.data?.code == null ) return;
  25. if (ignoreParentScanner.value) {
  26. event.stopPropagation();
  27. event.preventDefault();
  28. } else {
  29. keyword.value = event.detail.data?.code ?? '';
  30. const toast = showLoadingToast({ message: '查询中...', duration: 0 });
  31. search().finally(() => toast.close());
  32. }
  33. });
  34. } else if (window.platform) {
  35. const update = (event: CustomEvent) => {
  36. if (ignoreParentScanner.value) {
  37. event.stopPropagation();
  38. event.preventDefault();
  39. } else {
  40. keyword.value = event.detail.code;
  41. const toast = showLoadingToast({ message: '查询中...', duration: 0 });
  42. search().finally(() => toast.close());
  43. }
  44. };
  45. platform.addEventListener('scan', update)
  46. onCleanup = () => { platform.removeEventListener('scan', update) }
  47. }
  48. });
  49. tryOnUnmounted(() => onCleanup?.());
  50. const {
  51. data,
  52. loading,
  53. send: search,
  54. } = useRequest(() => getDataMethod(keyword.value?.trim()), {
  55. immediate: false,
  56. initialData: { ...dataset.value },
  57. })
  58. .onSuccess(async ({ data }) => {
  59. keyword.value = data.no;
  60. dataset.value = data;
  61. const { mode, value } = route.params;
  62. if (value) {
  63. await router.push({ path: `${keyword.value}`, replace: true });
  64. } else {
  65. await router.push({ path: `${mode}/${keyword.value}` });
  66. }
  67. tabIndex.value = 3;
  68. })
  69. .onError(() => {
  70. keyword.value = '';
  71. });
  72. watch(loading, (value) => {
  73. if (value) {
  74. showLoadingToast({ forbidClick: true, duration: 0, message: '加载中...' });
  75. } else {
  76. closeToast();
  77. }
  78. });
  79. function back(delta?: number) {
  80. stepStore.$reset();
  81. data.value = { ...dataset.value! };
  82. keyword.value = '';
  83. delta ??= route.params.value ? -2 : -1;
  84. tabIndex.value = 0;
  85. router.go(delta);
  86. }
  87. </script>
  88. <template>
  89. <div class="page page__home flex flex-col size-full">
  90. <header class="flex-none">
  91. <van-nav-bar :title="navTitle" left-text="返回" left-arrow @click-left="back()" />
  92. <van-search
  93. v-model="keyword"
  94. input-align="center"
  95. placeholder="请使用设备按钮进行扫码"
  96. :readonly="readonly || loading || loaded"
  97. :show-action="loaded"
  98. @search="keyword && search()"
  99. @cancel="back(-1)"
  100. />
  101. </header>
  102. <van-tabs class="content flex-auto overflow-hidden" v-model:active="tabIndex">
  103. <van-tab title="就诊信息">
  104. <van-cell-group>
  105. <van-cell title="患者" :value="data.patient?.name" />
  106. <van-cell title="性别" :value="data.patient?.gender" />
  107. <van-cell title="年龄" :value="data.patient?.age" />
  108. <van-cell title="手机号" :value="data.patient?.phone" />
  109. <van-cell title="医院" :value="data.patient?.hospital" />
  110. <van-cell title="门诊/住院" :value="data.patient?.category" />
  111. <van-cell title="科室/病区" :value="[data.patient?.department, data.patient?.area].filter((v) => !!v).join('/')" />
  112. <van-cell title="病床" :value="data.patient?.bed" />
  113. <van-cell title="临床诊断" :value="data.patient?.name" />
  114. <van-cell title="开方医生" :value="data.doctor?.name" />
  115. </van-cell-group>
  116. </van-tab>
  117. <van-tab title="处方信息">
  118. <van-cell-group>
  119. <van-cell title="处方类型" :value="data.prescription?.category" />
  120. <van-cell title="处方状态" :value="data.order?.state" />
  121. <van-cell title="总金额" :value="data.prescription?.totalPrice" />
  122. <van-cell title="剂型" :value="data.prescription?.dosageForm" />
  123. <van-cell title="剂数" :value="data.prescription?.count" />
  124. <van-cell title="处方用法" :value="data.prescription?.method" />
  125. <van-cell title="服药频次" :value="data.prescription?.frequency" />
  126. <van-cell title="服药时间" :value="data.prescription?.frequencyTime" />
  127. <van-cell title="煎药量" :value="data.prescription?.volume" />
  128. <van-cell title="是否代煎" :value="data.prescription?.decoction" />
  129. <van-cell title="开方医生备注" :value="data.prescription?.remark1" />
  130. <van-cell title="配送方式" :value="data.prescription?.dispatch?.method" />
  131. <van-cell title="收货人" :value="data.prescription?.dispatch?.name" />
  132. <van-cell title="收货电话" :value="data.prescription?.dispatch?.phone" />
  133. <van-cell title="收货地址" :value="data.prescription?.dispatch?.address" value-class="flex-2" />
  134. <van-cell title="嘱托" :value="data.prescription?.entrust" />
  135. <van-cell title="药师备注" :value="data.prescription?.remark2" />
  136. </van-cell-group>
  137. </van-tab>
  138. <van-tab title="药品信息">
  139. <table class="min-w-[600px] w-full">
  140. <thead>
  141. <tr>
  142. <th scope="col"></th>
  143. <th scope="col">药品名称</th>
  144. <th scope="col">药品规格</th>
  145. <th scope="col">剂量</th>
  146. <th scope="col">单位</th>
  147. <th scope="col">用法</th>
  148. <th scope="col">零售价</th>
  149. <th scope="col">产地</th>
  150. <th scope="col">小计</th>
  151. </tr>
  152. </thead>
  153. <tbody>
  154. <tr v-for="(medicine, index) in data.medicines" :key="medicine.id">
  155. <th scope="row">{{ index + 1 }}</th>
  156. <td class="w-24">{{ medicine.name }}</td>
  157. <td>{{ medicine.size }}</td>
  158. <td style="text-align: right">{{ medicine.dosage }}</td>
  159. <td>{{ medicine.unit }}</td>
  160. <td>{{ medicine.usage }}</td>
  161. <td>{{ medicine.place }}</td>
  162. <td style="text-align: right">{{ medicine.unitPrice }}</td>
  163. <td style="text-align: right">{{ medicine.totalPrice }}</td>
  164. </tr>
  165. </tbody>
  166. </table>
  167. </van-tab>
  168. <van-tab :title="tabTitle">
  169. <router-view :title="navTitle" @back="back"></router-view>
  170. </van-tab>
  171. </van-tabs>
  172. </div>
  173. </template>
  174. <style scoped lang="scss">
  175. .content {
  176. display: flex;
  177. flex-direction: column;
  178. :deep(.van-tabs__wrap) {
  179. flex: none;
  180. }
  181. :deep(.van-tabs__content) {
  182. flex: auto;
  183. overflow: auto;
  184. }
  185. //--van-cell-text-color: #fff
  186. --van-cell-value-color: var(--van-text-color);
  187. --van-cell-text-color: var(--van-text-color-2);
  188. table {
  189. border-collapse: collapse;
  190. border: 2px solid rgb(140 140 140);
  191. font-size: 14px;
  192. letter-spacing: 1px;
  193. }
  194. thead,
  195. tfoot {
  196. background-color: rgb(228 240 245);
  197. }
  198. th,
  199. td {
  200. border: 1px solid rgb(160 160 160);
  201. padding: 8px 10px;
  202. text-align: center;
  203. }
  204. }
  205. </style>
  206. <style>
  207. .flex-2 {
  208. flex: 2;
  209. }
  210. </style>