index.vue 13 KB

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