浏览代码

事业部: 对账单,对账单报表

lxf 1 年之前
父节点
当前提交
4706abda0d

+ 227 - 0
src/views/subsidiary/finance/check-bill/index.vue

@@ -0,0 +1,227 @@
+<template>
+  <div>
+    <el-card class="box-card">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        :searchConfig="searchConfig"
+        highlight-current-row
+        @get-list="getList"
+        @clickReset="clickReset">
+        <template #timePeriod="{ item }">
+          <div>
+            <el-row>
+              <el-col :span="11">{{ item.timePeriod }}</el-col>
+              <el-col :span="2" style="text-align: center">-</el-col>
+              <el-col :span="11">{{ item.timePeriod }}</el-col>
+            </el-row>
+          </div>
+        </template>
+        <template #receiptFileList="{ item }">
+          <div>
+            <el-button type="primary" @click="clickReceiptFile(item)" v-if="item.receiptFileList && item.receiptFileList.length > 0" text>查看</el-button>
+          </div>
+        </template>
+        <template #proofFileList="{ item }">
+          <div>
+            <el-button type="primary" @click="clickProofFile(item)" v-if="item.proofFileList && item.proofFileList.length > 0" text>查看</el-button>
+          </div>
+        </template>
+      </byTable>
+    </el-card>
+
+    <el-dialog :title="title" v-if="open" v-model="open" width="600">
+      <div v-if="fileList && fileList.length > 0">
+        <div v-for="(item, index) in fileList" :key="index" style="padding: 8px">
+          <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="openFile(item.fileUrl)">{{ item.fileName }}</a>
+        </div>
+      </div>
+      <template #footer>
+        <el-button @click="open = false" size="large">关 闭</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="94%">
+      <el-tabs v-model="activeName" class="demo-tabs">
+        <el-tab-pane label="SKU对账单" name="sku">
+          <PrintSKU :rowData="rowData" @clickCancel="openPrint = false" v-if="activeName === 'sku'"></PrintSKU>
+        </el-tab-pane>
+        <el-tab-pane label="BOM对账单" name="bom">
+          <PrintBOM :rowData="rowData" @clickCancel="openPrint = false" v-if="activeName === 'bom'"></PrintBOM>
+        </el-tab-pane>
+        <el-tab-pane label="订单对账单" name="order">
+          <PrintOrder :rowData="rowData" @clickCancel="openPrint = false" v-if="activeName === 'order'"></PrintOrder>
+        </el-tab-pane>
+      </el-tabs>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Check-bill">
+import byTable from "@/components/byTable/index";
+import PrintSKU from "@/views/group/finance/check-bill/printSKU.vue";
+import PrintBOM from "@/views/group/finance/check-bill/printBOM.vue";
+import PrintOrder from "@/views/group/finance/check-bill/printOrder.vue";
+
+const { proxy } = getCurrentInstance();
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    code: "",
+    departmentId: proxy.useUserStore().user.deptId,
+    beginTime: "",
+    endTime: "",
+  },
+});
+const loading = ref(false);
+const searchConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "code",
+      label: "对账单号",
+    },
+    {
+      type: "date",
+      propList: ["beginTime", "endTime"],
+      label: "对账日期",
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "对账单号",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "创建时间",
+        prop: "createTime",
+        width: 160,
+      },
+    },
+    {
+      attrs: {
+        label: "客户",
+        prop: "departmentName",
+      },
+    },
+    {
+      attrs: {
+        label: "对账金额",
+        prop: "amount",
+        align: "right",
+        width: 180,
+      },
+    },
+    {
+      attrs: {
+        label: "对账时间",
+        prop: "timePeriod",
+        align: "center",
+        width: 180,
+      },
+    },
+    {
+      attrs: {
+        label: "对账单",
+        slot: "receiptFileList",
+        align: "center",
+        width: 120,
+      },
+    },
+    {
+      attrs: {
+        label: "转账凭证",
+        slot: "proofFileList",
+        align: "center",
+        width: 120,
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: 80,
+        align: "center",
+        fixed: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "打印",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickPrint(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const getList = async (req, status) => {
+  if (status) {
+    sourceList.value.pagination = {
+      pageNum: sourceList.value.pagination.pageNum,
+      pageSize: sourceList.value.pagination.pageSize,
+    };
+  } else {
+    sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  }
+  loading.value = true;
+  proxy.post("/statementOfAccount/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getList();
+const clickReset = () => {
+  getList("", true);
+};
+const open = ref(false);
+const title = ref("");
+const fileList = ref([]);
+const clickReceiptFile = (row) => {
+  title.value = "对账单";
+  fileList.value = proxy.deepClone(row.receiptFileList);
+  open.value = true;
+};
+const clickProofFile = (row) => {
+  title.value = "转账凭证";
+  fileList.value = proxy.deepClone(row.proofFileList);
+  open.value = true;
+};
+const openFile = (path) => {
+  window.open(path);
+};
+const openPrint = ref(false);
+const rowData = ref({});
+const activeName = ref("sku");
+const clickPrint = (row) => {
+  activeName.value = "sku";
+  rowData.value = row;
+  openPrint.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-dialog) {
+  margin-top: 10px !important;
+  margin-bottom: 10px !important;
+}
+</style>

+ 208 - 0
src/views/subsidiary/finance/check-bill/printBOM.vue

@@ -0,0 +1,208 @@
+<template>
+  <div>
+    <el-card style="height: calc(100vh - 168px); overflow-y: auto; overflow-x: hidden" v-loading="loading">
+      <div id="tableId">
+        <el-table :data="tableData" border :row-style="{ height: '35px' }" header-row-class-name="tableHeader" show-summary :summary-method="getSummaries">
+          <el-table-column align="center">
+            <template #header>
+              <div style="text-align: center; font-size: 30px; padding: 8px">{{ props.rowData.departmentName }}-胜德体育对账单</div>
+              <div style="text-align: center; font-size: 18px; padding-bottom: 8px">( 对账时间: {{ rowData.timePeriod }} - {{ rowData.timePeriod }} )</div>
+            </template>
+            <el-table-column label="E10品号" prop="bomSpecCode" width="140" />
+            <el-table-column label="SKU品名" prop="bomSpecName" min-width="220" />
+            <el-table-column label="数量(PCS)" align="center" prop="quantity" width="130" />
+            <el-table-column label="BOM单价" align="center" prop="unitPrice" width="110" />
+            <el-table-column label="激光LOGO汇总" align="center" prop="laserLogoSummary" width="130" />
+            <el-table-column label="激光体位线汇总" align="center" prop="laserMitochondrialSummary" width="130" />
+            <el-table-column label="代发费汇总" align="center" prop="lssueFeeSummary" width="110" />
+            <el-table-column label="快递包材费汇总" align="center" prop="deliveryMaterialsFeeSummary" width="130" />
+            <el-table-column label="包装人工费汇总" align="center" prop="packingLaborSummary" width="130" />
+            <el-table-column label="小计" align="center" width="120">
+              <template #default="{ row }">
+                {{ moneyFormat(row.subtotal) }}
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" width="120">
+              <template #default="{ row }">
+                {{ moneyFormat(row.total) }}
+              </template>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div style="padding: 8px; text-align: center">
+        <el-button @click="clickCancel" size="large">关 闭</el-button>
+        <el-button type="primary" @click="deriveExcel()" size="large" v-preReClick>导 出</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+// import $ from "jquery";
+
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  rowData: Object,
+});
+const loading = ref(false);
+const tableData = ref([]);
+onMounted(() => {
+  if (props.rowData && props.rowData.id) {
+    loading.value = true;
+    proxy.post("/statementOfAccount/getDocumentByBom", { id: props.rowData.id }).then(
+      (res) => {
+        tableData.value = Object.freeze(res);
+        loading.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loading.value = false;
+      }
+    );
+  }
+});
+const labelList = ref({
+  2: "quantity",
+  4: "laserLogoSummary",
+  5: "laserMitochondrialSummary",
+  6: "lssueFeeSummary",
+  7: "deliveryMaterialsFeeSummary",
+  8: "packingLaborSummary",
+  9: "subtotal",
+  10: "total",
+});
+const textList = ref({
+  1: "胜德体育总经理:",
+  2: "申请日期:",
+});
+const getSummaries = ({ columns, data }) => {
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = h("div", { class: "" }, [
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "总计:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "备注:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "交货地点:",
+        }),
+        h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px" }, innerHTML: "申请人:" }),
+      ]);
+      return;
+    } else {
+      sums[index] = h("div", { class: "" }, [
+        [1, 3].includes(index)
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: getTotal(labelList.value[index]),
+            }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        [1, 2].includes(index)
+          ? h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px", "text-align": "left" }, innerHTML: textList.value[index] })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 0 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            }),
+      ]);
+      return;
+    }
+  });
+  return sums;
+};
+const getTotal = (label) => {
+  let list = tableData.value.map((item) => item[label]);
+  return Number(Math.round(list.reduce((acc, curr) => acc + curr, 0) * 100) / 100);
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", "");
+};
+const deriveExcel = () => {
+  proxy.getFile("/statementOfAccount/exportDocumentByBom", { id: props.rowData.id }).then((res) => {
+    proxy.downloadFile(res, "BOM对账单.xlsx");
+  });
+  // $("#tableId").table2excel({
+  //   exclude: ".noExl",
+  //   sheetName: "BOM对账单",
+  //   filename: "BOM对账单",
+  //   exclude_img: false,
+  //   exclude_links: false,
+  //   exclude_inputs: true,
+  // });
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-table thead.is-group th.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table__footer-wrapper tbody td.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table .el-table__cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .el-table__cell) {
+  border-right: 0px;
+}
+</style>

+ 308 - 0
src/views/subsidiary/finance/check-bill/printOrder.vue

@@ -0,0 +1,308 @@
+<template>
+  <div>
+    <el-card style="height: calc(100vh - 168px); overflow-y: auto; overflow-x: hidden" v-loading="loading">
+      <div id="tableId">
+        <el-table
+          :data="tableData"
+          border
+          :row-style="{ height: '35px' }"
+          header-row-class-name="tableHeader"
+          show-summary
+          :summary-method="getSummaries"
+          :span-method="objectSpanMethod"
+          max-height="calc(100vh - 79px)">
+          <el-table-column align="center">
+            <template #header>
+              <div style="text-align: center; font-size: 30px; padding: 8px">{{ props.rowData.departmentName }}-胜德体育对账单</div>
+              <div style="text-align: center; font-size: 18px; padding-bottom: 8px">( 对账时间: {{ rowData.timePeriod }} - {{ rowData.timePeriod }} )</div>
+            </template>
+            <el-table-column label="订单时间" prop="wlnCreateTime" align="center" width="160" />
+            <el-table-column label="订单号" prop="code" width="180" />
+            <el-table-column label="万里牛单号" prop="wlnCode" width="140" />
+            <el-table-column label="SKU单号" prop="skuSpecCode" width="140" />
+            <el-table-column label="SKU品号" prop="skuSpecName" width="180" />
+            <el-table-column label="SKU数量" prop="quantitySKU" width="100" />
+            <el-table-column label="BOM品号" prop="bomSpecCode" width="140" />
+            <el-table-column label="BOM品名" prop="bomSpecName" width="240" />
+            <el-table-column label="BOM数量" prop="quantityBOM" width="100" />
+            <el-table-column label="单价" prop="unitPriceBOM" width="100" />
+            <el-table-column label="激光LOGO" prop="laserLogoSummary" width="100" />
+            <el-table-column label="激光体位线" prop="laserMitochondrialSummary" width="100" />
+            <el-table-column label="代发费" prop="lssueFeeSummary" width="100" />
+            <el-table-column label="快递包材费" prop="deliveryMaterialsFeeSummary" width="100" />
+            <el-table-column label="包装人工费" prop="packingLaborSummary" width="100" />
+            <el-table-column label="SKU单价" prop="unitPriceSKU" width="100" />
+            <el-table-column label="小计" align="center" width="120">
+              <template #default="{ row }">
+                {{ moneyFormat(row.subtotal) }}
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" width="120">
+              <template #default="{ row }">
+                {{ moneyFormat(row.total) }}
+              </template>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div style="padding: 8px; text-align: center">
+        <el-button @click="clickCancel" size="large">关 闭</el-button>
+        <el-button type="primary" @click="deriveExcel()" size="large" v-preReClick>导 出</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+// import $ from "jquery";
+
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  rowData: Object,
+});
+const loading = ref(false);
+const tableData = ref([]);
+const total = ref(0);
+onMounted(() => {
+  if (props.rowData && props.rowData.id) {
+    loading.value = true;
+    proxy.post("/statementOfAccount/getDocumentByOrder", { id: props.rowData.id }).then(
+      (res) => {
+        let list = [];
+        if (res && res.length > 0) {
+          for (let i = 0; i < res.length; i++) {
+            if (res[i].skuSpecList && res[i].skuSpecList.length > 0) {
+              for (let j = 0; j < res[i].skuSpecList.length; j++) {
+                if (res[i].skuSpecList[j].total) {
+                  total.value = Number(Math.round((total.value + res[i].skuSpecList[j].total) * 100) / 100);
+                }
+                if (res[i].skuSpecList[j].bomSpecList && res[i].skuSpecList[j].bomSpecList.length > 0) {
+                  for (let x = 0; x < res[i].skuSpecList[j].bomSpecList.length; x++) {
+                    list.push({
+                      orderId: res[i].orderId,
+                      wlnCreateTime: res[i].wlnCreateTime,
+                      code: res[i].code,
+                      wlnCode: res[i].wlnCode,
+                      orderSkuId: res[i].skuSpecList[j].orderSkuId,
+                      skuSpecId: res[i].skuSpecList[j].skuSpecId,
+                      skuSpecCode: res[i].skuSpecList[j].skuSpecCode,
+                      skuSpecName: res[i].skuSpecList[j].skuSpecName,
+                      quantitySKU: res[i].skuSpecList[j].quantity,
+                      unitPriceSKU: res[i].skuSpecList[j].unitPrice,
+                      subtotal: res[i].skuSpecList[j].subtotal,
+                      total: res[i].skuSpecList[j].total,
+                      bomSpecCode: res[i].skuSpecList[j].bomSpecList[x].bomSpecCode,
+                      bomSpecName: res[i].skuSpecList[j].bomSpecList[x].bomSpecName,
+                      quantityBOM: res[i].skuSpecList[j].bomSpecList[x].quantity,
+                      unitPriceBOM: res[i].skuSpecList[j].bomSpecList[x].unitPrice,
+                      laserLogoSummary: res[i].skuSpecList[j].bomSpecList[x].laserLogoSummary,
+                      laserMitochondrialSummary: res[i].skuSpecList[j].bomSpecList[x].laserMitochondrialSummary,
+                      lssueFeeSummary: res[i].skuSpecList[j].bomSpecList[x].lssueFeeSummary,
+                      deliveryMaterialsFeeSummary: res[i].skuSpecList[j].bomSpecList[x].deliveryMaterialsFeeSummary,
+                      packingLaborSummary: res[i].skuSpecList[j].bomSpecList[x].packingLaborSummary,
+                    });
+                  }
+                }
+              }
+            }
+          }
+        }
+        tableData.value = Object.freeze(mergeRow(list));
+        loading.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loading.value = false;
+      }
+    );
+  }
+});
+const mergeRow = (list) => {
+  for (let field in list[0]) {
+    let k = 0;
+    let i = 0;
+    while (k < list.length) {
+      list[k][field + "Span"] = 1;
+      list[k][field + "Dis"] = false;
+      for (i = k + 1; i <= list.length - 1; i++) {
+        if (
+          list[k][field] === list[i][field] &&
+          list[k].orderSkuId === list[i].orderSkuId &&
+          list[k].orderSkuId === list[i].orderSkuId &&
+          list[k].orderId === list[i].orderId
+        ) {
+          list[k][field + "Span"]++;
+          list[k][field + "Dis"] = false;
+          list[i][field + "Span"] = 1;
+          list[i][field + "Dis"] = true;
+        } else {
+          break;
+        }
+      }
+      k = i;
+    }
+  }
+  return list;
+};
+const textList = ref({
+  4: "胜德体育总经理:",
+  7: "申请日期:",
+});
+const getSummaries = ({ columns, data }) => {
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = h("div", { class: "" }, [
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "总计:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "备注:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "交货地点:",
+        }),
+        h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px" }, innerHTML: "申请人:" }),
+      ]);
+      return;
+    } else {
+      sums[index] = h("div", { class: "" }, [
+        index !== 17
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: total.value,
+            }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        [4, 7].includes(index)
+          ? h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px", "text-align": "left" }, innerHTML: textList.value[index] })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 0 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            }),
+      ]);
+      return;
+    }
+  });
+  return sums;
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", "");
+};
+const deriveExcel = () => {
+  proxy.getFile("/statementOfAccount/exportDocumentByOrder", { id: props.rowData.id }).then((res) => {
+    proxy.downloadFile(res, "订单对账单.xlsx");
+  });
+  // $("#tableId").table2excel({
+  //   exclude: ".noExl",
+  //   sheetName: "订单对账单",
+  //   filename: "订单对账单",
+  //   exclude_img: false,
+  //   exclude_links: false,
+  //   exclude_inputs: true,
+  // });
+};
+const objectSpanMethod = ({ rowIndex, columnIndex }) => {
+  if ([0, 1, 2, 3, 4, 5, 15, 16, 17].includes(columnIndex)) {
+    let spanName = [
+      "wlnCreateTime",
+      "code",
+      "wlnCode",
+      "skuSpecCode",
+      "skuSpecName",
+      "quantitySKU",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "unitPriceSKU",
+      "subtotal",
+      "total",
+    ];
+    // 第一列的合并方法
+    const row1 = tableData.value[rowIndex][spanName[columnIndex] + "Span"];
+    const colspan = tableData.value[rowIndex][spanName[columnIndex] + "Dis"] ? 0 : 1;
+    const rowspan = colspan === 1 ? row1 : 0;
+    return {
+      rowspan: rowspan,
+      colspan: colspan,
+    };
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-table thead.is-group th.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table__footer-wrapper tbody td.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table .el-table__cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .el-table__cell) {
+  border-right: 0px;
+}
+</style>

+ 197 - 0
src/views/subsidiary/finance/check-bill/printSKU.vue

@@ -0,0 +1,197 @@
+<template>
+  <div>
+    <el-card style="height: calc(100vh - 168px); overflow-y: auto; overflow-x: hidden" v-loading="loading">
+      <div id="tableId">
+        <el-table :data="tableData" border :row-style="{ height: '35px' }" header-row-class-name="tableHeader" show-summary :summary-method="getSummaries">
+          <el-table-column align="center">
+            <template #header>
+              <div style="text-align: center; font-size: 30px; padding: 8px">{{ props.rowData.departmentName }}-胜德体育对账单</div>
+              <div style="text-align: center; font-size: 18px; padding-bottom: 8px">( 对账时间: {{ rowData.timePeriod }} - {{ rowData.timePeriod }} )</div>
+            </template>
+            <el-table-column label="SKU品号" prop="skuSpecCode" width="180" />
+            <el-table-column label="SKU品名" prop="skuSpecName" min-width="220" />
+            <el-table-column label="数量(PCS)" align="center" prop="quantity" width="160" />
+            <el-table-column label="SKU单价" align="center" prop="unitPrice" width="160" />
+            <el-table-column label="小计" align="center" width="180">
+              <template #default="{ row }">
+                {{ moneyFormat(row.subtotal) }}
+              </template>
+            </el-table-column>
+            <el-table-column label="合计" align="center" width="180">
+              <template #default="{ row }">
+                {{ moneyFormat(row.total) }}
+              </template>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div style="padding: 8px; text-align: center">
+        <el-button @click="clickCancel" size="large">关 闭</el-button>
+        <el-button type="primary" @click="deriveExcel()" size="large" v-preReClick>导 出</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+// import $ from "jquery";
+
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  rowData: Object,
+});
+const loading = ref(false);
+const tableData = ref([]);
+onMounted(() => {
+  if (props.rowData && props.rowData.id) {
+    loading.value = true;
+    proxy.post("/statementOfAccount/getDocumentBySku", { id: props.rowData.id }).then(
+      (res) => {
+        tableData.value = Object.freeze(res);
+        loading.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loading.value = false;
+      }
+    );
+  }
+});
+const labelList = ref({
+  2: "quantity",
+  5: "total",
+});
+const textList = ref({
+  1: "胜德体育总经理:",
+  2: "申请日期:",
+});
+const getSummaries = ({ columns, data }) => {
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = h("div", { class: "" }, [
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "总计:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "备注:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "交货地点:",
+        }),
+        h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px" }, innerHTML: "申请人:" }),
+      ]);
+      return;
+    } else {
+      sums[index] = h("div", { class: "" }, [
+        [1, 3, 4].includes(index)
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: getTotal(labelList.value[index]),
+            }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        [3, 4, 5].includes(index)
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 0 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px", "text-align": "left" }, innerHTML: textList.value[index] }),
+      ]);
+      return;
+    }
+  });
+  return sums;
+};
+const getTotal = (label) => {
+  let list = tableData.value.map((item) => item[label]);
+  return Number(Math.round(list.reduce((acc, curr) => acc + curr, 0) * 100) / 100);
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", "");
+};
+const deriveExcel = () => {
+  proxy.getFile("/statementOfAccount/exportDocumentBySku", { id: props.rowData.id }).then((res) => {
+    proxy.downloadFile(res, "SKU对账单.xlsx");
+  });
+  // $("#tableId").table2excel({
+  //   exclude: ".noExl",
+  //   sheetName: "SKU对账单",
+  //   filename: "SKU对账单",
+  //   exclude_img: false,
+  //   exclude_links: false,
+  //   exclude_inputs: true,
+  // });
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-table thead.is-group th.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table__footer-wrapper tbody td.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table .el-table__cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .el-table__cell) {
+  border-right: 0px;
+}
+</style>

+ 168 - 0
src/views/subsidiary/finance/summary/index.vue

@@ -0,0 +1,168 @@
+<template>
+  <div>
+    <el-card class="box-card">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        :searchConfig="searchConfig"
+        highlight-current-row
+        @get-list="getList"
+        @clickReset="clickReset">
+      </byTable>
+    </el-card>
+
+    <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="94%">
+      <el-tabs v-model="activeName" class="demo-tabs">
+        <el-tab-pane label="SKU对账单" name="sku">
+          <PrintSKU :idGroupConcat="idGroupConcat" @clickCancel="openPrint = false" v-if="activeName === 'sku'"></PrintSKU>
+        </el-tab-pane>
+        <el-tab-pane label="BOM对账单" name="bom">
+          <PrintBOM :idGroupConcat="idGroupConcat" @clickCancel="openPrint = false" v-if="activeName === 'bom'"></PrintBOM>
+        </el-tab-pane>
+        <el-tab-pane label="订单对账单" name="order">
+          <PrintOrder :idGroupConcat="idGroupConcat" @clickCancel="openPrint = false" v-if="activeName === 'order'"></PrintOrder>
+        </el-tab-pane>
+      </el-tabs>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+import PrintSKU from "@/views/group/finance/summary/printSKU.vue";
+import PrintBOM from "@/views/group/finance/summary/printBOM.vue";
+import PrintOrder from "@/views/group/finance/summary/printOrder.vue";
+
+const { proxy } = getCurrentInstance();
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    type: "1",
+    departmentId: proxy.useUserStore().user.deptId,
+    beginTime: "",
+    endTime: "",
+  },
+});
+const loading = ref(false);
+const searchConfig = computed(() => {
+  return [
+    {
+      type: "date",
+      propList: ["beginTime", "endTime"],
+      label: "日期",
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "维度",
+        prop: "dimensionality",
+      },
+    },
+    {
+      attrs: {
+        label: "客户",
+        prop: "departmentName",
+      },
+    },
+    {
+      attrs: {
+        label: "对账金额",
+        prop: "reconcilingAmount",
+        align: "right",
+      },
+      render(val) {
+        return proxy.moneyFormat(val);
+      },
+    },
+    {
+      attrs: {
+        label: "对账单数量",
+        prop: "quantityOfStatement",
+      },
+    },
+    {
+      attrs: {
+        label: "合同数量",
+        prop: "orderQuantity",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: 80,
+        align: "center",
+        fixed: "right",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "打印",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              clickPrint(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const getList = async (req, status) => {
+  if (status) {
+    sourceList.value.pagination = {
+      pageNum: sourceList.value.pagination.pageNum,
+      pageSize: sourceList.value.pagination.pageSize,
+    };
+  } else {
+    sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  }
+  loading.value = true;
+  proxy.post("/statementOfAccountMerge/page", sourceList.value.pagination).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      sourceList.value.data = res.rows.map((item) => {
+        return {
+          ...item,
+          isCheck: true,
+        };
+      });
+    } else {
+      sourceList.value.data = [];
+    }
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getList();
+const clickReset = () => {
+  getList("", true);
+};
+const openPrint = ref(false);
+const idGroupConcat = ref("");
+const activeName = ref("sku");
+const clickPrint = (row) => {
+  activeName.value = "sku";
+  idGroupConcat.value = row.idGroupConcat;
+  openPrint.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-dialog) {
+  margin-top: 10px !important;
+  margin-bottom: 10px !important;
+}
+</style>

+ 200 - 0
src/views/subsidiary/finance/summary/printBOM.vue

@@ -0,0 +1,200 @@
+<template>
+  <div>
+    <el-card style="height: calc(100vh - 168px); overflow-y: auto; overflow-x: hidden" v-loading="loading">
+      <div id="tableId">
+        <el-table :data="tableData" border :row-style="{ height: '35px' }" header-row-class-name="tableHeader" show-summary :summary-method="getSummaries">
+          <el-table-column label="E10品号" prop="bomSpecCode" width="140" />
+          <el-table-column label="SKU品名" prop="bomSpecName" min-width="220" />
+          <el-table-column label="数量(PCS)" align="center" prop="quantity" width="130" />
+          <el-table-column label="BOM单价" align="center" prop="unitPrice" width="110" />
+          <el-table-column label="激光LOGO汇总" align="center" prop="laserLogoSummary" width="130" />
+          <el-table-column label="激光体位线汇总" align="center" prop="laserMitochondrialSummary" width="130" />
+          <el-table-column label="代发费汇总" align="center" prop="lssueFeeSummary" width="110" />
+          <el-table-column label="快递包材费汇总" align="center" prop="deliveryMaterialsFeeSummary" width="130" />
+          <el-table-column label="包装人工费汇总" align="center" prop="packingLaborSummary" width="130" />
+          <el-table-column label="小计" align="center" width="120">
+            <template #default="{ row }">
+              {{ moneyFormat(row.subtotal) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="合计" align="center" width="120">
+            <template #default="{ row }">
+              {{ moneyFormat(row.total) }}
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div style="padding: 8px; text-align: center">
+        <el-button @click="clickCancel" size="large">关 闭</el-button>
+        <el-button type="primary" @click="deriveExcel()" size="large" v-preReClick>导 出</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  idGroupConcat: String,
+});
+const loading = ref(false);
+const tableData = ref([]);
+onMounted(() => {
+  if (props.idGroupConcat) {
+    loading.value = true;
+    proxy.post("/statementOfAccountMerge/getDocumentByBom", { idGroupConcat: props.idGroupConcat }).then(
+      (res) => {
+        tableData.value = Object.freeze(res);
+        loading.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loading.value = false;
+      }
+    );
+  }
+});
+const labelList = ref({
+  2: "quantity",
+  4: "laserLogoSummary",
+  5: "laserMitochondrialSummary",
+  6: "lssueFeeSummary",
+  7: "deliveryMaterialsFeeSummary",
+  8: "packingLaborSummary",
+  9: "subtotal",
+  10: "total",
+});
+const textList = ref({
+  1: "胜德体育总经理:",
+  2: "申请日期:",
+});
+const getSummaries = ({ columns, data }) => {
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = h("div", { class: "" }, [
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "总计:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "备注:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "交货地点:",
+        }),
+        h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px" }, innerHTML: "申请人:" }),
+      ]);
+      return;
+    } else {
+      sums[index] = h("div", { class: "" }, [
+        [1, 3].includes(index)
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: getTotal(labelList.value[index]),
+            }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        [1, 2].includes(index)
+          ? h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px", "text-align": "left" }, innerHTML: textList.value[index] })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 0 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            }),
+      ]);
+      return;
+    }
+  });
+  return sums;
+};
+const getTotal = (label) => {
+  let list = tableData.value.map((item) => item[label]);
+  return Number(Math.round(list.reduce((acc, curr) => acc + curr, 0) * 100) / 100);
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", "");
+};
+const deriveExcel = () => {
+  proxy.getFile("/statementOfAccount/exportDocumentByBom", { idGroupConcat: props.idGroupConcat }).then((res) => {
+    proxy.downloadFile(res, "BOM对账单.xlsx");
+  });
+  // $("#tableId").table2excel({
+  //   exclude: ".noExl",
+  //   sheetName: "BOM对账单",
+  //   filename: "BOM对账单",
+  //   exclude_img: false,
+  //   exclude_links: false,
+  //   exclude_inputs: true,
+  // });
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-table thead.is-group th.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table__footer-wrapper tbody td.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table .el-table__cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .el-table__cell) {
+  border-right: 0px;
+}
+</style>

+ 300 - 0
src/views/subsidiary/finance/summary/printOrder.vue

@@ -0,0 +1,300 @@
+<template>
+  <div>
+    <el-card style="height: calc(100vh - 168px); overflow-y: auto; overflow-x: hidden" v-loading="loading">
+      <div id="tableId">
+        <el-table
+          :data="tableData"
+          border
+          :row-style="{ height: '35px' }"
+          header-row-class-name="tableHeader"
+          show-summary
+          :summary-method="getSummaries"
+          :span-method="objectSpanMethod"
+          max-height="calc(100vh - 79px)">
+          <el-table-column label="订单时间" prop="wlnCreateTime" align="center" width="160" />
+          <el-table-column label="订单号" prop="code" width="180" />
+          <el-table-column label="万里牛单号" prop="wlnCode" width="140" />
+          <el-table-column label="SKU单号" prop="skuSpecCode" width="140" />
+          <el-table-column label="SKU品号" prop="skuSpecName" width="240" />
+          <el-table-column label="SKU数量" prop="quantitySKU" width="100" />
+          <el-table-column label="BOM品号" prop="bomSpecCode" width="140" />
+          <el-table-column label="BOM品名" prop="bomSpecName" width="300" />
+          <el-table-column label="BOM数量" prop="quantityBOM" width="100" />
+          <el-table-column label="单价" prop="unitPriceBOM" width="100" />
+          <el-table-column label="激光LOGO" prop="laserLogoSummary" width="100" />
+          <el-table-column label="激光体位线" prop="laserMitochondrialSummary" width="100" />
+          <el-table-column label="代发费" prop="lssueFeeSummary" width="100" />
+          <el-table-column label="快递包材费" prop="deliveryMaterialsFeeSummary" width="100" />
+          <el-table-column label="包装人工费" prop="packingLaborSummary" width="100" />
+          <el-table-column label="SKU单价" prop="unitPriceSKU" width="100" />
+          <el-table-column label="小计" align="center" width="120">
+            <template #default="{ row }">
+              {{ moneyFormat(row.subtotal) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="合计" align="center" width="120">
+            <template #default="{ row }">
+              {{ moneyFormat(row.total) }}
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div style="padding: 8px; text-align: center">
+        <el-button @click="clickCancel" size="large">关 闭</el-button>
+        <el-button type="primary" @click="deriveExcel()" size="large" v-preReClick>导 出</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  idGroupConcat: String,
+});
+const loading = ref(false);
+const tableData = ref([]);
+const total = ref(0);
+onMounted(() => {
+  if (props.idGroupConcat) {
+    loading.value = true;
+    proxy.post("/statementOfAccountMerge/getDocumentByOrder", { idGroupConcat: props.idGroupConcat }).then(
+      (res) => {
+        let list = [];
+        if (res && res.length > 0) {
+          for (let i = 0; i < res.length; i++) {
+            if (res[i].skuSpecList && res[i].skuSpecList.length > 0) {
+              for (let j = 0; j < res[i].skuSpecList.length; j++) {
+                if (res[i].skuSpecList[j].total) {
+                  total.value = Number(Math.round((total.value + res[i].skuSpecList[j].total) * 100) / 100);
+                }
+                if (res[i].skuSpecList[j].bomSpecList && res[i].skuSpecList[j].bomSpecList.length > 0) {
+                  for (let x = 0; x < res[i].skuSpecList[j].bomSpecList.length; x++) {
+                    list.push({
+                      orderId: res[i].orderId,
+                      wlnCreateTime: res[i].wlnCreateTime,
+                      code: res[i].code,
+                      wlnCode: res[i].wlnCode,
+                      orderSkuId: res[i].skuSpecList[j].orderSkuId,
+                      skuSpecId: res[i].skuSpecList[j].skuSpecId,
+                      skuSpecCode: res[i].skuSpecList[j].skuSpecCode,
+                      skuSpecName: res[i].skuSpecList[j].skuSpecName,
+                      quantitySKU: res[i].skuSpecList[j].quantity,
+                      unitPriceSKU: res[i].skuSpecList[j].unitPrice,
+                      subtotal: res[i].skuSpecList[j].subtotal,
+                      total: res[i].skuSpecList[j].total,
+                      bomSpecCode: res[i].skuSpecList[j].bomSpecList[x].bomSpecCode,
+                      bomSpecName: res[i].skuSpecList[j].bomSpecList[x].bomSpecName,
+                      quantityBOM: res[i].skuSpecList[j].bomSpecList[x].quantity,
+                      unitPriceBOM: res[i].skuSpecList[j].bomSpecList[x].unitPrice,
+                      laserLogoSummary: res[i].skuSpecList[j].bomSpecList[x].laserLogoSummary,
+                      laserMitochondrialSummary: res[i].skuSpecList[j].bomSpecList[x].laserMitochondrialSummary,
+                      lssueFeeSummary: res[i].skuSpecList[j].bomSpecList[x].lssueFeeSummary,
+                      deliveryMaterialsFeeSummary: res[i].skuSpecList[j].bomSpecList[x].deliveryMaterialsFeeSummary,
+                      packingLaborSummary: res[i].skuSpecList[j].bomSpecList[x].packingLaborSummary,
+                    });
+                  }
+                }
+              }
+            }
+          }
+        }
+        tableData.value = Object.freeze(mergeRow(list));
+        loading.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loading.value = false;
+      }
+    );
+  }
+});
+const mergeRow = (list) => {
+  for (let field in list[0]) {
+    let k = 0;
+    let i = 0;
+    while (k < list.length) {
+      list[k][field + "Span"] = 1;
+      list[k][field + "Dis"] = false;
+      for (i = k + 1; i <= list.length - 1; i++) {
+        if (
+          list[k][field] === list[i][field] &&
+          list[k].orderSkuId === list[i].orderSkuId &&
+          list[k].orderSkuId === list[i].orderSkuId &&
+          list[k].orderId === list[i].orderId
+        ) {
+          list[k][field + "Span"]++;
+          list[k][field + "Dis"] = false;
+          list[i][field + "Span"] = 1;
+          list[i][field + "Dis"] = true;
+        } else {
+          break;
+        }
+      }
+      k = i;
+    }
+  }
+  return list;
+};
+const textList = ref({
+  4: "胜德体育总经理:",
+  7: "申请日期:",
+});
+const getSummaries = ({ columns, data }) => {
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = h("div", { class: "" }, [
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "总计:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "备注:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "交货地点:",
+        }),
+        h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px" }, innerHTML: "申请人:" }),
+      ]);
+      return;
+    } else {
+      sums[index] = h("div", { class: "" }, [
+        index !== 17
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: total.value,
+            }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        [4, 7].includes(index)
+          ? h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px", "text-align": "left" }, innerHTML: textList.value[index] })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 0 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            }),
+      ]);
+      return;
+    }
+  });
+  return sums;
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", "");
+};
+const deriveExcel = () => {
+  proxy.getFile("/statementOfAccountMerge/exportDocumentByOrder", { idGroupConcat: props.idGroupConcat }).then((res) => {
+    proxy.downloadFile(res, "订单对账单.xlsx");
+  });
+  // $("#tableId").table2excel({
+  //   exclude: ".noExl",
+  //   sheetName: "订单对账单",
+  //   filename: "订单对账单",
+  //   exclude_img: false,
+  //   exclude_links: false,
+  //   exclude_inputs: true,
+  // });
+};
+const objectSpanMethod = ({ rowIndex, columnIndex }) => {
+  if ([0, 1, 2, 3, 4, 5, 15, 16, 17].includes(columnIndex)) {
+    let spanName = [
+      "wlnCreateTime",
+      "code",
+      "wlnCode",
+      "skuSpecCode",
+      "skuSpecName",
+      "quantitySKU",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "",
+      "unitPriceSKU",
+      "subtotal",
+      "total",
+    ];
+    // 第一列的合并方法
+    const row1 = tableData.value[rowIndex][spanName[columnIndex] + "Span"];
+    const colspan = tableData.value[rowIndex][spanName[columnIndex] + "Dis"] ? 0 : 1;
+    const rowspan = colspan === 1 ? row1 : 0;
+    return {
+      rowspan: rowspan,
+      colspan: colspan,
+    };
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-table thead.is-group th.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table__footer-wrapper tbody td.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table .el-table__cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .el-table__cell) {
+  border-right: 0px;
+}
+</style>

+ 189 - 0
src/views/subsidiary/finance/summary/printSKU.vue

@@ -0,0 +1,189 @@
+<template>
+  <div>
+    <el-card style="height: calc(100vh - 168px); overflow-y: auto; overflow-x: hidden" v-loading="loading">
+      <div id="tableId">
+        <el-table :data="tableData" border :row-style="{ height: '35px' }" header-row-class-name="tableHeader" show-summary :summary-method="getSummaries">
+          <el-table-column label="SKU品号" prop="skuSpecCode" width="180" />
+          <el-table-column label="SKU品名" prop="skuSpecName" min-width="220" />
+          <el-table-column label="数量(PCS)" align="center" prop="quantity" width="160" />
+          <el-table-column label="SKU单价" align="center" prop="unitPrice" width="160" />
+          <el-table-column label="小计" align="center" width="180">
+            <template #default="{ row }">
+              {{ moneyFormat(row.subtotal) }}
+            </template>
+          </el-table-column>
+          <el-table-column label="合计" align="center" width="180">
+            <template #default="{ row }">
+              {{ moneyFormat(row.total) }}
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div style="padding: 8px; text-align: center">
+        <el-button @click="clickCancel" size="large">关 闭</el-button>
+        <el-button type="primary" @click="deriveExcel()" size="large" v-preReClick>导 出</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  idGroupConcat: String,
+});
+const loading = ref(false);
+const tableData = ref([]);
+onMounted(() => {
+  if (props.idGroupConcat) {
+    loading.value = true;
+    proxy.post("/statementOfAccountMerge/getDocumentBySku", { idGroupConcat: props.idGroupConcat }).then(
+      (res) => {
+        tableData.value = Object.freeze(res);
+        loading.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loading.value = false;
+      }
+    );
+  }
+});
+const labelList = ref({
+  2: "quantity",
+  5: "total",
+});
+const textList = ref({
+  1: "胜德体育总经理:",
+  2: "申请日期:",
+});
+const getSummaries = ({ columns, data }) => {
+  const sums = [];
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = h("div", { class: "" }, [
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "总计:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "备注:",
+        }),
+        h("div", {
+          style: { "text-align": "center", "border-style": "solid", "border-width": "0 1px 1px 0", "border-color": "#ebeef5", padding: "0 12px" },
+          innerHTML: "交货地点:",
+        }),
+        h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px" }, innerHTML: "申请人:" }),
+      ]);
+      return;
+    } else {
+      sums[index] = h("div", { class: "" }, [
+        [1, 3, 4].includes(index)
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 1px 1px 0",
+                "border-color": "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: getTotal(labelList.value[index]),
+            }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        h("div", {
+          style: {
+            "text-align": "center",
+            "border-style": "solid",
+            "border-width": "0 0 1px 0",
+            "border-color": "#ebeef5",
+            color: "#ebeef5",
+            padding: "0 12px",
+            height: "35px",
+          },
+          innerHTML: ".",
+        }),
+        [3, 4, 5].includes(index)
+          ? h("div", {
+              style: {
+                "text-align": "center",
+                "border-style": "solid",
+                "border-width": "0 0 1px 0",
+                "border-color": "#ebeef5",
+                color: "#ebeef5",
+                padding: "0 12px",
+                height: "35px",
+              },
+              innerHTML: ".",
+            })
+          : h("div", { style: { "font-size": "16px", "font-weight": 700, padding: "0 12px", "text-align": "left" }, innerHTML: textList.value[index] }),
+      ]);
+      return;
+    }
+  });
+  return sums;
+};
+const getTotal = (label) => {
+  let list = tableData.value.map((item) => item[label]);
+  return Number(Math.round(list.reduce((acc, curr) => acc + curr, 0) * 100) / 100);
+};
+const emit = defineEmits(["clickCancel"]);
+const clickCancel = () => {
+  emit("clickCancel", "");
+};
+const deriveExcel = () => {
+  proxy.getFile("/statementOfAccountMerge/exportDocumentBySku", { idGroupConcat: props.idGroupConcat }).then((res) => {
+    proxy.downloadFile(res, "SKU对账单.xlsx");
+  });
+  // $("#tableId").table2excel({
+  //   exclude: ".noExl",
+  //   sheetName: "SKU对账单",
+  //   filename: "SKU对账单",
+  //   exclude_img: false,
+  //   exclude_links: false,
+  //   exclude_inputs: true,
+  // });
+};
+</script>
+
+<style lang="scss" scoped>
+::v-deep(.el-table thead.is-group th.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table__footer-wrapper tbody td.el-table__cell) {
+  background-color: white !important;
+}
+::v-deep(.el-table .el-table__cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .cell) {
+  padding: 0;
+}
+::v-deep(.el-table__footer .el-table__cell) {
+  border-right: 0px;
+}
+</style>