明树Git Lab

Commit e91d68aa authored by zhanghan's avatar zhanghan

体系建设 投资规划 开发完毕

parent 7d1f1f9a
<template>
<div class="common-selector-container">
<el-select
v-if="!radio"
v-model="innerValue"
:placeholder="placeholder"
:no-data-text="noDataText"
:disabled="disabled"
style="width: 100%"
@change="handleChange"
>
<el-option
v-for="(item, index) in currentOptions"
:key="`${dictName}-${index}`"
:label="item[labelKey]"
:value="item[valueKey]"
></el-option>
</el-select>
<el-radio-group
v-else
v-model="innerValue"
:disabled="disabled"
@change="handleChange"
class="common-radio-group"
>
<el-radio
v-for="(item, index) in currentOptions"
:key="`${dictName}-${index}`"
:value="item[valueKey]"
>
{{ item[labelKey] }}
</el-radio>
</el-radio-group>
</div>
</template>
<script setup>
import {
ref,
watch,
defineProps,
defineEmits,
onMounted,
onUnmounted,
} from "vue";
// 极简Props:仅传 v-model + dictName(必传),其余可选
const props = defineProps({
// 双向绑定值(必传)
modelValue: {
type: [String, Number, Object],
default: undefined,
},
// 必传:指定从resourceData中取哪个字典(如dqlx/ zdfx-type/ fileHierarchy)
dictName: {
type: String,
required: true,
},
// 可选:自定义选项标签字段(默认name)
labelKey: {
type: String,
default: "name",
},
// 可选:自定义选项值字段(默认key)
valueKey: {
type: String,
default: "key",
},
// 可选:是否切换为单选组(默认false=下拉)
radio: {
type: Boolean,
default: false,
},
// 可选:是否禁用
disabled: {
type: Boolean,
default: false,
},
// 可选:自定义占位符
placeholder: {
type: String,
default: "请选择",
},
// 可选:自定义无数据文本
noDataText: {
type: String,
default: "暂无数据",
},
});
// 事件派发(v-model规范 + 自定义change)
const emit = defineEmits(["update:modelValue", "change"]);
// 内部状态
const innerValue = ref(props.modelValue); // 内部绑定值
const currentOptions = ref([]); // 最终渲染的字典数据
// 核心方法:从sessionStorage读取resourceData并匹配字典
const getDictFromStorage = () => {
try {
// 读取并解析sessionStorage中的resourceData
const resourceStr = sessionStorage.getItem("resourceData") || "{}";
const resourceData = JSON.parse(resourceStr);
// 根据dictName取对应字典,容错:非数组则置空
const targetDict = resourceData[props.dictName] || [];
currentOptions.value = Array.isArray(targetDict) ? targetDict : [];
} catch (e) {
currentOptions.value = [];
console.warn(`【通用选择器】读取${props.dictName}字典失败:`, e);
}
};
// 监听sessionStorage变化(适配resourceData动态更新的场景)
const handleStorageChange = (e) => {
if (e.key === "resourceData") getDictFromStorage();
};
// 初始化+监听
onMounted(() => {
getDictFromStorage(); // 首次加载读取字典
window.addEventListener("storage", handleStorageChange); // 监听storage变化
});
// 销毁时移除监听,避免内存泄漏
onUnmounted(() => {
window.removeEventListener("storage", handleStorageChange);
});
// 监听1:外部v-model值变化,同步到组件内部
watch(
() => props.modelValue,
(newVal) => {
innerValue.value = newVal;
},
{ immediate: true }
);
// 监听2:dictName/labelKey/valueKey变化,重新读取字典(适配动态切换字典的场景)
watch(
() => [props.dictName, props.labelKey, props.valueKey],
() => {
getDictFromStorage();
},
{ deep: true }
);
// 核心:值变化时更新外部v-model
const handleChange = (val) => {
emit("update:modelValue", val);
emit("change", val);
};
</script>
<style scoped lang="less">
.common-selector-container {
width: 100%; // 自适应布局
}
// 单选组间距优化
.common-radio-group {
display: flex;
flex-wrap: wrap;
gap: 16px 32px;
align-items: center;
width: 100%;
}
// 修复下拉选项宽度继承
:deep(.el-select) {
width: 100%;
}
</style>
import { createApp } from 'vue' import { createApp } from "vue";
import './style.css' import "./style.css";
import App from './App.vue' import App from "./App.vue";
import ElementPlus from 'element-plus' import ElementPlus from "element-plus";
import 'element-plus/dist/index.css' import "element-plus/dist/index.css";
import * as ElIcons from '@element-plus/icons' import CommonSelector from "@/components/CommonSelector.vue";
import zhCn from 'element-plus/dist/locale/zh-cn.mjs' import * as ElIcons from "@element-plus/icons";
import router from './router' import zhCn from "element-plus/dist/locale/zh-cn.mjs";
import { createPinia } from 'pinia'; import router from "./router";
import { createPinia } from "pinia";
import "./assets/fonts/font.less"; // 字体样式 import "./assets/fonts/font.less"; // 字体样式
import "../public/iconFont/iconfont.css"; // 图标字体样式 import "../public/iconFont/iconfont.css"; // 图标字体样式
import { $get, $post } from "@/data/https.js"; import { $get, $post } from "@/data/https.js";
import windowConfig from "@/window"; import windowConfig from "@/window";
import moment from "moment"; import moment from "moment";
const pinia = createPinia() const pinia = createPinia();
const app = createApp(App) const app = createApp(App);
app.config.globalProperties.$get = $get; app.config.globalProperties.$get = $get;
app.config.globalProperties.$post = $post; app.config.globalProperties.$post = $post;
app.config.globalProperties.windowConfig = windowConfig; app.config.globalProperties.windowConfig = windowConfig;
app.config.globalProperties.moment = moment; app.config.globalProperties.moment = moment;
for (const [key, component] of Object.entries(ElIcons)) { for (const [key, component] of Object.entries(ElIcons)) {
app.component(key, component) app.component(key, component);
} }
app.use(ElementPlus, {locale: zhCn}).use(router).use(pinia).mount('#app') app.component("CommonSelector", CommonSelector);
app.use(ElementPlus, { locale: zhCn }).use(router).use(pinia).mount("#app");
...@@ -14,30 +14,69 @@ ...@@ -14,30 +14,69 @@
<div class="project-tab-content"> <div class="project-tab-content">
<div class="tab-content"> <div class="tab-content">
<el-form :model="formData" :label-width="200" :disabled="isPreview"> <el-form :model="formData" :label-width="200" :disabled="isPreview">
<el-collapse v-model="activeCollapse">
<!-- 项目信息 -->
<el-collapse-item title="项目信息" name="项目信息">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="文件名称"> <el-form-item label-width="0" required>
<el-input <el-select
v-model="formData.qsmbgbzdw" v-model="formData.projectId"
placeholder="请输入文件名称" placeholder="请选择项目信息"
/> no-data-text="暂无数据"
@change="changeProject"
>
<el-option
v-for="item in projectList"
:key="item.key"
:label="item.projectName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item
title="项目公司自查报告"
name="项目公司自查报告"
>
<el-form-item label-width="0" label="">
<FileUploader v-model="formData.xmgszcbg" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="投资后评价报告" name="投资后评价报告">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label-width="0" label="">
<FileUploader v-model="formData.hpjbg" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="颁布时间"> <el-form-item label="评价时间">
<el-date-picker <el-date-picker
v-model="formData.qsmsj" v-model="formData.hpjsj"
type="datetime" type="datetime"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择颁布时间" placeholder="请选择评价时间"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报告编制单位">
<el-input
v-model="formData.hpjbgbzdw"
placeholder="请输入报告编制单位"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="评审单位"> <el-form-item label="评审单位">
<el-input <el-input
v-model="formData.qsmpsdw" v-model="formData.hpjpsdw"
placeholder="请输入评审单位" placeholder="请输入评审单位"
/> />
</el-form-item> </el-form-item>
...@@ -45,18 +84,75 @@ ...@@ -45,18 +84,75 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="评价结果"> <el-form-item label="评价结果">
<el-input <el-input
v-model="formData.qsmpjjg" v-model="formData.hpjpjjg"
placeholder="请输入评价结果" placeholder="请输入评价结果"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="问题整改" name="问题整改">
<DynamicTable
v-model="formData.tzhpjwtzgs"
:columns="problemColumns"
:default-row="problemDefaultRow"
:select-options="selectOptions"
:show-import-export="true"
export-name="问题整改数据"
:scrollbar-always-on="true"
:disabled="isPreview"
/>
</el-collapse-item>
<el-collapse-item
title="全生命周期评价报告"
name="全生命周期评价报告"
>
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label-width="0" label=""> <el-form-item label-width="0" label="">
<FileUploader v-model="formData.qsmzqpj" /> <FileUploader v-model="formData.qsmzqpj" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item label="评价时间">
<el-date-picker
v-model="formData.qsmsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择评价时间"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报告编制单位">
<el-input
v-model="formData.qsmbgbzdw"
placeholder="请输入报告编制单位"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="评审单位">
<el-input
v-model="formData.qsmpsdw"
placeholder="请输入评审单位"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="评价结果">
<el-input
v-model="formData.qsmpjjg"
placeholder="请输入评价结果"
/>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-collapse-item>
</el-collapse>
</el-form> </el-form>
</div> </div>
</div> </div>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="manage-header"> <div class="manage-header">
<div class="header-left"></div> <div class="header-left"></div>
<div class="header-right"> <div class="header-right">
<el-button type="primary" @click="shareAdd">新增</el-button> <el-button type="primary" @click="investmentAdd">新增</el-button>
</div> </div>
</div> </div>
<div class="manage-content" v-loading="loading"> <div class="manage-content" v-loading="loading">
...@@ -64,39 +64,44 @@ const { proxy } = getCurrentInstance(); ...@@ -64,39 +64,44 @@ const { proxy } = getCurrentInstance();
let tableData = ref([]); let tableData = ref([]);
let tableColumns = ref([ let tableColumns = ref([
{ {
prop: "qc", prop: "itemName",
label: "项目全称", label: "事项名称",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "jc", prop: "itemType",
label: "项目简称", label: "事项类型",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "nbtzglzt", prop: "planYear",
label: "内部投资管理主体", label: "编制年度",
showOverflowTooltip: true,
},
{
prop: "planCycle",
label: "规划周期(年)",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 170,
}, },
{ {
prop: "xmscjd", prop: "planUnit",
label: "项目所处阶段", label: "编制单位",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120,
}, },
{ {
prop: "gqjg", prop: "leadingDepartment",
label: "股权结构", label: "牵头部门",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120,
}, },
{ {
prop: "xmzbjze", prop: "creatorName",
label: "项目资本金总额(亿元)", label: "填报人",
showOverflowTooltip: true,
},
{
prop: "creatorTime",
label: "填报时间",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 180,
}, },
{ {
...@@ -116,13 +121,18 @@ let pageSize = ref(10); ...@@ -116,13 +121,18 @@ let pageSize = ref(10);
const getStatementData = () => { const getStatementData = () => {
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqyglList", url: "/api/project/getTzghList",
data: { data: {
page: currentPage.value, page: currentPage.value,
pagesize: pageSize.value, pagesize: pageSize.value,
}, },
callback: (data) => { callback: (data) => {
tableData.value = data.rows; tableData.value = data.rows.map((it) => {
return {
...it,
fjscLen: it.fjsc?.length + "个",
};
});
total.value = data.count; total.value = data.count;
loading.value = false; loading.value = false;
}, },
...@@ -138,12 +148,12 @@ const handleCurrentPageChange = (page) => { ...@@ -138,12 +148,12 @@ const handleCurrentPageChange = (page) => {
currentPage.value = page; currentPage.value = page;
getStatementData(); getStatementData();
}; };
const shareAdd = () => { const investmentAdd = () => {
router.push("/shareAdd"); router.push("/investmentAdd");
}; };
const editStatement = (item) => { const editStatement = (item) => {
router.push({ router.push({
name: "shareAdd", name: "investmentAdd",
query: { query: {
id: item.id, id: item.id,
}, },
...@@ -151,7 +161,7 @@ const editStatement = (item) => { ...@@ -151,7 +161,7 @@ const editStatement = (item) => {
}; };
const previewStatement = (item) => { const previewStatement = (item) => {
router.push({ router.push({
name: "shareAdd", name: "investmentAdd",
query: { query: {
isPreview: true, isPreview: true,
id: item.id, id: item.id,
...@@ -166,7 +176,7 @@ const deleteStatement = (item) => { ...@@ -166,7 +176,7 @@ const deleteStatement = (item) => {
}) })
.then(() => { .then(() => {
proxy.$post({ proxy.$post({
url: "/api/project/deleteCgqygl", url: "/api/project/deleteTzgh",
data: { data: {
id: item.id, id: item.id,
}, },
...@@ -184,5 +194,5 @@ onMounted(() => { ...@@ -184,5 +194,5 @@ onMounted(() => {
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/styles/manage.less"; @import "@/styles/verticalManages.less";
</style> </style>
...@@ -14,457 +14,111 @@ ...@@ -14,457 +14,111 @@
<div class="project-tab-content"> <div class="project-tab-content">
<div class="tab-content"> <div class="tab-content">
<el-form :model="formData" :label-width="200" :disabled="isPreview"> <el-form :model="formData" :label-width="200" :disabled="isPreview">
<el-collapse v-model="activeCollapse">
<el-collapse-item title="基本信息" name="基本信息">
<el-row :gutter="20"> <el-row :gutter="20">
<!-- 事项名称 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目信息" required> <el-form-item label="事项名称">
<el-select
v-model="formData.projectId"
placeholder="请选择项目信息"
no-data-text="暂无数据"
@change="changeProject"
>
<el-option
v-for="item in projectList"
:key="item.key"
:label="item.projectName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目所处阶段">
<el-select
v-model="formData.xmscjd"
placeholder="请选择项目所处阶段"
>
<el-option
v-for="item in options?.xmjd"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="全称">
<el-input
v-model="formData.qc"
placeholder="请输入全称"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="简称">
<el-input
v-model="formData.jc"
placeholder="请输入简称"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="内部投资管理主体">
<el-input
v-model="formData.nbtzglzt"
placeholder="请输入内部投资管理主体"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="股权结构">
<el-input <el-input
v-model="formData.gqjg" v-model="formData.itemName"
placeholder="请输入股权结构" placeholder="请输入事项名称"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 事项类型 -->
</el-collapse-item>
<el-collapse-item title="出资情况" name="出资情况">
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="事项类型">
label-width="210"
label="项目资本金总额(亿元)"
>
<el-input <el-input
v-model.number="formData.xmzbjze" v-model="formData.itemType"
placeholder="请输入项目资本金总额(亿元)" placeholder="请输入事项类型(如:年度/五年)"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 编制年度 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="编制年度">
label-width="210" <el-date-picker
label="公司资本金应出资总额(亿元)" v-model="formData.planYear"
> type="year"
<el-input format="YYYY"
v-model.number="formData.gszbjyczze" value-format="YYYY"
placeholder="请输入公司资本金应出资总额(亿元)" placeholder="请选择编制年度"
picker-options="{ disabledDate: (date) => date > new Date() }"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 规划周期(年) -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="规划周期(年)">
label-width="210" <el-input-number
label="公司当前应出资额(亿元)" v-model="formData.planCycle"
> placeholder="请输入规划周期"
<el-input :min="1"
v-model.number="formData.gsdqycze" :max="100"
placeholder="请输入公司当前应出资额(亿元)" style="width: 100%"
/> />
<span class="input-tip">单位:年</span>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 编制单位 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="编制单位">
label-width="210"
label="公司当前已出资额(亿元)"
>
<el-input <el-input
v-model.number="formData.gsdqyjcze" v-model="formData.planUnit"
placeholder="请输入公司当前已出资额(亿元)" placeholder="请输入编制单位"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 牵头部门 -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="牵头部门">
label-width="210"
label="公司当前应出未出金额(亿元)"
>
<el-input <el-input
v-model.number="formData.gsdqycwcje" v-model="formData.leadingDepartment"
placeholder="请输入公司当前应出未出金额(亿元)" placeholder="请输入牵头部门"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 填报人 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="填报人">
label-width="210"
label="公司当前剩余出资额(亿元)"
>
<el-input <el-input
v-model.number="formData.gsdqsycze" v-model="formData.creatorName"
placeholder="请输入公司当前剩余出资额(亿元)" placeholder="请输入填报人姓名"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 填报时间 -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label-width="210" label="超股比出资情况"> <el-form-item label="填报时间">
<el-input <el-date-picker
v-model="formData.cgbczqk" v-model="formData.creatorTime"
placeholder="请输入超股比出资情况" type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="请选择填报时间"
picker-options="{ disabledDate: (date) => date > new Date() }"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
</el-collapse-item>
<el-collapse-item <!-- 附件上传区域 - 上级单位投资规划 -->
title="合同约定权益获取"
name="合同约定权益获取"
>
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="我方权益合同条款约定"> <el-form-item label="上级单位投资规划" label-width="200">
<el-input <FileUploader v-model="formData.sjdwtzgh" />
type="textarea"
v-model="formData.wfqyhttkyd"
placeholder="请输入我方权益合同条款约定(市场、设计、施工、运营权、养护份额等权益)"
:rows="3"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 附件上传区域 - 本级单位投资规划 -->
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="权益获取进展"> <el-form-item label="本级单位投资规划" label-width="200">
<el-input <FileUploader v-model="formData.bjdwtzgh" />
type="textarea"
v-model="formData.qyhqjz"
placeholder="请输入权益获取进展"
:rows="3"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="权益获取与约定不一致的情况">
<el-input
type="textarea"
v-model="formData.qyhqyyd"
placeholder="请输入权益获取与约定不一致的情况"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="督办情况">
<el-input
type="textarea"
v-model="formData.dbqk"
placeholder="请输入督办情况"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="分红情况" name="分红情况">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="利润分配/分红约定">
<el-input
v-model="formData.lrfp"
placeholder="请输入利润分配/分红约定"
:rows="2"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否达到利润分配条件">
<el-radio-group
placeholder="请选择是否达到利润分配条件"
v-model="formData.sfddlrfptj"
>
<el-radio
v-for="item in options?.sf"
:key="item.id"
:id="item.name"
:value="item.key"
>{{ item.name }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="累计获取分红(万元)">
<el-input
v-model.number="formData.ljhqfh"
placeholder="请输入累计获取分红(万元)"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="资金流出" name="资金流出">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="应投入资金(万元)">
<el-input
v-model.number="formData.ytrzj"
placeholder="请输入应投入资金(万元)"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="累计投入资金(万元)">
<el-input
v-model.number="formData.ljtrzj"
placeholder="请输入累计投入资金(万元)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="尚需投入资金(万元)">
<el-input
v-model.number="formData.sxtrzj"
placeholder="请输入尚需投入资金(万元)"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="资金流入" name="资金流入">
<div class="tab-handle">
<el-button type="primary" @click="addPfyjlsqk"
>新增</el-button
>
</div>
<el-table
:data="wtyys"
style="width: 100%"
empty-text="暂无数据"
show-summary
:summary-method="sumWtyysColumns"
border
>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="lx" label="类型">
<template #default="scope">
<el-select
v-model="scope.row.lx"
placeholder="请选择"
no-data-text="暂无数据"
>
<el-option
v-for="item in options?.participation_capital"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="fwsj" label="服务时间">
<template #default="scope">
<el-date-picker
v-model="scope.row.fwsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
/>
</template>
</el-table-column>
<el-table-column prop="htje" label="合同金额(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.htje"
placeholder="请输入合同金额(万元)"
/>
</template>
</el-table-column>
<el-table-column prop="ywlr" label="业务利润(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.ywlr"
placeholder="请输入业务利润(万元)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="deletePfyjlsqk(scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="tab-handle">
<el-button type="primary" @click="addTzfhs">新增</el-button>
</div>
<el-table
:data="tzfhs"
style="width: 100%"
empty-text="暂无数据"
show-summary
:summary-method="sumTzfhsColumns"
border
>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="fhsj" label="分红时间">
<template #default="scope">
<el-date-picker
v-model="scope.row.fhsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
/>
</template>
</el-table-column>
<el-table-column prop="fhje" label="分红金额(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.fhje"
placeholder="请输入分红金额"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="deleteTzfhs(scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="subtotal">
<div class="label">流入小计</div>
<div class="value">{{ subtotalNum }}(万元)</div>
</div>
</el-collapse-item>
<el-collapse-item title="净现金流" name="净现金流">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="静态">
<el-input
v-model.number="formData.jt"
placeholder="请输入静态"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="折现(3.5%)">
<el-input
v-model.number="formData.zx"
placeholder="请输入折现(3.5%)"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 附件上传区域 - 其他材料 -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="联系人">
<el-input
v-model="formData.lxr"
placeholder="请输入联系人"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式">
<el-input
v-model="formData.lxfs"
placeholder="请输入联系方式"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="备注"> <el-form-item label="其他材料" label-width="200">
<el-input <FileUploader v-model="formData.qtcl" />
type="textarea"
v-model="formData.bz"
placeholder="请输入备注"
:rows="4"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-collapse-item>
</el-collapse>
</el-form> </el-form>
</div> </div>
</div> </div>
...@@ -474,308 +128,156 @@ ...@@ -474,308 +128,156 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted, getCurrentInstance, h, computed } from "vue"; import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/user.js"; import FileUploader from "../../components/FileUploader/index.vue";
import { number } from "echarts";
// 初始化全局变量 // 路由&全局实例
const userStore = useUserStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const token = ref(
userStore.authToken || sessionStorage.getItem("authToken") || ""
);
// 小记金额 // ========== 核心状态 ==========
const subtotalNum = computed(() => { const loading = ref(false); // 加载状态
let totalHtje = tzfhs.value.reduce((sum, item) => { const isPreview = ref(!!route.query.isPreview); // 是否预览模式
const num = Number(item.fhje) || 0; // 兼容空值/非数字 const rcTzghId = ref(route.query.id || ""); // 投资规划记录ID(匹配表名)
return sum + num; const options = ref({}); // 预留配置项,后续有下拉可扩展
}, 0);
let totalYwlr = wtyys.value.reduce((sum, item) => {
const num = Number(item.ywlr) || 0; // 兼容空值/非数字
return sum + num;
}, 0);
return (totalHtje + totalYwlr).toFixed(2); // ========== 表单核心数据(完全匹配RcTzgh表结构) ==========
});
// 折叠面板默认展开项
const activeCollapse = ref([
"基本信息",
"出资情况",
"合同约定权益获取",
"分红情况",
"资金流入",
"净现金流",
"资金流出",
"分红情况",
]);
// 表单数据
const formData = reactive({ const formData = reactive({
projectName: "", itemName: "", // 事项名称
qc: "", itemType: "", // 事项类型
jc: "", planYear: "", // 编制年度(YYYY格式)
nbtzglzt: "", planCycle: "", // 规划周期(年)
xmscjd: "", planUnit: "", // 编制单位
gqjg: "", leadingDepartment: "", // 牵头部门
xmzbjze: "", creatorName: "", // 填报人
gszbjyczze: "", creatorTime: "", // 填报时间
gsdqycze: "", sjdwtzgh: [], // 上级单位投资规划(附件JSON)
gsdqyjcze: "", bjdwtzgh: [], // 本级单位投资规划(附件JSON)
gsdqycwcje: "", qtcl: [], // 其他材料(附件JSON)
gsdqsycze: "", creator: proxy.$store?.getters?.userId || "", // 创建人ID(从全局状态取,可根据实际调整)
cgbczqk: "", del: 0, // 删除标识,默认正常
wfqyhttkyd: "",
qyhqjz: "",
qyhqyyd: "",
dbqk: "",
lrfp: "",
sfddlrfptj: "",
ljhqfh: "",
ytrzj: "",
ljtrzj: "",
sxtrzj: "",
jt: "",
zx: "",
lxr: "",
lxfs: "",
bz: "",
projectId: "",
del: 0, // del字段保留0默认值(删除标记,0为正常)
createdAt: "",
updatedAt: "",
}); });
let options = ref(); // ========== 接口请求 ==========
// 获取投资规划单条记录详情(编辑/预览时用)
function sumWtyysColumns(param) { const getRcTzghDetail = () => {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = h("div", "合计");
return;
}
const prop = column.property;
if (prop === "lx" || prop === "fwsj" || !prop) {
sums[index] = "";
return;
}
if (prop === "htje") {
const values = data.map((item) => Number(item.htje) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
if (prop === "ywlr") {
const values = data.map((item) => Number(item.ywlr) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
sums[index] = "";
});
return sums;
}
function sumTzfhsColumns(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = h("div", "合计");
return;
}
const prop = column.property;
if (prop === "fhsj" || !prop) {
sums[index] = "";
return;
}
// 分红金额合计
if (prop === "fhje") {
const values = data.map((item) => Number(item.fhje) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
sums[index] = "";
});
return sums;
}
// 加载状态
const loading = ref(false);
// 是否预览模式
const isPreview = ref(!!route.query.isPreview);
// 项目列表数据
const projectList = ref([]);
// 当前编辑的记录ID
const rcCgqyglId = ref(route.query.id || "");
let wtyys = ref([]);
const addPfyjlsqk = () => {
wtyys.value.push({});
};
const deletePfyjlsqk = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
wtyys.value.splice(index, 1);
});
};
let tzfhs = ref([]);
// 新增
const addTzfhs = () => {
tzfhs.value.push({});
};
// 删除
const deleteTzfhs = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
tzfhs.value.splice(index, 1);
});
};
// 获取项目列表
const getProjectData = () => {
proxy.$post({
url: "/api/project/listProject",
data: {
page: 1,
pagesize: 1000,
attributes: [],
menuType: "xmjc",
},
callback: (data) => {
projectList.value = data.rows || [];
},
});
};
// 选择项目后同步项目名称
const changeProject = (val) => {
const selectItem = projectList.value.find((item) => item.id === val);
if (selectItem) {
formData.projectName = selectItem.projectName;
}
};
// 获取单条记录详情(编辑/预览)
const getRcCgqyglDetail = () => {
if (!rcCgqyglId.value) return;
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqygl", url: "/api/project/getTzgh", // 匹配投资规划接口
data: { id: rcCgqyglId.value }, data: { id: rcTzghId.value },
callback: (data) => { callback: (data) => {
loading.value = false; loading.value = false;
Object.assign(formData, { Object.assign(formData, data);
...data, // 处理时间/数字格式,避免渲染报错
}); formData.planYear = data.planYear || "";
if (data.wtyys) { formData.planCycle = Number(data.planCycle) || "";
Object.assign(wtyys.value, data.wtyys); formData.creatorTime = data.creatorTime || "";
} // 附件数组默认值
// 新增:加载 formData.sjdwtzgh = data.sjdwtzgh || [];
if (data.tzfhs) { formData.bjdwtzgh = data.bjdwtzgh || [];
Object.assign(tzfhs.value, data.tzfhs); formData.qtcl = data.qtcl || [];
}
}, },
error: () => (loading.value = false),
}); });
}; };
// ========== 页面操作方法 ==========
// 返回上一页
const backClick = () => { const backClick = () => {
router.back(-1); router.back(-1);
}; };
// 保存/提交表单 // 保存/提交表单(新增/编辑统一处理)
const saveClick = () => { const saveClick = () => {
// 基础校验 // // 简单表单校验
if (!formData.projectId) { // if (!formData.itemName || !formData.itemType || !formData.planYear) {
ElMessage.warning("请选择项目信息"); // ElMessage.warning("请填写必填的事项名称、事项类型、编制年度");
return; // return;
} // }
// if (
// !formData.planCycle ||
// !formData.planUnit ||
// !formData.leadingDepartment
// ) {
// ElMessage.warning("请填写必填的规划周期、编制单位、牵头部门");
// return;
// }
// if (!formData.creatorName || !formData.creatorTime) {
// ElMessage.warning("请填写必填的填报人、填报时间");
// return;
// }
loading.value = true; loading.value = true;
// 区分新增/编辑 // 匹配投资规划的新增/编辑接口
const url = rcCgqyglId.value const url = rcTzghId.value
? "/api/project/updateCgqygl" ? "/api/project/updateTzgh"
: "/api/project/createCgqygl"; : "/api/project/createTzgh";
// 处理空数字字段:空值转为null,避免提交空字符串
const submitData = {
...formData,
projectId: formData.projectId + "",
wtyys: wtyys.value,
tzfhs: tzfhs.value,
};
proxy.$post({ proxy.$post({
url: url, url: url,
data: submitData, data: { ...formData },
callback: (res) => { callback: () => {
loading.value = false; loading.value = false;
ElMessage.success(rcCgqyglId.value ? "编辑成功" : "新增成功"); ElMessage.success(
rcTzghId.value ? "投资规划编辑成功" : "投资规划新增成功"
);
router.back(-1); router.back(-1);
}, },
error: (err) => {
loading.value = false;
ElMessage.error(err.msg || "操作失败,请稍后重试");
},
}); });
}; };
// 页面初始化 // ========== 页面初始化 ==========
onMounted(() => { onMounted(() => {
// 获取项目列表 // 编辑/预览模式,加载投资规划详情数据
getProjectData(); if (rcTzghId.value) {
options.value = JSON.parse(sessionStorage.getItem("resourceData")); getRcTzghDetail();
// 如果有ID则加载详情
if (rcCgqyglId.value) {
getRcCgqyglDetail();
} }
}); });
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/styles/verticalManages.less"; @import "@/styles/verticalManages.less";
// @import "@/styles/manage.less";
.subtotal { .add-project-container {
background-color: #f5f7fa; padding: 20px;
height: 40px; background: #f5f7fa;
min-height: calc(100vh - 60px);
}
.add-project-content {
background: #fff;
border-radius: 4px;
padding: 20px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
}
.add-project-header {
display: flex; display: flex;
.label { justify-content: space-between;
width: 100px; align-items: center;
height: 40px; margin-bottom: 20px;
text-align: center; padding-bottom: 10px;
line-height: 40px; border-bottom: 1px solid #ebeef5;
border-right: 1px solid #ebeef5; }
}
.value { // 表单样式优化
padding-left: 16px; :deep(.el-form-item__label) {
width: 100%; font-weight: 500;
line-height: 40px; }
} // 数字输入框提示文字
.input-tip {
margin-left: 8px;
color: #909399;
font-size: 12px;
}
// 附件上传区域间距
:deep(.el-upload) {
margin-bottom: 10px;
} }
</style> </style>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="manage-header"> <div class="manage-header">
<div class="header-left"></div> <div class="header-left"></div>
<div class="header-right"> <div class="header-right">
<el-button type="primary" @click="shareAdd">新增</el-button> <el-button type="primary" @click="investmentAdd">新增</el-button>
</div> </div>
</div> </div>
<div class="manage-content" v-loading="loading"> <div class="manage-content" v-loading="loading">
...@@ -64,39 +64,44 @@ const { proxy } = getCurrentInstance(); ...@@ -64,39 +64,44 @@ const { proxy } = getCurrentInstance();
let tableData = ref([]); let tableData = ref([]);
let tableColumns = ref([ let tableColumns = ref([
{ {
prop: "qc", prop: "itemName",
label: "项目全称", label: "事项名称",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "jc", prop: "itemType",
label: "项目简称", label: "事项类型",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "nbtzglzt", prop: "planYear",
label: "内部投资管理主体", label: "编制年度",
showOverflowTooltip: true,
},
{
prop: "planCycle",
label: "规划周期(年)",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 170,
}, },
{ {
prop: "xmscjd", prop: "planUnit",
label: "项目所处阶段", label: "编制单位",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120,
}, },
{ {
prop: "gqjg", prop: "leadingDepartment",
label: "股权结构", label: "牵头部门",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120,
}, },
{ {
prop: "xmzbjze", prop: "creatorName",
label: "项目资本金总额(亿元)", label: "填报人",
showOverflowTooltip: true,
},
{
prop: "creatorTime",
label: "填报时间",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 180,
}, },
{ {
...@@ -116,13 +121,18 @@ let pageSize = ref(10); ...@@ -116,13 +121,18 @@ let pageSize = ref(10);
const getStatementData = () => { const getStatementData = () => {
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqyglList", url: "/api/project/getTzghList",
data: { data: {
page: currentPage.value, page: currentPage.value,
pagesize: pageSize.value, pagesize: pageSize.value,
}, },
callback: (data) => { callback: (data) => {
tableData.value = data.rows; tableData.value = data.rows.map((it) => {
return {
...it,
fjscLen: it.fjsc?.length + "个",
};
});
total.value = data.count; total.value = data.count;
loading.value = false; loading.value = false;
}, },
...@@ -138,12 +148,12 @@ const handleCurrentPageChange = (page) => { ...@@ -138,12 +148,12 @@ const handleCurrentPageChange = (page) => {
currentPage.value = page; currentPage.value = page;
getStatementData(); getStatementData();
}; };
const shareAdd = () => { const investmentAdd = () => {
router.push("/shareAdd"); router.push("/investmentAdd");
}; };
const editStatement = (item) => { const editStatement = (item) => {
router.push({ router.push({
name: "shareAdd", name: "investmentAdd",
query: { query: {
id: item.id, id: item.id,
}, },
...@@ -151,7 +161,7 @@ const editStatement = (item) => { ...@@ -151,7 +161,7 @@ const editStatement = (item) => {
}; };
const previewStatement = (item) => { const previewStatement = (item) => {
router.push({ router.push({
name: "shareAdd", name: "investmentAdd",
query: { query: {
isPreview: true, isPreview: true,
id: item.id, id: item.id,
...@@ -166,7 +176,7 @@ const deleteStatement = (item) => { ...@@ -166,7 +176,7 @@ const deleteStatement = (item) => {
}) })
.then(() => { .then(() => {
proxy.$post({ proxy.$post({
url: "/api/project/deleteCgqygl", url: "/api/project/deleteTzgh",
data: { data: {
id: item.id, id: item.id,
}, },
...@@ -184,5 +194,5 @@ onMounted(() => { ...@@ -184,5 +194,5 @@ onMounted(() => {
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/styles/manage.less"; @import "@/styles/verticalManages.less";
</style> </style>
...@@ -14,457 +14,111 @@ ...@@ -14,457 +14,111 @@
<div class="project-tab-content"> <div class="project-tab-content">
<div class="tab-content"> <div class="tab-content">
<el-form :model="formData" :label-width="200" :disabled="isPreview"> <el-form :model="formData" :label-width="200" :disabled="isPreview">
<el-collapse v-model="activeCollapse">
<el-collapse-item title="基本信息" name="基本信息">
<el-row :gutter="20"> <el-row :gutter="20">
<!-- 事项名称 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目信息" required> <el-form-item label="事项名称">
<el-select
v-model="formData.projectId"
placeholder="请选择项目信息"
no-data-text="暂无数据"
@change="changeProject"
>
<el-option
v-for="item in projectList"
:key="item.key"
:label="item.projectName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目所处阶段">
<el-select
v-model="formData.xmscjd"
placeholder="请选择项目所处阶段"
>
<el-option
v-for="item in options?.xmjd"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="全称">
<el-input <el-input
v-model="formData.qc" v-model="formData.itemName"
placeholder="请输入全称" placeholder="请输入事项名称"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 事项类型 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="简称"> <el-form-item label="事项类型">
<el-input <CommonSelector
v-model="formData.jc" :radio="true"
placeholder="请输入简称" v-model="formData.itemType"
dictName="matterType"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 编制年度 -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="内部投资管理主体"> <el-form-item label="编制年度">
<el-input <el-date-picker
v-model="formData.nbtzglzt" v-model="formData.planYear"
placeholder="请输入内部投资管理主体" type="year"
/> format="YYYY"
</el-form-item> value-format="YYYY"
</el-col> placeholder="请选择编制年度"
<el-col :span="12"> picker-options="{ disabledDate: (date) => date > new Date() }"
<el-form-item label="股权结构">
<el-input
v-model="formData.gqjg"
placeholder="请输入股权结构"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="出资情况" name="出资情况">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label-width="210"
label="项目资本金总额(亿元)"
>
<el-input
v-model.number="formData.xmzbjze"
placeholder="请输入项目资本金总额(亿元)"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label-width="210"
label="公司资本金应出资总额(亿元)"
>
<el-input
v-model.number="formData.gszbjyczze"
placeholder="请输入公司资本金应出资总额(亿元)"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 规划周期(年) -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="规划周期(年)">
label-width="210" <el-input-number
label="公司当前应出资额(亿元)" v-model="formData.planCycle"
> placeholder="请输入规划周期"
<el-input :min="1"
v-model.number="formData.gsdqycze" :max="100"
placeholder="请输入公司当前应出资额(亿元)" style="width: 100%"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 编制单位 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="编制单位">
label-width="210"
label="公司当前已出资额(亿元)"
>
<el-input <el-input
v-model.number="formData.gsdqyjcze" v-model="formData.planUnit"
placeholder="请输入公司当前已出资额(亿元)" placeholder="请输入编制单位"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 牵头部门 -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="牵头部门">
label-width="210"
label="公司当前应出未出金额(亿元)"
>
<el-input <el-input
v-model.number="formData.gsdqycwcje" v-model="formData.leadingDepartment"
placeholder="请输入公司当前应出未出金额(亿元)" placeholder="请输入牵头部门"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 填报人 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item label="填报人">
label-width="210"
label="公司当前剩余出资额(亿元)"
>
<el-input <el-input
v-model.number="formData.gsdqsycze" v-model="formData.creatorName"
placeholder="请输入公司当前剩余出资额(亿元)" placeholder="请输入填报人姓名"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 填报时间 -->
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label-width="210" label="超股比出资情况"> <el-form-item label="填报时间">
<el-input <el-date-picker
v-model="formData.cgbczqk" v-model="formData.creatorTime"
placeholder="请输入超股比出资情况" type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="请选择填报时间"
picker-options="{ disabledDate: (date) => date > new Date() }"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
</el-collapse-item>
<el-collapse-item <!-- 附件上传区域 - 上级单位投资规划 -->
title="合同约定权益获取"
name="合同约定权益获取"
>
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="我方权益合同条款约定"> <el-form-item label="上级单位投资规划" label-width="200">
<el-input <FileUploader v-model="formData.sjdwtzgh" />
type="textarea"
v-model="formData.wfqyhttkyd"
placeholder="请输入我方权益合同条款约定(市场、设计、施工、运营权、养护份额等权益)"
:rows="3"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 附件上传区域 - 本级单位投资规划 -->
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="权益获取进展"> <el-form-item label="本级单位投资规划" label-width="200">
<el-input <FileUploader v-model="formData.bjdwtzgh" />
type="textarea"
v-model="formData.qyhqjz"
placeholder="请输入权益获取进展"
:rows="3"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="权益获取与约定不一致的情况">
<el-input
type="textarea"
v-model="formData.qyhqyyd"
placeholder="请输入权益获取与约定不一致的情况"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="督办情况">
<el-input
type="textarea"
v-model="formData.dbqk"
placeholder="请输入督办情况"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="分红情况" name="分红情况">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="利润分配/分红约定">
<el-input
v-model="formData.lrfp"
placeholder="请输入利润分配/分红约定"
:rows="2"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否达到利润分配条件">
<el-radio-group
placeholder="请选择是否达到利润分配条件"
v-model="formData.sfddlrfptj"
>
<el-radio
v-for="item in options?.sf"
:key="item.id"
:id="item.name"
:value="item.key"
>{{ item.name }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="累计获取分红(万元)">
<el-input
v-model.number="formData.ljhqfh"
placeholder="请输入累计获取分红(万元)"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="资金流出" name="资金流出">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="应投入资金(万元)">
<el-input
v-model.number="formData.ytrzj"
placeholder="请输入应投入资金(万元)"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="累计投入资金(万元)">
<el-input
v-model.number="formData.ljtrzj"
placeholder="请输入累计投入资金(万元)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="尚需投入资金(万元)">
<el-input
v-model.number="formData.sxtrzj"
placeholder="请输入尚需投入资金(万元)"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="资金流入" name="资金流入">
<div class="tab-handle">
<el-button type="primary" @click="addPfyjlsqk"
>新增</el-button
>
</div>
<el-table
:data="wtyys"
style="width: 100%"
empty-text="暂无数据"
show-summary
:summary-method="sumWtyysColumns"
border
>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="lx" label="类型">
<template #default="scope">
<el-select
v-model="scope.row.lx"
placeholder="请选择"
no-data-text="暂无数据"
>
<el-option
v-for="item in options?.participation_capital"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="fwsj" label="服务时间">
<template #default="scope">
<el-date-picker
v-model="scope.row.fwsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
/>
</template>
</el-table-column>
<el-table-column prop="htje" label="合同金额(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.htje"
placeholder="请输入合同金额(万元)"
/>
</template>
</el-table-column>
<el-table-column prop="ywlr" label="业务利润(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.ywlr"
placeholder="请输入业务利润(万元)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="deletePfyjlsqk(scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="tab-handle">
<el-button type="primary" @click="addTzfhs">新增</el-button>
</div>
<el-table
:data="tzfhs"
style="width: 100%"
empty-text="暂无数据"
show-summary
:summary-method="sumTzfhsColumns"
border
>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="fhsj" label="分红时间">
<template #default="scope">
<el-date-picker
v-model="scope.row.fhsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
/>
</template>
</el-table-column>
<el-table-column prop="fhje" label="分红金额(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.fhje"
placeholder="请输入分红金额"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="deleteTzfhs(scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="subtotal">
<div class="label">流入小计</div>
<div class="value">{{ subtotalNum }}(万元)</div>
</div>
</el-collapse-item>
<el-collapse-item title="净现金流" name="净现金流">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="静态">
<el-input
v-model.number="formData.jt"
placeholder="请输入静态"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <!-- 附件上传区域 - 其他材料 -->
<el-form-item label="折现(3.5%)">
<el-input
v-model.number="formData.zx"
placeholder="请输入折现(3.5%)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="联系人">
<el-input
v-model="formData.lxr"
placeholder="请输入联系人"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式">
<el-input
v-model="formData.lxfs"
placeholder="请输入联系方式"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="备注"> <el-form-item label="其他材料" label-width="200">
<el-input <FileUploader v-model="formData.qtcl" />
type="textarea"
v-model="formData.bz"
placeholder="请输入备注"
:rows="4"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-collapse-item>
</el-collapse>
</el-form> </el-form>
</div> </div>
</div> </div>
...@@ -474,308 +128,119 @@ ...@@ -474,308 +128,119 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted, getCurrentInstance, h, computed } from "vue"; import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/user.js"; import FileUploader from "../../components/FileUploader/index.vue";
import { number } from "echarts";
// 初始化全局变量 // 路由&全局实例
const userStore = useUserStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const token = ref(
userStore.authToken || sessionStorage.getItem("authToken") || ""
);
// 小记金额 // ========== 核心状态 ==========
const subtotalNum = computed(() => { const loading = ref(false); // 加载状态
let totalHtje = tzfhs.value.reduce((sum, item) => { const isPreview = ref(!!route.query.isPreview); // 是否预览模式
const num = Number(item.fhje) || 0; // 兼容空值/非数字 const rcTzghId = ref(route.query.id || ""); // 投资规划记录ID(匹配表名)
return sum + num; const options = ref({}); // 预留配置项,后续有下拉可扩展
}, 0);
let totalYwlr = wtyys.value.reduce((sum, item) => {
const num = Number(item.ywlr) || 0; // 兼容空值/非数字
return sum + num;
}, 0);
return (totalHtje + totalYwlr).toFixed(2); // ========== 表单核心数据(完全匹配RcTzgh表结构) ==========
});
// 折叠面板默认展开项
const activeCollapse = ref([
"基本信息",
"出资情况",
"合同约定权益获取",
"分红情况",
"资金流入",
"净现金流",
"资金流出",
"分红情况",
]);
// 表单数据
const formData = reactive({ const formData = reactive({
projectName: "", itemName: "", // 事项名称
qc: "", itemType: "", // 事项类型
jc: "", planYear: "", // 编制年度(YYYY格式)
nbtzglzt: "", planCycle: "", // 规划周期(年)
xmscjd: "", planUnit: "", // 编制单位
gqjg: "", leadingDepartment: "", // 牵头部门
xmzbjze: "", creatorName: "", // 填报人
gszbjyczze: "", creatorTime: "", // 填报时间
gsdqycze: "", sjdwtzgh: [], // 上级单位投资规划(附件JSON)
gsdqyjcze: "", bjdwtzgh: [], // 本级单位投资规划(附件JSON)
gsdqycwcje: "", qtcl: [], // 其他材料(附件JSON)
gsdqsycze: "", creator: proxy.$store?.getters?.userId || "", // 创建人ID(从全局状态取,可根据实际调整)
cgbczqk: "", del: 0, // 删除标识,默认正常
wfqyhttkyd: "",
qyhqjz: "",
qyhqyyd: "",
dbqk: "",
lrfp: "",
sfddlrfptj: "",
ljhqfh: "",
ytrzj: "",
ljtrzj: "",
sxtrzj: "",
jt: "",
zx: "",
lxr: "",
lxfs: "",
bz: "",
projectId: "",
del: 0, // del字段保留0默认值(删除标记,0为正常)
createdAt: "",
updatedAt: "",
}); });
let options = ref(); // ========== 接口请求 ==========
// 获取投资规划单条记录详情(编辑/预览时用)
function sumWtyysColumns(param) { const getRcTzghDetail = () => {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = h("div", "合计");
return;
}
const prop = column.property;
if (prop === "lx" || prop === "fwsj" || !prop) {
sums[index] = "";
return;
}
if (prop === "htje") {
const values = data.map((item) => Number(item.htje) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
if (prop === "ywlr") {
const values = data.map((item) => Number(item.ywlr) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
sums[index] = "";
});
return sums;
}
function sumTzfhsColumns(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = h("div", "合计");
return;
}
const prop = column.property;
if (prop === "fhsj" || !prop) {
sums[index] = "";
return;
}
// 分红金额合计
if (prop === "fhje") {
const values = data.map((item) => Number(item.fhje) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
sums[index] = "";
});
return sums;
}
// 加载状态
const loading = ref(false);
// 是否预览模式
const isPreview = ref(!!route.query.isPreview);
// 项目列表数据
const projectList = ref([]);
// 当前编辑的记录ID
const rcCgqyglId = ref(route.query.id || "");
let wtyys = ref([]);
const addPfyjlsqk = () => {
wtyys.value.push({});
};
const deletePfyjlsqk = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
wtyys.value.splice(index, 1);
});
};
let tzfhs = ref([]);
// 新增
const addTzfhs = () => {
tzfhs.value.push({});
};
// 删除
const deleteTzfhs = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
tzfhs.value.splice(index, 1);
});
};
// 获取项目列表
const getProjectData = () => {
proxy.$post({
url: "/api/project/listProject",
data: {
page: 1,
pagesize: 1000,
attributes: [],
menuType: "xmjc",
},
callback: (data) => {
projectList.value = data.rows || [];
},
});
};
// 选择项目后同步项目名称
const changeProject = (val) => {
const selectItem = projectList.value.find((item) => item.id === val);
if (selectItem) {
formData.projectName = selectItem.projectName;
}
};
// 获取单条记录详情(编辑/预览)
const getRcCgqyglDetail = () => {
if (!rcCgqyglId.value) return;
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqygl", url: "/api/project/getTzgh", // 匹配投资规划接口
data: { id: rcCgqyglId.value }, data: { id: rcTzghId.value },
callback: (data) => { callback: (data) => {
loading.value = false; loading.value = false;
Object.assign(formData, { Object.assign(formData, data);
...data, // 处理时间/数字格式,避免渲染报错
}); formData.planYear = data.planYear || "";
if (data.wtyys) { formData.planCycle = Number(data.planCycle) || "";
Object.assign(wtyys.value, data.wtyys); formData.creatorTime = data.creatorTime || "";
} // 附件数组默认值
// 新增:加载 formData.sjdwtzgh = data.sjdwtzgh || [];
if (data.tzfhs) { formData.bjdwtzgh = data.bjdwtzgh || [];
Object.assign(tzfhs.value, data.tzfhs); formData.qtcl = data.qtcl || [];
}
}, },
error: () => (loading.value = false),
}); });
}; };
// ========== 页面操作方法 ==========
// 返回上一页
const backClick = () => { const backClick = () => {
router.back(-1); router.back(-1);
}; };
// 保存/提交表单 // 保存/提交表单(新增/编辑统一处理)
const saveClick = () => { const saveClick = () => {
// 基础校验 // // 简单表单校验
if (!formData.projectId) { // if (!formData.itemName || !formData.itemType || !formData.planYear) {
ElMessage.warning("请选择项目信息"); // ElMessage.warning("请填写必填的事项名称、事项类型、编制年度");
return; // return;
} // }
// if (
// !formData.planCycle ||
// !formData.planUnit ||
// !formData.leadingDepartment
// ) {
// ElMessage.warning("请填写必填的规划周期、编制单位、牵头部门");
// return;
// }
// if (!formData.creatorName || !formData.creatorTime) {
// ElMessage.warning("请填写必填的填报人、填报时间");
// return;
// }
loading.value = true; loading.value = true;
// 区分新增/编辑 // 匹配投资规划的新增/编辑接口
const url = rcCgqyglId.value const url = rcTzghId.value
? "/api/project/updateCgqygl" ? "/api/project/updateTzgh"
: "/api/project/createCgqygl"; : "/api/project/createTzgh";
// 处理空数字字段:空值转为null,避免提交空字符串
const submitData = {
...formData,
projectId: formData.projectId + "",
wtyys: wtyys.value,
tzfhs: tzfhs.value,
};
proxy.$post({ proxy.$post({
url: url, url: url,
data: submitData, data: { ...formData },
callback: (res) => { callback: () => {
loading.value = false; loading.value = false;
ElMessage.success(rcCgqyglId.value ? "编辑成功" : "新增成功"); ElMessage.success(
rcTzghId.value ? "投资规划编辑成功" : "投资规划新增成功"
);
router.back(-1); router.back(-1);
}, },
error: (err) => {
loading.value = false;
ElMessage.error(err.msg || "操作失败,请稍后重试");
},
}); });
}; };
// 页面初始化 // ========== 页面初始化 ==========
onMounted(() => { onMounted(() => {
// 获取项目列表 // 编辑/预览模式,加载投资规划详情数据
getProjectData(); if (rcTzghId.value) {
options.value = JSON.parse(sessionStorage.getItem("resourceData")); getRcTzghDetail();
// 如果有ID则加载详情
if (rcCgqyglId.value) {
getRcCgqyglDetail();
} }
}); });
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/styles/verticalManages.less"; @import "@/styles/verticalManages.less";
// @import "@/styles/manage.less";
.subtotal {
background-color: #f5f7fa;
height: 40px;
display: flex;
.label {
width: 100px;
height: 40px;
text-align: center;
line-height: 40px;
border-right: 1px solid #ebeef5;
}
.value {
padding-left: 16px;
width: 100%;
line-height: 40px;
}
}
</style> </style>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="manage-header"> <div class="manage-header">
<div class="header-left"></div> <div class="header-left"></div>
<div class="header-right"> <div class="header-right">
<el-button type="primary" @click="evaluateAdd">新增</el-button> <el-button type="primary" @click="systemAdd">新增</el-button>
</div> </div>
</div> </div>
<div class="manage-content" v-loading="loading"> <div class="manage-content" v-loading="loading">
...@@ -64,34 +64,29 @@ const { proxy } = getCurrentInstance(); ...@@ -64,34 +64,29 @@ const { proxy } = getCurrentInstance();
let tableData = ref([]); let tableData = ref([]);
let tableColumns = ref([ let tableColumns = ref([
{ {
prop: "projectName", prop: "wjmc",
label: "项目信息",
showOverflowTooltip: true,
},
{
prop: "xmgszcbgLen",
label: "文件名称", label: "文件名称",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "hpjbgLen", prop: "wjcj",
label: "文件层级", label: "文件层级",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "qsmzqpjLen", prop: "wjlb",
label: "文件类别", label: "文件类别",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "附件上传", prop: "fjscLen",
label: "文件类别", label: "附件上传",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "颁布时间", prop: "bbsj",
label: "文件类别", label: "颁布时间",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
...@@ -112,7 +107,7 @@ let pageSize = ref(10); ...@@ -112,7 +107,7 @@ let pageSize = ref(10);
const getStatementData = () => { const getStatementData = () => {
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getTzhpjList", url: "/api/project/getTxjsList",
data: { data: {
page: currentPage.value, page: currentPage.value,
pagesize: pageSize.value, pagesize: pageSize.value,
...@@ -121,10 +116,7 @@ const getStatementData = () => { ...@@ -121,10 +116,7 @@ const getStatementData = () => {
tableData.value = data.rows.map((it) => { tableData.value = data.rows.map((it) => {
return { return {
...it, ...it,
fjscLen: it.fjsc?.length + "个",
xmgszcbgLen: it.xmgszcbg?.length + "个",
hpjbgLen: it.hpjbg?.length + "个",
qsmzqpjLen: it.qsmzqpj?.length + "个",
}; };
}); });
total.value = data.count; total.value = data.count;
...@@ -142,12 +134,12 @@ const handleCurrentPageChange = (page) => { ...@@ -142,12 +134,12 @@ const handleCurrentPageChange = (page) => {
currentPage.value = page; currentPage.value = page;
getStatementData(); getStatementData();
}; };
const evaluateAdd = () => { const systemAdd = () => {
router.push("/evaluateAdd"); router.push("/systemAdd");
}; };
const editStatement = (item) => { const editStatement = (item) => {
router.push({ router.push({
name: "evaluateAdd", name: "systemAdd",
query: { query: {
id: item.id, id: item.id,
}, },
...@@ -155,7 +147,7 @@ const editStatement = (item) => { ...@@ -155,7 +147,7 @@ const editStatement = (item) => {
}; };
const previewStatement = (item) => { const previewStatement = (item) => {
router.push({ router.push({
name: "evaluateAdd", name: "systemAdd",
query: { query: {
isPreview: true, isPreview: true,
id: item.id, id: item.id,
...@@ -170,7 +162,7 @@ const deleteStatement = (item) => { ...@@ -170,7 +162,7 @@ const deleteStatement = (item) => {
}) })
.then(() => { .then(() => {
proxy.$post({ proxy.$post({
url: "/api/project/deleteTzhpj", url: "/api/project/deleteTxjs",
data: { data: {
id: item.id, id: item.id,
}, },
......
...@@ -14,145 +14,62 @@ ...@@ -14,145 +14,62 @@
<div class="project-tab-content"> <div class="project-tab-content">
<div class="tab-content"> <div class="tab-content">
<el-form :model="formData" :label-width="200" :disabled="isPreview"> <el-form :model="formData" :label-width="200" :disabled="isPreview">
<el-collapse v-model="activeCollapse">
<!-- 项目信息 -->
<el-collapse-item title="项目信息" name="项目信息">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label-width="0" required> <el-form-item label="文件名称">
<el-select
v-model="formData.projectId"
placeholder="请选择项目信息"
no-data-text="暂无数据"
@change="changeProject"
>
<el-option
v-for="item in projectList"
:key="item.key"
:label="item.projectName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item
title="项目公司自查报告"
name="项目公司自查报告"
>
<el-form-item label-width="0" label="">
<FileUploader v-model="formData.xmgszcbg" />
</el-form-item>
</el-collapse-item>
<el-collapse-item title="投资后评价报告" name="投资后评价报告">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label-width="0" label="">
<FileUploader v-model="formData.hpjbg" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="评价时间">
<el-date-picker
v-model="formData.hpjsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择评价时间"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报告编制单位">
<el-input <el-input
v-model="formData.hpjbgbzdw" v-model="formData.wjmc"
placeholder="请输入报告编制单位" placeholder="请输入文件名称"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="评审单位"> <el-form-item label="颁布时间">
<el-input
v-model="formData.hpjpsdw"
placeholder="请输入评审单位"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="评价结果">
<el-input
v-model="formData.hpjpjjg"
placeholder="请输入评价结果"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="问题整改" name="问题整改">
<DynamicTable
v-model="formData.tzhpjwtzgs"
:columns="problemColumns"
:default-row="problemDefaultRow"
:select-options="selectOptions"
:show-import-export="true"
export-name="问题整改数据"
:scrollbar-always-on="true"
:disabled="isPreview"
/>
</el-collapse-item>
<el-collapse-item
title="全生命周期评价报告"
name="全生命周期评价报告"
>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label-width="0" label="">
<FileUploader v-model="formData.qsmzqpj" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="评价时间">
<el-date-picker <el-date-picker
v-model="formData.qsmsj" v-model="formData.bbsj"
type="datetime" type="year"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD"
placeholder="请选择评价时间" placeholder="请选择颁布时间"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="报告编制单位"> <el-form-item label="文件层级">
<el-input <el-radio-group
v-model="formData.qsmbgbzdw" v-model="formData.wjcj"
placeholder="请输入报告编制单位" placeholder="请选择文件层级"
/> >
<el-radio
v-for="item in options?.fileHierarchy"
:key="item.id"
:value="item.key"
>{{ item.name }}</el-radio
>
</el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="评审单位"> <el-form-item label="文件类别">
<el-input <el-select
v-model="formData.qsmpsdw" v-model="formData.wjlb"
placeholder="请输入评审单位" placeholder="请选择文件类别"
/> >
<el-option
v-for="item in options?.fileType"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="24">
<el-form-item label="评价结果"> <el-form-item label-width="0" label="">
<el-input <FileUploader v-model="formData.fjsc" />
v-model="formData.qsmpjjg"
placeholder="请输入评价结果"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-collapse-item>
</el-collapse>
</el-form> </el-form>
</div> </div>
</div> </div>
...@@ -164,207 +81,61 @@ ...@@ -164,207 +81,61 @@
<script setup> <script setup>
import { reactive, ref, onMounted, getCurrentInstance } from "vue"; import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage } from "element-plus";
import FileUploader from "../../components/FileUploader/index.vue"; import FileUploader from "../../components/FileUploader/index.vue";
// 引入增强后的DynamicTable组件
import DynamicTable from "../../components/FormDynamicTable/index.vue";
// 初始化全局变量 // 路由&全局实例
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
// 折叠面板默认展开项 // ========== 核心状态 ==========
const activeCollapse = ref([ const loading = ref(false); // 加载状态
"项目信息", const isPreview = ref(!!route.query.isPreview); // 是否预览模式
"项目公司自查报告", const rcCgqyglId = ref(route.query.id || ""); // 当前编辑记录ID
"投资后评价报告", const options = ref({}); // 下拉/单选全局配置项(文件层级/类别)
"问题整改",
"全生命周期评价报告",
]);
// ========== 问题整改表格配置 ==========
// 列配置(包含input、textarea、datetime、radio类型)
const problemColumns = ref([
{
prop: "ccwt",
label: "存在的问题",
type: "input",
placeholder: "请输入存在的问题",
minWidth: 140,
},
{
prop: "wtxs",
label: "问题详述",
type: "textarea",
placeholder: "请输入问题详述",
rows: 2,
minWidth: 140,
},
{
prop: "zgcs",
label: "整改措施",
type: "textarea",
placeholder: "请输入整改措施",
rows: 2,
minWidth: 140,
},
{
prop: "lsqk",
label: "落实情况",
type: "textarea",
placeholder: "请输入落实情况",
rows: 2,
minWidth: 140,
},
{
prop: "zrbm",
label: "责任部门",
type: "input",
placeholder: "请输入责任部门",
minWidth: 140,
},
{
prop: "zrr",
label: "责任人",
type: "input",
placeholder: "请输入责任人",
minWidth: 140,
},
{
prop: "zgqx",
label: "整改期限",
type: "datetime", // 日期时间选择器
placeholder: "请选择整改期限",
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
minWidth: 140,
},
{
prop: "sfgb",
label: "是否关闭",
type: "radio", // 单选框组
optionKey: "sf", // 对应selectOptions中的sf选项
align: "center",
minWidth: 140,
},
]);
// 问题整改默认行数据
const problemDefaultRow = ref({
ccwt: "",
wtxs: "",
zgcs: "",
lsqk: "",
zrbm: "",
zrr: "",
zgqx: "",
sfgb: "",
fjcl: [],
});
// 单选框选项配置
const selectOptions = ref({
sf: [
{ key: 1, name: "是" },
{ key: 2, name: "否" },
],
});
// ========== 表单数据 ========== // ========== 表单核心数据(删除无用数组,仅保留页面绑定的字段) ==========
const formData = reactive({ const formData = reactive({
xmgszcbg: [], wjmc: "", // 文件名称
hpjbg: [], bbsj: "", // 颁布时间
qsmzqpj: [], wjcj: "", // 文件层级
// 问题整改列表(由DynamicTable自动维护) wjlb: "", // 文件类别
tzhpjwtzgs: [], fjsc: [], // 附件上传
}); });
// 加载状态 // ========== 接口请求 ==========
const loading = ref(false); // 获取单条记录详情(编辑/预览时用)
// 是否预览模式
const isPreview = ref(!!route.query.isPreview);
// 项目列表数据
const projectList = ref([]);
// 当前编辑的记录ID
const rcCgqyglId = ref(route.query.id || "");
// ========== 原有方法保留(移除手动新增/删除) ==========
// 获取项目列表
const getProjectData = () => {
proxy.$post({
url: "/api/project/listProject",
data: {
page: 1,
pagesize: 1000,
attributes: [],
menuType: "xmjc",
},
callback: (data) => {
projectList.value = data.rows || [];
},
});
};
// 选择项目后同步项目名称
const changeProject = (val) => {
const selectItem = projectList.value.find((item) => item.id === val);
if (selectItem) {
formData.projectName = selectItem.projectName;
}
};
// 获取单条记录详情
const getJsqtzjcDetail = () => { const getJsqtzjcDetail = () => {
if (!rcCgqyglId.value) return;
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getTzhpjInfo", url: "/api/project/getTxjs",
data: { id: rcCgqyglId.value }, data: { id: rcCgqyglId.value },
callback: (data) => { callback: (data) => {
loading.value = false; loading.value = false;
Object.assign(formData, data); Object.assign(formData, data);
// 确保数组字段有默认值 // 确保附件数组有默认值,避免渲染报错
formData.tzhpjwtzgs = data.tzhpjwtzgs || []; formData.fjsc = data.fjsc || [];
formData.xmgszcbg = data.xmgszcbg || [];
formData.hpjbg = data.hpjbg || [];
formData.qsmzqpj = data.qsmzqpj || [];
// 同步单选选项(如果从接口获取)
if (data.sfOptions) {
selectOptions.value.sf = data.sfOptions;
}
}, },
error: () => (loading.value = false),
}); });
}; };
// ========== 页面操作方法 ==========
// 返回上一页 // 返回上一页
const backClick = () => { const backClick = () => {
router.back(-1); router.back(-1);
}; };
// 保存/提交表单 // 保存/提交表单(新增/编辑统一处理)
const saveClick = () => { const saveClick = () => {
if (!formData.projectId) {
ElMessage.warning("请选择项目信息");
return;
}
loading.value = true; loading.value = true;
const url = rcCgqyglId.value const url = rcCgqyglId.value
? "/api/project/updateTzhpj" ? "/api/project/updateTxjs"
: "/api/project/createTzhpj"; : "/api/project/createTxjs";
const submitData = {
...formData,
projectId: formData.projectId + "",
tzhpjwtzgs: formData.tzhpjwtzgs,
};
proxy.$post({ proxy.$post({
url: url, url: url,
data: submitData, data: { ...formData },
callback: () => { callback: () => {
loading.value = false; loading.value = false;
ElMessage.success(rcCgqyglId.value ? "编辑成功" : "新增成功"); ElMessage.success(rcCgqyglId.value ? "编辑成功" : "新增成功");
...@@ -377,22 +148,16 @@ const saveClick = () => { ...@@ -377,22 +148,16 @@ const saveClick = () => {
}); });
}; };
let options = ref(); // ========== 页面初始化 ==========
// 页面初始化
onMounted(() => { onMounted(() => {
getProjectData(); // 从sessionStorage获取全局配置项(文件层级/类别)
try { try {
options.value = JSON.parse(sessionStorage.getItem("resourceData")) || {}; options.value = JSON.parse(sessionStorage.getItem("resourceData")) || {};
// 合并全局选项到selectOptions
if (options.value.sf) {
selectOptions.value.sf = options.value.sf;
}
} catch (e) { } catch (e) {
options.value = {}; options.value = {};
console.warn("解析resourceData失败:", e); console.warn("解析resourceData失败:", e);
} }
// 编辑/预览模式,加载详情数据
if (rcCgqyglId.value) { if (rcCgqyglId.value) {
getJsqtzjcDetail(); getJsqtzjcDetail();
} }
...@@ -424,21 +189,7 @@ onMounted(() => { ...@@ -424,21 +189,7 @@ onMounted(() => {
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
} }
.tab-handle { // 保留核心样式,删除无用的表格/折叠面板样式(页面未使用)
margin-bottom: 10px;
text-align: left;
}
:deep(.el-table) {
--el-table-header-text-color: #303133;
--el-table-row-hover-bg-color: #f8f9fa;
}
:deep(.el-collapse-item__header) {
font-weight: 600;
font-size: 14px;
}
:deep(.el-form-item__label) { :deep(.el-form-item__label) {
font-weight: 500; font-weight: 500;
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="manage-header"> <div class="manage-header">
<div class="header-left"></div> <div class="header-left"></div>
<div class="header-right"> <div class="header-right">
<el-button type="primary" @click="shareAdd">新增</el-button> <el-button type="primary" @click="vscouncilAdd">新增</el-button>
</div> </div>
</div> </div>
<div class="manage-content" v-loading="loading"> <div class="manage-content" v-loading="loading">
...@@ -64,39 +64,39 @@ const { proxy } = getCurrentInstance(); ...@@ -64,39 +64,39 @@ const { proxy } = getCurrentInstance();
let tableData = ref([]); let tableData = ref([]);
let tableColumns = ref([ let tableColumns = ref([
{ {
prop: "qc", prop: "meetingCode",
label: "项目全称", label: "会议编号",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "jc", prop: "meetingName",
label: "项目简称", label: "会议名称",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "nbtzglzt", prop: "meetingDate",
label: "内部投资管理主体", label: "会议时间",
showOverflowTooltip: true,
},
{
prop: "meetingLocation",
label: "会议地点",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 170,
}, },
{ {
prop: "xmscjd", prop: "attendingLeaders",
label: "项目所处阶段", label: "参会领导",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120,
}, },
{ {
prop: "gqjg", prop: "attendingDepartments",
label: "股权结构", label: "参会部门",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120,
}, },
{ {
prop: "xmzbjze", prop: "meetingMinutesAttachmentLen", // 会议纪要附件数量(表meetingMinutesAttachment数组长度)
label: "项目资本金总额(亿元)", label: "会议纪要",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 180,
}, },
{ {
...@@ -116,13 +116,18 @@ let pageSize = ref(10); ...@@ -116,13 +116,18 @@ let pageSize = ref(10);
const getStatementData = () => { const getStatementData = () => {
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqyglList", url: "/api/project/getTwhglList",
data: { data: {
page: currentPage.value, page: currentPage.value,
pagesize: pageSize.value, pagesize: pageSize.value,
}, },
callback: (data) => { callback: (data) => {
tableData.value = data.rows; tableData.value = data.rows.map((it) => {
return {
...it,
fjscLen: it.fjsc?.length + "个",
};
});
total.value = data.count; total.value = data.count;
loading.value = false; loading.value = false;
}, },
...@@ -138,12 +143,12 @@ const handleCurrentPageChange = (page) => { ...@@ -138,12 +143,12 @@ const handleCurrentPageChange = (page) => {
currentPage.value = page; currentPage.value = page;
getStatementData(); getStatementData();
}; };
const shareAdd = () => { const vscouncilAdd = () => {
router.push("/shareAdd"); router.push("/vscouncilAdd");
}; };
const editStatement = (item) => { const editStatement = (item) => {
router.push({ router.push({
name: "shareAdd", name: "vscouncilAdd",
query: { query: {
id: item.id, id: item.id,
}, },
...@@ -151,7 +156,7 @@ const editStatement = (item) => { ...@@ -151,7 +156,7 @@ const editStatement = (item) => {
}; };
const previewStatement = (item) => { const previewStatement = (item) => {
router.push({ router.push({
name: "shareAdd", name: "vscouncilAdd",
query: { query: {
isPreview: true, isPreview: true,
id: item.id, id: item.id,
...@@ -166,7 +171,7 @@ const deleteStatement = (item) => { ...@@ -166,7 +171,7 @@ const deleteStatement = (item) => {
}) })
.then(() => { .then(() => {
proxy.$post({ proxy.$post({
url: "/api/project/deleteCgqygl", url: "/api/project/deleteTwhgl",
data: { data: {
id: item.id, id: item.id,
}, },
...@@ -184,5 +189,5 @@ onMounted(() => { ...@@ -184,5 +189,5 @@ onMounted(() => {
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/styles/manage.less"; @import "@/styles/verticalManages.less";
</style> </style>
...@@ -14,457 +14,74 @@ ...@@ -14,457 +14,74 @@
<div class="project-tab-content"> <div class="project-tab-content">
<div class="tab-content"> <div class="tab-content">
<el-form :model="formData" :label-width="200" :disabled="isPreview"> <el-form :model="formData" :label-width="200" :disabled="isPreview">
<el-collapse v-model="activeCollapse">
<el-collapse-item title="基本信息" name="基本信息">
<el-row :gutter="20"> <el-row :gutter="20">
<!-- 会议编号(必填、唯一) -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目信息" required> <el-form-item label="会议编号">
<el-select
v-model="formData.projectId"
placeholder="请选择项目信息"
no-data-text="暂无数据"
@change="changeProject"
>
<el-option
v-for="item in projectList"
:key="item.key"
:label="item.projectName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目所处阶段">
<el-select
v-model="formData.xmscjd"
placeholder="请选择项目所处阶段"
>
<el-option
v-for="item in options?.xmjd"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="全称">
<el-input
v-model="formData.qc"
placeholder="请输入全称"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="简称">
<el-input
v-model="formData.jc"
placeholder="请输入简称"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="内部投资管理主体">
<el-input
v-model="formData.nbtzglzt"
placeholder="请输入内部投资管理主体"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="股权结构">
<el-input
v-model="formData.gqjg"
placeholder="请输入股权结构"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="出资情况" name="出资情况">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label-width="210"
label="项目资本金总额(亿元)"
>
<el-input
v-model.number="formData.xmzbjze"
placeholder="请输入项目资本金总额(亿元)"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label-width="210"
label="公司资本金应出资总额(亿元)"
>
<el-input
v-model.number="formData.gszbjyczze"
placeholder="请输入公司资本金应出资总额(亿元)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label-width="210"
label="公司当前应出资额(亿元)"
>
<el-input
v-model.number="formData.gsdqycze"
placeholder="请输入公司当前应出资额(亿元)"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label-width="210"
label="公司当前已出资额(亿元)"
>
<el-input
v-model.number="formData.gsdqyjcze"
placeholder="请输入公司当前已出资额(亿元)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label-width="210"
label="公司当前应出未出金额(亿元)"
>
<el-input
v-model.number="formData.gsdqycwcje"
placeholder="请输入公司当前应出未出金额(亿元)"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label-width="210"
label="公司当前剩余出资额(亿元)"
>
<el-input
v-model.number="formData.gsdqsycze"
placeholder="请输入公司当前剩余出资额(亿元)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label-width="210" label="超股比出资情况">
<el-input
v-model="formData.cgbczqk"
placeholder="请输入超股比出资情况"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item
title="合同约定权益获取"
name="合同约定权益获取"
>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="我方权益合同条款约定">
<el-input
type="textarea"
v-model="formData.wfqyhttkyd"
placeholder="请输入我方权益合同条款约定(市场、设计、施工、运营权、养护份额等权益)"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="权益获取进展">
<el-input
type="textarea"
v-model="formData.qyhqjz"
placeholder="请输入权益获取进展"
:rows="3"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="权益获取与约定不一致的情况">
<el-input
type="textarea"
v-model="formData.qyhqyyd"
placeholder="请输入权益获取与约定不一致的情况"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="督办情况">
<el-input
type="textarea"
v-model="formData.dbqk"
placeholder="请输入督办情况"
:rows="3"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="分红情况" name="分红情况">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="利润分配/分红约定">
<el-input
v-model="formData.lrfp"
placeholder="请输入利润分配/分红约定"
:rows="2"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否达到利润分配条件">
<el-radio-group
placeholder="请选择是否达到利润分配条件"
v-model="formData.sfddlrfptj"
>
<el-radio
v-for="item in options?.sf"
:key="item.id"
:id="item.name"
:value="item.key"
>{{ item.name }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="累计获取分红(万元)">
<el-input <el-input
v-model.number="formData.ljhqfh" v-model="formData.meetingCode"
placeholder="请输入累计获取分红(万元)" placeholder="请输入会议编号(如:TWH202601)"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 会议名称(必填) -->
</el-collapse-item>
<el-collapse-item title="资金流出" name="资金流出">
<el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="应投入资金(万元)"> <el-form-item label="会议名称">
<el-input <el-input
v-model.number="formData.ytrzj" v-model="formData.meetingName"
placeholder="请输入应投入资金(万元)" placeholder="请输入会议名称"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 会议时间(必填) -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="累计投入资金(万元)"> <el-form-item label="会议时间">
<el-input
v-model.number="formData.ljtrzj"
placeholder="请输入累计投入资金(万元)"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="尚需投入资金(万元)">
<el-input
v-model.number="formData.sxtrzj"
placeholder="请输入尚需投入资金(万元)"
/>
</el-form-item>
</el-col>
</el-row>
</el-collapse-item>
<el-collapse-item title="资金流入" name="资金流入">
<div class="tab-handle">
<el-button type="primary" @click="addPfyjlsqk"
>新增</el-button
>
</div>
<el-table
:data="wtyys"
style="width: 100%"
empty-text="暂无数据"
show-summary
:summary-method="sumWtyysColumns"
border
>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="lx" label="类型">
<template #default="scope">
<el-select
v-model="scope.row.lx"
placeholder="请选择"
no-data-text="暂无数据"
>
<el-option
v-for="item in options?.participation_capital"
:key="item.key"
:label="item.name"
:value="item.key"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="fwsj" label="服务时间">
<template #default="scope">
<el-date-picker <el-date-picker
v-model="scope.row.fwsj" v-model="formData.meetingDate"
type="datetime" type="date"
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD"
placeholder="请选择" placeholder="请选择会议时间"
/> picker-options="{ disabledDate: (date) => date > new Date() }"
</template>
</el-table-column>
<el-table-column prop="htje" label="合同金额(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.htje"
placeholder="请输入合同金额(万元)"
/>
</template>
</el-table-column>
<el-table-column prop="ywlr" label="业务利润(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.ywlr"
placeholder="请输入业务利润(万元)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="deletePfyjlsqk(scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="tab-handle">
<el-button type="primary" @click="addTzfhs">新增</el-button>
</div>
<el-table
:data="tzfhs"
style="width: 100%" style="width: 100%"
empty-text="暂无数据"
show-summary
:summary-method="sumTzfhsColumns"
border
>
<el-table-column type="index" width="60" label="序号" />
<el-table-column prop="fhsj" label="分红时间">
<template #default="scope">
<el-date-picker
v-model="scope.row.fhsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
/>
</template>
</el-table-column>
<el-table-column prop="fhje" label="分红金额(万元)">
<template #default="scope">
<el-input
v-model.number="scope.row.fhje"
placeholder="请输入分红金额"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="60">
<template #default="scope">
<el-button
link
type="danger"
size="small"
@click="deleteTzfhs(scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="subtotal">
<div class="label">流入小计</div>
<div class="value">{{ subtotalNum }}(万元)</div>
</div>
</el-collapse-item>
<el-collapse-item title="净现金流" name="净现金流">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="静态">
<el-input
v-model.number="formData.jt"
placeholder="请输入静态"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 会议地点 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="折现(3.5%)"> <el-form-item label="会议地点">
<el-input <el-input
v-model.number="formData.zx" v-model="formData.meetingLocation"
placeholder="请输入折现(3.5%)" placeholder="请输入会议地点"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row>
<el-row :gutter="20"> <!-- 参会领导 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="联系人"> <el-form-item label="参会领导">
<el-input <el-input
v-model="formData.lxr" v-model="formData.attendingLeaders"
placeholder="请输入联系人" placeholder="请输入参会领导"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- 参会部门 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item label="联系方式"> <el-form-item label="参会部门">
<el-input <el-input
v-model="formData.lxfs" v-model="formData.attendingDepartments"
placeholder="请输入联系方式" placeholder="请输入参会部门"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <!-- 会议纪要附件(无需额外处理,组件直接绑定) -->
<el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="备注"> <el-form-item label="会议纪要附件" label-width="200">
<el-input <FileUploader v-model="formData.meetingMinutesAttachment" />
type="textarea"
v-model="formData.bz"
placeholder="请输入备注"
:rows="4"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-collapse-item>
</el-collapse>
</el-form> </el-form>
</div> </div>
</div> </div>
...@@ -474,308 +91,157 @@ ...@@ -474,308 +91,157 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted, getCurrentInstance, h, computed } from "vue"; import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/user.js"; import FileUploader from "../../components/FileUploader/index.vue";
import { number } from "echarts";
// 初始化全局变量 // 路由&全局实例
const userStore = useUserStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const token = ref(
userStore.authToken || sessionStorage.getItem("authToken") || ""
);
// 小记金额 // ========== 核心状态 ==========
const subtotalNum = computed(() => { const loading = ref(false); // 加载状态
let totalHtje = tzfhs.value.reduce((sum, item) => { const isPreview = ref(!!route.query.isPreview); // 是否预览模式
const num = Number(item.fhje) || 0; // 兼容空值/非数字 const rcTwhglId = ref(route.query.id || ""); // 投委会管理记录ID(匹配表名)
return sum + num;
}, 0);
let totalYwlr = wtyys.value.reduce((sum, item) => {
const num = Number(item.ywlr) || 0; // 兼容空值/非数字
return sum + num;
}, 0);
return (totalHtje + totalYwlr).toFixed(2); // 会议层级固定选项(匹配表注释:company-公司级,department-部门级,project-项目级)
}); const meetingLevelOptions = ref([
{ key: "company", label: "公司级" },
// 折叠面板默认展开项 { key: "department", label: "部门级" },
const activeCollapse = ref([ { key: "project", label: "项目级" },
"基本信息",
"出资情况",
"合同约定权益获取",
"分红情况",
"资金流入",
"净现金流",
"资金流出",
"分红情况",
]); ]);
// 表单数据 // ========== 表单核心数据(完全匹配RcTwhgl表结构) ==========
const formData = reactive({ const formData = reactive({
projectName: "", meetingCode: "", // 会议编号(唯一、必填)
qc: "", meetingName: "", // 会议名称(必填)
jc: "", meetingDate: "", // 会议时间(必填)
nbtzglzt: "", meetingLocation: "", // 会议地点
xmscjd: "", attendingLeaders: "", // 参会领导
gqjg: "", attendingDepartments: "", // 参会部门
xmzbjze: "", meetingMinutesAttachment: [], // 会议纪要附件(JSON数组,组件直接绑定)
gszbjyczze: "", projectId: "", // 所属项目ID
gsdqycze: "", creator: proxy.$store?.getters?.userId || "", // 创建人ID(从全局状态取,可调整)
gsdqyjcze: "", del: 0, // 删除标识,默认正常
gsdqycwcje: "",
gsdqsycze: "",
cgbczqk: "",
wfqyhttkyd: "",
qyhqjz: "",
qyhqyyd: "",
dbqk: "",
lrfp: "",
sfddlrfptj: "",
ljhqfh: "",
ytrzj: "",
ljtrzj: "",
sxtrzj: "",
jt: "",
zx: "",
lxr: "",
lxfs: "",
bz: "",
projectId: "",
del: 0, // del字段保留0默认值(删除标记,0为正常)
createdAt: "",
updatedAt: "",
}); });
let options = ref(); // ========== 接口请求 ==========
// 获取投委会管理单条记录详情(编辑/预览时用)
function sumWtyysColumns(param) { const getRcTwhglDetail = () => {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = h("div", "合计");
return;
}
const prop = column.property;
if (prop === "lx" || prop === "fwsj" || !prop) {
sums[index] = "";
return;
}
if (prop === "htje") {
const values = data.map((item) => Number(item.htje) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
if (prop === "ywlr") {
const values = data.map((item) => Number(item.ywlr) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
sums[index] = "";
});
return sums;
}
function sumTzfhsColumns(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = h("div", "合计");
return;
}
const prop = column.property;
if (prop === "fhsj" || !prop) {
sums[index] = "";
return;
}
// 分红金额合计
if (prop === "fhje") {
const values = data.map((item) => Number(item.fhje) || 0);
const total = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = total.toFixed(2) + "(万元)";
return;
}
sums[index] = "";
});
return sums;
}
// 加载状态
const loading = ref(false);
// 是否预览模式
const isPreview = ref(!!route.query.isPreview);
// 项目列表数据
const projectList = ref([]);
// 当前编辑的记录ID
const rcCgqyglId = ref(route.query.id || "");
let wtyys = ref([]);
const addPfyjlsqk = () => {
wtyys.value.push({});
};
const deletePfyjlsqk = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
wtyys.value.splice(index, 1);
});
};
let tzfhs = ref([]);
// 新增
const addTzfhs = () => {
tzfhs.value.push({});
};
// 删除
const deleteTzfhs = (index) => {
ElMessageBox.confirm("确认删除该项?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
tzfhs.value.splice(index, 1);
});
};
// 获取项目列表
const getProjectData = () => {
proxy.$post({
url: "/api/project/listProject",
data: {
page: 1,
pagesize: 1000,
attributes: [],
menuType: "xmjc",
},
callback: (data) => {
projectList.value = data.rows || [];
},
});
};
// 选择项目后同步项目名称
const changeProject = (val) => {
const selectItem = projectList.value.find((item) => item.id === val);
if (selectItem) {
formData.projectName = selectItem.projectName;
}
};
// 获取单条记录详情(编辑/预览)
const getRcCgqyglDetail = () => {
if (!rcCgqyglId.value) return;
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqygl", url: "/api/project/getTwhgl",
data: { id: rcCgqyglId.value }, data: { id: rcTwhglId.value },
callback: (data) => { callback: (data) => {
loading.value = false; loading.value = false;
Object.assign(formData, { Object.assign(formData, data);
...data, // 格式处理&默认值,避免渲染报错
}); formData.projectId = Number(data.projectId) || "";
if (data.wtyys) { formData.meetingDate = data.meetingDate || "";
Object.assign(wtyys.value, data.wtyys); formData.meetingMinutesAttachment = data.meetingMinutesAttachment || [];
}
// 新增:加载
if (data.tzfhs) {
Object.assign(tzfhs.value, data.tzfhs);
}
}, },
error: () => (loading.value = false),
}); });
}; };
// ========== 页面操作方法 ==========
// 返回上一页
const backClick = () => { const backClick = () => {
router.back(-1); router.back(-1);
}; };
// 保存/提交表单 // 保存/提交表单(新增/编辑统一处理)
const saveClick = () => { const saveClick = () => {
// 基础校验 // 核心必填项校验(表中allowNull:false的字段)
if (!formData.projectId) { if (!formData.meetingCode) {
ElMessage.warning("请选择项目信息"); ElMessage.warning("请填写会议编号,编号唯一请勿重复");
return;
}
if (!formData.meetingName) {
ElMessage.warning("请填写会议名称");
return;
}
if (!formData.meetingDate) {
ElMessage.warning("请选择会议时间");
return; return;
} }
loading.value = true; loading.value = true;
// 区分新增/编辑 // 投委会管理专属新增/编辑接口
const url = rcCgqyglId.value const url = rcTwhglId.value
? "/api/project/updateCgqygl" ? "/api/project/updateRcTwhgl"
: "/api/project/createCgqygl"; : "/api/project/createRcTwhgl";
// 处理空数字字段:空值转为null,避免提交空字符串
const submitData = {
...formData,
projectId: formData.projectId + "",
wtyys: wtyys.value,
tzfhs: tzfhs.value,
};
proxy.$post({ proxy.$post({
url: url, url: url,
data: submitData, data: { ...formData },
callback: (res) => { callback: () => {
loading.value = false; loading.value = false;
ElMessage.success(rcCgqyglId.value ? "编辑成功" : "新增成功"); ElMessage.success(
rcTwhglId.value ? "投委会记录编辑成功" : "投委会记录新增成功"
);
router.back(-1); router.back(-1);
}, },
error: (err) => {
loading.value = false;
// 唯一键冲突特殊提示(会议编号重复)
if (err.msg?.includes("unique") || err.msg?.includes("重复")) {
ElMessage.error("会议编号已存在,请更换唯一编号后重试");
} else {
ElMessage.error(err.msg || "操作失败,请稍后重试");
}
},
}); });
}; };
// 页面初始化 // ========== 页面初始化 ==========
onMounted(() => { onMounted(() => {
// 获取项目列表 // 编辑/预览模式,加载投委会管理详情数据
getProjectData(); if (rcTwhglId.value) {
options.value = JSON.parse(sessionStorage.getItem("resourceData")); getRcTwhglDetail();
// 如果有ID则加载详情
if (rcCgqyglId.value) {
getRcCgqyglDetail();
} }
}); });
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/styles/verticalManages.less"; @import "@/styles/verticalManages.less";
// @import "@/styles/manage.less";
.subtotal { .add-project-container {
background-color: #f5f7fa; padding: 20px;
height: 40px; background: #f5f7fa;
min-height: calc(100vh - 60px);
}
.add-project-content {
background: #fff;
border-radius: 4px;
padding: 20px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.04);
}
.add-project-header {
display: flex; display: flex;
.label { justify-content: space-between;
width: 100px; align-items: center;
height: 40px; margin-bottom: 20px;
text-align: center; padding-bottom: 10px;
line-height: 40px; border-bottom: 1px solid #ebeef5;
border-right: 1px solid #ebeef5; }
}
.value { // 表单样式优化
padding-left: 16px; :deep(.el-form-item__label) {
width: 100%; font-weight: 500;
line-height: 40px; }
} // 输入框提示文字
.input-tip {
margin-left: 4px;
color: #f56c6c;
font-size: 12px;
line-height: 1.5;
}
// 附件上传区域间距
:deep(.el-upload) {
margin-bottom: 8px;
} }
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment