This commit is contained in:
‘937886381’
2025-12-30 19:36:05 +08:00
parent 7b3873f9ea
commit 20ef2b9763
158 changed files with 3059 additions and 462 deletions

View File

@@ -0,0 +1,340 @@
<template>
<div style="flex: 1">
<Container name="指标填报详情" icon="cockpitItemIcon" size="indicatorDetailsBg" topSize="indicatorDetailsTitleBg">
<div class="kpi-content" style="padding: 14px 14px; display: flex;flex-direction: column; width: 100%;">
<!-- 查询表单区域 -->
<div class="bottom"
style="display: flex;gap: 8px; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);height: 64px;padding: 16px 16px;">
<div style="width: 4px;height: 16px;background: #0B58FF;border-radius: 1px;margin-top: 10px;"></div>
<el-form :inline="true" :model="form" class="demo-form-inline">
<el-form-item label="所属层级">
<el-select v-model="form.levelId" placeholder="请选择">
<el-option v-for="item in levelLList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="填报月份">
<el-date-picker v-model="form.month" type="month" placeholder="选择月" @change="handleMonthChange">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button style="background-color: #0B58FF;" type="primary" @click="onSubmit">查询</el-button>
<!-- <el-button type="primary" plain size="medium">导入</el-button> -->
</el-form-item>
</el-form>
</div>
<!-- 表格操作区域 + 表格区域 -->
<div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);height: 772px;padding: 16px 16px;flex-direction: column; gap: 8px;">
<!-- 只读模式显示编辑按钮 -->
<div v-if="!isDetail" style="display: flex;gap: 8px;align-items: center;height: 32px;">
<div style="width: 4px;height: 16px;background: #0B58FF;border-radius: 1px;"></div>
<div style="width: 58px;
height: 16px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0,0,0,0.85);
line-height: 16px;
text-align: right;
font-style: normal;">指标详情</div>
<el-button style="background-color: #0B58FF;height: 32px;line-height: 10px;" type="primary"
@click="handleEdit">编辑</el-button>
</div>
<!-- 编辑模式显示快捷操作按钮 -->
<div v-if="isDetail" style="display: flex;gap: 8px;align-items: center;height: 32px;">
<div style="width: 4px;height: 16px;background: #0B58FF;border-radius: 1px;"></div>
<div
style="width: 58px;height: 16px;font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 14px;color: rgba(0,0,0,0.85);line-height: 16px;text-align: right;font-style: normal;">
指标详情</div>
<el-button style="background-color: #0B58FF;height: 32px;line-height: 10px;" type="primary"
@click="handleSave">保存</el-button>
<el-button text style="height: 32px;line-height: 10px;" plain size="medium"
@click="handleCancel">取消</el-button>
</div>
<!-- 表格组件添加key属性强制刷新绑定所有必要属性 -->
<base-table style="height: 700px;" @emitFun="inputChange" class="right-aside" :table-props="tableProps"
:page="form.pageNo" :limit="form.pageSize" :table-data="tableData" ref="baseTable"
:key="`base-table-${isDetail}`" :maxHeight="700"
></base-table>
</div>
</div>
</Container>
</div>
</template>
<script>
import Container from './container.vue'
import { getLevelStruc, getRealMonthPage, updateRealMonthData, getDictListData, } from '@/api/cockpit'
import inputArea from './inputArea.vue' // 导入输入组件
export default {
name: 'ProductionStatus',
components: {
Container,
inputArea // 注册输入组件
},
props: {
// 可保留原有props配置若无需求可忽略
},
data() {
return {
form: {
levelId: 1,
pageNo: 1,
pageSize: 100,
month: undefined,
startTime: undefined, // 当月起始时间戳1号00:00:00
endTime: undefined // 当月结束时间戳月末23:59:59
},
dictData:[],
isDetail: false, // 编辑状态标识false=只读true=编辑
tableData: [], // 表格数据
levelLList: [], // 所属层级下拉数据
tableProps: [] // 表格列配置
}
},
watch: {
// 可选监听isDetail变化确保配置同步双重保障
isDetail(newVal) {
this.initTableProps(newVal);
}
},
mounted() {
// 1. 初始化当前月份到日期选择器
const currentDate = new Date();
this.form.month = currentDate;
// 2. 计算当月起止时间戳
this.setMonthTimeStamp();
// 3. 先初始化表格配置(优先于数据请求,避免表格空配置渲染)
this.initTableProps(this.isDetail);
// 4. 等待配置就绪后,再请求数据,避免异步冲突
this.getDictData()
this.$nextTick(() => {
this.getData();
});
},
methods: {
getDictData() {
getDictListData({ pageNo: 1, pageSize: 100, dictType: 'lb_dw' }).then((res) => {
this.dictData = res.data.list
})
},
// 表格单元格数据变更回调
inputChange(val) {
console.log('修改的数据:', val);
// 安全修改:判断索引是否存在,避免数组越界
if (this.tableData[val._pageIndex - 1]) {
this.tableData[val._pageIndex - 1][val.prop] = val[val.prop];
// 标记数据为已修改状态
this.tableData[val._pageIndex - 1].status = 1;
}
},
// 初始化表格列配置核心精准控制inputArea挂载
initTableProps(isEdit) {
console.log('当前编辑状态:', isEdit);
// 基础表格列配置(只读模式使用)
const baseTableProps = [
{ prop: 'type', label: '指标类型', align: 'center' },
{ prop: 'name', label: '指标名称', align: 'center' },
{ prop: 'unitLabel', label: '单位', align: 'center' },
{ prop: 'value', label: '实际值', align: 'center' },
];
if (isEdit) {
// 编辑模式仅给「预估值」列添加inputArea精准挂载避免无效配置
this.tableProps = baseTableProps.map(item => {
if (item.prop === 'value') { // 只给需要编辑的列添加子组件
return {
...item,
subcomponent: inputArea // 挂载输入组件
};
}
return item; // 其他列保持原有配置
});
} else {
// 只读模式:深拷贝基础配置,避免引用污染
this.tableProps = JSON.parse(JSON.stringify(baseTableProps));
}
console.log('表格配置:', this.tableProps);
},
// 切换到编辑模式
handleEdit() {
this.isDetail = true;
// 先更新表格配置,再强制表格刷新(双重保障)
this.initTableProps(this.isDetail);
this.$nextTick(() => {
if (this.$refs.baseTable) {
this.$refs.baseTable.$forceUpdate(); // 强制表格组件刷新
}
});
},
handleSave() {
this.$modal.confirm('是否确认保存数据?').then(() => {
return updateRealMonthData(this.tableData)
}).then(() => {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
});
this.$modal.msgSuccess("保存成功");
}).catch(() => { });
},
// 取消编辑,恢复只读模式
handleCancel() {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
});
console.log('已取消编辑,恢复原始数据');
},
handleClear() {
this.isDetail = false;
// 重置表格配置
this.initTableProps(this.isDetail);
// 清空并重新请求数据,恢复原始状态
this.$nextTick(() => {
this.tableData = [];
this.getData();
});
},
// 通用方法:计算指定月份(默认当前月)的起止时间戳
setMonthTimeStamp(selectDate) {
let targetDate;
if (selectDate) {
targetDate = new Date(selectDate); // 传入选中日期,计算对应月份
} else {
targetDate = new Date(); // 未传入,使用当前系统日期
}
const year = targetDate.getFullYear();
const month = targetDate.getMonth(); // 月份0-11
// 计算当月1号 00:00:00 时间戳
const startDate = new Date(year, month, 1, 0, 0, 0);
this.form.startTime = startDate.getTime();
// 计算当月最后一天 23:59:59 时间戳(精准版)
const lastDay = new Date(year, month + 1, 0).getDate();
const endDatePrecise = new Date(year, month, lastDay, 23, 59, 59);
this.form.endTime = endDatePrecise.getTime();
},
// 日期选择器变更事件:更新对应月份的起止时间戳
handleMonthChange(val) {
if (!val) {
// 清空选择时,重置时间戳
this.form.startTime = undefined;
this.form.endTime = undefined;
return;
}
// 计算选中月份的起止时间戳
this.setMonthTimeStamp(val);
},
getUnitLabel(unitCode) {
// 若字典为空或无匹配编码,返回原编码或空字符串
if (!this.dictData || this.dictData.length === 0) {
return unitCode || '';
}
// 查找匹配的字典项
const matchItem = this.dictData.find(item => item.value == unitCode);
// 返回匹配的label无匹配则返回原unit编码
return matchItem ? matchItem.label : (unitCode || '');
},
// 请求下拉数据和表格数据
getData() {
// 1. 请求所属层级下拉数据
getLevelStruc().then((res) => {
console.log('所属层级数据:', res);
this.levelLList = res.data || [];
}).catch(err => {
console.error('获取所属层级失败:', err);
this.levelLList = [];
});
// 2. 请求表格分页数据
getRealMonthPage({
levelId: this.form.levelId,
startTime: this.form.startTime,
endTime: this.form.endTime,
pageSize: this.form.pageSize,
pageNo: this.form.pageNo
}).then((res) => {
console.log('表格数据:', res);
this.tableData = res.data.map(item => {
// 新增unitLabel字段存储匹配后的显示名称
return {
...item,
unitLabel: this.getUnitLabel(item.unit)
};
});
}).catch(err => {
console.error('获取表格数据失败:', err);
this.tableData = [];
});
},
// 查询按钮点击事件(可根据需求扩展逻辑)
onSubmit() {
// 清空原有表格数据,重新请求
this.tableData = [];
this.$nextTick(() => {
this.getData();
});
}
}
}
</script>
<style lang='scss' scoped>
// 月份列表容器样式(保留原有配置,若无使用可忽略)
.month-list {
// 内联样式已优化行间距,此处可留空或补充
}
// 基础月份样式(保留原有配置,若无使用可忽略)
.monthItem {
width: 164px;
height: 42px;
border-radius: 4px;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 20px;
color: rgba(0, 0, 0, 0.85);
line-height: 42px;
text-align: center;
font-style: normal;
cursor: pointer;
transition: all 0.2s ease;
border: 2px solid transparent;
margin: 0;
}
.monthItem.has-data {
background-color: #D1E8FF;
}
.monthItem:not(.has-data) {
background-color: #EFF3F8;
}
.monthItem.active {
border: 2px solid #0B58FF !important;
}
</style>