index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <template>
  2. <div class="m-4">
  3. <div>
  4. <XTTitle title="透析设备" :right-data="titleData" @click="callTitleClick" />
  5. <div class="flex justify-between my-4">
  6. <XTTab
  7. type="illness"
  8. :width="136"
  9. :selected="activeKey"
  10. :data="tabData"
  11. @item-click="callTab"
  12. />
  13. <XTForm :form-data="formData" @change="callFormChange" @click="callFormClick" />
  14. </div>
  15. <div class="flex mb-2" v-if="siftData.length">
  16. <Sift :data="siftData" @close="callClose" />
  17. </div>
  18. <BasicTable @register="registerTable">
  19. <template #bodyCell="{ column, record }">
  20. <template v-if="column.key === 'useDate'">
  21. {{ record.useDate ? dayjs(record.useDate).format('YYYY-MM-DD') : '' }}
  22. </template>
  23. <template v-if="column.key === 'produceDate'">
  24. {{ record.produceDate ? dayjs(record.produceDate).format('YYYY-MM-DD') : '' }}
  25. </template>
  26. <template v-if="column.key === 'pumpType'">
  27. {{ formatDictValue(bizDictOptions.pumpType, record.pumpType) }}
  28. </template>
  29. <template v-if="column.key === 'deviceType'">
  30. <span
  31. :class="['table-dot']"
  32. :style="{
  33. backgroundColor: formatDictPreColor(bizDictOptions.deviceType, record.deviceType),
  34. }"
  35. />
  36. {{ formatDictValue(bizDictOptions.deviceType, record.deviceType) }}
  37. </template>
  38. <template v-if="column.key === 'infectiousDiseases'">
  39. <div class="flex">
  40. <div
  41. :style="{
  42. backgroundColor: formatDictColor(
  43. bizDictOptions.infectiousDiseases,
  44. record.infectiousDiseases,
  45. ),
  46. color: formatDictFontColor(
  47. bizDictOptions.infectiousDiseases,
  48. record.infectiousDiseases,
  49. ),
  50. padding: '1px 6px',
  51. borderRadius: '2px',
  52. marginRight: '4px',
  53. }"
  54. >
  55. {{ formatDictValue(bizDictOptions.infectiousDiseases, record.infectiousDiseases) }}
  56. </div>
  57. </div>
  58. </template>
  59. <template v-if="column.key === 'vascularAccess'">
  60. {{ formatDictValue(bizDictOptions.vascularAccess, record.vascularAccess) }}
  61. </template>
  62. <template v-if="column.key === 'patientReturn'">
  63. {{ formatDictValue(bizDictOptions.patientReturn, record.patientReturn) }}
  64. </template>
  65. <template v-if="column.key === 'action'">
  66. <TableAction
  67. :actions="[
  68. {
  69. auth: 'archives:patientBasic:query',
  70. icon: 'icon-xt-medical_default|iconfont',
  71. tooltip: '详情',
  72. label: '详情',
  73. onClick: handleView.bind(null, record),
  74. },
  75. ]"
  76. />
  77. </template>
  78. </template>
  79. </BasicTable>
  80. </div>
  81. <FormModal @register="registerModal" @success="callSuccess" />
  82. <FormDrawerSift @register="registerDrawer" @success="callSift" />
  83. </div>
  84. </template>
  85. <script setup lang="ts">
  86. import { XTTitle } from '/@/components/XTTitle/index';
  87. import { XTTab } from '/@/components/XTTab/index';
  88. import { XTForm } from '/@/components/XTForm/index';
  89. import { Sift } from '/@/components/XTList/index';
  90. import { BasicTable, useTable, TableAction } from '/@/components/TableCard';
  91. import { BasicTab, BasicTabActive, columns, siftFormSchema } from './data';
  92. import { ref } from 'vue';
  93. import { useRouter } from 'vue-router';
  94. import { archivesPatientBasicStats } from '/@/api/biz/archives/patientBasicApi';
  95. import { engineerDialysisDeviceQueryPage } from '@/api/biz/engineer/dialysisDeviceApi';
  96. import { listDictModelBatch } from '@/api/common';
  97. import {
  98. formatDictColor,
  99. formatDictFontColor,
  100. formatDictValue,
  101. formatDictPreColor,
  102. } from '/@/utils';
  103. import { onMounted, reactive } from 'vue';
  104. import dayjs from 'dayjs';
  105. import { useModal } from '/@/components/Modal';
  106. import FormModal from './FormModal.vue';
  107. // 筛选条件
  108. import FormDrawerSift from './FormDrawerSift.vue';
  109. import { useDrawer } from '@/components/Drawer';
  110. const bizDictOptions = reactive<any>({});
  111. const bizDictData = ref([
  112. // 泵类型
  113. { key: 'pumpType', dictCode: 'bm_pump' },
  114. // 设备类型
  115. { key: 'deviceType', dictCode: 'bm_det' },
  116. // 传染病类型
  117. { key: 'infectiousDiseases', dictCode: 'pb_epidemic' },
  118. ]);
  119. // 路由跳转
  120. const router = useRouter();
  121. const activeKey = ref(BasicTabActive);
  122. const tabData = ref(BasicTab);
  123. const [registerModal, { openModal }] = useModal();
  124. const [registerDrawer, { openDrawer }] = useDrawer();
  125. onMounted(async () => {
  126. const res = await listDictModelBatch(bizDictData.value.map(ele => ele.dictCode));
  127. for (const i in res) {
  128. const filter = bizDictData.value.filter(ele => ele.dictCode == i)[0];
  129. bizDictOptions[filter.key] = res[i];
  130. }
  131. const stats = await archivesPatientBasicStats();
  132. console.log('🚀 ~ file: index.vue:104 ~ onMounted ~ stats:', stats);
  133. tabData.value = tabData.value.map(ele => {
  134. if (ele.key == '0') {
  135. ele.value = stats.all;
  136. }
  137. if (ele.key == '1') {
  138. ele.value = stats.newPatient;
  139. }
  140. if (ele.key == '2') {
  141. ele.value = stats.noneFormulate;
  142. }
  143. if (ele.key == '3') {
  144. ele.value = stats.positive;
  145. }
  146. return ele;
  147. });
  148. console.log('🚀 ~ file: index.vue:118 ~ onMounted ~ tabData.value:', tabData.value);
  149. });
  150. const [registerTable, { reload }] = useTable({
  151. api: engineerDialysisDeviceQueryPage,
  152. exportAuthList: ['sys:log:export'],
  153. rowKey: 'id',
  154. columns,
  155. showIndexColumn: false,
  156. bordered: true,
  157. actionColumn: {
  158. width: 100,
  159. title: '操作',
  160. dataIndex: 'action',
  161. },
  162. beforeFetch: handleBeforeFetch,
  163. afterFetch: handleAfterFetch,
  164. });
  165. // 筛选数据
  166. const siftData = ref([]);
  167. // 标题数据
  168. const titleData = [
  169. {
  170. type: 'import',
  171. icon: 'icon-xt-import_default',
  172. },
  173. {
  174. type: 'add',
  175. btnIcon: 'icon-xt-add_default',
  176. btnText: '新增设备',
  177. },
  178. ];
  179. const formData = ref([
  180. {
  181. name: 'name',
  182. componentType: 'Input',
  183. placeholder: '请输入设备编号',
  184. prefix: 'icon-xt-search',
  185. width: 240,
  186. },
  187. {
  188. name: 'filter',
  189. componentType: 'IconBtn',
  190. count: 0,
  191. },
  192. ]);
  193. const formValue = reactive({
  194. name: '',
  195. }) as any;
  196. // const tableSort = ref([
  197. // {
  198. // field: 'create_time',
  199. // direction: 'DESC',
  200. // },
  201. // ]) as any;
  202. // 表格请求之前,对参数进行处理, 添加默认 排序
  203. function handleBeforeFetch(params) {
  204. // return { ...params, orders: tableSort.value };
  205. const sift = {};
  206. siftData.value.forEach(ele => {
  207. sift[ele.field] = ele.isDict ? ele.dict : ele.value;
  208. });
  209. if (params?.order) {
  210. params.orders = [
  211. {
  212. field: params.field,
  213. direction: params.order.substring(0, params.order.length - 3).toUpperCase(),
  214. },
  215. ];
  216. delete params.order;
  217. delete params.field;
  218. }
  219. return {
  220. ...params,
  221. queryType: activeKey.value == '0' ? '0' : activeKey.value,
  222. name: formValue.name,
  223. ...sift,
  224. };
  225. }
  226. function handleAfterFetch(data) {
  227. return data;
  228. }
  229. // 详情按钮事件
  230. function handleView(record: Recordable) {
  231. //
  232. router.push({
  233. path: '/bizEngineer/dialysisDevices/details',
  234. query: {
  235. id: record.id,
  236. name: record.name,
  237. },
  238. });
  239. }
  240. // 弹窗回调事件
  241. async function callSuccess({ isUpdate, values }) {
  242. console.log(isUpdate);
  243. console.log(values);
  244. await reload();
  245. }
  246. // 回调
  247. async function callTab(data) {
  248. activeKey.value = data.value;
  249. await reload();
  250. }
  251. function callTitleClick(data) {
  252. if (data.type == 'add') {
  253. openModal(true, {
  254. isUpdate: false,
  255. record: data,
  256. });
  257. }
  258. }
  259. async function callFormChange(data) {
  260. formValue.name = data.name ? data.name : '';
  261. await reload();
  262. }
  263. async function callFormClick(data) {
  264. if (data.name == 'filter') {
  265. const record = [];
  266. siftData.value.forEach(ele => {
  267. const obj = {
  268. field: ele.field,
  269. value: ele.value,
  270. } as any;
  271. if (ele.isDict) {
  272. obj.value = ele.dict;
  273. }
  274. record.push(obj);
  275. });
  276. openDrawer(true, {
  277. record,
  278. });
  279. }
  280. }
  281. // 筛选条件回调
  282. async function callSift(data) {
  283. siftData.value = [];
  284. for (const i in data) {
  285. if (data[i]) {
  286. siftFormSchema.forEach(ele => {
  287. // console.log('🚀 ~ file: index.vue:280 ~ obj ~ ele:', ele);
  288. if (ele.field == i) {
  289. siftData.value.push({
  290. field: ele.field,
  291. label: ele.label,
  292. value: ele.component.includes('Api')
  293. ? formatDictValue(bizDictOptions.gender, data[i])
  294. : data[i],
  295. isDict: ele.component.includes('Api'),
  296. dict: ele.component.includes('Api') ? data[i] : '',
  297. });
  298. }
  299. formData.value[formData.value.length - 1]['count'] = siftData.value.length;
  300. });
  301. }
  302. }
  303. await reload();
  304. }
  305. async function callClose(data) {
  306. if (data.type == 'clear') {
  307. console.log('清空全部');
  308. siftData.value = [];
  309. }
  310. if (data.type == 'close') {
  311. console.log('删除部分条件');
  312. siftData.value = siftData.value.filter(ele => {
  313. return ele.field != data.item?.field;
  314. });
  315. }
  316. formData.value[formData.value.length - 1]['count'] = siftData.value.length;
  317. await reload();
  318. }
  319. </script>
  320. <style lang="less" scoped>
  321. .table-dot {
  322. display: inline-block;
  323. width: 10px;
  324. height: 10px;
  325. margin-right: 6px;
  326. border-radius: 50%;
  327. }
  328. ::v-deep(.ant-btn-link) {
  329. color: rgb(61 65 85 / 100%);
  330. }
  331. </style>