中航光电热表web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1010 lines
28 KiB

<template>
<!-- <basic-container> -->
<div>
<el-form label-width="80px" :model="formLabelAlign">
<el-row>
<el-col :span="6">
<el-form-item label="维度:">
<el-select v-model="formLabelAlign.type" placeholder="请选择" @change="typeChange">
<el-option label="车间订单" value="1"> </el-option>
<el-option label="班组" value="2"> </el-option>
<el-option label="设备" value="3"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6" v-if="formLabelAlign.type == '1'">
<el-form-item label="车间订单号:" label-width="120px">
<el-input v-model="formLabelAlign.woCode" placeholder="请输入"></el-input>
</el-form-item>
</el-col>
<el-col :span="6" v-if="formLabelAlign.type == '2'">
<el-form-item label="班组:">
<!-- <el-input v-model="formLabelAlign.teamame" placeholder="请输入"></el-input> -->
<el-select v-model="formLabelAlign.teamName" filterable placeholder="请选择">
<el-option
v-for="(item, index) in selectTeamOptions"
:label="item"
:value="item"
:key="index"
>
</el-option>
<!-- <el-option label="班组2" value="2"> </el-option> -->
</el-select>
</el-form-item>
</el-col>
<el-col :span="6" v-if="formLabelAlign.type == '3'">
<el-form-item label="设备:">
<!-- <el-input v-model="formLabelAlign.equipName" placeholder="请输入"></el-input> -->
<el-select v-model="formLabelAlign.equipName" filterable placeholder="请选择">
<el-option
v-for="(item, index) in selectEquipOptions"
:label="item"
:value="item"
:key="index"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="时间:">
<el-date-picker
v-model="formLabelAlign.startTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="选择日期"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-button type="primary" icon="el-icon-search" @click="handleSubmit"> 搜索 </el-button>
<el-button icon="el-icon-delete" @click="handleSubmit"> 清空 </el-button>
</el-col>
</el-row>
</el-form>
<div class="gantt-container">
<!-- 头部标题和图例 -->
<div class="gantt-header">
<!-- <h2>设备生产任务甘特图</h2> -->
<div class="status-legend">
<div class="legend-item">
<span class="legend-color completed"></span>
<span>已完成</span>
</div>
<div class="legend-item">
<span class="legend-color processing"></span>
<span>进行中</span>
</div>
<div class="legend-item">
<span class="legend-color pending"></span>
<span>未开始</span>
</div>
</div>
</div>
<!-- 甘特图主体 -->
<div class="gantt-wrapper">
<!-- 左侧设备列表 -->
<div class="device-list">
<div
v-if="searchType == '1'"
class="device-item device-item-title"
:style="{ height: '36px' }"
>
车间订单号
</div>
<div
v-if="searchType == '2'"
class="device-item device-item-title"
:style="{ height: '36px' }"
>
班组
</div>
<div
v-if="searchType == '3'"
class="device-item device-item-title"
:style="{ height: '36px' }"
>
设备
</div>
<div
v-for="(device, index) in devices"
:key="index"
:style="{
height: getRowHeight(device) + 'px',
lineHeight: getRowHeight(device) + 'px',
textAlign: 'center',
borderBottom: '1px solid #ccc',
}"
:title="device"
>
{{ device }}
</div>
</div>
<!-- 右侧时间轴 (时间在上,刻度线在下) -->
<div class="timeline-container" @wheel.prevent="handleWheel">
<!-- 图表X轴区域(时间在上,刻度线在下) -->
<div class="chart-axis">
<!-- 时间标签 -->
<div class="time-labels" :style="{ width: `${timelineWidth}%` }">
<!-- 主刻度标签(小时) -->
<div
v-for="(time, index) in majorTickLabels"
:key="index"
class="major-label"
:style="{ left: `${(index / 24) * 100}%` }"
>
{{ time }}
</div>
<!-- 副刻度标签(30分钟,放大后显示) -->
<div v-if="zoomLevel >= 2" class="minor-labels">
<div
v-for="(time, index) in minorTickLabels"
:key="index"
class="minor-label"
:style="{ left: `${(index / (24 * 2)) * 100}%` }"
>
{{ time }}
</div>
</div>
</div>
<!-- 刻度线(在下方) -->
<div class="tick-lines" :style="{ width: `${timelineWidth}%` }">
<!-- 主刻度线(小时) -->
<div
v-for="(time, index) in majorTickLabels"
:key="index"
class="major-tick-line"
:style="{ left: `${(index / 24) * 100}%` }"
:title="time"
></div>
<!-- 副刻度线(30分钟,放大后显示) -->
<div v-if="zoomLevel >= 2" class="minor-tick-lines">
<div
v-for="(time, index) in minorTickLabels"
:key="index"
class="minor-tick-line"
:style="{ left: `${(index / (24 * 2)) * 100}%` }"
:title="time"
></div>
</div>
<!-- X轴基线 -->
<div class="axis-base-line"></div>
</div>
</div>
<!-- 甘特图内容区域 -->
<div class="chart-content" :style="{ width: `${timelineWidth}%` }">
<!-- 网格线 -->
<div class="grid-lines">
<div
v-for="(time, index) in majorTickLabels"
:key="index"
class="grid-line"
:style="{ left: `${(index / 24) * 100}%` }"
></div>
</div>
<!-- 任务容器 -->
<div class="tasks-container">
<div
v-for="(device, devIndex) in devices"
:key="devIndex"
class="device-task-row"
:style="{ height: getRowHeight(device) + 'px' }"
>
<template v-for="(layer, layerIndex) in getLayeredTasks(device)" :key="layerIndex">
<div
v-for="(task, taskIndex) in layer"
:key="taskIndex"
class="task-bar"
:style="{
left: `${getPositionPercent(task.startTime)}%`,
width: `${getWidthPercent(task.startTime, task.endTime)}%`,
backgroundColor: getStatusColor(task),
top: `${getLayerOffset(
layerIndex,
getLayeredTasks(device).length,
device
)}px`,
height: `${getLayerTaskHeight(getLayeredTasks(device).length, device)}px`,
}"
@mouseenter="showTooltip($event, task, device)"
@mouseleave="hideTooltip()"
>
<!-- 任务标签内容不变 -->
<span class="task-label" v-if="searchType == '1'">{{ task.processName }}</span>
<span class="task-label" v-if="searchType == '2'">{{ task.woCode }}</span>
<span class="task-label" v-if="searchType == '3'">{{ task.woCode }}</span>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
<!-- 悬浮提示框 -->
<div
v-if="tooltipVisible"
class="tooltip"
:style="{
left: `${tooltipX}px`,
top: `${tooltipY}px`,
}"
>
<div class="tooltip-content">
<!-- 工单标题 -->
<div class="wo-code-title" v-if="searchType == '1'">{{ tooltipData.woCode }}</div>
<div class="wo-code-title" v-if="searchType == '2'">{{ tooltipData.teamName }}</div>
<div class="wo-code-title" v-if="searchType == '3'">{{ tooltipData.equipName }}</div>
<!-- 详情列表 -->
<ul class="detail-list">
<li class="detail-item" v-if="searchType == '1'">
<span class="label">工序:</span>
<span class="value">{{ tooltipData.processName || '-' }}</span>
</li>
<li class="detail-item" v-if="searchType == '1'">
<span class="label">班组:</span>
<span class="value">{{ tooltipData.teamName || '-' }}</span>
</li>
<li class="detail-item" v-if="searchType == '2' || searchType == '3'">
<span class="label">车间订单号:</span>
<span class="value">{{ tooltipData.woCode || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">零件号:</span>
<span class="value">{{ tooltipData.partCode || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">流程卡号:</span>
<span class="value">{{ tooltipData.cardNo || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">批次号:</span>
<span class="value">{{ tooltipData.batchNo || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">当前工序:</span>
<span class="value">{{ tooltipData.currentProcessName || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">数量:</span>
<span class="value">{{ tooltipData.makeQty || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">计划开始时间:</span>
<span class="value">{{ tooltipData.planStartTime || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">实际开始时间:</span>
<span class="value">{{ tooltipData.factStartTime || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">计划完成时间:</span>
<span class="value">{{ tooltipData.planEndTime || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">实际完成时间:</span>
<span class="value">{{ tooltipData.factEndTime || '-' }}</span>
</li>
<li class="detail-item">
<span class="label">状态:</span>
<span class="value">
<el-tag v-if="searchType == '1'">
<i v-if="tooltipData.planStatus == '1'">未开始</i>
<i v-if="tooltipData.planStatus == '2'">加工中</i>
<i v-if="tooltipData.planStatus == '3'">报工完成</i>
<i v-if="tooltipData.planStatus == '5'">已完成</i>
<i v-if="tooltipData.planStatus == '6'">已返工</i>
</el-tag>
<el-tag v-if="searchType == '2' || searchType == '3'" :type="tooltipData.status">
<i v-if="tooltipData.orderStatus == '1'">未开始</i>
<i v-if="tooltipData.orderStatus == '2'">进行中</i>
<i v-if="tooltipData.orderStatus == '3'">已完成</i>
</el-tag>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- </basic-container> -->
</template>
<script>
import { getData, selectEquip, selectTeam } from '@/api/productionSchedulingPlan/scheduling';
export default {
name: 'GanttChart',
data() {
return {
searchType: '',
formLabelAlign: {
type: '1', //维度类型
startTime: null, //时间
teamName: '', //班组
equipName: '', //设备
woCode: '', //车间订单号
},
rowHeight: 36,
zoomLevel: 2, // 缩放级别 (1-4)
minZoom: 1,
maxZoom: 4,
// 设备列表
devices: [],
// 任务数据
taskData: [],
// 提示框相关
tooltipVisible: false,
tooltipData: {},
tooltipX: 0,
tooltipY: 0,
baseRowHeight: 36, // 基础行高(单任务时的高度)
rowHeights: {}, // 存储每个设备的动态行高
selectTeamOptions: [], //班组列表
selectEquipOptions: [], //设备列表
};
},
computed: {
// 时间轴总宽度
timelineWidth() {
return 100 * this.zoomLevel;
},
// 主刻度标签(小时)
majorTickLabels() {
return Array.from({ length: 24 }, (_, i) => `${i}:00`);
},
// 副刻度标签(30分钟)
minorTickLabels() {
const labels = [];
for (let hour = 0; hour < 24; hour++) {
labels.push(''); // 小时位置留空(主刻度已显示)
labels.push(`${hour}:30`);
}
return labels;
},
},
mounted() {
this.searchType = this.formLabelAlign.type;
this.formLabelAlign.startTime = new Date().toISOString().substr(0, 10);
this.getData();
this.getSelectTeam();
this.getSelectEquip()
},
methods: {
typeChange(){
this.formLabelAlign.teamName = ''
this.formLabelAlign.equipName = ''
this.formLabelAlign.woCode = ''
},
getData() {
getData(this.formLabelAlign).then(res => {
this.processData(res.data.data);
});
},
getSelectEquip() {
selectEquip().then(res => {
this.selectEquipOptions = res.data.data;
});
},
getSelectTeam() {
selectTeam().then(res => {
this.selectTeamOptions = res.data.data;
});
},
processData(rawData) {
const tasks = [];
const workOrders = Object.keys(rawData);
// 遍历每个工单的任务
workOrders.forEach(woCode => {
const woTasks = rawData[woCode] || [];
woTasks.forEach(task => {
tasks.push({
...task,
status: this.calcTaskStatus(task.startTime, task.endTime),
});
});
});
this.devices = workOrders;
this.taskData = tasks;
},
// 计算任务状态(已完成/进行中/未开始)
calcTaskStatus(startTime, endTime) {
const now = new Date();
const current = now.getHours() * 60 + now.getMinutes();
const start = this.timeToMinutes(startTime);
let end = this.timeToMinutes(endTime);
// 处理跨天(结束时间小于开始时间)
if (end < start) {
end += 24 * 60;
}
if (current >= end) {
return '已完成';
} else if (current >= start) {
return '进行中';
} else {
return '未开始';
}
},
// 判断任务状态
getTaskStatus(startTime, endTime) {
const now = new Date();
const currentHours = now.getHours();
const currentMinutes = now.getMinutes();
const currentTotal = currentHours * 60 + currentMinutes;
const startTotal = this.timeToMinutes(startTime);
const endTotal = this.timeToMinutes(endTime);
// 处理跨天情况(结束时间小于开始时间)
if (endTotal < startTotal) {
// 现在在[start, 24:00)或[00:00, end)之间为进行中
if (currentTotal >= startTotal || currentTotal < endTotal) {
return '进行中';
} else if (currentTotal >= endTotal) {
return '已完成';
} else {
return '未开始';
}
} else {
// 正常时间段
if (currentTotal >= endTotal) {
return '已完成';
} else if (currentTotal >= startTotal) {
return '进行中';
} else {
return '未开始';
}
}
},
handleSubmit() {
this.searchType = this.formLabelAlign.type;
this.devices = [];
this.taskData = [];
this.getData();
},
// 根据设备筛选任务
getDeviceTasks(device) {
if (this.searchType == '1') {
return this.taskData.filter(task => task.woCode === device);
}
if (this.searchType == '2') {
return this.taskData.filter(task => task.teamName === device);
}
if (this.searchType == '3') {
return this.taskData.filter(task => task.equipName === device);
}
},
// 时间转分钟数
timeToMinutes(timeStr) {
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
},
// 计算任务起始位置百分比
getPositionPercent(startTime) {
const totalMinutes = 24 * 60;
const startMinutes = this.timeToMinutes(startTime);
return (startMinutes / totalMinutes) * 100;
},
// 计算任务宽度百分比
getWidthPercent(startTime, endTime) {
const startMinutes = this.timeToMinutes(startTime);
const endMinutes = this.timeToMinutes(endTime);
const duration = endMinutes - startMinutes;
return (duration / (24 * 60)) * 100;
},
// 根据状态获取颜色
getStatusColor(row) {
let staus = this.searchType == '1' ? row.planStatus : row.orderStatus;
switch (staus) {
case '3':
return '#28a745';
case '2':
return '#007bff';
case '1':
return '#6c757d';
default:
return '#ccc';
}
},
// 鼠标滚轮缩放
handleWheel(e) {
if (e.deltaY < 0 && this.zoomLevel < this.maxZoom) {
this.zoomLevel += 0.5;
} else if (e.deltaY > 0 && this.zoomLevel > this.minZoom) {
this.zoomLevel -= 0.5;
}
},
// 放大/缩小/重置
zoomIn() {
if (this.zoomLevel < this.maxZoom) this.zoomLevel += 0.5;
},
zoomOut() {
if (this.zoomLevel > this.minZoom) this.zoomLevel -= 0.5;
},
resetZoom() {
this.zoomLevel = this.minZoom;
},
// 提示框控制
showTooltip(e, task, device) {
this.tooltipData = { ...task, device };
this.tooltipVisible = true; // 先显示tooltip以便获取尺寸
this.$nextTick(() => {
const tooltipEl = document.querySelector('.tooltip');
if (!tooltipEl) return; // 容错处理
const tooltipWidth = tooltipEl.offsetWidth;
const tooltipHeight = tooltipEl.offsetHeight;
const padding = 5; // 缩小边距,让tooltip更靠近鼠标
const mouseOffsetX = 8; // 水平偏移量(原10px改为8px)
const mouseOffsetY = 8; // 垂直偏移量(原10px改为8px)
// 初始位置(更靠近鼠标)
let x = e.pageX + mouseOffsetX;
let y = e.pageY + mouseOffsetY;
// 右侧边界检测
if (x + tooltipWidth > document.documentElement.clientWidth) {
x = e.pageX - tooltipWidth - mouseOffsetX;
}
// 底部边界检测
if (y + tooltipHeight > document.documentElement.clientHeight) {
y = e.pageY - tooltipHeight - mouseOffsetY;
}
// 确保不超出顶部和左侧
x = Math.max(padding, x);
y = Math.max(padding, y);
this.tooltipX = x;
this.tooltipY = y;
});
},
hideTooltip() {
this.tooltipVisible = false;
},
// 计算每个设备的行高
getRowHeight(device) {
const layers = this.getLayeredTasks(device);
const layerCount = layers.length;
// 行高 = 基础行高 * 层数(确保至少有基础行高)
const height = Math.max(this.baseRowHeight, layerCount * this.baseRowHeight);
// 缓存计算结果避免重复计算
this.rowHeights[device] = height;
return height;
},
// 修复层级偏移计算(基于实际行高)
getLayerOffset(layerIndex, totalLayers, device) {
const rowHeight = this.getRowHeight(device);
if (totalLayers <= 1) return 2; // 单层级时的顶部间距
// 计算每层可用高度(减去总间距)
const totalSpacing = totalLayers * 4; // 每层4px间距
const availableHeight = rowHeight - totalSpacing;
const layerHeight = availableHeight / totalLayers;
return layerIndex * (layerHeight + 4) + 2; // 2px顶部边距
},
// 修复任务高度计算(基于实际行高)
getLayerTaskHeight(totalLayers, device) {
const rowHeight = this.getRowHeight(device);
if (totalLayers <= 1) {
return rowHeight - 4; // 减去上下间距
} else {
const totalSpacing = totalLayers * 4;
const availableHeight = rowHeight - totalSpacing;
return availableHeight / totalLayers;
}
},
// 优化层级计算逻辑
getLayeredTasks(device) {
const tasks = this.getDeviceTasks(device);
if (!tasks.length) return [];
// 按开始时间排序,并处理跨天任务
const sortedTasks = [...tasks].sort((a, b) => {
const aStart = this.timeToMinutes(a.startTime);
const bStart = this.timeToMinutes(b.startTime);
// 跨天任务(结束时间小于开始时间)排在前面
if (this.timeToMinutes(a.endTime) < aStart && this.timeToMinutes(b.endTime) >= bStart) {
return -1;
}
return aStart - bStart;
});
const layers = [];
sortedTasks.forEach(task => {
let placed = false;
const taskStart = this.timeToMinutes(task.startTime);
const taskEnd = this.timeToMinutes(task.endTime);
// 处理跨天任务的结束时间(转换为第二天的分钟数)
const adjustedEnd = taskEnd < taskStart ? taskEnd + 24 * 60 : taskEnd;
for (let i = 0; i < layers.length; i++) {
const lastTask = layers[i][layers[i].length - 1];
const lastEnd = this.timeToMinutes(lastTask.endTime);
const lastAdjustedEnd =
lastEnd < this.timeToMinutes(lastTask.startTime) ? lastEnd + 24 * 60 : lastEnd;
if (taskStart >= lastAdjustedEnd) {
layers[i].push(task);
placed = true;
break;
}
}
if (!placed) {
layers.push([task]);
}
});
return layers;
},
},
};
</script>
<style scoped>
.gantt-container {
width: 100%;
padding: 20px;
box-sizing: border-box;
font-family: Arial, sans-serif;
}
.gantt-header {
height: 40px;
}
.zoom-controls {
display: flex;
gap: 10px;
margin-bottom: 15px;
padding-left: 265px;
align-items: center;
}
.zoom-btn {
display: flex;
align-items: center;
gap: 5px;
padding: 4px 10px;
background-color: #f1f5f9;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
transition: all 0.2s;
}
.zoom-btn:hover {
background-color: #e2e8f0;
}
.zoom-info {
font-size: 12px;
color: #666;
}
.status-legend {
display: flex;
gap: 20px;
float: right;
}
.legend-item {
display: flex;
align-items: center;
gap: 5px;
font-size: 14px;
}
.legend-color {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 2px;
}
.legend-color.completed {
background-color: #28a745;
}
.legend-color.processing {
background-color: #007bff;
}
.legend-color.pending {
background-color: #6c757d;
}
.gantt-wrapper {
display: flex;
height: calc(100% - 120px);
border: 1px solid #eee;
overflow: hidden;
}
.device-list {
width: 250px;
background-color: #f8f9fa;
border-right: 1px solid #eee;
/* overflow-y: auto; */
flex-shrink: 0;
}
.device-item {
font-size: 16px;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
line-height: 36px;
padding-left: 15px;
padding-right: 15px;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1px;
background-color: #eee;
}
}
.device-item-title {
background: #284c89 !important;
text-align: center;
color: #fff;
}
.timeline-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}
/* 图表X轴区域样式(时间在上,刻度线在下) */
.chart-axis {
height: 36px;
position: relative;
}
/* 时间标签容器 */
.time-labels {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 30px;
display: flex;
background-color: #284c89 !important;
}
/* 主刻度标签(小时) */
.major-label {
position: absolute;
top: 0;
left: 0;
/* transform: translateX(-50%); */
font-size: 16px;
color: #fff;
font-weight: 500;
white-space: nowrap;
line-height: 30px;
}
/* 副刻度标签(30分钟) */
.minor-labels {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.minor-label {
position: absolute;
top: 0;
left: 0;
/* transform: translateX(-50%); */
font-size: 16px;
color: #fff;
white-space: nowrap;
line-height: 30px;
padding: 0 2px;
}
/* 刻度线容器(在下方) */
.tick-lines {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 6px;
background-color: #284c89 !important;
}
/* 主刻度线(小时) */
.major-tick-line {
position: absolute;
bottom: 0;
width: 1px;
height: 4px;
background-color: #fff;
transform: translateX(-50%);
}
/* 副刻度线(30分钟) */
.minor-tick-lines {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}
.minor-tick-line {
position: absolute;
bottom: 0;
width: 1px;
height: 4px;
background-color: #fff;
transform: translateX(-50%);
}
/* X轴基线 */
.axis-base-line {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1px;
background-color: #dee2e6;
}
/* 图表内容区域 */
.chart-content {
flex: 1;
position: relative;
overflow-y: auto;
}
/* 网格线样式 */
.grid-lines {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.grid-line {
position: absolute;
top: 0;
bottom: 0;
width: 0px;
background-color: #e9ecef;
}
/* 任务容器 */
.tasks-container {
position: relative;
width: 100%;
height: 100%;
}
.device-task-row {
position: relative;
border-bottom: 1px solid #e9ecef;
box-sizing: border-box;
padding: 0;
margin: 0;
}
.task-bar {
position: absolute;
border-radius: 18px;
display: flex;
align-items: center;
padding: 0 10px;
box-sizing: border-box;
cursor: pointer;
overflow: hidden;
transition: all 0.2s;
white-space: nowrap;
}
.task-bar:hover {
transform: translateY(-2px);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
}
.task-label {
font-size: 14px;
color: white;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 提示框 */
.tooltip {
position: fixed;
background-color: white;
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
z-index: 1000;
font-size: 12px;
pointer-events: none;
/* z-index: 100; */
}
.tooltip-content div {
margin: 3px 0;
}
.wo-code-title {
font-size: 18px;
font-weight: bold;
color: #1f2d3d;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #e6e6e6;
}
.detail-list {
list-style: none;
padding: 0;
margin: 0;
.detail-item {
display: flex;
align-items: center;
margin-bottom: 5px;
line-height: 20px;
.label {
width: 100px;
color: #666;
font-weight: 500;
}
.value {
flex: 1;
color: #333;
}
}
}
:deep(.el-button--primary) {
background-color: #284c89 !important;
color: #fff;
}
</style>