index.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <script setup lang="tsx">
  2. import { ref, useTemplateRef } from 'vue';
  3. import {
  4. fetchGetFailPointsList,
  5. fetchGetPointsList,
  6. fetchGetPointsOutList,
  7. fetchImportPoints
  8. } from '@/service/api/government/points';
  9. import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
  10. import { useAuth } from '@/hooks/business/auth';
  11. import { useTable } from '@/components/zt/Table/hooks/useTable';
  12. import { useModal } from '@/components/zt/Modal/hooks/useModal';
  13. import type { FormSchema } from '@/components/zt/Form/types/form';
  14. import SVGIcon from '@/components/custom/svg-icon.vue';
  15. const importTemplateRef = useTemplateRef('importTemplateRef');
  16. const ModalColumns: NaiveUI.TableColumn<Api.government.PointsRecharge>[] = [
  17. {
  18. key: 'channelName',
  19. title: '所属企业',
  20. align: 'center'
  21. },
  22. {
  23. key: 'userName',
  24. title: '员工姓名',
  25. align: 'center'
  26. },
  27. {
  28. key: 'userPhone',
  29. title: '员工手机号',
  30. align: 'center'
  31. },
  32. {
  33. key: 'points',
  34. title: '充值积分',
  35. align: 'center'
  36. },
  37. {
  38. key: 'expiryDate',
  39. title: '过期日期',
  40. align: 'center'
  41. },
  42. {
  43. key: 'createTime',
  44. title: '创建时间',
  45. align: 'center'
  46. }
  47. ];
  48. const outColumns: NaiveUI.TableColumn<Api.government.PointsRechargeVO>[] = [
  49. {
  50. key: 'channelName',
  51. title: '所属企业',
  52. align: 'center'
  53. },
  54. {
  55. key: 'totalPoints',
  56. title: '总充值积分',
  57. align: 'center'
  58. },
  59. {
  60. key: 'totalUserCount',
  61. title: '总充值人次',
  62. align: 'center'
  63. },
  64. {
  65. key: 'createTime',
  66. title: '操作时间',
  67. align: 'center'
  68. }
  69. ];
  70. const searchSchemas: FormSchema[] = [
  71. {
  72. field: 'channelId',
  73. label: '所属企业',
  74. component: 'ApiSelect',
  75. componentProps: {
  76. api: fetchGetAllChannelList,
  77. labelFeild: 'channelName',
  78. valueFeild: 'id'
  79. }
  80. },
  81. {
  82. field: 'userPhone',
  83. label: '员工手机号',
  84. component: 'NInput'
  85. }
  86. ];
  87. const failColumns: NaiveUI.TableColumn<Api.government.PointsFailureRecordVO>[] = [
  88. {
  89. key: 'index',
  90. title: '序号',
  91. align: 'center',
  92. render(_, rowIndex) {
  93. return rowIndex + 1;
  94. }
  95. },
  96. {
  97. key: 'name',
  98. title: '任务名称',
  99. align: 'center'
  100. },
  101. {
  102. key: 'createTime',
  103. title: '时间',
  104. align: 'center',
  105. render(row) {
  106. return (
  107. <div>
  108. <div>创建时间:{row.createTime}</div>
  109. <div>完成时间:{row.createTime}</div>
  110. </div>
  111. );
  112. }
  113. },
  114. {
  115. key: 'totalUserCount',
  116. title: '操作人',
  117. align: 'center',
  118. render(row) {
  119. return (
  120. <div>
  121. <div>{row.createByRole}</div>
  122. <div>({row.createByName})</div>
  123. </div>
  124. );
  125. }
  126. },
  127. {
  128. key: 'successStatus',
  129. title: '状态',
  130. align: 'center',
  131. width: 240,
  132. render(row) {
  133. return (
  134. <div class={'flex items-center'}>
  135. 共{Number(row.successStatus) + Number(row.failureStatus)}条,成功:{row.successStatus},
  136. <span class={'flex items-center text-red-500'}>
  137. 失败:
  138. {row.failureStatus}
  139. {row.failureStatus != 0 && (
  140. <div onClick={() => hanleExportFailure(row.code)}>
  141. <SVGIcon
  142. icon={'tdesign:download'}
  143. class={'ml-1 cursor-pointer text-20px'}
  144. style={'color:var(--n-color)'}
  145. ></SVGIcon>
  146. </div>
  147. )}
  148. </span>
  149. </div>
  150. );
  151. }
  152. }
  153. ];
  154. const failData = ref<Api.government.PointsFailureRecordVO[]>([]);
  155. const [registerTable, { refresh }] = useTable({
  156. searchFormConfig: {
  157. schemas: searchSchemas.slice(0, 1),
  158. inline: false,
  159. size: 'small',
  160. labelPlacement: 'left',
  161. isFull: false
  162. },
  163. tableConfig: {
  164. keyField: 'id',
  165. title: '充值积分',
  166. showAddButton: false
  167. }
  168. });
  169. const [registerModalTable, { refresh: refreshModal }] = useTable({
  170. searchFormConfig: {
  171. schemas: searchSchemas,
  172. inline: false,
  173. size: 'small',
  174. labelPlacement: 'left',
  175. isFull: false
  176. },
  177. tableConfig: {
  178. keyField: 'id',
  179. title: '积分列表',
  180. showAddButton: false,
  181. minHeight: 400
  182. }
  183. });
  184. const [registerModal, { openModal }] = useModal({
  185. title: '充值积分',
  186. height: 800,
  187. showFooter: false,
  188. width: 1200
  189. });
  190. const [registerModalFail, { openModal: openModalFail }] = useModal({
  191. title: '导入记录',
  192. height: 400,
  193. showFooter: false
  194. });
  195. async function handleSubmitImport(file: File) {
  196. const { error } = await fetchImportPoints(file);
  197. if (!error) {
  198. importTemplateRef.value?.closeModal();
  199. refreshModal();
  200. } else {
  201. importTemplateRef.value?.setSubLoading(false);
  202. }
  203. }
  204. function handleOpenPoints() {
  205. importTemplateRef.value?.openModal();
  206. }
  207. async function openImportModal() {
  208. openModalFail();
  209. const { data } = await fetchGetFailPointsList();
  210. failData.value = data as Api.government.PointsFailureRecordVO[];
  211. }
  212. function hanleExportFailure(code: string) {
  213. window.open(`${import.meta.env.VITE_SERVICE_BASE_URL}/platform/pointsFailureRecord/export?code=${code}`, '_blank');
  214. }
  215. </script>
  216. <template>
  217. <LayoutTable>
  218. <ZTable :show-table-action="false" :columns="outColumns" :api="fetchGetPointsOutList" @register="registerTable">
  219. <template #prefix>
  220. <NButton size="small" @click="openModal">充值积分</NButton>
  221. </template>
  222. </ZTable>
  223. <BasicModal @register="registerModal" @after-leave="refresh">
  224. <LayoutTable>
  225. <ZTable
  226. :show-table-action="false"
  227. :columns="ModalColumns"
  228. :api="fetchGetPointsList"
  229. @register="registerModalTable"
  230. >
  231. <template #prefix>
  232. <NButton v-if="useAuth().hasAuth('points:user:import')" size="small" @click="handleOpenPoints">
  233. 导入积分
  234. </NButton>
  235. <NButton v-if="useAuth().hasAuth('points:user:import-record')" size="small" @click="openImportModal">
  236. 导入记录
  237. </NButton>
  238. </template>
  239. </ZTable>
  240. </LayoutTable>
  241. </BasicModal>
  242. <BasicModal @register="registerModalFail">
  243. <NDataTable :columns="failColumns" :data="failData" size="small" remote class="sm:h-full" />
  244. </BasicModal>
  245. <ZImportTemplate
  246. ref="importTemplateRef"
  247. url="/platform/pointsRecharge/exportTemplate"
  248. template-text="导入积分模版.xlsx"
  249. modal-text="导入积分"
  250. @submit="handleSubmitImport"
  251. ></ZImportTemplate>
  252. </LayoutTable>
  253. </template>
  254. <style scoped></style>