Bladeren bron

feat: 预收管理功能

liujt 2 maanden geleden
bovenliggende
commit
a011e6791b

+ 37 - 1
src/api/financialManage/advanceReceipt/index.js

@@ -47,7 +47,7 @@ export async function deleteAdvanceReceipt(data) {
 
 // 提交
 export async function submit(data) {
-  const res = await request.post('/eom/finadvance/submit', data);
+  const res = await request.post('/eom/finadvance/submit?id=' + data.id);
   if (res.data.code == 0) {
     return res.data.data;
   }
@@ -61,3 +61,39 @@ export async function approve(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+// 撤销
+export async function withdraw(data) {
+  const res = await request.post('/eom/finadvance/withdraw?id=' + data.id);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 完结
+export async function complete(data) {
+  const res = await request.post('/eom/finadvance/complete?id=' + data.id);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 收款明细提交
+export async function saveDetailDetail(data) {
+  const res = await request.post('/eom/finadvance/saveDetail', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 收款条件列表
+export async function receiveTermsPageList(data) {
+  const res = await request.post('/main/paymentConditionRules/page', data );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 42 - 0
src/enum/dict.js

@@ -361,6 +361,48 @@ export const paymentTypeOp = [
   }
 ];
 
+// 收款日计算日期
+export const calcReceiveDateTypeOp = [
+  {
+    label: '订单日期',
+    value: '1'
+  },
+  {
+    label: '出库日期',
+    value: '2'
+  },
+  {
+    label: '应收单日期',
+    value: '3'
+  },
+  {
+    label: '开票日期',
+    value: '4'
+  },
+  {
+    label: '对账单日期',
+    value: '5'
+  }
+];
+
+// 收/付款日确定方式
+export const payConfirmTypeOp = [
+  {
+    label: '交易日',
+    value: '1'
+  },
+  {
+    label: 'X天后',
+    value: '2'
+  }
+];
+
+export const dateUnitOptions = [
+  { value: 'day', label: '天' },
+  { value: 'month', label: '月' },
+  { value: 'year', label: '年' }
+];
+
 //委外订单来源类型
 
 export const orderSourceType = ['3', '4', '5', '6', '7'];

+ 35 - 10
src/views/financialManage/advanceReceipt/components/addDialog.vue

@@ -10,7 +10,7 @@
     :title="isDetail ? '预收款详情' : isUpdate ? '修改预收款' : '新增预收款'"
     @update:visible="updateVisible"
   >
-    <div class="switch_left" v-if="isDetail">
+    <!-- <div class="switch_left" v-if="isDetail">
       <ul>
         <li
           v-for="item in tabOptions"
@@ -21,7 +21,7 @@
           {{ item.name }}
         </li>
       </ul>
-    </div>
+    </div> -->
     <el-form
       ref="form"
       :model="form"
@@ -127,8 +127,8 @@
           </el-form-item>
         </el-col>
         <el-col :span="8">
-          <el-form-item label="收款条件:" prop="collectionConditionId">
-            <el-select
+          <el-form-item label="收款条件:" prop="collectionConditionName">
+            <!-- <el-select
               v-model="form.collectionConditionId"
               placeholder="请选择"
               style="width: 100%"
@@ -140,7 +140,15 @@
                 :label="item.label"
                 :value="item.value"
               />
-            </el-select>
+            </el-select> -->
+            <el-input
+              clearable
+              v-model="form.collectionConditionName"
+              @click.native="openReceiveTerms"
+              placeholder="请选择"
+              :disabled="isDetail"
+              readonly
+            />
           </el-form-item>
         </el-col>
       </el-row>
@@ -233,6 +241,8 @@
       }"
       @changeParent="changeOrder"
     ></saleOrderListDialog>
+    <!-- 收款条件 -->
+    <receiveTermsDialog ref="receiveTermsDialogRef" @changeParent="changeReceiveTerms"></receiveTermsDialog>
     <bpmDetail
       v-if="activeComp === 'bpm' && form.processInstanceId"
       :id="form.processInstanceId"
@@ -255,6 +265,7 @@
   import contractListDialog from '@/views/saleManage/saleOrder/components/contractListDialog.vue';
   import saleOrderListDialog from '@/views/saleManage/saleOrder/invoice/components/orderListDialog.vue'; //销售订单
   import { getSaleOrderDetail } from '@/api/saleManage/saleorder';
+  import receiveTermsDialog from './receiveTermsDialog.vue';
   export default {
     components: {
       headerTitle,
@@ -262,7 +273,8 @@
       contractListDialog,
       saleOrderListDialog,
       parentList,
-      bpmDetail
+      bpmDetail,
+      receiveTermsDialog
     },
     data() {
       return {
@@ -335,8 +347,9 @@
           contactId: '',
           sourceType: 3,
           sourceCode: '',
-          fundType: '1',
+          fundType: 1,
           collectionConditionId: '',
+          collectionConditionName: '',
           remark: '',
           files: [],
           detailList: []
@@ -383,6 +396,13 @@
       }
     },
     methods: {
+      changeReceiveTerms(row, index) {
+        console.log('changeReceiveTerms~~~', row)
+        this.form.collectionConditionId = row.id;
+        this.form.collectionConditionName = row.name;
+        console.log('changeReceiveTerms!!!', this.form)
+        this.$forceUpdate()
+      },
       generateCode() {
         const now = new Date();
         const year = now.getFullYear();
@@ -404,12 +424,12 @@
           this.$nextTick(() => {
             this.$refs.inventoryTableDetailsRef &&
               this.$refs.inventoryTableDetailsRef.putTableValue(
-                this.form.productList || []
+                this.form || []
               );
           });
         } else {
           this.resetForm();
-          this.generateCode();
+          // this.generateCode();
           this.$nextTick(() => {
             this.$refs.inventoryTableDetailsRef &&
               this.$refs.inventoryTableDetailsRef.putTableValue([]);
@@ -450,6 +470,10 @@
           this.$refs.selectContractRef.open();
         }
       },
+      
+      openReceiveTerms() {
+        this.$refs.receiveTermsDialogRef.open();
+      },
       async changeOrder(row) {
         this.form.sourceCode = row.orderNo;
         this.form.sourceId = row.id;
@@ -483,8 +507,9 @@
           sourceType: 3,
           sourceCode: '',
           sourceId: '',
-          fundType: '1',
+          fundType: 1,
           collectionConditionId: '',
+          collectionConditionName: '',
           remark: '',
           files: [],
           detailList: []

+ 33 - 31
src/views/financialManage/advanceReceipt/components/collectDialog.vue

@@ -38,14 +38,14 @@
         :toolkit="[]"
       >
         <!-- 收款时间 -->
-        <template v-slot:collectTime="{ row: r, $index }">
+        <template v-slot:receivedDate="{ row: r, $index }">
           <el-form-item
-            :prop="`tableData.${$index}.collectTime`"
+            :prop="`tableData.${$index}.receivedDate`"
             :rules="{ required: true, message: '请选择收款时间', trigger: 'change' }"
             class="table-form-item"
           >
             <el-date-picker
-              v-model="r.collectTime"
+              v-model="r.receivedDate"
               type="date"
               placeholder="年/月/日"
               value-format="yyyy-MM-dd"
@@ -55,14 +55,14 @@
           </el-form-item>
         </template>
         <!-- 已收金额 -->
-        <template v-slot:collectAmount="{ row: r, $index }">
+        <template v-slot:receivedTotalPrice="{ row: r, $index }">
           <el-form-item
-            :prop="`tableData.${$index}.collectAmount`"
+            :prop="`tableData.${$index}.receivedTotalPrice`"
             :rules="{ required: true, message: '请输入已收金额', trigger: 'blur' }"
             class="table-form-item"
           >
             <el-input
-              v-model="r.collectAmount"
+              v-model="r.receivedTotalPrice"
               placeholder="请输入"
               size="small"
               @input="calcAmount"
@@ -70,24 +70,23 @@
           </el-form-item>
         </template>
         <!-- 支付类型 -->
-        <template v-slot:payType="{ row: r, $index }">
+        <template v-slot:paymentType="{ row: r, $index }">
           <el-form-item
-            :prop="`tableData.${$index}.payType`"
+            :prop="`tableData.${$index}.paymentType`"
             :rules="{ required: true, message: '请选择支付类型', trigger: 'change' }"
             class="table-form-item"
           >
             <DictSelection
-              v-model="item.payType"
+              v-model="item.paymentType"
               dictName="支付类型"
               placeholder="请选择"
               class="payment-select"
-              :disabled="isDetail"
             />
           </el-form-item>
         </template>
         <!-- 附件 -->
-        <template v-slot:attachment="{ row: r }">
-          <fileMain v-model="r.attachment" :limit="1"></fileMain>
+        <template v-slot:files="{ row: r }">
+          <fileMain v-model="r.files" :limit="1"></fileMain>
         </template>
         <!-- 备注 -->
         <template v-slot:remark="{ row: r }">
@@ -123,6 +122,7 @@
 <script>
   import headerTitle from '@/components/header-title';
   import fileMain from '@/components/addDoc/index.vue';
+  import { saveDetailDetail } from '@/api/financialManage/advanceReceipt';
 
   export default {
     components: {
@@ -146,32 +146,32 @@
             fixed: 'left'
           },
           {
-            prop: 'collectTime',
+            prop: 'receivedDate',
             label: '收款时间',
             align: 'center',
             minWidth: 160,
-            slot: 'collectTime'
+            slot: 'receivedDate'
           },
           {
-            prop: 'collectAmount',
+            prop: 'receivedTotalPrice',
             label: '已收金额',
             align: 'center',
             minWidth: 140,
-            slot: 'collectAmount'
+            slot: 'receivedTotalPrice'
           },
           {
-            prop: 'payType',
+            prop: 'paymentType',
             label: '支付类型',
             align: 'center',
             minWidth: 140,
-            slot: 'payType'
+            slot: 'paymentType'
           },
           {
-            prop: 'attachment',
+            prop: 'files',
             label: '附件',
             align: 'center',
             minWidth: 120,
-            slot: 'attachment'
+            slot: 'files'
           },
           {
             prop: 'remark',
@@ -195,7 +195,7 @@
     computed: {
       receivedAmount() {
         return this.form.tableData.reduce((sum, item) => {
-          const val = parseFloat(item.collectAmount);
+          const val = parseFloat(item.receivedTotalPrice);
           return sum + (isNaN(val) ? 0 : val);
         }, 0).toFixed(2);
       },
@@ -214,10 +214,10 @@
 
       addRow() {
         this.form.tableData.push({
-          collectTime: '',
-          collectAmount: '',
-          payType: '',
-          attachment: [],
+          receivedDate: '',
+          receivedTotalPrice: '',
+          paymentType: '',
+          files: [],
           remark: ''
         });
       },
@@ -243,28 +243,30 @@
         }
         for (let i = 0; i < this.form.tableData.length; i++) {
           const item = this.form.tableData[i];
-          if (!item.collectTime) {
+          if (!item.receivedDate) {
             this.$message.warning(`第${i + 1}行收款时间不能为空`);
             return;
           }
-          if (!item.collectAmount) {
+          if (!item.receivedTotalPrice) {
             this.$message.warning(`第${i + 1}行已收金额不能为空`);
             return;
           }
-          if (!item.payType) {
+          if (!item.paymentType) {
             this.$message.warning(`第${i + 1}行支付类型不能为空`);
             return;
           }
         }
 
         this.loading = true;
-        // TODO: 调用收款保存接口
-        setTimeout(() => {
+        saveDetailDetail({
+          // advanceId: this.row.id,
+          poList: this.form.tableData
+        }).then(() => {
           this.loading = false;
           this.$message.success('收款成功');
           this.updateVisible(false);
           this.$emit('done');
-        }, 500);
+        });
       },
 
       updateVisible(value) {

+ 273 - 0
src/views/financialManage/advanceReceipt/components/receiveTermsDialog.vue

@@ -0,0 +1,273 @@
+<!-- 预收款新增/编辑弹窗 -->
+<template>
+  <ele-modal
+    width="70%"
+    :visible="visible"
+    :maxable="true"
+    :append-to-body="true"
+    :close-on-click-modal="false"
+    custom-class="ele-dialog-form"
+    title="收款条件"
+    @update:visible="updateVisible"
+  >
+    <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="datasource"
+        height="calc(100vh - 375px)"
+        full-height="calc(100vh - 116px)"
+        tool-class="ele-toolbar-form"
+        :selection.sync="selection"
+        :page-size="20"
+        @columns-change="handleColumnChange"
+        @cell-click="cellClick"
+        :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:action="{ row }">
+            <el-radio class="radio" v-model="radio" :label="row.id"
+            ><i></i
+            ></el-radio>
+        </template>
+
+        <template v-slot:ruleState="{ row }">
+        <el-switch
+            v-model="row.ruleState"
+            active-color="#13ce66"
+            inactive-color="#ff4949"
+            active-value="1"
+            inactive-value="0"
+            @change="(val) => handleStatus(row, val)"
+        >
+        </el-switch>
+        </template>
+    </ele-pro-table>
+
+    <template v-slot:footer>
+        <el-button type="primary" :loading="loading" @click="selected">
+          选择
+        </el-button>
+        <el-button @click="updateVisible(false)">取消</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script>
+  import {
+    receiveTermsPageList
+  } from '@/api/financialManage/advanceReceipt';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+  import { calcReceiveDateTypeOp, payConfirmTypeOp, dateUnitOptions } from '@/enum/dict';
+
+  export default {
+    mixins: [tabMixins],
+    components: {
+
+    },
+    props: {
+        isAll: {
+            type: Boolean,
+            default: false
+        },
+    },
+    data() {
+      return {
+        selection: [],
+        cacheKeyUrl: 'eom-202608101410-receiveTerms',
+        visible: false,
+        loading: false,
+        radio: '',
+        current: null,
+        currentIndex: null,
+      };
+    },
+    computed: {
+        columns() {
+            let selection = null;
+            if (this.isAll) {
+                selection = {
+                    width: 45,
+                    type: 'selection',
+                    columnKey: 'selection',
+                    align: 'center',
+                    reserveSelection: true
+                };
+                } else {
+                selection = {
+                    action: 'action',
+                    slot: 'action',
+                    align: 'center',
+                    label: '选择',
+                    minWidth: 100
+                };
+            }
+            return [
+                // {
+                //     width: 45,
+                //     type: 'selection',
+                //     columnKey: 'selection',
+                //     align: 'center'
+                // },
+                selection,
+                {
+                    columnKey: 'index',
+                    label: '序号',
+                    type: 'index',
+                    width: 55,
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    fixed: 'left'
+                },
+                {
+                    prop: 'code',
+                    label: '编码',
+                    align: 'center',
+                    // sortable: true,
+                    showOverflowTooltip: true,
+                    minWidth: 160
+                },
+                {
+                    prop: 'name',
+                    label: '收款条件名称',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 160
+                },
+                {
+                    prop: 'dateType',
+                    label: '收款日计算日期',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 160,
+                    formatter: (row) => {
+                    return calcReceiveDateTypeOp.find(item => item.value === row.dateType)?.label || '';
+                    }
+                },
+                {
+                    prop: 'rulesTypePOList',
+                    label: '支付方式',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 140,
+                    formatter: (row) => {
+                    return this.buildPaymentMethod(row.rulesTypePOList);
+                    }
+                },
+                {
+                    prop: 'determinationMethod',
+                    label: '收款日确认方式',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 140,
+                    formatter: (row) => {
+                    return payConfirmTypeOp.find(item => item.value === row.determinationMethod)?.label || '';
+                    }
+                },
+                {
+                    prop: 'remark',
+                    label: '备注',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 180
+                },
+                {
+                    prop: 'createUserId',
+                    label: '创建人',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 120
+                },
+                {
+                    prop: 'createTime',
+                    label: '创建时间',
+                    align: 'center',
+                    showOverflowTooltip: true,
+                    minWidth: 120
+                },
+                //   {
+                //     prop: 'ruleState',
+                //     slot: 'ruleState',
+                //     label: '状态',
+                //     align: 'center',
+                //     showOverflowTooltip: true,
+                //     minWidth: 120
+                //   },
+                ]
+        }
+    },
+    methods: {
+        // 单击获取id
+      cellClick(row) {
+        this.current = row;
+        console.log(row);
+        this.radio = row.id;
+      },
+        // 构建支付方式字符串
+      buildPaymentMethod(list) {
+        return list
+          .map(item => {
+            const unit =
+              (dateUnitOptions.find(opt => opt.value === item.dateType) || {}).label ||
+              '月';
+            return `${item.percentage}% ${item.paymentSum}${unit} ${item.paymentType}`;
+          })
+          .join(',');
+      },
+        /* 表格数据源 */
+      async datasource({ page, limit, where, order }) {
+
+        const res = await receiveTermsPageList({
+          pageNum: page,
+          size: limit,
+          conditionConfigurationType: 'rules',
+          ruleState: 1,
+          ...where
+        });
+        console.log('res', res);
+        return res
+      },
+
+
+      async open() {
+        this.visible = true;
+        this.$nextTick(() => {
+          this.$refs.form && this.$refs.form.clearValidate();
+        });
+      },
+      selected() {
+        if (!this.current && !this.isAll) {
+          return this.$message.warning('请至少选择一条数据');
+        }
+        if (this.isAll) {
+          if (!this.selection.length) {
+            return this.$message.warning('请至少选择一条数据');
+          }
+        }
+        this.$emit(
+          'changeParent',
+          this.isAll ? this.selection : this.current,
+          this.currentIndex
+        );
+        this.updateVisible();
+      },
+
+      updateVisible(value) {
+        this.visible = value;
+        this.current = null;
+        this.radio = '';
+      }
+    }
+  };
+</script>

+ 18 - 18
src/views/financialManage/advanceReceipt/components/searchForm.vue

@@ -19,24 +19,24 @@
             type: 'input',
             placeholder: '编码、名称、型号、规格'
           },
-          {
-            label: '下拉检索:',
-            value: 'searchType',
-            type: 'select',
-            placeholder: '请选择',
-            planList: [
-              { label: '编码', value: 'code' },
-              { label: '名称', value: 'name' },
-              { label: '型号', value: 'model' },
-              { label: '规格', value: 'specification' }
-            ]
-          },
-          {
-            label: '关键词:',
-            value: 'searchName2',
-            type: 'input',
-            placeholder: '编码、名称、型号、规格'
-          },
+          // {
+          //   label: '下拉检索:',
+          //   value: 'searchType',
+          //   type: 'select',
+          //   placeholder: '请选择',
+          //   planList: [
+          //     { label: '编码', value: 'code' },
+          //     { label: '名称', value: 'name' },
+          //     { label: '型号', value: 'model' },
+          //     { label: '规格', value: 'specification' }
+          //   ]
+          // },
+          // {
+          //   label: '关键词:',
+          //   value: 'searchName2',
+          //   type: 'input',
+          //   placeholder: '编码、名称、型号、规格'
+          // },
           {
             label: '创建时间:',
             value: 'createTime',

+ 35 - 28
src/views/financialManage/advanceReceipt/index.vue

@@ -36,8 +36,9 @@
           </template>
           <!-- 操作列 -->
           <template v-slot:action="{ row }">
-            <template v-if="row.status === 0">
+            <template v-if="row.approvalStatus === 0">
               <el-link
+                v-if="$hasPermission('eom:finadvance:update')"
                 type="primary"
                 :underline="false"
                 @click="openEdit('edit', row)"
@@ -45,6 +46,7 @@
                 修改
               </el-link>
               <el-link
+                v-if="$hasPermission('eom:finadvance:submit')"
                 type="primary"
                 :underline="false"
                 @click="handleSubmit(row)"
@@ -52,6 +54,7 @@
                 提交
               </el-link>
               <el-popconfirm
+                v-if="$hasPermission('eom:finadvance:delete')"
                 class="ele-action"
                 title="确定要删除此信息吗?"
                 @confirm="remove([row.id])"
@@ -61,30 +64,17 @@
                 </template>
               </el-popconfirm>
             </template>
-            <template v-else-if="row.status === 1">
-              <el-link
-                type="primary"
-                :underline="false"
-                @click="handleCollect(row)"
-              >
-                收款
-              </el-link>
-              <el-link
-                type="success"
-                :underline="false"
-                @click="handleComplete()"
-              >
-                完结
-              </el-link>
+            <template v-else-if="row.approvalStatus === 1">
               <el-link
+                v-if="$hasPermission('eom:finadvance:withdraw')"
                 type="warning"
                 :underline="false"
-                @click="handleRevoke()"
+                @click="handleRevoke(row)"
               >
                 撤销
               </el-link>
             </template>
-            <template v-else-if="row.status === 2">
+            <template v-else-if="row.approvalStatus === 2">
               <el-link
                 type="primary"
                 :underline="false"
@@ -93,9 +83,10 @@
                 收款
               </el-link>
               <el-link
+                v-if="$hasPermission('eom:finadvance:complete')"
                 type="success"
                 :underline="false"
-                @click="handleComplete()"
+                @click="handleComplete(row)"
               >
                 完结
               </el-link>
@@ -121,8 +112,9 @@
   import { paymentStatus, reviewStatus } from '@/enum/dict';
   import {
     advanceReceiptPageList,
-    deleteAdvanceReceipt,submit,approve
+    deleteAdvanceReceipt,submit,approve, withdraw, complete
   } from '@/api/financialManage/advanceReceipt';
+  
   export default {
     mixins: [tabMixins],
     components: {
@@ -310,7 +302,9 @@
             this.$message.success('提交成功');
             this.reload();
           });
-        });
+        }).catch(() => {
+          // this.$message.info('已取消提交');
+        });;
       },
 
       // 收款
@@ -319,13 +313,20 @@
       },
 
       // 撤销
-      handleRevoke() {
+      handleRevoke(row) {
         this.$confirm('确定要撤销该预收款吗?', '提示', {
           type: 'warning'
         }).then(() => {
-          // TODO: 调用撤销接口
-          this.$message.success('撤销成功');
-          this.reload();
+          withdraw({
+            id: row.id
+          })
+          .then((res) => {
+            // TODO: 调用撤销接口
+            this.$message.success('撤销成功');
+            this.reload();
+          }).catch(() => {
+            // this.$message.info('已取消撤销');
+          });
         });
       },
 
@@ -334,9 +335,15 @@
         this.$confirm('确定要完结该预收款吗?', '提示', {
           type: 'warning'
         }).then(() => {
-          // TODO: 调用完结接口
-          this.$message.success('完结成功');
-          this.reload();
+          complete({
+            id: row.id
+          }).then((res) => {
+            // TODO: 调用完结接口
+            this.$message.success('完结成功');
+            this.reload();
+          });
+        }).catch(() => {
+          // this.$message.info('已取消完结');
         });
       }
     }