index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <template>
  2. <el-card class="box-card">
  3. <byTable
  4. :hideTable="true"
  5. :hidePagination="true"
  6. :source="sourceList.data"
  7. :pagination="sourceList.pagination"
  8. :config="config"
  9. :loading="loading"
  10. :searchConfig="searchConfig"
  11. highlight-current-row
  12. :action-list="[
  13. {
  14. text: '导出Excel',
  15. action: () => clickExcel(),
  16. },
  17. {
  18. text: 'Excel文件',
  19. action: () => clickExcelFile(),
  20. },
  21. ]"
  22. @get-list="getList"
  23. @clickReset="clickReset"
  24. @changeRadioGroup="changeRadioGroup">
  25. </byTable>
  26. <el-table
  27. :data="sourceList.data"
  28. border
  29. :row-style="{ height: '35px' }"
  30. header-row-class-name="tableHeader"
  31. :span-method="objectSpanMethod"
  32. max-height="calc(100vh - 344px)">
  33. <el-table-column label="发货时间" prop="statementOfAccountTime" align="center" width="160" />
  34. <el-table-column label="事业部" prop="departmentName" width="120" />
  35. <el-table-column label="店铺" prop="shopName" width="160" />
  36. <el-table-column label="MES系统单号" prop="mesCode" width="180" />
  37. <el-table-column label="万里牛销售单号" prop="sellCode" width="180" />
  38. <el-table-column label="E10单号" prop="wlnCode" width="140" />
  39. <el-table-column label="SKU单号" prop="skuSpecCode" width="140" />
  40. <el-table-column label="SKU品号" prop="skuSpecName" width="180" />
  41. <el-table-column label="SKU数量" prop="quantitySKU" align="center" width="90" />
  42. <el-table-column label="BOM品号" prop="bomSpecCode" width="140" />
  43. <el-table-column label="BOM品名" prop="bomSpecName" width="300" />
  44. <el-table-column label="定制加工类型" prop="customProcessingType" width="140" />
  45. <el-table-column label="存货会计分类" prop="classifyName" width="120" />
  46. <el-table-column label="单位" prop="unit" width="80" />
  47. <el-table-column label="BOM数量" prop="quantityBOM" align="center" width="90" />
  48. <el-table-column label="单价" prop="unitPriceBOM" align="center" width="80" />
  49. <el-table-column label="激光LOGO" prop="laserLogoSummary" align="center" width="100" />
  50. <el-table-column label="激光体位线" prop="laserMitochondrialSummary" align="center" width="100" />
  51. <el-table-column label="代发费" prop="lssueFeeSummary" align="center" width="90" />
  52. <el-table-column label="快递包材费" prop="deliveryMaterialsFeeSummary" align="center" width="100" />
  53. <el-table-column label="包装人工费" prop="packingLaborSummary" align="center" width="100" />
  54. <el-table-column label="管理费" prop="managementFeeSummary" align="center" width="90" />
  55. <el-table-column label="打样费" prop="proofingFeeSummary" align="center" width="90" />
  56. <el-table-column label="SKU单价" prop="unitPriceSKU" align="center" width="90" />
  57. <el-table-column label="小计" align="center" width="120">
  58. <template #default="{ row }">
  59. {{ moneyFormat(row.subtotal) }}
  60. </template>
  61. </el-table-column>
  62. <el-table-column label="合计" align="center" width="120">
  63. <template #default="{ row }">
  64. {{ moneyFormat(row.total) }}
  65. </template>
  66. </el-table-column>
  67. </el-table>
  68. <el-row style="padding: 10px 0" justify="end" type="flex">
  69. <el-pagination
  70. background
  71. layout="total, sizes, prev, pager, next, jumper"
  72. :current-page="sourceList.pagination.pageNum"
  73. :page-size="sourceList.pagination.pageSize"
  74. :total="sourceList.pagination.total"
  75. @current-change="handlePageChange"
  76. @size-change="handleSizeChange" />
  77. </el-row>
  78. <el-dialog title="Excel文件" v-if="openFileList" v-model="openFileList" width="60%">
  79. <ExcelFile></ExcelFile>
  80. <template #footer>
  81. <el-button @click="openFileList = false" size="large">关 闭</el-button>
  82. </template>
  83. </el-dialog>
  84. </el-card>
  85. </template>
  86. <script setup>
  87. import byTable from "/src/components/byTable/index";
  88. import * as date from "/src/utils/date";
  89. import { ElMessage, ElMessageBox } from "element-plus";
  90. import ExcelFile from "/src/views/group/finance/check-bill/ExcelFile.vue";
  91. const { proxy } = getCurrentInstance();
  92. const departmentList = ref([{ dictKey: "0", dictValue: "胜德体育" }]);
  93. const sourceList = ref({
  94. data: [],
  95. pagination: {
  96. total: 0,
  97. pageNum: 1,
  98. pageSize: 10,
  99. code: "",
  100. departmentId: "",
  101. skuSpecCode: "",
  102. skuSpecName: "",
  103. beginTime: "",
  104. endTime: "",
  105. type: 1,
  106. },
  107. });
  108. const loading = ref(false);
  109. const searchConfig = computed(() => {
  110. return [
  111. {
  112. type: "input",
  113. prop: "code",
  114. label: "订单号",
  115. },
  116. {
  117. type: "select",
  118. prop: "departmentId",
  119. data: departmentList.value,
  120. label: "事业部",
  121. },
  122. {
  123. type: "input",
  124. prop: "skuSpecCode",
  125. label: "SKU品号",
  126. },
  127. {
  128. type: "input",
  129. prop: "skuSpecName",
  130. label: "SKU品名",
  131. },
  132. {
  133. type: "radio-group",
  134. prop: "type",
  135. label: "维度",
  136. data: [
  137. {
  138. dictKey: 1,
  139. dictValue: "本年度",
  140. },
  141. {
  142. dictKey: 2,
  143. dictValue: "近365天",
  144. },
  145. {
  146. dictKey: 3,
  147. dictValue: "近180天",
  148. },
  149. {
  150. dictKey: 4,
  151. dictValue: "近90天",
  152. },
  153. ],
  154. },
  155. {
  156. type: "date",
  157. propList: ["beginTime", "endTime"],
  158. label: "日期",
  159. },
  160. ];
  161. });
  162. const config = computed(() => {
  163. return [];
  164. });
  165. const getDemandData = () => {
  166. proxy.post("/department/page", { pageNum: 1, pageSize: 999 }).then((res) => {
  167. if (res.rows && res.rows.length > 0) {
  168. departmentList.value = departmentList.value.concat(
  169. res.rows.map((item) => {
  170. return {
  171. dictKey: item.id,
  172. dictValue: item.name,
  173. };
  174. })
  175. );
  176. }
  177. });
  178. };
  179. getDemandData();
  180. const mergeRow = (list) => {
  181. for (let field in list[0]) {
  182. let k = 0;
  183. let i = 0;
  184. while (k < list.length) {
  185. list[k][field + "Span"] = 1;
  186. list[k][field + "Dis"] = false;
  187. for (i = k + 1; i <= list.length - 1; i++) {
  188. if (["statementOfAccountTime", "departmentName", "shopName", "mesCode", "sellCode", "wlnCode", "outerBoxPackingFee", "total"].includes(field)) {
  189. if (list[k][field] === list[i][field] && list[k].orderId === list[i].orderId) {
  190. list[k][field + "Span"]++;
  191. list[k][field + "Dis"] = false;
  192. list[i][field + "Span"] = 1;
  193. list[i][field + "Dis"] = true;
  194. } else {
  195. break;
  196. }
  197. } else {
  198. if (list[k][field] === list[i][field] && list[k].orderId === list[i].orderId && list[k].skuSpecCode === list[i].skuSpecCode) {
  199. list[k][field + "Span"]++;
  200. list[k][field + "Dis"] = false;
  201. list[i][field + "Span"] = 1;
  202. list[i][field + "Dis"] = true;
  203. } else {
  204. break;
  205. }
  206. }
  207. }
  208. k = i;
  209. }
  210. }
  211. return list;
  212. };
  213. const getList = async (req, status) => {
  214. if (status) {
  215. sourceList.value.pagination = {
  216. pageNum: sourceList.value.pagination.pageNum,
  217. pageSize: sourceList.value.pagination.pageSize,
  218. };
  219. } else {
  220. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  221. }
  222. loading.value = true;
  223. proxy.post("/statementOfAccountMerge/salesOutWarehouseDetails", sourceList.value.pagination).then((res) => {
  224. let list = [];
  225. if (res.rows && res.rows.length > 0) {
  226. for (let i = 0; i < res.rows.length; i++) {
  227. let mesCode = "";
  228. let sellCode = "";
  229. if (res.rows[i].wlnCode) {
  230. sellCode = res.rows[i].code;
  231. } else {
  232. mesCode = res.rows[i].code;
  233. }
  234. if (res.rows[i].skuSpecList && res.rows[i].skuSpecList.length > 0) {
  235. for (let j = 0; j < res.rows[i].skuSpecList.length; j++) {
  236. if (res.rows[i].skuSpecList[j].bomSpecList && res.rows[i].skuSpecList[j].bomSpecList.length > 0) {
  237. for (let y = 0; y < res.rows[i].skuSpecList[j].bomSpecList.length; y++) {
  238. list.push({
  239. orderId: res.rows[i].orderId,
  240. statementOfAccountTime: res.rows[i].statementOfAccountTime,
  241. departmentName: res.rows[i].departmentName,
  242. shopName: res.rows[i].shopName,
  243. mesCode: mesCode,
  244. sellCode: sellCode,
  245. wlnCode: res.rows[i].wlnCode,
  246. skuSpecCode: res.rows[i].skuSpecList[j].skuSpecCode,
  247. skuSpecName: res.rows[i].skuSpecList[j].skuSpecName,
  248. quantitySKU: res.rows[i].skuSpecList[j].quantity,
  249. bomSpecCode: res.rows[i].skuSpecList[j].bomSpecList[y].bomSpecCode,
  250. bomSpecName: res.rows[i].skuSpecList[j].bomSpecList[y].bomSpecName,
  251. customProcessingType: res.rows[i].skuSpecList[j].bomSpecList[y].customProcessingType,
  252. classifyName: res.rows[i].skuSpecList[j].bomSpecList[y].classifyName,
  253. unit: res.rows[i].skuSpecList[j].bomSpecList[y].unit,
  254. quantityBOM: res.rows[i].skuSpecList[j].bomSpecList[y].quantity,
  255. unitPriceBOM: res.rows[i].skuSpecList[j].bomSpecList[y].unitPrice,
  256. laserLogoSummary: res.rows[i].skuSpecList[j].bomSpecList[y].laserLogoSummary,
  257. laserMitochondrialSummary: res.rows[i].skuSpecList[j].bomSpecList[y].laserMitochondrialSummary,
  258. lssueFeeSummary: res.rows[i].skuSpecList[j].bomSpecList[y].lssueFeeSummary,
  259. deliveryMaterialsFeeSummary: res.rows[i].skuSpecList[j].bomSpecList[y].deliveryMaterialsFeeSummary,
  260. packingLaborSummary: res.rows[i].skuSpecList[j].bomSpecList[y].packingLaborSummary,
  261. managementFeeSummary: res.rows[i].skuSpecList[j].bomSpecList[y].managementFeeSummary,
  262. proofingFeeSummary: res.rows[i].skuSpecList[j].bomSpecList[y].proofingFeeSummary,
  263. unitPriceSKU: res.rows[i].skuSpecList[j].unitPrice,
  264. subtotal: res.rows[i].skuSpecList[j].subtotal,
  265. outerBoxPackingFee: res.rows[i].outerBoxPackingFee,
  266. total: res.rows[i].total,
  267. });
  268. }
  269. }
  270. }
  271. }
  272. }
  273. }
  274. sourceList.value.data = Object.freeze(mergeRow(list));
  275. sourceList.value.pagination.total = res.total;
  276. setTimeout(() => {
  277. loading.value = false;
  278. }, 200);
  279. });
  280. };
  281. const clickReset = () => {
  282. sourceList.value.pagination.type = 1;
  283. changeRadioGroup();
  284. };
  285. const changeRadioGroup = (item) => {
  286. let beginTime = "";
  287. let endTime = "";
  288. if (sourceList.value.pagination.type == 1) {
  289. beginTime = date.getYearFirstDay();
  290. endTime = date.getYearLastDay();
  291. } else if (sourceList.value.pagination.type == 2) {
  292. let days = date.getDaysNoTime(365);
  293. beginTime = days.startTime;
  294. endTime = days.endTime;
  295. } else if (sourceList.value.pagination.type == 3) {
  296. let days = date.getDaysNoTime(180);
  297. beginTime = days.startTime;
  298. endTime = days.endTime;
  299. } else if (sourceList.value.pagination.type == 4) {
  300. let days = date.getDaysNoTime(90);
  301. beginTime = days.startTime;
  302. endTime = days.endTime;
  303. }
  304. getList({ beginTime: beginTime, endTime: endTime, ...item });
  305. };
  306. changeRadioGroup();
  307. const handlePageChange = (val) => {
  308. changeRadioGroup({ pageNum: val });
  309. };
  310. const handleSizeChange = (val) => {
  311. changeRadioGroup({ pageNum: 1, pageSize: val });
  312. };
  313. const openFileList = ref(false);
  314. const clickExcel = () => {
  315. ElMessageBox.confirm("你是否确认此操作", "提示", {
  316. confirmButtonText: "确定",
  317. cancelButtonText: "取消",
  318. type: "warning",
  319. })
  320. .then(() => {
  321. proxy.postFile("/statementOfAccountMerge/exportSalesOutWarehouseDetails", sourceList.value.pagination).then(() => {
  322. ElMessage({ message: "导出成功", type: "success" });
  323. openFileList.value = true;
  324. });
  325. })
  326. .catch(() => {});
  327. };
  328. const clickExcelFile = () => {
  329. openFileList.value = true;
  330. };
  331. const objectSpanMethod = ({ rowIndex, columnIndex }) => {
  332. if ([0, 1, 2, 3, 4, 5, 6, 7, 8, 23, 24, 25, 26, 27].includes(columnIndex)) {
  333. let spanName = [
  334. "statementOfAccountTime",
  335. "departmentName",
  336. "shopName",
  337. "mesCode",
  338. "sellCode",
  339. "wlnCode",
  340. "skuSpecCode",
  341. "skuSpecName",
  342. "quantitySKU",
  343. "",
  344. "",
  345. "",
  346. "",
  347. "",
  348. "",
  349. "",
  350. "",
  351. "",
  352. "",
  353. "",
  354. "",
  355. "",
  356. "unitPriceSKU",
  357. "subtotal",
  358. "outerBoxPackingFee",
  359. "total",
  360. ];
  361. // 第一列的合并方法
  362. const row1 = sourceList.value.data[rowIndex][spanName[columnIndex] + "Span"];
  363. const colspan = sourceList.value.data[rowIndex][spanName[columnIndex] + "Dis"] ? 0 : 1;
  364. const rowspan = colspan === 1 ? row1 : 0;
  365. return {
  366. rowspan: rowspan,
  367. colspan: colspan,
  368. };
  369. }
  370. };
  371. </script>
  372. <style lang="scss" scoped></style>