/*-----------弹窗模块管理------------------- */
<template>
<el-dialog :title="dialogMode === 'create' ? '新建' : dialogMode === 'edit' ? '修改' : '查看'" :visible.sync="dialogVisible"
:modal-append-to-body="true" append-to-body :close-on-click-modal="false" custom-class="fixed-height-dialog"
width="60%" top="5vh">
<el-form label-width="80px" ref="formRef" :model="currentForm" style="height: 100%;
display: flex;
flex-direction: column;" :rules="rules">
<!-- 项目信息区域 -->
<div class="formBorder">
<el-row :gutter="10">
<el-col :span="6">
<el-form-item size="mini" label="项目名称" prop="projectName">
<el-input v-model="currentForm.projectName" clearable style="width:100%" size="mini"
:disabled="dialogMode === 'view'">
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item size="mini" label="项目编号" prop="projectCode">
<el-input v-model="currentForm.projectCode" clearable style="width:100%" size="mini"
:disabled="dialogMode === 'view'">
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item size="mini" label="项目周期" prop="projectDate">
<el-date-picker v-model="projectDate" range-separator="→" start-placeholder="请选择开始日期"
end-placeholder="请选择结束日期" type="daterange" size="mini" style="width: 100%;" unlink-panels
:disabled="dialogMode === 'view'">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item label="负责人" size="mini" style="width:
fit-content;">
<el-input v-model="currentForm.projectUser" clearable style="width:100%" size="mini"
:disabled="dialogMode === 'view'">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="项目概述">
<el-input v-model="currentForm.remark" :rows="2" :disabled="dialogMode === 'view'">
</el-input>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="formBorder2">
<el-container style="height: 100%;">
<el-header style="height: auto;
flex-shrink: 0;
padding-bottom: 10px;">
<el-row :gutter="10" type="flex" class="searchDialog">
<el-col :span="5">
<el-select v-model="filterForm.maintenanceCompanyName" placeholder="请选择管养单位" size="mini" clearable
filterable @clear="resetSearch" :disabled="dialogMode === 'view'">
<el-option v-for="item in MaintenanceUnitoptions" :key="item.value" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="5">
<el-select v-model="filterForm.routeCode" placeholder="请选择路线编号" size="mini" clearable filterable
@clear="resetSearch" :disabled="dialogMode === 'view'">
<el-option v-for="item in routeCodeOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-col>
<el-col :span="5">
<el-input v-model="filterForm.searchKey" placeholder="请输入边坡编号或名称" size="mini" clearable
@keyup.enter.native="searchForm" @clear="resetSearch" :disabled="dialogMode === 'view'">
<i slot="suffix" class="el-input__icon el-icon-search"></i>
</el-input>
</el-col>
<el-col :span="5">
<el-select v-model="filterForm.evaluateLevel" placeholder="请选择技术状态等级" size="mini" clearable
@clear="resetSearch" :disabled="dialogMode === 'view'">
<el-option v-for="item in evaluateLeveloptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-col>
<el-col :span="2" :offset="4">
<el-button type="primary" size="mini" style="width:100%" icon="el-icon-search" @click="searchForm"
:loading="loading" :disabled="dialogMode === 'view'">搜索
</el-button>
</el-col>
</el-row>
</el-header>
<el-main style="overflow-y: hidden;">
<el-table ref="scrollTable" v-loading="loading" style="width: 100%;" border :data="formTabledata"
:row-style="{ height: '36px' }" :cell-style="{ padding: '4px 0', textAlign: 'center' }"
:header-cell-style="{
height: '36px',
padding: '4px 0',
lineHeight: '36px',
textAlign: 'center'
}" @selection-change="handleSelectionChange" :row-key="getRowkey">
<el-table-column type="selection" width="55" :selectable="isRowSelectable" :reserve-selection="true">
</el-table-column>
<el-table-column label="管养单位" prop="maintenanceCompanyName" width="290" show-overflow-tooltip>
</el-table-column>
<el-table-column label="路线编号" prop="routeCode" width="100">
</el-table-column>
<el-table-column label="边坡编号" prop="sideSlopeCode" width="240" show-overflow-tooltip>
</el-table-column>
<el-table-column label="边坡名称" prop="sideSlopeName" width="267" show-overflow-tooltip>
</el-table-column>
<el-table-column label="技术状态等级" width="137">
<template slot-scope="scope">
{{ mapEvaluateLevel(scope.row.evaluateLevel) }}
</template>
</el-table-column>
</el-table>
</el-main>
<!-- 分页区域 -->
<el-footer style="flex-shrink: 0;
padding-top: 10px;">
<el-pagination background @current-change="handleCurrentChange" :current-page="pageParams.pageNo"
:page-size="pageParams.pageSize" layout="total, prev, pager, next" :total="total">
</el-pagination>
</el-footer>
</el-container>
</div>
</el-form>
<!-- 弹窗底部按钮 -->
<div slot="footer" class="dialog-footer" v-if="dialogMode === 'create' || dialogMode === 'edit'">
<el-button @click="dialogVisible = false">取消
</el-button>
<el-button type="primary" @click="submitForm">提交
</el-button>
</div>
</el-dialog>
</template>
<script>
import { mapCfg } from "@/utils";
import {
getPeriodicInspectionSideSlopePageList,
addPeriodicInspection,
modifyPeriodicInspection,
getSelectedPeriodicInspectionSideSlopeList
} from "../../api/testProject";
import { getMaintenanceCompanyList, getRouteList } from "../../api/basicInformation";
export default {
name: "SideSlopeDialog",
props: {
visible: Boolean, // 控制弹窗显示
mode: String, // 模式:create/edit/view
initialForm: Object, // 初始表单数据
},
data() {
return {
isInitializingSelection: false, // 初始化状态标志
dialogVisible: this.visible, // 弹窗显示状态
dialogMode: this.mode, // 当前模式
currentForm: {
projectCode: '', // 项目编号
projectName: '', // 项目名称
projectStartDate: '', // 开始日期
projectEndDate: '', // 结束日期
projectUser: '', // 项目负责人
remark: '', // 备注
sideSlopeDetailList: [] // 边坡详情列表
},
projectDate: [], // 项目日期范围
total: 0, // 总数据量
loading: false, // 加载状态
pageParams: { // 分页参数
pageNo: 1,
pageSize: 10,
},
filterForm: { // 搜索条件
maintenanceCompanyName: "",
routeCode: "",
searchKey: "",
evaluateLevel: "",
},
mulitipleSelection: [],
allSelection: new Map(),
MaintenanceUnitoptions: [], // 管养单位选项
routeCodeOptions: [], // 路线编号选项
formTabledata: [], // 表格数据
evaluateLeveloptions: [], // 技术状态等级选项
rules: { // 表单验证规则
projectName: [
{ required: true, message: "项目名称不能为空", trigger: "blur" },
],
projectCode: [
{ required: true, message: "项目编码不能为空", trigger: "blur" },
],
},
};
},
watch: {
// 修复1:监听visible变化时确保加载数据
async visible(val) {
this.dialogVisible = val;
if (val) {
// 打开对话框时重置状态
this.resetAllData();
// 关键修复:确保在创建模式外加载数据
if (this.dialogMode !== 'create' && this.currentForm.id) {
// 确保在DOM更新后加载数据
await this.$nextTick();
await this.LoadListData();
}
} else {
// 关闭对话框时重置数据
this.resetAllData();
}
},
// 修复2:监听模式变化
mode(val) {
this.dialogMode = val;
// 当模式从创建变为编辑/查看时,确保加载数据
if (this.dialogVisible && val !== 'create' && this.currentForm.id) {
this.LoadListData();
}
},
// 修复3:监听初始表单数据变化
initialForm: {
deep: true,
immediate: true, // 添加立即执行
async handler(val) {
this.currentForm = { ...val };
this.projectDate = [val.projectStartDate, val.projectEndDate];
// 关键修复:当初始表单有ID时立即加载数据
if (this.dialogVisible && val.id && this.dialogMode !== 'create') {
await this.$nextTick();
await this.LoadListData();
}
}
},
// 同步弹窗显示状态到父组件
dialogVisible(val) {
this.$emit("update:visible", val);
},
projectDate: {
deep: true,
handler(value) {
if (value && value.length === 2) {
this.currentForm.projectStartDate = value[0];
this.currentForm.projectEndDate = value[1];
}
},
},
},
async created() {
// 初始化数据
this.getRouteList();
await this.getEvaluateLevel();
this.getMaintenanceCompanyList();
},
methods: {
handleSelectionChange(selection) {
// 跳过初始化阶段的选中状态变更
if (this.isInitializingSelection) return;
// 获取当前页选中项的key集合
const currentPageKeys = new Set(
selection.map(row => row.sideSlopeUniqueCode)
);
// 处理当前页的取消选中操作
this.formTabledata.forEach(row => {
const key = row.sideSlopeUniqueCode;
// 仅当行在全局选中池中但不在当前页选中集合时删除
if (this.allSelection.has(key) && !currentPageKeys.has(key)) {
this.allSelection.delete(key);
}
});
// 添加新选中的项到全局池
selection.forEach(row => {
const key = row.sideSlopeUniqueCode;
if (!this.allSelection.has(key)) {
this.allSelection.set(key, row);
}
});
// 更新当前页选中引用
this.mulitipleSelection = selection;
},
getRowkey(row) {
return row.sideSlopeUniqueCode;
},
// 判断行是否可选(查看模式禁用选择)
isRowSelectable(row, index) {
return this.dialogMode !== "view";
},
// 获取管养单位列表
async getMaintenanceCompanyList() {
const res = await getMaintenanceCompanyList();
this.MaintenanceUnitoptions = res.map((item) => ({
value: item,
label: item,
}));
},
// 获取路线列表
async getRouteList() {
const res = await getRouteList();
this.routeCodeOptions = res.map((item) => ({
value: item.id,
label: item.routeCode,
}));
},
// 搜索方法
searchForm() {
// this.showSelectedOnly = false,
this.pageParams.pageNo = 1;
this.LoadListData();
},
// 重置搜索条件
resetSearch() {
// this.showSelectedOnly = true,
this.filterForm = {
maintenanceCompanyName: "",
routeCode: "",
searchKey: "",
evaluateLevel: "",
};
this.pageParams.pageNo = 1;
this.LoadListData();
},
// 重置组件状态
resetAllData() {
this.resetSelection();
this.formTabledata = []; // 清空表格数据
this.total = 0; // 重置总条数
this.pageParams = { // 重置分页
pageNo: 1,
pageSize: 10
};
// 重置搜索条件(可选)
this.filterForm = {
maintenanceCompanyName: "",
routeCode: "",
searchKey: "",
evaluateLevel: ""
};
},
// 修改原有方法
resetSelection() {
this.allSelection.clear();
this.allSelection = new Map();
if (this.$refs.scrollTable) {
this.$refs.scrollTable.clearSelection();
}
},
// 映射技术状态等级
mapEvaluateLevel(level) {
const option = this.evaluateLeveloptions.find(
(item) => item.value === level
);
return option.label;
},
// 加载表格数据
async LoadListData() {
this.loading = true;
try {
const params = {
orgId: this.filterForm.maintenanceCompanyName,
routeId: this.filterForm.routeCode,
searchKey: this.filterForm.searchKey,
evaluateLevel: this.filterForm.evaluateLevel,
pageSize: this.pageParams.pageSize,
pageNo: this.pageParams.pageNo,
};
// 获取表格数据
const res = await getPeriodicInspectionSideSlopePageList(params);
this.formTabledata = res.entities;
this.total = res.entityCount;
// 处理非创建模式的数据加载
if (this.dialogMode !== 'create' && this.currentForm.id) {
// 首次加载时获取所有选中项
if (this.pageParams.pageNo === 1) {
const selected = await getSelectedPeriodicInspectionSideSlopeList({
periodicId: this.currentForm.id,
pageSize: 10000, // 获取所有选中项
pageNo: 1
});
// 重置全局选中池
this.allSelection.clear();
this.mulitipleSelection = selected.entities;
// 存储全局选中状态
this.mulitipleSelection.forEach(item => {
this.allSelection.set(item.sideSlopeUniqueCode, item);
});
}
// 设置当前页选中状态
this.isInitializingSelection = true;
this.$nextTick(() => {
this.formTabledata.forEach(row => {
if (this.allSelection.has(row.sideSlopeUniqueCode)) {
this.$refs.scrollTable.toggleRowSelection(row, true);
}
});
this.isInitializingSelection = false;
});
}
} catch (error) {
console.error("加载数据失败:", error);
this.$message.error("加载数据失败");
} finally {
this.loading = false;
}
},
// 当前页码变化
handleCurrentChange(val) {
this.pageParams.pageNo = val;
this.LoadListData();
},
// 获取技术状态等级选项
async getEvaluateLevel() {
const levelList = await mapCfg("Inspection.Regular.RegularEvaluateLevel")();
this.evaluateLeveloptions = levelList.map((item) => ({
value: item.key,
label: item.value,
}));
},
// 提交表单
async submitForm() {
this.$refs.formRef.validate(async (valid) => {
if (valid) {
// 验证是否选择了边坡
const selectedItems = Array.from(this.allSelection.values());
if (this.allSelection.size === 0) {
this.$message.warning("请至少选择一个边坡");
return;
}
// 构造提交参数
const params = {
...this.currentForm,
sideSlopeDetailList: selectedItems.map(item => ({
sideSlopeUniqueCode: item.sideSlopeUniqueCode,
evaluateLevel: item.evaluateLevel,
evaluateDate: item.evaluateDate || undefined
})),
};
// 根据模式选择操作
const action = this.dialogMode === "create"
? addPeriodicInspection
: modifyPeriodicInspection;
// 执行操作
try {
const success = await action(params);
if (success) {
this.$message.success(
this.dialogMode === "create" ? "新建成功" : "修改成功"
);
this.$refs.scrollTable.clearSelection();
this.$emit("success");
this.dialogVisible = false;
} else {
this.$message.error("操作失败");
}
} catch (error) {
this.$message.error(error.message || "操作失败");
}
}
});
}
},
};
</script>
<style lang="scss" scoped>
/* 修复1:弹性容器最小高度约束 */
:deep(.fixed-height-dialog),
.formBorder2,
.formBorder2 .el-container,
.formBorder2 .el-main {
min-height: 0 !important;
}
/* 表格行高优化 */
:deep(.el-table) {
.el-table__row {
height: 36px !important;
td {
padding: 4px 0 !important;
}
}
.el-table__header {
th {
padding: 4px 0 !important;
.cell {
line-height: 28px !important;
}
}
}
/* 确保内部滚动 */
.el-table__body-wrapper {
overflow-y: auto !important;
max-height: calc(100vh - 400px) !important;
}
}
/* 表单区域固定 */
.formBorder {
position: relative; ///为伪元素提供定位上下文
border: thin dotted black !important;
padding: 10px !important;
margin-top: 15px !important;
flex-shrink: 0 !important;
height: auto !important;
overflow: visible !important;
margin-bottom: 15px !important;
/* 边框的文字 */
&::before {
content: "项目信息";
position: absolute;
top: -8px; //调整到更合适的位置
left: 15px; //向右移动避免遮挡
background-color: #fff; //背景色需与页面背景一致
padding: 0 8px;
font-size: 13px;
color: #606266;
z-index: 10; //提高层级确保显示
font-weight: 500; //加粗文字
pointer-events: none; //防止点击穿透
}
}
.formBorder2 {
position: relative;
border: thin dotted black;
padding: 10px;
flex: 1;
min-height: 0;
overflow: hidden; // 保留
display: flex;
flex-direction: column;
padding-top: 25px; // 新增
&::before {
content: "待检边坡";
position: absolute;
top: 5px; // 调整到新增的padding区域内部
left: 15px;
background-color: #fff;
padding: 0 8px;
font-size: 13px;
color: #606266;
z-index: 1000;
font-weight: 500;
pointer-events: none;
}
.el-container {
height: auto !important; // 覆盖行内样式
flex: 1; // 填满剩余空间
display: flex;
flex-direction: column;
min-height: 0;
.el-header {
flex-shrink: 0;
height: auto !important;
padding-bottom: 10px;
}
.el-main {
flex: 1;
overflow: hidden;
position: relative;
padding: 0;
}
.el-footer {
flex-shrink: 0;
padding-top: 10px;
}
}
}
// 弹窗底部按钮区域
.dialog-footer {
padding: 10px 20px;
border-top: 1px solid #ebeef5;
text-align: center;
}
// 搜索区域样式
.searchDialog {
margin-top: 5px;
}
// 空数据样式
:deep(.el-table__empty-block) {
min-height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
// 分页样式
:deep(.el-pagination) {
padding: 5px 0;
}
// 表格高度控制
:deep(.el-table) {
height: 100% !important;
.el-table__body-wrapper {
overflow-y: auto !important;
}
}
</style><template>
<div class="project-management-block">
<!-- 弹窗组件 -->
<side-slope-dialog
:visible="dialogVisible"
:mode="currentMode"
:initial-form="currentForm"
@update:visible="dialogVisible = $event"
@success="handleDialogSuccess" />
<div class="project-management-block--header">
<el-form
size="mini"
:inline="true"
class="fr ml10"
align="left">
<el-input
v-model="searchParams.projectName"
placeholder="项目名称或编号"
size="mini"
clearable
@clear="resetSearch"
style="width: 140px;"
class="mr10" />
<el-select
v-model="searchParams.status"
placeholder="项目状态"
size="mini"
clearable
@clear="resetSearch"
style="width: 140px;"
class="mr10">
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
filterable />
</el-select>
<el-date-picker
v-model="searchProjectDate"
value-format="timestamp"
size="mini"
class="mr10"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
<el-button
type="primary"
size="mini"
style="width: 80px;"
@click="handleSearch"
class="mr10"
>查询
</el-button>
<el-button
type="success"
size="mini"
style="width: 80px;"
@click="openCreateDialog"
class="mr10"
>新建
</el-button>
</el-form>
</div>
<div class="project-management-block--content" >
<!-- 项目数据表格 -->
<el-table
:data="tableData"
border
style="width: 100%;
flex: 1;"
height="100%"
>
<el-table-column
label="序号"
type="index"
width="120">
</el-table-column>
<el-table-column
label="项目名称"
prop="projectName"
width="250">
</el-table-column>
<el-table-column
label="项目编号"
prop="projectCode"
width="220">
</el-table-column>
<el-table-column
label="项目周期"
width="250">
<template slot-scope="scope">
{{ scope.row.projectStartDate ?
formatDateRange(scope.row.projectStartDate, scope.row.projectEndDate)
: ''
}}
</template>
</el-table-column>
<el-table-column
label="项目状态"
width="150">
<template slot-scope="scope">
{{ scope.row.status ?
getStatusText(scope.row.status)
: ''
}}
</template>
</el-table-column>
<el-table-column
label="边坡总数"
prop="sideSlopeTotalCount"
width="150">
</el-table-column>
<el-table-column
label="已完成边坡数"
prop="sideSlopeCompleteCount"
width="194">
</el-table-column>
<el-table-column
label="完成率"
width="150">
<template slot-scope="scope">
{{
scope.row.sideSlopeTotalCount ?
calculateCompletionRate(
scope.row.sideSlopeCompleteCount,
scope.row.sideSlopeTotalCount
) : ''
}}
</template>
</el-table-column>
<el-table-column
label="操作"
width="195">
<template
slot-scope="scope">
<div
v-if="scope.row.id"
style="display: flex;
justify-content: center;">
<el-button
size="mini"
type="primary"
@click="openViewDialog(scope.row)"
style="padding: 4px 8px;
font-size: 12px"
>查看
</el-button>
<el-button
size="mini"
type="info"
@click="openEditDialog(scope.row)"
style="padding: 4px 8px;
font-size: 12px"
>编辑
</el-button>
<el-button
size="mini"
type="danger"
@click="deleteItem(scope.row)"
style="padding: 4px 8px;
font-size: 12px"
>删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="project-management-block--footer">
<el-pagination
background
layout="total,prev, pager, next,jumper"
:current-page.sync="pageParams.pageNo"
:page-size="pageParams.pageSize"
:total="pageParams.total"/>
</div>
</div>
</template>
<script>
// 导入模块
import SideSlopeDialog from './SideSlopeDialog.vue' // 项目详情弹窗组件
import { mapCfg } from '@/utils' // 字典配置映射工具
//接口
import {
getPeriodicInspectionPageList,
deletePeriodicInspection
} from '../../api/testProject'
// 组件定义
export default {
name: 'ProjectManagement', // 组件名称
components: {
SideSlopeDialog // 注册弹窗组件
},
// 数据模型
data() {
return {
// 搜索参数对象
searchParams: {
projectName: '', // 项目名称/编号搜索词
status: '', // 项目状态筛选值
projectStartDate: '', // 项目开始日期
projectEndDate: '' // 项目结束日期
},
// 日期范围选择器绑定值
searchProjectDate: [],
// 项目状态下拉选项
statusOptions: [],
// 表格数据源
tableData: [],
// 分页参数
pageParams: {
pageNo: 1, // 当前页码
pageSize: 10, // 每页条数
total: 0 // 总数据量
},
// 弹窗控制参数
dialogVisible: false, // 弹窗显示状态
currentMode: '', // 弹窗模式: 'create'/'edit'/'view'
currentForm: null // 当前表单数据
}
},
// 监听器
watch: {
//监听日期范围选择器变化:将选择器值同步到搜索参数对象
searchProjectDate(newVal) {
if (newVal && newVal.length === 2) {
this.searchParams.projectStartDate = newVal[0]
this.searchParams.projectEndDate = newVal[1]
} else {
this.searchParams.projectStartDate = ''
this.searchParams.projectEndDate = ''
}
}
},
// 生命周期钩子
async created() {
// 初始化状态选项
this.getStatus()
// 加载表格数据
this.loadTableData()
},
// 方法/函数
methods: {
// 工具方法
//根据状态值获取状态文本
getStatusText(statusValue) {
const option = this.statusOptions.find((opt) => opt.value === statusValue)
return option ? option.label : ''
},
//格式化日期范围
formatDateRange(start, end) {
if (!start || !end) return ''
// 截取日期部分(去除时间)
const format = (dateStr) => dateStr.substring(0, 10)
return `${format(start)} 至 ${format(end)}`
},
//计算完成率
calculateCompletionRate(completed, total) {
if (!total || isNaN(total) || total <= 0) return '0%'
return `${((completed / total) * 100).toFixed(1)}%`
},
// 弹窗操作方法
//创建项目弹窗
openCreateDialog() {
this.currentMode = 'create'
// 重置表单数据
this.currentForm = {
projectCode: '',
projectName: '',
projectStartDate: '',
projectEndDate: '',
projectUser: '',
remark: '',
sideSlopeDetailList: []
}
this.dialogVisible = true
},
//编辑项目弹窗
openEditDialog(row) {
this.currentMode = 'edit'
// 复制当前行数据到表单
this.currentForm = {
...row,
projectStartDate: row.projectStartDate,
projectEndDate: row.projectEndDate
}
this.dialogVisible = true
},
//查看项目弹窗
openViewDialog(row) {
this.currentMode = 'view'
// 复制当前行数据到表单
this.currentForm = {
...row,
projectStartDate: row.projectStartDate,
projectEndDate: row.projectEndDate
}
this.dialogVisible = true
},
// 弹窗操作成功回调,刷新表格数据(返回第一页)
handleDialogSuccess() {
this.pageParams.pageNo = 1
this.loadTableData()
},
// 数据操作方法
//加载表格数据,根据搜索参数和分页设置获取项目数据
async loadTableData() {
// 转换日期为时间戳格式
const startTime = this.searchParams.projectStartDate
? new Date(this.searchParams.projectStartDate).getTime()
: null
const endTime = this.searchParams.projectEndDate
? new Date(this.searchParams.projectEndDate).getTime()
: null
// 构造API参数
const params = {
pageNo: this.pageParams.pageNo,
pageSize: this.pageParams.pageSize,
searchKey: this.searchParams.projectName,
status: this.searchParams.status,
startTime,
endTime
}
try {
// 调用API获取项目数据
const res = await getPeriodicInspectionPageList(params)
this.tableData = res.entities || []
this.pageParams.total = res.entityCount || 0
} catch (error) {
console.error('加载项目列表失败', error)
this.tableData = []
this.pageParams.total = 0
}
},
//搜索方法重置到第一页并重新加载数据
handleSearch() {
this.pageParams.pageNo = 1
this.loadTableData()
},
//重置搜索条件,清空所有搜索参数并重新加载数据
resetSearch() {
this.searchParams = {
projectName: '',
status: '',
projectStartDate: '',
projectEndDate: ''
}
this.searchProjectDate = []
this.handleSearch()
},
//删除项目
async deleteItem(row) {
try {
// 显示确认对话框
await this.$confirm('确定要删除该项目吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
// 调用删除API
await deletePeriodicInspection({ periodicId: row.id })
this.$message.success('删除成功')
// 如果删除的是最后一页的最后一条,返回上一页
if (this.tableData.length === 1 && this.pageParams.pageNo > 1) {
this.pageParams.pageNo -= 1
}
// 重新加载数据
this.loadTableData()
} catch (error) {
// 用户取消删除时不显示错误
if (error !== 'cancel') {
this.$message.error('删除失败')
}
}
},
//从字典配置加载状态选项
getStatus() {
try {
// 获取字典配置
const dictList = mapCfg('Inspection.Periodic.PeriodicInspectionStatus')()
// 转换为Element-UI需要的格式
this.statusOptions = dictList.map((item) => ({
value: item.key,
label: item.value
}))
} catch (e) {
console.error("获取状态失败", e);
this.statusOptions = [];
}
}
}
}
</script>
<style lang="scss" scoped>
.project-management-block {
width: 100%;
height: 100%;
position: relative;
background-color: #fff;
&--header {
height: 50px;
box-sizing: border-box;
padding: 10px;
border-bottom: 1px solid #ebeef5;
}
&--content {
display: block;
padding: 10px;
height: calc(100% - 90px);
position: relative;
z-index: 10;
}
&--footer {
border-top: 1px solid #ebeef5;
padding: 4px 10px 0 10px;
position: relative;
z-index: 11;
text-align: center;
}
}
/* 优化表格样式 */
::v-deep .el-table {
flex: 1;
min-height: 0; // 防止flex布局溢出
/* 单元格样式 */
th,
td {
padding: 4px 0;
}
/* 表头样式 */
.el-table__header-wrapper {
line-height: 1;
th {
.cell {
line-height: 1.2;
}
}
}
}
/* 分页组件样式优化,确保在不同缩放比例下可见 */
::v-deep .el-pagination {
padding: 4px 5px;
.btn-prev,
.btn-next,
.el-pager li,
.el-pagination__jump {
min-width: 28px;
height: 28px;
line-height: 28px;
margin: 0 2px;
}
.el-pagination__total,
.el-pagination__jump {
font-size: 12px;
}
}
/* 响应式调整 */
@media screen and (max-width: 1200px) {
.project-management-block--header .el-col {
margin-bottom: 8px;
}
::v-deep .el-pagination {
display: flex;
flex-wrap: wrap;
justify-content: center;
&>* {
margin-bottom: 5px;
}
}
}
</style>vue.runtime.esm.js:4662 [Vue warn]: Error in callback for immediate watcher "initialForm" (Promise/async): "TypeError: Cannot read properties of null (reading 'projectStartDate')"
found in
---> <SideSlopeDialog> at src/pages/conservation-management/SideSlopeDialog.vue
<ProjectManagement> at src/pages/conservation-management/_ProjectManagement.vue
<TabPage> at src/pages/base/components/TabPage.vue
<ElTabPane> at packages/tabs/src/tab-pane.vue
<ElTabs> at packages/tabs/src/tabs.vue
<ElMain> at packages/main/src/main.vue
<ElContainer> at packages/container/src/main.vue... (1 recursive calls)
<AppMain> at src/pages/base/AppMain.vue
<Backend> at src/pages/common/Backend.vue
<App> at src/App.vue
<Root>这是怎么回事
最新发布