合同相对人目录
This commit is contained in:
parent
36bf4c4ab3
commit
e5d161b8b1
|
@ -53,8 +53,8 @@ export function setupElegantRouter() {
|
|||
return '/contract/archive/edit/:id?'
|
||||
}
|
||||
|
||||
if (key === 'contract_perform_edit') {
|
||||
return '/contract/perform/edit/:id?'
|
||||
if (key === 'contract_company_edit') {
|
||||
return '/contract/company/edit/:id?'
|
||||
}
|
||||
|
||||
return routePath
|
||||
|
|
|
@ -35,6 +35,8 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
|||
contract_archive_list: () => import("@/views/contract/archive/list/index.vue"),
|
||||
contract_business_edit: () => import("@/views/contract/business/edit/[id].vue"),
|
||||
contract_business_list: () => import("@/views/contract/business/list/index.vue"),
|
||||
contract_company_edit: () => import("@/views/contract/company/edit/[id].vue"),
|
||||
contract_company_list: () => import("@/views/contract/company/list/index.vue"),
|
||||
contract_config: () => import("@/views/contract/config/index.vue"),
|
||||
contract_declaration_edit: () => import("@/views/contract/declaration/edit/[id].vue"),
|
||||
contract_declaration_list: () => import("@/views/contract/declaration/list/index.vue"),
|
||||
|
|
|
@ -270,6 +270,40 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'contract_company',
|
||||
path: '/contract/company',
|
||||
component: 'view.contract_company_list',
|
||||
meta: {
|
||||
title: '合同相对人',
|
||||
icon: 'icon-park-outline:lens-alignment',
|
||||
order: 99
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'contract_company_edit',
|
||||
path: '/contract/company/edit/:id?',
|
||||
component: 'view.contract_company_edit',
|
||||
meta: {
|
||||
hideInMenu: true,
|
||||
title: '合同相对人编辑',
|
||||
activeMenu: 'contract_company',
|
||||
order: 99
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'contract_company_list',
|
||||
path: '/contract/company/list',
|
||||
component: 'view.contract_company_list',
|
||||
meta: {
|
||||
hideInMenu: true,
|
||||
title: '合同相对人',
|
||||
activeMenu: 'contract_company',
|
||||
order: 20
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'contract_config',
|
||||
path: '/contract/config',
|
||||
|
@ -326,7 +360,7 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||
children: [
|
||||
{
|
||||
name: 'contract_perform_edit',
|
||||
path: '/contract/perform/edit/:id?',
|
||||
path: '/contract/perform/edit/:id',
|
||||
component: 'view.contract_perform_edit',
|
||||
meta: {
|
||||
hideInMenu: true,
|
||||
|
|
|
@ -197,12 +197,15 @@ const routeMap: RouteMap = {
|
|||
"contract_business": "/contract/business",
|
||||
"contract_business_edit": "/contract/business/edit/:id?",
|
||||
"contract_business_list": "/contract/business/list",
|
||||
"contract_company": "/contract/company",
|
||||
"contract_company_edit": "/contract/company/edit/:id?",
|
||||
"contract_company_list": "/contract/company/list",
|
||||
"contract_config": "/contract/config",
|
||||
"contract_declaration": "/contract/declaration",
|
||||
"contract_declaration_edit": "/contract/declaration/edit/:id?",
|
||||
"contract_declaration_list": "/contract/declaration/list",
|
||||
"contract_perform": "/contract/perform",
|
||||
"contract_perform_edit": "/contract/perform/edit/:id?",
|
||||
"contract_perform_edit": "/contract/perform/edit/:id",
|
||||
"contract_perform_list": "/contract/perform/list",
|
||||
"duty": "/duty",
|
||||
"function": "/function",
|
||||
|
|
|
@ -53,12 +53,15 @@ declare module "@elegant-router/types" {
|
|||
"contract_business": "/contract/business";
|
||||
"contract_business_edit": "/contract/business/edit/:id?";
|
||||
"contract_business_list": "/contract/business/list";
|
||||
"contract_company": "/contract/company";
|
||||
"contract_company_edit": "/contract/company/edit/:id?";
|
||||
"contract_company_list": "/contract/company/list";
|
||||
"contract_config": "/contract/config";
|
||||
"contract_declaration": "/contract/declaration";
|
||||
"contract_declaration_edit": "/contract/declaration/edit/:id?";
|
||||
"contract_declaration_list": "/contract/declaration/list";
|
||||
"contract_perform": "/contract/perform";
|
||||
"contract_perform_edit": "/contract/perform/edit/:id?";
|
||||
"contract_perform_edit": "/contract/perform/edit/:id";
|
||||
"contract_perform_list": "/contract/perform/list";
|
||||
"duty": "/duty";
|
||||
"function": "/function";
|
||||
|
@ -202,6 +205,8 @@ declare module "@elegant-router/types" {
|
|||
| "contract_archive_list"
|
||||
| "contract_business_edit"
|
||||
| "contract_business_list"
|
||||
| "contract_company_edit"
|
||||
| "contract_company_list"
|
||||
| "contract_config"
|
||||
| "contract_declaration_edit"
|
||||
| "contract_declaration_list"
|
||||
|
|
|
@ -0,0 +1,605 @@
|
|||
<script setup lang="ts">
|
||||
import { reactive, ref, computed, onMounted } from "vue";
|
||||
import { c, useDialog, useMessage } from "naive-ui";
|
||||
import type { UploadCustomRequestOptions, UploadFileInfo, UploadInst } from "naive-ui";
|
||||
import {
|
||||
getMeetingList,
|
||||
getAddressorList,
|
||||
saveMeeting,
|
||||
} from "@/api/office/meeting";
|
||||
import { useVxeTable } from "@/hooks/common/vxeTable";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRequest } from "alova/client";
|
||||
import { DICT_TYPE, getDictObj, getDictOptions } from '@/utils/dict';
|
||||
import { uploadFile, uploadFiles, downloadFile } from "@/api/system/file";
|
||||
import ChooseUserModal from "@/views/user-center/ChooseUserModal.vue";
|
||||
import { router } from "@/router";
|
||||
|
||||
import { useTabStore } from "@/store/modules/tab";
|
||||
|
||||
import { FileUploader } from "@/utils/file";
|
||||
import { FileSource } from "@/enums";
|
||||
|
||||
const { xGridRef, gridProps, triggerProxy } = useVxeTable({ ref: 'xGridRef' });
|
||||
|
||||
const PrimaryKey = "guid"
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
|
||||
const route = useRoute();
|
||||
const id = route.params.id as string;
|
||||
|
||||
const tabStore = useTabStore();
|
||||
|
||||
const contractData = ref({});
|
||||
const isContractBaseLoading = ref(false)
|
||||
|
||||
const uploadRef = ref<UploadInst | null>(null);
|
||||
|
||||
const fileUploader = new FileUploader({
|
||||
uploadRef,
|
||||
data: { source: FileSource.Ht },
|
||||
onSuccess: (fileList: any[]) => {
|
||||
console.log('[ fileList ] >', fileList)
|
||||
handleSubmit('submit')
|
||||
},
|
||||
onError: (err: any) => {
|
||||
console.log('[ err ] >', err)
|
||||
},
|
||||
})
|
||||
|
||||
/** 必填字段校验 */
|
||||
const requiredFieldRules: any = {
|
||||
"contractName": { required: true, message: '合同名称不得为空' },
|
||||
"ctrType": { required: true, message: '合同类别不得为空' },
|
||||
"ctrTwoType": { required: true, message: '合同二级类别不得为空' },
|
||||
"fundAllocation": { required: true, message: '资金流向不得为空' },
|
||||
"fundDitch": { required: true, message: '资金渠道不得为空' },
|
||||
"organiza": { required: true, message: '组织形式不得为空' },
|
||||
}
|
||||
|
||||
/** 必填字段校验,如果是必填字段则返回对应message */
|
||||
function isRequired(field: string): string {
|
||||
let rule = requiredFieldRules[field];
|
||||
if (rule && rule.required) {
|
||||
return rule.message || `${field}不可为空`;
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
/** Hooks 数据请求 - 选商数据 */
|
||||
const currData = ref<any>({
|
||||
fileUuid: "",
|
||||
isBid: 0,
|
||||
});
|
||||
const { send, onSuccess, loading } = useRequest(params => Apis.ht.get_selectmerchantsbasicinfo_getone(
|
||||
{
|
||||
params: params
|
||||
}
|
||||
), {
|
||||
immediate: false,
|
||||
});
|
||||
onSuccess((res: any) => {
|
||||
|
||||
console.log(res);
|
||||
if (res.data && res.data?.rows && res.data?.rows.length > 0) {
|
||||
currData.value = res.data?.rows[0] || {};
|
||||
|
||||
// 处理选商文件
|
||||
if (currData.value?.fileUuid) {
|
||||
Apis.common.get_attachment_list({
|
||||
params: {
|
||||
uuid: currData.value?.fileUuid,
|
||||
},
|
||||
}).then((res: any) => {
|
||||
console.log(res);
|
||||
fileUploader.setFileList(res.data.rows);
|
||||
});
|
||||
}
|
||||
|
||||
console.log("当前数据:", currData.value);
|
||||
}
|
||||
});
|
||||
|
||||
/** Hooks 数据请求 - 合同类型 */
|
||||
const {
|
||||
data: contractTypeData,
|
||||
onSuccess: onContractTypeSuccess,
|
||||
loading: addressLoading,
|
||||
} = useRequest(Apis.ht.get_contractrefertype_list({}), { immediate: true, initialData: { rows: [] } });
|
||||
onContractTypeSuccess((res: any) => {
|
||||
console.log(res);
|
||||
currData.value.htlb = contractTypeData.value.rows[0].contrLevelId
|
||||
});
|
||||
|
||||
|
||||
/** Hooks - 表格 */
|
||||
const gridOptions = reactive(gridProps({
|
||||
columns: [
|
||||
{ type: 'seq', title: '序号', width: 60 },
|
||||
{ field: 'referenceName', title: '签约依据名称', minWidth: 150 },
|
||||
{ field: 'referenceId', title: '签约依据编号', width: 200 },
|
||||
{ field: 'attachments', title: '附件', width: 120 },
|
||||
{
|
||||
title: '操作',
|
||||
width: 120,
|
||||
slots: { default: 'operation' }
|
||||
}
|
||||
],
|
||||
data: [],
|
||||
toolbarConfig: {
|
||||
enabled: false
|
||||
},
|
||||
pagerConfig: {
|
||||
enabled: false
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
* @param file
|
||||
*/
|
||||
function handleDownload(file: UploadFileInfo) {
|
||||
message.loading("下载中");
|
||||
if (file.file) {
|
||||
return true;
|
||||
} else {
|
||||
downloadFile(file.batchId).then((res) => {
|
||||
message.destroyAll();
|
||||
message.success(`下载成功:${file.name}`);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开选择签约依据弹窗
|
||||
*/
|
||||
async function handleOpenChooseBasisContractModal(status: boolean) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 筛选合同列表数据
|
||||
*
|
||||
*/
|
||||
function filterContractTypes(parentId: string) {
|
||||
return contractTypeData.value.rows.map((item) => {
|
||||
item.label = item.contrLevelName;
|
||||
item.value = item.contrLevelId;
|
||||
return item
|
||||
}).filter((item) => item.parentId === parentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交
|
||||
*/
|
||||
async function handleSubmit(type: "submit" | "upload") {
|
||||
console.log(currData.value);
|
||||
if (type === "submit") {
|
||||
// 提交
|
||||
if (fileUploader.fileList.value && fileUploader.fileList.value.length) {
|
||||
let fileNames = fileUploader.fileList.value.map((item) => item.name);
|
||||
currData.value.fileName = JSON.stringify(fileNames);
|
||||
let fileUuids = fileUploader.fileList.value.map((item) => item.batchId);
|
||||
currData.value.fileUuid = JSON.stringify(fileUuids);
|
||||
} else {
|
||||
currData.value.fileName = JSON.stringify([]);
|
||||
currData.value.fileUuid = JSON.stringify([]);
|
||||
}
|
||||
|
||||
if (
|
||||
currData.value.custom_otherEquipment &&
|
||||
currData.value.custom_otherEquipment.length > 0
|
||||
) {
|
||||
currData.value.otherEquipment = currData.value.custom_otherEquipment.join(",");
|
||||
}
|
||||
|
||||
await Apis.ht.post_contractbaseinfo_apply({
|
||||
data: currData.value
|
||||
});
|
||||
|
||||
message.success("提交成功");
|
||||
back();
|
||||
} else {
|
||||
fileUploader.initiateUpload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面返回并关闭tab
|
||||
*/
|
||||
function back() {
|
||||
router.back();
|
||||
tabStore.removeActiveTab();
|
||||
}
|
||||
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
if (id) {
|
||||
// 先查询合同基本信息
|
||||
isContractBaseLoading.value = true;
|
||||
Apis.ht.get_contractbaseinfo_getone({
|
||||
params: {
|
||||
guid: id
|
||||
}
|
||||
}).then(async (data: any) => {
|
||||
console.log(data)
|
||||
if (data && data.contractId) {
|
||||
|
||||
contractData.value = data;
|
||||
// 查询选商信息
|
||||
await send({ contractId: data.contractId });
|
||||
} else {
|
||||
dialog.error({
|
||||
title: '提示',
|
||||
content: '当前合同不存在',
|
||||
positiveText: '返回上一层',
|
||||
closable: false,
|
||||
maskClosable: false,
|
||||
onPositiveClick: () => {
|
||||
back()
|
||||
}
|
||||
})
|
||||
}
|
||||
}).finally(() => {
|
||||
isContractBaseLoading.value = false
|
||||
})
|
||||
|
||||
// await addressorSend();
|
||||
}
|
||||
});
|
||||
|
||||
const containerRef = ref<HTMLElement | undefined>(undefined);
|
||||
|
||||
function handleBack() {
|
||||
dialog.warning({
|
||||
title: "提示",
|
||||
content: `是否确认返回上一页面?`,
|
||||
positiveText: "确认",
|
||||
negativeText: "取消",
|
||||
onPositiveClick: async () => {
|
||||
back();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="containerRef"
|
||||
class="flex-col-stretch relative gap-16px overflow-hidden bg-white px-4 py-2 lt-sm:overflow-auto">
|
||||
<div>
|
||||
<n-affix class="z-20 w-full bg-white py-1" :trigger-top="10" position="absolute" :listen-to="() => containerRef">
|
||||
<n-space>
|
||||
<n-button type="primary" size="small" @click="handleSubmit('upload')">
|
||||
<template #icon>
|
||||
<icon-mdi-content-save-outline />
|
||||
</template>
|
||||
保存</n-button>
|
||||
|
||||
<n-button type="primary" size="small" @click="handleSubmit('upload')">
|
||||
<template #icon>
|
||||
<icon-mdi-send />
|
||||
</template>
|
||||
提交</n-button>
|
||||
|
||||
<n-button v-if="id" type="error" size="small">
|
||||
<template #icon>
|
||||
<icon-mdi-delete-outline />
|
||||
</template>
|
||||
废除
|
||||
</n-button>
|
||||
|
||||
<n-button size="small" @click="handleBack()">
|
||||
<template #icon>
|
||||
<icon-mdi-undo-variant />
|
||||
</template>
|
||||
返回
|
||||
</n-button>
|
||||
</n-space>
|
||||
</n-affix>
|
||||
</div>
|
||||
|
||||
<n-space vertical class="overflow-auto">
|
||||
<div class="h-20px"></div>
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>合同立项基本信息</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<n-spin :show="isContractBaseLoading">
|
||||
<n-descriptions label-placement="left" bordered :column="6" label-class="w-120px!" size="small">
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
合同名称
|
||||
<span v-if="isRequired('contractName')" class="text-red">*</span>
|
||||
</template>
|
||||
<n-input v-model:value="contractData.contractName" placeholder="请输入"></n-input>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
合同类别
|
||||
<span v-if="isRequired('ctrType')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="h-80px overflow-y-auto">
|
||||
<DictTag v-model:value="contractData.ctrType" :options="filterContractTypes('-1')" selectable>
|
||||
</DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
二级类别
|
||||
<span v-if="isRequired('ctrTwoType')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="h-80px overflow-y-auto">
|
||||
<DictTag v-model:value="contractData.ctrTwoType" :options="filterContractTypes(contractData.ctrType)"
|
||||
selectable placeholder="请选择二级类别">
|
||||
</DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
资金流向
|
||||
<span v-if="isRequired('fundAllocation')" class="text-red">*</span>
|
||||
</template>
|
||||
<DictTag v-model:value="contractData.fundAllocation" :options="getDictOptions(DICT_TYPE.contractFundFlow)"
|
||||
selectable> </DictTag>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
资金渠道
|
||||
<span v-if="isRequired('fundDitch')" class="text-red">*</span>
|
||||
</template>
|
||||
<DictTag v-model:value="contractData.fundDitch" :options="getDictOptions(DICT_TYPE.contractFundingSource)"
|
||||
selectable> </DictTag>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
组织形式
|
||||
<span v-if="isRequired('organiza')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<DictTag v-model:value="contractData.organiza"
|
||||
:options="getDictOptions(DICT_TYPE.contractOrganizationForm)" selectable> </DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="2">
|
||||
<template #label>
|
||||
预算金额
|
||||
<span v-if="isRequired('budgetSum')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="flex flex-row">
|
||||
<n-input-number class="flex-1" v-model:value="contractData.budgetSum"
|
||||
placeholder="请输入"></n-input-number>
|
||||
<n-select class="w-100px ml-2" v-model:value="contractData.priceType"
|
||||
:options="getDictOptions(DICT_TYPE.contractCurrencyUnit)" ceholder="请输入"></n-select>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="2">
|
||||
<template #label> 框架协议 </template>
|
||||
<span v-if="isRequired('frameProtocol')" class="text-red">*</span>
|
||||
<n-radio-group v-model:value="contractData.frameProtocol" name="radiogroup1">
|
||||
<n-space>
|
||||
<n-radio :value="1"> 是 </n-radio>
|
||||
<n-radio :value="0"> 否 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="2" label-width="150px">
|
||||
<template #label> 框架协议下的合同 </template>
|
||||
<span v-if="isRequired('frameProtocolCtr')" class="text-red">*</span>
|
||||
<n-radio-group v-model:value="contractData.frameProtocolCtr" name="radiogroup2">
|
||||
<n-space>
|
||||
<n-radio :value="1"> 是 </n-radio>
|
||||
<n-radio :value="0"> 否 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-descriptions-item>
|
||||
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>选商资料</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<n-spin :show="loading || addressLoading">
|
||||
<n-descriptions label-placement="left" bordered :column="3" label-class="w-130px" size="small">
|
||||
<n-descriptions-item :span="2">
|
||||
<template #label> 项目
|
||||
<span v-if="isRequired('projectNum')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="min-w-400px">
|
||||
<NSelect v-model:value="currData.projectNum" :options="getDictOptions(DICT_TYPE.comprehensiveProject)">
|
||||
</NSelect>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="1">
|
||||
<template #label> 项目类别
|
||||
<span v-if="isRequired('projectProp')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="h-80px overflow-y-auto">
|
||||
<DictTag v-model:value="currData.projectProp" :options="getDictOptions(DICT_TYPE.contractProjectType)"
|
||||
selectable> </DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 项目名称
|
||||
<span v-if="isRequired('projectNameId')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NSelect v-model:value="currData.projectNameId"
|
||||
:options="getDictOptions(DICT_TYPE.comprehensiveProjectName)">
|
||||
</NSelect>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 商务计价方式
|
||||
<span v-if="isRequired('priceStyleId')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="">
|
||||
<DictTag v-model:value="currData.priceStyleId" :options="getDictOptions(DICT_TYPE.contractPriceStyle)"
|
||||
selectable> </DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 选商方式
|
||||
<span v-if="isRequired('priceStyleId')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="">
|
||||
<DictTag v-model:value="currData.priceStyleId"
|
||||
:options="getDictOptions(DICT_TYPE.contractSelectionMethod)" selectable> </DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 选商方式说明
|
||||
<span v-if="isRequired('choiceReason')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.choiceReason" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 资质要求
|
||||
<span v-if="isRequired('qualificReq')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.qualificReq" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 划分标段
|
||||
<span v-if="isRequired('isBid')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="h-80px overflow-y-auto">
|
||||
<DictTag v-model:value="currData.isBid" :options="getDictOptions(DICT_TYPE.sectionType)" selectable>
|
||||
</DictTag>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 项目范围
|
||||
<span v-if="isRequired('projectRange')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.projectRange" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 项目内容
|
||||
<span v-if="isRequired('projectContent')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.projectContent" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 工期要求(质量要求)
|
||||
<span v-if="isRequired('quality')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.quality" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 工程量(采购量)
|
||||
<span v-if="isRequired('stockNums')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.stockNums" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 计划投资明细
|
||||
<span v-if="isRequired('stockPlanMx')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<NInput v-model:value="currData.stockPlanMx" type="textarea"> </NInput>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>招标文件</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<n-spin :show="loading || addressLoading">
|
||||
<n-descriptions label-placement="left" bordered :column="3" label-class="w-100px" size="small">
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 相关附件 </template>
|
||||
<div>
|
||||
<NUpload ref="uploadAfterRef" directory-dnd multiple :default-file-list="fileUploader.fileList.value"
|
||||
:custom-request="fileUploader.customRequest" show-download-button :default-upload="false" :max="5"
|
||||
@update:file-list="fileUploader.handleFileUpdate" @download="handleDownload"
|
||||
@finish="fileUploader.handleFileUploadFinish">
|
||||
<n-button>上传文件</n-button>
|
||||
</NUpload>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>签约依据</span>
|
||||
</div>
|
||||
</template>
|
||||
<n-spin :show="loading || addressLoading">
|
||||
<VxeGrid ref="xGridRef" v-bind="gridOptions">
|
||||
<template #operation></template>
|
||||
</VxeGrid>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
|
||||
</n-space>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.readonly .n-input__input-el) {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
:deep(.readonly .n-input__textarea-el) {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,164 @@
|
|||
<script setup lang="ts">
|
||||
import { reactive, ref, computed } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicForm, useForm } from '@/components/Form';
|
||||
import { PrimaryKey, getColumns, getFormSchema } from './schema';
|
||||
|
||||
import { useVxeTable } from '@/hooks/common/vxeTable';
|
||||
import { usePagination } from 'alova/client';
|
||||
import { paginationProps } from "@/utils/alova";
|
||||
import { toDetailPage } from '../../utils';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
const { routerPush } = useRouterPush();
|
||||
|
||||
const { xGridRef, gridProps, triggerProxy } = useVxeTable({ ref: 'xGridRef' });
|
||||
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
|
||||
const editModalRef = ref();
|
||||
const recordModalRef = ref();
|
||||
|
||||
const searchParams = reactive<any>({});
|
||||
|
||||
/** Hooks - 表单 */
|
||||
const [register, { setFieldsValue, getFieldsValue }] = useForm({
|
||||
gridProps: { cols: '1 s:2 m:3 l:3 xl:4 2xl:4' },
|
||||
labelWidth: 80,
|
||||
schemas: getFormSchema()
|
||||
});
|
||||
|
||||
/** Hooks - 数据请求 */
|
||||
const { send, onSuccess } = usePagination(({ pageNum, pageSize }: any) =>
|
||||
Apis.ht.get_selectmerchantsbasicinfo_page({ params: { pageNum, pageSize, ...searchParams, ...getFieldsValue() } }),
|
||||
{ ...paginationProps(), immediate: false }
|
||||
);
|
||||
onSuccess((res: any) => {
|
||||
console.log(res);
|
||||
});
|
||||
|
||||
/** Hooks - 表格 */
|
||||
const gridOptions = reactive(gridProps({
|
||||
columns: getColumns(),
|
||||
proxyConfig: {
|
||||
autoLoad: true,
|
||||
ajax: {
|
||||
query: ({ page }) => send({ pageNum: page.currentPage, pageSize: page.pageSize })
|
||||
},
|
||||
}
|
||||
}));
|
||||
|
||||
function handleQuery(_values: Recordable) {
|
||||
triggerProxy("reload");
|
||||
}
|
||||
|
||||
function handleReset(_values: Recordable) {
|
||||
triggerProxy("reload");
|
||||
}
|
||||
|
||||
function openEditModal(record?: Recordable) {
|
||||
|
||||
if (record && record.contractId) {
|
||||
routerPush({
|
||||
path: '/contract/business/edit/' + record.guid,
|
||||
})
|
||||
} else {
|
||||
routerPush({
|
||||
path: '/contract/business/edit',
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 选中数据 */
|
||||
const selectRow: Recordable = computed(() => {
|
||||
return xGridRef.value?.getRadioRecord() || null
|
||||
})
|
||||
|
||||
/** 单选框选中事件 */
|
||||
const setSelectRow = (row: Recordable) => {
|
||||
if (selectRow.value && selectRow.value[PrimaryKey] === row[PrimaryKey]) {
|
||||
xGridRef.value?.clearRadioRow()
|
||||
} else {
|
||||
xGridRef.value?.setRadioRow(row)
|
||||
}
|
||||
}
|
||||
|
||||
/** 表格单元格单击事件 */
|
||||
function handleCellClick({ row }) {
|
||||
setSelectRow(row)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-col-stretch gap-4px overflow-hidden bg-white px-4 py-2 lt-sm:overflow-auto">
|
||||
<BasicForm @register="register" @submit="handleQuery" @reset="handleReset">
|
||||
<template #money-slot>
|
||||
<NInput placeholder=""></NInput>
|
||||
<span class="mx-1">至</span>
|
||||
<NInput placeholder=""></NInput>
|
||||
</template>
|
||||
</BasicForm>
|
||||
<div class="vxebasic-table-container">
|
||||
<VxeGrid ref="xGridRef" v-bind="gridOptions" @cell-click="handleCellClick">
|
||||
<template #toolbar_buttons>
|
||||
<NSpace>
|
||||
|
||||
<NButton type="primary" :disabled="!selectRow || !selectRow.guid"
|
||||
@click="toDetailPage('business', selectRow.guid)">
|
||||
<template #icon>
|
||||
<icon-mdi-eye />
|
||||
</template>
|
||||
查看
|
||||
</NButton>
|
||||
|
||||
<!-- <NButton type="primary" @click="openEditModal()">
|
||||
<template #icon>
|
||||
<icon-mdi-plus />
|
||||
</template>
|
||||
新增
|
||||
</NButton>
|
||||
|
||||
<NButton type="warning" :disabled="!selectRow || !selectRow[PrimaryKey]" @click="openEditModal(selectRow)">
|
||||
<template #icon>
|
||||
<icon-mdi-square-edit-outline />
|
||||
</template>
|
||||
修改
|
||||
</NButton>
|
||||
|
||||
<NButton type="error" :disabled="!selectRow || !selectRow[PrimaryKey]" @click="handleDelete(selectRow)">
|
||||
<template #icon>
|
||||
<icon-mdi-delete-outline />
|
||||
</template>
|
||||
删除
|
||||
</NButton> -->
|
||||
|
||||
</NSpace>
|
||||
</template>
|
||||
|
||||
<template #radio_cell="{ row, checked }">
|
||||
<span class="text-base" @click.stop="setSelectRow(row)">
|
||||
<icon-mdi-check-circle-outline v-if="checked"></icon-mdi-check-circle-outline>
|
||||
<icon-mdi-checkbox-blank-circle-outline v-else></icon-mdi-checkbox-blank-circle-outline>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #contract-name-slot="{ row }">
|
||||
<NTooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<span class="text-blue hover:underline underline-offset-2 cursor-pointer" @click="openEditModal(row)">{{
|
||||
row.contractName }}</span>
|
||||
</template>
|
||||
<span class=""> {{ row.contractName }}</span>
|
||||
</NTooltip>
|
||||
</template>
|
||||
|
||||
|
||||
</VxeGrid>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,58 @@
|
|||
import type { VxeGridPropTypes } from 'vxe-table';
|
||||
import type { FormSchema } from '@/components/Form';
|
||||
import { useRender } from '@/components/Table';
|
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict';
|
||||
|
||||
export const PrimaryKey = 'guid';
|
||||
|
||||
export function getColumns(_params: any = {}): VxeGridPropTypes.Columns {
|
||||
return [
|
||||
{ type: 'radio', width: 40, slots: { radio: 'radio_cell' }, align: 'center', fixed: 'left' },
|
||||
{ field: 'reportNo', title: '报审序号', width: 100 },
|
||||
{
|
||||
field: 'contractName', title: '合同名称', minWidth: 200, slots: {
|
||||
default: 'contract-name-slot'
|
||||
}
|
||||
},
|
||||
{ field: 'choiceTypeName', title: '选商方式', width: 150 },
|
||||
{ field: 'fundDitchName', title: '资金渠道', width: 150 },
|
||||
{ field: 'contractMoney', title: '金额', width: 100 },
|
||||
{ field: 'priceTypeName', title: '币种', width: 100 },
|
||||
{ field: 'inputPerson', title: '承办人', width: 100 },
|
||||
{ field: 'inputDepartName', title: '承办部门', width: 100 },
|
||||
{ field: 'inputDate', title: '承办时间', width: 130 },
|
||||
];
|
||||
}
|
||||
|
||||
export function getFormSchema(_params: any = {}): FormSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'contractName',
|
||||
component: 'NInput',
|
||||
label: '合同名称',
|
||||
componentProps: { placeholder: "" }
|
||||
},
|
||||
{
|
||||
field: 'inputDepartName',
|
||||
component: 'NInput',
|
||||
label: '承办部门',
|
||||
componentProps: { placeholder: "" }
|
||||
},
|
||||
{
|
||||
field: 'contractMoney',
|
||||
component: 'NInputNumber',
|
||||
label: '合同金额',
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: 'choiceType',
|
||||
component: 'NSelect',
|
||||
label: '选商方式',
|
||||
componentProps: {
|
||||
placeholder: "",
|
||||
options: getDictOptions(DICT_TYPE.contractSelectionMethod)
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted, ref, reactive } from 'vue';
|
||||
import { usePagination, useRequest } from 'alova/client';
|
||||
import { paginationProps } from "@/utils/alova";
|
||||
import { useVxeTable } from '@/hooks/common/vxeTable';
|
||||
import { getDictObj, DICT_TYPE } from '@/utils/dict';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
id: string
|
||||
}>(), {
|
||||
id: '',
|
||||
});
|
||||
|
||||
// 签约依据
|
||||
const { xGridRef, gridProps } = useVxeTable({ ref: 'xGridRef' });
|
||||
|
||||
/** Hooks - 数据请求 合同基本信息 */
|
||||
const { send, data, loading, onSuccess } = useRequest(params =>
|
||||
Apis.ht.get_contractbaseinfo_getone({ params: params }),
|
||||
{ initialData: {}, immediate: false }
|
||||
);
|
||||
onSuccess((data: any) => {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
/** Hooks - 表格 */
|
||||
const gridOptions = reactive(gridProps({
|
||||
maxHeight: '400px',
|
||||
columns: [
|
||||
{ type: 'seq', title: '序号', width: 50, align: 'center' },
|
||||
{ field: 'meetingDate', title: '签约依据名称', width: 150, align: 'center' },
|
||||
{ field: 'meetTheme', title: '签约依据编号', minWidth: 200, slots: { default: 'meetingThemeSlot' }, headerAlign: 'center', align: 'left' },
|
||||
],
|
||||
data: [],
|
||||
pagerConfig: {
|
||||
enabled: false
|
||||
},
|
||||
toolbarConfig: {
|
||||
enabled: false
|
||||
},
|
||||
}));
|
||||
|
||||
// 审批信息
|
||||
const { xGridRef: xGridRef2, triggerProxy: triggerProxy2 } = useVxeTable({ ref: 'xGridRef2' });
|
||||
|
||||
|
||||
/** Hooks - 表格 */
|
||||
const gridOptions2 = reactive(gridProps({
|
||||
maxHeight: '400px',
|
||||
columns: [
|
||||
{ type: 'seq', title: '序号', width: 50, align: 'center' },
|
||||
{ field: 'meetingDate', title: '任务名称', minWidth: 150, align: 'center' },
|
||||
{ field: 'ssfs', title: '送审方式', width: 200, headerAlign: 'center', align: 'left' },
|
||||
{ field: 'spjb', title: '审批级别', width: 150, },
|
||||
{ field: 'spr', title: '审批人', width: 150, },
|
||||
{ field: 'sssj', title: '送审时间', width: 150, },
|
||||
{ field: 'spzt', title: '审批状态', width: 150, },
|
||||
],
|
||||
proxyConfig: {
|
||||
autoLoad: false,
|
||||
ajax: {
|
||||
query: ({ page }) => send({ pageNum: page.currentPage, pageSize: page.pageSize })
|
||||
},
|
||||
},
|
||||
pagerConfig: {
|
||||
enabled: false
|
||||
},
|
||||
toolbarConfig: {
|
||||
enabled: false
|
||||
},
|
||||
}));
|
||||
|
||||
const currData = ref<any>({})
|
||||
|
||||
onMounted(async () => {
|
||||
console.log('立项组件加载')
|
||||
// 加载单条数据
|
||||
send({ guid: props.id })
|
||||
|
||||
// try {
|
||||
// let data = await Apis.ht.get_contractbaseinfo_getone({
|
||||
// params: { guid: props.id }
|
||||
// })
|
||||
// console.log('[ data ] >', data)
|
||||
// } catch (error) {
|
||||
|
||||
// } finally {
|
||||
|
||||
// }
|
||||
|
||||
// triggerProxy2('reload')
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<NSpace vertical>
|
||||
|
||||
<n-spin :show="loading">
|
||||
<NCard title="合同付款" size="small">
|
||||
<NDescriptions bordered size="small" :column="2" label-placement="left" label-class="w-150px">
|
||||
<NDescriptionsItem label="合同名称">
|
||||
{{ data.ctrTypeName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="合同编号">
|
||||
{{ data.contractName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="合同标的金额">
|
||||
{{ data.ctrTwoTypeName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="累计结算金额">
|
||||
{{ data.price }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="本次付款金额">
|
||||
<NInputNumber v-model:value="data.price1"></NInputNumber>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="剩余金额">
|
||||
{{ data.price }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="应付款时间">
|
||||
<NDatePicker type="date"></NDatePicker>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="付款性质">
|
||||
<NSelect></NSelect>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="付款单位">
|
||||
<NInput v-model:value="data.name"></NInput>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="收款单位">
|
||||
<NInput v-model:value="data.name"></NInput>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem label="承办人">{{ data.inputPerson }}</NDescriptionsItem>
|
||||
<NDescriptionsItem label="承办人部门">{{ data.inputDepartName }}</NDescriptionsItem>
|
||||
<NDescriptionsItem label="承办时间">{{ data.inputDate }}</NDescriptionsItem>
|
||||
</NDescriptions>
|
||||
</NCard>
|
||||
</n-spin>
|
||||
|
||||
<NCard title="签约依据信息" size="small">
|
||||
<VxeGrid ref="xGridRef" v-bind="gridOptions">
|
||||
</VxeGrid>
|
||||
</NCard>
|
||||
|
||||
<NCard title="审批信息" size="small">
|
||||
<VxeGrid ref="xGridRef2" v-bind="gridOptions2">
|
||||
</VxeGrid>
|
||||
</NCard>
|
||||
|
||||
</NSpace>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style></style>
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { computed, defineAsyncComponent, onMounted, reactive, ref } from "vue";
|
||||
import { useDialog, useMessage } from "naive-ui";
|
||||
import type { UploadCustomRequestOptions, UploadFileInfo, UploadInst } from "naive-ui";
|
||||
import { useRoute } from "vue-router";
|
||||
|
@ -16,6 +16,11 @@ import { useTabStore } from "@/store/modules/tab";
|
|||
import { FileUploader } from "@/utils/file";
|
||||
import { FileSource } from "@/enums";
|
||||
|
||||
const ContractPayment = defineAsyncComponent(() => import('../components/contract-payment/contract-payment.vue'));
|
||||
const ContractModify = defineAsyncComponent(() => import('../components/contract-modify/contract-modify.vue'));
|
||||
const ContractRelieve = defineAsyncComponent(() => import('../components/contract-relieve/contract-relieve.vue'));
|
||||
const ContractBreak = defineAsyncComponent(() => import('../components/contract-break/contract-break.vue'));
|
||||
|
||||
const { xGridRef, gridProps, triggerProxy } = useVxeTable({ ref: "xGridRef" });
|
||||
|
||||
const PrimaryKey = "guid";
|
||||
|
@ -141,7 +146,7 @@ function handleDownload(file: UploadFileInfo) {
|
|||
/**
|
||||
* 打开选择签约依据弹窗
|
||||
*/
|
||||
async function handleOpenChooseBasisContractModal(status: boolean) {}
|
||||
async function handleOpenChooseBasisContractModal(status: boolean) { }
|
||||
|
||||
/**
|
||||
* 筛选合同列表数据
|
||||
|
@ -254,261 +259,24 @@ function handleBack() {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="flex-col-stretch relative gap-16px overflow-hidden bg-white px-4 py-2 lt-sm:overflow-auto"
|
||||
>
|
||||
<!-- <div>
|
||||
<n-affix
|
||||
class="z-20 w-full bg-white py-1"
|
||||
:trigger-top="10"
|
||||
position="absolute"
|
||||
:listen-to="() => containerRef"
|
||||
>
|
||||
<n-space>
|
||||
<n-button type="primary" size="small" @click="handleSubmit('upload')">
|
||||
<template #icon>
|
||||
<icon-mdi-content-save-outline />
|
||||
</template>
|
||||
保存
|
||||
</n-button>
|
||||
|
||||
<n-button type="primary" size="small" @click="handleSubmit('upload')">
|
||||
<template #icon>
|
||||
<icon-mdi-send />
|
||||
</template>
|
||||
提交
|
||||
</n-button>
|
||||
|
||||
<n-button v-if="id" type="error" size="small">
|
||||
<template #icon>
|
||||
<icon-mdi-delete-outline />
|
||||
</template>
|
||||
删除
|
||||
</n-button>
|
||||
|
||||
<n-button size="small" @click="handleBack()">
|
||||
<template #icon>
|
||||
<icon-mdi-undo-variant />
|
||||
</template>
|
||||
返回
|
||||
</n-button>
|
||||
</n-space>
|
||||
</n-affix>
|
||||
</div> -->
|
||||
<div ref="containerRef"
|
||||
class="flex-col-stretch relative gap-16px overflow-hidden bg-white px-4 py-2 lt-sm:overflow-auto">
|
||||
|
||||
<n-tabs type="card" animated>
|
||||
<n-tab-pane name="1" tab="合同付款"> </n-tab-pane>
|
||||
<n-tab-pane name="2" tab="合同变更"> </n-tab-pane>
|
||||
<n-tab-pane name="3" tab="合同终止(解除)申报"> </n-tab-pane>
|
||||
<n-tab-pane name="4" tab="违约情况申报"> </n-tab-pane>
|
||||
<n-tab-pane name="1" tab="合同付款">
|
||||
<ContractPayment></ContractPayment>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="2" tab="合同变更">
|
||||
<ContractModify></ContractModify>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="3" tab="合同终止(解除)申报">
|
||||
<ContractRelieve></ContractRelieve>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="4" tab="违约情况申报">
|
||||
<ContractBreak></ContractBreak>
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
|
||||
<n-space vertical class="overflow-auto">
|
||||
<!-- <div class="h-20px" /> -->
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>基本信息</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<n-spin :show="loading">
|
||||
<n-descriptions
|
||||
label-placement="left"
|
||||
bordered
|
||||
:column="6"
|
||||
label-class="w-120px!"
|
||||
size="small"
|
||||
>
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
合同名称
|
||||
<span v-if="isRequired('contractName')" class="text-red">*</span>
|
||||
</template>
|
||||
<n-input v-model:value="currData.contractName" placeholder="请输入" />
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
合同类别
|
||||
<span v-if="isRequired('ctrType')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="h-80px overflow-y-auto">
|
||||
<DictTag
|
||||
v-model:value="currData.ctrType"
|
||||
:options="filterContractTypes('-1')"
|
||||
selectable
|
||||
/>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
二级类别
|
||||
<span v-if="isRequired('ctrTwoType')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="h-80px overflow-y-auto">
|
||||
<DictTag
|
||||
v-model:value="currData.ctrTwoType"
|
||||
:options="filterContractTypes(currData.ctrType)"
|
||||
selectable
|
||||
placeholder="请选择二级类别"
|
||||
/>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
资金流向
|
||||
<span v-if="isRequired('fundAllocation')" class="text-red">*</span>
|
||||
</template>
|
||||
<DictTag
|
||||
v-model:value="currData.fundAllocation"
|
||||
:options="getDictOptions(DICT_TYPE.contractFundFlow)"
|
||||
selectable
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
资金渠道
|
||||
<span v-if="isRequired('fundDitch')" class="text-red">*</span>
|
||||
</template>
|
||||
<DictTag
|
||||
v-model:value="currData.fundDitch"
|
||||
:options="getDictOptions(DICT_TYPE.contractFundingSource)"
|
||||
selectable
|
||||
/>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="6">
|
||||
<template #label>
|
||||
组织形式
|
||||
<span v-if="isRequired('organiza')" class="text-red">*</span>
|
||||
</template>
|
||||
<div>
|
||||
<DictTag
|
||||
v-model:value="currData.organiza"
|
||||
:options="getDictOptions(DICT_TYPE.contractOrganizationForm)"
|
||||
selectable
|
||||
/>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="2">
|
||||
<template #label>
|
||||
预算金额
|
||||
<span v-if="isRequired('budgetSum')" class="text-red">*</span>
|
||||
</template>
|
||||
<div class="flex flex-row">
|
||||
<n-input-number
|
||||
v-model:value="currData.budgetSum"
|
||||
class="flex-1"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
<n-select
|
||||
v-model:value="currData.priceType"
|
||||
class="w-100px ml-2"
|
||||
:options="getDictOptions(DICT_TYPE.contractCurrencyUnit)"
|
||||
ceholder="请输入"
|
||||
/>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="2">
|
||||
<template #label> 框架协议 </template>
|
||||
<span v-if="isRequired('frameProtocol')" class="text-red">*</span>
|
||||
<n-radio-group v-model:value="currData.frameProtocol" name="radiogroup1">
|
||||
<n-space>
|
||||
<n-radio :value="1"> 是 </n-radio>
|
||||
<n-radio :value="0"> 否 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-descriptions-item>
|
||||
|
||||
<n-descriptions-item :span="2" label-width="150px">
|
||||
<template #label> 框架协议下的合同 </template>
|
||||
<span v-if="isRequired('frameProtocolCtr')" class="text-red">*</span>
|
||||
<n-radio-group v-model:value="currData.frameProtocolCtr" name="radiogroup2">
|
||||
<n-space>
|
||||
<n-radio :value="1"> 是 </n-radio>
|
||||
<n-radio :value="0"> 否 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>相关资料</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<n-spin :show="loading || addressLoading">
|
||||
<n-descriptions
|
||||
label-placement="left"
|
||||
bordered
|
||||
:column="3"
|
||||
label-class="w-100px"
|
||||
size="small"
|
||||
>
|
||||
<n-descriptions-item :span="3">
|
||||
<template #label> 相关附件 </template>
|
||||
<div>
|
||||
<NUpload
|
||||
ref="uploadRef"
|
||||
directory-dnd
|
||||
multiple
|
||||
:default-file-list="fileUploader.fileList.value"
|
||||
:custom-request="fileUploader.customRequest"
|
||||
show-download-button
|
||||
:default-upload="false"
|
||||
:max="5"
|
||||
@update:file-list="fileUploader.handleFileUpdate"
|
||||
@download="handleDownload"
|
||||
@finish="fileUploader.handleFileUploadFinish"
|
||||
>
|
||||
<n-button>上传文件</n-button>
|
||||
</NUpload>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
|
||||
<n-card size="small">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center">
|
||||
<span>签约依据</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #header-extra>
|
||||
<n-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleOpenChooseBasisContractModal(true)"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-mdi-plus />
|
||||
</template>
|
||||
新增签约依据
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<n-spin :show="loading || addressLoading">
|
||||
<VxeGrid ref="xGridRef" v-bind="gridOptions">
|
||||
<template #toolbar_buttons />
|
||||
<template #operation />
|
||||
</VxeGrid>
|
||||
</n-spin>
|
||||
</n-card>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
Loading…
Reference in New Issue