bonus-ui/src/views/system/project/index.vue

1212 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<!-- 搜索表单 -->
<el-form
:inline="true"
label-width="80px"
label-position="right"
size="small"
ref="searchFormRef"
:model="searchParams"
>
<el-card class="search-box">
<!-- 关键修改使用 flex 布局实现自适应换行 -->
<div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 10px;">
<el-form-item prop="pro_name" label="工程名称" style="margin-bottom: 0; width: 320px">
<el-input
clearable
placeholder="请输入工程名称"
v-model="searchParams.pro_name"
style="width: 100%; min-width: 200px;"
/>
</el-form-item>
<!-- <el-form-item prop="pro_code" label="工程编号" style="margin-bottom: 0; width: 320px">-->
<!-- <el-input-->
<!-- clearable-->
<!-- placeholder="请输入工程编号"-->
<!-- v-model="searchParams.pro_code"-->
<!-- style="width: 100%; min-width: 200px;"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item prop="org_name" label="建管单位" style="margin-bottom: 0; width: 320px">-->
<!-- <el-input-->
<!-- clearable-->
<!-- placeholder="请输入单位名称"-->
<!-- v-model="searchParams.org_name"-->
<!-- style="width: 100%; min-width: 200px;"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item prop="project_type" label="工程类型" style="margin-bottom: 0; width: 320px">
<el-select
clearable
placeholder="选择工程类型"
v-model="searchParams.project_type"
style="width: 100%; min-width: 200px;"
>
<el-option
v-for="item in projectTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 按钮区域 -->
<div style="display: flex; gap: 10px; margin-left: auto;">
<el-button @click="getProjectListData" size="mini" icon="el-icon-search" type="primary" class="primary-lease">
查询
</el-button>
<el-button @click="onReset" icon="el-icon-refresh" size="mini" class="primary-lease">重置</el-button>
</div>
</div>
<el-row>
</el-row>
</el-card>
</el-form>
<!-- 数据列表 -->
<el-card class="content-box">
<el-row style="margin-bottom: 16px; display: flex; justify-content: flex-end; align-items: center; gap: 10px;">
<el-button
size="mini"
@click="handleAdd"
type="primary"
class="primary-lease"
>
工程新建
</el-button>
<el-button
size="mini"
type="danger"
class="primary-lease"
@click="handleBatchDelete"
:disabled="selectedRows.length === 0"
>
批量删除
</el-button>
</el-row>
<div class="table-container">
<el-table
:data="projectList"
show-overflow-tooltip
border stripe height="100%"
@selection-change="handleSelectionChange"
>
<!--复选列-->
<el-table-column type="selection" width="55" align="center"/>
<el-table-column align="center" label="序号" type="index" width="80"/>
<el-table-column align="center" prop="pro_name" label="工程名称"/>
<el-table-column align="center" label="工程编号">
<template slot-scope="scope">
<a
style="cursor: pointer; color: #00a288; text-decoration: underline"
@click="handleToDetails(scope.row.id)"
>
{{ scope.row.pro_code }}
</a>
</template>
</el-table-column>
<el-table-column align="center" prop="dict_label" label="工程类型"/>
<el-table-column align="center" prop="voltage" label="电压等级"/>
<el-table-column align="center" prop="scale" label="规模"/>
<el-table-column align="center" prop="province" label="所在省"/>
<el-table-column align="center" prop="city" label="所在市"/>
<el-table-column align="center" prop="county" label="所在区/县"/>
<el-table-column align="center" prop="mechanize_rate" label="机械化率"/>
<el-table-column align="center" label="操作" :width="220">
<template slot-scope="scope">
<!-- 查看详情按钮(复用编辑按钮样式,仅改文字和方法) -->
<!-- <el-button-->
<!-- size="small"-->
<!-- type="info"-->
<!-- class="primary-lease"-->
<!-- @click="handleViewDetails(scope.row)"-->
<!-- >-->
<!-- 查看-->
<!-- </el-button>-->
<!-- 编辑按钮:移除 v-if 条件,直接显示 -->
<el-button
size="small"
type="primary"
class="primary-lease"
@click="handleEdit(scope.row)"
>
编辑
</el-button>
<!-- 删除按钮:移除 v-if 条件,直接显示 -->
<el-popconfirm
width="220"
icon="el-icon-info"
icon-color="#626AEF"
title="确定删除该项工程吗?"
@confirm="handleDelete(scope.row.id)"
>
<template slot="reference">
<el-button size="small" type="danger" class="primary-lease" style="margin-left: 8px;">
删除
</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
<div class="pagination-wrapper">
<el-pagination
background
layout="total,sizes,prev, pager, next"
:total="total"
:page-size="searchParams.pageSize"
:current-page="searchParams.pageNum"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</el-card>
<!-- 新增/编辑对话框 -->
<el-dialog
width="1000px"
@close="handleDialogClose"
destroy-on-close
:title="dialogTitle"
:visible.sync="addOrEditDialogVisible"
custom-class="simple-dialog"
>
<el-form
label-width="100px"
label-position="right"
ref="addOrEditFormRef"
:model="addOrEditForm"
:rules="addOrEditFormRules"
class="simple-form"
label-class="el-form-item__label"
>
<el-row :gutter="20">
<el-col :span="24">
<el-row :gutter="15">
<el-col :span="12">
<el-form-item label="工程名称" prop="pro_name">
<el-input
v-model="addOrEditForm.pro_name"
placeholder="请输入工程名称"
style="width: 100%"
maxlength="50"
show-word-limit
:disabled="isView"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程编号" prop="pro_code">
<el-input
v-model="addOrEditForm.pro_code"
placeholder="请输入工程编号"
style="width: 100%"
maxlength="30"
show-word-limit
:disabled="!isAdd || isView"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="15">
<el-col :span="12">
<el-form-item label="电压等级" prop="voltage">
<el-input
v-model="addOrEditForm.voltage"
placeholder="请输入电压等级500"
style="width: 100%"
maxlength="10"
show-word-limit
:disabled="isView"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规模" prop="scale">
<el-input
v-model="addOrEditForm.scale"
placeholder="请输入规模"
style="width: 100%"
maxlength="50"
show-word-limit
:disabled="isView"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工程类型" prop="project_type"> <!-- 注意prop要与表单字段对齐 -->
<el-select
clearable
style="width: 100%"
placeholder="请选择工程类型"
v-model="addOrEditForm.project_type"
:disabled="isView"
>
<el-option
v-for="item in projectTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建管单位" prop="org_name">
<el-input
v-model="addOrEditForm.org_name"
placeholder="请输入单位"
style="width: 100%"
maxlength="50"
show-word-limit
:disabled="isView"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="机械化率" prop="mechanize_rate">
<el-input
v-model="addOrEditForm.mechanize_rate"
placeholder="请输入机械化率"
style="width: 100%"
maxlength="50"
show-word-limit
:disabled="isView"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="15">
<el-col :span="12">
<el-form-item label="开工时间" prop="start_time">
<el-date-picker
type="date"
placeholder="选择开工时间"
v-model="addOrEditForm.start_time"
value-format="yyyy-MM-dd"
style="width: 100%"
:disabled="isView"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投产时间" prop="put_time">
<el-date-picker
type="date"
placeholder="选择投产时间"
v-model="addOrEditForm.put_time"
value-format="yyyy-MM-dd"
style="width: 100%"
:disabled="isView"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="15">
<el-col :span="8">
<el-form-item label="所在省" prop="province">
<el-select
clearable
style="width: 100%"
placeholder="请选择所在省"
v-model="addOrEditForm.province"
@change="loadCities"
>
<el-option
v-for="item in provinceOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所在市" prop="city">
<el-select
clearable
style="width: 100%"
placeholder="请选择所在市"
v-model="addOrEditForm.city"
@change="loadDistricts"
:disabled="!addOrEditForm.province"
>
<el-option
v-for="item in cityOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所在区/县" prop="county">
<el-select
clearable
style="width: 100%"
placeholder="请选择所在区/县"
v-model="addOrEditForm.county"
:disabled="!addOrEditForm.city"
>
<el-option
v-for="item in districtOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input
type="textarea"
v-model="addOrEditForm.remark"
placeholder="请输入备注内容"
:rows="3"
style="width: 100%"
maxlength="100"
show-word-limit
:disabled="isView"
/>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addOrEditDialogVisible = false" class="cancel-btn">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="submitLoading" class="confirm-btn" v-if="!isView">
<span v-if="!submitLoading">{{ isAdd ? '新增' : '保存' }}</span>
<span v-else>提交中...</span>
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listProject,
getProject,
addProject,
updateProject,
delProject,
getProjectTypeList,
delProjectBatch // 新增导入批量删除API
} from '@/api/system/project'
import { Message } from 'element-ui'
import { getProvinces, getCities, getCounties } from '@/api/system/region'
export default {
name: 'ProjectManagement',
data() {
return {
total: 0,
projectList: [],
selectedRows: [], // 存储选中的表格行
provinceOptions: [], // 省份下拉选项
cityOptions: [], // 城市下拉选项
districtOptions: [], // 区县下拉选项
dialogTitle: '新增工程',
addOrEditDialogVisible: false,
submitLoading: false,
isAdd: true,
isView: false,
// 搜索参数
searchParams: {
pro_name: '',
pro_code: '',
project_type: '',
org_name: '',
dict_value:'',
pageSize: 10,
pageNum: 1
},
// 表单数据
addOrEditForm: {
id: '',
pro_name: '',
pro_code: '',
project_type: '',
org_name: '',
contractUnit: '',
mechanize_rate: '',
remark: '',
voltage: '',
scale: '',
province: '',
city: '',
county: '',
start_time: '',
put_time: '',
},
projectTypeList: [],
// 表单验证规则
addOrEditFormRules: {
// 以下字段保持必填
pro_name: [
{ required: true, message: '请输入工程名称', trigger: 'blur' }
],
pro_code: [
{ required: true, message: '请输入工程编号', trigger: 'blur' }
],
voltage: [
{ required: true, message: '请输入电压等级', trigger: 'blur' }
],
scale: [
{ required: true, message: '请输入规模', trigger: 'blur' }
],
project_type: [
{ required: true, message: '请选择工程类型', trigger: 'change' }
],
province: [
{ required: true, message: '请选择所在省', trigger: 'blur' }
],
city: [
{ required: true, message: '请选择所在市', trigger: 'blur' }
],
county: [
{ required: true, message: '请选择所在区/县', trigger: 'blur' }
],
start_time: [
{ message: '请选择开工时间', trigger: 'change' }
],
put_time: [
{ message: '请选择投产时间', trigger: 'change' },
{ validator: this.validateTimeDifference, trigger: 'change' }
],
mechanize_rate: [
{
pattern: /^(100(\.0{1,2})?|0(\.\d{1,2})?|[1-9]\d{0,1}(\.\d{1,2})?)$/,
message: '请输入 0 ~ 100 之间的有效数字,且不能以 0 开头(如 01、010',
trigger: 'blur'
}
],
org_name: [
// 非必填,仅保留长度限制(可选)
{ max: 50, message: '单位名称不能超过50个字符', trigger: 'blur' }
],
remark: [
{ max: 100, message: '备注不能超过100个字符', trigger: 'blur' }
],
contractUnit: [] // 完全非必填,留空数组
}
}
},
mounted() {
this.loadProvinces() // 页面加载时加载省份
this.getProjectListData()
this.loadProjectTypes()
},
methods: {
// 自定义校验:投产时间必须晚于开工时间
validateTimeDifference(rule, value, callback) {
const startTime = this.addOrEditForm.start_time; // 开工时间
const endTime = value; // 投产时间(当前校验字段的值)
// 若未选择投产时间,直接通过(非必填)
if (!endTime) return callback();
// 若已选择开工时间,校验时间差
if (startTime) {
const startDate = new Date(startTime);
const endDate = new Date(endTime);
// 若投产时间早于或等于开工时间,提示错误
if (endDate <= startDate) {
return callback(new Error('投产时间必须晚于开工时间'));
}
}
// 校验通过
callback();
},
async loadProvinces() {
try {
const res = await getProvinces()
if (res.code === 200) {
// 关键转换:将 areaCode → valuename → label
this.provinceOptions = res.data.map(item => ({
value: item.areaCode, // 下拉框的选项值(存储用)
label: item.short_name // 下拉框的显示文本(用户看)
}))
} else {
Message.error('加载省份失败:' + (res.message || '未知错误'))
}
} catch (error) {
console.error('省份加载异常:', error)
Message.error('网络异常,无法加载省份数据')
}
},
// 加载城市
async loadCities(provinceAreaCode) {
console.log('loadCities param:', provinceAreaCode)
// 关键改动:当省份改变时,清空城市和区县的选项及表单值
// 即使 provinceAreaCode 为空(例如用户清空了省份选择),也执行清空操作
this.cityOptions = [];
this.districtOptions = [];
this.addOrEditForm.city = '';
this.addOrEditForm.county = '';
// 如果没有传入有效的省份编码,则直接返回
if (!provinceAreaCode || !/^\d{6,12}$/.test(provinceAreaCode)) {
console.error('❌ 传入了无效的 provinceAreaCode', provinceAreaCode);
return;
}
try {
const res = await getCities(provinceAreaCode)
if (res.code === 200) {
this.cityOptions = res.data.map(item => ({
value: item.areaCode,
label: item.short_name
}))
} else {
Message.error('加载城市失败')
}
} catch (error) {
console.error('城市加载异常:', error)
Message.error('无法加载城市数据')
}
},
// 加载区县
async loadDistricts(cityAreaCode) {
console.log('loadDistricts param:', cityAreaCode)
// 关键改动:当城市改变时,清空区县的选项及表单值
// 即使 cityAreaCode 为空,也执行清空操作
this.districtOptions = [];
this.addOrEditForm.county = '';
// 如果没有传入有效的城市编码,则直接返回
if (!cityAreaCode || !/^\d{6,12}$/.test(cityAreaCode)) {
console.error('❌ 传入了无效的 cityAreaCode', cityAreaCode);
return;
}
try {
const res = await getCounties(cityAreaCode)
if (res.code === 200) {
this.districtOptions = res.data.map(item => ({
value: item.areaCode,
label: item.name
}))
} else {
Message.error('加载区县失败')
}
} catch (error) {
console.error('区县加载异常:', error)
Message.error('无法加载区县数据')
}
},
// 获取工程列表
async getProjectListData() {
try {
const res = await listProject(this.searchParams)
if (res.code === 200) {
this.projectList = res.data.rows || []
this.total = res.data.total || 0
} else {
Message.error(res.message || '获取工程列表失败')
}
} catch (error) {
Message.error('网络错误,获取工程列表失败')
}
},
// 加载工程类型
async loadProjectTypes() {
try {
const res = await getProjectTypeList()
if (res.code === 200) {
this.projectTypeList = res.data.map(item => ({
label: item.dict_label,
value: item.dict_value
}))
} else {
Message.error('获取工程类型失败:' + (res.message || ''))
}
} catch (error) {
Message.error('加载工程类型时发生网络错误')
}
},
// 重置搜索
onReset() {
this.searchParams = {
pro_name: '',
pro_code: '',
project_type: '',
org_name: '',
pageSize: this.searchParams.pageSize,
pageNum: 1
}
this.$refs.searchFormRef?.clearValidate()
this.getProjectListData()
},
// 表格选择变化
handleSelectionChange(selection) {
this.selectedRows = selection
},
// 详情页跳转
handleToDetails(id) {
this.$router.push({name: 'demand-details', query: {id}})
},
// 新增工程
handleAdd() {
this.isAdd = true
this.isView = false
this.dialogTitle = '新增工程'
this.addOrEditForm = {
id: '',
pro_name: '',
pro_code: '',
project_type: '',
org_name: '',
contractUnit: '',
remark: '',
voltage: '',
scale: '',
province: '',
city: '',
county: '',
start_time: '',
put_time: ''
}
this.$refs.addOrEditFormRef?.clearValidate()
this.addOrEditDialogVisible = true
},
// 查看详情
async handleViewDetails(row) {
this.isView = true
this.dialogTitle = '查看工程详情'
try {
const res = await getProject(row.id)
if (res.code === 200) {
this.addOrEditForm = {...res.data}
this.addOrEditDialogVisible = true
} else {
Message.error(res.message || '获取工程详情失败')
}
} catch (error) {
Message.error('网络错误,获取工程详情失败')
}
},
async handleEdit(row) {
this.isAdd = false;
this.isView = false;
this.dialogTitle = '编辑工程';
try {
// 1. 获取工程详情
const res = await getProject(row.id);
if (res.code !== 200) return this.$message.error('获取详情失败');
// 拿到原始数据
const projectData = res.data;
// ================== 核心修改开始 ==================
// 2. 处理机械化率的格式:去除百分号,并转换为数字
if (projectData.mechanize_rate && typeof projectData.mechanize_rate === 'string') {
// 使用 replace('%', '') 去掉百分号
// 使用 parseFloat() 将字符串转换为数字
projectData.mechanize_rate = parseFloat(projectData.mechanize_rate.replace('%', ''));
}
// ================== 核心修改结束 ==================
// 3. 确保省份列表已加载(含 areaCode 映射)
await this.loadProvinces();
// 4. 省份名称 -> 编码
const targetProvince = this.provinceOptions.find(item => item.label === projectData.province);
const provinceCode = targetProvince ? targetProvince.value : '';
if (!provinceCode) {
Message.warning(`未找到“${projectData.province}”对应的编码,请手动选择`);
this.addOrEditForm = { ...projectData }; // 这里也会使用处理后的数据
this.addOrEditDialogVisible = true;
return;
}
// 5. 用编码加载城市列表
await this.loadCities(provinceCode);
// 城市名称 -> 编码
const targetCity = this.cityOptions.find(item => item.label === projectData.city);
const cityCode = targetCity ? targetCity.value : '';
// 6. 用编码加载区县列表
await this.loadDistricts(cityCode);
// 区县名称 -> 编码
const targetCounty = this.districtOptions.find(item => item.label === projectData.county);
const countyCode = targetCounty ? targetCounty.value : '';
// 7. 表单赋值(此时 projectData.mechanize_rate 已经是数字 80 了)
this.addOrEditForm = {
...projectData,
province: provinceCode,
city: cityCode,
county: countyCode
};
this.addOrEditDialogVisible = true;
this.$nextTick(() => this.$refs.addOrEditFormRef?.clearValidate());
} catch (error) {
console.error('编辑失败:', error);
Message.error('网络错误,编辑失败');
}
},
// 提交表单
async handleSubmit() {
const valid = await this.$refs.addOrEditFormRef?.validate()
if (!valid) return
// 处理机械化率:添加%符号
if (this.addOrEditForm.mechanize_rate) {
this.addOrEditForm.mechanize_rate = `${this.addOrEditForm.mechanize_rate}%`
}
this.submitLoading = true
try {
let res = this.isAdd ? await addProject(this.addOrEditForm) : await updateProject(this.addOrEditForm)
if (res.code === 200) {
Message.success(this.isAdd ? '新增工程成功' : '编辑工程成功')
this.addOrEditDialogVisible = false
this.getProjectListData()
} else {
Message.error(res.message || (this.isAdd ? '新增工程失败' : '编辑工程失败'))
}
} catch (error) {
Message.error('网络错误,操作失败')
} finally {
this.submitLoading = false
}
},
// 删除工程
async handleDelete(id) {
try {
const res = await delProject(id)
if (res.code === 200) {
Message.success('删除工程成功')
this.getProjectListData()
} else {
Message.error(res.message || '删除工程失败')
}
} catch (error) {
Message.error('网络错误,删除工程失败')
}
},
// 批量删除 - 修复后的方法
async handleBatchDelete() {
if (this.selectedRows.length === 0) {
Message.warning('请选择要删除的工程')
return
}
try {
await this.$confirm(
`确定删除选中的 ${this.selectedRows.length} 个工程吗?`,
'提示',
{
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消'
}
)
const ids = this.selectedRows.map(row => row.id)
const res = await delProjectBatch(ids)
if (res.code === 200) {
Message.success(`成功删除 ${this.selectedRows.length} 个工程`)
this.getProjectListData()
this.selectedRows = [] // 清空选中状态
} else {
Message.error(res.message || '批量删除失败')
}
} catch (error) {
if (error !== 'cancel') {
Message.error('网络错误,批量删除失败')
}
}
},
// 关闭对话框
handleDialogClose() {
this.isView = false
this.$refs.addOrEditFormRef?.clearValidate()
},
// 分页大小改变
handleSizeChange(val) {
this.searchParams.pageSize = val
this.getProjectListData()
},
// 当前页码改变
handleCurrentChange(val) {
this.searchParams.pageNum = val
this.getProjectListData()
}
}
}
</script>
<style lang="scss" scoped>
/* 样式部分保持不变 */
::v-deep .upload-tip .el-form-item__label {
color: transparent;
}
.el-pagination {
justify-content: flex-end;
padding: 5px 0;
}
::v-deep .el-pagination.is-background .el-pager li.is-active {
background-color: #3cb4a6;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 6px;
width: 95%;
}
.img-list {
display: flex;
align-items: center;
.img-items {
width: 100px;
height: 100px;
margin-right: 8px;
position: relative;
img {
width: 100%;
height: 100%;
}
.mask-img {
visibility: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000;
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
.delete-icon {
font-size: 20px;
cursor: pointer;
z-index: 9;
color: #fff;
}
}
}
.img-items:hover .mask-img {
visibility: visible;
}
}
.app-container-content {
::v-deep .el-dialog {
display: flex !important;
flex-direction: column !important;
margin: 0 !important;
position: absolute !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
max-height: 100vh !important;
.el-dialog__body {
flex: 1;
overflow-y: scroll !important;
padding: 20px 40px;
}
.dialog-content {
padding: 20px;
}
}
}
.search-box {
margin-bottom: 20px;
border-radius: 8px;
padding: 0;
::v-deep .el-card__body {
padding: 20px !important;
}
}
.el-form-item--small.el-form-item {
margin-bottom: 0px;
}
.content-box {
border-radius: 8px;
height: calc(100vh - 210px);
display: flex;
flex-direction: column;
overflow: hidden;
::v-deep .el-card__body {
display: flex !important;
flex-direction: column !important;
height: 100% !important;
padding: 20px;
}
.el-row:first-child {
margin-bottom: 16px;
flex-shrink: 0;
.el-col {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 12px;
}
}
.table-container {
flex: 1;
overflow: hidden;
margin-bottom: 0;
min-height: 0;
display: flex;
flex-direction: column;
}
.pagination-wrapper {
flex-shrink: 0;
padding-top: 6px;
margin-top: auto;
text-align: right;
::v-deep .pagination-container {
padding: 0px 20px !important;
margin-bottom: 30px;
}
}
::v-deep .el-table {
&.el-table--striped .el-table__body {
tr.el-table__row--striped td {
background-color: #F6FBFA !important;
}
}
.el-table__header {
background: #E9F0EE;
th {
background: #E9F0EE !important;
color: #606266;
font-weight: 600;
height: 50px;
}
}
&.el-table--striped .el-table__body tr.el-table__row:hover > td.el-table__cell {
background-color: #CCF1E9 !important;
}
}
}
.dialog-table {
border-radius: 6px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
::v-deep .el-table {
border-radius: 6px;
overflow: hidden;
&.el-table--striped .el-table__body {
tr.el-table__row--striped td {
background-color: #F6FBFA !important;
}
}
.el-table__header {
background: #E9F0EE;
th {
background: #E9F0EE !important;
color: #606266;
font-weight: 600;
height: 45px;
font-size: 14px;
border-bottom: 2px solid #e4e7ed;
}
}
.el-table__body {
tr {
transition: all 0.2s ease;
&:hover {
background-color: #f8f9fa;
}
td {
padding: 12px 8px;
font-size: 13px;
border-bottom: 1px solid #f0f2f5;
}
}
}
&.el-table--striped .el-table__body tr.el-table__row:hover > td.el-table__cell {
background-color: #CCF1E9 !important;
}
&::before {
display: none;
}
&::after {
display: none;
}
}
}
.simple-dialog {
.el-dialog__header {
padding: 15px 20px;
border-bottom: 1px solid #eee;
.el-dialog__title {
font-size: 16px;
font-weight: 600;
}
}
.el-dialog__body {
padding: 20px;
}
.el-dialog__footer {
padding: 10px 20px;
border-top: 1px solid #eee;
text-align: right;
}
}
.simple-form {
.el-form-item {
margin-bottom: 15px;
.el-form-item__label {
color: #333;
padding-right: 10px;
&::before {
content: '*';
color: #ff4d4f;
margin-right: 4px;
}
&.no-required::before {
content: '';
margin-right: 0;
}
}
}
.el-input, .el-select, .el-date-picker {
width: 100%;
}
.el-textarea {
width: 100%;
&:focus {
border-color: #1890ff;
}
}
}
.dialog-footer {
.cancel-btn {
margin-right: 10px;
}
.confirm-btn {
background-color: #1890ff;
border-color: #1890ff;
}
}
</style>