You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1888 lines
58 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<el-steps :active="step" align-center>
<el-step title="选择预算计划"> </el-step>
<el-step title="新增预算支出事项"> </el-step>
<el-step title="新增成功"> </el-step>
</el-steps>
<div style="padding: 20px">
<div v-show="step === 1">
<div style="display: flex;justify-content: space-between;align-items: center;">
<DatePicker
:value="planSelect.year"
placeholder="选择所属年份"
placement="bottom-start"
style="width: 180px;margin-right: 10px;"
type="year"
@on-change="(e) => {
planSelect.year = e
getBudgets()
}"
></DatePicker>
<el-select
placeholder="科室选择"
clearable
size="small"
v-model="planSelect.plan_department_id"
style="width: 180px;margin-right: 10px;"
@change="getBudgets"
>
<el-option
v-for="item in departments"
:label="item.name"
:value="item.id"
:key="item.id"
>
</el-option>
</el-select>
<el-cascader
placeholder="资金类型选择"
:options="planTypes"
:props="{
checkStrictly: false,
label: 'name',
value: 'id',
}"
:value="planSelect.type"
clearable
size="small"
style="width: 220px;margin-right: 10px;"
@change="(e) => {
planSelect.type = e[e.length - 1] || '';
getBudgets();
}"
/>
<Input
v-model="planSelect.name"
search
enter-button="搜 索"
clearable
placeholder="搜索预算计划.."
@on-search="getBudgets"
/>
</div>
<xy-table
:list="plans"
:show-index="false"
:table-item="planTable"
:height="boxheight"
style="margin-top: 10px"
ref="editorPlanTable"
row-key="id"
border
default-expand-all
@select="planPick"
:tree-props="{ children: 'notChildren', hasChildren: 'hasChildren' }"
>
<template v-slot:btns>
<el-table-column
label="使用金额(元)"
header-align="center"
width="144"
>
<template slot-scope="scope" v-if="scope.row.pid === 0">
<InputNumber
style="width: 120px"
:min="0"
:precision="2"
:active-change="false"
v-model="scope.row._inputMoney"
:formatter="
(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
"
:parser="(value) => value.replace(/\$\s?|(,*)/g, '')"
></InputNumber>
</template>
</el-table-column>
</template>
</xy-table>
<div style="display: flex; justify-content: flex-end">
<Page
:total="planTotal"
show-elevator
@on-change="
(e) => {
planSelect.page = e;
getBudgets();
}
"
/>
</div>
<div style="text-align: center">
<el-button type="primary" style="margin-top: 12px" @click="() => nextStep()"
>下一步</el-button
>
</div>
</div>
<el-card v-show="step === 2">
<el-popover placement="right-start" width="660" trigger="click">
<xy-table
:list="planSelections"
size="mini"
:table-item="[
...planTable.slice(1),
{
width: 120,
align: 'right',
label: '使用金额(元)',
prop: '_inputMoney',
formatter: (v1, v2, value) =>
`${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
},
]"
:height="400"
style="width: 100%"
row-key="id"
border
:tree-props="{
children: 'notChildren',
hasChildren: 'hasChildren',
}"
>
<template #btns></template>
</xy-table>
<el-button
icon="el-icon-s-order"
size="small"
type="primary"
slot="reference"
>查看已选预算计划</el-button
>
</el-popover>
<br>
<Tag v-show="form.use_framework_buy" checkable color="warning">已使用框架协议</Tag>
<Divider></Divider>
<el-form
ref="form"
class="el-form-body"
label-position="left"
size="small"
:model="form"
:rules="rules"
label-width="180px"
>
<el-form-item prop="name" label="项目名称">
<el-input
placeholder="请填写项目名称"
v-model="form.name"
style="width: 100%"
/>
</el-form-item>
<template v-if="!isLedger">
<el-form-item prop="is_contract" label="是否需要签订合同">
<el-radio-group v-model="form.is_contract">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="is_simple" label="是否为直接支付">
<el-radio-group v-model="form.is_simple">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
<span style="flex: 1; text-align: right">(无需采购流程,如水电邮寄费等)</span>
</el-form-item>
<template v-if="form.is_simple">
<el-form-item prop="supply" label="承包商/供货商/协议方">
<el-input
v-model="form.supply"
placeholder="请填写承包商/供货商/协议方"
style="width: 100%"
/>
</el-form-item>
<el-form-item prop="money" label="合同金额(元)">
<InputNumber
style="width: 100%"
:min="0"
:step="10000"
:precision="2"
:active-change="false"
v-model="form.money"
:formatter="
(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
"
:parser="(value) => value.replace(/\$\s?|(,*)/g, '')"
></InputNumber>
</el-form-item>
</template>
<template v-else>
<el-form-item prop="type" label="项目类型">
<el-select
clearable
placeholder="请选择项目类型"
v-model="form.type"
style="width: 100%"
>
<el-option
v-for="item in types"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="purchase_type_id" label="采购形式">
<el-radio-group v-model="form.purchase_type_id">
<el-radio
v-for="item in purchaseType"
:key="item.id"
:label="item.id"
>{{ item.value }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="purchase_way_id" label="采购方式">
<el-select
clearable
placeholder="请选择采购方式"
v-model="form.purchase_way_id"
style="width: 100%"
>
<el-option
v-for="item in purchaseWayFormat()"
:label="item.value"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="money_way_id" label="资金渠道">
<el-select
multiple
size="small"
clearable
placeholder="请选择资金渠道"
:value="
form.money_way_id
? form.money_way_id.split(',').map((i) => Number(i))
: []
"
style="width: 100%"
@change="
(e) => {
form.money_way_id = e.length > 0 ? e.toString() : '';
}
"
>
<el-option
v-for="item in moneyWay"
:value="item.id"
:label="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="plan_price" label="采购预算价(元)">
<InputNumber
style="width: 100%"
:min="0"
:step="10000"
:precision="2"
:active-change="false"
v-model="form.plan_price"
:formatter="
(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
"
:parser="(value) => value.replace(/\$\s?|(,*)/g, '')"
></InputNumber>
</el-form-item>
</template>
<el-form-item
prop="use_framework_buy"
label="是否使用框架协议采购内容"
>
<el-radio-group v-model="form.use_framework_buy">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
prop="is_framework"
label="是否新生成框架协议"
v-show="isShowIsFramework"
>
<el-radio-group v-model="form.is_framework">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
prop="contract_to_contracts"
label="关联的框架协议合同"
v-show="form.use_framework_buy"
>
<div
class="form__contract-to-contracts--no"
@click="isShowContractToContracts = true"
>
请选择关联的框架协议合同
</div>
<div v-if="contractToContractsSelections.length > 0">
<Tag type="dot"
closable
v-for="(i,index) in contractToContractsSelections"
:color="['primary','success','error','warning'][index%4]"
:key="i.id"
@on-close="closeTag(i)">{{ i.name.slice(0,17) }}</Tag>
</div>
</el-form-item>
</template>
<template v-else>
<el-form-item prop="is_contract" label="是否需要签订合同">
<el-radio-group :value="1">
<el-radio :label="1" disabled>是</el-radio>
<el-radio :label="0" disabled>否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="contract_type" label="是否需要签订合同">
<el-select style="width: 100%" v-model="form.contract_type">
<el-option v-for="(item,index) in contractTypes" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="supply" label="承包商\供应商">
<el-input style="width: 100%;" placeholder="请填写承包商\供应商" v-model="form.supply" />
</el-form-item>
<el-form-item prop="money" label="合同金额(元)">
<InputNumber
style="width: 100%"
:min="0"
:step="10000"
:precision="2"
:active-change="false"
v-model="form.money"
:formatter="
(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
"
:parser="(value) => value.replace(/\$\s?|(,*)/g, '')"
></InputNumber>
</el-form-item>
<el-form-item
prop="is_framework"
label="是否新生成框架协议"
v-show="isShowIsFramework"
>
<el-radio-group v-model="form.is_framework">
<el-radio :label="1">是</el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
</template>
</el-form>
<div style="text-align: center">
<el-button style="margin-top: 12px" @click="forwardStep"
>上一步</el-button
>
<el-button
style="margin-top: 12px"
type="warning"
plain
@click="resetForm"
>重置</el-button
>
<el-button :loading="btnLoading" style="margin-top: 12px" type="primary" @click="() => nextStep()"
>提交</el-button
>
</div>
</el-card>
<el-card v-show="step === 3">
<div class="done">
<i class="el-icon-success" style="color: #58bb73;font-size: 40px;"></i>
<p>{{ type === 'add' ? '创建' : '编辑' }}完成</p>
<svg
height="230"
viewBox="0 0 230 230"
width="230"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-1"
node-id="5"
spreadMethod="pad"
x1="-0.19665861"
x2="1.0436114"
y1="0.5"
y2="0.5"
>
<stop offset="0" stop-color="#56c6fb" />
<stop offset="1" stop-color="#56c6fb" stop-opacity="0" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-2"
node-id="8"
spreadMethod="pad"
x1="0"
x2="1.0564857"
y1="0.40330252"
y2="0.6062147"
>
<stop offset="0" stop-color="#7983d6" />
<stop offset="1" stop-color="#242c83" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-3"
node-id="11"
spreadMethod="pad"
x1="0.6815462"
x2="0"
y1="0.44933662"
y2="0.62995005"
>
<stop offset="0" stop-color="#7dd2fb" />
<stop offset="1" stop-color="#3797e2" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-4"
node-id="14"
spreadMethod="pad"
x1="1.0198022"
x2="0"
y1="0.42886087"
y2="0.64435285"
>
<stop offset="0" stop-color="#eeeeee" />
<stop offset="1" stop-color="#d8d8d8" stop-opacity="0" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-5"
node-id="17"
spreadMethod="pad"
x1="-0.019802213"
x2="1"
y1="0.44724947"
y2="0.60703945"
>
<stop offset="0" stop-color="#eeeeee" />
<stop offset="1" stop-color="#d8d8d8" stop-opacity="0" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-6"
node-id="20"
spreadMethod="pad"
x1="0"
x2="1.0564857"
y1="0.4574653"
y2="0.5467211"
>
<stop offset="0" stop-color="#7983d6" />
<stop offset="1" stop-color="#242c83" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-7"
node-id="23"
spreadMethod="pad"
x1="0.7455665"
x2="0"
y1="0.4161634"
y2="0.70934254"
>
<stop offset="0" stop-color="#e5e7fc" />
<stop offset="1" stop-color="#b4b7d5" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-8"
node-id="26"
spreadMethod="pad"
x1="0.6362425"
x2="0.23553719"
y1="0.28847575"
y2="1"
>
<stop offset="0" stop-color="#c4caf6" />
<stop offset="1" stop-color="#b8beed" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-9"
node-id="29"
spreadMethod="pad"
x1="1"
x2="-0.05648565"
y1="0.455"
y2="0.549429"
>
<stop offset="0" stop-color="#7983d6" />
<stop offset="1" stop-color="#242c83" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-10"
node-id="32"
spreadMethod="pad"
x1="0.7575835"
x2="0"
y1="0.4590923"
y2="0.5966975"
>
<stop offset="0" stop-color="#aeb4e0" />
<stop offset="1" stop-color="#7b84cd" />
</linearGradient>
<linearGradient
gradientUnits="objectBoundingBox"
id="linearGradient-11"
node-id="35"
spreadMethod="pad"
x1="0.73618025"
x2="0.012557022"
y1="0.4830155"
y2="0.54331756"
>
<stop offset="0" stop-color="#9da3d6" />
<stop offset="1" stop-color="#757fcd" />
</linearGradient>
</defs>
<g node-id="128">
<g node-id="129">
<g node-id="130">
<path
d="M 40.84 148.59 L 40.84 155.58 L 47.83 155.58 L 47.83 148.59 L 40.84 148.59 Z M 51.33 148.59 L 51.33 155.58 L 99.40 155.58 L 99.40 148.59 L 51.33 148.59 Z"
fill="url(#linearGradient-1)"
fill-opacity="0.4"
fill-rule="evenodd"
group-id="1,2,3"
id="形状结合"
node-id="41"
stroke="none"
target-height="6.991913"
target-width="58.557228"
target-x="40.842773"
target-y="148.58554"
/>
</g>
<g node-id="131">
<g node-id="132">
<path
d="M 84.10 93.80 L 48.10 93.80 L 61.60 115.40 L 97.22 115.40 Z"
fill="url(#linearGradient-2)"
fill-rule="evenodd"
group-id="1,2,4,5"
id="矩形"
node-id="43"
stroke="none"
target-height="21.599998"
target-width="49.116924"
target-x="48.099995"
target-y="93.8"
/>
</g>
<g node-id="133">
<path
d="M 69.70 71.30 L 161.50 71.30 L 161.50 118.10 L 69.70 118.10 Z"
fill="url(#linearGradient-3)"
fill-rule="evenodd"
group-id="1,2,4,6"
id="矩形"
node-id="45"
stroke="none"
target-height="46.799995"
target-width="91.8"
target-x="69.7"
target-y="71.3"
/>
<g node-id="135">
<path
d="M 77.80 83.00 L 138.10 83.00 L 138.10 115.40 L 77.80 115.40 Z"
fill="url(#linearGradient-4)"
fill-opacity="0.25150117"
fill-rule="evenodd"
group-id="1,2,4,6,8"
id="矩形备份-26"
node-id="46"
stroke="none"
target-height="32.4"
target-width="60.30001"
target-x="77.799995"
target-y="83"
/>
</g>
<g node-id="136">
<path
d="M 161.50 71.30 L 101.20 71.30 L 101.20 99.20 L 161.50 99.20 Z"
fill="url(#linearGradient-5)"
fill-opacity="0.21880595"
fill-rule="evenodd"
group-id="1,2,4,6,9"
id="矩形备份-30"
node-id="47"
stroke="none"
target-height="27.899994"
target-width="60.300003"
target-x="101.2"
target-y="71.3"
/>
</g>
<path
d="M 134.50 84.22 L 128.20 78.50 L 111.23 96.22 L 101.08 87.43 L 94.90 94.08 L 111.20 108.20 Z"
fill="#ffffff"
fill-rule="nonzero"
group-id="1,2,4,6"
id="路径"
node-id="48"
stroke="none"
target-height="29.699997"
target-width="39.600006"
target-x="94.899994"
target-y="78.5"
/>
<path
d="M 69.70 71.30 L 161.50 71.30 L 161.50 65.00 L 69.70 65.00 Z"
fill="#4da3df"
fill-rule="evenodd"
group-id="1,2,4,6,10"
id="矩形"
node-id="49"
stroke="none"
target-height="6.300003"
target-width="91.8"
target-x="69.7"
target-y="65"
/>
</g>
<g node-id="134">
<path
d="M 175.00 115.40 L 98.50 115.40 L 106.60 140.60 L 184.90 140.60 Z"
fill="url(#linearGradient-6)"
fill-rule="evenodd"
stroke="none"
/>
</g>
<path
d="M 61.60 115.40 L 138.10 115.40 L 138.10 164.90 L 61.60 164.90 Z"
fill="url(#linearGradient-7)"
fill-rule="evenodd"
group-id="1,2,4"
id="矩形"
stroke="none"
/>
<path
d="M 73.30 150.50 L 120.10 150.50 L 120.10 154.10 L 73.30 154.10 Z"
fill="#f8f8fa"
fill-rule="evenodd"
stroke="none"
/>
<path
d="M 138.10 115.40 L 174.10 115.40 L 174.10 164.90 L 138.10 164.90 Z"
fill="url(#linearGradient-8)"
fill-rule="evenodd"
stroke="none"
/>
<path
d="M 148.00 121.70 L 166.00 121.70 L 166.00 127.10 L 148.00 127.10 Z"
fill="url(#linearGradient-9)"
fill-rule="evenodd"
stroke="none"
/>
<path
d="M 151.22 93.80 L 187.22 93.80 L 174.10 115.40 L 138.10 115.40 Z"
fill="url(#linearGradient-10)"
fill-rule="evenodd"
stroke="none"
/>
<path
d="M 61.60 115.40 L 138.10 115.40 L 130.00 140.60 L 53.50 140.60 Z"
fill="url(#linearGradient-11)"
fill-rule="evenodd"
stroke="none"
/>
<path
d="M 54.40 141.50 L 129.10 141.50"
fill="none"
stroke="#d7dbff"
stroke-linecap="square"
stroke-width="1.8"
/>
<path
d="M 175.00 141.50 L 184.00 141.50"
fill="none"
stroke="#6a72c9"
stroke-linecap="square"
stroke-width="1.8"
/>
</g>
</g>
<path
d="M 168.03 65.00 L 168.03 78.50 L 181.53 78.50"
fill="none"
stroke="#979797"
stroke-linecap="butt"
stroke-width="2.7"
/>
</g>
</svg>
<div class="done__btns">
<Button shape="circle" @click="nextStep(true)">新建</Button>
<Button
type="primary"
style="margin-left: 40px"
shape="circle"
@click="
$router.push({
path: '/contract/contract/contractList',
query: {
keyword: form.name,
},
})
"
>查看</Button
>
</div>
</div>
</el-card>
</div>
<el-drawer
size="580px"
title="框架协议合同"
:visible.sync="isShowContractToContracts"
direction="rtl"
:before-close="handleDrawerClose"
>
<div style="padding: 0 20px">
<div style="margin-bottom: 15px;">
<el-input
v-model="contractSelect.keyword"
placeholder="关键字搜索"
clearable
@clear="handleKeywordClear"
@keyup.enter.native="handleKeywordSearch"
>
<el-button
slot="append"
icon="el-icon-search"
@click="handleKeywordSearch"
></el-button>
</el-input>
</div>
<xy-table
:list="contractList"
ref="contractToContractsTable"
:table-item="contractTable"
:height="600"
stripe
size="small"
>
<template #btns></template>
</xy-table>
<div style="display: flex; justify-content: center">
<el-pagination
:current-page.sync="contractSelect.page"
:page-size="contractSelect.page_size"
layout="prev, pager, next, jumper"
:total="contractTotal"
@current-change="e => {
contractSelect.page = e;
getContractToContracts();
}"
>
</el-pagination>
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import { getparameter, getparameterTree } from '@/api/system/dictionary'
import {
addContrant,
editorContract,
detailContract,
checkContractName,
getContract,
} from "@/api/contract/contract";
import { getBudget } from "@/api/budget/budget";
import { getInfo } from "@/api/user.js";
import { listdeptNoAuth } from '@/api/system/department'
export default {
data() {
return {
window: {
width: 0,
height: 0,
top: 0,
left: 0,
},
btnLoading: false,
type: "add",
contractId: "",
step: 1,
types: [
{ label: "服务", value: 1 },
{ label: "货物", value: 2 },
{ label: "工程", value: 3 },
], //项目类型
contractTypes: [
{ label: "收入类", value: 1 },
{ label: "支出类", value: 2 },
{ label: "技术协议", value: 3 },
],
form: {
type: "",
is_plan: 1,
purchase_type_id: "",
is_contract: 1,
purchase_way_id: "",
money_way_id: "",
plan_price: 0,
name: "",
contract_plan_links: [],
is_simple: 0,
supply: "",
money: 0,
status: 1,
is_framework: 0,
use_framework_buy: 0,
content: "",
contract_to_contracts: [],
outcome_type: 1
},
planTypes: [],
departments: [],
purchaseType: [],
moneyWay: [],
purchaseWay: [],
userList: ["ma_sm", "admin", "yu_l", "wang_yx", "li_f", "chen_y"],
boxheight: 300,
user: null,
adminEdit: false,
isShowEditor: false,
isShowPlan: false,
detail: {},
plan: [],
options: [
{
value: 1,
label: "待申请",
},
{
value: 2,
label: "流转中",
},
{
value: 3,
label: "已办结",
},
],
// rules: {
// name: [
// {
// required: true,
// message: "必填",
// trigger: "blur",
// },
// {
// validator: async (rule, value, callback) => {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// const { msg } = await checkContractName({ name: value });
// if (msg === "未重名") {
// callback();
// } else {
// callback(new Error(msg));
// }
// }
// },
// trigger: "blur",
// },
// ],
// supply: [
// {
// validator: (rule, value, callback) => {
// if (this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// type: [
// {
// validator: (rule, value, callback) => {
// if (!this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// purchase_type_id: [
// {
// validator: (rule, value, callback) => {
// if (!this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// purchase_way_id: [
// {
// validator: (rule, value, callback) => {
// if (!this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// money: [
// {
// validator: (rule, value, callback) => {
// if (this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// if (/^\d+(\.\d+)?$/.test(value)) {
// callback();
// } else {
// callback(new Error("必须为数字"));
// }
// }
// } else {
// callback();
// }
// },
// trigger: "blur",
// },
// ],
// plan_money: [
// {
// validator: (rule, value, callback) => {
// if (!this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// if (/^\d+(\.\d+)?$/.test(value)) {
// callback();
// } else {
// callback(new Error("必须为数字"));
// }
// }
// } else {
// callback();
// }
// },
// trigger: "blur",
// },
// ],
// money_way_id: [
// {
// validator: (rule, value, callback) => {
// if (!this.form.is_simple) {
// if (!this.hasValue(value)) {
// callback(new Error("必填"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// contract_plan_links: [
// {
// validator: (rule, value, callback) => {
// if (this.form.is_plan) {
// if (this.form.contract_plan_links.length === 0) {
// return callback(new Error("必选"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// contract_to_contracts: [
// {
// validator: (rule, value, callback) => {
// if (this.form.use_framework_buy) {
// if (this.form.contract_to_contracts.length === 0) {
// return callback(new Error("必选"));
// } else {
// callback();
// }
// } else {
// callback();
// }
// },
// trigger: "change",
// },
// ],
// },
plans: [],
planSelect: {
name: "",
page_size: 20,
page: 1,
is_tree: 1,
year: new Date().getFullYear().toString(),
plan_department_id: "",
type: ""
},
planTable: [
{
sortable: false,
width: 44,
type: "selection",
reserveSelection: true,
fixed: "left",
selectable: (row, index) => {
return row.pid === 0;
},
},
{
label: "科室",
prop: "plan_department.name",
width: 100,
align: "center",
},
{
label: "年份",
prop: "year",
width: 80,
align: "center",
},
{
label: "分类",
prop: "type_detail.value",
width: 120,
},
{
label: "名称",
prop: "name",
minWidth: 180,
align: "left",
},
{
label: "内容",
prop: "content",
minWidth: 180,
align: "left",
},
{
label: "计划金额",
prop: "update_money",
align: "right",
width: 120,
formatter: (v1, v2, value) => {
return `${(value && parseFloat(value) !== 0) ? value : v1.money }`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") }
},
{
label: "实付金额",
prop: "use_money_total",
width: 120,
align: "right",
formatter: (v1, v2, value) =>
value ? `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : "",
},
{
label: "已用金额",
prop: "has_money_total",
width: 120,
align: "right",
formatter: (v1, v2, value) =>
value ? `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : "",
},
],
planTotal: 0,
contractSelect: {
page: 1,
page_size: 10,
is_framework: 1,
keyword: "",
},
contractList: [],
loading: false,
contractTable: [
{
type: "selection",
width: 56,
align: "center",
fixed: "left",
reserveSelection: true,
},
{
label: "项目名称",
prop: "name",
minWidth: 180,
align: "left",
},
{
label: "框架合同总额",
prop: "plan_price",
width: 120,
align: "right"
},
{
prop: "purchase_type.value",
label: "采购形式",
width: 120,
},
{
label: "项目类型",
width: 120,
customFn: (row) => (
<span>
{this.types.find((i) => i.value === row.type)?.label || "-"}
</span>
),
},
{
prop: "purchase_way.value",
label: "采购方式",
width: 120,
},
],
contractTotal: 0,
isShowContractToContracts: false,
};
},
methods: {
planPick (selection, row) {
if (row.year != new Date().getFullYear()) {
this.$confirm("您选择了非本年预算,是否继续?").catch(_ => {
this.$refs['editorPlanTable'].toggleRowSelection(row)
})
}
},
setType(type) {
if (["add", "edit"].find((i) => i === type)) {
this.type = type;
} else {
console.warn('type need "add" or "edit"');
}
},
hasValue(value) {
return (
value !== "" &&
value !== undefined &&
value !== "undefined" &&
value !== null
);
},
//获取资金渠道
async getMoneyWay() {
this.moneyWay =
(
await getparameter({
number: "money_way",
})
)?.detail || [];
},
//获取购买方式
async getPurchaseWay() {
this.purchaseWay =
(
await getparameter({
number: "purchase_way",
})
)?.detail || [];
},
//获取购买形式列表
async getPurchaseType() {
this.purchaseType =
(
await getparameter({
number: "purchase_type",
})
)?.detail || [];
},
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res;
});
},
async getPlanTypes() {
const res = await getparameterTree({
id: 3
});
const dataHandler = (data) => {
data.forEach(i => {
if (i.hasOwnProperty('detail')) {
i.children = i.detail.map(j => {
j.name = j.value
return j;
})
} else {
dataHandler(i['children'])
}
})
return data;
}
this.planTypes = dataHandler(res?.children) || []
},
forwardStep() {
if (this.step > 1) {
this.step--;
}
},
nextStep(isRefresh = false) {
if (isRefresh) {
this.$refs["editorPlanTable"]?.clearSelection();
this.$refs["contractToContractsTable"]?.clearSelection();
this.resetForm();
this.step = 1;
return;
}
if (this.step >= 3) return;
if (this.step === 1) {
const selections = this.$refs["editorPlanTable"].getSelection();
if (selections?.length > 0) {
for (let i of selections) {
if (i._inputMoney <= 0) {
this.$message({
type: "warning",
message: `【${i.year}】${i.name} 使用金额需要大于0`,
});
return;
}
if ((i._inputMoney > (Number(i.update_money) || (Number(i.money)) - Number(i.has_money_total))) || (i._inputMoney > (Number(i.update_money) || (Number(i.money)) - Number(i.use_money_total)))) {
this.$message({
type: "warning",
message: `【${i.year}】${i.name} 使用金额大于剩余预算!`,
});
return;
}
}
this.form.contract_plan_links = selections.map((i) => ({
plan_id: i.id,
use_money: i._inputMoney,
new_money: i.money,
}));
this.step = 2;
} else {
this.$message({
type: "warning",
message: "请先选择预算计划!",
});
}
} else if (this.step === 2) {
//submit
this.$refs["form"].validate((valid) => {
if (valid) {
this.btnLoading = true
if (!this.form.use_framework_buy) {
this.form.contract_to_contracts = []
} else {
this.form.contract_plan_links = []
}
if (this.form.is_contract && this.form.is_simple) {
this.form.purchase_status = 3;
this.form.invite_status = 3;
}
if (this.type === 'add') {
addContrant(this.form,true).then(res => {
this.btnLoading = false
//this.step = 3;
this.$router.push({
path: this.form.is_simple ? '/contract/contractAll' : '/contract/contract/contractList',
query: {
keyword: this.form.name,
},
})
getContract({
page: 1,
page_size: 1,
sort_name: "created_at"
},true).then(res => {
const openData = res.list.data[0]
if (openData) {
if (
openData.is_simple !== 1 &&
openData.purchase_status === 1 &&
((openData.req_status === 3 && openData.is_plan === 0) ||
openData.is_plan === 1) &&
!openData.is_substitute
) {
this.buyProcess(openData)
}
}
})
}).catch(_ => this.btnLoading = false)
}
if (this.type === 'edit') {
editorContract({
id: this.contractId,
...this.form
}).then(res => {
this.btnLoading = false
this.step = 3;
}).catch(_ => this.btnLoading = false)
}
}
});
}
},
async buyProcess(row) {
let baseInfo = {
title: row?.name,
iszhengfucaigou:
(row.purchase_type?.value === "政府采购") ? "政府采购" : "否",
out_caigou_id: row.id,
type: this.types.find((item) => {
return item.value === row.type;
})?.label,
yusuan: row?.plan_price?.toString(),
zijinlaiyuan: row.money_way_detail?.value,
zijinlaiyuanjuti: row?.plans.reduce((pre,cur,index)=>(index === 0 ? (`【${cur?.year}】${cur?.name}`) : (pre+`,【${cur?.year}】${cur?.name}`)),"")
};
let url = `${process.env.VUE_APP_OUT_OLD}?s=/flow/add/modid/8&auth_token=${this.$store.getters.oa_token}&out_caigou_id=${
row.id
}&contract_json=${JSON.stringify(baseInfo)}`;
window.open(
url,
"buyProcess",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
);
},
//获取预算计划
async getBudgets() {
let res = await getBudget(this.planSelect);
res.list.forEach((item) => (item._inputMoney = 0));
this.plans = res.list;
this.planTotal = res.list.total || 0;
},
handleDrawerClose(done) {
this.$confirm("确认关闭?")
.then((_) => {
this.form.contract_to_contracts = this.$refs['contractToContractsTable']?.getSelection().map(i => {
return this.id ? {
contract_id: this.contractId,
to_contract_id: i.id,
use_money: this.form.plan_price
} : {
to_contract_id: i.id,
use_money: this.form.plan_price
}
})
done();
})
.catch((_) => {});
},
resetForm() {
this.form = {
type: "",
is_plan: 1,
purchase_type_id: "",
is_contract: 1,
purchase_way_id: "",
money_way_id: "",
plan_price: 0,
name: "",
contract_plan_links: this.planSelections.map((i) => ({
plan_id: i.id,
use_money: i._inputMoney,
new_money: i.money,
})),
is_simple: 0,
supply: "",
money: 0,
status: 1,
is_framework: 0,
use_framework_buy: 0,
content: "",
contract_to_contracts: [],
outcome_type: 1
};
this.$refs["form"].clearValidate();
},
//框架合同
async getContractToContracts() {
const res = await getContract(this.contractSelect, true);
this.contractList = res.list.data;
this.contractTotal = res.list.total;
},
// 关键字搜索
handleKeywordSearch() {
this.contractSelect.page = 1;
this.getContractToContracts();
},
// 清除关键字
handleKeywordClear() {
this.contractSelect.keyword = "";
this.contractSelect.page = 1;
this.getContractToContracts();
},
closeTag (i) {
// 从表格中找到对应的行并取消选中
const table = this.$refs['contractToContractsTable'];
if (table) {
const currentSelections = table.getSelection();
const rowToDeselect = currentSelections.find(j => j.id === i.id);
if (rowToDeselect) {
// 取消选中该行(第二个参数为 false 表示取消选中)
table.toggleRowSelection(rowToDeselect, false);
}
// 更新 form.contract_to_contracts
const newSelections = table.getSelection();
this.form.contract_to_contracts = newSelections.map(item => {
return this.id ? {
contract_id: this.contractId,
to_contract_id: item.id,
use_money: this.form.plan_price
} : {
to_contract_id: item.id,
use_money: this.form.plan_price
};
});
}
},
async getDetail () {
const res = await detailContract({
id: this.contractId
})
this.form = {
type: res?.type,
is_plan: res?.is_plan,
purchase_type_id: res?.purchase_type_id,
is_contract: res?.is_contract,
purchase_way_id: res?.purchase_way_id,
money_way_id: res?.money_way_id,
plan_price: Number(res?.plan_price),
name: res?.name,
contract_plan_links: [],
is_simple: res?.is_simple,
supply: res?.supply,
money: Number(res?.money),
status: res?.status,
is_framework: res?.is_framework,
use_framework_buy: res?.use_framework_buy,
content: res?.content,
contract_to_contracts: [],
}
}
},
computed: {
purchaseWayFormat() {
return function () {
if (!this.form.purchase_type_id) {
return this.purchaseWay;
} else {
let temp = this.purchaseType.find((i) => i.id === this.form.purchase_type_id);
let arr = temp?.remark?.split(",")?.map((i) => Number(i));
return this.purchaseWay.filter((i) => arr.indexOf(i.id) !== -1);
}
};
},
isLedger () {
return this.$route.query.isLedger;
},
isShowIsFramework() {
let temp1 = this.form.purchase_type_id;
let temp2 = this.form.use_framework_buy;
const selectedPurchaseType = this.purchaseType.find(item => item.id === this.form.purchase_type_id);
if (
selectedPurchaseType?.value === "直接采购" &&
this.form.use_framework_buy
) {
this.form.is_framework = true;
return false;
} else {
return true;
}
},
planSelections() {
let temp = this.form.contract_plan_links;
return this.$refs["editorPlanTable"]?.getSelection() || [];
},
contractToContractsSelections () {
let temp = this.form.contract_to_contracts;
return this.$refs["contractToContractsTable"]?.getSelection() || []
},
rules() {
return this.isLedger ? {
name: [
{
required: true,
message: "必填",
trigger: "blur",
},
{
validator: async (rule, value, callback) => {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
const { msg } = await checkContractName({ name: value });
if (msg === "未重名") {
callback();
} else {
callback(new Error(msg));
}
}
},
trigger: "blur",
},
],
supply: [
{
validator: (rule, value, callback) => {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
callback();
}
},
trigger: "change",
},
],
money: [
{
validator: (rule, value, callback) => {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
if (/^\d+(\.\d+)?$/.test(value)) {
callback();
} else {
callback(new Error("必须为数字"));
}
}
},
trigger: "blur",
}
]
} : {
name: [
{
required: true,
message: "必填",
trigger: "blur",
},
{
validator: async (rule, value, callback) => {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
const { msg } = await checkContractName({ name: value });
if (msg === "未重名") {
callback();
} else {
callback(new Error(msg));
}
}
},
trigger: "blur",
},
],
supply: [
{
validator: (rule, value, callback) => {
if (this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
type: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
purchase_type_id: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
purchase_way_id: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
money: [
{
validator: (rule, value, callback) => {
if (this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
if (/^\d+(\.\d+)?$/.test(value)) {
callback();
} else {
callback(new Error("必须为数字"));
}
}
} else {
callback();
}
},
trigger: "blur",
},
],
plan_money: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
if (/^\d+(\.\d+)?$/.test(value)) {
callback();
} else {
callback(new Error("必须为数字"));
}
}
} else {
callback();
}
},
trigger: "blur",
},
],
money_way_id: [
{
validator: (rule, value, callback) => {
if (!this.form.is_simple) {
if (!this.hasValue(value)) {
callback(new Error("必填"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
contract_plan_links: [
{
validator: (rule, value, callback) => {
if (this.form.is_plan) {
if (this.form.contract_plan_links.length === 0) {
return callback(new Error("必选"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
contract_to_contracts: [
{
validator: (rule, value, callback) => {
if (this.form.use_framework_buy) {
if (this.form.contract_to_contracts.length === 0) {
return callback(new Error("必选"));
} else {
callback();
}
} else {
callback();
}
},
trigger: "change",
},
],
}
}
},
created() {
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;
this.getPlanTypes();
this.getDepartment();
this.getBudgets();
this.getMoneyWay();
this.getPurchaseType();
this.getPurchaseWay();
this.boxheight = document.documentElement.clientHeight - 400;
},
watch: {
isShowContractToContracts(val) {
if (val) {
this.getContractToContracts();
} else {
this.contractSelect = {
page: 1,
page_size: 10,
is_framework: 1,
keyword: "",
};
this.contractList = [];
this.contractTotal = 0;
}
},
},
mounted() {
let that = this;
getInfo().then((response) => {
this.user = response;
if (that.userList.indexOf(response.username) != -1) {
that.adminEdit = true;
}
});
},
beforeRouteEnter(to, from, next) {
next(vm => {
const { contractId } = to.query
vm.contractId = contractId;
if (contractId) {
vm.setType('edit')
vm.getDetail()
}
})
}
};
</script>
<style scoped lang="scss">
.form__contract-to-contracts--no {
min-height: 30px;
border: 1px solid #dcdee2;
border-radius: 4px;
display: flex;
flex-wrap: wrap;
align-items: center;
align-content: center;
height: 30px;
line-height: 30px;
color: #cdd0d5;
width: 100%;
cursor: pointer;
padding: 0 8px;
}
.el-form-body {
width: 100%;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 40px;
grid-row-gap: 15px;
padding: 20px;
}
.done {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
& > p {
font-size: 20px;
font-weight: 600;
color: #666;
line-height: 2;
margin-top: 12px;
}
}
</style>