cz před 11 měsíci
rodič
revize
dcd1ff1479

+ 54 - 4
src/components/process/SF/CostControl.vue

@@ -409,7 +409,7 @@
                 </div>
               </template>
             </el-table-column> -->
-            <el-table-column label="核算项目名称" width="200" prop="accountSubjectsNames" v-if="isShowAtt('accountSubjectsId','detailObj')">
+            <el-table-column label="记账科目名称" width="200" prop="accountSubjectsNames" v-if="isShowAtt('accountSubjectsId','detailObj')">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
                   <el-input v-model="row.accountSubjectsNames" placeholder=" ">
@@ -418,20 +418,21 @@
               </template>
             </el-table-column>
 
-            <el-table-column label="核算项目" width="200" prop="subjectsCalculateItemNameList" v-if="isShowAtt('accountSubjectsId','detailObj')">
+            <el-table-column label="核算项目名称" width="200" prop="subjectsCalculateItemNameList" v-if="isShowAtt('accountSubjectsId','detailObj')">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
                   <div v-for="(key,index) in row.subjectsCalculateItemNameList" :key="key"
                        :style="{ marginBottom:row.subjectsCalculateItemNameList.length > index+1  ? '10px' : '' }">
                     <el-tree-select v-model="row.submitMapData[key]" :data="selectDataMap[key]" check-strictly node-key="deptId"
                                     :props="defaultPropsDept" :placeholder="'请选择'+key" style="width:100%" filterable
-                                    v-if="['核算中心', '部门' ].includes(key)" />
+                                    v-if="['核算中心', '部门' ].includes(key)" @change="(val)=>getLabelData(val,key,$index)" />
                     <div v-else-if="['客户'].includes(key)">
                       <el-button type="primary" @click="handleOpenSelectCustomer($index)" plain v-if="getAccountSubjectsId"
                                  style="margin-bottom:10px">选择客户</el-button>
                       <el-input v-model="row.customerName" placeholder="请选择客户" disabled></el-input>
                     </div>
-                    <el-select v-model="row.submitMapData[key]" :placeholder="'请选择'+key" style="width: 100%" filterable v-else>
+                    <el-select v-model="row.submitMapData[key]" :placeholder="'请选择'+key" style="width: 100%" filterable v-else
+                               @change="(val)=>getLabelData(val,key,$index)">
                       <el-option v-for="item in selectDataMap[key]" :key="item.value" :label="item.label" :value="item.value" />
                     </el-select>
                   </div>
@@ -1816,6 +1817,7 @@ const clickAdd = () => {
       accountSubjectsNames: accountSubjectsNames.value,
       subjectsCalculateItemNameList: subjectsCalculateItemNameList.value,
       submitMapData: {},
+      submitMapLabelData: {},
       logisticsCompanyId: "",
       invoiceTaxPoint: "",
       currentPayable: null,
@@ -1853,6 +1855,7 @@ const clickAdd = () => {
         accountSubjectsNames: accountSubjectsNames.value,
         subjectsCalculateItemNameList: subjectsCalculateItemNameList.value,
         submitMapData: {},
+        submitMapLabelData: {},
         logisticsCompanyId: "",
         invoiceTaxPoint: "",
         currentPayable: null,
@@ -1894,6 +1897,46 @@ const selectCustomer = (row) => {
   proxy.msgTip("选择成功");
 };
 
+function findNodeById(treeData, nodeId) {
+  // 遍历当前层级的所有节点
+  for (let i = 0; i < treeData.length; i++) {
+    let node = treeData[i];
+    // 如果当前节点的 ID 匹配目标节点的 ID,则返回当前节点
+    if (node.deptId === nodeId) {
+      return node;
+    }
+    // 如果当前节点有子节点,则递归调用当前函数继续查找子节点
+    if (node.children && node.children.length > 0) {
+      let foundNode = findNodeById(node.children, nodeId);
+      // 如果在子节点中找到了目标节点,则返回找到的节点
+      if (foundNode) {
+        return foundNode;
+      }
+    }
+  }
+  // 如果遍历完所有节点仍未找到目标节点,则返回 null
+  return null;
+}
+
+const getLabelData = (val, key, index) => {
+  if ((val, key)) {
+    let data = selectDataMap.value[key];
+    if (["核算中心", "部门"].includes(key)) {
+      let current = findNodeById(data, val);
+      if (current) {
+        formData.data.costControlDetailList[index].submitMapLabelData[key] =
+          current.deptName;
+      }
+    } else {
+      let current = data.find((x) => x.value == val);
+      if (current) {
+        formData.data.costControlDetailList[index].submitMapLabelData[key] =
+          current.label;
+      }
+    }
+  }
+};
+
 const getOutboundFile = async () => {
   let ids = formData.data.contractOutboundInfoList.map((x) => x.id);
   const allFile = await proxy.getFileData({
@@ -2021,6 +2064,7 @@ const handleSubmit = async (isStag = false) => {
       for (let i = 0; i < formData.data.costControlDetailList.length; i++) {
         const row = formData.data.costControlDetailList[i];
         let calculateItemList = [];
+        let calculateItemStr = row.accountSubjectsNames + " - ";
         if (
           row.subjectsCalculateItemNameList &&
           row.subjectsCalculateItemNameList.length > 0
@@ -2032,9 +2076,15 @@ const handleSubmit = async (isStag = false) => {
                 type: key,
                 businessId: row.submitMapData[key],
               });
+              calculateItemStr +=
+                row.submitMapLabelData[key] +
+                (j < row.subjectsCalculateItemNameList.length - 1 ? " - " : "");
             }
           }
         }
+        if (!route.query.processType) {
+          row.calculateItemStr = calculateItemStr;
+        }
         row.calculateItemList = calculateItemList;
       }
       if (Array.isArray(formData.data.companyId)) {

+ 788 - 0
src/views/report/accountBalance/index.vue

@@ -0,0 +1,788 @@
+<template>
+  <div class="pageIndexClass">
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :selectConfig="selectConfig" :config="config" highlight-current-row
+               :action-list="[{
+                text: '导出Excel',
+                action: () => exportExcel(),
+                disabled: false,
+              }
+        ]" @get-list="getList" :hideTable="true" :hidePagination="true">
+        <template #code="{item}">
+          <div style="width:100%">
+            <span class="el-click" @click="getDtl(item)">{{item.code}}</span>
+          </div>
+        </template>
+      </byTable>
+      <div style="padding:0 15px;background:#fff">
+        <el-table :data="sourceList.data" :height="tableHeight" style="width: 100%;margin-top:-10px" v-loading="loading" border
+                  :span-method="objectSpanMethod" :row-class-name="getRowClass" id="my-table">
+          <el-table-column prop="subjectsCode" label="科目代码" width="120" fixed="left">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                <span v-if="$index < sourceList.data.length - 1"> {{row.subjectsCode}}</span>
+                <div style="text-align:right" v-else>
+                  合计:
+                </div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="subjectsName" label="科目名称" width="90" fixed="left" />
+          <el-table-column prop="calculateItemStr" label="核算项目" min-width="150" fixed="left" />
+          <el-table-column prop="yearBeginBalance" label="年初余额" width="90" fixed="left" align="right">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.yearBeginBalance,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <template v-if="monthList && monthList.length>0">
+            <el-table-column v-for="col in monthList" :key="col.key" :label="col.label" width="90" align="left">
+              <template #default="{ row, $index }">
+                <div style="width: 100%" v-if="row['month'+col.key+'Amount']">
+                  {{moneyFormat(row['month'+col.key+'Amount'],2)}}
+                </div>
+              </template>
+            </el-table-column>
+          </template>
+          <el-table-column prop="tradeAmount" label="本期发生" width="90" align="right">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.tradeAmount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="balanceAmount" label="余额" width="90" align="right">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.balanceAmount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+    </div>
+
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="60%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
+
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import moment from "moment";
+import FileSaver from "file-saver";
+import * as XLSX from "xlsx";
+
+const { proxy } = getCurrentInstance();
+const tableHeight = ref(0);
+const getTableHeight = () => {
+  tableHeight.value = window.innerHeight - 150 - 30;
+};
+getTableHeight();
+window.addEventListener("resize", () => {
+  getTableHeight();
+});
+const sealType = computed(() => proxy.useUserStore().allDict["seal_type"]);
+const userList = ref([]);
+const deptData = ref([]);
+const typeData = ref([
+  {
+    label: "收入",
+    value: "10",
+  },
+  {
+    label: "支出",
+    value: "20",
+  },
+]);
+const monthList = ref([
+  { key: 1, label: "1月" },
+  { key: 2, label: "2月" },
+  { key: 3, label: "3月" },
+  { key: 4, label: "4月" },
+  { key: 5, label: "5月" },
+  { key: 6, label: "6月" },
+  { key: 7, label: "7月" },
+  { key: 8, label: "8月" },
+  { key: 9, label: "9月" },
+  { key: 10, label: "10月" },
+  { key: 11, label: "11月" },
+  { key: 12, label: "12月" },
+]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    year: moment().format("yyyy"),
+  },
+});
+const loading = ref(false);
+const statusData = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "审批驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "作废",
+    value: 88,
+  },
+]);
+const processingMethod = ref([
+  {
+    dictKey: 10,
+    dictValue: "业务自采",
+  },
+  {
+    dictKey: 20,
+    dictValue: "生产处理",
+  },
+]);
+
+const contractType = ref([
+  {
+    dictKey: "3",
+    dictValue: "打样订单",
+  },
+  {
+    dictKey: "2",
+    dictValue: "内销订单",
+  },
+  {
+    dictKey: "1",
+    dictValue: "外贸订单(退税)",
+  },
+  {
+    dictKey: "4",
+    dictValue: "外贸订单(不退税)",
+  },
+]);
+const selectConfig = computed(() => {
+  return [
+    {
+      type: "time",
+      itemType: "year",
+      label: "年份",
+      placeholder: "请选择",
+      prop: "year",
+      placeholderOne: "",
+      propOne: "",
+      clearable: false,
+      fn: () => {
+        getList();
+      },
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "订单编号",
+        slot: "code",
+      },
+    },
+
+    // {
+    //   attrs: {
+    //     label: "印章类型",
+    //     prop: "type",
+    //   },
+    //   render(val) {
+    //     return proxy.dictKeyValue(val, sealType.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "业务员",
+        prop: "createUserName",
+      },
+    },
+    {
+      attrs: {
+        label: "跟单员",
+        prop: "applyTime",
+      },
+    },
+    {
+      attrs: {
+        label: "订单类型",
+        prop: "contractType",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, contractType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "订单处理方式",
+        prop: "processingMethod",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, processingMethod.value);
+      },
+    },
+    {
+      attrs: {
+        label: "销售金额",
+        prop: "deptName",
+      },
+    },
+    {
+      attrs: {
+        label: "订单出货金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "出货申请出货金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "已收定金",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "是否可结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "是否已结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户名称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户简称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "应收金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "收款金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "未收金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "出货日期",
+        prop: "amount",
+      },
+    },
+    {
+      attrs: {
+        label: "账龄级别",
+        prop: "amount",
+      },
+    },
+    // {
+    //   attrs: {
+    //     label: "审批状态",
+    //     prop: "status",
+    //     width: 100,
+    //   },
+    //   render(type) {
+    //     return proxy.dictValueLabel(type, statusData.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+      },
+      renderHTML(row) {
+        return row.createUser == proxy.useUserStore().user.userId
+          ? [
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "修改",
+                      type: "primary",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      clickUpdate(row);
+                    },
+                  }
+                : {},
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "删除",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/delete", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+              row.status == 10 || row.status == 30
+                ? {
+                    attrs: {
+                      label: "作废",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/cancellation", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+            ]
+          : [];
+      },
+    },
+  ];
+});
+const corporationList = ref([]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/report/finance/subjectBalance", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+const getDeptData = (val) => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      pageSize: 9999,
+      keyword: "",
+      ancestors: proxy.useUserStore().user.companyId,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // type: 2,
+    })
+    .then((res) => {
+      deptData.value = proxy.handleTree(res.data, "deptId");
+    });
+};
+// getDeptData();
+const modalType = ref("add");
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "印章名称",
+      required: true,
+      itemWidth: 50,
+      itemType: "text",
+    },
+    {
+      type: "select",
+      prop: "sealType",
+      label: "印章类型",
+      data: sealType.value,
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "applyUserId",
+      label: "存管人员",
+      required: true,
+      filterable: true,
+      data: userList.value,
+      itemWidth: 50,
+      fn: (val) => {
+        let current = userList.value.find((x) => x.value == val);
+        console.log(current, "ada");
+        if (current) {
+          formData.data.deptId = current.deptId;
+        }
+      },
+    },
+    {
+      type: "treeSelect",
+      prop: "deptId",
+      label: "存管部门",
+      data: deptData.value,
+      propsTreeLabel: "deptName",
+      propsTreeValue: "deptId",
+      itemWidth: 50,
+      disabled: 50,
+    },
+    {
+      type: "input",
+      prop: "accountNumber",
+      label: "印章用途",
+      itemWidth: 100,
+      itemType: "textarea",
+    },
+  ];
+});
+const rules = ref({
+  name: [{ required: true, message: "请输入承包商", trigger: "blur" }],
+  taxPoints: [{ required: true, message: "请输入税点", trigger: "blur" }],
+  accountBank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
+  accountName: [{ required: true, message: "请输入开户名", trigger: "blur" }],
+  accountNumber: [{ required: true, message: "请输入账号", trigger: "blur" }],
+});
+const formData = reactive({
+  data: {
+    accountRemainderList: [{ currency: "", remainder: undefined }],
+  },
+});
+const openModal = (val) => {
+  // modalType.value = val;
+  // formData.data = {
+  //   accountRemainderList: [{ currency: "", remainder: undefined }],
+  // };
+  // loadingDialog.value = false;
+  // dialogVisible.value = true;
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+    },
+  });
+};
+const clickBalance = () => {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
+    formData.data.accountRemainderList.push({
+      currency: "",
+      remainder: undefined,
+    });
+  } else {
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
+  }
+};
+const handleRemove = (index) => {
+  formData.data.accountRemainderList.splice(index, 1);
+};
+const isRepeat = (arr) => {
+  var hash = {};
+  for (var i in arr) {
+    if (hash[arr[i].currency]) return true;
+    hash[arr[i].currency] = true;
+  }
+  return false;
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/contractor/" + modalType.value, formData.data).then(
+      () => {
+        proxy.msgTip("操作成功", 1);
+        dialogVisible.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+    // if (
+    //   formData.data.accountRemainderList &&
+    //   formData.data.accountRemainderList.length > 0
+    // ) {
+    //   if (isRepeat(formData.data.accountRemainderList)) {
+    //     return ElMessage("请勿重复添加货币余额");
+    //   } else {
+    //     loadingDialog.value = true;
+    //     proxy.post("/accountManagement/" + modalType.value, formData.data).then(
+    //       () => {
+    //         ElMessage({
+    //           message: modalType.value == "add" ? "添加成功" : "编辑成功",
+    //           type: "success",
+    //         });
+    //         dialogVisible.value = false;
+    //         getList();
+    //       },
+    //       (err) => {
+    //         console.log(err);
+    //         loadingDialog.value = false;
+    //       }
+    //     );
+    //   }
+    // } else {
+    //   return ElMessage("请添加至少一条类型余额");
+    // }
+  });
+};
+
+const update = (row) => {
+  loadingDialog.value = false;
+  modalType.value = "edit";
+  formData.data = proxy.deepClone(row);
+  dialogVisible.value = true;
+};
+
+const clickUpdate = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+      businessId: row.id,
+    },
+  });
+};
+
+const getDtl = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴流程查看",
+      random: proxy.random(),
+      businessId: row.id,
+      processType: 20,
+    },
+  });
+};
+
+const exportExcel = () => {
+  proxy.msgTip("正在导出,请稍后", 2);
+  const wb = XLSX.utils.table_to_book(document.querySelector("#my-table")); // 关联dom节点
+  // 设置百分比列的单元格样式
+  const percentStyle = {
+    font: { bold: true },
+    fill: { fgColor: { rgb: "FFFF00" } },
+    border: { top: { style: "thin" }, bottom: { style: "thin" } },
+  };
+
+  // if (wb.Sheets.Sheet1) {
+  //   // 达成率单元格的key开头
+  //   let cellKey = "";
+  //   for (const key in wb.Sheets.Sheet1) {
+  //     let value = wb.Sheets.Sheet1[key];
+  //     if (value && value.v == "月达成率") {
+  //       cellKey = key.match(/[a-zA-Z]+/g)[0];
+  //     }
+  //     // key有包含cellKey的
+  //     if (cellKey && key.includes(cellKey)) {
+  //       // 单元格的样式
+  //       wb.Sheets.Sheet1[key].s = percentStyle;
+  //       // 用于指定单元格中显示值的格式,例如日期格式、百分比格式等
+  //       wb.Sheets.Sheet1[key].z = "0.00%";
+  //     }
+  //   }
+  // }
+  const wbout = XLSX.write(wb, {
+    bookType: "xlsx",
+    bookSST: true,
+    type: "array",
+  });
+  try {
+    FileSaver.saveAs(
+      new Blob([wbout], {
+        type: "application/octet-stream",
+      }),
+      "科目余额.xlsx"
+    );
+  } catch (e) {
+    console.log(e, wbout);
+  }
+  return wbout;
+};
+
+const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
+  // 手动配置合计列
+  if (rowIndex == sourceList.value.data.length - 1) {
+    if (columnIndex == 0) {
+      return {
+        rowspan: 1,
+        colspan: 3,
+      };
+    } else if (columnIndex == 1 || columnIndex == 2) {
+      return {
+        rowspan: 1,
+        colspan: 0,
+      };
+    } else {
+      return {
+        rowspan: 1,
+        colspan: 1,
+      };
+    }
+  }
+};
+
+const getRowClass = ({ row, rowIndex }) => {
+  if (rowIndex == sourceList.value.data.length - 1) {
+    return "sumRow";
+  }
+  return "";
+};
+
+const changeMoney = (val, month, customerId) => {
+  if (customerId && month) {
+    let accountDate = Number(month) > 9 ? month : "0" + month;
+    proxy.post("/customerPayableBalance/edit", {
+      customerId,
+      accountDate: sourceList.value.pagination.year + "-" + accountDate,
+      adjust: val,
+    });
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+:deep(
+    .el-table .el-table__header-wrapper th,
+    .el-table .el-table__fixed-header-wrapper th
+  ) {
+  height: auto !important;
+}
+:deep(.el-table th.el-table__cell) {
+  background: #fff !important;
+}
+:deep(.el-table .el-table__cell) {
+  padding: 0 !important;
+}
+:deep(.el-table .cell) {
+  padding: 0 8px !important;
+  font-size: 12px !important;
+}
+
+:deep(.sumRow) {
+  background-color: #f5f7fa !important;
+  .el-table-fixed-column--left,
+  .el-table-fixed-column--right {
+    background-color: #f5f7fa !important;
+  }
+}
+:deep(.el-input-number .el-input__inner) {
+  text-align: right !important;
+}
+</style>

+ 805 - 0
src/views/report/accountsReceivableEndorsement/index.vue

@@ -0,0 +1,805 @@
+<template>
+  <div class="pageIndexClass">
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :selectConfig="selectConfig" :config="config" highlight-current-row
+               :action-list="[{
+                text: '导出Excel',
+                action: () => exportExcel(),
+                disabled: false,
+              }
+        ]" @get-list="getList" :hideTable="true" :hidePagination="true">
+        <template #code="{item}">
+          <div style="width:100%">
+            <span class="el-click" @click="getDtl(item)">{{item.code}}</span>
+          </div>
+        </template>
+      </byTable>
+      <div style="padding:0 15px;background:#fff">
+
+        <el-table :data="sourceList.data" :height="tableHeight" style="width: 100%;margin-top:-10px" v-loading="loading" border
+                  :span-method="objectSpanMethod" :row-class-name="getRowClass" id="my-table">
+          <el-table-column prop="customerName" label="客户名称" width="120" fixed="left">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                <span v-if="$index < sourceList.data.length - 1"> {{row.customerName}}</span>
+                <div style="text-align:right" v-else>
+                  合计:
+                </div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="customerShortName" label="客户简称" width="100" fixed="left" />
+          <el-table-column prop="saleUserName" label="业务员" width="100" fixed="left" />
+          <el-table-column prop="yearBeginBalance" label="年初余额" width="80" fixed="left" align="right">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.yearBeginBalance,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <template v-if="monthList && monthList.length>0">
+            <el-table-column v-for="col in monthList" :key="col.key" :label="col.label" align="center">
+              <el-table-column label="应收" width="80" align="right">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%" v-if="row[col.key] && row[col.key].receivableAmount">
+                    {{moneyFormat(row[col.key].receivableAmount,2)}}
+                  </div>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="已收" width="80" align="right">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%" v-if="row[col.key] && row[col.key].receivedAmount">
+                    {{moneyFormat(row[col.key].receivedAmount,2)}}
+                  </div>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="调整" width="100" align="right">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-input-number onmousewheel="return false;" v-model="row[col.key].adjustAmount" placeholder=" " style="width: 100%"
+                                     :precision="2" :controls="false" :min="0" @change="(val)=>changeMoney(val,col.key,row.customerId)"
+                                     v-if="$index < sourceList.data.length - 1" />
+                    <div v-else> {{row[col.key].adjustAmount}}</div>
+                  </div>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="期末余额" width="80" align="right">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%" v-if="row[col.key] && row[col.key].balanceAmount">
+                    {{moneyFormat(row[col.key].balanceAmount,2)}}
+                  </div>
+                </template>
+              </el-table-column>
+
+            </el-table-column>
+          </template>
+        </el-table>
+      </div>
+
+    </div>
+
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="60%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
+
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import moment from "moment";
+import FileSaver from "file-saver";
+import * as XLSX from "xlsx";
+
+const { proxy } = getCurrentInstance();
+const tableHeight = ref(0);
+const getTableHeight = () => {
+  tableHeight.value = window.innerHeight - 150 - 30;
+};
+getTableHeight();
+window.addEventListener("resize", () => {
+  getTableHeight();
+});
+const sealType = computed(() => proxy.useUserStore().allDict["seal_type"]);
+const userList = ref([]);
+const deptData = ref([]);
+const typeData = ref([
+  {
+    label: "收入",
+    value: "10",
+  },
+  {
+    label: "支出",
+    value: "20",
+  },
+]);
+const monthList = ref([
+  { key: 1, label: "1月" },
+  { key: 2, label: "2月" },
+  { key: 3, label: "3月" },
+  { key: 4, label: "4月" },
+  { key: 5, label: "5月" },
+  { key: 6, label: "6月" },
+  { key: 7, label: "7月" },
+  { key: 8, label: "8月" },
+  { key: 9, label: "9月" },
+  { key: 10, label: "10月" },
+  { key: 11, label: "11月" },
+  { key: 12, label: "12月" },
+]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    year: moment().format("yyyy"),
+  },
+});
+const loading = ref(false);
+const statusData = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "审批驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "作废",
+    value: 88,
+  },
+]);
+const processingMethod = ref([
+  {
+    dictKey: 10,
+    dictValue: "业务自采",
+  },
+  {
+    dictKey: 20,
+    dictValue: "生产处理",
+  },
+]);
+
+const contractType = ref([
+  {
+    dictKey: "3",
+    dictValue: "打样订单",
+  },
+  {
+    dictKey: "2",
+    dictValue: "内销订单",
+  },
+  {
+    dictKey: "1",
+    dictValue: "外贸订单(退税)",
+  },
+  {
+    dictKey: "4",
+    dictValue: "外贸订单(不退税)",
+  },
+]);
+const selectConfig = computed(() => {
+  return [
+    {
+      type: "time",
+      itemType: "year",
+      label: "年份",
+      placeholder: "请选择",
+      prop: "year",
+      placeholderOne: "",
+      propOne: "",
+      clearable: false,
+      fn: () => {
+        getList();
+      },
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "订单编号",
+        slot: "code",
+      },
+    },
+
+    // {
+    //   attrs: {
+    //     label: "印章类型",
+    //     prop: "type",
+    //   },
+    //   render(val) {
+    //     return proxy.dictKeyValue(val, sealType.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "业务员",
+        prop: "createUserName",
+      },
+    },
+    {
+      attrs: {
+        label: "跟单员",
+        prop: "applyTime",
+      },
+    },
+    {
+      attrs: {
+        label: "订单类型",
+        prop: "contractType",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, contractType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "订单处理方式",
+        prop: "processingMethod",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, processingMethod.value);
+      },
+    },
+    {
+      attrs: {
+        label: "销售金额",
+        prop: "deptName",
+      },
+    },
+    {
+      attrs: {
+        label: "订单出货金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "出货申请出货金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "已收定金",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "是否可结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "是否已结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户名称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户简称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "应收金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "收款金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "未收金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "出货日期",
+        prop: "amount",
+      },
+    },
+    {
+      attrs: {
+        label: "账龄级别",
+        prop: "amount",
+      },
+    },
+    // {
+    //   attrs: {
+    //     label: "审批状态",
+    //     prop: "status",
+    //     width: 100,
+    //   },
+    //   render(type) {
+    //     return proxy.dictValueLabel(type, statusData.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+      },
+      renderHTML(row) {
+        return row.createUser == proxy.useUserStore().user.userId
+          ? [
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "修改",
+                      type: "primary",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      clickUpdate(row);
+                    },
+                  }
+                : {},
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "删除",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/delete", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+              row.status == 10 || row.status == 30
+                ? {
+                    attrs: {
+                      label: "作废",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/cancellation", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+            ]
+          : [];
+      },
+    },
+  ];
+});
+const corporationList = ref([]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/report/finance/receivableAccounts", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+const getDeptData = (val) => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      pageSize: 9999,
+      keyword: "",
+      ancestors: proxy.useUserStore().user.companyId,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // type: 2,
+    })
+    .then((res) => {
+      deptData.value = proxy.handleTree(res.data, "deptId");
+    });
+};
+// getDeptData();
+const modalType = ref("add");
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "印章名称",
+      required: true,
+      itemWidth: 50,
+      itemType: "text",
+    },
+    {
+      type: "select",
+      prop: "sealType",
+      label: "印章类型",
+      data: sealType.value,
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "applyUserId",
+      label: "存管人员",
+      required: true,
+      filterable: true,
+      data: userList.value,
+      itemWidth: 50,
+      fn: (val) => {
+        let current = userList.value.find((x) => x.value == val);
+        console.log(current, "ada");
+        if (current) {
+          formData.data.deptId = current.deptId;
+        }
+      },
+    },
+    {
+      type: "treeSelect",
+      prop: "deptId",
+      label: "存管部门",
+      data: deptData.value,
+      propsTreeLabel: "deptName",
+      propsTreeValue: "deptId",
+      itemWidth: 50,
+      disabled: 50,
+    },
+    {
+      type: "input",
+      prop: "accountNumber",
+      label: "印章用途",
+      itemWidth: 100,
+      itemType: "textarea",
+    },
+  ];
+});
+const rules = ref({
+  name: [{ required: true, message: "请输入承包商", trigger: "blur" }],
+  taxPoints: [{ required: true, message: "请输入税点", trigger: "blur" }],
+  accountBank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
+  accountName: [{ required: true, message: "请输入开户名", trigger: "blur" }],
+  accountNumber: [{ required: true, message: "请输入账号", trigger: "blur" }],
+});
+const formData = reactive({
+  data: {
+    accountRemainderList: [{ currency: "", remainder: undefined }],
+  },
+});
+const openModal = (val) => {
+  // modalType.value = val;
+  // formData.data = {
+  //   accountRemainderList: [{ currency: "", remainder: undefined }],
+  // };
+  // loadingDialog.value = false;
+  // dialogVisible.value = true;
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+    },
+  });
+};
+const clickBalance = () => {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
+    formData.data.accountRemainderList.push({
+      currency: "",
+      remainder: undefined,
+    });
+  } else {
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
+  }
+};
+const handleRemove = (index) => {
+  formData.data.accountRemainderList.splice(index, 1);
+};
+const isRepeat = (arr) => {
+  var hash = {};
+  for (var i in arr) {
+    if (hash[arr[i].currency]) return true;
+    hash[arr[i].currency] = true;
+  }
+  return false;
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/contractor/" + modalType.value, formData.data).then(
+      () => {
+        proxy.msgTip("操作成功", 1);
+        dialogVisible.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+    // if (
+    //   formData.data.accountRemainderList &&
+    //   formData.data.accountRemainderList.length > 0
+    // ) {
+    //   if (isRepeat(formData.data.accountRemainderList)) {
+    //     return ElMessage("请勿重复添加货币余额");
+    //   } else {
+    //     loadingDialog.value = true;
+    //     proxy.post("/accountManagement/" + modalType.value, formData.data).then(
+    //       () => {
+    //         ElMessage({
+    //           message: modalType.value == "add" ? "添加成功" : "编辑成功",
+    //           type: "success",
+    //         });
+    //         dialogVisible.value = false;
+    //         getList();
+    //       },
+    //       (err) => {
+    //         console.log(err);
+    //         loadingDialog.value = false;
+    //       }
+    //     );
+    //   }
+    // } else {
+    //   return ElMessage("请添加至少一条类型余额");
+    // }
+  });
+};
+
+const update = (row) => {
+  loadingDialog.value = false;
+  modalType.value = "edit";
+  formData.data = proxy.deepClone(row);
+  dialogVisible.value = true;
+};
+
+const clickUpdate = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+      businessId: row.id,
+    },
+  });
+};
+
+const getDtl = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴流程查看",
+      random: proxy.random(),
+      businessId: row.id,
+      processType: 20,
+    },
+  });
+};
+
+const exportExcel = () => {
+  proxy.msgTip("正在导出,请稍后", 2);
+  const wb = XLSX.utils.table_to_book(document.querySelector("#my-table")); // 关联dom节点
+  // 设置百分比列的单元格样式
+  const percentStyle = {
+    font: { bold: true },
+    fill: { fgColor: { rgb: "FFFF00" } },
+    border: { top: { style: "thin" }, bottom: { style: "thin" } },
+  };
+
+  // if (wb.Sheets.Sheet1) {
+  //   // 达成率单元格的key开头
+  //   let cellKey = "";
+  //   for (const key in wb.Sheets.Sheet1) {
+  //     let value = wb.Sheets.Sheet1[key];
+  //     if (value && value.v == "月达成率") {
+  //       cellKey = key.match(/[a-zA-Z]+/g)[0];
+  //     }
+  //     // key有包含cellKey的
+  //     if (cellKey && key.includes(cellKey)) {
+  //       // 单元格的样式
+  //       wb.Sheets.Sheet1[key].s = percentStyle;
+  //       // 用于指定单元格中显示值的格式,例如日期格式、百分比格式等
+  //       wb.Sheets.Sheet1[key].z = "0.00%";
+  //     }
+  //   }
+  // }
+  const wbout = XLSX.write(wb, {
+    bookType: "xlsx",
+    bookSST: true,
+    type: "array",
+  });
+  try {
+    FileSaver.saveAs(
+      new Blob([wbout], {
+        type: "application/octet-stream",
+      }),
+      "应收账款-批单.xlsx"
+    );
+  } catch (e) {
+    console.log(e, wbout);
+  }
+  return wbout;
+};
+
+const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
+  // 手动配置合计列
+  if (rowIndex == sourceList.value.data.length - 1) {
+    if (columnIndex == 0) {
+      return {
+        rowspan: 1,
+        colspan: 3,
+      };
+    } else if (columnIndex == 1 || columnIndex == 2) {
+      return {
+        rowspan: 1,
+        colspan: 0,
+      };
+    } else {
+      return {
+        rowspan: 1,
+        colspan: 1,
+      };
+    }
+  }
+};
+
+const getRowClass = ({ row, rowIndex }) => {
+  if (rowIndex == sourceList.value.data.length - 1) {
+    return "sumRow";
+  }
+  return "";
+};
+
+const changeMoney = (val, month, customerId) => {
+  if (customerId && month) {
+    let accountDate = Number(month) > 9 ? month : "0" + month;
+    proxy.post("/customerPayableBalance/edit", {
+      customerId,
+      accountDate: sourceList.value.pagination.year + "-" + accountDate,
+      adjust: val,
+    });
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+:deep(
+    .el-table .el-table__header-wrapper th,
+    .el-table .el-table__fixed-header-wrapper th
+  ) {
+  height: auto !important;
+}
+:deep(.el-table th.el-table__cell) {
+  background: #fff !important;
+}
+:deep(.el-table .el-table__cell) {
+  padding: 0 !important;
+}
+:deep(.el-table .cell) {
+  padding: 0 8px !important;
+  font-size: 12px !important;
+}
+
+:deep(.sumRow) {
+  background-color: #f5f7fa !important;
+  .el-table-fixed-column--left,
+  .el-table-fixed-column--right {
+    background-color: #f5f7fa !important;
+  }
+}
+:deep(.el-input-number .el-input__inner) {
+  text-align: right !important;
+}
+</style>

+ 863 - 0
src/views/report/agingAnalysis/index.vue

@@ -0,0 +1,863 @@
+<template>
+  <div class="pageIndexClass">
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :selectConfig="selectConfig" :config="config" highlight-current-row
+               :action-list="[{
+                text: '导出Excel',
+                action: () => exportExcel(),
+                disabled: false,
+              }
+        ]" @get-list="getList" :hideTable="true" :hidePagination="true">
+        <template #code="{item}">
+          <div style="width:100%">
+            <span class="el-click" @click="getDtl(item)">{{item.code}}</span>
+          </div>
+        </template>
+      </byTable>
+      <div style="padding:0 15px;background:#fff">
+        <el-table :data="sourceList.data" :height="tableHeight" style="width: 100%;margin-top:-10px" v-loading="loading" border
+                  :span-method="objectSpanMethod" :row-class-name="getRowClass" id="my-table">
+          <el-table-column prop="customerName" label="客户名称">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                <span v-if="$index < sourceList.data.length - 1"> {{row.customerName}}</span>
+                <div style="text-align:right" v-else>
+                  合计:
+                </div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="customerShortName" label="客户简称" />
+          <el-table-column label="0~30" align="right" width="120">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.ageLess30Amount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="30~60" align="right" width="120">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.age30To60Amount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="60~90" align="right" width="120">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.age60To90Amount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="90~120" align="right" width="120">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.age90To120Amount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="120以上" align="right" width="120">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.ageGreater120Amount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="总计" align="right" width="120">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.receivableAmount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="60%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
+
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import moment from "moment";
+import FileSaver from "file-saver";
+import * as XLSX from "xlsx";
+
+const { proxy } = getCurrentInstance();
+const tableHeight = ref(0);
+const getTableHeight = () => {
+  tableHeight.value = window.innerHeight - 150 - 30;
+};
+getTableHeight();
+window.addEventListener("resize", () => {
+  getTableHeight();
+});
+const sealType = computed(() => proxy.useUserStore().allDict["seal_type"]);
+const userList = ref([]);
+const deptData = ref([]);
+const typeData = ref([
+  {
+    label: "收入",
+    value: "10",
+  },
+  {
+    label: "支出",
+    value: "20",
+  },
+]);
+const monthList = ref([
+  { key: 1, label: "1月" },
+  { key: 2, label: "2月" },
+  { key: 3, label: "3月" },
+  { key: 4, label: "4月" },
+  { key: 5, label: "5月" },
+  { key: 6, label: "6月" },
+  { key: 7, label: "7月" },
+  { key: 8, label: "8月" },
+  { key: 9, label: "9月" },
+  { key: 10, label: "10月" },
+  { key: 11, label: "11月" },
+  { key: 12, label: "12月" },
+]);
+const monthData = ref(moment().format("YYYY-MM"));
+const month = ref("");
+const getMonth = (val) => {
+  month.value = val.split("-")[1];
+  if (Number(month.value) < 10) {
+    month.value = month.value.split("")[1];
+  }
+};
+// getMonth(monthData.value);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    checkDate: monthData.value,
+  },
+});
+const loading = ref(false);
+const statusData = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "审批驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "作废",
+    value: 88,
+  },
+]);
+const processingMethod = ref([
+  {
+    dictKey: 10,
+    dictValue: "业务自采",
+  },
+  {
+    dictKey: 20,
+    dictValue: "生产处理",
+  },
+]);
+
+const contractType = ref([
+  {
+    dictKey: "3",
+    dictValue: "打样订单",
+  },
+  {
+    dictKey: "2",
+    dictValue: "内销订单",
+  },
+  {
+    dictKey: "1",
+    dictValue: "外贸订单(退税)",
+  },
+  {
+    dictKey: "4",
+    dictValue: "外贸订单(不退税)",
+  },
+]);
+const accountAgeList = ref([
+  {
+    label: "0~30",
+    value: "0~30",
+  },
+  {
+    label: "30~60",
+    value: "30~60",
+  },
+  {
+    label: "60~90",
+    value: "60~90",
+  },
+  {
+    label: "90~120",
+    value: "90~120",
+  },
+  {
+    label: "120以上",
+    value: "120以上",
+  },
+]);
+const selectConfig = computed(() => {
+  return [
+    {
+      type: "time",
+      itemType: "month",
+      label: "年月",
+      placeholder: "请选择",
+      prop: "checkDate",
+      placeholderOne: "",
+      propOne: "",
+      clearable: false,
+      fn: (val) => {
+        // getMonth(val);
+        getList();
+      },
+    },
+    {
+      label: "账龄",
+      prop: "accountAge",
+      data: accountAgeList.value,
+    },
+    // {
+    //   label: "业务员",
+    //   prop: "saleUserId",
+    //   data: userList.value,
+    // },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "订单编号",
+        slot: "code",
+      },
+    },
+
+    // {
+    //   attrs: {
+    //     label: "印章类型",
+    //     prop: "type",
+    //   },
+    //   render(val) {
+    //     return proxy.dictKeyValue(val, sealType.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "业务员",
+        prop: "createUserName",
+      },
+    },
+    {
+      attrs: {
+        label: "跟单员",
+        prop: "applyTime",
+      },
+    },
+    {
+      attrs: {
+        label: "订单类型",
+        prop: "contractType",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, contractType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "订单处理方式",
+        prop: "processingMethod",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, processingMethod.value);
+      },
+    },
+    {
+      attrs: {
+        label: "销售金额",
+        prop: "deptName",
+      },
+    },
+    {
+      attrs: {
+        label: "订单出货金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "出货申请出货金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "已收定金",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "是否可结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "是否已结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户名称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户简称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "应收金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "收款金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "未收金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "出货日期",
+        prop: "amount",
+      },
+    },
+    {
+      attrs: {
+        label: "账龄级别",
+        prop: "amount",
+      },
+    },
+    // {
+    //   attrs: {
+    //     label: "审批状态",
+    //     prop: "status",
+    //     width: 100,
+    //   },
+    //   render(type) {
+    //     return proxy.dictValueLabel(type, statusData.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+      },
+      renderHTML(row) {
+        return row.createUser == proxy.useUserStore().user.userId
+          ? [
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "修改",
+                      type: "primary",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      clickUpdate(row);
+                    },
+                  }
+                : {},
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "删除",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/delete", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+              row.status == 10 || row.status == 30
+                ? {
+                    attrs: {
+                      label: "作废",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/cancellation", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+            ]
+          : [];
+      },
+    },
+  ];
+});
+const corporationList = ref([]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/report/finance/agingAnalysis", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+const getDeptData = (val) => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      pageSize: 9999,
+      keyword: "",
+      ancestors: proxy.useUserStore().user.companyId,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // type: 2,
+    })
+    .then((res) => {
+      deptData.value = proxy.handleTree(res.data, "deptId");
+    });
+};
+// getDeptData();
+const getDict = () => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+};
+// getDict();
+const modalType = ref("add");
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "印章名称",
+      required: true,
+      itemWidth: 50,
+      itemType: "text",
+    },
+    {
+      type: "select",
+      prop: "sealType",
+      label: "印章类型",
+      data: sealType.value,
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "applyUserId",
+      label: "存管人员",
+      required: true,
+      filterable: true,
+      data: userList.value,
+      itemWidth: 50,
+      fn: (val) => {
+        let current = userList.value.find((x) => x.value == val);
+        console.log(current, "ada");
+        if (current) {
+          formData.data.deptId = current.deptId;
+        }
+      },
+    },
+    {
+      type: "treeSelect",
+      prop: "deptId",
+      label: "存管部门",
+      data: deptData.value,
+      propsTreeLabel: "deptName",
+      propsTreeValue: "deptId",
+      itemWidth: 50,
+      disabled: 50,
+    },
+    {
+      type: "input",
+      prop: "accountNumber",
+      label: "印章用途",
+      itemWidth: 100,
+      itemType: "textarea",
+    },
+  ];
+});
+const rules = ref({
+  name: [{ required: true, message: "请输入承包商", trigger: "blur" }],
+  taxPoints: [{ required: true, message: "请输入税点", trigger: "blur" }],
+  accountBank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
+  accountName: [{ required: true, message: "请输入开户名", trigger: "blur" }],
+  accountNumber: [{ required: true, message: "请输入账号", trigger: "blur" }],
+});
+const formData = reactive({
+  data: {
+    accountRemainderList: [{ currency: "", remainder: undefined }],
+  },
+});
+const openModal = (val) => {
+  // modalType.value = val;
+  // formData.data = {
+  //   accountRemainderList: [{ currency: "", remainder: undefined }],
+  // };
+  // loadingDialog.value = false;
+  // dialogVisible.value = true;
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+    },
+  });
+};
+const clickBalance = () => {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
+    formData.data.accountRemainderList.push({
+      currency: "",
+      remainder: undefined,
+    });
+  } else {
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
+  }
+};
+const handleRemove = (index) => {
+  formData.data.accountRemainderList.splice(index, 1);
+};
+const isRepeat = (arr) => {
+  var hash = {};
+  for (var i in arr) {
+    if (hash[arr[i].currency]) return true;
+    hash[arr[i].currency] = true;
+  }
+  return false;
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/contractor/" + modalType.value, formData.data).then(
+      () => {
+        proxy.msgTip("操作成功", 1);
+        dialogVisible.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+    // if (
+    //   formData.data.accountRemainderList &&
+    //   formData.data.accountRemainderList.length > 0
+    // ) {
+    //   if (isRepeat(formData.data.accountRemainderList)) {
+    //     return ElMessage("请勿重复添加货币余额");
+    //   } else {
+    //     loadingDialog.value = true;
+    //     proxy.post("/accountManagement/" + modalType.value, formData.data).then(
+    //       () => {
+    //         ElMessage({
+    //           message: modalType.value == "add" ? "添加成功" : "编辑成功",
+    //           type: "success",
+    //         });
+    //         dialogVisible.value = false;
+    //         getList();
+    //       },
+    //       (err) => {
+    //         console.log(err);
+    //         loadingDialog.value = false;
+    //       }
+    //     );
+    //   }
+    // } else {
+    //   return ElMessage("请添加至少一条类型余额");
+    // }
+  });
+};
+
+const update = (row) => {
+  loadingDialog.value = false;
+  modalType.value = "edit";
+  formData.data = proxy.deepClone(row);
+  dialogVisible.value = true;
+};
+
+const clickUpdate = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+      businessId: row.id,
+    },
+  });
+};
+
+const getDtl = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴流程查看",
+      random: proxy.random(),
+      businessId: row.id,
+      processType: 20,
+    },
+  });
+};
+
+const exportExcel = () => {
+  proxy.msgTip("正在导出,请稍后", 2);
+  const wb = XLSX.utils.table_to_book(document.querySelector("#my-table")); // 关联dom节点
+  // 设置百分比列的单元格样式
+  const percentStyle = {
+    font: { bold: true },
+    fill: { fgColor: { rgb: "FFFF00" } },
+    border: { top: { style: "thin" }, bottom: { style: "thin" } },
+  };
+
+  // if (wb.Sheets.Sheet1) {
+  //   // 达成率单元格的key开头
+  //   let cellKey = "";
+  //   for (const key in wb.Sheets.Sheet1) {
+  //     let value = wb.Sheets.Sheet1[key];
+  //     if (value && value.v == "月达成率") {
+  //       cellKey = key.match(/[a-zA-Z]+/g)[0];
+  //     }
+  //     // key有包含cellKey的
+  //     if (cellKey && key.includes(cellKey)) {
+  //       // 单元格的样式
+  //       wb.Sheets.Sheet1[key].s = percentStyle;
+  //       // 用于指定单元格中显示值的格式,例如日期格式、百分比格式等
+  //       wb.Sheets.Sheet1[key].z = "0.00%";
+  //     }
+  //   }
+  // }
+  const wbout = XLSX.write(wb, {
+    bookType: "xlsx",
+    bookSST: true,
+    type: "array",
+  });
+  try {
+    FileSaver.saveAs(
+      new Blob([wbout], {
+        type: "application/octet-stream",
+      }),
+      "账龄分析.xlsx"
+    );
+  } catch (e) {
+    console.log(e, wbout);
+  }
+  return wbout;
+};
+// 合并行单元格
+const getMergeCellData = (data) => {
+  let rowspanArr = [];
+  let rowspanIndex = 0;
+  data.map((row, index) => {
+    if (index === 0) {
+      rowspanArr.push(1);
+    } else {
+      //注意这里的saleUserId是表格合并单元格绑定的字段,根据自己的需求来改
+      if (row.saleUserId === data[index - 1].saleUserId) {
+        //第一列需合并相同内容的判断条件
+        rowspanArr[rowspanIndex] += 1;
+        rowspanArr.push(0);
+      } else {
+        rowspanArr.push(1);
+        rowspanIndex = index;
+      }
+    }
+  });
+  return rowspanArr;
+};
+const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
+  // 手动配置合计列
+  if (rowIndex == sourceList.value.data.length - 1) {
+    if (columnIndex == 0) {
+      return {
+        rowspan: 1,
+        colspan: 2,
+      };
+    } else if (columnIndex == 1) {
+      return {
+        rowspan: 1,
+        colspan: 0,
+      };
+    } else {
+      return {
+        rowspan: 1,
+        colspan: 1,
+      };
+    }
+  }
+};
+const getRowClass = ({ row, rowIndex }) => {
+  if (rowIndex == sourceList.value.data.length - 1) {
+    return "sumRow";
+  }
+  return "";
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+:deep(
+    .el-table .el-table__header-wrapper th,
+    .el-table .el-table__fixed-header-wrapper th
+  ) {
+  height: auto !important;
+}
+:deep(.el-table th.el-table__cell) {
+  background: #fff !important;
+}
+:deep(.el-table .el-table__cell) {
+  padding: 0 !important;
+}
+:deep(.el-table .cell) {
+  padding: 0 8px !important;
+  font-size: 12px !important;
+}
+
+:deep(.sumRow) {
+  background-color: #f5f7fa !important;
+  .el-table-fixed-column--left,
+  .el-table-fixed-column--right {
+    background-color: #f5f7fa !important;
+  }
+}
+</style>

+ 1 - 1
src/views/report/expressPaymentSummary/index.vue

@@ -486,7 +486,7 @@ const getDeptData = (val) => {
       deptData.value = proxy.handleTree(res.data, "deptId");
     });
 };
-getDeptData();
+// getDeptData();
 const modalType = ref("add");
 const dialogVisible = ref(false);
 const loadingDialog = ref(false);

+ 1 - 1
src/views/report/expressRechargeSummary/index.vue

@@ -478,7 +478,7 @@ const getDeptData = (val) => {
       deptData.value = proxy.handleTree(res.data, "deptId");
     });
 };
-getDeptData();
+// getDeptData();
 const modalType = ref("add");
 const dialogVisible = ref(false);
 const loadingDialog = ref(false);

+ 1 - 1
src/views/report/orderSummary/index.vue

@@ -476,7 +476,7 @@ const getDeptData = (val) => {
       deptData.value = proxy.handleTree(res.data, "deptId");
     });
 };
-getDeptData();
+// getDeptData();
 const modalType = ref("add");
 const dialogVisible = ref(false);
 const loadingDialog = ref(false);

+ 813 - 0
src/views/report/receivableCheck/index.vue

@@ -0,0 +1,813 @@
+<template>
+  <div class="pageIndexClass">
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :selectConfig="selectConfig" :config="config" highlight-current-row
+               :action-list="[{
+                text: '导出Excel',
+                action: () => exportExcel(),
+                disabled: false,
+              }
+        ]" @get-list="getList" :hideTable="true" :hidePagination="true">
+        <template #code="{item}">
+          <div style="width:100%">
+            <span class="el-click" @click="getDtl(item)">{{item.code}}</span>
+          </div>
+        </template>
+      </byTable>
+      <div style="padding:0 15px;background:#fff">
+        <el-table :data="sourceList.data" :height="tableHeight" style="width: 100%;margin-top:-10px" v-loading="loading" border
+                  :span-method="objectSpanMethod" :row-class-name="getRowClass" id="my-table">
+          <el-table-column prop="saleUserName" label="业务员">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                <span v-if="$index < sourceList.data.length - 1"> {{row.saleUserName}}</span>
+                <div style="text-align:right" v-else>
+                  合计:
+                </div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="customerName" label="客户名称" />
+          <el-table-column prop="customerShortName" label="客户简称" />
+          <el-table-column :label="month+'月应收余额'" align="right">
+            <template #default="{ row, $index }">
+              <div style="width: 100%">
+                {{moneyFormat(row.receivableAmount,2)}}
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+    </div>
+
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-if="dialogVisible" v-model="dialogVisible" width="60%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
+
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import moment from "moment";
+import FileSaver from "file-saver";
+import * as XLSX from "xlsx";
+
+const { proxy } = getCurrentInstance();
+const tableHeight = ref(0);
+const getTableHeight = () => {
+  tableHeight.value = window.innerHeight - 150 - 30;
+};
+getTableHeight();
+window.addEventListener("resize", () => {
+  getTableHeight();
+});
+const sealType = computed(() => proxy.useUserStore().allDict["seal_type"]);
+const userList = ref([]);
+const deptData = ref([]);
+const typeData = ref([
+  {
+    label: "收入",
+    value: "10",
+  },
+  {
+    label: "支出",
+    value: "20",
+  },
+]);
+const monthList = ref([
+  { key: 1, label: "1月" },
+  { key: 2, label: "2月" },
+  { key: 3, label: "3月" },
+  { key: 4, label: "4月" },
+  { key: 5, label: "5月" },
+  { key: 6, label: "6月" },
+  { key: 7, label: "7月" },
+  { key: 8, label: "8月" },
+  { key: 9, label: "9月" },
+  { key: 10, label: "10月" },
+  { key: 11, label: "11月" },
+  { key: 12, label: "12月" },
+]);
+const monthData = ref(moment().format("YYYY-MM"));
+const month = ref("");
+const getMonth = (val) => {
+  month.value = val.split("-")[1];
+  if (Number(month.value) < 10) {
+    month.value = month.value.split("")[1];
+  }
+};
+getMonth(monthData.value);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    checkDate: monthData.value,
+  },
+});
+const loading = ref(false);
+const statusData = ref([
+  {
+    label: "草稿",
+    value: 0,
+  },
+  {
+    label: "审批中",
+    value: 10,
+  },
+  {
+    label: "审批驳回",
+    value: 20,
+  },
+  {
+    label: "审批通过",
+    value: 30,
+  },
+  {
+    label: "作废",
+    value: 88,
+  },
+]);
+const processingMethod = ref([
+  {
+    dictKey: 10,
+    dictValue: "业务自采",
+  },
+  {
+    dictKey: 20,
+    dictValue: "生产处理",
+  },
+]);
+
+const contractType = ref([
+  {
+    dictKey: "3",
+    dictValue: "打样订单",
+  },
+  {
+    dictKey: "2",
+    dictValue: "内销订单",
+  },
+  {
+    dictKey: "1",
+    dictValue: "外贸订单(退税)",
+  },
+  {
+    dictKey: "4",
+    dictValue: "外贸订单(不退税)",
+  },
+]);
+const selectConfig = computed(() => {
+  return [
+    {
+      type: "time",
+      itemType: "month",
+      label: "年月",
+      placeholder: "请选择",
+      prop: "checkDate",
+      placeholderOne: "",
+      propOne: "",
+      clearable: false,
+      fn: (val) => {
+        getMonth(val);
+        getList();
+      },
+    },
+    {
+      label: "业务员",
+      prop: "saleUserId",
+      data: userList.value,
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "订单编号",
+        slot: "code",
+      },
+    },
+
+    // {
+    //   attrs: {
+    //     label: "印章类型",
+    //     prop: "type",
+    //   },
+    //   render(val) {
+    //     return proxy.dictKeyValue(val, sealType.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "业务员",
+        prop: "createUserName",
+      },
+    },
+    {
+      attrs: {
+        label: "跟单员",
+        prop: "applyTime",
+      },
+    },
+    {
+      attrs: {
+        label: "订单类型",
+        prop: "contractType",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, contractType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "订单处理方式",
+        prop: "processingMethod",
+        width: 110,
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, processingMethod.value);
+      },
+    },
+    {
+      attrs: {
+        label: "销售金额",
+        prop: "deptName",
+      },
+    },
+    {
+      attrs: {
+        label: "订单出货金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "出货申请出货金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "已收定金",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "是否可结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "是否已结算",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户名称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户简称",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "应收金额",
+        prop: "educationName",
+      },
+    },
+    {
+      attrs: {
+        label: "收款金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "未收金额",
+        prop: "amount",
+      },
+      render(val) {
+        return proxy.moneyFormat(val, 2);
+      },
+    },
+    {
+      attrs: {
+        label: "出货日期",
+        prop: "amount",
+      },
+    },
+    {
+      attrs: {
+        label: "账龄级别",
+        prop: "amount",
+      },
+    },
+    // {
+    //   attrs: {
+    //     label: "审批状态",
+    //     prop: "status",
+    //     width: 100,
+    //   },
+    //   render(type) {
+    //     return proxy.dictValueLabel(type, statusData.value);
+    //   },
+    // },
+    {
+      attrs: {
+        label: "操作",
+        width: "120",
+        align: "center",
+      },
+      renderHTML(row) {
+        return row.createUser == proxy.useUserStore().user.userId
+          ? [
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "修改",
+                      type: "primary",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      clickUpdate(row);
+                    },
+                  }
+                : {},
+              row.status == 0
+                ? {
+                    attrs: {
+                      label: "删除",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/delete", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+              row.status == 10 || row.status == 30
+                ? {
+                    attrs: {
+                      label: "作废",
+                      type: "danger",
+                      text: true,
+                    },
+                    el: "button",
+                    click() {
+                      proxy
+                        .msgConfirm()
+                        .then((res) => {
+                          proxy
+                            .post("/educationSubsidy/cancellation", {
+                              id: row.id,
+                            })
+                            .then((res) => {
+                              proxy.msgTip("操作成功", 1);
+                              getList();
+                            });
+                        })
+                        .catch((err) => {});
+                    },
+                  }
+                : {},
+            ]
+          : [];
+      },
+    },
+  ];
+});
+const corporationList = ref([]);
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/report/finance/receivableCheck", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getList();
+const getDeptData = (val) => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+
+  proxy
+    .get("/tenantDept/list", {
+      pageNum: 1,
+      pageSize: 9999,
+      keyword: "",
+      ancestors: proxy.useUserStore().user.companyId,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // type: 2,
+    })
+    .then((res) => {
+      deptData.value = proxy.handleTree(res.data, "deptId");
+    });
+};
+// getDeptData();
+const getDict = () => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: proxy.useUserStore().user.tenantId,
+      // companyId: proxy.useUserStore().user.companyId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+};
+getDict();
+const modalType = ref("add");
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "印章名称",
+      required: true,
+      itemWidth: 50,
+      itemType: "text",
+    },
+    {
+      type: "select",
+      prop: "sealType",
+      label: "印章类型",
+      data: sealType.value,
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "applyUserId",
+      label: "存管人员",
+      required: true,
+      filterable: true,
+      data: userList.value,
+      itemWidth: 50,
+      fn: (val) => {
+        let current = userList.value.find((x) => x.value == val);
+        console.log(current, "ada");
+        if (current) {
+          formData.data.deptId = current.deptId;
+        }
+      },
+    },
+    {
+      type: "treeSelect",
+      prop: "deptId",
+      label: "存管部门",
+      data: deptData.value,
+      propsTreeLabel: "deptName",
+      propsTreeValue: "deptId",
+      itemWidth: 50,
+      disabled: 50,
+    },
+    {
+      type: "input",
+      prop: "accountNumber",
+      label: "印章用途",
+      itemWidth: 100,
+      itemType: "textarea",
+    },
+  ];
+});
+const rules = ref({
+  name: [{ required: true, message: "请输入承包商", trigger: "blur" }],
+  taxPoints: [{ required: true, message: "请输入税点", trigger: "blur" }],
+  accountBank: [{ required: true, message: "请输入开户行", trigger: "blur" }],
+  accountName: [{ required: true, message: "请输入开户名", trigger: "blur" }],
+  accountNumber: [{ required: true, message: "请输入账号", trigger: "blur" }],
+});
+const formData = reactive({
+  data: {
+    accountRemainderList: [{ currency: "", remainder: undefined }],
+  },
+});
+const openModal = (val) => {
+  // modalType.value = val;
+  // formData.data = {
+  //   accountRemainderList: [{ currency: "", remainder: undefined }],
+  // };
+  // loadingDialog.value = false;
+  // dialogVisible.value = true;
+  proxy.$router.replace({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+    },
+  });
+};
+const clickBalance = () => {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
+    formData.data.accountRemainderList.push({
+      currency: "",
+      remainder: undefined,
+    });
+  } else {
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
+  }
+};
+const handleRemove = (index) => {
+  formData.data.accountRemainderList.splice(index, 1);
+};
+const isRepeat = (arr) => {
+  var hash = {};
+  for (var i in arr) {
+    if (hash[arr[i].currency]) return true;
+    hash[arr[i].currency] = true;
+  }
+  return false;
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/contractor/" + modalType.value, formData.data).then(
+      () => {
+        proxy.msgTip("操作成功", 1);
+        dialogVisible.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+    // if (
+    //   formData.data.accountRemainderList &&
+    //   formData.data.accountRemainderList.length > 0
+    // ) {
+    //   if (isRepeat(formData.data.accountRemainderList)) {
+    //     return ElMessage("请勿重复添加货币余额");
+    //   } else {
+    //     loadingDialog.value = true;
+    //     proxy.post("/accountManagement/" + modalType.value, formData.data).then(
+    //       () => {
+    //         ElMessage({
+    //           message: modalType.value == "add" ? "添加成功" : "编辑成功",
+    //           type: "success",
+    //         });
+    //         dialogVisible.value = false;
+    //         getList();
+    //       },
+    //       (err) => {
+    //         console.log(err);
+    //         loadingDialog.value = false;
+    //       }
+    //     );
+    //   }
+    // } else {
+    //   return ElMessage("请添加至少一条类型余额");
+    // }
+  });
+};
+
+const update = (row) => {
+  loadingDialog.value = false;
+  modalType.value = "edit";
+  formData.data = proxy.deepClone(row);
+  dialogVisible.value = true;
+};
+
+const clickUpdate = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴发起流程",
+      random: proxy.random(),
+      businessId: row.id,
+    },
+  });
+};
+
+const getDtl = (row) => {
+  proxy.$router.push({
+    path: "/platform_manage/process/processApproval",
+    query: {
+      flowKey: "education_subsidy_flow",
+      flowName: "学历补贴流程查看",
+      random: proxy.random(),
+      businessId: row.id,
+      processType: 20,
+    },
+  });
+};
+
+const exportExcel = () => {
+  proxy.msgTip("正在导出,请稍后", 2);
+  const wb = XLSX.utils.table_to_book(document.querySelector("#my-table")); // 关联dom节点
+  // 设置百分比列的单元格样式
+  const percentStyle = {
+    font: { bold: true },
+    fill: { fgColor: { rgb: "FFFF00" } },
+    border: { top: { style: "thin" }, bottom: { style: "thin" } },
+  };
+
+  // if (wb.Sheets.Sheet1) {
+  //   // 达成率单元格的key开头
+  //   let cellKey = "";
+  //   for (const key in wb.Sheets.Sheet1) {
+  //     let value = wb.Sheets.Sheet1[key];
+  //     if (value && value.v == "月达成率") {
+  //       cellKey = key.match(/[a-zA-Z]+/g)[0];
+  //     }
+  //     // key有包含cellKey的
+  //     if (cellKey && key.includes(cellKey)) {
+  //       // 单元格的样式
+  //       wb.Sheets.Sheet1[key].s = percentStyle;
+  //       // 用于指定单元格中显示值的格式,例如日期格式、百分比格式等
+  //       wb.Sheets.Sheet1[key].z = "0.00%";
+  //     }
+  //   }
+  // }
+  const wbout = XLSX.write(wb, {
+    bookType: "xlsx",
+    bookSST: true,
+    type: "array",
+  });
+  try {
+    FileSaver.saveAs(
+      new Blob([wbout], {
+        type: "application/octet-stream",
+      }),
+      "应收余额核对.xlsx"
+    );
+  } catch (e) {
+    console.log(e, wbout);
+  }
+  return wbout;
+};
+// 合并行单元格
+const getMergeCellData = (data) => {
+  let rowspanArr = [];
+  let rowspanIndex = 0;
+  data.map((row, index) => {
+    if (index === 0) {
+      rowspanArr.push(1);
+    } else {
+      //注意这里的saleUserId是表格合并单元格绑定的字段,根据自己的需求来改
+      if (row.saleUserId === data[index - 1].saleUserId) {
+        //第一列需合并相同内容的判断条件
+        rowspanArr[rowspanIndex] += 1;
+        rowspanArr.push(0);
+      } else {
+        rowspanArr.push(1);
+        rowspanIndex = index;
+      }
+    }
+  });
+  return rowspanArr;
+};
+const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
+  // 手动配置合计列
+  if (rowIndex == sourceList.value.data.length - 1) {
+    if (columnIndex == 0) {
+      return {
+        rowspan: 1,
+        colspan: 3,
+      };
+    } else if (columnIndex == 1 || columnIndex == 2) {
+      return {
+        rowspan: 1,
+        colspan: 0,
+      };
+    } else {
+      return {
+        rowspan: 1,
+        colspan: 1,
+      };
+    }
+  } else {
+    if (columnIndex === 0) {
+      const rowspan = getMergeCellData(sourceList.value.data)[rowIndex];
+      const colspan = rowspan > 0 ? 1 : 0;
+      return {
+        rowspan: rowspan,
+        colspan: colspan,
+      };
+    }
+  }
+};
+
+const getRowClass = ({ row, rowIndex }) => {
+  if (rowIndex == sourceList.value.data.length - 1) {
+    return "sumRow";
+  }
+  return "";
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+:deep(
+    .el-table .el-table__header-wrapper th,
+    .el-table .el-table__fixed-header-wrapper th
+  ) {
+  height: auto !important;
+}
+:deep(.el-table th.el-table__cell) {
+  background: #fff !important;
+}
+:deep(.el-table .el-table__cell) {
+  padding: 0 !important;
+}
+:deep(.el-table .cell) {
+  padding: 0 8px !important;
+  font-size: 12px !important;
+}
+
+:deep(.sumRow) {
+  background-color: #f5f7fa !important;
+  .el-table-fixed-column--left,
+  .el-table-fixed-column--right {
+    background-color: #f5f7fa !important;
+  }
+}
+</style>

+ 1 - 1
src/views/systemTenant/tenant/deptTenant/index.vue

@@ -182,7 +182,7 @@ const formConfig = computed(() => {
       prop: "type",
       label: "机构类型",
       data: typeList.value,
-      disabled: modalType.value == "edit" || disabledType.value,
+      disabled: disabledType.value,
       style: {
         width: "100%",
       },