index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. <script setup lang="tsx">
  2. import { ref } from 'vue';
  3. import { NButton, NPopconfirm, NSwitch } from 'naive-ui';
  4. import {
  5. fetchAddUser,
  6. fetchDeleteUser,
  7. fetchEditUser,
  8. fetchExportUser,
  9. fetchGetImportRecordList,
  10. fetchGetUserList
  11. } from '@/service/api/government/user-list';
  12. import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
  13. import { useTable } from '@/components/zt/Table/hooks/useTable';
  14. import { useModalFrom } from '@/components/zt/ModalForm/hooks/useModalForm';
  15. import type { ModalMethods } from '@/components/zt/Modal/types';
  16. import { useModal } from '@/components/zt/Modal/hooks/useModal';
  17. import SVGIcon from '@/components/custom/svg-icon.vue';
  18. const importTemplateRef = ref<ModalMethods>();
  19. const columns: NaiveUI.TableColumn<Api.government.userList>[] = [
  20. {
  21. key: 'channelName',
  22. title: '所属企业',
  23. align: 'center'
  24. },
  25. {
  26. key: 'realName',
  27. title: '员工姓名',
  28. align: 'center'
  29. },
  30. {
  31. key: 'userMobile',
  32. title: '手机号码',
  33. align: 'center'
  34. },
  35. {
  36. key: 'total',
  37. title: '总充值积分',
  38. align: 'center'
  39. },
  40. {
  41. key: 'available',
  42. title: '当前可用积分',
  43. align: 'center'
  44. },
  45. {
  46. key: 'expired',
  47. title: '已过期积分',
  48. align: 'center'
  49. },
  50. {
  51. key: 'used',
  52. title: '已消耗积分',
  53. align: 'center'
  54. },
  55. {
  56. key: 'status',
  57. title: '状态',
  58. align: 'center',
  59. render: row => {
  60. return (
  61. <NSwitch
  62. uncheckedValue={0}
  63. checkedValue={1}
  64. value={row.status}
  65. onUpdate:value={val => {
  66. row.status = val;
  67. fetchEditUser(row);
  68. }}
  69. ></NSwitch>
  70. );
  71. }
  72. }
  73. ];
  74. const [registerTable, { refresh, setTableLoading }] = useTable({
  75. searchFormConfig: {
  76. schemas: [
  77. {
  78. field: 'channelId',
  79. label: '所属企业',
  80. component: 'ApiSelect',
  81. componentProps: {
  82. api: fetchGetAllChannelList,
  83. labelFeild: 'channelName',
  84. valueFeild: 'id'
  85. }
  86. },
  87. {
  88. field: 'realName',
  89. label: '员工姓名',
  90. component: 'NInput'
  91. },
  92. {
  93. field: 'userMobile',
  94. label: '手机号码',
  95. component: 'NInput'
  96. }
  97. ],
  98. inline: false,
  99. size: 'small',
  100. labelPlacement: 'left',
  101. isFull: false
  102. },
  103. tableConfig: {
  104. keyField: 'userId',
  105. title: '员工列表',
  106. showAddButton: true
  107. }
  108. });
  109. const [registerModalTable] = useTable({
  110. tableConfig: {
  111. keyField: 'id',
  112. title: '导入记录',
  113. showTableHeaderAction: false,
  114. showSearch: false,
  115. minHeight: 400
  116. }
  117. });
  118. const failColumns: NaiveUI.TableColumn<Api.government.importRecordList>[] = [
  119. {
  120. key: 'index',
  121. title: '序号',
  122. align: 'center',
  123. render(_, rowIndex) {
  124. return rowIndex + 1;
  125. }
  126. },
  127. {
  128. key: 'taskName',
  129. title: '任务名称',
  130. align: 'center'
  131. },
  132. {
  133. key: 'createTime',
  134. title: '时间',
  135. align: 'center'
  136. },
  137. {
  138. key: 'operator',
  139. title: '操作人',
  140. align: 'center'
  141. },
  142. {
  143. key: 'result',
  144. title: '状态',
  145. align: 'center',
  146. width: 240,
  147. render(row) {
  148. return (
  149. <div class={'flex items-center'}>
  150. 共{Number(row.success) + Number(row.error)}条,成功:{row.success},
  151. <span class={'flex items-center text-red-500'}>
  152. 失败:
  153. {row.error}
  154. {row.error != 0 && (
  155. <div onClick={() => hanleExportFailure(row.batchNo)}>
  156. <SVGIcon
  157. icon={'tdesign:download'}
  158. class={'ml-1 cursor-pointer text-20px'}
  159. style={'color:var(--n-loading-color)'}
  160. ></SVGIcon>
  161. </div>
  162. )}
  163. </span>
  164. </div>
  165. );
  166. }
  167. }
  168. ];
  169. function hanleExportFailure(batchNo: string) {
  170. window.open(
  171. `${import.meta.env.VITE_SERVICE_BASE_URL}/admin/enterprise/downloadErrorExcel?batchNo=${batchNo}`,
  172. '_blank'
  173. );
  174. }
  175. async function handleDelete(row: Api.government.userList) {
  176. setTableLoading(true);
  177. await fetchDeleteUser(row.userId);
  178. console.log(row, 'row');
  179. refresh();
  180. }
  181. const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValue }] = useModalFrom({
  182. modalConfig: {
  183. title: '员工 ',
  184. width: 600,
  185. isShowHeaderText: true,
  186. height: 200
  187. },
  188. formConfig: {
  189. schemas: [
  190. {
  191. label: '',
  192. field: 'userId',
  193. component: 'NInput',
  194. show: false
  195. },
  196. {
  197. field: 'realName',
  198. label: '员工姓名',
  199. component: 'NInput',
  200. required: true
  201. },
  202. {
  203. field: 'userMobile',
  204. label: '手机号码',
  205. component: 'NInput',
  206. required: true,
  207. componentProps: {
  208. maxlength: 11
  209. },
  210. rules: [
  211. {
  212. pattern: /^1[3456789]\d{9}$/,
  213. message: '请输入正确的手机号',
  214. trigger: ['blur', 'input']
  215. }
  216. ]
  217. },
  218. {
  219. field: 'channelId',
  220. label: '所属企业',
  221. component: 'ApiSelect',
  222. componentProps: {
  223. api: fetchGetAllChannelList,
  224. labelFeild: 'channelName',
  225. valueFeild: 'id'
  226. },
  227. required: true
  228. }
  229. ],
  230. gridProps: {
  231. cols: '1'
  232. },
  233. labelWidth: 120
  234. }
  235. });
  236. const [registerModalFail, { openModal: openModalFail }] = useModal({
  237. title: '导入记录',
  238. height: 600,
  239. showFooter: false,
  240. width: 1200
  241. });
  242. async function handleSubmit() {
  243. const form = await getFieldsValue();
  244. if (form.userId) {
  245. await fetchEditUser(form);
  246. } else {
  247. await fetchAddUser(form);
  248. }
  249. closeModal();
  250. refresh();
  251. }
  252. async function edit(row: Recordable) {
  253. openModal(row);
  254. setFieldsValue(row);
  255. }
  256. function openImportModal() {
  257. importTemplateRef.value?.openModal();
  258. }
  259. async function handleSubmitImport(file: File) {
  260. const { error } = await fetchExportUser({ file });
  261. if (!error) {
  262. importTemplateRef.value?.closeModal();
  263. refresh();
  264. }
  265. importTemplateRef.value?.setSubLoading(false);
  266. }
  267. </script>
  268. <template>
  269. <LayoutTable>
  270. <ZTable :columns="columns" :api="fetchGetUserList" @register="registerTable" @add="openModal">
  271. <template #op="{ row }">
  272. <NButton size="small" ghost type="primary" :disabled="Boolean(row.available)" @click="edit(row)">编辑</NButton>
  273. <NPopconfirm @positive-click="handleDelete(row)">
  274. <template #trigger>
  275. <NButton size="small" type="error" ghost :disabled="Boolean(row.available)">删除</NButton>
  276. </template>
  277. 确定删除吗?
  278. </NPopconfirm>
  279. </template>
  280. <template #prefix>
  281. <NSpace>
  282. <NButton size="small" @click="openImportModal">导入员工</NButton>
  283. <NButton size="small" @click="openModalFail">导入记录</NButton>
  284. </NSpace>
  285. </template>
  286. </ZTable>
  287. <ZImportTemplate
  288. ref="importTemplateRef"
  289. url="/admin/enterprise/downloadExcel"
  290. template-text="员工导入模版.xlsx"
  291. modal-text="导入员工"
  292. @submit="handleSubmitImport"
  293. ></ZImportTemplate>
  294. <BasicModal @register="registerModalFail">
  295. <LayoutTable>
  296. <ZTable
  297. :columns="failColumns"
  298. :show-table-action="false"
  299. :api="fetchGetImportRecordList"
  300. @register="registerModalTable"
  301. ></ZTable>
  302. </LayoutTable>
  303. </BasicModal>
  304. <BasicModelForm @register-modal-form="registerModalForm" @submit-form="handleSubmit"></BasicModelForm>
  305. </LayoutTable>
  306. </template>
  307. <style scoped></style>