index.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <template>
  2. <ele-page flex-table>
  3. <page-search @search="reload" v-if="historyData == '1'" />
  4. <common-table
  5. ref="pageRef"
  6. :pageConfig="pageConfig"
  7. :columns="columns"
  8. :tools="false"
  9. show-summary
  10. :summary-method="getSummaries"
  11. :flex-table="false"
  12. >
  13. <template #toolbar="{ row }">
  14. <div>
  15. <el-radio-group
  16. @change="handleStatusChange"
  17. v-model="historyData"
  18. >
  19. <el-radio-button label="订单审核实时统计" value="0" />
  20. <el-radio-button label="订单审核历史统计" value="1" />
  21. </el-radio-group>
  22. <el-button
  23. style="margin-left: 40px"
  24. type="success"
  25. plain
  26. v-permission="'statistic:recycleOrder:export'"
  27. v-if="historyData == '1'"
  28. @click="handleExportExcel(row)"
  29. >
  30. 导出EXCEL
  31. </el-button>
  32. </div>
  33. </template>
  34. </common-table>
  35. </ele-page>
  36. </template>
  37. <script setup>
  38. import { ref, reactive } from 'vue';
  39. import CommonTable from '@/components/CommonPage/CommonTable.vue';
  40. import pageSearch from './components/page-search.vue';
  41. defineOptions({ name: 'AuditOrder' });
  42. const historyData = ref('0');
  43. function handleStatusChange(val) {
  44. historyData.value = val;
  45. pageConfig.params = { historyData: val };
  46. pageRef.value?.reload();
  47. }
  48. /** 表格列配置 */
  49. const columns = ref([
  50. { type: 'index', label: '#', align: 'center', width: 80 },
  51. { label: '审核员', prop: 'nickName', align: 'center' },
  52. { label: '录入审核订单', prop: 'orderNum', align: 'center' },
  53. { label: '录入书籍数量', prop: 'bookNum', align: 'center' },
  54. { label: '实际回收数量', prop: 'recycleBookNum', align: 'center' },
  55. { label: '品相良好', prop: 'goodNum', align: 'center' },
  56. { label: '品相一般', prop: 'generalNum', align: 'center' },
  57. { label: '品相极差', prop: 'canRefundNum', align: 'center' },
  58. {
  59. label: '不良率',
  60. prop: 'badRate',
  61. align: 'center',
  62. formatter: (row) => (row.badRate || 0) + '%'
  63. },
  64. { label: '预估金额', prop: 'expectMoney', align: 'center' },
  65. { label: '审核金额', prop: 'finalMoney', align: 'center' },
  66. { label: '审核日期', prop: 'statDate', align: 'center' }
  67. ]);
  68. /** 页面组件实例 */
  69. const pageRef = ref(null);
  70. const pageConfig = reactive({
  71. pageUrl: '/order/ordercheck/stat/pagelist', // 默认使用实时统计接口
  72. params: { historyData: 0 }, // 默认查询实时数据
  73. exportUrl: '/order/ordercheck/stat/export',
  74. fileName: '审核统计',
  75. cacheKey: 'auditOrderTable'
  76. });
  77. /**
  78. * 自定义表格汇总计算方法
  79. * @param {Object} param0 - 表格数据和列信息
  80. * @returns {Array} - 汇总行显示的数据
  81. */
  82. function getSummaries({ columns, data }) {
  83. const sums = [];
  84. columns.forEach((column, index) => {
  85. if (index === 0) {
  86. sums[index] = '合计';
  87. return;
  88. }
  89. const values = data.map((item) => Number(item[column.property]));
  90. if (!values.length) {
  91. sums[index] = 'N/A';
  92. return;
  93. }
  94. switch (column.property) {
  95. case 'badRate': {
  96. // 不良率 = 品相极差总数 / 录入书籍总数
  97. const totalBadValues = data.map((item) =>
  98. Number(item.canRefundNum || 0)
  99. );
  100. const totalNumValues = data.map((item) =>
  101. Number(item.bookNum || 0)
  102. );
  103. const totalBadSum = totalBadValues.reduce((prev, curr) => {
  104. const value = Number(curr);
  105. if (!isNaN(value)) {
  106. return prev + value;
  107. } else {
  108. return prev;
  109. }
  110. }, 0);
  111. const totalNumSum = totalNumValues.reduce((prev, curr) => {
  112. const value = Number(curr);
  113. if (!isNaN(value)) {
  114. return prev + value;
  115. } else {
  116. return prev;
  117. }
  118. }, 0);
  119. if (totalNumSum > 0) {
  120. sums[index] =
  121. ((totalBadSum / totalNumSum) * 100).toFixed(2) +
  122. '%';
  123. } else {
  124. sums[index] = '0.00%';
  125. }
  126. break;
  127. }
  128. case 'orderNum':
  129. case 'bookNum':
  130. case 'recycleBookNum':
  131. case 'goodNum':
  132. case 'generalNum':
  133. case 'canRefundNum': {
  134. // 数量类字段求和
  135. const sum = values.reduce((prev, curr) => {
  136. const value = Number(curr);
  137. if (!isNaN(value)) {
  138. return prev + value;
  139. } else {
  140. return prev;
  141. }
  142. }, 0);
  143. sums[index] = sum;
  144. break;
  145. }
  146. case 'expectMoney':
  147. case 'finalMoney': {
  148. // 金额类字段求和,保留两位小数
  149. const sum = values.reduce((prev, curr) => {
  150. const value = Number(curr);
  151. if (!isNaN(value)) {
  152. return prev + value;
  153. } else {
  154. return prev;
  155. }
  156. }, 0);
  157. sums[index] = sum.toFixed(2);
  158. break;
  159. }
  160. default:
  161. sums[index] = '';
  162. }
  163. });
  164. return sums;
  165. }
  166. //刷新表格
  167. function reload(where) {
  168. pageRef.value?.reload(where);
  169. }
  170. //导出excel
  171. function handleExportExcel() {
  172. pageRef.value?.exportData('审核统计');
  173. }
  174. </script>