Files
maintenance_system/src/views/zhinengxunjian/gongdanliebiao.vue
2025-09-18 19:56:24 +08:00

1092 lines
29 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>
<div class="work-order-management">
<!-- 顶部导航栏 -->
<div class="navigation-tabs">
<div class="nav-tab" @click="handleInspection1">待办事项</div>
<div class="nav-tab" @click="handleInspection2">巡检管理</div>
<div class="nav-tab" @click="handleInspection3">试验管理</div>
<div class="nav-tab" @click="handleInspection4">报修管理</div>
<div class="nav-tab" @click="handleInspection5">抢修管理</div>
<div class="nav-tab active" @click="handleInspection6">工单管理</div>
<div class="nav-tab" @click="handleInspection7">运维组织</div>
</div>
<!-- 页面标题 -->
<TitleComponent title="工单管理模块" subtitle="发起工单任务,跟踪流程记录和执行情况"></TitleComponent>
<div class="tabs-wrapper">
<div style="display: flex; align-items: center; gap: 10px">
<el-button type="primary" @click="handleInspectionManagement1">工单列表</el-button>
<el-button type="primary" @click="handleInspectionManagement2">派单计划</el-button>
<el-button type="primary" @click="handleInspectionManagement3">执行计划</el-button>
</div>
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-container">
<div class="filter-item">
<el-select v-model="workOrderType" placeholder="工单类型" clearable>
<el-option label="全部类型" value="all"></el-option>
<el-option label="维护保养" value="maintenance"></el-option>
<el-option label="检查检测" value="inspection"></el-option>
<el-option label="安装调试" value="installation"></el-option>
<el-option label="升级改造" value="upgrade"></el-option>
</el-select>
</div>
<div class="filter-item">
<el-select v-model="workOrderStatus" placeholder="全部状态" clearable>
<el-option label="全部状态" value="all"></el-option>
<el-option label="已接单" value="accepted"></el-option>
<el-option label="待处理" value="pending"></el-option>
<el-option label="执行中" value="executing"></el-option>
<el-option label="已完成" value="completed"></el-option>
</el-select>
</div>
<div class="filter-item">
<el-select v-model="priority" placeholder="全部优先级" clearable>
<el-option label="全部优先级" value="all"></el-option>
<el-option label="高" value="high"></el-option>
<el-option label="中" value="medium"></el-option>
<el-option label="低" value="low"></el-option>
</el-select>
</div>
<div class="filter-item">
<el-date-picker v-model="createDate" type="date" placeholder="创建日期" format="yyyy/MM/dd" value-format="yyyy/MM/dd"></el-date-picker>
</div>
<div class="filter-actions">
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
<el-button type="primary" class="create-btn" @click="handleCreateWorkOrder">发起工单任务</el-button>
</div>
</div>
</div>
<!-- 表格 -->
<div class="table-wrapper">
<el-table :data="pagedTableData" stripe style="width: 100%" highlight-current-row class="custom-table">
<el-table-column align="center" prop="orderNo" label="工单编号" min-width="120"></el-table-column>
<el-table-column align="center" prop="description" label="工单描述" min-width="150"></el-table-column>
<el-table-column align="center" prop="type" label="类型" min-width="100">
<template #default="scope">
<el-tag :type="getTypeTagType(scope.row.type)" class="type-tag">
{{ scope.row.type }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="priority" label="优先级" min-width="100">
<template #default="scope">
<el-tag :type="getPriorityTagType(scope.row.priority)" class="priority-tag">
{{ scope.row.priority }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="creator" label="创建人" min-width="100"></el-table-column>
<el-table-column align="center" prop="createTime" label="创建时间" min-width="140"></el-table-column>
<el-table-column align="center" prop="deadline" label="截止时间" min-width="140"></el-table-column>
<el-table-column align="center" prop="status" label="状态" min-width="100">
<template #default="scope">
<el-tag :type="getStatusTagType(scope.row.status)" class="status-tag">
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作" min-width="180" fixed="right">
<template #default="scope">
<el-button type="text" @click="handleViewDetail(scope.row)" class="action-btn">查看详情</el-button>
<el-button type="text" @click="handleEvaluate(scope.row)" class="action-btn">评价</el-button>
<el-button
type="text"
@click="handleCancel(scope.row)"
size="small"
class="action-btn cancel-btn"
v-if="['已接单', '待处理'].includes(scope.row.status)"
>
取消
</el-button>
<el-button type="text" @click="handleCommunicate(scope.row)" class="action-btn" v-if="scope.row.status === '执行中'"> 沟通 </el-button>
<el-button type="text" @click="handleArchive(scope.row)" class="action-btn" v-if="scope.row.status === '已完成'"> 归档 </el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页区域 -->
<div class="pagination-section">
<div class="pagination-info">
显示第{{ (currentPage - 1) * pageSize + 1 }}{{ Math.min(currentPage * pageSize, total) }}{{ total }}条记录
</div>
<div class="pagination-controls">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="prev, pager, next, jumper"
:total="total"
background
>
</el-pagination>
</div>
</div>
<!-- 发起工单弹窗 -->
<el-dialog v-model="createDialogVisible" title="发起工单任务" width="900px" class="create-dialog" center>
<el-form :model="createForm" :rules="createFormRules" ref="createFormRef" label-width="120px" class="custom-form">
<el-form-item label="工单标题*" prop="title">
<el-input v-model="createForm.title" placeholder="请输入工单标题" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="工单类型*" prop="type">
<el-select v-model="createForm.type" placeholder="请选择类型">
<el-option label="维护保养" value="维护保养" />
<el-option label="检查检测" value="检查检测" />
<el-option label="安装调试" value="安装调试" />
<el-option label="升级改造" value="升级改造" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="优先级*" prop="priority">
<el-select v-model="createForm.priority" placeholder="请选择优先级">
<el-option label="高" value="高" />
<el-option label="中" value="中" />
<el-option label="低" value="低" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="截止时间*" prop="deadline">
<el-date-picker v-model="createForm.deadline" type="date" placeholder="yyyy/mm/日" format="yyyy/MM/dd" value-format="yyyy/MM/dd" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="工单描述*" prop="description">
<el-input v-model="createForm.description" type="textarea" :rows="3" placeholder="请详细描述工单内容、要求和注意事项等信息" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="执行地点*" prop="location">
<el-input v-model="createForm.location" placeholder="请填写执行地点" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="相关设备/系统">
<el-select v-model="createForm.relatedEquipment" placeholder="请填写相关设备或系统名称" filterable allow-create>
<el-option label="设备A" value="设备A" />
<el-option label="设备B" value="设备B" />
<el-option label="系统1" value="系统1" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="上传图片">
<div class="upload-container">
<div class="upload-box">
<i class="el-icon-upload avatar-uploader-icon"></i>
<div class="upload-text">点击或拖拽文件至此处上传</div>
<div class="upload-hint">支持PDFWordExcel图片等格式最大50MB</div>
</div>
</div>
</el-form-item>
<el-form-item label="工单描述">
<el-input v-model="createForm.resultDescription" type="textarea" :rows="3" placeholder="请描述该工单完成后预期达成的成果" />
</el-form-item>
<el-form-item label="是否需要执行人" prop="needAssignee">
<el-radio-group v-model="createForm.needAssignee">
<el-radio label="true">指定执行人</el-radio>
<el-radio label="false">由系统分配</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="选择执行人" prop="assignee" v-if="createForm.needAssignee === 'true'">
<el-select v-model="createForm.assignee" placeholder="请选择执行人">
<el-option label="李阳" value="李阳" />
<el-option label="张工" value="张工" />
<el-option label="王工" value="王工" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleSaveDraft">保存草稿</el-button>
<el-button @click="cancelCreate">取消</el-button>
<el-button type="primary" @click="submitCreate">提交工单</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
<script setup>
import { ref, computed, reactive } from 'vue';
import router from '@/router';
import TitleComponent from './TitleComponent.vue';
// 激活的选项卡
const activeTab = ref('list');
// 筛选条件
const workOrderType = ref('all');
const workOrderStatus = ref('all');
const priority = ref('all');
const createDate = ref('');
// 工单数据
const rawTableData = ref([
{
orderNo: 'WO-2023-0620-056',
description: '季度设备维护保养',
type: '维护保养',
priority: '高',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '已接单'
},
{
orderNo: 'WO-2023-0620-057',
description: '安全设备检查检测',
type: '检查检测',
priority: '中',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '待处理'
},
{
orderNo: 'WO-2023-0620-058',
description: '新设备安装调试',
type: '安装调试',
priority: '高',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '执行中'
},
{
orderNo: 'WO-2023-0620-059',
description: '系统升级改造',
type: '升级改造',
priority: '中',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '已完成'
},
{
orderNo: 'WO-2023-0620-060',
description: '季度设备维护保养',
type: '维护保养',
priority: '高',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '已接单'
},
{
orderNo: 'WO-2023-0620-061',
description: '季度设备维护保养',
type: '维护保养',
priority: '高',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '已接单'
},
{
orderNo: 'WO-2023-0620-062',
description: '网络设备检查',
type: '检查检测',
priority: '中',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '待处理'
},
{
orderNo: 'WO-2023-0620-063',
description: '服务器升级',
type: '升级改造',
priority: '高',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '执行中'
},
{
orderNo: 'WO-2023-0620-064',
description: '空调维护',
type: '维护保养',
priority: '低',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '已完成'
},
{
orderNo: 'WO-2023-0620-065',
description: 'UPS设备检测',
type: '检查检测',
priority: '中',
creator: '李阳',
createTime: '2023-06-20 09:30',
deadline: '2023-06-30 17:00',
status: '已接单'
}
]);
// 分页相关
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(rawTableData.value.length);
// 分页处理后的数据
const pagedTableData = computed(() => {
// 筛选逻辑
let filteredData = [...rawTableData.value];
if (workOrderType.value !== 'all') {
filteredData = filteredData.filter((item) => item.type === workOrderType.value);
}
if (workOrderStatus.value !== 'all') {
filteredData = filteredData.filter((item) => item.status === workOrderStatus.value);
}
if (priority.value !== 'all') {
filteredData = filteredData.filter((item) => item.priority === priority.value);
}
if (createDate.value) {
filteredData = filteredData.filter((item) => item.createTime.includes(createDate.value));
}
// 更新总条数
total.value = filteredData.length;
// 分页处理
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return filteredData.slice(startIndex, endIndex);
});
// 获取类型标签样式
const getTypeTagType = (type) => {
const typeMap = {
// 维护保养为红色
'维护保养': 'danger',
// 检查检测为绿色
'检查检测': 'success',
// 安装调试为黄色
'安装调试': 'warning',
// 升级改造为绿色
'升级改造': 'success'
};
return typeMap[type] || 'default';
};
// 获取优先级标签样式
const getPriorityTagType = (priority) => {
const priorityMap = {
'高': 'danger',
'中': 'warning',
'低': 'info'
};
return priorityMap[priority] || 'default';
};
// 获取状态标签样式
const getStatusTagType = (status) => {
const statusMap = {
'已接单': 'primary',
'待处理': 'warning',
'执行中': 'success',
'已完成': 'info'
};
return statusMap[status] || 'default';
};
// 搜索处理
const handleSearch = () => {
currentPage.value = 1; // 重置到第一页
};
// 分页事件
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1;
};
const handleCurrentChange = (val) => {
currentPage.value = val;
};
// 选项卡点击
const handleTabClick = (tab) => {
console.log('切换到选项卡:', tab.name);
// 重置筛选条件和分页
workOrderType.value = 'all';
workOrderStatus.value = 'all';
priority.value = 'all';
createDate.value = '';
currentPage.value = 1;
};
// 操作按钮事件
const handleViewDetail = (row) => {
console.log('查看详情:', row);
};
const handleEvaluate = (row) => {
console.log('评价:', row);
};
const handleCancel = (row) => {
console.log('取消工单:', row);
};
const handleCommunicate = (row) => {
console.log('沟通:', row);
};
const handleArchive = (row) => {
console.log('归档:', row);
};
// 创建工单弹窗相关
const createDialogVisible = ref(false);
const createFormRef = ref(null);
const createForm = reactive({
title: '',
type: '',
priority: '',
deadline: '',
description: '',
location: '',
relatedEquipment: '',
resultDescription: '',
needAssignee: 'true',
assignee: ''
});
const createFormRules = {
title: [{ required: true, message: '请输入工单标题', trigger: 'blur' }],
type: [{ required: true, message: '请选择工单类型', trigger: 'change' }],
priority: [{ required: true, message: '请选择优先级', trigger: 'change' }],
deadline: [{ required: true, message: '请选择截止时间', trigger: 'change' }],
description: [{ required: true, message: '请输入工单描述', trigger: 'blur' }],
location: [{ required: true, message: '请输入执行地点', trigger: 'blur' }],
needAssignee: [{ required: true, message: '请选择是否需要指定执行人', trigger: 'change' }],
assignee: [{ required: true, message: '请选择执行人', trigger: 'change' }]
};
// 打开创建工单弹窗
const handleCreateWorkOrder = () => {
createDialogVisible.value = true;
};
// 提交创建工单
const submitCreate = () => {
console.log('提交工单:', createForm);
// 这里可以添加表单验证和提交逻辑
createDialogVisible.value = false;
// 重置表单
Object.keys(createForm).forEach((key) => {
createForm[key] = '';
});
};
// 取消创建工单
const cancelCreate = () => {
createDialogVisible.value = false;
// 重置表单
Object.keys(createForm).forEach((key) => {
createForm[key] = '';
});
};
// 保存草稿
const handleSaveDraft = () => {
console.log('保存草稿:', createForm);
ElMessage.success('草稿保存成功');
createDialogVisible.value = false;
};
// 导航路由跳转
const handleInspection1 = () => {
router.push('/rili/rili');
};
const handleInspection2 = () => {
router.push('/rili/InspectionManagement');
};
const handleInspection3 = () => {
router.push('/rili/shiyanguanli');
};
const handleInspection4 = () => {
router.push('/rili/baoxiuguanli');
};
const handleInspection5 = () => {
router.push('/rili/qiangxiuguanli');
};
const handleInspection6 = () => {
router.push('/rili/gongdanliebiao');
};
const handleInspection7 = () => {
router.push('/rili/renyuanzhuangtai');
};
const handleInspectionManagement1 = () => {
router.push('/rili/gongdanliebiao');
};
const handleInspectionManagement2 = () => {
router.push('/rili/paidanjilu');
};
const handleInspectionManagement3 = () => {
router.push('/rili/zhixingjilu');
};
</script>
<style scoped>
.work-order-management {
padding: 20px;
background-color: #f5f7fa;
min-height: 100vh;
}
/* 选项卡样式 */
.tabs-wrapper {
background-color: #fff;
padding: 20px;
border-radius: 8px;
margin-bottom: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.custom-tabs {
padding-top: 1px;
}
.custom-tabs .el-tabs__header {
margin: 0 -20px;
padding: 0 20px;
border-bottom: 1px solid #e4e7ed;
}
.custom-tabs .el-tabs__nav-wrap::after {
height: 0;
}
.custom-tabs .el-tabs__item {
font-size: 14px;
color: #606266;
padding: 14px 20px;
margin-right: 20px;
}
.custom-tabs .el-tabs__item.is-active {
color: #165dff;
font-weight: 500;
}
.custom-tabs .el-tabs__item:hover {
color: #165dff;
}
/* 筛选栏样式 */
.filter-bar {
background-color: #fff;
border-radius: 8px;
margin-bottom: 24px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
padding: 16px 24px;
}
.filter-container {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16px;
width: 100%;
}
.filter-item {
flex-shrink: 0;
}
.filter-bar .el-select,
.filter-bar .el-date-picker {
width: 180px;
height: 36px;
}
.filter-bar .el-select .el-input__inner,
.filter-bar .el-date-picker .el-input__inner {
border-radius: 4px;
border-color: #dcdfe6;
transition: all 0.2s ease;
}
.filter-bar .el-select .el-input__inner:focus,
.filter-bar .el-date-picker .el-input__inner:focus {
border-color: #165dff;
box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1);
}
.filter-actions {
margin-left: auto;
display: flex;
gap: 12px;
flex-shrink: 0;
}
.search-btn {
background-color: #f2f3f5;
color: #303133;
border-color: #f2f3f5;
transition: all 0.2s ease;
}
.search-btn:hover {
background-color: #e5e6eb;
color: #303133;
border-color: #e5e6eb;
}
.create-btn {
background-color: #165dff;
border-color: #165dff;
transition: all 0.2s ease;
}
.create-btn:hover {
background-color: #0e42d2;
border-color: #0e42d2;
}
/* 表格样式 */
.table-wrapper {
background-color: #fff;
border-radius: 8px;
margin-bottom: 24px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.custom-table {
border-collapse: collapse;
width: 100%;
}
.custom-table th {
background-color: #f5f7fa;
font-weight: 500;
color: #606266;
text-align: center;
padding: 12px 8px;
border-bottom: 1px solid #e4e7ed;
}
.custom-table td {
padding: 12px 8px;
border-bottom: 1px solid #e4e7ed;
color: #303133;
text-align: center;
}
.custom-table tr:hover {
background-color: #f5f7fa;
}
.custom-table tr.current-row {
background-color: #ecf5ff;
}
.type-tag,
.priority-tag,
.status-tag {
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
}
/* 操作按钮样式 */
.action-btn {
color: #165dff;
font-size: 12px;
padding: 4px 8px;
margin: 0 2px;
}
.action-btn:hover {
color: #0e42d2;
background-color: #e8f3ff;
}
.cancel-btn {
color: #f56c6c;
}
.cancel-btn:hover {
color: #e64340;
background-color: #fff2f0;
}
/* 分页区域样式 */
.pagination-section {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;
padding: 16px 24px;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
}
.pagination-info {
font-size: 14px;
color: #606266;
}
.pagination-controls .el-pagination {
margin: 0;
}
.pagination-controls .el-pagination button,
.pagination-controls .el-pagination .el-pager li {
min-width: 36px;
height: 36px;
line-height: 36px;
border-radius: 4px;
}
.pagination-controls .el-pagination .el-pager li.active {
background-color: #165dff;
color: #fff;
}
/* 导航栏样式 */
.navigation-tabs {
display: flex;
margin-bottom: 20px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
padding: 2px;
}
.nav-tab {
padding: 12px 24px;
cursor: pointer;
transition: all 0.3s ease;
border-radius: 4px;
font-size: 14px;
color: #606266;
border-right: 1px solid #f0f0f0;
flex: 1;
text-align: center;
}
.nav-tab:last-child {
border-right: none;
}
.nav-tab:hover {
color: #409eff;
background-color: #ecf5ff;
}
.nav-tab.active {
background-color: #409eff;
color: #fff;
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.3);
}
.nav-tab {
cursor: pointer;
user-select: none;
}
/* 弹窗样式 */
.create-dialog {
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
overflow: hidden;
}
.create-dialog .el-dialog__header {
padding: 20px 24px;
border-bottom: 1px solid #f0f0f0;
background: linear-gradient(135deg, #f8f9ff 0%, #f0f2ff 100%);
}
.create-dialog .el-dialog__title {
font-size: 18px;
font-weight: 600;
color: #303133;
letter-spacing: 0.5px;
}
.create-dialog .el-dialog__body {
padding: 24px;
background-color: #ffffff;
}
.custom-form .el-form-item {
margin-bottom: 20px;
}
.custom-form .el-form-item__label {
font-size: 14px;
color: #303133;
font-weight: 500;
padding: 10px 0;
}
/* 表单元素美化 */
.custom-form .el-input__inner,
.custom-form .el-select .el-input__inner,
.custom-form .el-date-picker .el-input__inner {
border-radius: 6px;
border-color: #dcdfe6;
transition: all 0.3s ease;
height: 40px;
padding: 0 15px;
font-size: 14px;
background-color: #fff;
}
.custom-form .el-input__inner:hover,
.custom-form .el-select .el-input__inner:hover,
.custom-form .el-date-picker .el-input__inner:hover {
border-color: #c0c4cc;
}
.custom-form .el-input__inner:focus,
.custom-form .el-select .el-input__inner:focus,
.custom-form .el-date-picker .el-input__inner:focus {
border-color: #165dff;
box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1);
}
/* 文本域美化 */
.custom-form .el-textarea__inner {
border-radius: 6px;
border-color: #dcdfe6;
transition: all 0.3s ease;
padding: 10px 15px;
font-size: 14px;
resize: vertical;
min-height: 100px;
}
.custom-form .el-textarea__inner:hover {
border-color: #c0c4cc;
}
.custom-form .el-textarea__inner:focus {
border-color: #165dff;
box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1);
}
/* 单选按钮美化 */
.custom-form .el-radio-group {
display: flex;
gap: 20px;
padding: 5px 0;
}
.custom-form .el-radio {
font-size: 14px;
color: #303133;
}
.custom-form .el-radio__label {
padding-left: 8px;
}
/* 上传区域样式 */
.upload-container {
width: 100%;
}
.upload-box {
border: 2px dashed #dcdfe6;
border-radius: 8px;
padding: 40px 20px;
text-align: center;
cursor: pointer;
background-color: #f8f9fa;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.upload-box::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, #e0e7ff, transparent);
transform: scaleX(0);
transform-origin: left;
transition: transform 0.3s ease;
}
.upload-box:hover {
border-color: #165dff;
background-color: #f0f5ff;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(22, 93, 255, 0.1);
}
.upload-box:hover::before {
transform: scaleX(1);
}
.avatar-uploader-icon {
font-size: 36px;
color: #909399;
margin-bottom: 12px;
transition: color 0.3s ease;
}
.upload-box:hover .avatar-uploader-icon {
color: #165dff;
transform: scale(1.1);
}
.upload-text {
font-size: 14px;
color: #606266;
margin-bottom: 8px;
font-weight: 500;
}
.upload-hint {
font-size: 12px;
color: #909399;
line-height: 1.5;
}
/* 弹窗按钮美化 */
.create-dialog .dialog-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
padding: 16px 24px;
background-color: #fafafa;
border-top: 1px solid #f0f0f0;
}
.create-dialog .dialog-footer .el-button {
padding: 10px 24px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
transition: all 0.3s ease;
height: 40px;
}
.create-dialog .dialog-footer .el-button:first-child {
background-color: #f5f7fa;
color: #606266;
border-color: #f5f7fa;
}
.create-dialog .dialog-footer .el-button:first-child:hover {
background-color: #e6e8eb;
color: #303133;
border-color: #e6e8eb;
}
.create-dialog .dialog-footer .el-button:nth-child(2) {
background-color: #f5f7fa;
color: #606266;
border-color: #dcdfe6;
}
.create-dialog .dialog-footer .el-button:nth-child(2):hover {
background-color: #e6e8eb;
color: #303133;
border-color: #c0c4cc;
}
.create-dialog .dialog-footer .el-button:last-child {
background-color: #165dff;
border-color: #165dff;
color: #fff;
}
.create-dialog .dialog-footer .el-button:last-child:hover {
background-color: #0e42d2;
border-color: #0e42d2;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(22, 93, 255, 0.3);
}
/* 表单验证反馈 */
.custom-form .el-form-item.is-error .el-input__inner,
.custom-form .el-form-item.is-error .el-select .el-input__inner {
border-color: #f56c6c;
}
.custom-form .el-form-item.is-error .el-input__inner:focus,
.custom-form .el-form-item.is-error .el-select .el-input__inner:focus {
border-color: #f56c6c;
box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.1);
}
/* 响应式设计 */
@media (max-width: 1200px) {
.filter-container {
flex-direction: column;
align-items: stretch;
}
.filter-actions {
margin-left: 0;
justify-content: flex-end;
}
.filter-bar .el-select,
.filter-bar .el-date-picker {
width: 100%;
}
}
@media (max-width: 768px) {
.work-order-management {
padding: 10px;
}
.navigation-tabs {
flex-wrap: wrap;
}
.nav-tab {
flex: 1 0 33%;
padding: 10px 0;
font-size: 12px;
}
.pagination-section {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
}
</style>