|
|
<template>
|
|
|
<div ref="contractList" style="padding: 0 20px;">
|
|
|
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="合同列表">
|
|
|
<div slot="content"></div>
|
|
|
<slot>
|
|
|
<div class="selects">
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">关键字</span>
|
|
|
<span>
|
|
|
<Input v-model="select.keyword" clearable placeholder="关键字搜索" style="width: 200px"/>
|
|
|
</span>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">服务商/供应商</span>
|
|
|
<span>
|
|
|
<Input v-model="select.supply" clearable placeholder="请输入服务商/供应商" style="width: 200px"/>
|
|
|
</span>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">预算计划</span>
|
|
|
|
|
|
<span>
|
|
|
<Input v-model="select.plan_name" clearable placeholder="请选择预算计划" @on-focus="showPlanForSearch()"
|
|
|
style="width: 200px" @on-clear="clearSelectForSearch"/>
|
|
|
</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">签订年份</span>
|
|
|
<span>
|
|
|
<DatePicker :value="select.year" placeholder="选择年份" placement="bottom" style="width: 90px;"
|
|
|
type="year"
|
|
|
@on-change="(e)=>select.year = e"></DatePicker>
|
|
|
</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">创建日期</span>
|
|
|
<span>
|
|
|
<DatePicker v-model="select.showDatePicker" clearable placeholder="请选择日期" placement="bottom-start"
|
|
|
style="width: 200px" type="daterange" @on-change="datePick"></DatePicker>
|
|
|
</span>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
项目类型
|
|
|
</span>
|
|
|
<Select v-model="select.type" clearable placeholder="请选择项目类型" style="width:140px;">
|
|
|
<Option v-for="item in type" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
业务科室
|
|
|
</span>
|
|
|
<el-select v-model="select.department_id" clearable placeholder="业务科室选择" size="small"
|
|
|
style="width: 120px;">
|
|
|
<el-option v-for="item in departments" :key="item.id" :label="item.name" :value="item.id">
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
采购形式
|
|
|
</span>
|
|
|
<Select v-model="select.purchase_type_id" clearable placeholder="请选择采购形式" style="width:140px;">
|
|
|
<Option v-for="item in purchaseType" :key="item.id" :value="item.id">{{ item.value }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
采购方式
|
|
|
</span>
|
|
|
<Select v-model="select.purchase_way_id" clearable placeholder="请选择采购方式" style="width:200px;">
|
|
|
<Option v-for="item in purchaseWay" :key="item.id" :value="item.id">{{ item.value }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
预算金额
|
|
|
</span>
|
|
|
<el-input-number size="small" :controls="false" v-model="select.start_plan_price" :min="0" placeholder="最小金额" style="width: 100px;"/>
|
|
|
<span style="padding: 0 5px;">-</span>
|
|
|
<el-input-number size="small" :controls="false" v-model="select.end_plan_price" :min="0" placeholder="最大金额" style="width: 100px;"/>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
合同状态
|
|
|
</span>
|
|
|
<Select v-model="select.status" clearable placeholder="请选择" style="width:100px;">
|
|
|
<Option v-for="item in [{label:'待签订',value:1},{label:'已签订',value:2}]" :key="item.value"
|
|
|
:value="item.value">{{ item.label }}
|
|
|
</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
招标流程状态
|
|
|
</span>
|
|
|
|
|
|
<Select v-model="select.invite_status" clearable placeholder="请选择" style="width:100px;">
|
|
|
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
|
|
|
</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
采购流程状态
|
|
|
</span>
|
|
|
|
|
|
<Select v-model="select.purchase_status" clearable placeholder="请选择" style="width:100px;">
|
|
|
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
|
|
|
</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
合同会签状态
|
|
|
</span>
|
|
|
|
|
|
<Select v-model="select.join_status" clearable placeholder="请选择" style="width:100px;">
|
|
|
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
|
|
|
</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div>
|
|
|
<span style="padding: 0 6px;word-break: keep-all;">
|
|
|
请示流程状态
|
|
|
</span>
|
|
|
<Select v-model="select.req_status" clearable placeholder="请选择" style="width:100px;">
|
|
|
<Option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}
|
|
|
</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
|
|
|
<Button style="margin-left: 10px" type="primary" @click="handleAddContract">新增</Button>
|
|
|
<Button style="margin-left: 10px" type="primary" @click="getContracts">查询</Button>
|
|
|
<Button ghost style="margin-left: 10px" type="primary"
|
|
|
@click=" select = {showDatePicker:'',ageIndex:1,startDate:'',endDate:'',type:'',department:'',purchaseModality:'',purchaseMethods:'',priceMin:null,priceMax:null,status:''}">
|
|
|
重置
|
|
|
</Button>
|
|
|
<Button type="primary" @click="downloadExel()" style="margin-left: 10px">导出</Button>
|
|
|
<!-- <Button type="primary" style="margin-left: 10px">导出</Button>-->
|
|
|
</div>
|
|
|
</slot>
|
|
|
</lx-header>
|
|
|
|
|
|
<xy-table ref="xyTable" :cell-style="cellStyle" :list="list" :show-summary="true" :summary-method="summary"
|
|
|
:table-item="table" @cellClick="showPaymentPlan" @delete="(row)=>deleteContract(row.id)" @editor="">
|
|
|
<template v-slot:btns>
|
|
|
<el-table-column fixed="right" header-align="center" label="操作" width="200">
|
|
|
<template slot-scope="scope">
|
|
|
<div class="slot-btns">
|
|
|
<template v-if="scope.row.status === 2&&scope.row.is_end===0">
|
|
|
<template v-if="scope.row.is_assurance==1">
|
|
|
<!-- 如果是 履约文件-->
|
|
|
<template v-if="scope.row.assurance_status==1">
|
|
|
<!-- 那么必须财务审核通过-->
|
|
|
<Button class="slot-btns-item" size="small" type="primary"
|
|
|
@click="$refs['paymentRegistration'].getContract(scope.row),$refs['paymentRegistration'].isShowPaymentRegistration = true">
|
|
|
付款登记
|
|
|
</Button>
|
|
|
</template>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
<Button class="slot-btns-item" size="small" type="primary"
|
|
|
@click="$refs['paymentRegistration'].getContract(scope.row),$refs['paymentRegistration'].isShowPaymentRegistration = true">
|
|
|
付款登记
|
|
|
</Button>
|
|
|
</template>
|
|
|
</template>
|
|
|
|
|
|
<template v-if="scope.row.status === 1 && scope.row.join_status === 3">
|
|
|
<Button class="slot-btns-item" size="small" type="primary"
|
|
|
@click="$refs['contractSign'].isShow = true,$refs['contractSign'].contractId = scope.row.id">
|
|
|
签订合同
|
|
|
</Button>
|
|
|
</template>
|
|
|
<template
|
|
|
v-if="scope.row.invite_status === 1 && scope.row.purchase_status === 3 && (scope.row.purchase_way ? scope.row.purchase_way.remark === 'true' : false) && !scope.row.is_substitute">
|
|
|
<Button class="slot-btns-item" size="small" type="primary" @click="bidding(scope.row)">招标审查</Button>
|
|
|
</template>
|
|
|
<!-- <Button class="slot-btns-item" type="primary" size="small">附件管理</Button>-->
|
|
|
<template v-if="scope.row.req_status === 1 && (scope.row.is_plan === 0 && !scope.row.is_substitute || scope.row.has_charge)">
|
|
|
<Button class="slot-btns-item" size="small" type="primary" @click="askProcess(scope.row)">请示流程
|
|
|
</Button>
|
|
|
</template>
|
|
|
<!--不需要走采购流程那么直接就是会签,如果采购方式不需要招标的也是直接会签-->
|
|
|
<template
|
|
|
v-if="(scope.row.has_charge && scope.row.req_status === 3 && scope.row.join_status === 1) || (scope.row.join_status === 1 && ((scope.row.invite_status === 3)||((scope.row.purchase_way ? scope.row.purchase_way.remark === 'false' : false) && scope.row.purchase_status === 3)) || ( scope.row.is_substitute && scope.row.join_status === 1) ) ">
|
|
|
|
|
|
<Button class="slot-btns-item" size="small" type="primary" @click="signProcess(scope.row)">合同会签
|
|
|
</Button>
|
|
|
</template>
|
|
|
<template
|
|
|
v-if="!scope.row.has_charge && scope.row.is_simple !== 1 && scope.row.purchase_status === 1 && ((scope.row.req_status === 3 && scope.row.is_plan === 0)||scope.row.is_plan === 1)&& !scope.row.is_substitute ">
|
|
|
<Button class="slot-btns-item" size="small" type="primary" @click="buyProcess(scope.row)">采购流程
|
|
|
</Button>
|
|
|
</template>
|
|
|
|
|
|
<Poptip trigger="hover" placement="bottom" transfer>
|
|
|
<Button ghost size="small" type="primary">更多</Button>
|
|
|
<div slot="content">
|
|
|
<template
|
|
|
v-if="!(scope.row.req_status != 1 || scope.row.join_status != 1 || scope.row.invite_status != 1 || scope.row.purchase_status != 1 || scope.row.status === 2)">
|
|
|
<Poptip :transfer="true" confirm placement="bottom" title="确认要删除吗"
|
|
|
@on-ok="()=>deleteContract(scope.row.id)">
|
|
|
<i-button class="slot-btns-item" ghost size="small" type="error">删除
|
|
|
</i-button>
|
|
|
</Poptip>
|
|
|
</template>
|
|
|
<Button class="slot-btns-item" size="small" type="primary"
|
|
|
@click="$refs['detailContract'].getDetail(scope.row.id),$refs['detailContract'].isShowDetail = true">
|
|
|
查看
|
|
|
</Button>
|
|
|
<template v-if="scope.row.status != 2||hasEdit">
|
|
|
<Button class="slot-btns-item" size="small" type="primary"
|
|
|
@click="handleEdit(scope.row)">编辑
|
|
|
</Button>
|
|
|
</template>
|
|
|
<template v-if="hasEdit&&scope.row.status === 2">
|
|
|
<Button class="slot-btns-item" size="small" type="primary"
|
|
|
@click="$refs['contractSign'].isShow = true,$refs['contractSign'].contractId = scope.row.id">
|
|
|
签订修改
|
|
|
</Button>
|
|
|
</template>
|
|
|
</div>
|
|
|
</Poptip>
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</template>
|
|
|
</xy-table>
|
|
|
|
|
|
<div style="display: flex;justify-content: flex-end;">
|
|
|
<Page :total="total" show-elevator @on-change="pageChange" show-sizer @on-page-size-change="pageSizeChange"/>
|
|
|
</div>
|
|
|
|
|
|
<!-- 新增合同模态框 -->
|
|
|
<Modal
|
|
|
v-model="isShowAdd"
|
|
|
:title="isEditMode ? '编辑合同' : '新增合同'"
|
|
|
width="800"
|
|
|
:mask-closable="false"
|
|
|
:closable="false"
|
|
|
class="contract-add-modal"
|
|
|
>
|
|
|
<!-- Steps Header -->
|
|
|
<div class="steps-header">
|
|
|
<div class="step" :class="{ active: currentStep === 1 }">
|
|
|
<span class="step-number">1</span>
|
|
|
<span class="step-text">选择类型</span>
|
|
|
</div>
|
|
|
<div class="step" :class="{ active: currentStep === 2 }">
|
|
|
<span class="step-number">2</span>
|
|
|
<span class="step-text">基本信息</span>
|
|
|
</div>
|
|
|
<div class="step" :class="{ active: currentStep === 3 }">
|
|
|
<span class="step-number">3</span>
|
|
|
<span class="step-text">附件信息</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Step Content -->
|
|
|
<div class="step-content">
|
|
|
<!-- Step 1: Type Selection -->
|
|
|
<div v-show="currentStep === 1" class="step-content">
|
|
|
<div class="form-group">
|
|
|
<label class="form-label">分类</label>
|
|
|
<Select v-model="form.category" @on-change="handleCategoryChange" placeholder="请选择分类" class="form-input">
|
|
|
<Option v-for="item in categoryOptions" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div class="form-group">
|
|
|
<label class="form-label">事项类型</label>
|
|
|
<Select v-model="form.affairType" @on-change="handleAffairTypeChange" placeholder="请选择事项类型" class="form-input">
|
|
|
<Option v-for="item in affairTypeOptions" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div class="form-group">
|
|
|
<label class="form-label">合同类型</label>
|
|
|
<Select v-model="form.contractType" @on-change="handleContractTypeChange" placeholder="请选择合同类型" class="form-input">
|
|
|
<Option v-for="item in contractTypeOptions" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div class="form-group">
|
|
|
<label class="form-label">采购形式</label>
|
|
|
<Select v-model="form.purchaseForm" @on-change="handlePurchaseFormChange" placeholder="请选择采购形式" class="form-input">
|
|
|
<Option v-for="item in purchaseFormOptions" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
<div class="form-group">
|
|
|
<label class="form-label">采购方式</label>
|
|
|
<Select v-model="form.purchaseMethod" @on-change="handlePurchaseMethodChange" placeholder="请选择采购方式" class="form-input">
|
|
|
<Option v-for="item in purchaseMethodOptions" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
|
|
</Select>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Step 2: Basic Information -->
|
|
|
<div v-show="currentStep === 2" class="step-content">
|
|
|
<!-- 选择的合同模版类型信息 -->
|
|
|
<div class="template-info">
|
|
|
<div class="info-title">合同类型</div>
|
|
|
<div class="info-content">
|
|
|
<div class="info-item">
|
|
|
<span class="label">合同分类:</span>
|
|
|
<span class="value">{{ getCategoryName(form.category) }}</span>
|
|
|
</div>
|
|
|
<div class="info-item">
|
|
|
<span class="label">事务类型:</span>
|
|
|
<span class="value">{{ getAffairTypeName(form.affairType) }}</span>
|
|
|
</div>
|
|
|
<div class="info-item">
|
|
|
<span class="label">合同类型:</span>
|
|
|
<span class="value">{{ getContractTypeName(form.contractType) }}</span>
|
|
|
</div>
|
|
|
<div class="info-item">
|
|
|
<span class="label">采购形式:</span>
|
|
|
<span class="value">{{ getPurchaseFormName(form.purchaseForm) }}</span>
|
|
|
</div>
|
|
|
<div class="info-item">
|
|
|
<span class="label">采购方式:</span>
|
|
|
<span class="value">{{ getPurchaseMethodName(form.purchaseMethod) }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 流程控制 -->
|
|
|
<div class="form-section">
|
|
|
<div class="section-title">合同配置</div>
|
|
|
<div class="process-control-grid">
|
|
|
<div class="control-item">
|
|
|
<div class="control-label">是否为简易流程</div>
|
|
|
<div class="control-content">
|
|
|
<el-radio-group v-model="form.is_simple">
|
|
|
<el-radio :label="0">否</el-radio>
|
|
|
<el-radio :label="1">是</el-radio>
|
|
|
</el-radio-group>
|
|
|
<div class="helper-text">(水电煤、报刊订阅、网络通讯、车辆使用等费用付款)</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="control-item">
|
|
|
<div class="control-label">是否为河道处收费类项目</div>
|
|
|
<div class="control-content">
|
|
|
<el-radio-group v-model="form.has_charge">
|
|
|
<el-radio :label="0">否</el-radio>
|
|
|
<el-radio :label="1">是</el-radio>
|
|
|
</el-radio-group>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="control-item">
|
|
|
<div class="control-label">是否为预算内确定项目</div>
|
|
|
<div class="control-content">
|
|
|
<el-radio-group v-model="form.isBudget">
|
|
|
<el-radio :label="0">否</el-radio>
|
|
|
<el-radio :label="1">是</el-radio>
|
|
|
</el-radio-group>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="control-item">
|
|
|
<div class="control-label">是否为代建项目</div>
|
|
|
<div class="control-content">
|
|
|
<el-radio-group v-model="form.is_substitute">
|
|
|
<el-radio :label="0">否</el-radio>
|
|
|
<el-radio :label="1">是</el-radio>
|
|
|
</el-radio-group>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 基本信息表单 -->
|
|
|
<div class="form-section">
|
|
|
<div class="section-title">基本信息</div>
|
|
|
<el-form :model="form" label-width="140px" ref="basicInfoForm">
|
|
|
<el-form-item label="项目名称" prop="name" :rules="[{ required: true, message: '请输入项目名称', trigger: 'submit' }]" v-show="showFields.projectName">
|
|
|
<el-input v-model="form.name" placeholder="请输入项目名称"></el-input>
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="项目类型" prop="type" :rules="[{ required: true, message: '请选择项目类型', trigger: 'submit' }]" v-show="showFields.projectType">
|
|
|
<el-select v-model="form.type" placeholder="请选择项目类型" style="width: 100%">
|
|
|
<el-option v-for="item in type" :key="item.value" :value="item.value" :label="item.label"></el-option>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 新增承包商/供应商输入框 -->
|
|
|
<el-form-item
|
|
|
label="承包商/供应商"
|
|
|
prop="supply"
|
|
|
:rules="[{ required: form.is_simple === 1, message: '请输入承包商/供应商', trigger: 'submit' }]"
|
|
|
v-show="form.is_simple === 1">
|
|
|
<el-input v-model="form.supply" placeholder="请输入承包商/供应商"></el-input>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 新增执行科室选择 -->
|
|
|
<el-form-item label="执行科室" prop="contract_carry_department" :rules="[{ required: true, message: '请选择执行科室', trigger: 'submit' }]">
|
|
|
<div class="department-selector">
|
|
|
<el-select
|
|
|
v-model="form.contract_carry_department"
|
|
|
placeholder="请选择执行科室"
|
|
|
style="width: 100%"
|
|
|
multiple
|
|
|
collapse-tags
|
|
|
@remove-tag="removeDepartment">
|
|
|
<el-option
|
|
|
v-for="item in departments"
|
|
|
:key="item.id"
|
|
|
:label="item.name"
|
|
|
:value="item.id">
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
<div class="department-tags" v-if="form.contract_carry_department && form.contract_carry_department.length > 0">
|
|
|
<el-tag
|
|
|
v-for="id in form.contract_carry_department"
|
|
|
:key="id"
|
|
|
closable
|
|
|
@close="removeDepartment(id)">
|
|
|
{{ getDepartmentName(id) }}
|
|
|
</el-tag>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="合同预算金额(元)" prop="price" :rules="[{ required: true, message: '请输入预算金额', trigger: 'submit' }]" v-show="showFields.budgetPrice">
|
|
|
<el-input-number v-model="form.price" :min="0" :precision="2" :step="1000" style="width: 100%"></el-input-number>
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="资金渠道" prop="moneyWay" :rules="[{ required: true, message: '请选择资金渠道', trigger: 'submit' }]" v-show="showFields.fundChannel">
|
|
|
<div class="money-way-selector">
|
|
|
<el-select
|
|
|
v-model="form.moneyWay"
|
|
|
placeholder="请选择资金渠道"
|
|
|
style="width: 100%"
|
|
|
multiple
|
|
|
collapse-tags
|
|
|
@remove-tag="removeMoneyWay">
|
|
|
<el-option
|
|
|
v-for="item in moneyWay"
|
|
|
:key="item.id"
|
|
|
:label="item.value"
|
|
|
:value="item.id">
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
<div class="money-way-tags" v-if="form.moneyWay && form.moneyWay.length > 0">
|
|
|
<el-tag
|
|
|
v-for="id in form.moneyWay"
|
|
|
:key="id"
|
|
|
closable
|
|
|
@close="removeMoneyWay(id)">
|
|
|
{{ getMoneyWayName(id) }}
|
|
|
</el-tag>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="关联预算计划" prop="plan" v-show="showFields.budgetPlan" :rules="[{ required: true, message: '请选择关联预算计划', trigger: 'change' }]">
|
|
|
<div class="plan-selector">
|
|
|
<el-input
|
|
|
v-model="form.plan_display"
|
|
|
placeholder="请选择预算计划"
|
|
|
readonly
|
|
|
class="plan-input"
|
|
|
@focus="showPlanForSearch('modal')">
|
|
|
</el-input>
|
|
|
<div class="plan-tags" v-if="form.plan && form.plan.length > 0">
|
|
|
<el-tag
|
|
|
v-for="item in form.plan"
|
|
|
:key="item.id"
|
|
|
closable
|
|
|
@close="removePlan(item)">
|
|
|
{{ item.label }}
|
|
|
</el-tag>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Step 3: Attachment Information -->
|
|
|
<div v-show="currentStep === 3" class="step-content">
|
|
|
<!-- 事前支付表格 -->
|
|
|
<div v-if="form.before_contract_template && !form.showAfterPayment" class="form-section">
|
|
|
<div class="section-title">事前支付表格</div>
|
|
|
<div ref="beforePaymentForm" v-html="form.before_forms || form.before_contract_template.template"></div>
|
|
|
</div>
|
|
|
<!-- 事后支付表格 -->
|
|
|
<div v-else-if="form.contract_template" class="form-section">
|
|
|
<div class="section-title">事后支付表格</div>
|
|
|
<div ref="afterPaymentForm" v-html="form.forms || form.contract_template.template"></div>
|
|
|
</div>
|
|
|
<!-- 无支付表格提示 -->
|
|
|
<div v-else class="form-section">
|
|
|
<div class="section-title">无支付表格</div>
|
|
|
<div class="no-payment-form">当前选择的合同类型没有配置支付表格</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div slot="footer">
|
|
|
<div class="modal-footer">
|
|
|
<Button v-if="currentStep > 1" @click="prevStep" class="action-button">上一步</Button>
|
|
|
<Button v-if="currentStep < 3" type="primary" @click="nextStep" class="action-button">下一步</Button>
|
|
|
<!-- 当有事前支付表格且未显示事后支付表格时 -->
|
|
|
<template v-if="currentStep === 3 && form.before_contract_template && !form.showAfterPayment">
|
|
|
<!-- 新增模式下显示跳过按钮 -->
|
|
|
<template v-if="!isEditMode">
|
|
|
<Button type="primary" @click="nextPaymentStep" class="action-button">下一步</Button>
|
|
|
<Button @click="skipPrePayment" class="action-button">跳过,稍后填写</Button>
|
|
|
</template>
|
|
|
<!-- 编辑模式下,只有当before_forms为空时才显示跳过按钮 -->
|
|
|
<template v-else-if="(!form.before_forms || form.before_forms.trim() === '' || !form.skipBeforeTemplate)">
|
|
|
<Button type="primary" @click="nextPaymentStep" class="action-button">下一步</Button>
|
|
|
<Button @click="skipPrePayment" class="action-button">跳过,稍后填写</Button>
|
|
|
</template>
|
|
|
<!-- 编辑模式下,如果before_forms不为空,只显示下一步按钮 -->
|
|
|
<template v-else>
|
|
|
<Button type="primary" @click="nextPaymentStep" class="action-button">下一步</Button>
|
|
|
</template>
|
|
|
</template>
|
|
|
<!-- 当显示事后支付表格时 -->
|
|
|
<template v-else-if="currentStep === 3 && form.contract_template">
|
|
|
<!-- 新增模式下显示跳过按钮 -->
|
|
|
<template v-if="!isEditMode">
|
|
|
<Button type="primary" @click="submit" class="action-button">提交</Button>
|
|
|
<Button @click="skipPostPayment" class="action-button">跳过,稍后填写</Button>
|
|
|
</template>
|
|
|
<!-- 编辑模式下,只有当forms为空时才显示跳过按钮 -->
|
|
|
<template v-else-if="(!form.forms || form.forms.trim() === '' || !form.skipAfterTemplate)">
|
|
|
<Button type="primary" @click="submit" class="action-button">提交</Button>
|
|
|
<Button @click="skipPostPayment" class="action-button">跳过,稍后填写</Button>
|
|
|
</template>
|
|
|
<!-- 编辑模式下,如果forms不为空,只显示提交按钮 -->
|
|
|
<template v-else>
|
|
|
<Button type="primary" @click="submit" class="action-button">提交</Button>
|
|
|
</template>
|
|
|
</template>
|
|
|
<!-- 当没有支付表格时,只显示"提交"按钮 -->
|
|
|
<Button v-else-if="currentStep === 3" type="primary" @click="submit" class="action-button">提交</Button>
|
|
|
<Button @click="cancel" class="action-button">取消</Button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</Modal>
|
|
|
|
|
|
<!-- 搜索使用 预算计划 -->
|
|
|
<xy-dialog :is-show.sync="isShowPlanForSearch" title="预算计划" :width="720" @on-ok="planSelectForSearch">
|
|
|
<template v-slot:normalContent>
|
|
|
<Input v-model="planSearch.name" search enter-button="搜 索" placeholder="搜索预算计划.."
|
|
|
@on-search="searchBudgets"/>
|
|
|
<div style="margin: 10px 0;display: flex;justify-content: space-between;align-items: center;">
|
|
|
<div v-if="planSource === 'search'">已选择:<span style="margin-right:10px">{{ select.plan_name }}</span></div>
|
|
|
<div v-if="planSource === 'modal'">已选择:<span style="margin-right:10px">{{ form.plan_display }}</span></div>
|
|
|
<el-link type="success" @click="clearSelectForSearch">清空选择</el-link>
|
|
|
</div>
|
|
|
<xy-table :list="plans" @rowClick="selectPlanForSearch" :show-index="false" :table-item="planTableSearch"
|
|
|
:height="310" style="margin-top: 10px;" ref="singlePlanTable">
|
|
|
<template v-slot:btns>
|
|
|
<el-table-column label="使用金额" header-align="center" v-if="planSource === 'modal'">
|
|
|
<template slot-scope="scope">
|
|
|
<Input :value="scope.row.useMoney" @input="planInput($event, scope.row)" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</template>
|
|
|
</xy-table>
|
|
|
<div style="display: flex;justify-content: flex-end;">
|
|
|
<Page :total="planTotal" show-elevator @on-change="planPageChange"/>
|
|
|
</div>
|
|
|
<el-tag type="warning">点击行进行选择</el-tag>
|
|
|
</template>
|
|
|
<template v-slot:footerContent>
|
|
|
<Button type="primary" @click="planSelectForSearch">确定</Button>
|
|
|
</template>
|
|
|
</xy-dialog>
|
|
|
|
|
|
<!-- 新增表 预算计划 -->
|
|
|
<xy-dialog :is-show.sync="isShowPlan" :width="720" title="预算计划" @on-ok="planSelect">
|
|
|
<template v-slot:normalContent>
|
|
|
<div style="display: flex;">
|
|
|
<el-select placeholder="科室选择" clearable size="small" v-model="planSearch.plan_department_id"
|
|
|
style="width: 160px;">
|
|
|
<el-option v-for="item in departments" :label="item.name" :value="item.id" :key="item.id">
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
<Input v-model="planSearch.name" enter-button="搜 索" placeholder="搜索预算计划.." search
|
|
|
@on-search="searchBudgets"/>
|
|
|
</div>
|
|
|
<xy-table ref="planTable" :height="300" :list="plans" :show-index="false" :table-item="planTable"
|
|
|
style="margin-top: 10px;" @select="selectPlan">
|
|
|
<template v-slot:btns>
|
|
|
<el-table-column header-align="center" label="使用金额" fixed="right" width="140">
|
|
|
<template slot-scope="scope">
|
|
|
<Input :value="scope.row.useMoney" @input="planInput($event,scope.row)"/>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</template>
|
|
|
</xy-table>
|
|
|
|
|
|
<div style="display: flex;justify-content: flex-end;">
|
|
|
<Page :total="planTotal" show-elevator @on-change="planPageChange"/>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<template v-slot:footerContent>
|
|
|
<Button type="primary" @click="isShowPlan = false">确定</Button>
|
|
|
</template>
|
|
|
</xy-dialog>
|
|
|
|
|
|
<!-- 编辑-->
|
|
|
<editor ref="editor" :departments="departments" :is-show-editor.sync="isShowEditor" :money-way="moneyWay" :purchase-type="purchaseType"
|
|
|
:purchase-way="purchaseWay" @success="getContracts"></editor>
|
|
|
|
|
|
<!-- 查看-->
|
|
|
<detail ref="detailContract"></detail>
|
|
|
|
|
|
<!--付款登记-->
|
|
|
<paymentRegistration ref="paymentRegistration"></paymentRegistration>
|
|
|
|
|
|
<!-- 合同签订-->
|
|
|
<contractSign ref="contractSign" @signSuccess="getContracts"></contractSign>
|
|
|
|
|
|
<!-- 查看付款计划-->
|
|
|
<contractPaymentRegistration ref="contractPaymentRegistration"></contractPaymentRegistration>
|
|
|
|
|
|
<govPlane ref="govPlane" @selected="row => form.gov_plane_id = row.id"></govPlane>
|
|
|
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import {
|
|
|
getContract,
|
|
|
addContrant,
|
|
|
delContract,
|
|
|
checkContractName,
|
|
|
editorContract
|
|
|
} from "@/api/contract/contract"
|
|
|
import {
|
|
|
getparameter
|
|
|
} from "@/api/system/dictionary"
|
|
|
import {
|
|
|
getContractCategoryTemplateBaseConfig,
|
|
|
getContractCategoryTemplateConfigParams,
|
|
|
getContractFormList
|
|
|
} from '@/api/businessConfig/businessConfig'
|
|
|
import {
|
|
|
listdeptNoAuth
|
|
|
} from "@/api/system/department";
|
|
|
import {
|
|
|
getBudget
|
|
|
} from "@/api/budget/budget"
|
|
|
import {
|
|
|
getOatoken
|
|
|
} from "@/api/oatoken"
|
|
|
import {
|
|
|
parseTime
|
|
|
} from "@/utils"
|
|
|
import {
|
|
|
Message
|
|
|
} from "element-ui";
|
|
|
import {
|
|
|
getInfo
|
|
|
} from '@/api/user.js'
|
|
|
import {
|
|
|
getToken
|
|
|
} from '@/utils/auth'
|
|
|
import editor from "./components/editorContract"
|
|
|
import detail from "./components/detailContract"
|
|
|
import paymentRegistration from "./components/paymentRegistration";
|
|
|
import contractSign from "@/views/contract/components/contractSign";
|
|
|
import contractPaymentRegistration from "@/views/contract/components/contractPaymentRegistration";
|
|
|
import govPlane from './components/govPlane.vue';
|
|
|
import {
|
|
|
download
|
|
|
} from '@/utils/downloadRequest'
|
|
|
export default {
|
|
|
components: {
|
|
|
editor,
|
|
|
detail,
|
|
|
paymentRegistration,
|
|
|
contractSign,
|
|
|
contractPaymentRegistration,
|
|
|
govPlane,
|
|
|
},
|
|
|
data() {
|
|
|
var planPass = (rule, value, callback) => {
|
|
|
if (this.form.isBudget) {
|
|
|
if (this.form.plan.length === 0) {
|
|
|
callback(new Error('必选'))
|
|
|
} else {
|
|
|
callback()
|
|
|
}
|
|
|
} else {
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
var supplyPass = (rule,value,callback) => {
|
|
|
if(this.form.is_simple){
|
|
|
if(value === ''){
|
|
|
callback(new Error('必填'))
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
var moneyPass = (rule,value,callback) => {
|
|
|
if(this.form.is_simple){
|
|
|
if(value === ''){
|
|
|
callback(new Error('必填'))
|
|
|
}else{
|
|
|
if(/^\d+(\.\d+)?$/.test(value)){
|
|
|
callback()
|
|
|
}else{
|
|
|
callback(new Error('必须为数字'))
|
|
|
}
|
|
|
}
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
var typePass = (rule,value,callback) => {
|
|
|
if(!this.form.is_simple){
|
|
|
if(value === ''){
|
|
|
callback(new Error('必填'))
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
var methodsPass = (rule,value,callback) => {
|
|
|
if(!this.form.is_simple){
|
|
|
if(value === ''){
|
|
|
callback(new Error('必填'))
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
var modalityPass = (rule,value,callback) => {
|
|
|
if(!this.form.is_simple){
|
|
|
if(value === ''){
|
|
|
callback(new Error('必填'))
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
var pricePass = (rule,value,callback) => {
|
|
|
if(!this.form.is_simple){
|
|
|
if(value === ''){
|
|
|
callback(new Error('必填'))
|
|
|
}else{
|
|
|
if(/^\d+(\.\d+)?$/.test(value)){
|
|
|
callback()
|
|
|
}else{
|
|
|
callback(new Error('必须为数字'))
|
|
|
}
|
|
|
}
|
|
|
}else{
|
|
|
callback()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
userList: ["liuxiangyu", "zhushulan", "admin", "jiangjiao"],
|
|
|
window: {
|
|
|
width: 0,
|
|
|
height: 0,
|
|
|
top: 0,
|
|
|
left: 0
|
|
|
},
|
|
|
hasEdit: false,
|
|
|
// 添加控制显示/隐藏的变量
|
|
|
showFields: {
|
|
|
purchaseMethod: true,
|
|
|
projectName: true,
|
|
|
projectType: true,
|
|
|
budgetPrice: true,
|
|
|
fundChannel: true,
|
|
|
budgetPlan: true,
|
|
|
request: true,
|
|
|
purchaseApproval: true,
|
|
|
tenderReview: true,
|
|
|
contractSign: true
|
|
|
},
|
|
|
planSource: 'search',
|
|
|
isShowPlanForSearch: false,
|
|
|
options: [{
|
|
|
value: "",
|
|
|
label: '全部'
|
|
|
}, {
|
|
|
value: 1,
|
|
|
label: '待申请'
|
|
|
}, {
|
|
|
value: 2,
|
|
|
label: '流转中'
|
|
|
}, {
|
|
|
value: 3,
|
|
|
label: '已办结'
|
|
|
}],
|
|
|
|
|
|
//搜索
|
|
|
select: {
|
|
|
keyword: '',
|
|
|
showDatePicker: '',
|
|
|
pageIndex: 1,
|
|
|
pageSize: 10,
|
|
|
startDate: "",
|
|
|
endDate: "",
|
|
|
type: "",
|
|
|
department_id: "",
|
|
|
purchaseModality: "",
|
|
|
purchaseMethods: "",
|
|
|
priceMin: null,
|
|
|
priceMax: null,
|
|
|
status: "",
|
|
|
year: "",
|
|
|
plan_id: "",
|
|
|
plan_name: "请选择预算计划",
|
|
|
start_plan_price: undefined,
|
|
|
end_plan_price: undefined,
|
|
|
|
|
|
},
|
|
|
type: [{
|
|
|
label: '服务',
|
|
|
value: 1
|
|
|
}, {
|
|
|
label: '货物',
|
|
|
value: 2
|
|
|
}, {
|
|
|
label: '工程',
|
|
|
value: 3
|
|
|
}],
|
|
|
purchaseType: [], //购买形式
|
|
|
purchaseWay: [], //购买方式
|
|
|
moneyWay: [], //资金渠道
|
|
|
departments: [], //部门科室
|
|
|
list: [], //数据
|
|
|
total: 0,
|
|
|
//表格
|
|
|
table: [{
|
|
|
label: "项目名称",
|
|
|
width: 380,
|
|
|
prop: 'name',
|
|
|
fixed: 'left',
|
|
|
align: 'left'
|
|
|
},
|
|
|
{
|
|
|
label: "采购形式",
|
|
|
width: 120,
|
|
|
prop: 'purchase_type.value',
|
|
|
formatter:(cell, data, value) => {
|
|
|
return value ? value : '无'
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "项目类型",
|
|
|
width: 120,
|
|
|
prop: 'type',
|
|
|
formatter: (cell, data, value) => {
|
|
|
|
|
|
switch (value) {
|
|
|
case 1:
|
|
|
return "服务"
|
|
|
break;
|
|
|
case 2:
|
|
|
return "货物"
|
|
|
break;
|
|
|
case 3:
|
|
|
return "工程"
|
|
|
break;
|
|
|
default:
|
|
|
return "无"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "采购流程",
|
|
|
multiHd: [{
|
|
|
label: "请示流程",
|
|
|
width: 140,
|
|
|
prop: 'req_status',
|
|
|
formatter: (cell, data, value) => {
|
|
|
if (cell.is_substitute && !cell.has_charge) {
|
|
|
return '无'
|
|
|
}
|
|
|
if (cell.is_plan === 1 && !cell.has_charge) {
|
|
|
return '无'
|
|
|
}
|
|
|
switch (value) {
|
|
|
case 1:
|
|
|
return "待申请"
|
|
|
break;
|
|
|
case 2:
|
|
|
return "流转中"
|
|
|
break;
|
|
|
case 3:
|
|
|
return "已办结"
|
|
|
break;
|
|
|
default:
|
|
|
return "异常"
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "采购业务审批流程",
|
|
|
width: 158,
|
|
|
prop: 'purchase_status',
|
|
|
formatter: (cell, data, value) => {
|
|
|
if (cell.is_substitute || cell.is_simple) {
|
|
|
return '无'
|
|
|
}
|
|
|
switch (value) {
|
|
|
case 1:
|
|
|
return "待申请"
|
|
|
break;
|
|
|
case 2:
|
|
|
return "流转中"
|
|
|
break;
|
|
|
case 3:
|
|
|
return "已办结"
|
|
|
break;
|
|
|
default:
|
|
|
return "异常"
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "招标审核流程",
|
|
|
width: 145,
|
|
|
prop: 'invite_status',
|
|
|
formatter: (cell, data, value) => {
|
|
|
if (cell.is_substitute || cell.is_simple) {
|
|
|
return '无'
|
|
|
}
|
|
|
if (cell.purchase_way?.remark === 'false') {
|
|
|
return '无'
|
|
|
}
|
|
|
switch (value) {
|
|
|
case 1:
|
|
|
return "待申请"
|
|
|
break;
|
|
|
case 2:
|
|
|
return "流转中"
|
|
|
break;
|
|
|
case 3:
|
|
|
return "已办结"
|
|
|
break;
|
|
|
default:
|
|
|
return "异常"
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "合同会签流程",
|
|
|
width: 145,
|
|
|
prop: 'join_status',
|
|
|
formatter: (cell, data, value) => {
|
|
|
if(cell.is_simple){
|
|
|
return "无"
|
|
|
}
|
|
|
switch (value) {
|
|
|
case 1:
|
|
|
return "待申请"
|
|
|
break;
|
|
|
case 2:
|
|
|
return "流转中"
|
|
|
break;
|
|
|
case 3:
|
|
|
return "已办结"
|
|
|
break;
|
|
|
default:
|
|
|
return "异常"
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
]
|
|
|
},
|
|
|
{
|
|
|
label: "采购方式",
|
|
|
width: 120,
|
|
|
prop: "purchase_way.value",
|
|
|
formatter:(cell,data,value) => {
|
|
|
return value ? value : "无"
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "资金渠道",
|
|
|
width: 320,
|
|
|
align: "left",
|
|
|
customFn: (row) => {
|
|
|
return row.money_way_detail.map(item => item.value).join(',')
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "预算计划",
|
|
|
width: 320,
|
|
|
align: "left",
|
|
|
customFn: (row) => {
|
|
|
return row.plans.map(item => {
|
|
|
return (
|
|
|
<div>
|
|
|
[{item.year}] - {item.name}
|
|
|
</div>
|
|
|
)
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '已申请金额(元)',
|
|
|
prop: 'apply_money_total',
|
|
|
width: 140,
|
|
|
align: 'right',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '已付金额(元)',
|
|
|
prop: 'fund_log_total',
|
|
|
width: 140,
|
|
|
align: 'right',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '支付占比',
|
|
|
width: 140,
|
|
|
customFn: (row) => {
|
|
|
let per = ((((row.fund_log_total) / row.money) || 0) * 100)?.toFixed(2) || 0
|
|
|
return `${per}%`
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "合同预算价(元)",
|
|
|
width: 140,
|
|
|
prop: "plan_price",
|
|
|
align: 'right',
|
|
|
formatter: (v1, v2, value) => {
|
|
|
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '合同签订价(元)',
|
|
|
width: 140,
|
|
|
prop: 'money',
|
|
|
align: 'right',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "合同状态",
|
|
|
width: 120,
|
|
|
prop: "status",
|
|
|
formatter: (cell, data, value) => {
|
|
|
switch (value) {
|
|
|
case 1:
|
|
|
return "待签订"
|
|
|
break;
|
|
|
case 2:
|
|
|
return "已签订"
|
|
|
break;
|
|
|
default:
|
|
|
return "未知"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "结算状态",
|
|
|
width: 120,
|
|
|
prop: "is_end",
|
|
|
formatter: (cell, data, value) => {
|
|
|
return value === 0 ? "未结清" : "已结清";
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '付款计划',
|
|
|
prop: 'sign_plan_count',
|
|
|
width: 120,
|
|
|
formatter: (cell, data, value) => {
|
|
|
if (value == 0) return '暂无'
|
|
|
return value + '期'
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "供应商/服务商",
|
|
|
width: 220,
|
|
|
prop: 'supply',
|
|
|
align: "left"
|
|
|
},
|
|
|
{
|
|
|
label: "业务科室",
|
|
|
width: 140,
|
|
|
prop: 'department.name'
|
|
|
},
|
|
|
{
|
|
|
label: "经办人",
|
|
|
width: 140,
|
|
|
prop: 'admin.name'
|
|
|
},
|
|
|
{
|
|
|
label: "签订日期",
|
|
|
width: 160,
|
|
|
prop: 'date',
|
|
|
formatter: (cell, data, value) => {
|
|
|
if (value)
|
|
|
return parseTime(new Date(value), "{y}-{m}-{d}")
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "创建日期",
|
|
|
width: 160,
|
|
|
prop: 'created_at',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return parseTime(new Date(value), "{y}-{m}-{d}")
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "执行科室",
|
|
|
minWidth: 200,
|
|
|
prop: "contract_carry_department",
|
|
|
customFn: row => {
|
|
|
return row.contract_carry_department.map(i => i.carry_department.name).join(',')
|
|
|
}
|
|
|
}
|
|
|
],
|
|
|
//总计
|
|
|
tableTotal: {
|
|
|
fundLogTotal: 0,
|
|
|
moneyTotal: 0,
|
|
|
planPriceTotal: 0
|
|
|
},
|
|
|
|
|
|
planTypes: [],
|
|
|
planTableSearch: [{
|
|
|
label: "分类",
|
|
|
prop: 'type',
|
|
|
formatter: (cell, data, value) => {
|
|
|
let res = this.moneyWay.filter(item => {
|
|
|
return item.id === value
|
|
|
})
|
|
|
return res[0]?.value || '未知'
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "年份",
|
|
|
prop: 'year',
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
label: "名称",
|
|
|
prop: 'name',
|
|
|
align: 'left'
|
|
|
},
|
|
|
|
|
|
{
|
|
|
label: "计划金额",
|
|
|
prop: 'money',
|
|
|
align: 'right',
|
|
|
width: 120,
|
|
|
customFn: (row) => {
|
|
|
let m1 = row.money;
|
|
|
let m2 = row.update_money;
|
|
|
|
|
|
return m2 == 0 ? m1 : m2;
|
|
|
}
|
|
|
}
|
|
|
],
|
|
|
planTable: [{
|
|
|
width: 36,
|
|
|
sortable: false,
|
|
|
type: 'selection',
|
|
|
fixed: "left"
|
|
|
},
|
|
|
{
|
|
|
label: "分类",
|
|
|
prop: 'type',
|
|
|
formatter: (cell, data, value) => {
|
|
|
let res = this.moneyWay.filter(item => {
|
|
|
return item.id === value
|
|
|
})
|
|
|
return res[0]?.value || '未知'
|
|
|
},
|
|
|
width: 100,
|
|
|
fixed: "left"
|
|
|
},
|
|
|
|
|
|
{
|
|
|
label: "科室",
|
|
|
prop: 'plan_department.name',
|
|
|
width: 100,
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
label: "年份",
|
|
|
prop: 'year',
|
|
|
width: 80,
|
|
|
align: 'center'
|
|
|
},
|
|
|
{
|
|
|
label: "隶属",
|
|
|
prop: 'pid_info.name',
|
|
|
width: 180,
|
|
|
align: 'left'
|
|
|
},
|
|
|
{
|
|
|
label: "名称",
|
|
|
prop: 'name',
|
|
|
width: 320,
|
|
|
align: 'left'
|
|
|
},
|
|
|
{
|
|
|
label: "计划金额",
|
|
|
prop: 'money',
|
|
|
align: 'right',
|
|
|
width: 120,
|
|
|
customFn: (row) => {
|
|
|
let m1 = row.money;
|
|
|
let m2 = row.update_money;
|
|
|
|
|
|
return m2 == 0 ? m1 : m2;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "已用金额",
|
|
|
prop: 'use_money_total',
|
|
|
width: 120,
|
|
|
align: 'right'
|
|
|
},
|
|
|
],
|
|
|
|
|
|
|
|
|
//新增
|
|
|
isShowAdd: false,
|
|
|
currentStep: 1,
|
|
|
form: {
|
|
|
category: '',
|
|
|
affairType: '',
|
|
|
contractType: '',
|
|
|
purchaseForm: '',
|
|
|
purchaseSubForm: '',
|
|
|
purchaseMethod: '',
|
|
|
forms:'',
|
|
|
before_forms:'',
|
|
|
originBeforeForms:'',
|
|
|
originAfterForms:'',
|
|
|
other_data:[],
|
|
|
before_other_data:[],
|
|
|
skipBeforeTemplate:false,
|
|
|
skipAfterTemplate:false,
|
|
|
name: '',
|
|
|
type: '', // 项目类型
|
|
|
moneyWay: [],
|
|
|
plan: [],
|
|
|
plan_display: '', // 预算计划显示文本
|
|
|
price: 0,
|
|
|
supply: '',
|
|
|
// 流程控制字段
|
|
|
is_simple: 0, // 是否为简易流程
|
|
|
has_charge: 0, // 是否为河道处收费类项目
|
|
|
isBudget: 0, // 是否为预算内确定项目
|
|
|
is_substitute: 0, // 是否为代建项目
|
|
|
// 新增流程控制字段
|
|
|
request: 0, // 请示流程
|
|
|
purchaseApproval: 0, // 采购业务审批流程
|
|
|
tenderReview: 0, // 招标文件审查流程
|
|
|
contractSign: 0, // 合同会签流程
|
|
|
expenses: [
|
|
|
{
|
|
|
content: '',
|
|
|
amount: 0,
|
|
|
ratio: '',
|
|
|
payee: ''
|
|
|
}
|
|
|
],
|
|
|
showAfterPayment: false, // 是否显示事后支付表格
|
|
|
contract_carry_department: [] // 新增执行科室字段
|
|
|
},
|
|
|
categoryOptions: [],
|
|
|
purchaseMethodsMap: {},
|
|
|
affairTypeOptions: [],
|
|
|
contractTypeOptions: [],
|
|
|
purchaseFormOptions: [],
|
|
|
purchaseMethodOptions: [],
|
|
|
isShowPlan: false, //新增中预算计划
|
|
|
plans: [], //预算数据
|
|
|
planSearch: {
|
|
|
name: "",
|
|
|
plan_department_id: ""
|
|
|
},
|
|
|
planTotal: 0,
|
|
|
plansPageIndex: 1,
|
|
|
|
|
|
isShowEditor: false,
|
|
|
contractTypes: [
|
|
|
{ label: '设备采购', value: 'equipment' },
|
|
|
{ label: '工程合同', value: 'project' },
|
|
|
{ label: '服务合同', value: 'service' }
|
|
|
],
|
|
|
plan: [], // 添加这个来存储选中的预算计划
|
|
|
isEditMode: false, // 添加编辑模式标识
|
|
|
currentContractId: null, // 添加当前编辑的合同ID
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
toExport() {
|
|
|
this.select.is_export = 1;
|
|
|
this.getContracts(true);
|
|
|
},
|
|
|
clearSelectForSearch() {
|
|
|
this.select.plan_id = "";
|
|
|
this.select.plan_name = "请选择预算计划";
|
|
|
|
|
|
},
|
|
|
async getPlanTypes() {
|
|
|
const res = await getparameter({
|
|
|
number: 'money_way'
|
|
|
})
|
|
|
this.planTypes = res.detail
|
|
|
console.log(this.planTypes)
|
|
|
},
|
|
|
|
|
|
//预算计划金额输入
|
|
|
planInput(e, row) {
|
|
|
if (!/^[0-9]+.?[0-9]*$/.test(e) && e) {
|
|
|
Message({
|
|
|
type: 'warning',
|
|
|
message: '金额格式错误'
|
|
|
})
|
|
|
row.useMoney = 0
|
|
|
return
|
|
|
}
|
|
|
if (e <= (Number(row.money) - Number(row.use_money_total))) {
|
|
|
row.useMoney = e
|
|
|
this.plan.forEach(item => {
|
|
|
if (item.value.plan_id == row.id) {
|
|
|
item.value.use_money = e
|
|
|
}
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
Message({
|
|
|
type: 'warning',
|
|
|
message: '使用金额大于剩余预算'
|
|
|
})
|
|
|
row.useMoney = 0
|
|
|
},
|
|
|
//合计
|
|
|
summary(param) {
|
|
|
this.$nextTick(() => {
|
|
|
this.$refs['xyTable'].$children[0].doLayout()
|
|
|
})
|
|
|
const {
|
|
|
columns,
|
|
|
data
|
|
|
} = param
|
|
|
const sums = []
|
|
|
columns.map((column, index) => {
|
|
|
if (index === 0) {
|
|
|
sums[index] = '总计'
|
|
|
return
|
|
|
}
|
|
|
if (column.property === 'fund_log_total') {
|
|
|
sums[index] = this.tableTotal.fundLogTotal
|
|
|
return
|
|
|
}
|
|
|
if (column.property === 'plan_price') {
|
|
|
sums[index] = this.tableTotal.planPriceTotal
|
|
|
return
|
|
|
}
|
|
|
if (column.property === 'money') {
|
|
|
sums[index] = this.tableTotal.moneyTotal
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// const values = data.map(item => Number(item[column.property]));
|
|
|
// if (!values.every(value => isNaN(value)) && (column.property === 'money' || column.property === 'plan_price'|| column.property === 'fund_log_total')) {
|
|
|
//
|
|
|
// sums[index] = sums[index].toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
|
|
|
// } else {
|
|
|
// sums[index] = '';
|
|
|
// }
|
|
|
})
|
|
|
|
|
|
return sums
|
|
|
},
|
|
|
cellStyle({
|
|
|
row,
|
|
|
column,
|
|
|
rowIndex,
|
|
|
columnIndex
|
|
|
}) {
|
|
|
if (column.property === 'req_status') {
|
|
|
if ((row.is_plan || row.is_substitute || row.is_simple) && !row.has_charge) {
|
|
|
return {
|
|
|
'color': 'rgb(140,140,140)'
|
|
|
}
|
|
|
}
|
|
|
switch (row.req_status) {
|
|
|
case 1:
|
|
|
return {
|
|
|
'color': 'rgb(96,109,241)'
|
|
|
}
|
|
|
break;
|
|
|
case 2:
|
|
|
return {
|
|
|
'color': 'rgb(219,122,122)'
|
|
|
}
|
|
|
break;
|
|
|
case 3:
|
|
|
return {
|
|
|
'color': 'rgb(147,201,134)'
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
return {
|
|
|
'color': 'rgb(220,185,126)'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (column.property === 'purchase_status') {
|
|
|
if (row.is_substitute || row.is_simple) {
|
|
|
return {
|
|
|
'color': 'rgb(140,140,140)'
|
|
|
}
|
|
|
}
|
|
|
switch (row.purchase_status) {
|
|
|
case 1:
|
|
|
return {
|
|
|
'color': 'rgb(96,109,241)'
|
|
|
}
|
|
|
break;
|
|
|
case 2:
|
|
|
return {
|
|
|
'color': 'rgb(219,122,122)'
|
|
|
}
|
|
|
break;
|
|
|
case 3:
|
|
|
return {
|
|
|
'color': 'rgb(147,201,134)'
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
return {
|
|
|
'color': 'rgb(220,185,126)'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (column.property === 'invite_status') {
|
|
|
if (row.purchase_way?.remark === 'false' || row.is_substitute || row.is_simple) {
|
|
|
return {
|
|
|
'color': 'rgb(140,140,140)'
|
|
|
}
|
|
|
}
|
|
|
switch (row.invite_status) {
|
|
|
case 1:
|
|
|
return {
|
|
|
'color': 'rgb(96,109,241)'
|
|
|
}
|
|
|
break;
|
|
|
case 2:
|
|
|
return {
|
|
|
'color': 'rgb(219,122,122)'
|
|
|
}
|
|
|
break;
|
|
|
case 3:
|
|
|
return {
|
|
|
'color': 'rgb(147,201,134)'
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
return {
|
|
|
'color': 'rgb(220,185,126)'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (column.property === 'join_status') {
|
|
|
if(row.is_simple){
|
|
|
return {
|
|
|
'color': 'rgb(140,140,140)'
|
|
|
}
|
|
|
}
|
|
|
switch (row.join_status) {
|
|
|
case 1:
|
|
|
return {
|
|
|
'color': 'rgb(96,109,241)'
|
|
|
}
|
|
|
break;
|
|
|
case 2:
|
|
|
return {
|
|
|
'color': 'rgb(219,122,122)'
|
|
|
}
|
|
|
break;
|
|
|
case 3:
|
|
|
return {
|
|
|
'color': 'rgb(147,201,134)'
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
return {
|
|
|
'color': 'rgb(220,185,126)'
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
//y验证合同的名称是否存在重复
|
|
|
checkName(name) {
|
|
|
// 暂时不调用 API,直接返回
|
|
|
console.log('检查名称:', name)
|
|
|
},
|
|
|
confirmPlanForSearch() {
|
|
|
this.isShowPlanForSearch = false;
|
|
|
this.getContracts();
|
|
|
},
|
|
|
|
|
|
//点击付款计划查看
|
|
|
showPaymentPlan(row, column, cell) {
|
|
|
if (column.property === 'sign_plan_count') {
|
|
|
this.$refs['contractPaymentRegistration'].getSignPlan(row.id)
|
|
|
row.status === 2 ? this.$refs['contractPaymentRegistration'].isSign = true : this.$refs[
|
|
|
'contractPaymentRegistration'].isSign = false
|
|
|
this.$refs['contractPaymentRegistration'].isShow = true
|
|
|
}
|
|
|
if (column.property === 'fund_log_total') {
|
|
|
this.$router.push(`/contract/paymentRegistrationList?contractId=${row.id}`)
|
|
|
}
|
|
|
},
|
|
|
//招标文件审查
|
|
|
async bidding(row) {
|
|
|
let baseInfo = {
|
|
|
"项目名称": row?.name,
|
|
|
"项目预算(元)": row?.plan_price
|
|
|
}
|
|
|
let res = await getOatoken()
|
|
|
let url =
|
|
|
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/27?oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
|
|
|
let bidding = window.open(url, 'bidding',
|
|
|
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
|
|
|
)
|
|
|
},
|
|
|
|
|
|
//采购流程
|
|
|
async buyProcess(row) {
|
|
|
let baseInfo = {
|
|
|
"项目名称": row?.name,
|
|
|
"采购形式": row?.purchase_type?.value,
|
|
|
"采购方式": row?.purchase_way?.value,
|
|
|
"项目类型": this.type.find(item => {
|
|
|
return item.value === row.type
|
|
|
})?.label,
|
|
|
"资金渠道": row?.money_way?.value,
|
|
|
"项目预算(元)": row?.plan_price
|
|
|
}
|
|
|
let res = await getOatoken()
|
|
|
let url =
|
|
|
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/2?oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
|
|
|
let buyProcess = window.open(url, 'buyProcess',
|
|
|
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
|
|
|
)
|
|
|
},
|
|
|
//会签流程
|
|
|
async signProcess(row) {
|
|
|
let baseInfo = {
|
|
|
"合同名称": row?.name,
|
|
|
"执行部门": row?.carry_department,
|
|
|
"合同金额(元)": row?.money,
|
|
|
//"承包商\\供应商":row.supply
|
|
|
}
|
|
|
let res = await getOatoken()
|
|
|
let url =
|
|
|
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/3?oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
|
|
|
let signProcess = window.open(url, 'signProcess',
|
|
|
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
|
|
|
)
|
|
|
},
|
|
|
//请示流程
|
|
|
async askProcess(row) {
|
|
|
let res = await getOatoken()
|
|
|
let url =
|
|
|
`${process.env.VUE_APP_OUT_URL}/admin/flow/create/17?oatoken=${res.oatoken}&out_contract_id=${row.id}`
|
|
|
let askProcess = window.open(url, 'askProcess',
|
|
|
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
|
|
|
)
|
|
|
},
|
|
|
|
|
|
//防抖
|
|
|
debounce(fn, delay = 500) {
|
|
|
let timer = null
|
|
|
return function _debounce() {
|
|
|
if (timer) clearTimeout(timer)
|
|
|
timer = setTimeout(() => {
|
|
|
fn()
|
|
|
}, delay)
|
|
|
}
|
|
|
},
|
|
|
|
|
|
//翻页
|
|
|
pageChange(e) {
|
|
|
this.select.pageIndex = e
|
|
|
this.getContracts()
|
|
|
},
|
|
|
planPageChange(e) {
|
|
|
this.plansPageIndex = e
|
|
|
this.getBudgets()
|
|
|
},
|
|
|
//日期选择
|
|
|
datePick(e) {
|
|
|
this.select.start_created_at = e[0]
|
|
|
this.select.end_created_at = e[1]
|
|
|
},
|
|
|
|
|
|
//获取预算计划
|
|
|
async getBudgets() {
|
|
|
let res = await getBudget({
|
|
|
name: this.planSearch.name,
|
|
|
page_size: 10,
|
|
|
page: this.plansPageIndex,
|
|
|
plan_department_id: this.planSearch.plan_department_id,
|
|
|
top_pid: 1
|
|
|
})
|
|
|
this.plans = res.list.data
|
|
|
|
|
|
this.planTotal = res.list.total;
|
|
|
|
|
|
this.toggleSelection(this.plan.map(item => {
|
|
|
return item.value.plan_id
|
|
|
}), 1)
|
|
|
},
|
|
|
//获取资金渠道
|
|
|
async getMoneyWay() {
|
|
|
this.moneyWay = (await getparameter({
|
|
|
number: 'money_way'
|
|
|
})).detail
|
|
|
|
|
|
this.form.moneyWay = this.moneyWay
|
|
|
},
|
|
|
//获取购买方式
|
|
|
async getPurchaseWay() {
|
|
|
this.purchaseWay = (await getparameter({
|
|
|
number: 'purchase_way'
|
|
|
})).detail
|
|
|
}, //计划搜索
|
|
|
searchBudgets() {
|
|
|
this.plansPageIndex = 1;
|
|
|
this.getBudgets();
|
|
|
},
|
|
|
//获取科室
|
|
|
async getDepartment() {
|
|
|
this.departments = await listdeptNoAuth()
|
|
|
},
|
|
|
//获取购买形式列表
|
|
|
async getPurchaseType() {
|
|
|
this.purchaseType = (await getparameter({
|
|
|
number: 'purchase_type'
|
|
|
})).detail
|
|
|
},
|
|
|
pageSizeChange(e) {
|
|
|
|
|
|
this.select.pageSize = e;
|
|
|
this.select.pageIndex = 1;
|
|
|
this.getContracts();
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
downloadExel() {
|
|
|
|
|
|
download(
|
|
|
'/api/admin/contract/index',
|
|
|
'get', {
|
|
|
is_auth: 1,
|
|
|
is_export: 1,
|
|
|
...this.select
|
|
|
},
|
|
|
'合同列表.xlsx')
|
|
|
},
|
|
|
//获取合同列表
|
|
|
async getContracts(is_export,noloading=false) {
|
|
|
|
|
|
const res = await getContract({
|
|
|
page_size: this.select.pageSize,
|
|
|
page: this.select.pageIndex,
|
|
|
is_auth: 1,
|
|
|
...this.select
|
|
|
},noloading)
|
|
|
|
|
|
let tokens = getToken();
|
|
|
// if (is_export) {
|
|
|
// this.select.is_export == 1
|
|
|
// var url = "/api/admin/contract/index?is_auth=1&token=" + tokens
|
|
|
// Object.keys(this.select).map((key, item) => {
|
|
|
// url += "&" + key + "=" + this.select[key];
|
|
|
// });
|
|
|
// url = location.host + url;
|
|
|
// console.log(url)
|
|
|
// window.open("http://" + url, '_blank')
|
|
|
// this.select.is_export = 0
|
|
|
// return;
|
|
|
// }
|
|
|
|
|
|
this.list = res.list.data
|
|
|
this.total = res.list.total
|
|
|
this.tableTotal.fundLogTotal = res.fund_log_total
|
|
|
this.tableTotal.moneyTotal = Number(res.money_total).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,')
|
|
|
this.tableTotal.planPriceTotal = Number(res.plan_price_total).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g,
|
|
|
'$1,')
|
|
|
},
|
|
|
|
|
|
|
|
|
//新建合同
|
|
|
//显示
|
|
|
async showPlan() {
|
|
|
this.isShowPlan = true
|
|
|
await this.getBudgets()
|
|
|
},
|
|
|
showPlanForSearch(source) {
|
|
|
this.planSource = source
|
|
|
this.isShowPlan = true
|
|
|
this.getBudgets()
|
|
|
// 初始化 plan 数组
|
|
|
if (source === 'modal') {
|
|
|
this.plan = this.form.plan || []
|
|
|
} else {
|
|
|
this.plan = []
|
|
|
}
|
|
|
},
|
|
|
selectPlanForSearch(sel, row) {
|
|
|
if (this.planSource === 'modal') {
|
|
|
if (sel) {
|
|
|
let select = sel.map(item => {
|
|
|
let plan = this.plans.find(p => p.id === item.id)
|
|
|
return {
|
|
|
label: plan.name,
|
|
|
value: {
|
|
|
plan_id: plan.id,
|
|
|
use_money: plan.useMoney || 0,
|
|
|
new_money: plan.money
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
this.plan = [...this.form.plan, ...select]
|
|
|
// 更新显示文本,显示所有已选择的计划
|
|
|
this.form.plan_display = this.plan.map(item => item.label).join(', ')
|
|
|
} else {
|
|
|
this.plan = this.form.plan
|
|
|
// 更新显示文本,显示所有已选择的计划
|
|
|
this.form.plan_display = this.plan.map(item => item.label).join(', ')
|
|
|
}
|
|
|
} else {
|
|
|
this.select.plan_name = row.name
|
|
|
this.select.plan_id = row.id
|
|
|
}
|
|
|
},
|
|
|
planSelectForSearch() {
|
|
|
if (this.plan.length === 0) {
|
|
|
Message({
|
|
|
type: 'warning',
|
|
|
message: '选择计划不能为空'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
for (let item of this.plan) {
|
|
|
if (!item.value.use_money) {
|
|
|
Message({
|
|
|
type: 'warning',
|
|
|
message: '金额不能为空'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
// 设置表单数据
|
|
|
this.form.plan = this.plan
|
|
|
// 设置显示文本
|
|
|
this.form.plan_display = this.plan.map(item => item.label).join(', ')
|
|
|
// 关闭对话框
|
|
|
this.isShowPlan = false
|
|
|
},
|
|
|
//选择计划
|
|
|
selectPlan(sel, row) {
|
|
|
console.log(sel)
|
|
|
if (sel) {
|
|
|
let select = sel.map(item => {
|
|
|
return {
|
|
|
label: item.name,
|
|
|
value: {
|
|
|
plan_id: item.id,
|
|
|
use_money: item.useMoney,
|
|
|
new_money: item.money
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
this.plan = [...this.form.plan, ...select]
|
|
|
} else {
|
|
|
this.plan = this.form.plan
|
|
|
}
|
|
|
},
|
|
|
//确认计划选择
|
|
|
planSelect() {
|
|
|
if (this.plan.length === 0) {
|
|
|
Message({
|
|
|
type: 'warning',
|
|
|
message: '选择计划不能为空'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
for (let item of this.plan) {
|
|
|
if (!item.value.use_money) {
|
|
|
Message({
|
|
|
type: 'warning',
|
|
|
message: '金额不能为空'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
// 设置表单数据
|
|
|
this.form.plan = this.plan
|
|
|
// 设置显示文本,使用换行符分隔
|
|
|
this.form.plan_display = this.plan.map(item => item.label).join('\n')
|
|
|
// 关闭对话框
|
|
|
this.isShowPlan = false
|
|
|
},
|
|
|
|
|
|
delPlan(val) {
|
|
|
this.form.plan = this.form.plan.filter(item => item.value.plan_id !== val.value.plan_id)
|
|
|
},
|
|
|
//默认选择计划
|
|
|
toggleSelection(plans) {
|
|
|
if (plans) {
|
|
|
this.plans.filter(plan => {
|
|
|
if (plans.includes(plan.id)) {
|
|
|
let selectedPlan = this.plan.find(item => item.value.plan_id === plan.id)
|
|
|
if (selectedPlan) {
|
|
|
plan.useMoney = selectedPlan.value.use_money
|
|
|
}
|
|
|
return true
|
|
|
}
|
|
|
}).map(row => {
|
|
|
this.$refs.planTable.toggleRowSelection(row)
|
|
|
})
|
|
|
} else {
|
|
|
this.$refs.planTable.clearSelection()
|
|
|
}
|
|
|
},
|
|
|
//提交新建
|
|
|
async submit() {
|
|
|
try {
|
|
|
// 保存事前支付表格的数据
|
|
|
if (!this.form.showAfterPayment && this.form.before_contract_template) {
|
|
|
// 获取所有输入控件
|
|
|
const inputs = this.$refs.beforePaymentForm.querySelectorAll('input, select, textarea');
|
|
|
|
|
|
// 遍历所有输入控件,更新值到 HTML
|
|
|
inputs.forEach(input => {
|
|
|
const fieldName = input.getAttribute('data-field');
|
|
|
if (fieldName) {
|
|
|
const field = this.form.before_contract_template.contract_template_fields.find(f => f.field === fieldName);
|
|
|
if (field) {
|
|
|
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
|
// 对于复选框和单选框,需要找到选中的值
|
|
|
const checkedInput = this.$refs.beforePaymentForm.querySelector(`[data-field="${fieldName}"]:checked`);
|
|
|
field.value = checkedInput ? checkedInput.value : '';
|
|
|
// 更新 HTML 中的 checked 状态
|
|
|
if (checkedInput) {
|
|
|
checkedInput.setAttribute('checked', 'checked');
|
|
|
}
|
|
|
} else {
|
|
|
field.value = input.value;
|
|
|
// 更新 HTML 中的 value
|
|
|
input.setAttribute('value', input.value);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 获取更新后的 HTML
|
|
|
const beforeFormHtml = this.$refs.beforePaymentForm.innerHTML;
|
|
|
|
|
|
// 更新模板和保存数据
|
|
|
this.form.before_forms = beforeFormHtml;
|
|
|
}
|
|
|
|
|
|
// 保存事后支付表格的数据
|
|
|
if (this.form.showAfterPayment && this.form.contract_template) {
|
|
|
// 获取所有输入控件
|
|
|
const inputs = this.$refs.afterPaymentForm.querySelectorAll('input, select, textarea');
|
|
|
|
|
|
// 遍历所有输入控件,更新值到 HTML
|
|
|
inputs.forEach(input => {
|
|
|
const fieldName = input.getAttribute('data-field');
|
|
|
if (fieldName) {
|
|
|
const field = this.form.contract_template.contract_template_fields.find(f => f.field === fieldName);
|
|
|
if (field) {
|
|
|
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
|
// 对于复选框和单选框,需要找到选中的值
|
|
|
const checkedInput = this.$refs.afterPaymentForm.querySelector(`[data-field="${fieldName}"]:checked`);
|
|
|
field.value = checkedInput ? checkedInput.value : '';
|
|
|
// 更新 HTML 中的 checked 状态
|
|
|
if (checkedInput) {
|
|
|
checkedInput.setAttribute('checked', 'checked');
|
|
|
}
|
|
|
} else {
|
|
|
field.value = input.value;
|
|
|
// 更新 HTML 中的 value
|
|
|
input.setAttribute('value', input.value);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 获取更新后的 HTML
|
|
|
const afterFormHtml = this.$refs.afterPaymentForm.innerHTML;
|
|
|
|
|
|
// 更新模板和保存数据
|
|
|
this.form.forms = afterFormHtml;
|
|
|
}
|
|
|
|
|
|
// 构建提交数据
|
|
|
const submitData = {
|
|
|
...this.form,
|
|
|
is_plan: this.form.isBudget ? 1 : 0,
|
|
|
money_way_id: this.form.moneyWay.join(','),
|
|
|
contract_plan_links: this.form.plan.map(item => ({
|
|
|
plan_id: item.value.plan_id,
|
|
|
use_money: item.value.use_money
|
|
|
})),
|
|
|
contract_carry_department: this.form.contract_carry_department.map(id => ({
|
|
|
carry_department_id: id
|
|
|
}))
|
|
|
};
|
|
|
|
|
|
submitData.contract_category = this.form.category
|
|
|
submitData.work_type = this.form.affairType
|
|
|
submitData.contract_type = this.form.contractType
|
|
|
submitData.purchase_type_id = this.form.purchaseForm
|
|
|
submitData.purchase_way_id = this.form.purchaseMethod
|
|
|
|
|
|
// 处理事前支付模板
|
|
|
if (this.form.skipBeforeTemplate && !this.isEditMode) {
|
|
|
// 如果用户选择跳过,提交空的模板和字段列表
|
|
|
submitData.before_forms = '';
|
|
|
submitData.before_other_data = [];
|
|
|
} else if (this.form.before_contract_template) {
|
|
|
// 如果用户填写了模板,提交当前填写的模板和字段列表
|
|
|
submitData.before_forms = this.form.before_forms;
|
|
|
submitData.before_other_data = this.form.before_contract_template.contract_template_fields;
|
|
|
}
|
|
|
|
|
|
// 处理事后支付模板
|
|
|
if (this.form.skipAfterTemplate && !this.isEditMode) {
|
|
|
// 如果用户选择跳过,提交空的模板和字段列表
|
|
|
submitData.forms = '';
|
|
|
submitData.other_data = [];
|
|
|
} else if (this.form.contract_template) {
|
|
|
// 如果用户填写了模板,提交当前填写的模板和字段列表
|
|
|
submitData.forms = this.form.forms;
|
|
|
submitData.other_data = this.form.contract_template.contract_template_fields;
|
|
|
}
|
|
|
|
|
|
// 根据是新增还是编辑调用不同的API
|
|
|
if (this.isEditMode) {
|
|
|
submitData.id = this.currentContractId;
|
|
|
await editorContract(submitData);
|
|
|
} else {
|
|
|
await addContrant(submitData);
|
|
|
}
|
|
|
|
|
|
// 提交成功后关闭弹窗并刷新列表
|
|
|
this.isShowAdd = false;
|
|
|
this.getContracts();
|
|
|
Message({
|
|
|
type: 'success',
|
|
|
message: this.isEditMode ? '编辑成功' : '新增成功'
|
|
|
});
|
|
|
} catch (error) {
|
|
|
console.error('提交失败:', error);
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '提交失败'
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
|
|
|
//删除合同
|
|
|
deleteContract(id) {
|
|
|
delContract({
|
|
|
id
|
|
|
}).then(res => {
|
|
|
Message({
|
|
|
type: 'success',
|
|
|
message: '操作成功'
|
|
|
})
|
|
|
this.getContracts()
|
|
|
})
|
|
|
},
|
|
|
handleCategoryChange() {
|
|
|
this.form.affairType = ''
|
|
|
this.form.contractType = ''
|
|
|
this.form.purchaseForm = ''
|
|
|
this.form.purchaseMethod = ''
|
|
|
this.updateTypeOptions()
|
|
|
},
|
|
|
|
|
|
handleAffairTypeChange() {
|
|
|
this.form.contractType = ''
|
|
|
this.form.purchaseForm = ''
|
|
|
this.form.purchaseMethod = ''
|
|
|
this.updateTypeOptions()
|
|
|
},
|
|
|
|
|
|
handleContractTypeChange() {
|
|
|
this.form.purchaseForm = ''
|
|
|
this.form.purchaseMethod = ''
|
|
|
this.updateTypeOptions()
|
|
|
},
|
|
|
|
|
|
handlePurchaseFormChange() {
|
|
|
this.form.purchaseMethod = ''
|
|
|
this.updateTypeOptions()
|
|
|
},
|
|
|
|
|
|
handlePurchaseMethodChange() {
|
|
|
this.updateTypeOptions()
|
|
|
},
|
|
|
|
|
|
updateTypeOptions() {
|
|
|
// 重置所有选项
|
|
|
this.affairTypeOptions = []
|
|
|
this.contractTypeOptions = []
|
|
|
this.purchaseFormOptions = []
|
|
|
this.purchaseMethodOptions = []
|
|
|
this.purchaseSubFormOptions = []
|
|
|
|
|
|
// 获取当前选中的分类
|
|
|
const selectedCategory = this.categoryOptions.find(item => item.id === this.form.category)
|
|
|
if (!selectedCategory) return
|
|
|
|
|
|
// 更新事项类型选项
|
|
|
this.affairTypeOptions = selectedCategory.children || []
|
|
|
|
|
|
// 获取当前选中的事项类型
|
|
|
const selectedAffairType = this.affairTypeOptions.find(item => item.id === this.form.affairType)
|
|
|
if (!selectedAffairType) return
|
|
|
|
|
|
// 更新合同类型选项
|
|
|
this.contractTypeOptions = selectedAffairType.children || []
|
|
|
|
|
|
// 获取当前选中的合同类型
|
|
|
const selectedContractType = this.contractTypeOptions.find(item => item.id === this.form.contractType)
|
|
|
if (!selectedContractType) return
|
|
|
|
|
|
// 更新采购形式选项
|
|
|
this.purchaseFormOptions = selectedContractType.children || []
|
|
|
|
|
|
// 获取当前选中的采购形式
|
|
|
const selectedPurchaseForm = this.purchaseFormOptions.find(item => item.id === this.form.purchaseForm)
|
|
|
if (!selectedPurchaseForm) return
|
|
|
|
|
|
// 更新采购子形式选项
|
|
|
this.purchaseSubFormOptions = selectedPurchaseForm.children || []
|
|
|
|
|
|
// 获取当前选中的采购子形式
|
|
|
const selectedPurchaseSubForm = this.purchaseSubFormOptions.find(item => item.id === this.form.purchaseSubForm)
|
|
|
|
|
|
// 如果有采购子形式,使用其children作为采购方式
|
|
|
if (selectedPurchaseSubForm && selectedPurchaseSubForm.children) {
|
|
|
this.purchaseMethodOptions = selectedPurchaseSubForm.children
|
|
|
}
|
|
|
// 如果没有采购子形式,使用采购形式的children作为采购方式
|
|
|
else if (selectedPurchaseForm.children) {
|
|
|
this.purchaseMethodOptions = selectedPurchaseForm.children
|
|
|
}
|
|
|
},
|
|
|
|
|
|
nextStep() {
|
|
|
if (this.currentStep === 1) {
|
|
|
// 验证是否至少选择了一个下拉框
|
|
|
if (!this.form.category && !this.form.affairType && !this.form.contractType &&
|
|
|
!this.form.purchaseForm && !this.form.purchaseMethod) {
|
|
|
this.$Message.warning('请至少选择一个选项');
|
|
|
return;
|
|
|
}
|
|
|
// 获取模版配置
|
|
|
this.getTemplateConfig();
|
|
|
} else if (this.currentStep === 2) {
|
|
|
// 验证基本信息表单
|
|
|
const visibleFields = [];
|
|
|
|
|
|
// 检查项目名称是否显示
|
|
|
if (this.showFields.projectName) {
|
|
|
visibleFields.push('name');
|
|
|
}
|
|
|
|
|
|
// 检查项目类型是否显示
|
|
|
if (this.showFields.projectType) {
|
|
|
visibleFields.push('type');
|
|
|
}
|
|
|
|
|
|
// 检查预算价格是否显示
|
|
|
if (this.showFields.budgetPrice) {
|
|
|
visibleFields.push('price');
|
|
|
}
|
|
|
|
|
|
// 检查资金渠道是否显示
|
|
|
if (this.showFields.fundChannel) {
|
|
|
visibleFields.push('moneyWay');
|
|
|
}
|
|
|
|
|
|
// 检查预算计划是否显示
|
|
|
if (this.showFields.budgetPlan) {
|
|
|
visibleFields.push('plan');
|
|
|
}
|
|
|
|
|
|
// 检查显示的表单项是否都已填写
|
|
|
const missingFields = visibleFields.filter(field => {
|
|
|
if (field === 'moneyWay') {
|
|
|
return !this.form.moneyWay || this.form.moneyWay.length === 0;
|
|
|
} else if (field === 'plan') {
|
|
|
return !this.form.plan || this.form.plan.length === 0;
|
|
|
} else {
|
|
|
return !this.form[field];
|
|
|
}
|
|
|
});
|
|
|
|
|
|
if (missingFields.length > 0) {
|
|
|
this.$Message.warning('请填写所有必填项');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 在进入第三步之前,确保所有必要的数据都被正确设置
|
|
|
if (!this.form.type) {
|
|
|
this.form.type = '';
|
|
|
}
|
|
|
if (!this.form.contract_carry_department) {
|
|
|
this.form.contract_carry_department = [];
|
|
|
}
|
|
|
if (!this.form.moneyWay) {
|
|
|
this.form.moneyWay = [];
|
|
|
}
|
|
|
|
|
|
// 如果存在事前支付表格,则跳转到事前支付表格
|
|
|
if (this.form.before_contract_template) {
|
|
|
this.form.showAfterPayment = false;
|
|
|
}
|
|
|
|
|
|
this.currentStep++;
|
|
|
} else if (this.currentStep === 3) {
|
|
|
this.currentStep++;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
prevStep() {
|
|
|
if (this.currentStep === 3) {
|
|
|
// 如果在事后支付表格,先保存内容
|
|
|
if (this.form.showAfterPayment &&
|
|
|
this.form.contract_template &&
|
|
|
this.form.contract_template.contract_template_fields &&
|
|
|
this.$refs.afterPaymentForm) {
|
|
|
// 获取所有输入控件
|
|
|
const inputs = this.$refs.afterPaymentForm.querySelectorAll('input, select, textarea');
|
|
|
|
|
|
// 遍历所有输入控件,更新值到 HTML
|
|
|
inputs.forEach(input => {
|
|
|
const fieldName = input.getAttribute('data-field');
|
|
|
if (fieldName) {
|
|
|
const field = this.form.contract_template.contract_template_fields.find(f => f.field === fieldName);
|
|
|
if (field) {
|
|
|
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
|
// 对于复选框和单选框,需要找到选中的值
|
|
|
const checkedInput = this.$refs.afterPaymentForm.querySelector(`[data-field="${fieldName}"]:checked`);
|
|
|
field.value = checkedInput ? checkedInput.value : '';
|
|
|
// 更新 HTML 中的 checked 状态
|
|
|
if (checkedInput) {
|
|
|
checkedInput.setAttribute('checked', 'checked');
|
|
|
}
|
|
|
} else {
|
|
|
field.value = input.value;
|
|
|
// 更新 HTML 中的 value
|
|
|
input.setAttribute('value', input.value);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 获取更新后的 HTML
|
|
|
const afterFormHtml = this.$refs.afterPaymentForm.innerHTML;
|
|
|
|
|
|
// 更新模保存数据
|
|
|
this.form.forms = afterFormHtml;
|
|
|
}
|
|
|
if (this.form.showAfterPayment && this.form.before_contract_template) {
|
|
|
// 如果在事后支付表格且有事前支付表格,则返回事前支付表格
|
|
|
this.form.showAfterPayment = false;
|
|
|
} else {
|
|
|
// 其他情况正常返回上一步
|
|
|
this.currentStep--;
|
|
|
}
|
|
|
} else {
|
|
|
this.currentStep--;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 获取模版配置参数
|
|
|
async getTemplateConfig() {
|
|
|
try {
|
|
|
const params = {
|
|
|
category: this.form.category || 0,
|
|
|
work_type: this.form.affairType || 0,
|
|
|
contract_type: this.form.contractType || 0,
|
|
|
purchase_form: this.form.purchaseForm || 0
|
|
|
}
|
|
|
|
|
|
console.log('请求模版配置参数:', params)
|
|
|
const res = await getContractCategoryTemplateConfigParams(params)
|
|
|
console.log('模版配置返回数据:', res)
|
|
|
|
|
|
if (res.errcode !== undefined) {
|
|
|
this.$message.error(res.errmsg || '获取模版配置失败')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 在编辑模式下,保存当前的forms和before_forms值
|
|
|
let currentForms = null;
|
|
|
let currentBeforeForms = null;
|
|
|
if (this.isEditMode) {
|
|
|
currentForms = this.form.forms;
|
|
|
currentBeforeForms = this.form.before_forms;
|
|
|
}
|
|
|
|
|
|
// 根据返回的配置参数设置表单
|
|
|
this.setFormConfig(res)
|
|
|
|
|
|
// 在编辑模式下,恢复forms和before_forms的值
|
|
|
if (this.isEditMode) {
|
|
|
this.form.forms = currentForms;
|
|
|
this.form.before_forms = currentBeforeForms;
|
|
|
}
|
|
|
|
|
|
if (this.form.forms && this.form.forms.trim() !== '') {
|
|
|
this.form.skipAfterTemplate = true;
|
|
|
}
|
|
|
|
|
|
if (this.form.before_forms && this.form.before_forms.trim() !== '') {
|
|
|
this.form.skipBeforeTemplate = true;
|
|
|
}
|
|
|
|
|
|
// 进入下一步
|
|
|
this.currentStep++
|
|
|
} catch (error) {
|
|
|
console.error('获取模版配置失败:', error)
|
|
|
this.$message.error('获取模版配置失败')
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 设置表单配置
|
|
|
setFormConfig(config) {
|
|
|
console.log('模版配置参数:', config)
|
|
|
|
|
|
// 只更新显示/隐藏状态,不影响数据来源
|
|
|
Object.assign(this.showFields, {
|
|
|
projectName: config.project_name === 1, // 项目名称
|
|
|
projectType: config.project_type === 1, // 项目类型
|
|
|
budgetPrice: config.budget_price === 1, // 预算价格
|
|
|
fundChannel: config.fund_channel === 1, // 资金渠道
|
|
|
budgetPlan: config.budget_plan === 1 // 预算计划
|
|
|
})
|
|
|
|
|
|
// 保存支付表格模板
|
|
|
if (config.before_contract_template) {
|
|
|
// 处理事前支付表格模板
|
|
|
let beforeTemplate = config.before_contract_template.template;
|
|
|
if (beforeTemplate && config.before_contract_template.contract_template_fields) {
|
|
|
console.log('处理事前支付表格模板:', config.before_contract_template.contract_template_fields)
|
|
|
|
|
|
// 遍历字段列表,为每个字段找到对应的控件
|
|
|
config.before_contract_template.contract_template_fields.forEach(field => {
|
|
|
// 在模板中查找 data-field 属性值与字段名相同的控件
|
|
|
const regex = new RegExp(`<[^>]*data-field="${field.field}"[^>]*>`, 'g');
|
|
|
const matches = beforeTemplate.match(regex);
|
|
|
|
|
|
if (matches) {
|
|
|
matches.forEach(match => {
|
|
|
// 获取控件类型
|
|
|
let controlType = 'text';
|
|
|
if (match.includes('type="number"')) controlType = 'number';
|
|
|
else if (match.includes('type="date"')) controlType = 'date';
|
|
|
else if (match.includes('type="checkbox"')) controlType = 'checkbox';
|
|
|
else if (match.includes('type="radio"')) controlType = 'radio';
|
|
|
else if (match.includes('<select')) controlType = 'select';
|
|
|
else if (match.includes('<textarea')) controlType = 'textarea';
|
|
|
|
|
|
// 根据控件类型设置 id 和 value
|
|
|
let newControl = match;
|
|
|
|
|
|
// 添加 id
|
|
|
if (!newControl.includes('id=')) {
|
|
|
newControl = newControl.replace('data-field', `id="before_${field.field}" data-field`);
|
|
|
}
|
|
|
|
|
|
// 设置 value
|
|
|
if (controlType === 'checkbox' || controlType === 'radio') {
|
|
|
// 对于复选框和单选框,需要处理 options
|
|
|
const options = field.options ? JSON.parse(field.options) : [];
|
|
|
options.forEach(opt => {
|
|
|
const optionRegex = new RegExp(`<input[^>]*value="${opt.value}"[^>]*>`, 'g');
|
|
|
const optionMatches = newControl.match(optionRegex);
|
|
|
if (optionMatches) {
|
|
|
optionMatches.forEach(optionMatch => {
|
|
|
const checked = field.value === opt.value ? 'checked' : '';
|
|
|
newControl = newControl.replace(optionMatch, optionMatch.replace('>', ` ${checked}>`));
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
// 对于其他控件,直接设置 value
|
|
|
if (!newControl.includes('value=')) {
|
|
|
newControl = newControl.replace('>', ` value="${field.value || ''}">`);
|
|
|
} else {
|
|
|
newControl = newControl.replace(/value="[^"]*"/, `value="${field.value || ''}"`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 替换原控件
|
|
|
beforeTemplate = beforeTemplate.replace(match, newControl);
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
this.form.before_contract_template = config.before_contract_template;
|
|
|
this.form.before_contract_template.template = beforeTemplate;
|
|
|
}
|
|
|
|
|
|
if (config.contract_template) {
|
|
|
// 处理事后支付表格模板
|
|
|
let afterTemplate = config.contract_template.template;
|
|
|
if (afterTemplate && config.contract_template.contract_template_fields) {
|
|
|
console.log('处理事后支付表格模板:', config.contract_template.contract_template_fields)
|
|
|
|
|
|
// 遍历字段列表,为每个字段找到对应的控件
|
|
|
config.contract_template.contract_template_fields.forEach(field => {
|
|
|
// 在模板中查找 data-field 属性值与字段名相同的控件
|
|
|
const regex = new RegExp(`<[^>]*data-field="${field.field}"[^>]*>`, 'g');
|
|
|
const matches = afterTemplate.match(regex);
|
|
|
|
|
|
if (matches) {
|
|
|
matches.forEach(match => {
|
|
|
// 获取控件类型
|
|
|
let controlType = 'text';
|
|
|
if (match.includes('type="number"')) controlType = 'number';
|
|
|
else if (match.includes('type="date"')) controlType = 'date';
|
|
|
else if (match.includes('type="checkbox"')) controlType = 'checkbox';
|
|
|
else if (match.includes('type="radio"')) controlType = 'radio';
|
|
|
else if (match.includes('<select')) controlType = 'select';
|
|
|
else if (match.includes('<textarea')) controlType = 'textarea';
|
|
|
|
|
|
// 根据控件类型设置 id 和 value
|
|
|
let newControl = match;
|
|
|
|
|
|
// 添加 id
|
|
|
if (!newControl.includes('id=')) {
|
|
|
newControl = newControl.replace('data-field', `id="after_${field.field}" data-field`);
|
|
|
}
|
|
|
|
|
|
// 设置 value
|
|
|
if (controlType === 'checkbox' || controlType === 'radio') {
|
|
|
// 对于复选框和单选框,需要处理 options
|
|
|
const options = field.options ? JSON.parse(field.options) : [];
|
|
|
options.forEach(opt => {
|
|
|
const optionRegex = new RegExp(`<input[^>]*value="${opt.value}"[^>]*>`, 'g');
|
|
|
const optionMatches = newControl.match(optionRegex);
|
|
|
if (optionMatches) {
|
|
|
optionMatches.forEach(optionMatch => {
|
|
|
const checked = field.value === opt.value ? 'checked' : '';
|
|
|
newControl = newControl.replace(optionMatch, optionMatch.replace('>', ` ${checked}>`));
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
// 对于其他控件,直接设置 value
|
|
|
if (!newControl.includes('value=')) {
|
|
|
newControl = newControl.replace('>', ` value="${field.value || ''}">`);
|
|
|
} else {
|
|
|
newControl = newControl.replace(/value="[^"]*"/, `value="${field.value || ''}"`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 替换原控件
|
|
|
afterTemplate = afterTemplate.replace(match, newControl);
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
this.form.contract_template = config.contract_template;
|
|
|
this.form.contract_template.template = afterTemplate;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
handleAddContract() {
|
|
|
this.isShowAdd = true;
|
|
|
// Call API to get category options
|
|
|
this.getCategoryOptions();
|
|
|
// Reset form
|
|
|
this.resetForm();
|
|
|
},
|
|
|
|
|
|
handleAddContractOk() {
|
|
|
// 这个方法可以移除,因为功能已经被 nextStep 和 submit 方法替代
|
|
|
},
|
|
|
|
|
|
handleAddContractCancel() {
|
|
|
// 这个方法可以移除,因为功能已经被 cancel 方法替代
|
|
|
},
|
|
|
|
|
|
cancel() {
|
|
|
this.isShowAdd = false
|
|
|
this.resetForm()
|
|
|
},
|
|
|
|
|
|
resetForm() {
|
|
|
this.currentStep = 1;
|
|
|
this.isEditMode = false;
|
|
|
this.currentContractId = null;
|
|
|
this.form = {
|
|
|
category: '',
|
|
|
affairType: '',
|
|
|
contractType: '',
|
|
|
purchaseForm: '',
|
|
|
purchaseSubForm: '',
|
|
|
purchaseMethod: '',
|
|
|
name: '',
|
|
|
type: '',
|
|
|
moneyWay: [],
|
|
|
plan: [],
|
|
|
plan_display: '',
|
|
|
price: 0,
|
|
|
supply: '',
|
|
|
is_simple: 0,
|
|
|
has_charge: 0,
|
|
|
isBudget: 0,
|
|
|
is_substitute: 0,
|
|
|
request: 0,
|
|
|
purchaseApproval: 0,
|
|
|
tenderReview: 0,
|
|
|
contractSign: 0,
|
|
|
expenses: [
|
|
|
{
|
|
|
content: '',
|
|
|
amount: 0,
|
|
|
ratio: '',
|
|
|
payee: ''
|
|
|
}
|
|
|
],
|
|
|
showAfterPayment: false,
|
|
|
contract_carry_department: []
|
|
|
};
|
|
|
|
|
|
this.affairTypeOptions = [];
|
|
|
this.contractTypeOptions = [];
|
|
|
this.purchaseFormOptions = [];
|
|
|
this.purchaseSubFormOptions = [];
|
|
|
this.purchaseMethodOptions = [];
|
|
|
},
|
|
|
|
|
|
// 获取分类配置
|
|
|
async getCategoryOptions() {
|
|
|
try {
|
|
|
// 获取分类配置
|
|
|
const res = await getContractCategoryTemplateBaseConfig()
|
|
|
if (res.errcode !== undefined) {
|
|
|
this.$message.error(res.errmsg || '获取分类配置失败')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 保存采购方式映射
|
|
|
this.purchaseMethodsMap = res.purchase_methods || {}
|
|
|
|
|
|
// 设置分类选项 - 从第二级开始(合同类、报销类、其他支出类)
|
|
|
this.categoryOptions = res.map?.[0]?.children || []
|
|
|
|
|
|
// 递归处理每一层的 children,确保所有层级都被正确解析
|
|
|
const processChildren = (items) => {
|
|
|
if (!items) return
|
|
|
items.forEach(item => {
|
|
|
if (item.children) {
|
|
|
// 确保每个子项都有正确的 id 和 name
|
|
|
item.children = item.children.map(child => ({
|
|
|
id: child.id,
|
|
|
name: child.name || child.value, // 添加对 value 字段的支持
|
|
|
children: child.children || []
|
|
|
}))
|
|
|
processChildren(item.children)
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
// 处理所有层级的 children
|
|
|
processChildren(this.categoryOptions)
|
|
|
|
|
|
// 初始化其他选项
|
|
|
this.updateTypeOptions()
|
|
|
} catch (error) {
|
|
|
console.error('获取分类配置失败:', error)
|
|
|
this.$message.error('获取分类配置失败')
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 初始化采购方式映射
|
|
|
initPurchaseMethodsMap() {
|
|
|
this.purchaseMethodsMap = {}
|
|
|
// 递归遍历分类选项,构建采购方式映射
|
|
|
const traverse = (items) => {
|
|
|
items.forEach(item => {
|
|
|
if (item.children) {
|
|
|
traverse(item.children)
|
|
|
} else {
|
|
|
// 如果是叶子节点,添加到映射中
|
|
|
this.purchaseMethodsMap[item.id] = item.name
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
traverse(this.categoryOptions)
|
|
|
},
|
|
|
|
|
|
// 获取分类名称的方法
|
|
|
getCategoryName(id) {
|
|
|
const category = this.categoryOptions.find(item => item.id === id)
|
|
|
return category ? category.name : ''
|
|
|
},
|
|
|
|
|
|
getAffairTypeName(id) {
|
|
|
const category = this.categoryOptions.find(item => item.id === this.form.category)
|
|
|
if (category && category.children) {
|
|
|
const affairType = category.children.find(item => item.id === id)
|
|
|
return affairType ? affairType.name : ''
|
|
|
}
|
|
|
return ''
|
|
|
},
|
|
|
|
|
|
getContractTypeName(id) {
|
|
|
const category = this.categoryOptions.find(item => item.id === this.form.category)
|
|
|
if (category && category.children) {
|
|
|
const affairType = category.children.find(item => item.id === this.form.affairType)
|
|
|
if (affairType && affairType.children) {
|
|
|
const contractType = affairType.children.find(item => item.id === id)
|
|
|
return contractType ? contractType.name : ''
|
|
|
}
|
|
|
}
|
|
|
return ''
|
|
|
},
|
|
|
|
|
|
getPurchaseFormName(id) {
|
|
|
const category = this.categoryOptions.find(item => item.id === this.form.category)
|
|
|
if (category && category.children) {
|
|
|
const affairType = category.children.find(item => item.id === this.form.affairType)
|
|
|
if (affairType && affairType.children) {
|
|
|
const contractType = affairType.children.find(item => item.id === this.form.contractType)
|
|
|
if (contractType && contractType.children) {
|
|
|
const purchaseForm = contractType.children.find(item => item.id === id)
|
|
|
return purchaseForm ? purchaseForm.name : ''
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return ''
|
|
|
},
|
|
|
|
|
|
getPurchaseMethodName(id) {
|
|
|
// 从嵌套结构中查找采购方式名称
|
|
|
const category = this.categoryOptions.find(item => item.id === this.form.category)
|
|
|
if (category && category.children) {
|
|
|
const affairType = category.children.find(item => item.id === this.form.affairType)
|
|
|
if (affairType && affairType.children) {
|
|
|
const contractType = affairType.children.find(item => item.id === this.form.contractType)
|
|
|
if (contractType && contractType.children) {
|
|
|
const purchaseForm = contractType.children.find(item => item.id === this.form.purchaseForm)
|
|
|
if (purchaseForm && purchaseForm.children) {
|
|
|
// 如果有选择子表单,从子表单中查找
|
|
|
if (this.form.purchaseSubForm) {
|
|
|
const purchaseSubForm = purchaseForm.children.find(item => item.id === this.form.purchaseSubForm)
|
|
|
if (purchaseSubForm && purchaseSubForm.children) {
|
|
|
const purchaseMethod = purchaseSubForm.children.find(item => item.id === id)
|
|
|
if (purchaseMethod) {
|
|
|
return purchaseMethod.name
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 直接从采购形式中查找
|
|
|
const purchaseMethod = purchaseForm.children.find(item => item.id === id)
|
|
|
if (purchaseMethod) {
|
|
|
return purchaseMethod.name
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 备用:从映射中查找
|
|
|
return this.purchaseMethodsMap[id] || ''
|
|
|
},
|
|
|
|
|
|
// 更新预算计划显示文本
|
|
|
updatePlanDisplay() {
|
|
|
if (this.form.plan && this.form.plan.length > 0) {
|
|
|
this.form.plan_display = `已选择 ${this.form.plan.length} 个预算计划`
|
|
|
} else {
|
|
|
this.form.plan_display = ''
|
|
|
}
|
|
|
},
|
|
|
// 新增方法:移除预算计划
|
|
|
removePlan(item) {
|
|
|
// 从 plan 数组中移除
|
|
|
this.plan = this.plan.filter(p => p.value.plan_id !== item.value.plan_id)
|
|
|
// 从 form.plan 中移除
|
|
|
this.form.plan = this.form.plan.filter(p => p.value.plan_id !== item.value.plan_id)
|
|
|
// 更新显示文本
|
|
|
this.form.plan_display = this.plan.map(p => p.label).join(', ')
|
|
|
},
|
|
|
// 切换到事后支付表格
|
|
|
nextPaymentStep() {
|
|
|
// 保存事前支付表格的数据
|
|
|
if (this.form.before_contract_template && !this.form.showAfterPayment) {
|
|
|
// 获取所有输入控件
|
|
|
const inputs = this.$refs.beforePaymentForm.querySelectorAll('input, select, textarea');
|
|
|
|
|
|
// 遍历所有输入控件,更新值到 HTML
|
|
|
inputs.forEach(input => {
|
|
|
const fieldName = input.getAttribute('data-field');
|
|
|
if (fieldName) {
|
|
|
const field = this.form.before_contract_template.contract_template_fields.find(f => f.field === fieldName);
|
|
|
if (field) {
|
|
|
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
|
// 对于复选框和单选框,需要找到选中的值
|
|
|
const checkedInput = this.$refs.beforePaymentForm.querySelector(`[data-field="${fieldName}"]:checked`);
|
|
|
field.value = checkedInput ? checkedInput.value : '';
|
|
|
// 更新 HTML 中的 checked 状态
|
|
|
if (checkedInput) {
|
|
|
checkedInput.setAttribute('checked', 'checked');
|
|
|
}
|
|
|
} else {
|
|
|
field.value = input.value;
|
|
|
// 更新 HTML 中的 value
|
|
|
input.setAttribute('value', input.value);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
// 获取更新后的 HTML
|
|
|
const beforeFormHtml = this.$refs.beforePaymentForm.innerHTML;
|
|
|
|
|
|
// 更新模板和保存数据
|
|
|
this.form.before_forms = beforeFormHtml;
|
|
|
}
|
|
|
this.form.showAfterPayment = true;
|
|
|
},
|
|
|
// 获取资金渠道名称的方法
|
|
|
getMoneyWayName(id) {
|
|
|
const way = this.moneyWay.find(item => item.id === id)
|
|
|
return way ? way.value : ''
|
|
|
},
|
|
|
|
|
|
// 移除资金渠道
|
|
|
removeMoneyWay(id) {
|
|
|
this.form.moneyWay = this.form.moneyWay.filter(item => item !== id)
|
|
|
},
|
|
|
|
|
|
// 获取科室名称的方法
|
|
|
getDepartmentName(id) {
|
|
|
const dept = this.departments.find(item => item.id === id)
|
|
|
return dept ? dept.name : ''
|
|
|
},
|
|
|
|
|
|
// 移除科室
|
|
|
removeDepartment(id) {
|
|
|
this.form.contract_carry_department = this.form.contract_carry_department.filter(item => item !== id)
|
|
|
},
|
|
|
|
|
|
// 跳过事前支付表格
|
|
|
skipPrePayment() {
|
|
|
this.form.showAfterPayment = true
|
|
|
if (this.isEditMode) {
|
|
|
this.form.before_forms = this.originBeforeForms;
|
|
|
}else{
|
|
|
this.form.before_forms = '';
|
|
|
this.form.before_other_data = [];
|
|
|
this.form.skipBeforeTemplate = true;
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 跳过事后支付表格
|
|
|
skipPostPayment() {
|
|
|
if (this.isEditMode) {
|
|
|
this.form.forms = this.originAfterForms;
|
|
|
}else{
|
|
|
this.form.forms = '';
|
|
|
this.form.other_data = [];
|
|
|
this.form.skipAfterTemplate = true;
|
|
|
}
|
|
|
|
|
|
this.submit()
|
|
|
},
|
|
|
|
|
|
// 更新事前表格字段值
|
|
|
updateBeforeFieldValue(field, value) {
|
|
|
if (this.form.before_contract_template && this.form.before_contract_template.contract_template_fields) {
|
|
|
const fieldObj = this.form.before_contract_template.contract_template_fields.find(f => f.field === field);
|
|
|
if (fieldObj) {
|
|
|
fieldObj.value = value;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 更新事后表格字段值
|
|
|
updateAfterFieldValue(field, value) {
|
|
|
if (this.form.contract_template && this.form.contract_template.contract_template_fields) {
|
|
|
const fieldObj = this.form.contract_template.contract_template_fields.find(f => f.field === field);
|
|
|
if (fieldObj) {
|
|
|
fieldObj.value = value;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 编辑按钮点击事件
|
|
|
async handleEdit(row) {
|
|
|
this.isEditMode = true;
|
|
|
this.currentContractId = row.id;
|
|
|
this.isShowAdd = true;
|
|
|
this.currentStep = 1;
|
|
|
|
|
|
try {
|
|
|
// 1. 先获取分类选项
|
|
|
await this.getCategoryOptions();
|
|
|
|
|
|
// 2. 获取合同详情
|
|
|
const res = await getContract({ id: row.id });
|
|
|
if (res && res.list && res.list.data && res.list.data.length > 0) {
|
|
|
const detail = res.list.data[0];
|
|
|
|
|
|
// 3. 通过正常的流程来初始化下拉框
|
|
|
// 设置分类
|
|
|
if (detail.contract_category) {
|
|
|
this.form.category = detail.contract_category;
|
|
|
this.handleCategoryChange(detail.contract_category);
|
|
|
}
|
|
|
|
|
|
// 设置事项类型
|
|
|
if (detail.work_type) {
|
|
|
this.form.affairType = detail.work_type;
|
|
|
this.handleAffairTypeChange(detail.work_type);
|
|
|
}
|
|
|
|
|
|
// 设置合同类型
|
|
|
if (detail.contract_type) {
|
|
|
this.form.contractType = detail.contract_type;
|
|
|
this.handleContractTypeChange(detail.contract_type);
|
|
|
}
|
|
|
|
|
|
// 设置采购形式
|
|
|
if (detail.purchase_type_id) {
|
|
|
this.form.purchaseForm = detail.purchase_type_id;
|
|
|
this.handlePurchaseFormChange(detail.purchase_type_id);
|
|
|
}
|
|
|
|
|
|
// 设置采购方式
|
|
|
if (detail.purchase_way_id) {
|
|
|
this.form.purchaseMethod = detail.purchase_way_id;
|
|
|
}
|
|
|
|
|
|
console.log("detail", detail);
|
|
|
|
|
|
// 保存其他表单数据
|
|
|
this.form = {
|
|
|
...this.form,
|
|
|
forms: detail.forms,
|
|
|
before_forms: detail.before_forms,
|
|
|
originBeforeForms: detail.before_forms,
|
|
|
originAfterForms: detail.forms,
|
|
|
other_data: detail.other_data,
|
|
|
before_other_data: detail.before_other_data,
|
|
|
type: detail.type,
|
|
|
isBudget: detail.is_plan,
|
|
|
is_simple: detail.is_simple,
|
|
|
has_charge: detail.has_charge,
|
|
|
is_substitute: detail.is_substitute,
|
|
|
supply: detail.supply,
|
|
|
price: detail.plan_price,
|
|
|
name: detail.name,
|
|
|
moneyWay: detail.money_way_id ? detail.money_way_id.split(',').map(Number) : [],
|
|
|
plan: detail.plans.map(item => {
|
|
|
return {
|
|
|
label: item.name,
|
|
|
value: {
|
|
|
plan_id: item.id,
|
|
|
use_money: detail.plan_link ? detail.plan_link.filter(item1 => {
|
|
|
return item1.plan_id === item.id
|
|
|
})[0]?.use_money : 0,
|
|
|
new_money: item.money
|
|
|
}
|
|
|
}
|
|
|
}),
|
|
|
contract_carry_department: detail.contract_carry_department.map(i => i.carry_department_id),
|
|
|
before_contract_template: detail.before_contract_template,
|
|
|
contract_template: detail.contract_template
|
|
|
};
|
|
|
|
|
|
// 设置预算计划显示文本
|
|
|
if (this.form.plan && this.form.plan.length > 0) {
|
|
|
this.form.plan_display = this.form.plan.map(item => item.label).join(', ');
|
|
|
}
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('初始化编辑数据失败:', error);
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '初始化编辑数据失败'
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 新增按钮点击事件
|
|
|
handleAdd() {
|
|
|
this.isEditMode = false;
|
|
|
this.currentContractId = null;
|
|
|
this.isShowAdd = true;
|
|
|
this.currentStep = 1;
|
|
|
this.form = {
|
|
|
...this.form,
|
|
|
category: '',
|
|
|
affairType: '',
|
|
|
contractType: '',
|
|
|
purchaseForm: '',
|
|
|
purchaseMethod: '',
|
|
|
type: '',
|
|
|
isBudget: false,
|
|
|
is_simple: 0,
|
|
|
has_charge: 0,
|
|
|
is_substitute: 0,
|
|
|
supply: '',
|
|
|
price: '',
|
|
|
name: '',
|
|
|
moneyWay: [],
|
|
|
plan: [],
|
|
|
contract_carry_department: [],
|
|
|
before_contract_template: null,
|
|
|
contract_template: null
|
|
|
};
|
|
|
this.getCategoryOptions();
|
|
|
},
|
|
|
|
|
|
// 新增获取合同详情方法
|
|
|
async getContractDetail(id) {
|
|
|
try {
|
|
|
const res = await getContract({ id });
|
|
|
if (res && res.list && res.list.data && res.list.data.length > 0) {
|
|
|
const detail = res.list.data[0];
|
|
|
console.log("detail", detail);
|
|
|
// 填充表单数据
|
|
|
this.form = {
|
|
|
...this.form,
|
|
|
// 第一步的五个分类选择
|
|
|
category: detail.category,
|
|
|
affairType: detail.work_type,
|
|
|
contractType: detail.contract_type,
|
|
|
purchaseForm: detail.purchase_type_id, // 采购形式
|
|
|
purchaseMethod: detail.purchase_way_id, // 采购方式
|
|
|
// 其他基本信息
|
|
|
type: detail.type,
|
|
|
isBudget: detail.is_plan,
|
|
|
is_simple: detail.is_simple,
|
|
|
has_charge: detail.has_charge,
|
|
|
is_substitute: detail.is_substitute,
|
|
|
supply: detail.supply,
|
|
|
price: detail.plan_price,
|
|
|
name: detail.name,
|
|
|
moneyWay: detail.money_way_id ? detail.money_way_id.split(',').map(Number) : [],
|
|
|
plan: detail.plans.map(item => {
|
|
|
return {
|
|
|
label: item.name,
|
|
|
value: {
|
|
|
plan_id: item.id,
|
|
|
use_money: detail.plan_link ? detail.plan_link.filter(item1 => {
|
|
|
return item1.plan_id === item.id
|
|
|
})[0]?.use_money : 0,
|
|
|
new_money: item.money
|
|
|
}
|
|
|
}
|
|
|
}),
|
|
|
contract_carry_department: detail.contract_carry_department.map(i => i.carry_department_id),
|
|
|
before_contract_template: detail.before_contract_template,
|
|
|
contract_template: detail.contract_template,
|
|
|
before_forms: detail.before_forms,
|
|
|
before_other_data: detail.before_other_data,
|
|
|
forms: detail.forms,
|
|
|
other_data: detail.other_data,
|
|
|
};
|
|
|
|
|
|
// 设置预算计划显示文本
|
|
|
if (this.form.plan && this.form.plan.length > 0) {
|
|
|
this.form.plan_display = this.form.plan.map(item => item.label).join(', ');
|
|
|
}
|
|
|
|
|
|
// 确保停留在第一步
|
|
|
this.currentStep = 1;
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('获取合同详情失败:', error);
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '获取合同详情失败'
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 验证表单
|
|
|
validateForm() {
|
|
|
// 验证第一步的必填字段
|
|
|
if (this.currentStep === 1) {
|
|
|
if (!this.form.category) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择合同分类'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.affairType) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择事项类型'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.contractType) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择合同类型'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.purchaseForm) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择采购形式'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.purchaseMethod) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择采购方式'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 验证第二步的必填字段
|
|
|
if (this.currentStep === 2) {
|
|
|
if (!this.form.type) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择合同性质'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.name) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请输入合同名称'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.price) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请输入合同金额'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.moneyWay || this.form.moneyWay.length === 0) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择资金来源'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.plan || this.form.plan.length === 0) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择预算计划'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
if (!this.form.contract_carry_department || this.form.contract_carry_department.length === 0) {
|
|
|
Message({
|
|
|
type: 'error',
|
|
|
message: '请选择合同承办部门'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
},
|
|
|
},
|
|
|
mounted() {
|
|
|
this.window.width = screen.availWidth * 0.95
|
|
|
this.window.height = screen.availHeight * 0.95
|
|
|
this.window.top = (window.screen.height - 30 - this.window.height) / 2
|
|
|
this.window.left = (window.screen.width - 10 - this.window.width) / 2
|
|
|
let that = this;
|
|
|
getInfo().then(response => {
|
|
|
console.log(response)
|
|
|
this.user = response;
|
|
|
|
|
|
if (that.userList.indexOf(response.username) != -1) {
|
|
|
that.hasEdit = true;
|
|
|
}
|
|
|
}).catch(error => {
|
|
|
})
|
|
|
this.getPurchaseType()
|
|
|
this.getContracts()
|
|
|
this.getDepartment()
|
|
|
this.getPurchaseWay()
|
|
|
this.getMoneyWay()
|
|
|
|
|
|
//页面激活后刷新合同列表
|
|
|
window.onfocus = () => {
|
|
|
this.getContracts(false, true)
|
|
|
}
|
|
|
},
|
|
|
destroyed() {
|
|
|
window.onfocus = null
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.selects {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
& > div {
|
|
|
margin-bottom: 6px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.selectTop {
|
|
|
margin-top: 10px;
|
|
|
}
|
|
|
|
|
|
.contract-add-plan {
|
|
|
min-height: 30px;
|
|
|
border: 1px solid #dcdee2;
|
|
|
border-radius: 4px;
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
align-items: center;
|
|
|
align-content: center;
|
|
|
|
|
|
padding: 0 8px;
|
|
|
|
|
|
&-no-plan {
|
|
|
height: 30px;
|
|
|
line-height: 30px;
|
|
|
color: #CDD0D5;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
.slot-btns {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
align-content: center;
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
&-item {
|
|
|
margin: 0 6px 4px 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.xy-table-item-label {
|
|
|
width: 200px;
|
|
|
}
|
|
|
|
|
|
.xy-table-item-price {
|
|
|
position: relative;
|
|
|
|
|
|
&::after {
|
|
|
position: absolute;
|
|
|
right: 0;
|
|
|
top: 0;
|
|
|
content: '(元)'
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.contract-add-modal {
|
|
|
:deep(.ivu-modal-content) {
|
|
|
border-radius: 8px;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
:deep(.ivu-modal-header) {
|
|
|
background: #f8f8f9;
|
|
|
padding: 16px 24px;
|
|
|
border-bottom: 1px solid #e8eaec;
|
|
|
}
|
|
|
|
|
|
:deep(.ivu-modal-body) {
|
|
|
padding: 24px;
|
|
|
}
|
|
|
|
|
|
.steps-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
margin-bottom: 32px;
|
|
|
padding: 0 20px;
|
|
|
|
|
|
.step {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
position: relative;
|
|
|
flex: 1;
|
|
|
|
|
|
&:not(:last-child)::after {
|
|
|
content: '';
|
|
|
position: absolute;
|
|
|
top: 16px;
|
|
|
left: 50%;
|
|
|
width: 100%;
|
|
|
height: 2px;
|
|
|
background: #e8eaec;
|
|
|
z-index: 1;
|
|
|
}
|
|
|
|
|
|
.step-number {
|
|
|
width: 32px;
|
|
|
height: 32px;
|
|
|
border-radius: 50%;
|
|
|
background: #e8eaec;
|
|
|
color: #fff;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
margin-bottom: 8px;
|
|
|
position: relative;
|
|
|
z-index: 2;
|
|
|
}
|
|
|
|
|
|
.step-text {
|
|
|
color: #808695;
|
|
|
font-size: 14px;
|
|
|
}
|
|
|
|
|
|
&.active {
|
|
|
.step-number {
|
|
|
background: #2d8cf0;
|
|
|
}
|
|
|
.step-text {
|
|
|
color: #2d8cf0;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.step-content {
|
|
|
padding: 0 20px;
|
|
|
}
|
|
|
|
|
|
.form-group {
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
.form-label {
|
|
|
display: block;
|
|
|
margin-bottom: 8px;
|
|
|
color: #515a6e;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
.form-input {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
.form-button {
|
|
|
width: 100%;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.expense-table {
|
|
|
width: 100%;
|
|
|
border-collapse: collapse;
|
|
|
margin-top: 8px;
|
|
|
|
|
|
th, td {
|
|
|
padding: 8px;
|
|
|
border: 1px solid #e8eaec;
|
|
|
text-align: center;
|
|
|
}
|
|
|
|
|
|
th {
|
|
|
background: #f8f8f9;
|
|
|
color: #515a6e;
|
|
|
font-weight: 500;
|
|
|
}
|
|
|
|
|
|
td {
|
|
|
.ivu-input {
|
|
|
border: none;
|
|
|
&:focus {
|
|
|
box-shadow: none;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.step-actions {
|
|
|
display: flex;
|
|
|
justify-content: flex-end;
|
|
|
gap: 12px;
|
|
|
margin-top: 32px;
|
|
|
padding: 0 20px;
|
|
|
|
|
|
.action-button {
|
|
|
min-width: 100px;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.template-info {
|
|
|
background-color: #f5f7fa;
|
|
|
border-radius: 4px;
|
|
|
padding: 16px;
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
.info-title {
|
|
|
font-size: 16px;
|
|
|
font-weight: 600;
|
|
|
color: #1f2937;
|
|
|
margin-bottom: 16px;
|
|
|
padding-bottom: 12px;
|
|
|
border-bottom: 1px solid #e5e7eb;
|
|
|
}
|
|
|
|
|
|
.info-content {
|
|
|
display: grid;
|
|
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
|
gap: 16px;
|
|
|
|
|
|
.info-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
.label {
|
|
|
color: #4b5563;
|
|
|
font-weight: 500;
|
|
|
margin-right: 8px;
|
|
|
min-width: 84px;
|
|
|
}
|
|
|
|
|
|
.value {
|
|
|
color: #1f2937;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.form-section {
|
|
|
background-color: #ffffff;
|
|
|
border-radius: 4px;
|
|
|
padding: 20px;
|
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
.section-title {
|
|
|
font-size: 16px;
|
|
|
font-weight: 600;
|
|
|
color: #1f2937;
|
|
|
margin-bottom: 20px;
|
|
|
padding-bottom: 12px;
|
|
|
border-bottom: 1px solid #e5e7eb;
|
|
|
}
|
|
|
|
|
|
:deep(.el-form-item) {
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
&:last-child {
|
|
|
margin-bottom: 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
:deep(.el-form-item__label) {
|
|
|
font-weight: 500;
|
|
|
color: #4b5563;
|
|
|
}
|
|
|
|
|
|
:deep(.el-input),
|
|
|
:deep(.el-input-number),
|
|
|
:deep(.el-select) {
|
|
|
width: 100%;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.helper-text {
|
|
|
margin-top: 8px;
|
|
|
color: #666;
|
|
|
font-size: 13px;
|
|
|
line-height: 1.4;
|
|
|
}
|
|
|
|
|
|
.form-section {
|
|
|
& + .form-section {
|
|
|
margin-top: 24px;
|
|
|
}
|
|
|
|
|
|
:deep(.el-radio-group) {
|
|
|
.el-radio {
|
|
|
margin-right: 30px;
|
|
|
|
|
|
&:last-child {
|
|
|
margin-right: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.process-control-grid {
|
|
|
display: grid;
|
|
|
grid-template-columns: repeat(2, 1fr);
|
|
|
gap: 20px;
|
|
|
|
|
|
.control-item {
|
|
|
background: #f9fafb;
|
|
|
border-radius: 4px;
|
|
|
padding: 16px;
|
|
|
|
|
|
.control-label {
|
|
|
color: #4b5563;
|
|
|
font-weight: 500;
|
|
|
margin-bottom: 12px;
|
|
|
}
|
|
|
|
|
|
.control-content {
|
|
|
.helper-text {
|
|
|
margin-top: 8px;
|
|
|
color: #666;
|
|
|
font-size: 13px;
|
|
|
line-height: 1.4;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
:deep(.el-radio-group) {
|
|
|
display: flex;
|
|
|
gap: 24px;
|
|
|
|
|
|
.el-radio {
|
|
|
margin-right: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.plan-selector {
|
|
|
width: 100%;
|
|
|
|
|
|
.plan-input {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
.plan-tags {
|
|
|
margin-top: 8px;
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
gap: 8px;
|
|
|
|
|
|
.el-tag {
|
|
|
margin-right: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.search-box {
|
|
|
margin-bottom: 16px;
|
|
|
}
|
|
|
|
|
|
.plan-list {
|
|
|
height: 400px;
|
|
|
overflow-y: auto;
|
|
|
}
|
|
|
|
|
|
.modal-footer {
|
|
|
display: flex;
|
|
|
justify-content: flex-end;
|
|
|
gap: 12px;
|
|
|
padding: 10px 0;
|
|
|
|
|
|
.action-button {
|
|
|
min-width: 100px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.no-payment-form {
|
|
|
padding: 20px;
|
|
|
text-align: center;
|
|
|
color: #909399;
|
|
|
font-size: 14px;
|
|
|
background-color: #f5f7fa;
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
|
|
|
.money-way-selector {
|
|
|
width: 100%;
|
|
|
|
|
|
.money-way-tags {
|
|
|
margin-top: 8px;
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
gap: 8px;
|
|
|
|
|
|
.el-tag {
|
|
|
margin-right: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.department-selector {
|
|
|
width: 100%;
|
|
|
|
|
|
.department-tags {
|
|
|
margin-top: 8px;
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
gap: 8px;
|
|
|
|
|
|
.el-tag {
|
|
|
margin-right: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.skip-option {
|
|
|
margin-top: 16px;
|
|
|
text-align: center;
|
|
|
|
|
|
.el-button {
|
|
|
color: #909399;
|
|
|
|
|
|
&:hover {
|
|
|
color: #409EFF;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</style>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
// ... existing styles ...
|
|
|
|
|
|
// 加宽 require 提示框
|
|
|
::v-deep .el-form-item__error {
|
|
|
width: 200px;
|
|
|
white-space: normal;
|
|
|
word-break: break-all;
|
|
|
text-align: right;
|
|
|
right: 0;
|
|
|
left: auto;
|
|
|
}
|
|
|
</style>
|