调试生产完成率
This commit is contained in:
parent
b46e8f430d
commit
51f57889c6
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
//日生产完成率
|
||||
export function ProPlanAchievementrate(data) {
|
||||
return request({
|
||||
url: '/mes/reportManagement/report/productionCompletionRate',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
@ -1,104 +1,58 @@
|
||||
<template>
|
||||
<div class="production-completion-rate">
|
||||
<!-- 顶部操作栏 -->
|
||||
<!-- <div class="top-bar"> -->
|
||||
<!-- <div class="group-config">
|
||||
<span>当前组数配置:</span>
|
||||
<el-button size="small" @click="decreaseGroup">-</el-button>
|
||||
<el-input v-model="groupCount" size="small" style="width: 60px; text-align: center;" />
|
||||
<el-button size="small" @click="increaseGroup">+</el-button>
|
||||
</div> -->
|
||||
<!-- <div class="order-status">
|
||||
<span>工单状态操作:</span>
|
||||
<el-select v-model="selectedOrder" placeholder="选择工单" size="small" style="width: 200px;">
|
||||
<el-option v-for="order in workOrderOptions" :key="order.value" :label="order.label"
|
||||
:value="order.value" />
|
||||
</el-select>
|
||||
<el-button size="small" type="warning" @click="pauseWorkOrder">暂停工单</el-button>
|
||||
</div> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<!-- 日/月完成率切换标签 -->
|
||||
<div class="tab-container">
|
||||
<div :class="['tab', { active: activeTab === 'day' }]" @click="switchTab('day')">日生产完成率</div>
|
||||
<div :class="['tab', { active: activeTab === 'month' }]" @click="switchTab('month')">月生产完成率</div>
|
||||
</div>
|
||||
|
||||
<!-- 进度条组件 -->
|
||||
<div class="progress-container">
|
||||
<div class="progress-info">
|
||||
<div class="info-item">
|
||||
<span class="label">目标值:</span>
|
||||
<span class="value">{{ targetValue }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">实际值:</span>
|
||||
<span class="value actual">{{ actualValue }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">完成率:</span>
|
||||
<span class="value">{{ completionRate }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress-bar-container">
|
||||
<div class="progress-bar" :style="{ width: progressBarWidth + '%' }" :class="{
|
||||
'progress-success': completionRate >= 90,
|
||||
'progress-warning': completionRate >= 70 && completionRate < 90,
|
||||
'progress-danger': completionRate < 70
|
||||
}">
|
||||
<span class="progress-text">{{ completionRate }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 查询区域 -->
|
||||
<!-- <div class="query-area">
|
||||
<el-form :model="queryForm" inline @submit.prevent>
|
||||
<el-form-item label="选择日期">
|
||||
<el-date-picker v-model="queryForm.date" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div> -->
|
||||
|
||||
<!-- 整体完成率柱状图 -->
|
||||
<!-- <div class="chart-container">
|
||||
<h3>整体生产完成率(目标vs实际)</h3>
|
||||
<div id="completionChart" style="width: 20%; height: 20vh;"></div>
|
||||
</div> -->
|
||||
|
||||
<!-- 小组小时产量统计表格 -->
|
||||
<div class="table-container">
|
||||
<!-- 固定表头 -->
|
||||
<div class="table-header">
|
||||
<table class="production-table">
|
||||
<div v-if="loading" style="text-align: center; padding: 20px;">
|
||||
<el-icon size="20">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
<span style="margin-left: 8px;">加载中...</span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="hourlyProductionList.length === 0"
|
||||
style="text-align: center; padding: 20px; color: #909399;">
|
||||
暂无生产数据
|
||||
</div>
|
||||
|
||||
<div v-else class="scroll-wrapper">
|
||||
<table class="production-table-header">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>小组</th>
|
||||
<th>工单编号</th>
|
||||
<th>型号</th>
|
||||
<th>排班时段</th>
|
||||
<th>8:30目标</th>
|
||||
<th>8:30实际</th>
|
||||
<th>9:30目标</th>
|
||||
<th>9:30实际</th>
|
||||
<th>10:30目标</th>
|
||||
<th>10:30实际</th>
|
||||
<th>11:30目标</th>
|
||||
<th>11:30实际</th>
|
||||
<th>13:30目标</th>
|
||||
<th>13:30实际</th>
|
||||
<th>14:30目标</th>
|
||||
<th>14:30实际</th>
|
||||
<th>15:30目标</th>
|
||||
<th>15:30实际</th>
|
||||
<th>16:30目标</th>
|
||||
<th>16:30实际</th>
|
||||
<th>8:00目标</th>
|
||||
<th>8:00实际</th>
|
||||
<th>9:00目标</th>
|
||||
<th>9:00实际</th>
|
||||
<th>10:00目标</th>
|
||||
<th>10:00实际</th>
|
||||
<th>11:00目标</th>
|
||||
<th>11:00实际</th>
|
||||
<th>12:00目标</th>
|
||||
<th>12:00实际</th>
|
||||
<th>13:00目标</th>
|
||||
<th>13:00实际</th>
|
||||
<th>14:00目标</th>
|
||||
<th>14:00实际</th>
|
||||
<th>15:00目标</th>
|
||||
<th>15:00实际</th>
|
||||
<th>16:00目标</th>
|
||||
<th>16:00实际</th>
|
||||
<th>17:00目标</th>
|
||||
<th>17:00实际</th>
|
||||
<th>18:00目标</th>
|
||||
<th>18:00实际</th>
|
||||
<th>19:00目标</th>
|
||||
<th>19:00实际</th>
|
||||
<th>20:00目标</th>
|
||||
<th>20:00实际</th>
|
||||
<th>21:00目标</th>
|
||||
<th>21:00实际</th>
|
||||
<th>当日总目标</th>
|
||||
<th>当日实际</th>
|
||||
<th>完成率</th>
|
||||
@ -106,35 +60,45 @@
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 可滚动的数据行 -->
|
||||
<div class="scroll-wrapper">
|
||||
<vue3-seamless-scroll :list="hourlyProductionList" :wheel="true" :step="0.3" :hover="true"
|
||||
direction="up" class="scroll-table">
|
||||
<table class="production-table">
|
||||
<!-- 表格内容:无缝滚动 -->
|
||||
<Vue3SeamlessScroll class="seamless-scroll" :list="hourlyProductionList" :step="0.3" :hover="true"
|
||||
direction="up" :singleHeight="60" :isWatch="true">
|
||||
<table class="production-table-body">
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in hourlyProductionList" :key="index">
|
||||
<td>{{ item.groupName }}</td>
|
||||
<td>{{ item.orderNo }}</td>
|
||||
<td>{{ item.model }}</td>
|
||||
<td>{{ item.model || '-' }}</td>
|
||||
<td>{{ item.shiftTime }}</td>
|
||||
<td>{{ item['8:30Target'] }}</td>
|
||||
<td>{{ item['8:30Actual'] }}</td>
|
||||
<td>{{ item['9:30Target'] }}</td>
|
||||
<td>{{ item['9:30Actual'] }}</td>
|
||||
<td>{{ item['10:30Target'] }}</td>
|
||||
<td>{{ item['10:30Actual'] }}</td>
|
||||
<td>{{ item['11:30Target'] }}</td>
|
||||
<td>{{ item['11:30Actual'] }}</td>
|
||||
<td>{{ item['13:30Target'] }}</td>
|
||||
<td>{{ item['13:30Actual'] }}</td>
|
||||
<td>{{ item['14:30Target'] }}</td>
|
||||
<td>{{ item['14:30Actual'] }}</td>
|
||||
<td>{{ item['15:30Target'] }}</td>
|
||||
<td>{{ item['15:30Actual'] }}</td>
|
||||
<td>{{ item['16:30Target'] }}</td>
|
||||
<td>{{ item['16:30Actual'] }}</td>
|
||||
<td>{{ item['8:00Target'] || 0 }}</td>
|
||||
<td>{{ item['8:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['9:00Target'] || 0 }}</td>
|
||||
<td>{{ item['9:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['10:00Target'] || 0 }}</td>
|
||||
<td>{{ item['10:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['11:00Target'] || 0 }}</td>
|
||||
<td>{{ item['11:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['12:00Target'] || 0 }}</td>
|
||||
<td>{{ item['12:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['13:00Target'] || 0 }}</td>
|
||||
<td>{{ item['13:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['14:00Target'] || 0 }}</td>
|
||||
<td>{{ item['14:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['15:00Target'] || 0 }}</td>
|
||||
<td>{{ item['15:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['16:00Target'] || 0 }}</td>
|
||||
<td>{{ item['16:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['17:00Target'] || 0 }}</td>
|
||||
<td>{{ item['17:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['18:00Target'] || 0 }}</td>
|
||||
<td>{{ item['18:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['19:00Target'] || 0 }}</td>
|
||||
<td>{{ item['19:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['20:00Target'] || 0 }}</td>
|
||||
<td>{{ item['20:00Actual'] || 0 }}</td>
|
||||
<td>{{ item['21:00Target'] || 0 }}</td>
|
||||
<td>{{ item['21:00Actual'] || 0 }}</td>
|
||||
<td>{{ item.dailyTarget }}</td>
|
||||
<td>{{ item.dailyActual }}</td>
|
||||
<td>
|
||||
@ -142,267 +106,132 @@
|
||||
<span style="margin-left: 5px;">{{ item.completionRate }}%</span>
|
||||
</td>
|
||||
<td>
|
||||
<el-tag :type="item.status === '正常生产' ? 'success' : 'warning'">
|
||||
{{ item.status }}
|
||||
<el-tag :type="getStatusTagType(item.status)">
|
||||
{{ getStatusText(item.status) }}
|
||||
</el-tag>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</vue3-seamless-scroll>
|
||||
</Vue3SeamlessScroll>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { Loading } from '@element-plus/icons-vue'
|
||||
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
|
||||
|
||||
// 顶部操作栏数据
|
||||
const groupCount = ref(18)
|
||||
const selectedOrder = ref('WO001(Model-X1)')
|
||||
const workOrderOptions = ref([
|
||||
{ label: 'WO001(Model-X1)', value: 'WO001(Model-X1)' },
|
||||
{ label: 'WO002(Model-Y2)', value: 'WO002(Model-Y2)' },
|
||||
{ label: 'WO003(Model-Z3)', value: 'WO003(Model-Z3)' }
|
||||
])
|
||||
|
||||
// 标签切换
|
||||
import { ProPlanAchievementrate } from "@/api/productManagement/analysisOfProductionCompletionRate"
|
||||
const activeTab = ref('day')
|
||||
const loading = ref(false)
|
||||
const hourlyProductionList = ref([])
|
||||
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
'未开始': '未开始',
|
||||
'开始': '正常生产',
|
||||
'完成': '已完成',
|
||||
'暂停': '暂停生产'
|
||||
}
|
||||
return statusMap[status] || status
|
||||
}
|
||||
|
||||
const getStatusTagType = (status) => {
|
||||
const typeMap = {
|
||||
'未开始': 'info',
|
||||
'开始': 'success',
|
||||
'完成': 'primary',
|
||||
'暂停': 'warning'
|
||||
}
|
||||
return typeMap[status] || 'info'
|
||||
}
|
||||
|
||||
const transformApiData = (apiData) => {
|
||||
if (!Array.isArray(apiData)) return []
|
||||
|
||||
return apiData.map(item => {
|
||||
const tableItem = {
|
||||
groupName: item.groupName || '',
|
||||
orderNo: item.workOrder || '',
|
||||
model: item.model,
|
||||
shiftTime: item.workTimePeriod || '',
|
||||
dailyTarget: item.deliveryNum || 0,
|
||||
dailyActual: item.completionNum || 0,
|
||||
completionRate: item.completionRate || 0,
|
||||
status: item.status || ''
|
||||
}
|
||||
const hours = ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00']
|
||||
hours.forEach(hour => {
|
||||
tableItem[`${hour}Target`] = 0
|
||||
tableItem[`${hour}Actual`] = 0
|
||||
})
|
||||
|
||||
if (Array.isArray(item.list)) {
|
||||
item.list.forEach(hourItem => {
|
||||
const cleanTime = hourItem.startTime.replace(/:/g, ':').replace(/\s/g, '')
|
||||
if (hours.includes(cleanTime)) {
|
||||
tableItem[`${cleanTime}Target`] = hourItem.planNum || 0
|
||||
tableItem[`${cleanTime}Actual`] = hourItem.completionNum || 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return tableItem
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const getProductionData = () => {
|
||||
loading.value = true
|
||||
ProPlanAchievementrate().then(res => {
|
||||
loading.value = false
|
||||
if (res && res.code === 200 && Array.isArray(res.data)) {
|
||||
hourlyProductionList.value = transformApiData(res.data)
|
||||
console.log('接口数据加载成功:', res.data)
|
||||
} else {
|
||||
hourlyProductionList.value = []
|
||||
console.error('接口返回格式异常:', res)
|
||||
}
|
||||
}).catch(err => {
|
||||
loading.value = false
|
||||
hourlyProductionList.value = []
|
||||
console.error('接口请求失败:', err)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const switchTab = (tab) => {
|
||||
activeTab.value = tab
|
||||
// 切换标签后重新渲染图表
|
||||
initChart()
|
||||
getProductionData()
|
||||
}
|
||||
|
||||
// 进度条数据
|
||||
const targetValue = ref(5000) // 目标值
|
||||
const actualValue = ref(4200) // 实际值
|
||||
const completionRate = computed(() => {
|
||||
return Math.round((actualValue.value / targetValue.value) * 100)
|
||||
})
|
||||
const progressBarWidth = computed(() => {
|
||||
return Math.min(100, Math.max(0, (actualValue.value / targetValue.value) * 100))
|
||||
})
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
date: '2026-01-14'
|
||||
})
|
||||
|
||||
// 小组小时产量数据(完全匹配截图)
|
||||
const hourlyProductionList = ref([
|
||||
{
|
||||
groupName: '第5组',
|
||||
orderNo: 'WO001',
|
||||
model: 'Model-X1',
|
||||
shiftTime: '9:00-18:00',
|
||||
'8:30Target': 14,
|
||||
'8:30Actual': 13,
|
||||
'9:30Target': 16,
|
||||
'9:30Actual': 14,
|
||||
'10:30Target': 14,
|
||||
'10:30Actual': 11,
|
||||
'11:30Target': 15,
|
||||
'11:30Actual': 12,
|
||||
'13:30Target': 15,
|
||||
'13:30Actual': 11,
|
||||
'14:30Target': 14,
|
||||
'14:30Actual': 11,
|
||||
'15:30Target': 15,
|
||||
'15:30Actual': 14,
|
||||
'16:30Target': 14,
|
||||
'16:30Actual': 13,
|
||||
dailyTarget: 123,
|
||||
dailyActual: 99,
|
||||
completionRate: 80.49,
|
||||
status: '正常生产'
|
||||
},
|
||||
{
|
||||
groupName: '第6组',
|
||||
orderNo: 'WO002',
|
||||
model: 'Model-Y2',
|
||||
shiftTime: '8:30-17:30',
|
||||
'8:30Target': 29,
|
||||
'8:30Actual': 25,
|
||||
'9:30Target': 28,
|
||||
'9:30Actual': 21,
|
||||
'10:30Target': 27,
|
||||
'10:30Actual': 22,
|
||||
'11:30Target': 28,
|
||||
'11:30Actual': 24,
|
||||
'13:30Target': 28,
|
||||
'13:30Actual': 22,
|
||||
'14:30Target': 28,
|
||||
'14:30Actual': 25,
|
||||
'15:30Target': 28,
|
||||
'15:30Actual': 20,
|
||||
'16:30Target': 27,
|
||||
'16:30Actual': 24,
|
||||
dailyTarget: 227,
|
||||
dailyActual: 183,
|
||||
completionRate: 80.62,
|
||||
status: '正常生产'
|
||||
},
|
||||
{
|
||||
groupName: '第7组',
|
||||
orderNo: 'WO003',
|
||||
model: 'Model-Z3',
|
||||
shiftTime: '8:30-17:30',
|
||||
'8:30Target': 62,
|
||||
'8:30Actual': 50,
|
||||
'9:30Target': 63,
|
||||
'9:30Actual': 59,
|
||||
'10:30Target': 56,
|
||||
'10:30Actual': 50,
|
||||
'11:30Target': 64,
|
||||
'11:30Actual': 48,
|
||||
'13:30Target': 63,
|
||||
'13:30Actual': 58,
|
||||
'14:30Target': 61,
|
||||
'14:30Actual': 45,
|
||||
'15:30Target': 57,
|
||||
'15:30Actual': 48,
|
||||
'16:30Target': 57,
|
||||
'16:30Actual': 48,
|
||||
dailyTarget: 472,
|
||||
dailyActual: 406,
|
||||
completionRate: 86.02,
|
||||
status: '暂停生产'
|
||||
},
|
||||
{
|
||||
groupName: '第8组',
|
||||
orderNo: 'WO001',
|
||||
model: 'Model-X1',
|
||||
shiftTime: '8:30-17:30',
|
||||
'8:30Target': 48,
|
||||
'8:30Actual': 45,
|
||||
'9:30Target': 41,
|
||||
'9:30Actual': 37,
|
||||
'10:30Target': 49,
|
||||
'10:30Actual': 40,
|
||||
'11:30Target': 46,
|
||||
'11:30Actual': 43,
|
||||
'13:30Target': 47,
|
||||
'13:30Actual': 46,
|
||||
'14:30Target': 43,
|
||||
'14:30Actual': 34,
|
||||
'15:30Target': 41,
|
||||
'15:30Actual': 39,
|
||||
'16:30Target': 48,
|
||||
'16:30Actual': 46,
|
||||
dailyTarget: 358,
|
||||
dailyActual: 330,
|
||||
completionRate: 92.18,
|
||||
status: '正常生产'
|
||||
}
|
||||
])
|
||||
|
||||
// 组数增减
|
||||
const decreaseGroup = () => {
|
||||
if (groupCount.value > 15) groupCount.value--
|
||||
}
|
||||
const increaseGroup = () => {
|
||||
if (groupCount.value < 20) groupCount.value++
|
||||
}
|
||||
|
||||
// 暂停工单
|
||||
const pauseWorkOrder = () => {
|
||||
// 这里可以添加暂停工单的接口调用
|
||||
console.log('暂停工单:', selectedOrder.value)
|
||||
alert(`已暂停工单: ${selectedOrder.value}`)
|
||||
}
|
||||
|
||||
// 查询与重置
|
||||
const handleSearch = () => {
|
||||
console.log('搜索条件:', queryForm)
|
||||
// 这里可以添加搜索接口调用
|
||||
}
|
||||
const handleReset = () => {
|
||||
queryForm.date = '2026-01-14'
|
||||
}
|
||||
|
||||
// 初始化图表
|
||||
let chartInstance = null
|
||||
const initChart = () => {
|
||||
if (chartInstance) chartInstance.dispose()
|
||||
chartInstance = echarts.init(document.getElementById('completionChart'))
|
||||
|
||||
const option = {
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||
legend: { data: ['目标产量', '实际产量'] },
|
||||
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
|
||||
xAxis: { type: 'category', data: ['整体生产'] },
|
||||
yAxis: { type: 'value', max: 5000 },
|
||||
series: [
|
||||
{
|
||||
name: '目标产量',
|
||||
type: 'bar',
|
||||
data: [4800],
|
||||
itemStyle: { color: '#409eff' }
|
||||
},
|
||||
{
|
||||
name: '实际产量',
|
||||
type: 'bar',
|
||||
data: [4200],
|
||||
itemStyle: { color: '#67c23a' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chartInstance.setOption(option)
|
||||
window.addEventListener('resize', () => chartInstance.resize())
|
||||
}
|
||||
|
||||
// 页面挂载时初始化
|
||||
onMounted(() => {
|
||||
// initChart()
|
||||
getProductionData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.production-completion-rate {
|
||||
/* padding: 20px; */
|
||||
/* background-color: #f5f7fa; */
|
||||
/* min-height: 100vh; */
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 10px 15px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.group-config,
|
||||
.order-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
/* padding: 10px; */
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-radius: 4px 4px 0 0;
|
||||
overflow: hidden;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #409eff;
|
||||
color: #409eff;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s;
|
||||
width: 45vw;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
@ -410,158 +239,90 @@ onMounted(() => {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.progress-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.value.actual {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.progress-bar-container {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: #ebeef5;
|
||||
border-radius: 15px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
width: 0;
|
||||
background: linear-gradient(to right, #409eff, #67c23a);
|
||||
border-radius: 15px;
|
||||
transition: width 0.5s ease-in-out;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-success {
|
||||
background: linear-gradient(to right, #67c23a, #52b12d);
|
||||
}
|
||||
|
||||
/* .progress-warning {
|
||||
background: linear-gradient(to right, #e6a23c, #d78c1b);
|
||||
} */
|
||||
|
||||
.progress-danger {
|
||||
background: linear-gradient(to right, #f56c6c, #f34b4b);
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.query-area {
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.table-container {
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.table-header table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.scroll-wrapper {
|
||||
position: relative;
|
||||
height: 45vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
height: 100%;
|
||||
background-color: red !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.production-table {
|
||||
height: 67vh;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.production-table-header {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
min-width: 120px;
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.production-table th,
|
||||
.production-table td {
|
||||
.production-table-header th {
|
||||
border: 1px solid #ebeef5;
|
||||
padding: 8px 12px;
|
||||
border-bottom: none;
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.production-table th {
|
||||
white-space: normal;
|
||||
min-width: 100px;
|
||||
background-color: #eef2f7;
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
z-index: 999 !important;
|
||||
}
|
||||
|
||||
.seamless-scroll {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.production-table td {
|
||||
background-color: #fff;
|
||||
.production-table-body {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
min-width: 1200px;
|
||||
}
|
||||
|
||||
.production-table-body tr:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.production-table-body td {
|
||||
border: 1px solid #ebeef5;
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
min-width: 100px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.scroll-wrapper::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.scroll-wrapper::-webkit-scrollbar-thumb {
|
||||
background-color: #dcdfe6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.scroll-wrapper::-webkit-scrollbar-track {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user