|
|
|
|
@ -22,7 +22,8 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="有无合同" prop="contractFlag">
|
|
|
|
|
<el-radio-group v-model="form.contractFlag" :disabled="isFormDisabled">
|
|
|
|
|
<el-radio v-for="dict in contract_flag" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
|
|
|
|
<el-radio v-for="dict in contract_flag" :key="dict.value" :value="dict.value">{{ dict.label }}
|
|
|
|
|
</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -30,7 +31,8 @@
|
|
|
|
|
<el-form-item label="合同编号" prop="contractCode">
|
|
|
|
|
<el-input v-model="form.contractCode" placeholder="请输入合同编号" :disabled="isFormDisabled">
|
|
|
|
|
<template #append>
|
|
|
|
|
<el-button type="primary" @click="generateContractCode" :disabled="isCodeGenerated">生成合同编号</el-button>
|
|
|
|
|
<el-button type="primary" @click="generateContractCode" :disabled="isCodeGenerated">生成合同编号
|
|
|
|
|
</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -43,7 +45,8 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="合同大类" prop="contractCategory">
|
|
|
|
|
<el-select v-model="form.contractCategory" placeholder="请选择合同大类" disabled>
|
|
|
|
|
<el-option v-for="dict in contract_category" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
|
|
|
|
<el-option v-for="dict in contract_category" :key="dict.value" :label="dict.label"
|
|
|
|
|
:value="dict.value"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -57,14 +60,16 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="业务方向" prop="businessDirection">
|
|
|
|
|
<el-select v-model="form.businessDirection" placeholder="请选择业务方向" :disabled="isFormDisabled">
|
|
|
|
|
<el-option v-for="dict in business_direction" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
|
|
|
|
<el-option v-for="dict in business_direction" :key="dict.value" :label="dict.label"
|
|
|
|
|
:value="dict.value"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="部门" prop="contractDeptId">
|
|
|
|
|
<el-select v-model="form.contractDeptId" :disabled="isFormDisabled" placeholder="请选择部门">
|
|
|
|
|
<el-option v-for="item in deptInfoList" :key="item.deptId" :label="item.deptName" :value="item.deptId" />
|
|
|
|
|
<el-option v-for="item in deptInfoList" :key="item.deptId" :label="item.deptName"
|
|
|
|
|
:value="item.deptId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -86,35 +91,34 @@
|
|
|
|
|
<el-input v-model="form.signingPlace" placeholder="请输入签订地点" :disabled="isFormDisabled" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="合同总价" prop="totalPrice">
|
|
|
|
|
<el-input v-model="form.totalPrice" placeholder="根据合同物料自动计算" disabled>
|
|
|
|
|
<template #append>元</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="甲方公司" prop="oneCustomerId">
|
|
|
|
|
<el-select v-model="form.oneCustomerId" placeholder="请选择甲方公司" :disabled="isFormDisabled" filterable>
|
|
|
|
|
<el-option v-for="item in customerInfoList" :key="item.customerId" :label="item.customerName" :value="item.customerId" />
|
|
|
|
|
<el-select v-model="form.oneCustomerId" placeholder="请选择甲方公司" :disabled="isFormDisabled"
|
|
|
|
|
filterable>
|
|
|
|
|
<el-option v-for="item in customerInfoList" :key="item.customerId" :label="item.customerName"
|
|
|
|
|
:value="item.customerId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="乙方公司" prop="twoCustomerId">
|
|
|
|
|
<el-select v-model="form.twoCustomerId" placeholder="请选择乙方公司" :disabled="isFormDisabled" filterable>
|
|
|
|
|
<el-option v-for="item in customerInfoList" :key="item.customerId" :label="item.customerName" :value="item.customerId" />
|
|
|
|
|
<el-select v-model="form.twoCustomerId" placeholder="请选择乙方公司" :disabled="isFormDisabled"
|
|
|
|
|
filterable>
|
|
|
|
|
<el-option v-for="item in customerInfoList" :key="item.customerId" :label="item.customerName"
|
|
|
|
|
:value="item.customerId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="甲方授权代表" prop="oneRepresent">
|
|
|
|
|
<el-input v-model="form.oneRepresent" placeholder="请输入甲方法人或其授权代表" :disabled="isFormDisabled" />
|
|
|
|
|
<el-input v-model="form.oneRepresent" placeholder="请输入甲方法人或其授权代表"
|
|
|
|
|
:disabled="isFormDisabled" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="乙方授权代表" prop="twoRepresent">
|
|
|
|
|
<el-input v-model="form.twoRepresent" placeholder="请输入乙方法人或其授权代表" :disabled="isFormDisabled" />
|
|
|
|
|
<el-input v-model="form.twoRepresent" placeholder="请输入乙方法人或其授权代表"
|
|
|
|
|
:disabled="isFormDisabled" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
@ -146,7 +150,8 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="合同状态" prop="contractStatus">
|
|
|
|
|
<el-radio-group v-model="form.contractStatus" disabled>
|
|
|
|
|
<el-radio v-for="dict in contract_status" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
|
|
|
|
<el-radio v-for="dict in contract_status" :key="dict.value" :value="dict.value">{{ dict.label }}
|
|
|
|
|
</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -158,14 +163,18 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="合同模板标识" prop="contractTemplateFlag">
|
|
|
|
|
<el-radio-group v-model="form.contractTemplateFlag" :disabled="isFormDisabled">
|
|
|
|
|
<el-radio v-for="dict in contract_template_flag" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
|
|
|
|
<el-radio v-for="dict in contract_template_flag" :key="dict.value" :value="dict.value">{{ dict.label
|
|
|
|
|
}}
|
|
|
|
|
</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="合同负责人" prop="contractManagerId">
|
|
|
|
|
<el-select v-model="form.contractManagerId" placeholder="请选择该合同客户经理或签订人" :disabled="isFormDisabled" filterable>
|
|
|
|
|
<el-option v-for="item in userInfoList" :key="item.userId" :label="item.nickName" :value="item.userId" />
|
|
|
|
|
<el-select v-model="form.contractManagerId" placeholder="请选择该合同客户经理或签订人"
|
|
|
|
|
:disabled="isFormDisabled" filterable>
|
|
|
|
|
<el-option v-for="item in userInfoList" :key="item.userId" :label="item.nickName"
|
|
|
|
|
:value="item.userId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -200,6 +209,13 @@
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="合同总价" prop="totalPrice">
|
|
|
|
|
<el-input v-model="form.totalPrice" placeholder="根据合同物料自动计算" disabled>
|
|
|
|
|
<template #append>元</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-form-item label="备注" prop="remark">
|
|
|
|
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" :disabled="isFormDisabled" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
@ -213,6 +229,32 @@
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
<!-- 合同付款方式维护 -->
|
|
|
|
|
<el-card shadow="never" style="margin-top: 0">
|
|
|
|
|
<template #header>
|
|
|
|
|
<div style="text-align: left; font-weight: bold; font-size: 18px">合同付款方式</div>
|
|
|
|
|
</template>
|
|
|
|
|
<div style="margin-bottom: 16px">
|
|
|
|
|
<el-button type="primary" icon="Plus" v-if="!isFormDisabled" @click="handleAddPaymentMethod"
|
|
|
|
|
>新增付款方式
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<el-table :data="contractPaymentMethodList" v-loading="buttonLoading" border>
|
|
|
|
|
<el-table-column label="序号" align="center" prop="sortOrder" width="80" />
|
|
|
|
|
<!-- <el-table-column label="付款节点" align="center" prop="paymentMethod" width="140" min-width="120" />-->
|
|
|
|
|
<!-- <el-table-column label="支付期限(天)" align="center" prop="paymentDeadline" width="100" />-->
|
|
|
|
|
<!-- <el-table-column label="支付比例(%)" align="center" prop="paymentPercentage" width="100" />-->
|
|
|
|
|
<!-- <el-table-column label="发票比例(%)" align="center" prop="invoicePercentage" width="100" />-->
|
|
|
|
|
<el-table-column label="付款条款" align="center" prop="paymentDescription" min-width="120" />
|
|
|
|
|
<el-table-column label="操作" align="center" fixed="right" width="150" v-if="!isFormDisabled">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-button link type="primary" icon="Edit" @click="handleEditPaymentMethod(scope.row)">编辑</el-button>
|
|
|
|
|
<el-button link type="danger" icon="Delete" @click="handleDeletePaymentMethod(scope.row)">删除</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
<!-- 合同物料区域 -->
|
|
|
|
|
<el-card shadow="never" style="margin-top: 0">
|
|
|
|
|
<template #header>
|
|
|
|
|
@ -222,10 +264,11 @@
|
|
|
|
|
<!-- 合同物料表格 -->
|
|
|
|
|
<div style="margin-bottom: 16px">
|
|
|
|
|
<el-button type="primary" icon="Plus" v-if="!isFormDisabled" @click="handleAddMaterial"
|
|
|
|
|
>新增合同物料
|
|
|
|
|
>新增合同物料
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button type="success" icon="Plus" v-if="!isFormDisabled" @click="handleAddMaterialInfo" v-hasPermi="['oa/base:materialInfo:contractAdd']"
|
|
|
|
|
>添加SAP物料
|
|
|
|
|
<el-button type="success" icon="Plus" v-if="!isFormDisabled" @click="handleAddMaterialInfo"
|
|
|
|
|
v-hasPermi="['oa/base:materialInfo:contractAdd']"
|
|
|
|
|
>添加SAP物料
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@ -272,7 +315,8 @@
|
|
|
|
|
|
|
|
|
|
<!-- 合同物料备注 -->
|
|
|
|
|
<el-form-item label="合同物料备注" prop="materialRemark" style="margin-bottom: 16px">
|
|
|
|
|
<el-input v-model="form.materialRemark" type="textarea" :rows="3" placeholder="请输入合同物料备注" :disabled="isFormDisabled" />
|
|
|
|
|
<el-input v-model="form.materialRemark" type="textarea" :rows="3" placeholder="请输入合同物料备注"
|
|
|
|
|
:disabled="isFormDisabled" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
</el-card>
|
|
|
|
|
@ -284,7 +328,8 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="标准物料标识" prop="materialFlag">
|
|
|
|
|
<el-radio-group v-model="materialForm.materialFlag">
|
|
|
|
|
<el-radio v-for="dict in material_flag" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
|
|
|
|
|
<el-radio v-for="dict in material_flag" :key="dict.value" :value="dict.value">{{ dict.label }}
|
|
|
|
|
</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -333,7 +378,8 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="物料单位" prop="unitId">
|
|
|
|
|
<el-select v-model="materialForm.unitId" placeholder="请选择物料单位">
|
|
|
|
|
<el-option v-for="item in unitInfoList" :key="item.unitId" :label="item.unitName" :value="item.unitId" />
|
|
|
|
|
<el-option v-for="item in unitInfoList" :key="item.unitId" :label="item.unitName"
|
|
|
|
|
:value="item.unitId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -405,8 +451,62 @@
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 合同付款方式编辑对话框 -->
|
|
|
|
|
<el-dialog :title="paymentMethodDialog.title" v-model="paymentMethodDialog.visible" width="500px" append-to-body>
|
|
|
|
|
<el-form ref="paymentMethodFormRef" :model="paymentMethodForm" :rules="paymentMethodRules" label-width="120px">
|
|
|
|
|
<el-form-item label="序号" prop="sortOrder">
|
|
|
|
|
<el-input-number v-model="paymentMethodForm.sortOrder" placeholder="根据顺序自动生成" style="width: 100%"
|
|
|
|
|
:min="1" readonly :controls="false" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="付款节点" prop="paymentStageId">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="paymentMethodForm.paymentStageId"
|
|
|
|
|
placeholder="请选择付款节点"
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
filterable
|
|
|
|
|
@change="onPaymentStageChange"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in paymentStageList"
|
|
|
|
|
:key="item.paymentStageId"
|
|
|
|
|
:label="item.paymentMethod"
|
|
|
|
|
:value="item.paymentStageId"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="支付期限(天)" prop="paymentDeadline">
|
|
|
|
|
<el-input-number v-model="paymentMethodForm.paymentDeadline" placeholder="请输入支付期限(天)"
|
|
|
|
|
style="width: 100%" :min="0" @change="refreshPaymentDescription" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="支付比例(%)" prop="paymentPercentage">
|
|
|
|
|
<el-input-number v-model="paymentMethodForm.paymentPercentage" placeholder="请输入支付比例(如:30)"
|
|
|
|
|
style="width: 100%" :min="0" :max="100" @change="refreshPaymentDescription" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="发票比例(%)" prop="invoicePercentage">
|
|
|
|
|
<el-input-number v-model="paymentMethodForm.invoicePercentage" placeholder="请输入发票比例(如:30)"
|
|
|
|
|
style="width: 100%" :min="0" :max="100" @change="refreshPaymentDescription" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="付款条款" prop="paymentDescription">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="paymentMethodForm.paymentDescription"
|
|
|
|
|
type="textarea"
|
|
|
|
|
:rows="5"
|
|
|
|
|
placeholder="选择付款节点后自动带出条款模板,可修改"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<div class="dialog-footer">
|
|
|
|
|
<el-button type="primary" @click="submitPaymentMethodForm">确 定</el-button>
|
|
|
|
|
<el-button @click="cancelPaymentMethod">取 消</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 销售物料选择 -->
|
|
|
|
|
<SaleMaterialSelect ref="saleMaterialSelectRef" :multiple="false" @confirm-call-back="saleMaterialSelectCallBack"></SaleMaterialSelect>
|
|
|
|
|
<SaleMaterialSelect ref="saleMaterialSelectRef" :multiple="false"
|
|
|
|
|
@confirm-call-back="saleMaterialSelectCallBack"></SaleMaterialSelect>
|
|
|
|
|
|
|
|
|
|
<!-- 添加SAP物料对话框 -->
|
|
|
|
|
<el-dialog title="添加SAP物料" v-model="materialInfoDialog.visible" width="800px" append-to-body>
|
|
|
|
|
@ -430,7 +530,8 @@
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="物料单位" prop="unitId">
|
|
|
|
|
<el-select v-model="materialInfoForm.unitId" placeholder="请选择物料单位" style="width: 100%">
|
|
|
|
|
<el-option v-for="item in unitInfoList" :key="item.unitId" :label="item.unitName" :value="item.unitId" />
|
|
|
|
|
<el-option v-for="item in unitInfoList" :key="item.unitId" :label="item.unitName"
|
|
|
|
|
:value="item.unitId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -453,6 +554,7 @@
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 添加或修改OSS对象存储对话框 -->
|
|
|
|
|
<el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" append-to-body>
|
|
|
|
|
<el-form ref="ossFormRef" :model="form" :rules="rules" label-width="80px">
|
|
|
|
|
@ -477,9 +579,15 @@
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup name="ContractInfoEdit" lang="ts">
|
|
|
|
|
import { addContractInfo, contractSubmitAndFlowStart, getContractInfo, updateContractInfo } from '@/api/oa/erp/contractInfo';
|
|
|
|
|
import {
|
|
|
|
|
addContractInfo,
|
|
|
|
|
contractSubmitAndFlowStart,
|
|
|
|
|
getContractInfo,
|
|
|
|
|
updateContractInfo
|
|
|
|
|
} from '@/api/oa/erp/contractInfo';
|
|
|
|
|
import { ContractInfoForm } from '@/api/oa/erp/contractInfo/types';
|
|
|
|
|
import { ContractMaterialVO, ContractMaterialForm } from '@/api/oa/erp/contractMaterial/types';
|
|
|
|
|
import { ContractPaymentMethodForm } from '@/api/oa/erp/contractPaymentMethod/types';
|
|
|
|
|
import { getBaseUnitInfoList } from '@/api/oa/base/unitInfo';
|
|
|
|
|
import { getRuleGenerateCode } from '@/api/system/codeRule';
|
|
|
|
|
import { startWorkFlow } from '@/api/workflow/task';
|
|
|
|
|
@ -498,6 +606,8 @@ import { getInfo } from '@/api/login';
|
|
|
|
|
import FileUpload from '@/components/FileUpload/index.vue';
|
|
|
|
|
import { contractAddMaterialInfo } from '@/api/oa/base/materialInfo';
|
|
|
|
|
import { MaterialInfoForm } from '@/api/oa/base/materialInfo/types';
|
|
|
|
|
import { listPaymentStage } from '@/api/oa/base/paymentStage';
|
|
|
|
|
import type { PaymentStageVO } from '@/api/oa/base/paymentStage/types';
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
@ -505,7 +615,15 @@ const router = useRouter();
|
|
|
|
|
|
|
|
|
|
// 路由参数
|
|
|
|
|
const routeParams = ref<Record<string, any>>({});
|
|
|
|
|
const { contract_category, business_direction, contract_flag, contract_type, contract_status, material_flag, contract_template_flag } = toRefs<any>(
|
|
|
|
|
const {
|
|
|
|
|
contract_category,
|
|
|
|
|
business_direction,
|
|
|
|
|
contract_flag,
|
|
|
|
|
contract_type,
|
|
|
|
|
contract_status,
|
|
|
|
|
material_flag,
|
|
|
|
|
contract_template_flag
|
|
|
|
|
} = toRefs<any>(
|
|
|
|
|
proxy?.useDict('contract_category', 'business_direction', 'contract_flag', 'contract_type', 'contract_status', 'material_flag', 'contract_template_flag')
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@ -548,6 +666,11 @@ const contractMaterialList = computed(() => {
|
|
|
|
|
return (form.value as any).contractMaterialList || [];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 合同付款方式列表计算属性
|
|
|
|
|
const contractPaymentMethodList = computed(() => {
|
|
|
|
|
return (form.value as any).contractPaymentMethodList || [];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/** 查询打印模板下拉框结构 */
|
|
|
|
|
const printTemplateList = ref([]);
|
|
|
|
|
const getPrintTemplateListSelect = async () => {
|
|
|
|
|
@ -584,6 +707,13 @@ const getUserInfoListSelect = async () => {
|
|
|
|
|
userInfoList.value = res.data;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 付款节点下拉列表(回款阶段) */
|
|
|
|
|
const paymentStageList = ref<PaymentStageVO[]>([]);
|
|
|
|
|
const getPaymentStageListSelect = async () => {
|
|
|
|
|
const res = await listPaymentStage({ pageNum: 1, pageSize: 500 });
|
|
|
|
|
paymentStageList.value = res.rows || [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 合同物料对话框
|
|
|
|
|
const materialDialog = reactive({
|
|
|
|
|
visible: false,
|
|
|
|
|
@ -619,6 +749,116 @@ const materialRules = {
|
|
|
|
|
taxRate: [{ required: true, message: '税率不能为空', trigger: 'blur' }]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 合同付款方式对话框
|
|
|
|
|
const paymentMethodDialog = reactive({
|
|
|
|
|
visible: false,
|
|
|
|
|
title: ''
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 合同付款方式表单数据
|
|
|
|
|
const initPaymentMethodFormData: ContractPaymentMethodForm = {
|
|
|
|
|
paymentMethodId: undefined,
|
|
|
|
|
contractId: undefined,
|
|
|
|
|
sortOrder: undefined,
|
|
|
|
|
paymentStageId: undefined,
|
|
|
|
|
paymentDeadline: undefined,
|
|
|
|
|
paymentPercentage: undefined,
|
|
|
|
|
invoicePercentage: 0,
|
|
|
|
|
paymentAmount: undefined,
|
|
|
|
|
paymentDescription: undefined,
|
|
|
|
|
remark: undefined,
|
|
|
|
|
activeFlag: '1'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const paymentMethodForm = ref<ContractPaymentMethodForm>({ ...initPaymentMethodFormData });
|
|
|
|
|
|
|
|
|
|
const paymentMethodFormRef = ref<ElFormInstance>();
|
|
|
|
|
|
|
|
|
|
// 合同付款方式表单验证规则
|
|
|
|
|
const paymentMethodRules = {
|
|
|
|
|
paymentStageId: [{ required: true, message: '请选择付款节点', trigger: 'change' }],
|
|
|
|
|
paymentDeadline: [{ required: true, message: '支付期限(天)不能为空', trigger: 'blur' }],
|
|
|
|
|
paymentPercentage: [{ required: true, message: '支付比例不能为空', trigger: 'blur' }],
|
|
|
|
|
invoicePercentage: [{ required: true, message: '发票比例不能为空', trigger: 'blur' }]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 付款条款模板占位符映射:模板中的占位符 -> 数据字段名 */
|
|
|
|
|
const PAYMENT_TEMPLATE_PLACEHOLDERS: Record<string, string> = {
|
|
|
|
|
'{序号}': 'sortOrder',
|
|
|
|
|
'{支付期限}': 'paymentDeadline',
|
|
|
|
|
'{支付比例}': 'paymentPercentage',
|
|
|
|
|
'{发票比例}': 'invoicePercentage'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 通用方法:将付款条款模板中的占位符替换为实际数据
|
|
|
|
|
* @param template 模板字符串,可含 {序号}、{支付期限}、{支付比例}、{发票比例}
|
|
|
|
|
* @param data 数据对象,需含 sortOrder、paymentDeadline、paymentPercentage、invoicePercentage
|
|
|
|
|
* @returns 替换后的字符串
|
|
|
|
|
*/
|
|
|
|
|
const replacePaymentTemplate = (template: string | undefined, data: Record<string, any>): string => {
|
|
|
|
|
if (template == null || template === '') return '';
|
|
|
|
|
let result = template;
|
|
|
|
|
for (const [placeholder, fieldKey] of Object.entries(PAYMENT_TEMPLATE_PLACEHOLDERS)) {
|
|
|
|
|
const value = data[fieldKey];
|
|
|
|
|
result = result.replaceAll(placeholder, value !== undefined && value !== null ? String(value) : '');
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 当发票比例为 0 时,删除付款条款中从「且」到「后」之间的内容(含「且」「后」)
|
|
|
|
|
* @param text 付款条款文本
|
|
|
|
|
* @param invoicePercentage 发票比例
|
|
|
|
|
* @returns 处理后的文本
|
|
|
|
|
*/
|
|
|
|
|
const removeSegmentWhenInvoiceZero = (text: string, invoicePercentage: any): string => {
|
|
|
|
|
if (text == null || text === '') return text;
|
|
|
|
|
const isZero = invoicePercentage === 0 || invoicePercentage === '0' || Number(invoicePercentage) === 0;
|
|
|
|
|
if (!isZero) return text;
|
|
|
|
|
const startChar = '且';
|
|
|
|
|
const endChar = '后';
|
|
|
|
|
const idxStart = text.indexOf(startChar);
|
|
|
|
|
if (idxStart === -1) return text;
|
|
|
|
|
const idxEnd = text.indexOf(endChar, idxStart);
|
|
|
|
|
if (idxEnd === -1) return text;
|
|
|
|
|
return text.slice(0, idxStart) + text.slice(idxEnd + endChar.length);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 替换占位符并视发票比例删除「且…后」段落
|
|
|
|
|
*/
|
|
|
|
|
const applyPaymentDescription = (template: string | undefined, data: Record<string, any>): string => {
|
|
|
|
|
const replaced = replacePaymentTemplate(template, data);
|
|
|
|
|
return removeSegmentWhenInvoiceZero(replaced, data.invoicePercentage);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 当前付款方式弹窗使用的条款模板原文(用于字段变更时重新替换) */
|
|
|
|
|
const paymentMethodTemplateRaw = ref<string | null>(null);
|
|
|
|
|
|
|
|
|
|
/** 根据当前表单数据刷新付款条款(占位符替换 + 发票为0时删「且…后」) */
|
|
|
|
|
const refreshPaymentDescription = () => {
|
|
|
|
|
if (paymentMethodTemplateRaw.value) {
|
|
|
|
|
paymentMethodForm.value.paymentDescription = applyPaymentDescription(
|
|
|
|
|
paymentMethodTemplateRaw.value,
|
|
|
|
|
paymentMethodForm.value as Record<string, any>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 选择付款节点后带出该节点的付款条款模板并做字段匹配 */
|
|
|
|
|
const onPaymentStageChange = (paymentStageId: string | number | undefined) => {
|
|
|
|
|
if (paymentStageId == null) return;
|
|
|
|
|
const stage = paymentStageList.value.find((s) => s.paymentStageId === paymentStageId || String(s.paymentStageId) === String(paymentStageId));
|
|
|
|
|
if (stage?.paymentTemplate) {
|
|
|
|
|
paymentMethodTemplateRaw.value = stage.paymentTemplate;
|
|
|
|
|
paymentMethodForm.value.paymentDescription = applyPaymentDescription(
|
|
|
|
|
stage.paymentTemplate,
|
|
|
|
|
paymentMethodForm.value as Record<string, any>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type ContractInfoFormEx = ContractInfoForm & { file?: any };
|
|
|
|
|
|
|
|
|
|
const initFormData: ContractInfoFormEx = {
|
|
|
|
|
@ -654,6 +894,7 @@ const initFormData: ContractInfoFormEx = {
|
|
|
|
|
variables: undefined,
|
|
|
|
|
activeFlag: '1',
|
|
|
|
|
contractMaterialList: [],
|
|
|
|
|
contractPaymentMethodList: [],
|
|
|
|
|
file: undefined,
|
|
|
|
|
signingPlace: undefined,
|
|
|
|
|
materialRemark: undefined
|
|
|
|
|
@ -668,7 +909,7 @@ const data = reactive<{ form: ContractInfoFormEx; rules: any }>({
|
|
|
|
|
businessDirection: [{ required: true, message: '业务方向不能为空', trigger: 'blur' }],
|
|
|
|
|
contractManagerId: [{ required: true, message: '合同负责人不能为空', trigger: 'blur' }],
|
|
|
|
|
contractDeptId: [{ required: true, message: '部门不能为空', trigger: 'blur' }],
|
|
|
|
|
contractTemplateFlag: [{ required: true, message: '合同模板标识不能为空', trigger: 'blur' }],
|
|
|
|
|
contractTemplateFlag: [{ required: true, message: '合同模板标识不能为空', trigger: 'blur' }]
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@ -927,6 +1168,84 @@ const cancelMaterial = () => {
|
|
|
|
|
materialDialog.visible = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 新增付款方式(序号 = 当前条数 + 1)
|
|
|
|
|
const handleAddPaymentMethod = () => {
|
|
|
|
|
resetPaymentMethodForm();
|
|
|
|
|
paymentMethodForm.value.contractId = form.value.contractId as any;
|
|
|
|
|
const list = (form.value as any).contractPaymentMethodList || [];
|
|
|
|
|
paymentMethodForm.value.sortOrder = list.length + 1;
|
|
|
|
|
paymentMethodDialog.visible = true;
|
|
|
|
|
paymentMethodDialog.title = '新增付款方式';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 编辑付款方式
|
|
|
|
|
const handleEditPaymentMethod = (row: any) => {
|
|
|
|
|
resetPaymentMethodForm();
|
|
|
|
|
paymentMethodForm.value = { ...row };
|
|
|
|
|
paymentMethodDialog.visible = true;
|
|
|
|
|
paymentMethodDialog.title = '编辑付款方式';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 删除付款方式(删除后按顺序重新赋值序号)
|
|
|
|
|
const handleDeletePaymentMethod = async (row: any) => {
|
|
|
|
|
await proxy?.$modal.confirm('是否确认删除该付款方式?');
|
|
|
|
|
if (!(form.value as any).contractPaymentMethodList) {
|
|
|
|
|
(form.value as any).contractPaymentMethodList = [];
|
|
|
|
|
}
|
|
|
|
|
const list = (form.value as any).contractPaymentMethodList;
|
|
|
|
|
const index = list.findIndex((item: any) => item.paymentMethodId === row.paymentMethodId);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
list.splice(index, 1);
|
|
|
|
|
list.forEach((item: any, i: number) => {
|
|
|
|
|
item.sortOrder = i + 1;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
proxy?.$modal.msgSuccess('删除成功');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重置付款方式表单
|
|
|
|
|
const resetPaymentMethodForm = () => {
|
|
|
|
|
paymentMethodForm.value = { ...initPaymentMethodFormData };
|
|
|
|
|
paymentMethodTemplateRaw.value = null;
|
|
|
|
|
paymentMethodFormRef.value?.resetFields();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 取消付款方式编辑
|
|
|
|
|
const cancelPaymentMethod = () => {
|
|
|
|
|
resetPaymentMethodForm();
|
|
|
|
|
paymentMethodDialog.visible = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 提交付款方式表单
|
|
|
|
|
const submitPaymentMethodForm = () => {
|
|
|
|
|
paymentMethodFormRef.value?.validate((valid: boolean) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
if (!(form.value as any).contractPaymentMethodList) {
|
|
|
|
|
(form.value as any).contractPaymentMethodList = [];
|
|
|
|
|
}
|
|
|
|
|
const list = (form.value as any).contractPaymentMethodList;
|
|
|
|
|
const data = { ...paymentMethodForm.value };
|
|
|
|
|
// 付款条款占位符替换为当前字段值后再保存
|
|
|
|
|
data.paymentDescription = applyPaymentDescription(data.paymentDescription || '', data as Record<string, any>);
|
|
|
|
|
if (data.paymentMethodId) {
|
|
|
|
|
const index = list.findIndex((item: any) => item.paymentMethodId === data.paymentMethodId);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
list[index] = data;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
list.push({ ...data, paymentMethodId: undefined });
|
|
|
|
|
}
|
|
|
|
|
// 按顺序自动赋值序号,并重新替换付款条款中的 {序号}
|
|
|
|
|
list.forEach((item: any, index: number) => {
|
|
|
|
|
item.sortOrder = index + 1;
|
|
|
|
|
item.paymentDescription = applyPaymentDescription(item.paymentDescription || '', item);
|
|
|
|
|
});
|
|
|
|
|
proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
paymentMethodDialog.visible = false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 计算未税单价(由含税与税率推未税)
|
|
|
|
|
const calculateBeforePrice = () => {
|
|
|
|
|
const tax = Number(materialForm.value.taxRate);
|
|
|
|
|
@ -1011,6 +1330,7 @@ const loadSelectOptions = () => {
|
|
|
|
|
getCustomerInfoListSelect();
|
|
|
|
|
getPrintTemplateListSelect();
|
|
|
|
|
getUserInfoListSelect();
|
|
|
|
|
getPaymentStageListSelect();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|