明树Git Lab

Commit a172f9f8 authored by zhanghan's avatar zhanghan

运营期投资回收

parent 0f4cf72a
Pipeline #107008 passed with stage
in 19 seconds
<template>
<div class="mixed-table-wrap">
<!-- 调试用:可删除 -->
<!-- {{ tableDataRef }}tableData -->
<el-table
:data="tableDataRef"
style="width: 100%"
border
:cell-style="tableCellStyle"
row-key="serialNumber"
v-if="validConfig"
>
<!-- 序号列:保留原逻辑 -->
<el-table-column
prop="serialNumber"
label="序号"
width="80"
align="center"
/>
<!-- 指标项列(层级缩进):保留原逻辑 -->
<el-table-column
prop="indicatorName"
label="名称"
align="left"
width="260"
>
<template #default="{ row }">
<div style="text-align: left">{{ row.indicatorName }}</div>
</template>
</el-table-column>
<!-- 合计列:文本行隐藏合计值,不显示0.00 → 从内部数据取值 -->
<el-table-column label="合计" width="140" align="right">
<template #default="{ row }">
<span v-if="!row.noTotal">
{{ row.total ? Number(row.total).toFixed(2) : "0.00" }}万元
</span>
<span v-else>&nbsp;</span>
</template>
</el-table-column>
<!-- 动态时间列:改用【处理后的有效时间列表】,保留原条件渲染逻辑 -->
<el-table-column
v-for="time in validDynamicTimeList"
:key="`time-col-${time}`"
:label="time"
width="140"
align="center"
>
<template #default="{ row }">
<!-- 1. 文本行:多行文本输入框,支持字符串 → 绑定内部数据 -->
<el-input
v-if="row.isTextRow"
v-model="row[time]"
type="textarea"
:rows="2"
:disabled="isPreview"
placeholder="请输入说明"
style="width: 100%"
@input="() => handleTextInput(row)"
/>
<!-- 2. 数字行:金额输入框(0+、2位小数)→ 绑定内部数据 -->
<el-input-number
v-else
v-model="row[time]"
:min="0"
:precision="2"
controls-position="right"
:disabled="isPreview"
placeholder="请输入金额"
style="width: 100%"
@change="() => handleFinancialChange(row)"
/>
</template>
</el-table-column>
</el-table>
<!-- 配置不合法提示:保留原逻辑 -->
<div v-else style="text-align: center; padding: 20px; color: #909399">
请传入合法的表格配置(包含indicatorList、dynamicTimeList)
</div>
</div>
</template>
<script setup>
import { ref, computed, watch, nextTick, defineProps, defineEmits } from "vue";
// 1. 重构Props/Emit:对齐参考组件,改用defineProps+defineEmits,隔离v-model循环
// 替代原defineModel,避免对象式v-model的循环更新问题,和参考组件统一
const props = defineProps({
// 核心配置对象:包含indicatorList/dynamicTimeList/tableData
modelValue: {
type: Object,
default: () => ({ indicatorList: [], dynamicTimeList: [], tableData: [] }),
validator: (val) =>
val &&
Array.isArray(val.indicatorList) &&
Array.isArray(val.dynamicTimeList),
},
// 预览模式:保留原配置
isPreview: {
type: Boolean,
default: false,
},
});
// 定义发射事件:双向绑定+业务事件,和参考组件一致
const emit = defineEmits([
"update:modelValue", // v-model双向绑定更新
"handleTableChange", // 自定义业务变化事件(可让父组件监听)
]);
// 2. 核心:创建组件内部响应式数据,完全隔离外部Props → 参考组件核心设计
// 所有数据操作先改内部,再统一发射,避免直接修改Props导致的循环更新
const tableDataRef = ref([]);
// 3. 处理动态时间列表:对齐参考组件,做【去重/去空/trim/兜底】→ 关键健壮性改造
// 解决原组件直接用props中可能的无效时间列(空值/空格/重复)问题
const validDynamicTimeList = computed(() => {
const rawTimeList = props.modelValue.dynamicTimeList || [];
if (!Array.isArray(rawTimeList) || rawTimeList.length === 0) {
// 兜底默认值:保证表格至少有列渲染,不会空白
return ["2025", "2026", "2027"];
}
return [...new Set(rawTimeList)]
.map((time) => (typeof time === "string" ? time.trim() : "")) // 去除隐形空白
.filter((time) => !!time); // 过滤空值
});
// 4. 配置合法性校验:基于【处理后的有效时间列表】重构,更严谨
const validConfig = computed(() => {
const { indicatorList } = props.modelValue;
return (
Array.isArray(indicatorList) &&
indicatorList.length > 0 &&
validDynamicTimeList.value.length > 0
);
});
// 5. 工具方法:初始化行的时间字段 → 对齐参考组件initRowTimeField
// 针对【文本行/数字行】做差异化初始化,避免类型混乱
const initRowTimeField = (row) => {
if (!row || typeof row !== "object") return;
validDynamicTimeList.value.forEach((time) => {
if (row.isTextRow) {
// 文本行:无值则置空字符串,保留原有字符串
row[time] =
row[time] === undefined || row[time] === null ? "" : String(row[time]);
} else {
// 数字行:无值/非数字则置0,确保数字类型
row[time] =
row[time] === undefined ||
row[time] === null ||
isNaN(Number(row[time]))
? 0
: Number(row[time]);
}
});
};
// 6. 工具方法:计算单行合计 → 对齐参考组件calcRowTotal
// 仅数字行生效,自动过滤文本行/非数字,解决浮点精度问题
const calculateRowTotal = (row) => {
if (!row || typeof row !== "object" || row.noTotal || row.isTextRow) return 0;
const total = validDynamicTimeList.value.reduce((sum, time) => {
return sum + (Number(row[time]) || 0);
}, 0);
return Number(total.toFixed(2)); // 保留2位小数,避免0.1+0.2=0.30000000000000004
};
// 7. 核心工具方法:深拷贝+数据处理 → 对齐参考组件handleTableData
// 强制保留所有原有字段,仅【初始化时间字段/计算合计】,避免字段丢失
const handleTableData = (sourceIndicatorList, sourceTableData) => {
if (!validConfig.value) return [];
const newData = [];
sourceIndicatorList.forEach((item, index) => {
const { name, isTextRow = false, noTotal = false } = item;
// 深拷贝源数据行:保留所有原有字段(serialNumber/level/indicatorName等)
const originRow =
sourceTableData.find((row) => row.indicatorName === name) || {};
const rowData = JSON.parse(
JSON.stringify({
serialNumber: index + 1,
level: 0,
indicatorName: name,
isTextRow,
noTotal,
total: 0,
...originRow, // 源数据行覆盖默认值,保留原有配置
}),
);
// 初始化时间字段:差异化处理文本/数字行
initRowTimeField(rowData);
// 计算合计:仅数字行/需要合计的行生效
rowData.total = calculateRowTotal(rowData);
newData.push(rowData);
});
return newData;
};
// 8. 工具方法:数据变化后统一发射 → 对齐参考组件emitDataChange
// 深拷贝后发射,保留所有字段,避免父组件修改影响内部数据,统一发射逻辑
const emitDataChange = (newInnerData) => {
if (props.isPreview) return; // 预览模式不发射
// 深拷贝内部数据,避免引用传递
const emitData = JSON.parse(JSON.stringify(newInnerData));
// 构造父组件需要的完整配置对象,保持原数据结构
const newModelValue = {
...props.modelValue,
tableData: emitData,
};
// 统一发射:双向绑定更新 + 业务事件
emit("update:modelValue", newModelValue);
emit("handleTableChange", newModelValue);
};
// 9. 监听Props变化:同步到内部数据 → 对齐参考组件的watch逻辑
// 仅同步,不发射;nextTick确保有效时间列表先处理完成
watch(
() => props.modelValue,
async (newVal) => {
if (!validConfig.value) return;
await nextTick(); // 等待有效时间列表计算完成
const newTableData = handleTableData(
newVal.indicatorList,
newVal.tableData,
);
tableDataRef.value = newTableData; // 只更新内部数据,不直接修改Props
},
{ deep: true, immediate: true }, // 深度监听+立即执行,组件挂载即初始化
);
// 监听有效时间列表变化:更新内部数据后统一发射 → 对齐参考组件
watch(
() => validDynamicTimeList.value,
() => {
if (!validConfig.value || tableDataRef.value.length === 0) return;
// 重新初始化时间字段+计算合计
tableDataRef.value.forEach((row) => {
initRowTimeField(row);
row.total = calculateRowTotal(row);
});
emitDataChange(tableDataRef.value);
},
{ deep: true, immediate: true },
);
// 10. 数字行输入回调 → 重构,仅更新内部数据,再统一发射
const handleFinancialChange = (currentRow) => {
if (props.isPreview || !currentRow || currentRow.noTotal) return;
currentRow.total = calculateRowTotal(currentRow); // 仅更新内部数据的合计
emitDataChange(tableDataRef.value); // 统一发射所有数据
};
// 11. 文本行输入回调 → 重构,同步内部数据后统一发射(可扩展)
const handleTextInput = (currentRow) => {
if (props.isPreview || !currentRow) return;
emitDataChange(tableDataRef.value); // 文本输入仅同步,统一发射
};
// 12. 表格单元格样式 → 保留原逻辑,微调健壮性
const tableCellStyle = ({ row }) => {
// 合计行高亮
if (row?.isTotal) {
return { background: "#f5f7fa", fontWeight: "bold", textAlign: "right" };
}
// 所有行右对齐,文本行输入框单独左对齐(样式层处理)
return { textAlign: "right" };
};
</script>
<style scoped lang="scss">
// 外层容器:适配滚动,和参考组件样式统一
.mixed-table-wrap {
width: 100%;
box-sizing: border-box;
overflow-x: auto;
}
// 数字输入框样式:对齐参考组件,填满单元格
:deep(.el-input-number) {
width: 100%;
}
:deep(.el-input-number__input) {
text-align: right;
padding-right: 25px;
width: 100% !important;
}
// 文本输入框样式:适配表格,和数字框高度对齐,保留原逻辑
:deep(.el-input__textarea) {
resize: none; // 禁止手动拉伸
text-align: left !important; // 文本左对齐,符合阅读习惯
min-height: 40px !important; // 固定最小高度,和数字框对齐
}
// 表格列头样式:统一对齐,保留原逻辑
:deep(.el-table__header-cell) {
text-align: right !important;
&.el-table__header-cell--align-center {
text-align: center !important;
}
}
// 表格单元格:优化内边距,避免输入框溢出,保留原逻辑
:deep(.el-table__cell) {
padding: 4px 8px !important;
height: 48px !important; // 统一行高,和参考组件一致
vertical-align: middle !important;
}
// 表格行高:统一设置,避免行高混乱
:deep(.el-table__row) {
height: 48px !important;
}
</style>
...@@ -66,40 +66,28 @@ const { proxy } = getCurrentInstance(); ...@@ -66,40 +66,28 @@ const { proxy } = getCurrentInstance();
let tableData = ref([]); let tableData = ref([]);
let tableColumns = ref([ let tableColumns = ref([
{ {
prop: "qc", prop: "projectName",
label: "项目称", label: "项目称",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "jc", prop: "xmgsmc",
label: "项目称", label: "项目公司名称",
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ {
prop: "nbtzglzt", prop: "ssejqy",
label: "内部投资管理主体", label: "所属二级企业",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 170, width: 170,
}, },
{ {
prop: "xmscjd", prop: "xmgsmc",
label: "项目所处阶段", label: "项目公司名称",
showOverflowTooltip: true, showOverflowTooltip: true,
width: 120, width: 120,
}, },
{
prop: "gqjg",
label: "股权结构",
showOverflowTooltip: true,
width: 120,
},
{
prop: "xmzbjze",
label: "项目资本金总额(亿元)",
showOverflowTooltip: true,
width: 180,
},
{ {
prop: "operations", prop: "operations",
......
...@@ -15,10 +15,8 @@ ...@@ -15,10 +15,8 @@
<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 v-model="activeCollapse">
<el-collapse-item title="测试列表" name="测试列表">
</el-collapse-item>
<el-collapse-item title="项目基本信息" name="项目基本信息"> <el-collapse-item title="项目基本信息" name="项目基本信息">
<el-row :gutter="20"> <el-row :gutter="24">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目名称" required> <el-form-item label="项目名称" required>
<el-select <el-select
...@@ -124,7 +122,7 @@ ...@@ -124,7 +122,7 @@
<DynamicTable <DynamicTable
:columns="transferColumns" :columns="transferColumns"
:disabled="isPreview" :disabled="isPreview"
v-model="formData.cgdwczqkxz" v-model="formData.projectGdxxs"
> >
</DynamicTable> </DynamicTable>
</el-collapse-item> </el-collapse-item>
...@@ -318,6 +316,44 @@ ...@@ -318,6 +316,44 @@
</el-col> </el-col>
</el-row> </el-row>
</el-collapse-item> </el-collapse-item>
<el-collapse-item
title="截止12月末累计应收"
name="截止12月末累计应收"
>
<FinancialTable
v-model="formData.jzymljys"
:is-preview="isPreview"
/>
</el-collapse-item>
<el-collapse-item
title="截止12月末累计实收"
name="截止12月末累计实收"
>
<FinancialTable
v-model="formData.jzymljsh"
:is-preview="isPreview"
/>
</el-collapse-item>
<el-collapse-item
title="投资回收(决策)"
name="投资回收(决策)"
>
<FinancialTable
v-model="formData.tzhsjc"
:is-preview="isPreview"
/>
</el-collapse-item>
<el-collapse-item
title="投资回收(计划)"
name="投资回收(计划)"
>
<FinancialTable
v-model="formData.tzhsjh"
:is-preview="isPreview"
/>
</el-collapse-item>
</el-collapse> </el-collapse>
</el-form> </el-form>
</div> </div>
...@@ -330,83 +366,57 @@ ...@@ -330,83 +366,57 @@
<script setup> <script setup>
import { reactive, ref, onMounted, getCurrentInstance, h, computed } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, h, computed } 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 { number } from "echarts";
import DynamicTable from "@/components/FormDynamicTable/index.vue"; import DynamicTable from "@/components/FormDynamicTable/index.vue";
import FinancialTable from "@/components/FinancialTable.vue";
const transferColumns = ref([ const transferColumns = ref([
{ {
prop: "mc", prop: "njfcgbl",
label: "能建方持股比例", label: "能建方持股比例",
type: "textarea", type: "input",
headerGroup: "能建内容", headerGroup: "能建内容",
placeholder: "请填写能建方持股比例", placeholder: "请填写能建方持股比例",
}, },
{ {
prop: "mc", prop: "njfcgblqk",
label: "能建方持股比例情况", label: "能建方持股比例情况",
type: "textarea", type: "input",
headerGroup: "能建内容", headerGroup: "能建内容",
placeholder: "请填写能建方持股比例情况", placeholder: "请填写能建方持股比例情况",
}, },
{ {
prop: "mc", prop: "njfcgblqk_nt",
label: "能建方持股比例情况", label: "能建方持股比例情况",
type: "textarea", type: "input",
headerGroup: "能建以外", headerGroup: "能建以外",
placeholder: "请填写能建方持股比例情况", placeholder: "请填写能建方持股比例情况",
}, },
{ {
prop: "mc", prop: "zwfcgbl",
label: "政府方持股比例", label: "政府方持股比例",
type: "textarea", type: "input",
headerGroup: "能建以外", headerGroup: "能建以外",
placeholder: "请填写政府方持股比例", placeholder: "请填写政府方持股比例",
}, },
{ {
prop: "fj", prop: "jjcgbl",
label: "基金持股比例", label: "基金持股比例",
type: "textarea", type: "input",
headerGroup: "能建以外", headerGroup: "能建以外",
placeholder: "请输入基金持股比例", placeholder: "请输入基金持股比例",
min: 0, min: 0,
}, },
{ {
prop: "bz", prop: "njfglmc",
label: "能建方关联名称", label: "能建方关联名称",
headerGroup: "能建以外", headerGroup: "能建以外",
type: "textarea", type: "textarea",
placeholder: "请输入能建方关联名称", placeholder: "请输入能建方关联名称",
}, },
]); ]);
// 初始化全局变量
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(() => {
let totalHtje = tzfhs.value.reduce((sum, item) => {
const num = Number(item.fhje) || 0; // 兼容空值/非数字
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);
});
// 折叠面板默认展开项 // 折叠面板默认展开项
const activeCollapse = ref([ const activeCollapse = ref([
...@@ -415,116 +425,167 @@ const activeCollapse = ref([ ...@@ -415,116 +425,167 @@ const activeCollapse = ref([
"合同约定权益获取", "合同约定权益获取",
"分红情况", "分红情况",
"投资额完成情况(万元)", "投资额完成情况(万元)",
"投资回收(决策)",
"投资回收(计划)",
"2025年投资回收累计完成情况-年度更新",
"净现金流", "净现金流",
"截止12月末累计应收",
"截止12月末累计实收",
"资金流出", "资金流出",
"分红情况", "分红情况",
]); ]);
// 表单数据 // 表单数据
let initTableData = () => {
Object.assign(formData, {
jzymljys: {
// 指标列表
indicatorList: [
{ name: "政府付费", isTextRow: false, noTotal: false },
{ name: "政府补贴", isTextRow: false, noTotal: false },
{ name: "使用者付费", isTextRow: false, noTotal: false },
{ name: "使用者欠付", isTextRow: false, noTotal: false },
{ name: "补贴收入", isTextRow: false, noTotal: false },
{
name: "销售回款(含房地产、水泥、新能源售电、其他生产制造收入等)",
isTextRow: false,
noTotal: false,
},
{ name: "资产盘活", isTextRow: false, noTotal: false },
{ name: "股权分红", isTextRow: false, noTotal: false },
{ name: "其他", isTextRow: false, noTotal: false },
// 关键:标记为文本行+不需要合计
{ name: "目标(决策)与计划差异说明", isTextRow: true, noTotal: true },
],
// 时间列表(月度)
dynamicTimeList: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
// 表格数据(子组件会自动初始化,父组件可传初始值)
tableData: [],
},
jzymljsh: {
// 指标列表
indicatorList: [
{ name: "政府付费", isTextRow: false, noTotal: false },
{ name: "政府补贴", isTextRow: false, noTotal: false },
{ name: "使用者付费", isTextRow: false, noTotal: false },
{ name: "使用者欠付", isTextRow: false, noTotal: false },
{ name: "补贴收入", isTextRow: false, noTotal: false },
{
name: "销售回款(含房地产、水泥、新能源售电、其他生产制造收入等)",
isTextRow: false,
noTotal: false,
},
{ name: "资产盘活", isTextRow: false, noTotal: false },
{ name: "股权分红", isTextRow: false, noTotal: false },
{ name: "其他", isTextRow: false, noTotal: false },
// 关键:标记为文本行+不需要合计
{ name: "目标(决策)与计划差异说明", isTextRow: true, noTotal: true },
],
// 时间列表(月度)
dynamicTimeList: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
// 表格数据(子组件会自动初始化,父组件可传初始值)
tableData: [],
},
tzhsjc: {
// 指标列表
indicatorList: [
{ name: "建设期政府付费", isTextRow: false, noTotal: false },
{ name: "运营期政府付费", isTextRow: false, noTotal: false },
{ name: "投资价差收取", isTextRow: false, noTotal: false },
{ name: "参股项目投资回收", isTextRow: false, noTotal: false },
{ name: "代建工程款回收", isTextRow: false, noTotal: false },
{ name: "政府付费", isTextRow: false, noTotal: false },
{ name: "政府补贴", isTextRow: false, noTotal: false },
{ name: "使用者付费", isTextRow: false, noTotal: false },
{ name: "使用者欠付", isTextRow: false, noTotal: false },
{ name: "补贴收入", isTextRow: false, noTotal: false },
{
name: "销售回款(含房地产、水泥、新能源售电、其他生产制造收入等)",
isTextRow: false,
noTotal: false,
},
{ name: "资产盘活", isTextRow: false, noTotal: false },
{ name: "股权分红", isTextRow: false, noTotal: false },
{ name: "其他", isTextRow: false, noTotal: false },
// 关键:标记为文本行+不需要合计
{ name: "目标(决策)与计划差异说明", isTextRow: true, noTotal: true },
],
// 时间列表(月度)
dynamicTimeList: ["一季度", "二季度", "三季度", "四季度"],
// 表格数据(子组件会自动初始化,父组件可传初始值)
tableData: [],
},
tzhsjh: {
// 指标列表
indicatorList: [
{ name: "建设期政府付费", isTextRow: false, noTotal: false },
{ name: "运营期政府付费", isTextRow: false, noTotal: false },
{ name: "投资价差收取", isTextRow: false, noTotal: false },
{ name: "参股项目投资回收", isTextRow: false, noTotal: false },
{ name: "代建工程款回收", isTextRow: false, noTotal: false },
{ name: "政府付费", isTextRow: false, noTotal: false },
{ name: "政府补贴", isTextRow: false, noTotal: false },
{ name: "使用者付费", isTextRow: false, noTotal: false },
{ name: "使用者欠付", isTextRow: false, noTotal: false },
{ name: "补贴收入", isTextRow: false, noTotal: false },
{
name: "销售回款(含房地产、水泥、新能源售电、其他生产制造收入等)",
isTextRow: false,
noTotal: false,
},
{ name: "资产盘活", isTextRow: false, noTotal: false },
{ name: "股权分红", isTextRow: false, noTotal: false },
{ name: "其他", isTextRow: false, noTotal: false },
// 关键:标记为文本行+不需要合计
{ name: "目标(决策)与计划差异说明", isTextRow: true, noTotal: true },
],
// 时间列表(月度)
dynamicTimeList: ["一季度", "二季度", "三季度", "四季度"],
// 表格数据(子组件会自动初始化,父组件可传初始值)
tableData: [],
},
});
};
const formData = reactive({ const formData = reactive({
projectName: "", jzymljys: {},
qc: "", jzymljsh: {},
jc: "", tzhsjc: {},
nbtzglzt: "", tzhsjh: {},
xmscjd: "", projectGdxxs: [],
gqjg: "",
xmzbjze: "",
gszbjyczze: "",
gsdqycze: "",
gsdqyjcze: "",
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(); let options = ref();
function sumWtyysColumns(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 === "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 changeProject = (val) => { const changeProject = (val) => {
proxy.$post({ proxy.$post({
...@@ -532,7 +593,16 @@ const changeProject = (val) => { ...@@ -532,7 +593,16 @@ const changeProject = (val) => {
data: { id: val }, data: { id: val },
callback: (data) => { callback: (data) => {
loading.value = false; loading.value = false;
Object.assign(formData, data); // Object.assign(formData, data);
loading.value = false;
formData.projectName = data.projectName || "";
formData.sbdw = data.sbdw || "";
formData.xmgsmc = data.xmgsmc || "";
formData.xmkgsjyj = data.xmkgsjyj || "";
formData.xmjgsjyj = data.xmjgsjyj || "";
formData.xmjd = data.xmjd || "";
formData.yynxn = data.yynxn || "";
formData.xmjsqy = data.xmjsqy || "";
}, },
error: () => { error: () => {
loading.value = false; loading.value = false;
...@@ -551,36 +621,6 @@ const projectList = ref([]); ...@@ -551,36 +621,6 @@ const projectList = ref([]);
// 当前编辑的记录ID // 当前编辑的记录ID
const rcCgqyglId = ref(route.query.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 = () => { const getProjectData = () => {
proxy.$post({ proxy.$post({
...@@ -603,20 +643,15 @@ const getRcCgqyglDetail = () => { ...@@ -603,20 +643,15 @@ const getRcCgqyglDetail = () => {
loading.value = true; loading.value = true;
proxy.$post({ proxy.$post({
url: "/api/project/getCgqygl", url: "/api/project/getYyqtzhsInfo",
data: { id: rcCgqyglId.value }, data: { id: rcCgqyglId.value },
callback: (data) => { callback: (data) => {
loading.value = false; loading.value = false;
console.log(data.jzymljys.tableData[0], "1111");
Object.assign(formData, { Object.assign(formData, {
...data, ...data,
}); });
if (data.wtyys) {
Object.assign(wtyys.value, data.wtyys);
}
// 新增:加载
if (data.tzfhs) {
Object.assign(tzfhs.value, data.tzfhs);
}
}, },
}); });
}; };
...@@ -636,15 +671,13 @@ const saveClick = () => { ...@@ -636,15 +671,13 @@ const saveClick = () => {
loading.value = true; loading.value = true;
// 区分新增/编辑 // 区分新增/编辑
const url = rcCgqyglId.value const url = rcCgqyglId.value
? "/api/project/updateCgqygl" ? "/api/project/updateYyqtzhs"
: "/api/project/createCgqygl"; : "/api/project/createYyqtzhs";
// 处理空数字字段:空值转为null,避免提交空字符串 // 处理空数字字段:空值转为null,避免提交空字符串
const submitData = { const submitData = {
...formData, ...formData,
projectId: formData.projectId + "", projectId: formData.projectId + "",
wtyys: wtyys.value,
tzfhs: tzfhs.value,
}; };
proxy.$post({ proxy.$post({
...@@ -666,6 +699,8 @@ onMounted(() => { ...@@ -666,6 +699,8 @@ onMounted(() => {
// 如果有ID则加载详情 // 如果有ID则加载详情
if (rcCgqyglId.value) { if (rcCgqyglId.value) {
getRcCgqyglDetail(); getRcCgqyglDetail();
} else {
initTableData();
} }
}); });
</script> </script>
......
...@@ -790,6 +790,12 @@ ...@@ -790,6 +790,12 @@
name="项目年度计划表格(单位:万元)" name="项目年度计划表格(单位:万元)"
> >
<div class="annualPlans"> <div class="annualPlans">
{{ formData.xmndjh }}formData.xmndjh
{{ formData.xmndjh }}formData.xmndjh
{{
formData.annualDynamicTimeList
}}formData.annualDynamicTimeList
<annualPlan <annualPlan
v-model="formData.xmndjh" v-model="formData.xmndjh"
:dynamic-time-list="annualDynamicTimeList" :dynamic-time-list="annualDynamicTimeList"
......
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