index.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <template>
  2. <div class="m-4">
  3. <div>
  4. <XTTitle title="个人排班" />
  5. <div class="flex justify-between my-4">
  6. <XTTab
  7. type="illness"
  8. :width="158"
  9. :selected="activeKey"
  10. :data="tabData"
  11. @item-click="callTab"
  12. />
  13. <XTForm :form-data="formData" @change="callFormChange" />
  14. </div>
  15. <BasicTable @register="registerTable">
  16. <template #bodyCell="{ column, record }">
  17. <template v-if="column.key === 'name'">
  18. <span :class="['table-dot', 'table-dot--' + record.status]" />
  19. <span>{{ record.name }}</span>
  20. </template>
  21. <template v-if="column.key === 'patientGender'">
  22. <span
  23. :style="{
  24. backgroundColor: formatDictColor(bizDictOptions.gender, record.patientGender),
  25. color: formatDictFontColor(bizDictOptions.gender, record.patientGender),
  26. padding: '1px 6px',
  27. borderRadius: '2px',
  28. marginRight: '4px',
  29. }"
  30. >
  31. {{ formatDictValue(bizDictOptions.gender, record.patientGender) }}
  32. </span>
  33. </template>
  34. <template v-if="column.key === 'patientType'">
  35. {{ formatDictValue(bizDictOptions.type, record.patientType) }}
  36. </template>
  37. <!-- <template v-if="column.key === 'infectiousDiseases'">
  38. <div class="flex">
  39. <div
  40. v-for="item in record.infectiousDiseases"
  41. :key="item"
  42. :style="{
  43. backgroundColor: formatDictColor(bizDictOptions.infectiousDiseases, item),
  44. color: formatDictFontColor(bizDictOptions.infectiousDiseases, item),
  45. padding: '1px 6px',
  46. borderRadius: '2px',
  47. marginRight: '4px',
  48. }"
  49. >
  50. {{ formatDictValue(bizDictOptions.infectiousDiseases, item) }}
  51. </div>
  52. </div>
  53. </template> -->
  54. <template v-if="column.key === 'frequency'">
  55. <span v-if="record.frequency">
  56. {{ record.frequency?.times }}次/{{ record.frequency?.week }}周
  57. </span>
  58. <span v-else> 无 </span>
  59. </template>
  60. <template v-if="column.key === 'machine' && record.machine.length">
  61. <div class="flex">
  62. <div v-for="(item, index) in record.machine" :key="item" class="inline-flex">
  63. <i
  64. v-if="item == 'pump_dual'"
  65. class="mr-1 iconfont icon-xt-dual-pump_default color-man"
  66. />
  67. {{ formatDictValue(bizDictOptions.pump, item) }}
  68. <span v-if="index < record.machine.length - 1">、</span>
  69. </div>
  70. </div>
  71. </template>
  72. <template v-if="column.key === 'specialNeed'">
  73. <div class="flex table-special">
  74. <div class="inline-flex">
  75. {{ record.specialNeedWeek }}
  76. </div>
  77. <div class="divider" v-if="record.specialNeedSailingSorts?.length" />
  78. <div class="inline-flex"> 第二班、第三班 </div>
  79. </div>
  80. </template>
  81. <template v-if="column.key === 'action'">
  82. <TableAction
  83. :actions="[
  84. {
  85. auth: 'sys:log:query',
  86. icon: 'icon-xt-details_edit_default|iconfont',
  87. tooltip: '编辑',
  88. onClick: handleEdit.bind(null, record),
  89. },
  90. {
  91. auth: 'sys:log:query',
  92. disabled: !record.frequency,
  93. icon: 'icon-xt-bed_default|iconfont',
  94. tooltip: '排班',
  95. onClick: handleEdit.bind(null, record),
  96. },
  97. // {
  98. // auth: 'sys:log:query',
  99. // icon: 'icon-xt-details_delete_default|iconfont',
  100. // tooltip: '删除',
  101. // popConfirm: {
  102. // title: '是否确认删除',
  103. // placement: 'left',
  104. // confirm: handleDelete.bind(null, record),
  105. // },
  106. // },
  107. ]"
  108. />
  109. </template>
  110. </template>
  111. </BasicTable>
  112. </div>
  113. <FormModal @register="registerModal" @success="callSuccess" />
  114. </div>
  115. </template>
  116. <script setup lang="ts">
  117. import { XTTitle } from '/@/components/XTTitle/index';
  118. import { XTTab } from '/@/components/XTTab/index';
  119. import { XTForm } from '/@/components/XTForm/index';
  120. import { BasicTable, useTable, TableAction } from '/@/components/TableCard';
  121. import { BasicTab, BasicTabActive, BasicWeekEnum, columns } from './data';
  122. import { ref } from 'vue';
  123. import {
  124. bedScheduledPersonQueryPage,
  125. bedScheduledPersonStats,
  126. // bedScheduledPersonRemove,
  127. } from '/@/api/biz/bed/scheduledPersonApi';
  128. import { listDictModelBatch } from '@/api/common';
  129. import { formatDictColor, formatDictFontColor, formatDictValue } from '/@/utils';
  130. import { onMounted, reactive } from 'vue';
  131. import { useModal } from '/@/components/Modal';
  132. import FormModal from './FormModal.vue';
  133. // import { useMessage } from '@/hooks/web/useMessage';
  134. const bizDictOptions = reactive<any>({});
  135. const bizDictData = ref([
  136. { key: 'gender', dictCode: 'pb_sex' },
  137. { key: 'type', dictCode: 'pb_type' },
  138. { key: 'pump', dictCode: 'bm_pump' },
  139. ]);
  140. const activeKey = ref(BasicTabActive);
  141. const tabData = ref(BasicTab);
  142. const [registerModal, { openModal }] = useModal();
  143. // const { createMessage } = useMessage();
  144. onMounted(async () => {
  145. const res = await listDictModelBatch(bizDictData.value.map(ele => ele.dictCode));
  146. for (const i in res) {
  147. const filter = bizDictData.value.filter(ele => ele.dictCode == i)[0];
  148. bizDictOptions[filter.key] = res[i];
  149. }
  150. const stats = await bedScheduledPersonStats();
  151. tabData.value = tabData.value.map(ele => {
  152. if (ele.key == '0') {
  153. ele.value = stats.all;
  154. }
  155. if (ele.key == '1') {
  156. ele.value = stats.newPatient;
  157. }
  158. if (ele.key == '2') {
  159. ele.value = stats.noneScheduled;
  160. }
  161. return ele;
  162. });
  163. });
  164. const [registerTable, { reload }] = useTable({
  165. api: bedScheduledPersonQueryPage,
  166. rowKey: 'id',
  167. columns,
  168. showIndexColumn: true,
  169. bordered: true,
  170. actionColumn: {
  171. width: 100,
  172. title: '操作',
  173. dataIndex: 'action',
  174. fixed: 'right',
  175. },
  176. beforeFetch: handleBeforeFetch,
  177. afterFetch: handleAfterFetch,
  178. });
  179. // 筛选数据
  180. const formData = ref([
  181. {
  182. name: 'tableSort',
  183. componentType: 'Select',
  184. placeholder: '请选择',
  185. width: 120,
  186. defaultValue: 'archivesCreateTime',
  187. dicts: [
  188. { label: '建档时间', value: 'archivesCreateTime' },
  189. { label: '按姓氏', value: 'patientNamePinyin' },
  190. ],
  191. },
  192. {
  193. name: 'patientName',
  194. componentType: 'Input',
  195. placeholder: '请输入患者姓名',
  196. prefix: 'icon-xt-search',
  197. width: 240,
  198. },
  199. ]);
  200. const formValue = reactive({
  201. patientName: '',
  202. tableSort: 'archivesCreateTime',
  203. }) as any;
  204. // 表格请求之前,对参数进行处理, 添加默认 排序
  205. function handleBeforeFetch(params) {
  206. return {
  207. ...params,
  208. // queryType: activeKey.value == '0' ? '0' : activeKey.value,
  209. patientName: formValue.patientName,
  210. orders: [{ field: formValue.tableSort, direction: 'DESC' }],
  211. };
  212. }
  213. function handleAfterFetch(data) {
  214. console.log('🚀 ~ file: index.vue:238 ~ handleAfterFetch ~ data:', data);
  215. const res = data.map(ele => {
  216. ele.specialNeedWeek = '';
  217. for (const i in ele.specialNeed) {
  218. if (ele.specialNeed[i] && i != 'sailingSorts') {
  219. ele.specialNeedWeek = ele.specialNeedWeek.concat('、', BasicWeekEnum[i]);
  220. }
  221. }
  222. ele.specialNeedWeek = ele.specialNeedWeek.substring(1);
  223. // 班次需要请求
  224. ele.specialNeedSailingSorts = ele.specialNeed?.sailingSorts;
  225. // console.log('ele', ele);
  226. return ele;
  227. });
  228. return res;
  229. }
  230. // 详情按钮事件
  231. function handleEdit(record: Recordable) {
  232. console.log('🚀 ~ file: index.vue:206 ~ handleView ~ record:', record);
  233. record.gender = formatDictValue(bizDictOptions.gender, record.patientGender);
  234. openModal(true, {
  235. isUpdate: true,
  236. record,
  237. });
  238. }
  239. // 删除按钮事件
  240. // async function handleDelete(record: Recordable) {
  241. // await bedScheduledPersonRemove([record.id]);
  242. // createMessage.success('删除成功!');
  243. // await reload();
  244. // }
  245. // 弹窗回调事件
  246. async function callSuccess({ isUpdate, values }) {
  247. console.log(isUpdate);
  248. console.log(values);
  249. await reload();
  250. }
  251. // 回调
  252. async function callTab(data) {
  253. activeKey.value = data.value;
  254. await reload();
  255. }
  256. async function callFormChange(data) {
  257. formValue.patientName = data.patientName ? data.patientName : '';
  258. formValue.tableSort = data.tableSort ? data.tableSort : '';
  259. await reload();
  260. }
  261. </script>
  262. <style lang="less" scoped>
  263. ::v-deep(.ant-btn-link) {
  264. color: rgb(61 65 85 / 100%);
  265. }
  266. .table-dot {
  267. display: inline-block;
  268. width: 10px;
  269. height: 10px;
  270. margin-right: 6px;
  271. border-radius: 50%;
  272. &--1 {
  273. background-color: #1bc1b3;
  274. }
  275. &--2 {
  276. background-color: #f7b500;
  277. }
  278. }
  279. .divider {
  280. height: 16px;
  281. width: 1px;
  282. background-color: #ccc;
  283. margin: 4px 6px 0;
  284. }
  285. .table-special .table-special-item:last-of-type {
  286. color: red;
  287. }
  288. </style>