Forráskód Böngészése

feat(财务模块): 新增收款/付款计划管理功能及相关组件

liujt 9 hónapja
szülő
commit
871876d536

+ 673 - 0
src/BIZComponents/paymentCollectionPlan/Detail.vue

@@ -0,0 +1,673 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules">
+    <ele-pro-table
+      ref="table"
+      :needPage="false"
+      :columns="columns"
+      :datasource="form.datasource"
+      :toolkit="[]"
+      class="time-form"
+    >
+      <!-- 表头工具栏 -->
+      <template v-slot:toolbar>
+        <div class="headbox">
+            <!-- <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-plus"
+            class="ele-btn-icon"
+            @click="handlAdd"
+            v-if="type!='view'"
+            >
+            新增
+            </el-button> -->
+
+            <!-- <div class="pricebox">
+                <span class="amount">比例合计:{{ allRatio }}元</span>
+                <span class="amount">计划收款金额合计:{{ allPrice }}元</span>
+            </div> -->
+        </div>
+      </template>
+
+      <template v-slot:headerPeriod="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:period="scope">
+        <span>第{{ scope.row.period }}期</span>
+      </template>
+
+      <template v-slot:moneyName="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.moneyName'"
+          :rules="{
+            required: true,
+            message: '请输入',
+            trigger: 'blur'
+          }"
+        >
+          <el-input
+            v-model="scope.row.moneyName"
+            placeholder="请输入"
+            :disabled="type=='view'"
+
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:headerMoneyName="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:ratio="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.ratio'"
+          :rules="{
+            required: true,
+            pattern: numberReg,
+            message: '请输入正确的比例',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            v-model="scope.row.ratio"
+            placeholder="请输入"
+            :disabled="type=='view'"
+            @input="(val) => ratioInput(val, scope.$index)"
+          >
+            <template slot="append">%</template>
+          </el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:type="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.type'"
+          :rules="{
+            required: true,
+            message: '请选择款项类型',
+            trigger: 'change'
+          }"
+        >
+          <el-select
+            v-model="scope.row.type"
+            placeholder="请选择"
+            style="width: 100%"
+            :disabled="type=='view'"
+
+          >
+            <el-option
+              v-for="item in paymentTypeOp"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </template>
+      <template v-slot:headerRatio="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:headerPrice="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:price="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.price'"
+          :rules="{
+            required: true,
+            pattern: numberReg,
+            message: '请输入正确的金额',
+            trigger: 'change'
+          }"
+        >
+            <el-input
+                type="number"
+                :min="0"
+                :disabled="type=='view'"
+                v-model="scope.row.price"
+                style="width: 100%"
+                placeholder="请输入"
+            >
+                <template slot="append">元</template>
+            </el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:deadLine="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.deadLine'"
+          :rules="{
+            required: true,
+            message: '请选择日期',
+            trigger: 'change'
+          }"
+        >
+          <el-date-picker
+            style="width: 140px"
+            v-model="scope.row.deadLine"
+            :disabled="type=='view'"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:headerDeadLine="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:remark="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.remark'"
+        >
+          <el-input
+            v-model="scope.row.remark"
+            type="textarea"
+            placeholder="请输入"
+            :disabled="type=='view'"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <!-- 操作列 -->
+      <template v-slot:action="{ row }">
+        <el-popconfirm
+          class="ele-action"
+          title="确定要删除吗?"
+          @confirm="remove(row)"
+        >
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+      </template>
+    </ele-pro-table>
+  </el-form>
+</template>
+<script>
+  import { emailReg, phoneReg, numberReg } from 'ele-admin';
+  import { paymentTypeOp } from '@/enum/dict';
+  export default {
+    props: {
+      delDetailIds: Array,
+      type: String,
+      discountTotalPrice: {
+        type: [Number, String],
+        default: 0
+      }
+    },
+    data() {
+      const defaultForm = {
+        key: null,
+        deadLine: null,
+        moneyName: '',
+        price: null,
+        ratio: null,
+        remark: '',
+        type: '',
+        period: null
+      };
+      return {
+        // allPrice: 0,
+        // allRatio: 0,
+        numberReg,
+        defaultForm,
+        discountAmount: 0,
+        form: {
+          datasource: []
+        },
+        paymentTypeOp,
+
+        rules: {}
+      };
+    },
+    computed: {
+      canHandl() {
+        return this.form.datasource.length;
+      },
+      columns() {
+        return [
+          {
+            width: 45,
+            type: 'index',
+            columnKey: 'index',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '收款计划编码',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '发票号',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '关联应收编码',
+            align: 'center'
+          },
+          {
+            prop: 'period',
+            label: '期数',
+            slot: 'period',
+            headerSlot: 'headerPeriod',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '款项类型',
+            slot: 'type',
+            headerSlot: 'headerMoneyName',
+            align: 'center'
+          },
+          {
+            prop: 'moneyName',
+            label: '款项名称',
+            slot: 'moneyName',
+            headerSlot: 'headerMoneyName',
+            align: 'center',
+            width: 170
+          },
+          {
+            width: 150,
+            prop: 'ratio',
+            label: '比例',
+            slot: 'ratio',
+            headerSlot: 'headerRatio',
+            align: 'center'
+          },
+          {
+            width: 170,
+            prop: 'price',
+            label: '计划收款金额',
+            slot: 'price',
+            align: 'center',
+            headerSlot: 'headerPrice',
+          },
+
+          {
+            width: 160,
+            prop: 'deadLine',
+            label: '计划收款日期',
+            slot: 'deadLine',
+            headerSlot: 'headerDeadLine',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '是否已开票',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '已开票金额',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '开票日期',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '是否生成应收款项',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '应收金额',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '已收款金额',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '实际收款日期',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '发货状态',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '对账状态',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'remark',
+            label: '收款状态',
+            slot: 'remark',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '逾期状态',
+            align: 'center'
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true,
+            show: this.type != 'view'
+          }
+        ];
+      },
+      allRatio() {
+        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.ratio), 0).toFixed(2);
+      },
+      allPrice() {
+        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.price), 0).toFixed(2);
+      },
+    },
+    watch: {
+      discountAmount(newval) {
+        if (newval) {
+          this.refreshprice();
+        }
+      }
+    },
+    methods: {
+      setDiscountAmount(val) {
+        this.discountAmount = val;
+      },
+      //输入比例更新金额
+      async ratioInput(val, index = null) {
+        val = Number(val);
+        try {
+          if (index != null) {
+            await this.checkRatio();
+          }
+          let newval = (val / 100).toFixed(2);
+          let price = (this.discountAmount * newval).toFixed(2);
+          console.log(newval, price, index, '88888');
+          if (index != null) {
+            console.log(newval, price, index, '999999');
+            this.$set(this.form.datasource[index], 'price', price);
+          } else {
+            return price;
+          }
+        } catch (error) {
+          return 0;
+        }
+
+        //this.$set( this.form.datasource[index], 'price',  price)
+      },
+      //检验比例
+      checkRatio() {
+        return new Promise((resolve, reject) => {
+          let newData = this.form.datasource,
+            sum = 0;
+          newData.forEach((r) => {
+            if (r.ratio) {
+              sum += Number(r.ratio);
+            }
+          });
+          console.log(sum, '3333333');
+          if (sum > 100) {
+            this.$message.error('总共比例不能超过100');
+            this.$set(
+              this.form.datasource[this.form.datasource.length - 1],
+              'ratio',
+              null
+            );
+            this.$set(
+              this.form.datasource[this.form.datasource.length - 1],
+              'price',
+              0.0
+            );
+            reject(false);
+          } else {
+            resolve(true);
+          }
+        });
+      },
+      refreshprice() {
+        let newData = this.form.datasource;
+        newData.forEach(async (r, index) => {
+          if (r.ratio) {
+            console.log(this.ratioInput(Number(r.ratio)), '9999888888');
+            r.price = await this.ratioInput(Number(r.ratio));
+          }
+        });
+      },
+      // 返回列表数据
+      getTableValue() {
+        return this.form.datasource;
+      },
+      //修改回显
+      putTableValue(data) {
+        if (data && data?.length) {
+          this.form.datasource = data;
+        }
+      },
+      remove(row) {
+        let index = this.form.datasource.findIndex((n) => n.key == row.key);
+        if (index !== -1) {
+          this.form.datasource.splice(index, 1);
+          this.setSort();
+          if (row.id) {
+            this.delDetailIds.push(row.id);
+          }
+        }
+      },
+      // 清空表格
+      restTable() {
+        this.form.datasource = [];
+      },
+      // 重新排序
+      setSort() {
+        this.form.datasource.forEach((n, index) => {
+          n.key = index + 1;
+        });
+      },
+      defaultList(method, period, dateRange) {
+        console.log('method, period', method, period);
+        const tempList = []
+        if(dateRange) {
+          this.setDefaultList(dateRange, period);
+          return
+        }
+        if(method == 3) {
+          let params = ['预付款', '交货款'];
+          for(let i = 0; i < period; i++) {
+            let i = JSON.parse(JSON.stringify(this.defaultForm));
+              i.moneyName = item;
+              i.type = i < params.length ? this.paymentTypeOp[index].value : '';
+              i.key = index + 1;
+              i.period = index + 1;
+              tempList.push(i);
+          }
+          // params.forEach((item, index) => {
+          //     let i = JSON.parse(JSON.stringify(this.defaultForm));
+          //     i.moneyName = item;
+          //     i.type = this.paymentTypeOp[index].value;
+          //     i.key = index + 1;
+          //     i.period = index + 1;
+          //     tempList.push(i);
+          // });
+        } else {
+          // method == 4 || method == 5 || method == 6 || method == 7 || method == 8
+          let params = [''];
+          params.forEach((item, index) => {
+              let i = JSON.parse(JSON.stringify(this.defaultForm));
+              i.key = index + 1;
+              i.period = index + 1;
+              tempList.push(i);
+          });
+        }
+        this.form.datasource = tempList;
+      },
+
+      transformDaysFun(date) {
+        const startDate = new Date(date[0]);
+        const endDate = new Date(date[1]);
+        // 计算毫秒差并转换为天数,使用Math.ceil确保结果为整数
+        const days = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24)) + 1;
+        console.log('包含两头的天数:', days);
+
+        // 生成包括头尾在内的所有日期
+        const allDates = [];
+        const current = new Date(startDate);
+        
+        // 遍历从开始日期到结束日期的所有天数
+        while (current <= endDate) {
+          // 格式化日期为YYYY-MM-dd
+          const year = current.getFullYear();
+          const month = current.getMonth() + 1; // 月份从0开始,需要+1
+          const day = current.getDate();
+          
+          const formattedMonth = String(month).padStart(2, '0');
+          const formattedDay = String(day).padStart(2, '0');
+          const formattedDateStr = `${year}-${formattedMonth}-${formattedDay}`;
+          
+          allDates.push(formattedDateStr);
+          
+          // 移动到下一天
+          current.setDate(current.getDate() + 1);
+        }
+        return allDates;
+      },
+
+      transformMonthFun(date, day) {
+        // 处理月份数据(转换为Date对象)
+        const parseMonthDate = (dateStr) => {
+          return dateStr instanceof Date ? dateStr : new Date(dateStr + '-01');
+        };
+        
+        const start = parseMonthDate(date[0]);
+        const end = parseMonthDate(date[1]);
+        
+        // 先生成所有月份的日期数组
+        const allMonthDates = [];
+        const currentDate = new Date(start);
+        
+        // 遍历从开始月份到结束月份的所有月份
+        while (currentDate <= end) {
+          const year = currentDate.getFullYear();
+          const month = currentDate.getMonth() + 1; // 月份从0开始,需要+1
+          const receiptDate = day;
+          
+          // 格式化日期为YYYY-MM-dd
+          const formattedMonth = String(month).padStart(2, '0');
+          const formattedDate = String(receiptDate).padStart(2, '0');
+          const deadLine = receiptDate ? `${year}-${formattedMonth}-${formattedDate}` : '';
+          
+          allMonthDates.push(deadLine);
+          
+          // 使用Date对象的setMonth方法正确移动到下一个月(自动处理年份变化)
+          currentDate.setMonth(currentDate.getMonth() + 1);
+        }
+        return allMonthDates;
+      },
+      setDefaultList(dateRange, period) {
+        const tempPeriod = period || 0;
+
+        // 计算基本比例
+        const basicRatio = 100 / tempPeriod;
+        let totalRatio = 0;
+        
+        // 生成付款计划列表项
+        const tempList = [];
+        
+        // 根据传入的period参数生成付款计划
+        for (let i = 0; i < tempPeriod; i++) {
+          let item = JSON.parse(JSON.stringify(this.defaultForm));
+          // 获取日期:如果i小于日期数组长度则使用对应日期,否则设为空
+          const deadLine = i < dateRange.length ? dateRange[i] : '';
+          const ratio = parseFloat(basicRatio.toFixed(2));
+
+          item.period = i + 1;
+          item.deadLine = deadLine;
+          item.ratio = ratio;
+
+          tempList.push(item);
+          totalRatio += ratio;
+        }
+        
+        // 调整最后一项的比例,确保总和为100
+        if (tempList.length > 0) {
+          const difference = 100 - totalRatio;
+          if (difference !== 0) {
+            tempList[tempList.length - 1].ratio = parseFloat((tempList[tempList.length - 1].ratio + difference).toFixed(2));
+          }
+        }
+        
+        console.log('付款计划列表:~~', tempList);
+        this.form.datasource = tempList;
+        // this.$set(this.form, 'datasource', tempList);
+        console.log('付款计划列表:', this.form.datasource);
+      },
+      // 添加
+      handlAdd() {
+        let item = JSON.parse(JSON.stringify(this.defaultForm));
+        item.key = this.form.datasource.length + 1;
+        this.form.datasource.push(item);
+      },
+
+      validateForm(callback) {
+        //开始表单校验
+        this.$refs.form.validate((valid) => {
+          callback(valid);
+        });
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .time-form .el-form-item {
+    margin-bottom: 0 !important;
+  }
+
+  .headbox {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      padding-right: 30px;
+    }
+  }
+
+  .pricebox {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      font-weight: bold;
+    }
+    :deep(.el-input-group__append) {
+      padding: 0;
+    }
+</style>

+ 619 - 0
src/BIZComponents/paymentCollectionPlan/Index.vue

@@ -0,0 +1,619 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules">
+    <ele-pro-table
+      ref="table"
+      :needPage="false"
+      :columns="columns"
+      :datasource="form.datasource"
+      :toolkit="[]"
+      class="time-form"
+    >
+      <!-- 表头工具栏 -->
+      <template v-slot:toolbar>
+        <div class="headbox">
+            <el-button
+            size="small"
+            type="primary"
+            icon="el-icon-plus"
+            class="ele-btn-icon"
+            @click="handlAdd"
+            v-if="type!='view'"
+            >
+            新增
+            </el-button>
+
+            <div class="pricebox">
+                <span class="amount">比例合计:{{ allRatio }}元</span>
+                <span class="amount">计划收款金额合计:{{ allPrice }}元</span>
+
+                <!-- <el-form-item
+                    style="width: 300px"
+                    label="优惠后总金额:"
+                    prop="discountTotalPrice"
+                    :rules="{
+                        required: true,
+                        message: '请输入优惠后总金额',
+                        trigger: 'change'
+                    }"
+                >
+                    <el-input
+                    type="number"
+                    :min="0"
+                    :max="allPrice"
+                    :disabled="!allPrice"
+                    v-model="form.discountTotalPrice"
+                    style="width: 180px"
+                    placeholder="请输入"
+                    @input="discountInputByOrder(form.discountTotalPrice)"
+                    >
+                    <template slot="append">元</template>
+                    </el-input>
+                </el-form-item> -->
+            </div>
+        </div>
+      </template>
+
+      <template v-slot:headerPeriod="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:period="scope">
+        <span>第{{ scope.row.period }}期</span>
+      </template>
+
+      <template v-slot:moneyName="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.moneyName'"
+          :rules="{
+            required: true,
+            message: '请输入',
+            trigger: 'blur'
+          }"
+        >
+          <el-input
+            v-model="scope.row.moneyName"
+            placeholder="请输入"
+            :disabled="type=='view'"
+
+          ></el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:headerMoneyName="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:ratio="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.ratio'"
+          :rules="{
+            required: true,
+            pattern: numberReg,
+            message: '请输入正确的比例',
+            trigger: 'change'
+          }"
+        >
+          <el-input
+            v-model="scope.row.ratio"
+            placeholder="请输入"
+            :disabled="type=='view'"
+            @input="(val) => ratioInput(val, scope.$index)"
+          >
+            <template slot="append">%</template>
+          </el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:type="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.type'"
+          :rules="{
+            required: true,
+            message: '请选择款项类型',
+            trigger: 'change'
+          }"
+        >
+          <el-select
+            v-model="scope.row.type"
+            placeholder="请选择"
+            style="width: 100%"
+            :disabled="type=='view'"
+
+          >
+            <el-option
+              v-for="item in paymentTypeOp"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </template>
+      <template v-slot:headerRatio="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+
+      <template v-slot:headerPrice="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:price="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.price'"
+          :rules="{
+            required: true,
+            pattern: numberReg,
+            message: '请输入正确的金额',
+            trigger: 'change'
+          }"
+        >
+            <el-input
+                type="number"
+                :min="0"
+                :disabled="type=='view'"
+                v-model="scope.row.price"
+                style="width: 100%"
+                placeholder="请输入"
+            >
+                <template slot="append">元</template>
+            </el-input>
+        </el-form-item>
+      </template>
+      <template v-slot:deadLine="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.deadLine'"
+          :rules="{
+            required: true,
+            message: '请选择日期',
+            trigger: 'change'
+          }"
+        >
+          <el-date-picker
+            style="width: 140px"
+            v-model="scope.row.deadLine"
+            :disabled="type=='view'"
+            type="date"
+            placeholder="选择日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+      </template>
+      <template v-slot:headerDeadLine="{ column }">
+        <span class="is-required">{{ column.label }}</span>
+      </template>
+      <template v-slot:remark="scope">
+        <el-form-item
+          style="margin-bottom: 20px"
+          :prop="'datasource.' + scope.$index + '.remark'"
+        >
+          <el-input
+            v-model="scope.row.remark"
+            type="textarea"
+            placeholder="请输入"
+            :disabled="type=='view'"
+          ></el-input>
+        </el-form-item>
+      </template>
+      <!-- 操作列 -->
+      <template v-slot:action="{ row }">
+        <el-popconfirm
+          class="ele-action"
+          title="确定要删除吗?"
+          @confirm="remove(row)"
+        >
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+      </template>
+    </ele-pro-table>
+  </el-form>
+</template>
+<script>
+  import { emailReg, phoneReg, numberReg } from 'ele-admin';
+  import { paymentTypeOp } from '@/enum/dict';
+  export default {
+    props: {
+      delDetailIds: Array,
+      type: String,
+      discountTotalPrice: {
+        type: [Number, String],
+        default: 0
+      }
+    },
+    data() {
+      const defaultForm = {
+        key: null,
+        deadLine: null,
+        moneyName: '',
+        price: null,
+        ratio: null,
+        remark: '',
+        type: '',
+        period: null
+      };
+      return {
+        // allPrice: 0,
+        // allRatio: 0,
+        numberReg,
+        defaultForm,
+        discountAmount: 0,
+        form: {
+          datasource: []
+        },
+        paymentTypeOp,
+
+        rules: {}
+      };
+    },
+    computed: {
+      canHandl() {
+        return this.form.datasource.length;
+      },
+      columns() {
+        return [
+          {
+            width: 45,
+            type: 'index',
+            columnKey: 'index',
+            align: 'center',
+            fixed: 'left'
+          },
+          {
+            prop: 'period',
+            label: '期数',
+            slot: 'period',
+            headerSlot: 'headerPeriod',
+            align: 'center'
+          },
+          {
+            width: 120,
+            prop: 'type',
+            label: '款项类型',
+            slot: 'type',
+            headerSlot: 'headerMoneyName',
+            align: 'center'
+          },
+          {
+            prop: 'moneyName',
+            label: '款项名称',
+            slot: 'moneyName',
+            headerSlot: 'headerMoneyName',
+            align: 'center',
+            width: 170
+          },
+          {
+            width: 150,
+            prop: 'ratio',
+            label: '比例',
+            slot: 'ratio',
+            headerSlot: 'headerRatio',
+            align: 'center'
+          },
+          {
+            width: 170,
+            prop: 'price',
+            label: '计划收款金额',
+            slot: 'price',
+            align: 'center',
+            headerSlot: 'headerPrice',
+          },
+
+          {
+            width: 160,
+            prop: 'deadLine',
+            label: '计划收款日期',
+            slot: 'deadLine',
+            headerSlot: 'headerDeadLine',
+            align: 'center'
+          },
+          {
+            width: 220,
+            prop: 'remark',
+            label: '说明',
+            slot: 'remark',
+            align: 'center'
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true,
+            show: this.type != 'view'
+          }
+        ];
+      },
+      allRatio() {
+        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.ratio), 0).toFixed(2);
+      },
+      allPrice() {
+        return this.form.datasource.reduce((acc, cur) => acc + Number(cur.price), 0).toFixed(2);
+      },
+    },
+    watch: {
+      discountAmount(newval) {
+        if (newval) {
+          this.refreshprice();
+        }
+      }
+    },
+    methods: {
+      setDiscountAmount(val) {
+        this.discountAmount = val;
+      },
+      //输入比例更新金额
+      async ratioInput(val, index = null) {
+        val = Number(val);
+        try {
+          if (index != null) {
+            await this.checkRatio();
+          }
+          let newval = (val / 100).toFixed(2);
+          let price = (this.discountAmount * newval).toFixed(2);
+          console.log(newval, price, index, '88888');
+          if (index != null) {
+            console.log(newval, price, index, '999999');
+            this.$set(this.form.datasource[index], 'price', price);
+          } else {
+            return price;
+          }
+        } catch (error) {
+          return 0;
+        }
+
+        //this.$set( this.form.datasource[index], 'price',  price)
+      },
+      //检验比例
+      checkRatio() {
+        return new Promise((resolve, reject) => {
+          let newData = this.form.datasource,
+            sum = 0;
+          newData.forEach((r) => {
+            if (r.ratio) {
+              sum += Number(r.ratio);
+            }
+          });
+          console.log(sum, '3333333');
+          if (sum > 100) {
+            this.$message.error('总共比例不能超过100');
+            this.$set(
+              this.form.datasource[this.form.datasource.length - 1],
+              'ratio',
+              null
+            );
+            this.$set(
+              this.form.datasource[this.form.datasource.length - 1],
+              'price',
+              0.0
+            );
+            reject(false);
+          } else {
+            resolve(true);
+          }
+        });
+      },
+      refreshprice() {
+        let newData = this.form.datasource;
+        newData.forEach(async (r, index) => {
+          if (r.ratio) {
+            console.log(this.ratioInput(Number(r.ratio)), '9999888888');
+            r.price = await this.ratioInput(Number(r.ratio));
+          }
+        });
+      },
+      // 返回列表数据
+      getTableValue() {
+        return this.form.datasource;
+      },
+      //修改回显
+      putTableValue(data) {
+        if (data && data?.length) {
+          this.form.datasource = data;
+        }
+      },
+      remove(row) {
+        let index = this.form.datasource.findIndex((n) => n.key == row.key);
+        if (index !== -1) {
+          this.form.datasource.splice(index, 1);
+          this.setSort();
+          if (row.id) {
+            this.delDetailIds.push(row.id);
+          }
+        }
+      },
+      // 清空表格
+      restTable() {
+        this.form.datasource = [];
+      },
+      // 重新排序
+      setSort() {
+        this.form.datasource.forEach((n, index) => {
+          n.key = index + 1;
+        });
+      },
+      defaultList(method, period, dateRange) {
+        console.log('method, period', method, period);
+        const tempList = []
+        if(dateRange) {
+          this.setDefaultList(dateRange, period);
+          return
+        }
+        if(method == 3) {
+          let params = ['预付款', '交货款'];
+          for(let i = 0; i < period; i++) {
+            let i = JSON.parse(JSON.stringify(this.defaultForm));
+              i.moneyName = item;
+              i.type = i < params.length ? this.paymentTypeOp[index].value : '';
+              i.key = index + 1;
+              i.period = index + 1;
+              tempList.push(i);
+          }
+          // params.forEach((item, index) => {
+          //     let i = JSON.parse(JSON.stringify(this.defaultForm));
+          //     i.moneyName = item;
+          //     i.type = this.paymentTypeOp[index].value;
+          //     i.key = index + 1;
+          //     i.period = index + 1;
+          //     tempList.push(i);
+          // });
+        } else {
+          // method == 4 || method == 5 || method == 6 || method == 7 || method == 8
+          let params = [''];
+          params.forEach((item, index) => {
+              let i = JSON.parse(JSON.stringify(this.defaultForm));
+              i.key = index + 1;
+              i.period = index + 1;
+              tempList.push(i);
+          });
+        }
+        this.form.datasource = tempList;
+      },
+
+      transformDaysFun(date) {
+        const startDate = new Date(date[0]);
+        const endDate = new Date(date[1]);
+        // 计算毫秒差并转换为天数,使用Math.ceil确保结果为整数
+        const days = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24)) + 1;
+        console.log('包含两头的天数:', days);
+
+        // 生成包括头尾在内的所有日期
+        const allDates = [];
+        const current = new Date(startDate);
+        
+        // 遍历从开始日期到结束日期的所有天数
+        while (current <= endDate) {
+          // 格式化日期为YYYY-MM-dd
+          const year = current.getFullYear();
+          const month = current.getMonth() + 1; // 月份从0开始,需要+1
+          const day = current.getDate();
+          
+          const formattedMonth = String(month).padStart(2, '0');
+          const formattedDay = String(day).padStart(2, '0');
+          const formattedDateStr = `${year}-${formattedMonth}-${formattedDay}`;
+          
+          allDates.push(formattedDateStr);
+          
+          // 移动到下一天
+          current.setDate(current.getDate() + 1);
+        }
+        return allDates;
+      },
+
+      transformMonthFun(date, day) {
+        // 处理月份数据(转换为Date对象)
+        const parseMonthDate = (dateStr) => {
+          return dateStr instanceof Date ? dateStr : new Date(dateStr + '-01');
+        };
+        
+        const start = parseMonthDate(date[0]);
+        const end = parseMonthDate(date[1]);
+        
+        // 先生成所有月份的日期数组
+        const allMonthDates = [];
+        const currentDate = new Date(start);
+        
+        // 遍历从开始月份到结束月份的所有月份
+        while (currentDate <= end) {
+          const year = currentDate.getFullYear();
+          const month = currentDate.getMonth() + 1; // 月份从0开始,需要+1
+          const receiptDate = day;
+          
+          // 格式化日期为YYYY-MM-dd
+          const formattedMonth = String(month).padStart(2, '0');
+          const formattedDate = String(receiptDate).padStart(2, '0');
+          const deadLine = receiptDate ? `${year}-${formattedMonth}-${formattedDate}` : '';
+          
+          allMonthDates.push(deadLine);
+          
+          // 使用Date对象的setMonth方法正确移动到下一个月(自动处理年份变化)
+          currentDate.setMonth(currentDate.getMonth() + 1);
+        }
+        return allMonthDates;
+      },
+      setDefaultList(dateRange, period) {
+        const tempPeriod = period || 0;
+
+        // 计算基本比例
+        const basicRatio = 100 / tempPeriod;
+        let totalRatio = 0;
+        
+        // 生成付款计划列表项
+        const tempList = [];
+        
+        // 根据传入的period参数生成付款计划
+        for (let i = 0; i < tempPeriod; i++) {
+          let item = JSON.parse(JSON.stringify(this.defaultForm));
+          // 获取日期:如果i小于日期数组长度则使用对应日期,否则设为空
+          const deadLine = i < dateRange.length ? dateRange[i] : '';
+          const ratio = parseFloat(basicRatio.toFixed(2));
+
+          item.period = i + 1;
+          item.deadLine = deadLine;
+          item.ratio = ratio;
+
+          tempList.push(item);
+          totalRatio += ratio;
+        }
+        
+        // 调整最后一项的比例,确保总和为100
+        if (tempList.length > 0) {
+          const difference = 100 - totalRatio;
+          if (difference !== 0) {
+            tempList[tempList.length - 1].ratio = parseFloat((tempList[tempList.length - 1].ratio + difference).toFixed(2));
+          }
+        }
+        
+        console.log('付款计划列表:~~', tempList);
+        this.form.datasource = tempList;
+        // this.$set(this.form, 'datasource', tempList);
+        console.log('付款计划列表:', this.form.datasource);
+      },
+      // 添加
+      handlAdd() {
+        let item = JSON.parse(JSON.stringify(this.defaultForm));
+        item.key = this.form.datasource.length + 1;
+        this.form.datasource.push(item);
+      },
+
+      validateForm(callback) {
+        //开始表单校验
+        this.$refs.form.validate((valid) => {
+          callback(valid);
+        });
+      }
+    }
+  };
+</script>
+<style lang="scss" scoped>
+  .time-form .el-form-item {
+    margin-bottom: 0 !important;
+  }
+
+  .headbox {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      padding-right: 30px;
+    }
+  }
+
+  .pricebox {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      font-weight: bold;
+    }
+    :deep(.el-input-group__append) {
+      padding: 0;
+    }
+</style>

+ 268 - 0
src/views/financialManage/collectionPlan/components/detailDialog.vue

@@ -0,0 +1,268 @@
+<template>
+  <ele-modal
+    custom-class="ele-dialog-form long-dialog-form"
+    :centered="true"
+    v-if="visible"
+    :visible.sync="visible"
+    :title="title"
+    :close-on-click-modal="false"
+    :append-to-body="true"
+    width="70%"
+    @close="cancel"
+    :maxable="true"
+    :resizable="true"
+  >
+    <!-- <div class="switch">
+      <div class="switch_left">
+        <ul>
+          <li
+            v-for="item in tabOptions"
+            :key="item.key"
+            :class="{ active: activeComp == item.key }"
+            @click="changeK(item.key)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+    </div> -->
+    <div v-if="activeComp === 'main'">
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <headerTitle title="基本信息"></headerTitle>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="收款计划编码:" prop="type">
+              <el-input v-model="form.categoryName" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="合同编码:" prop="type">
+              <el-input v-model="form.categoryName" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="客户编码:" prop="type">
+              <el-input v-model="form.categoryName" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="交易方式:" prop="type">
+              <el-input v-model="form.categoryName" disabled></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="订单编码:" prop="HJQD" v-if="form.sourceType == 2">
+              <el-input v-model="form.HJQD" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="合同编号:" prop="contractStartDate">
+              <el-input v-model="form.contractStartDate" disabled></el-input>
+            </el-form-item>
+
+            <el-form-item label="客户名称:" prop="contractEndDate">
+              <el-input v-model="form.contractEndDate" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="发货模式:" prop="contractName">
+              <el-input v-model="form.contractName" disabled></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item prop="productionRequirements" label="订单类型:">
+              <el-input v-model="form.productionRequirements" disabled></el-input>
+            </el-form-item>
+            <el-form-item prop="productionRequirements" label="合同名称:">
+              <el-input v-model="form.productionRequirements" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="结算方式:" prop="payWay">
+              <el-input v-model="form.settlementModeName" disabled></el-input>
+            </el-form-item>
+            <el-form-item prop="contractFile" label="附件:">
+              <fileMain v-model="form.fileId" type="view"></fileMain>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <headerTitle
+        :title="form.type == '2' ? '付款计划' : '收款计划'"
+        style="margin-top: 30px"
+      ></headerTitle>
+      <paymentCollectionPlanDetail
+        ref="paymentCollectionPlanDetailRef"
+        type="view"
+      ></paymentCollectionPlanDetail>
+    </div>
+    <bpmDetail
+      v-if="activeComp === 'bpm' && form.processInstanceId"
+      :id="form.processInstanceId"
+    ></bpmDetail>
+    <div slot="footer" class="footer">
+      <el-button @click="cancel">返回</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import { getDetail, getExport } from '@/api/contractManage/contractBook';
+  import { getFile } from '@/api/system/file';
+  import dictMixins from '@/mixins/dictMixins';
+  import { copyObj } from '@/utils/util';
+  import bpmDetail from '@/views/bpm/processInstance/detail.vue';
+  import inventoryTabledetail from '@/BIZComponents/inventoryTableDetails.vue';
+  import paymentCollectionPlanDetail from '@/BIZComponents/paymentCollectionPlan/Detail.vue';
+
+  export default {
+    mixins: [dictMixins],
+    components: {
+      inventoryTabledetail,
+      bpmDetail,
+      paymentCollectionPlanDetail
+    },
+    data() {
+      return {
+        fullscreen: false,
+        cacheKeyUrl: 'eos-contractManage-contractBook-inventoryTableDetails',
+        activeName: '1',
+        activeComp: 'main',
+        tabOptions: [
+          { key: 'main', name: '合同详情' },
+          { key: 'bpm', name: '流程详情' },
+        ],
+        visible: false,
+        detailId: '',
+        title: '详情',
+        row: {},
+        form: {},
+        rules: {},
+        detailData: {},
+        sourceTypeList: [
+          {
+            code: 1,
+            name: '报价单',
+            parentId: '1'
+          },
+          {
+            code: 2,
+            name: '核价单',
+            parentId: '2'
+          },
+          {
+            code: 3,
+            name: '采购计划',
+            parentId: '2'
+          },
+          {
+            code: 4,
+            name: '商机',
+            parentId: '1'
+          },
+          {
+            code: 5,
+            name: '退货单',
+            parentId: '1'
+          },
+          {
+            code: 6,
+            name: '客户',
+            parentId: '1'
+          },
+          {
+            code: 7,
+            name: '销售订单',
+            parentId: '1'
+          }
+        ]
+      };
+    },
+    methods: {
+      //导出
+      async exportTable() {
+        this.loading = true;
+        const response = await getExport(this.detailId);
+      },
+      async open(row) {
+        console.log(row);
+        this.form = row;
+        this.activeComp = 'main';
+        this.visible = true;
+        this.activeName = '1';
+        this.getDetailData(row.id);
+        this.detailId = row.id;
+      },
+      changeK(key) {
+        this.activeComp = key;
+        if (key == 'main') {
+          this.$nextTick(() => {
+            this.$refs.inventoryTabledetailRef &&
+              this.$refs.inventoryTabledetailRef.putTableValue({
+                ...this.detailData,
+                ...this.detailData.contractVO
+              });
+            this.$refs.rawDetailListRef &&
+              this.$refs.rawDetailListRef.putTableValueNew(this.form.rawList); //原料
+            this.$refs.outputDetailListRef &&
+              this.$refs.outputDetailListRef.putTableValueNew(
+                this.form.outputList
+              );
+          });
+        }
+        if (key == 'changeList') {
+          this.$nextTick(() => {
+            this.$refs.changeList.init(this.form.id);
+          });
+        }
+      },
+      cancel() {
+        this.$nextTick(() => {
+          // 关闭后,销毁所有的表单数据
+          (this.form = copyObj(this.formDef)),
+            (this.otherForm = copyObj(this.otherFormDef)),
+            (this.tableBankData = []);
+          this.tableLinkData = [];
+          this.visible = false;
+        });
+      },
+      downloadFile(file) {
+        getFile({ objectName: file.storePath }, file.name);
+      },
+      async getDetailData(id) {
+        this.loading = true;
+        const data = await getDetail(id);
+        this.loading = false;
+        if (data) {
+          data.productList.forEach((item) => {
+            item['pricingWay'] = item.pricingWay || data.contractVO?.pricingWay;
+          });
+          this.detailData = data;
+          this.form = data.contractVO;
+          this.$refs.paymentListTable &&
+            this.$refs.paymentListTable.putTableValue(data.receiptPaymentList);
+          this.$nextTick(() => {
+            this.$refs.inventoryTabledetailRef &&
+              this.$refs.inventoryTabledetailRef.putTableValue({
+                ...data,
+                ...data.contractVO
+              });
+            this.$refs.rawDetailListRef &&
+              this.$refs.rawDetailListRef.putTableValueNew(this.form.rawList); //原料
+            this.$refs.outputDetailListRef &&
+              this.$refs.outputDetailListRef.putTableValueNew(
+                this.form.outputList
+              );
+          });
+        }
+      }
+    }
+  };
+</script>
+
+<style scoped lang="scss">
+  .ele-dialog-form {
+    .el-form-item {
+      margin-bottom: 10px;
+    }
+  }
+
+  .headbox {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    .amount {
+      font-size: 14px;
+      font-weight: bold;
+      margin-right: 20px;
+    }
+  }
+</style>

+ 75 - 0
src/views/financialManage/collectionPlan/components/searchTable.vue

@@ -0,0 +1,75 @@
+<!-- 搜索表单 -->
+<template>
+  <seekPage :seekList="seekList" :formLength="3" @search="search"></seekPage>
+</template>
+<script>
+import { paymentTypeOp } from '@/enum/dict';
+
+export default {
+  data() {
+    return {
+      paymentTypeOp,
+      overdueOptions: [{
+        label: '未逾期',
+        value: 1
+      },
+      {
+        label: '逾期中',
+        value: 0
+      }],
+      collectionTypeOp: [{
+        label: '收款计划',
+        value: 1
+      },
+      {
+        label: '收款单',
+        value: 0
+      }],
+    };
+  },
+  computed: {
+    // 表格列配置
+    seekList() {
+      return [
+        {
+          label: '关键字:',
+          value: 'searchName',
+          type: 'input',
+          placeholder: '收款计划编码/来源单据编码/客户名称'
+        },
+        {
+          label: '款项类型:',
+          value: 'collectionType',
+          type: 'select',
+          planList: this.paymentTypeOp,
+          placeholder: '请选择'
+        },
+        {
+          label: '逾期状态:',
+          value: 'orderStatus',
+          type: 'select',
+          planList: this.overdueOptions,
+          width: 380,
+          placeholder: ''
+        },
+        {
+          label: '查询日期:',
+          value: 'createTime',
+          type: 'date',
+          dateType: 'datetimerange',
+          placeholder: '',
+          width: 380,
+          valueAr: ['createTimeStart', 'createTimeEnd']
+        }
+      ];
+    }
+  },
+  methods: {
+    search(e) {
+      this.$emit('search', {
+        ...e
+      });
+    }
+  }
+};
+</script>

+ 722 - 0
src/views/financialManage/collectionPlan/index.vue

@@ -0,0 +1,722 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never" v-loading="loading">
+      <div class="switch">
+        <div class="switch_left">
+          <ul>
+            <li
+              v-for="item in tabOptions"
+              :key="item.key"
+              :class="{ active: activeComp == item.key }"
+              @click="activeComp = item.key"
+              style="height: 42px; line-height: 38px"
+            >
+              <!-- <el-badge :value="toDoReminder[item.reminder] || 0" class="item"> -->
+                {{ item.name }}
+              <!-- </el-badge> -->
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class="main" style="padding: 0 10px">
+        <div v-if="activeComp == 'collectionPlan'">
+          <div class="ele-border-lighter form-content" v-loading="loading">
+            <search-table @search="reload"></search-table>
+
+            <!-- 数据表格 -->
+            <ele-pro-table
+              ref="table"
+              :columns="columns"
+              :datasource="datasource"
+              height="calc(100vh - 365px)"
+              style="margin-bottom: 10px"
+              full-height="calc(100vh - 116px)"
+              tool-class="ele-toolbar-form"
+              :selection.sync="selection"
+              :page-size="20"
+              @columns-change="handleColumnChange"
+              :cache-key="cacheKeyUrl"
+            >
+              <!-- 表头工具栏 -->
+              <template v-slot:toolbar>
+                <el-button
+                  size="small"
+                  type="primary"
+                  icon="el-icon-plus"
+                  class="ele-btn-icon"
+                  @click="openEdit('add', {})"
+                >
+                  合并开票
+                </el-button>
+              </template>
+
+              <!-- 查看详情列 -->
+              <template v-slot:relationName="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  @click="openDetail(row)"
+                >
+                  {{ row.relationName }}
+                </el-link>
+              </template>
+              <template v-slot:orderNo="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  @click="openDetail(row)"
+                >
+                  {{ row.orderNo }}
+                </el-link>
+              </template>
+              <!-- 操作列 -->
+              <template v-slot:action="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  icon="el-icon-edit"
+                  v-if="
+                    (isNeed_process_is_close &&
+                      [0, 3].includes(row.orderStatus)) ||
+                    !isNeed_process_is_close
+                  "
+                  @click="openEdit('edit', row)"
+                >
+                  修改
+                </el-link>
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  icon="el-icon-plus"
+                  @click="saleOrderSubmit(row)"
+                  v-if="
+                    isNeed_process_is_close && [0, 3].includes(row.orderStatus)
+                  "
+                >
+                  提交
+                </el-link>
+                <el-popconfirm
+                  class="ele-action"
+                  title="确定要删除此信息吗?"
+                  v-if="
+                    (isNeed_process_is_close &&
+                      [0, 3].includes(row.orderStatus)) ||
+                    !isNeed_process_is_close
+                  "
+                  @confirm="remove([row.id])"
+                >
+                  <template v-slot:reference>
+                    <el-link
+                      type="danger"
+                      :underline="false"
+                      icon="el-icon-delete"
+                    >
+                      删除
+                    </el-link>
+                  </template>
+                </el-popconfirm>
+      
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  icon="el-icon-plus"
+                  @click="handleCommand('invoiceManage', row)"
+                  v-if="!row.hasInvoiceApply && [2].includes(row.orderStatus)"
+                >
+                  新增发票
+                </el-link>
+              </template>
+            </ele-pro-table>
+          </div>
+        </div>
+      </div>
+    </el-card>
+    <detailDialog ref="detailDialogRef"></detailDialog>
+    <contractr-detail ref="contractDetailRef"></contractr-detail>
+    <purchasingDetail ref="purchasingDetailRef"></purchasingDetail>
+    <purchasePlanDetail ref="purchasePlanDetailRef"></purchasePlanDetail>
+    <inquiryDetail ref="inquiryDetailRef"></inquiryDetail>
+
+    <!-- 多选删除弹窗 -->
+    <pop-modal
+      :visible.sync="delVisible"
+      content="是否确定删除?"
+      @done="commitBtn"
+    />
+    <process-submit-dialog
+      :isNotNeedProcess="true"
+      :isCloseRefresh="false"
+      :processSubmitDialogFlag.sync="processSubmitDialogFlag"
+      v-if="processSubmitDialogFlag"
+      ref="processSubmitDialogRef"
+      @reload="reload"
+    ></process-submit-dialog>
+ 
+    <importDialog
+      ref="importDialogRef"
+      @success="reload"
+      :fileUrl="'/eom/purchaseorder/importTemplate'"
+      :isWeb="false"
+      fileName="采购订单导入模板"
+      apiUrl="/eom/purchaseorder/importFile"
+    />
+    <printPurchaseOrder
+      ref="printPurchaseOrderRef"
+      :groupName="groupName"
+    ></printPurchaseOrder>
+  </div>
+</template>
+
+<script>
+import searchTable from './components/searchTable.vue';
+import detailDialog from './components/detailDialog.vue';
+import contractrDetail from '@/views/contractManage/contractBook/components/detailDialog.vue';
+import purchasingDetail from '@/views/purchasingManage/purchaseNeedManage/components/detailDialog.vue';
+import purchasePlanDetail from '@/views/purchasingManage/purchasePlanManage/components/detailDialog.vue';
+import inquiryDetail from '@/views/purchasingManage/inquiryManage/components/detailDialog.vue';
+import popModal from '@/components/pop-modal';
+import {
+  getTableList,
+  deleteInformation,
+  getExport
+} from '@/api/purchasingManage/purchaseOrder';
+import dictMixins from '@/mixins/dictMixins';
+import { purchaseOrderProgressStatusEnum, reviewStatus } from '@/enum/dict';
+import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
+import tabMixins from '@/mixins/tableColumnsMixin';
+import importDialog from '@/components/upload/import-dialog.vue';
+import exportButton from '@/components/upload/exportButton.vue';
+import { parameterGetByCode } from '@/api/main/index.js';
+import exceptionList from '@/views/saleManage/saleOrder/exceptionManagement/exceptionList/index.vue';
+import { getToDoReminder } from '@/api/common/index';
+import printPurchaseOrder from '@/views/purchasingManage/purchaseOrder/invoice/components/print-PurchaseOrder.vue';
+  import { enterprisePage } from '@/api/contractManage/contractBook';
+
+export default {
+  mixins: [dictMixins, tabMixins],
+  components: {
+    processSubmitDialog,
+    exportButton,
+    searchTable,
+    popModal,
+    contractrDetail,
+    importDialog,
+    exceptionList,
+    purchasingDetail,
+    purchasePlanDetail,
+    inquiryDetail,
+    printPurchaseOrder,
+    detailDialog
+  },
+  data() {
+    return {
+      activeComp: 'collectionPlan',
+      tabOptions: [
+        { key: 'collectionPlan', name: '收款计划管理', reminder: 'purchaseOrderNum' },
+      ],
+
+      selection: [], //单选中集合
+      delVisible: false, //批量删除弹框状态
+      loading: false, // 加载状态
+      processSubmitDialogFlag: false,
+      addOrEditDialogFlag: false,
+      addOrEditDialogFlag1: false,
+      params: {},
+
+      groupName: '',
+      columns: [
+        {
+          width: 45,
+          type: 'selection',
+          columnKey: 'selection',
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
+        {
+          prop: 'orderNo',
+          label: '收款计划编码',
+          align: 'center',
+          sortable: true,
+          slot: 'orderNo',
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'orderNo',
+          label: '订单编码',
+          align: 'center',
+          sortable: true,
+          slot: 'orderNo',
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '订单类型',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '合同编码',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '合同编号',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '合同名称',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '发票号',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'relationType',
+          label: '关联应收编码',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150,
+          formatter: (_row, _column, cellValue) => {
+            return _row.relationType == 1
+              ? '采购需求单'
+              : _row.relationType == 2
+              ? '采购计划单'
+              : _row.relationType == 3
+              ? '采购核价单'
+              : _row.relationType == 4
+              ? '采购合同'
+              : '';
+          }
+        },
+        {
+          prop: 'relationName',
+          label: '客户编号',
+          align: 'center',
+          slot: 'relationName',
+          showOverflowTooltip: true,
+          minWidth: 250
+        },
+        {
+          prop: 'deliveryDate',
+          label: '客户名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'purchaseTypeName',
+          label: '结算方式',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'partaName',
+          label: '交易方式',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'partaLinkName',
+          label: '发货模式',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130
+        },
+
+        {
+          prop: 'partaTel',
+          label: '期数',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130
+        },
+        {
+          prop: 'productNames',
+          label: '款项类型',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'productCodes',
+          label: '款项名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'batchNos',
+          label: '比例',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'productCount',
+          label: '计划收款金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'inboundCount',
+          label: '计划收款日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+
+        {
+          prop: 'partbName',
+          label: '是否已开票',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 250
+        },
+        {
+          prop: 'partbLinkName',
+          label: '已开票金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'partbTel',
+          label: '开票日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130
+        },
+        {
+          prop: 'isInspection',
+          label: '是否生成应收款项',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130,
+          formatter: (_row, _column, cellValue) => {
+            return cellValue == 1 ? '是' : '否';
+          }
+        },
+        {
+          prop: 'payAmount',
+          label: '应收金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'createUserName',
+          label: '已收款金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 170
+        },
+        {
+          prop: 'createTime',
+          label: '实际收款日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 170
+        },
+        {
+          prop: 'progress',
+          label: '发货状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          formatter: (_row, _column, cellValue) => {
+            return purchaseOrderProgressStatusEnum.find(
+              (val) => val.value == _row.progress
+            )?.label;
+          },
+          minWidth: 120
+        },
+        {
+          prop: 'orderStatus',
+          label: '审核状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '对账状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '收款状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '逾期状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 260,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true,
+          fixed: 'right'
+        }
+      ],
+      cacheKeyUrl: 'eos-5f2ac512-purchaseOrder-collectionPlan',
+      isRequired: true,
+      timeR: null,
+      toDoReminder: {}
+    };
+  },
+  computed: {},
+  created() {
+    this.requestDict('客户状态');
+    parameterGetByCode({
+      code: 'order_person_info'
+    }).then((res) => {
+      if (res.value) {
+        this.isRequired = res.value === '1';
+      }
+    });
+    this.getToDoReminder();
+    this.timeR = setInterval(() => {
+      this.getToDoReminder();
+    }, 60000);
+  },
+  beforeDestroy() {
+    clearInterval(this.timeR);
+  },
+  methods: {
+    getToDoReminder() {
+      getToDoReminder().then((res) => {
+        this.toDoReminder = res;
+      });
+    },
+    //更多菜单
+    handleCommand(command, row) {
+      console.log(command, row);
+      if (command === 'invoice') {
+        this.$refs.invoiceDialogRef.open('add', {}, row.id);
+      }
+      if (command === 'returnOrder') {
+        this.$refs.addReturnGoodsRef.open('add', {});
+      }
+      if (command === 'outsourceSend') {
+        this.addOrEditDialogFlag = true;
+
+        this.$nextTick(() => {
+          this.$refs.addOrEditDialogRef.open('add', {}, row.id);
+        });
+      }
+      if (command === 'invoiceManage') {
+        this.addOrEditDialogFlag1 = true;
+
+        this.$nextTick(() => {
+          this.$refs.addOrEditDialogRef.createInvoice1(row, 2, 3);
+        });
+      }
+    },
+
+    //点击左边分类
+    handleNodeClick(data, node) {
+      // this.curNodeData = data;
+      this.reload({ categoryId: data.id });
+    },
+    /* 表格数据源 */
+    datasource({ page, limit, where, order }) {
+      this.params = {
+        pageNum: page,
+        size: limit,
+        ...where
+      };
+      return getTableList(this.params);
+    },
+
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({ page: 1, where });
+    },
+
+    //新增编辑
+    openEdit(type, row) {
+      this.$refs.addDialogRef.open(type, row, row.id);
+      this.$refs.addDialogRef.$refs.form &&
+        this.$refs.addDialogRef.$refs.form.clearValidate();
+    },
+    uploadFile() {
+      this.$refs.importDialogRef.open();
+    },
+    //打印采购订单
+    handlePrint(ref) {
+        if (this.selection.length > 1)
+          return this.$message.warning('暂不支持批量打印,请选择一条');
+      // let flag = this.selection.some((item) => [2].includes(item.reviewStatus));
+      // if (!flag)
+      //   return this.$message.warning('抱歉需要已审核的发货单才能打印,请检查');
+
+      enterprisePage({
+        pageNum: 1,
+        size: 200
+      }).then((res) => {
+        console.log(res.list);
+        if (res.list?.length > 0) {
+          this.groupName = res.list[0].name;
+        }
+      });
+      this.$refs[ref].open(this.selection[0].id);
+    },
+    //批量删除
+    allDelBtn() {
+      if (this.selection.length === 0) return;
+      let flag = this.selection.some((item) =>
+        [1, 2].includes(item.orderStatus)
+      );
+      if (flag)
+        return this.$message.warning('抱歉已审核、审核中的数据不能删除,请检查');
+      this.delVisible = true;
+    },
+
+    //删除接口
+    remove(delData) {
+      deleteInformation(delData).then((res) => {
+        this.$message.success('删除成功!');
+        this.reload();
+      });
+    },
+
+    //删除弹框确定
+    commitBtn() {
+      const dataId = this.selection.map((v) => v.id);
+      this.remove(dataId);
+    },
+
+    //查看详情
+    openorderDetail(row) {
+      this.$refs.contactDetailDialogRef.open(row);
+    },
+    saleOrderSubmit(res) {
+      this.processSubmitDialogFlag = true;
+      this.$nextTick(() => {
+        let params = {
+          businessId: res.id,
+          businessKey: 'purchase_order_approve',
+          formCreateUserId: res.createUserId,
+          variables: {
+            businessCode: res.orderNo,
+            businessName: res.partaName,
+            businessType: res.sourceTypeName
+          }
+        };
+
+        this.$refs.processSubmitDialogRef.init(params);
+      });
+    },
+    //查看合同详情
+    openDetail(row) {
+      this.$refs.detailDialogRef.open(row);
+    },
+    // 导出
+    exportRowInfo(row) {
+      console.log(row);
+      getExport(row.id);
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+:deep .el-card__body {
+  padding: 0;
+}
+
+:deep(.el-link--inner) {
+  margin-left: 0px !important;
+}
+
+.sys-organization-list {
+  height: calc(100vh - 264px);
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  overflow: auto;
+}
+
+.sys-organization-list :deep(.el-tree-node__content) {
+  height: 40px;
+
+  & > .el-tree-node__expand-icon {
+    margin-left: 10px;
+  }
+}
+
+.switch_left ul .active {
+  border-top: 4px solid var(--color-primary);
+  color: var(--color-primary-5);
+}
+
+.switch {
+  padding-bottom: 20px;
+}
+
+.el-dropdown-link {
+  cursor: pointer;
+  color: var(--color-primary-5);
+}
+
+.el-icon-arrow-down {
+  font-size: 12px;
+}
+:deep(.el-badge__content.is-fixed) {
+  top: 4px;
+}
+</style>

+ 75 - 0
src/views/financialManage/paymentPlan/components/searchTable.vue

@@ -0,0 +1,75 @@
+<!-- 搜索表单 -->
+<template>
+  <seekPage :seekList="seekList" :formLength="3" @search="search"></seekPage>
+</template>
+<script>
+import { paymentTypeOp } from '@/enum/dict';
+
+export default {
+  data() {
+    return {
+      paymentTypeOp,
+      overdueOptions: [{
+        label: '未逾期',
+        value: 1
+      },
+      {
+        label: '逾期中',
+        value: 0
+      }],
+      collectionTypeOp: [{
+        label: '收款计划',
+        value: 1
+      },
+      {
+        label: '收款单',
+        value: 0
+      }],
+    };
+  },
+  computed: {
+    // 表格列配置
+    seekList() {
+      return [
+        {
+          label: '关键字:',
+          value: 'searchName',
+          type: 'input',
+          placeholder: '收款计划编码/来源单据编码/客户名称'
+        },
+        {
+          label: '款项类型:',
+          value: 'collectionType',
+          type: 'select',
+          planList: this.paymentTypeOp,
+          placeholder: '请选择'
+        },
+        {
+          label: '逾期状态:',
+          value: 'orderStatus',
+          type: 'select',
+          planList: this.overdueOptions,
+          width: 380,
+          placeholder: ''
+        },
+        {
+          label: '查询日期:',
+          value: 'createTime',
+          type: 'date',
+          dateType: 'datetimerange',
+          placeholder: '',
+          width: 380,
+          valueAr: ['createTimeStart', 'createTimeEnd']
+        }
+      ];
+    }
+  },
+  methods: {
+    search(e) {
+      this.$emit('search', {
+        ...e
+      });
+    }
+  }
+};
+</script>

+ 722 - 0
src/views/financialManage/paymentPlan/index.vue

@@ -0,0 +1,722 @@
+<template>
+  <div class="ele-body">
+    <el-card shadow="never" v-loading="loading">
+      <div class="switch">
+        <div class="switch_left">
+          <ul>
+            <li
+              v-for="item in tabOptions"
+              :key="item.key"
+              :class="{ active: activeComp == item.key }"
+              @click="activeComp = item.key"
+              style="height: 42px; line-height: 38px"
+            >
+              <!-- <el-badge :value="toDoReminder[item.reminder] || 0" class="item"> -->
+                {{ item.name }}
+              <!-- </el-badge> -->
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class="main" style="padding: 0 10px">
+        <div v-if="activeComp == 'collectionPlan'">
+          <div class="ele-border-lighter form-content" v-loading="loading">
+            <search-table @search="reload"></search-table>
+
+            <!-- 数据表格 -->
+            <ele-pro-table
+              ref="table"
+              :columns="columns"
+              :datasource="datasource"
+              height="calc(100vh - 365px)"
+              style="margin-bottom: 10px"
+              full-height="calc(100vh - 116px)"
+              tool-class="ele-toolbar-form"
+              :selection.sync="selection"
+              :page-size="20"
+              @columns-change="handleColumnChange"
+              :cache-key="cacheKeyUrl"
+            >
+              <!-- 表头工具栏 -->
+              <template v-slot:toolbar>
+                <el-button
+                  size="small"
+                  type="primary"
+                  icon="el-icon-plus"
+                  class="ele-btn-icon"
+                  @click="openEdit('add', {})"
+                >
+                  合并开票
+                </el-button>
+              </template>
+
+              <!-- 查看详情列 -->
+              <template v-slot:relationName="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  @click="openDetail(row)"
+                >
+                  {{ row.relationName }}
+                </el-link>
+              </template>
+              <template v-slot:orderNo="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  @click="openDetail(row)"
+                >
+                  {{ row.orderNo }}
+                </el-link>
+              </template>
+              <!-- 操作列 -->
+              <template v-slot:action="{ row }">
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  icon="el-icon-edit"
+                  v-if="
+                    (isNeed_process_is_close &&
+                      [0, 3].includes(row.orderStatus)) ||
+                    !isNeed_process_is_close
+                  "
+                  @click="openEdit('edit', row)"
+                >
+                  修改
+                </el-link>
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  icon="el-icon-plus"
+                  @click="saleOrderSubmit(row)"
+                  v-if="
+                    isNeed_process_is_close && [0, 3].includes(row.orderStatus)
+                  "
+                >
+                  提交
+                </el-link>
+                <el-popconfirm
+                  class="ele-action"
+                  title="确定要删除此信息吗?"
+                  v-if="
+                    (isNeed_process_is_close &&
+                      [0, 3].includes(row.orderStatus)) ||
+                    !isNeed_process_is_close
+                  "
+                  @confirm="remove([row.id])"
+                >
+                  <template v-slot:reference>
+                    <el-link
+                      type="danger"
+                      :underline="false"
+                      icon="el-icon-delete"
+                    >
+                      删除
+                    </el-link>
+                  </template>
+                </el-popconfirm>
+      
+                <el-link
+                  type="primary"
+                  :underline="false"
+                  icon="el-icon-plus"
+                  @click="handleCommand('invoiceManage', row)"
+                  v-if="!row.hasInvoiceApply && [2].includes(row.orderStatus)"
+                >
+                  新增发票
+                </el-link>
+              </template>
+            </ele-pro-table>
+          </div>
+        </div>
+      </div>
+    </el-card>
+    <detailDialog ref="detailDialogRef"></detailDialog>
+    <contractr-detail ref="contractDetailRef"></contractr-detail>
+    <purchasingDetail ref="purchasingDetailRef"></purchasingDetail>
+    <purchasePlanDetail ref="purchasePlanDetailRef"></purchasePlanDetail>
+    <inquiryDetail ref="inquiryDetailRef"></inquiryDetail>
+
+    <!-- 多选删除弹窗 -->
+    <pop-modal
+      :visible.sync="delVisible"
+      content="是否确定删除?"
+      @done="commitBtn"
+    />
+    <process-submit-dialog
+      :isNotNeedProcess="true"
+      :isCloseRefresh="false"
+      :processSubmitDialogFlag.sync="processSubmitDialogFlag"
+      v-if="processSubmitDialogFlag"
+      ref="processSubmitDialogRef"
+      @reload="reload"
+    ></process-submit-dialog>
+ 
+    <importDialog
+      ref="importDialogRef"
+      @success="reload"
+      :fileUrl="'/eom/purchaseorder/importTemplate'"
+      :isWeb="false"
+      fileName="采购订单导入模板"
+      apiUrl="/eom/purchaseorder/importFile"
+    />
+    <printPurchaseOrder
+      ref="printPurchaseOrderRef"
+      :groupName="groupName"
+    ></printPurchaseOrder>
+  </div>
+</template>
+
+<script>
+import searchTable from './components/searchTable.vue';
+import detailDialog from '@/views/financialManage/collectionPlan/components/detailDialog.vue';
+import contractrDetail from '@/views/contractManage/contractBook/components/detailDialog.vue';
+import purchasingDetail from '@/views/purchasingManage/purchaseNeedManage/components/detailDialog.vue';
+import purchasePlanDetail from '@/views/purchasingManage/purchasePlanManage/components/detailDialog.vue';
+import inquiryDetail from '@/views/purchasingManage/inquiryManage/components/detailDialog.vue';
+import popModal from '@/components/pop-modal';
+import {
+  getTableList,
+  deleteInformation,
+  getExport
+} from '@/api/purchasingManage/purchaseOrder';
+import dictMixins from '@/mixins/dictMixins';
+import { purchaseOrderProgressStatusEnum, reviewStatus } from '@/enum/dict';
+import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
+import tabMixins from '@/mixins/tableColumnsMixin';
+import importDialog from '@/components/upload/import-dialog.vue';
+import exportButton from '@/components/upload/exportButton.vue';
+import { parameterGetByCode } from '@/api/main/index.js';
+import exceptionList from '@/views/saleManage/saleOrder/exceptionManagement/exceptionList/index.vue';
+import { getToDoReminder } from '@/api/common/index';
+import printPurchaseOrder from '@/views/purchasingManage/purchaseOrder/invoice/components/print-PurchaseOrder.vue';
+  import { enterprisePage } from '@/api/contractManage/contractBook';
+
+export default {
+  mixins: [dictMixins, tabMixins],
+  components: {
+    processSubmitDialog,
+    exportButton,
+    searchTable,
+    popModal,
+    contractrDetail,
+    importDialog,
+    exceptionList,
+    purchasingDetail,
+    purchasePlanDetail,
+    inquiryDetail,
+    printPurchaseOrder,
+    detailDialog
+  },
+  data() {
+    return {
+      activeComp: 'collectionPlan',
+      tabOptions: [
+        { key: 'collectionPlan', name: '收款计划管理', reminder: 'purchaseOrderNum' },
+      ],
+
+      selection: [], //单选中集合
+      delVisible: false, //批量删除弹框状态
+      loading: false, // 加载状态
+      processSubmitDialogFlag: false,
+      addOrEditDialogFlag: false,
+      addOrEditDialogFlag1: false,
+      params: {},
+
+      groupName: '',
+      columns: [
+        {
+          width: 45,
+          type: 'selection',
+          columnKey: 'selection',
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
+        {
+          prop: 'orderNo',
+          label: '付款计划编码',
+          align: 'center',
+          sortable: true,
+          slot: 'orderNo',
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'orderNo',
+          label: '订单编码',
+          align: 'center',
+          sortable: true,
+          slot: 'orderNo',
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '订单类型',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '合同编码',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '合同编号',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '合同名称',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'sourceTypeName',
+          label: '发票号',
+          align: 'center',
+          sortable: true,
+          showOverflowTooltip: true,
+          minWidth: 200,
+        },
+        {
+          prop: 'relationType',
+          label: '关联应付编码',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150,
+          formatter: (_row, _column, cellValue) => {
+            return _row.relationType == 1
+              ? '采购需求单'
+              : _row.relationType == 2
+              ? '采购计划单'
+              : _row.relationType == 3
+              ? '采购核价单'
+              : _row.relationType == 4
+              ? '采购合同'
+              : '';
+          }
+        },
+        {
+          prop: 'relationName',
+          label: '客户编码',
+          align: 'center',
+          slot: 'relationName',
+          showOverflowTooltip: true,
+          minWidth: 250
+        },
+        {
+          prop: 'deliveryDate',
+          label: '客户名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'purchaseTypeName',
+          label: '结算方式',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'partaName',
+          label: '交易方式',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'partaLinkName',
+          label: '发货模式',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130
+        },
+
+        {
+          prop: 'partaTel',
+          label: '期数',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130
+        },
+        {
+          prop: 'productNames',
+          label: '款项类型',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'productCodes',
+          label: '款项名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'batchNos',
+          label: '比例',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'productCount',
+          label: '计划收款金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'inboundCount',
+          label: '计划收款日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+
+        {
+          prop: 'partbName',
+          label: '是否已开票',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 250
+        },
+        {
+          prop: 'partbLinkName',
+          label: '已开票金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'partbTel',
+          label: '开票日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130
+        },
+        {
+          prop: 'isInspection',
+          label: '是否生成应付款项',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 130,
+          formatter: (_row, _column, cellValue) => {
+            return cellValue == 1 ? '是' : '否';
+          }
+        },
+        {
+          prop: 'payAmount',
+          label: '应付金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'createUserName',
+          label: '已付款金额',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 170
+        },
+        {
+          prop: 'createTime',
+          label: '实际付款日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 170
+        },
+        {
+          prop: 'progress',
+          label: '收货状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          formatter: (_row, _column, cellValue) => {
+            return purchaseOrderProgressStatusEnum.find(
+              (val) => val.value == _row.progress
+            )?.label;
+          },
+          minWidth: 120
+        },
+        {
+          prop: 'orderStatus',
+          label: '审核状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '对账状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '付款状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          prop: 'orderStatus',
+          label: '逾期状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.orderStatus];
+          }
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 260,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true,
+          fixed: 'right'
+        }
+      ],
+      cacheKeyUrl: 'eos-5f2ac512-purchaseOrder-collectionPlan',
+      isRequired: true,
+      timeR: null,
+      toDoReminder: {}
+    };
+  },
+  computed: {},
+  created() {
+    this.requestDict('客户状态');
+    parameterGetByCode({
+      code: 'order_person_info'
+    }).then((res) => {
+      if (res.value) {
+        this.isRequired = res.value === '1';
+      }
+    });
+    this.getToDoReminder();
+    this.timeR = setInterval(() => {
+      this.getToDoReminder();
+    }, 60000);
+  },
+  beforeDestroy() {
+    clearInterval(this.timeR);
+  },
+  methods: {
+    getToDoReminder() {
+      getToDoReminder().then((res) => {
+        this.toDoReminder = res;
+      });
+    },
+    //更多菜单
+    handleCommand(command, row) {
+      console.log(command, row);
+      if (command === 'invoice') {
+        this.$refs.invoiceDialogRef.open('add', {}, row.id);
+      }
+      if (command === 'returnOrder') {
+        this.$refs.addReturnGoodsRef.open('add', {});
+      }
+      if (command === 'outsourceSend') {
+        this.addOrEditDialogFlag = true;
+
+        this.$nextTick(() => {
+          this.$refs.addOrEditDialogRef.open('add', {}, row.id);
+        });
+      }
+      if (command === 'invoiceManage') {
+        this.addOrEditDialogFlag1 = true;
+
+        this.$nextTick(() => {
+          this.$refs.addOrEditDialogRef.createInvoice1(row, 2, 3);
+        });
+      }
+    },
+
+    //点击左边分类
+    handleNodeClick(data, node) {
+      // this.curNodeData = data;
+      this.reload({ categoryId: data.id });
+    },
+    /* 表格数据源 */
+    datasource({ page, limit, where, order }) {
+      this.params = {
+        pageNum: page,
+        size: limit,
+        ...where
+      };
+      return getTableList(this.params);
+    },
+
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({ page: 1, where });
+    },
+
+    //新增编辑
+    openEdit(type, row) {
+      this.$refs.addDialogRef.open(type, row, row.id);
+      this.$refs.addDialogRef.$refs.form &&
+        this.$refs.addDialogRef.$refs.form.clearValidate();
+    },
+    uploadFile() {
+      this.$refs.importDialogRef.open();
+    },
+    //打印采购订单
+    handlePrint(ref) {
+        if (this.selection.length > 1)
+          return this.$message.warning('暂不支持批量打印,请选择一条');
+      // let flag = this.selection.some((item) => [2].includes(item.reviewStatus));
+      // if (!flag)
+      //   return this.$message.warning('抱歉需要已审核的发货单才能打印,请检查');
+
+      enterprisePage({
+        pageNum: 1,
+        size: 200
+      }).then((res) => {
+        console.log(res.list);
+        if (res.list?.length > 0) {
+          this.groupName = res.list[0].name;
+        }
+      });
+      this.$refs[ref].open(this.selection[0].id);
+    },
+    //批量删除
+    allDelBtn() {
+      if (this.selection.length === 0) return;
+      let flag = this.selection.some((item) =>
+        [1, 2].includes(item.orderStatus)
+      );
+      if (flag)
+        return this.$message.warning('抱歉已审核、审核中的数据不能删除,请检查');
+      this.delVisible = true;
+    },
+
+    //删除接口
+    remove(delData) {
+      deleteInformation(delData).then((res) => {
+        this.$message.success('删除成功!');
+        this.reload();
+      });
+    },
+
+    //删除弹框确定
+    commitBtn() {
+      const dataId = this.selection.map((v) => v.id);
+      this.remove(dataId);
+    },
+
+    //查看详情
+    openorderDetail(row) {
+      this.$refs.contactDetailDialogRef.open(row);
+    },
+    saleOrderSubmit(res) {
+      this.processSubmitDialogFlag = true;
+      this.$nextTick(() => {
+        let params = {
+          businessId: res.id,
+          businessKey: 'purchase_order_approve',
+          formCreateUserId: res.createUserId,
+          variables: {
+            businessCode: res.orderNo,
+            businessName: res.partaName,
+            businessType: res.sourceTypeName
+          }
+        };
+
+        this.$refs.processSubmitDialogRef.init(params);
+      });
+    },
+    //查看合同详情
+    openDetail(row) {
+      this.$refs.detailDialogRef.open(row);
+    },
+    // 导出
+    exportRowInfo(row) {
+      console.log(row);
+      getExport(row.id);
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+:deep .el-card__body {
+  padding: 0;
+}
+
+:deep(.el-link--inner) {
+  margin-left: 0px !important;
+}
+
+.sys-organization-list {
+  height: calc(100vh - 264px);
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  overflow: auto;
+}
+
+.sys-organization-list :deep(.el-tree-node__content) {
+  height: 40px;
+
+  & > .el-tree-node__expand-icon {
+    margin-left: 10px;
+  }
+}
+
+.switch_left ul .active {
+  border-top: 4px solid var(--color-primary);
+  color: var(--color-primary-5);
+}
+
+.switch {
+  padding-bottom: 20px;
+}
+
+.el-dropdown-link {
+  cursor: pointer;
+  color: var(--color-primary-5);
+}
+
+.el-icon-arrow-down {
+  font-size: 12px;
+}
+:deep(.el-badge__content.is-fixed) {
+  top: 4px;
+}
+</style>