DataTable.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <script lang="ts" setup>
  2. /**
  3. * @Name: DataTable.vue
  4. * @Description:审批查看(供货)数据表格
  5. * @Author: xinyan
  6. */
  7. import { Download, Plus, Refresh, Upload } from '@element-plus/icons-vue';
  8. import { ElMessage } from 'element-plus';
  9. import { usePagination } from '/@/utils/usePagination';
  10. import { useTableData } from '/@/utils/useTableData';
  11. import DataTableSlot from './DataTableSlot.vue';
  12. import { uesDownloadFile } from '/@/utils/useDownload';
  13. import { downloadFile } from '/@/utils/service';
  14. import PermissionButton from '/src/components/PermissionButton/index.vue';
  15. import ImportButton from '/src/components/ImportButton/index.vue';
  16. import VerticalDivider from '/src/components/VerticalDivider/index.vue';
  17. import * as api from '../api';
  18. import { useResponse } from '/@/utils/useResponse';
  19. import {
  20. CostDetailColumns,
  21. SupplyCheckColumns_Regular,
  22. SupplyCheckColumns_Special,
  23. } from '/@/views/price-approval/Columns';
  24. import EditDrawer from '/@/views/price-approval/approval-review-supply/components/EditDrawer.vue';
  25. const router = useRouter();
  26. interface Parameter {
  27. sku: string;
  28. platform: string;
  29. country_code: string;
  30. sales_mode: string;
  31. }
  32. const queryParameter: Parameter | undefined = inject('query-parameter');
  33. const { tableOptions, handlePageChange } = usePagination(fetchList);
  34. const gridRef = ref();
  35. const gridOptions: any = reactive({
  36. size: 'mini',
  37. border: false,
  38. round: true,
  39. stripe: true,
  40. currentRowHighLight: true,
  41. height: '100%',
  42. toolbarConfig: {
  43. size: 'large',
  44. slots: {
  45. buttons: 'toolbar_buttons',
  46. tools: 'toolbar_tools'
  47. }
  48. },
  49. rowConfig: {
  50. isHover: true
  51. },
  52. columnConfig: {
  53. resizable: true
  54. },
  55. pagerConfig: {
  56. total: tableOptions.value.total,
  57. page: tableOptions.value.page,
  58. limit: tableOptions.value.limit
  59. },
  60. loading: false,
  61. loadingConfig: {
  62. icon: 'vxe-icon-indicator roll',
  63. text: '正在拼命加载中...'
  64. },
  65. columns: '',
  66. data: ''
  67. });
  68. const checkedList = ref<Set<number>>(new Set());
  69. const btnLoading = ref(false);
  70. const editOpen = ref(false);
  71. const rowData = ref({});
  72. const dialogVisible = ref(false);
  73. const templateType = ref('cost');
  74. onBeforeMount(() => {
  75. gridOptions.pagerConfig.limit = 10;
  76. });
  77. onMounted(() => {
  78. fetchList();
  79. });
  80. async function fetchList(isQuery = false) {
  81. if (isQuery) {
  82. gridOptions.pagerConfig.page = 1;
  83. }
  84. gridOptions.data = [];
  85. gridOptions.columns = [];
  86. const query = {
  87. sku: queryParameter?.sku,
  88. platform: queryParameter?.platform,
  89. country_code: queryParameter?.country_code,
  90. sales_mode: queryParameter?.sales_mode,
  91. };
  92. await useTableData(api.getTableData, query, gridOptions);
  93. if (gridOptions && gridOptions.data?.length) await gridRef.value.loadColumn(SupplyCheckColumns_Special);
  94. gridOptions.showHeader = Boolean(gridOptions.data?.length);
  95. }
  96. function handleRefresh() {
  97. fetchList();
  98. }
  99. async function handleDownload() {
  100. gridOptions.loading = true;
  101. try {
  102. await uesDownloadFile({
  103. apiMethod: api.exportData,
  104. queryParams: {
  105. sku: queryParameter?.sku,
  106. platform: queryParameter?.platform,
  107. country_code:queryParameter?.country_code,
  108. sales_mode: queryParameter?.sales_mode,
  109. },
  110. fileName: '审批查看(供货)数据.xlsx',
  111. successMessage: () => ElMessage.success('数据导出成功!'),
  112. errorMessage: () => ElMessage.error('数据导出失败,请重试!'),
  113. });
  114. } finally {
  115. gridOptions.loading = false;
  116. }
  117. }
  118. function handleCreate() {
  119. router.push({ path: '/addPage', query: { type: 'supply' } });
  120. }
  121. function handleEdit(row: any) {
  122. editOpen.value = true;
  123. rowData.value = row;
  124. }
  125. async function singleDelete(row: any) {
  126. const res = await useResponse(api.deleteRow, row);
  127. if (res.code === 2000) {
  128. ElMessage.error({ message: '已删除!', plain: true, icon: 'Delete' });
  129. handleRefresh();
  130. }
  131. }
  132. function downloadTemplate() {
  133. const url = '/api/pricing/price_product_supply/import_data/';
  134. const fileName = '审批查看(供货)模板.xlsx';
  135. if (url) {
  136. downloadFile({
  137. url,
  138. method: 'GET',
  139. filename: fileName,
  140. });
  141. } else {
  142. console.error('未知的模板类型:', templateType.value);
  143. }
  144. }
  145. const gridEvents = {
  146. custom({ type }: any) {
  147. if (type == 'confirm') {
  148. fetchList();
  149. }
  150. }
  151. };
  152. function cellStyle() {
  153. return {
  154. fontWeight: 500,
  155. };
  156. }
  157. defineExpose({ fetchList });
  158. </script>
  159. <template>
  160. <vxe-grid ref="gridRef" :cell-style="cellStyle" v-bind="gridOptions" v-on="gridEvents">
  161. <!-- 工具栏左侧 -->
  162. <template #toolbar_buttons>
  163. <div class="flex gap-2">
  164. <div>
  165. <PermissionButton :icon="Plus" plain round type="primary" @click="handleCreate">新 增</PermissionButton>
  166. </div>
  167. <div class="custom-el-input">
  168. <el-select v-model="templateType" style="width: 200px">
  169. <template #prefix>
  170. <div class="flex items-center">
  171. <el-button
  172. size="small"
  173. style="margin-left: -7px; font-size: 14px; border-radius: 29px"
  174. text
  175. type="success"
  176. @click.stop="downloadTemplate"
  177. >
  178. 下载
  179. </el-button>
  180. <VerticalDivider style="margin-left: 7px" />
  181. </div>
  182. </template>
  183. <el-option label="审批查看(供货)" value="cost" />
  184. </el-select>
  185. </div>
  186. <VerticalDivider class="px-1" style="margin-left: 7px" />
  187. <ImportButton :icon="Upload" :uploadFunction="api.upload" bg text>导 入</ImportButton>
  188. </div>
  189. </template>
  190. <!-- 工具栏右侧 -->
  191. <template #toolbar_tools>
  192. <el-button circle class="toolbar-btn" @click="handleRefresh">
  193. <el-icon>
  194. <Refresh />
  195. </el-icon>
  196. </el-button>
  197. <el-button circle class="toolbar-btn" @click="handleDownload">
  198. <el-icon>
  199. <Download />
  200. </el-icon>
  201. </el-button>
  202. </template>
  203. <template #top>
  204. <div class="mb-2"></div>
  205. </template>
  206. <!-- 分页 -->
  207. <template #pager>
  208. <vxe-pager
  209. v-model:currentPage="gridOptions.pagerConfig.page"
  210. v-model:pageSize="gridOptions.pagerConfig.limit"
  211. :total="gridOptions.pagerConfig.total"
  212. class="mt-1.5"
  213. @page-change="handlePageChange"
  214. />
  215. </template>
  216. <template #empty>
  217. <el-empty description="暂无数据" />
  218. </template>
  219. <!-- 自定义列插槽 -->
  220. <template v-for="col in SupplyCheckColumns_Special" #[`${col.field}`]="{ row }">
  221. <DataTableSlot :field="col.field" :row="row" @edit-row="handleEdit" @handle-delete="singleDelete" />
  222. </template>
  223. </vxe-grid>
  224. <EditDrawer v-if="editOpen" v-model="editOpen" :row-data="rowData" @refresh="handleRefresh" />
  225. </template>
  226. <style scoped>
  227. .toolbar-btn {
  228. width: 34px;
  229. height: 34px;
  230. font-size: 18px;
  231. }
  232. :deep(.custom-el-input .el-select__wrapper) {
  233. border-radius: 20px;
  234. }
  235. </style>