<side-slope-dialog
:visible="dialogVisible"
:mode="currentMode"
:initial-form="currentForm"
@update:visible="dialogVisible = $event"
@success="handleDialogSuccess" />
<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>
<el-table
:data="tableData"
border
stripe
style="width: 100%;
flex: 1;"
height="100%"
row-key="id"
>
<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">
{{ `${formatDate(scope.row.projectStartDate)} 至 ${formatDate(scope.row.projectEndDate)}` }}
</template>
</el-table-column>
<el-table-column
label="项目状态"
width="150">
<template slot-scope="scope">
{{ 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.sideSlopeCompleteCount / scope.row.sideSlopeTotalCount) * 100).toFixed(1)}%` }}
</template>
</el-table-column>
<el-table-column
label="操作"
width="195">
<template
slot-scope="scope">
<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>
</template>
</el-table-column>
</el-table>
<el-pagination
background
layout="total,prev, pager, next,jumper"
:current-page.sync="pageParams.pageNo"
:page-size="pageParams.pageSize"
:total="pageParams.total"/>
</template>
<script>
// 导入模块
import SideSlopeDialog from './SideSlopeDialog.vue' // 项目详情弹窗组件
import { mapCfg } from '@/utils' // 字典配置映射工具
//接口
import {
getPeriodicInspectionPageList,
deletePeriodicInspection
} from '../../api/testProject'
import moment from 'moment'
// 组件定义
export default {
name: 'ProjectManagement', // 组件名称
components: {
SideSlopeDialog // 注册弹窗组件
},
// 数据模型
data() {
return {
// 搜索参数对象
searchParams: {
projectName: '', // 项目名称/编号搜索词
status: '', // 项目状态筛选值
projectStartDate: '', // 项目开始日期
projectEndDate: '' // 项目结束日期
},
// 日期范围选择器绑定值
searchProjectDate: [],
// 表格数据源
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()
},
computed:{
statusOptions() {
const dictList = mapCfg('Inspection.Periodic.PeriodicInspectionStatus')()
return dictList.map(item => ({
value: item.key,
label: item.value
}))
},
},
// 方法/函数
methods: {
// 工具方法
//根据状态值获取状态文本
getStatusText(statusValue) {
const option = this.statusOptions.find((opt) => opt.value === statusValue)
return option ? option.label : ''
},
// 格式化时间
formatDate(date) {
if (!date) return "";
return moment(date).format(`YYYY-MM-DD`);
},
// 弹窗操作方法
//创建项目弹窗
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('删除失败')
}
}
},
}
}
</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>/* * @Author: liuhm * @Date: 2024-9-26 14:43:05 * @Last Modified by: liuhm * @Last
Modified time: 2024-9-26 14:43:09 */ /**
|-------------------------------------------------- | | 任务管理 |
|-------------------------------------------------- */
<template>
<el-card class="custom">
<el-form :model="searchFormData" class="fl mr5">
<el-cascader
style="width: 200px"
v-model="searchFormData.orgId"
clearable
class="ml10"
filterable
:options="maintenanceCompanyList"
:props="{
value: 'id',
label: 'name',
emitPath: false,
checkStrictly: true,
children: 'childrenList'
}"
size="mini"
placeholder="请选择管养单位"
></el-cascader>
<el-select
style="width: 200px"
v-model="searchFormData.routeId"
clearable
class="ml10"
filterable
size="mini"
placeholder="请选择巡查路线"
>
<el-option
v-for="item in routerList"
:key="item.id"
:label="item.routeCode"
:value="item.id"
>
</el-option>
</el-select>
<el-button size="mini" icon="el-icon-search " @click="searchTable" />
</el-form>
<el-table
v-loading="tableLoading"
size="mini"
:data="dataSource"
:height="`${cardContentHeight + 35}px`"
row-key="id"
style="width: 100%"
border
stripe
:cell-class-name="cellClass"
>
<el-table-column label="序号" width="50" type="index" align="left" />
<el-table-column label="管养单位" prop="orgName" width="230" align="left" />
<el-table-column label="巡查时间" align="center" width="200" show-overflow-tooltip>
<template slot-scope="scope">