二期修改
This commit is contained in:
parent
84a938afeb
commit
5f08e47a2c
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="equipment-rate-container">
|
||||
<h2>设备停机率统计(当日)</h2>
|
||||
<!-- <h2>设备停机率统计(当日)</h2>
|
||||
<div class="table-container">
|
||||
<div class="table-header">
|
||||
<div class="cell">产线名称</div>
|
||||
@ -23,7 +23,37 @@
|
||||
</vue3-seamless-scroll>
|
||||
</div>
|
||||
|
||||
<div v-else class="empty-tip">暂无有派工的产线数据</div>
|
||||
<div v-else class="empty-tip">暂无有派工的产线数据</div> -->
|
||||
<!-- </div> -->
|
||||
<div class="equipment-rate-container">
|
||||
<!-- <h2>设备开机率统计(当日)</h2> -->
|
||||
<el-form :model="queryParams" label-position="right" inline ref="queryRef" @submit.prevent>
|
||||
<el-form-item label="搜索时间" prop="DateTimeRange">
|
||||
<el-date-picker v-model="queryParams.DateTimeRange" type="daterange" :clearable="false"
|
||||
unlink-panels range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"
|
||||
:shortcuts="shortcuts" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
|
||||
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData" v-loading="loading" ref="table" border highlight-current-row
|
||||
@sort-change="sortChange">
|
||||
<el-table-column label="序号" type="index" width="70" align="center"></el-table-column>
|
||||
<el-table-column prop="lineName" label="产线名称" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="lineCode" label="产线编码" align="center" />
|
||||
<el-table-column prop="downtimeHours" label="计划排产时间(小时)" align="center" />
|
||||
<el-table-column prop="downtimeRate" label="停机率" align="center" :show-overflow-tooltip="true" />
|
||||
</el-table>
|
||||
|
||||
<div style="margin-top: 20px; display: flex; justify-content: end;">
|
||||
<el-pagination v-model:current-page="queryParams.pageNum" background
|
||||
v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :disabled="total === 0"
|
||||
:layout="`total, sizes, prev, pager, next, jumper`" :total="total" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -32,25 +62,96 @@
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
|
||||
import { getProductdatatable } from "@/api/equipmentDowntimeRate/index.js"
|
||||
const allLines = ref([])
|
||||
|
||||
const getProductdatatableData = () => {
|
||||
getProductdatatable().then(res => {
|
||||
if (res.code === 200) {
|
||||
allLines.value = res.data.map(item => {
|
||||
return {
|
||||
lineName: item.lineName,
|
||||
lineCode: item.lineCode,
|
||||
planHours: item.planHours,
|
||||
downtimeHours: item.downtimeHours,
|
||||
downtimeRate: item.downtimeRate,
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
const loading = ref(false)
|
||||
const rawDataList = ref([])
|
||||
// 查询参数
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
DateTimeRange: [
|
||||
new Date(),
|
||||
new Date()
|
||||
]
|
||||
})
|
||||
|
||||
// 计算总条数
|
||||
const total = computed(() => rawDataList.value.length)
|
||||
|
||||
const tableData = computed(() => {
|
||||
const start = (queryParams.pageNum - 1) * queryParams.pageSize
|
||||
const end = start + queryParams.pageSize
|
||||
return rawDataList.value.slice(start, end)
|
||||
})
|
||||
|
||||
const formatDateToYYYYMMDD = (date) => {
|
||||
if (!date) return ''
|
||||
const d = new Date(date)
|
||||
const year = d.getFullYear()
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
// 获取数据列表
|
||||
const getProductdatatableData = () => {
|
||||
let data = {
|
||||
startTime: formatDateToYYYYMMDD(queryParams.DateTimeRange[0]),
|
||||
endTime: formatDateToYYYYMMDD(queryParams.DateTimeRange[1])
|
||||
}
|
||||
console.log('c', data);
|
||||
loading.value = true,
|
||||
getProductdatatable(data).then(res => {
|
||||
loading.value = false
|
||||
if (res.code === 200) {
|
||||
console.log('设备开机率', res);
|
||||
// 保存原始完整数据
|
||||
rawDataList.value = res.data || []
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
rawDataList.value = []
|
||||
})
|
||||
}
|
||||
getProductdatatableData()
|
||||
|
||||
// 每页条数改变时触发
|
||||
const handleSizeChange = (val) => {
|
||||
queryParams.pageSize = val
|
||||
// 条数变化后重置页码为1
|
||||
queryParams.pageNum = 1
|
||||
}
|
||||
|
||||
// 当前页码改变时触发
|
||||
const handleCurrentChange = (val) => {
|
||||
queryParams.pageNum = val
|
||||
}
|
||||
const sortChange = (params) => {
|
||||
console.log('排序参数', params);
|
||||
const { prop, order } = params
|
||||
if (prop && order) {
|
||||
const sortType = order === 'ascending' ? 1 : -1
|
||||
rawDataList.value.sort((a, b) => {
|
||||
if (!isNaN(Number(a[prop])) && !isNaN(Number(b[prop]))) {
|
||||
return (Number(a[prop]) - Number(b[prop])) * sortType
|
||||
}
|
||||
return a[prop].localeCompare(b[prop]) * sortType
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.DateTimeRange = [
|
||||
new Date(),
|
||||
new Date()
|
||||
]
|
||||
getProductdatatableData()
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
getProductdatatableData()
|
||||
}
|
||||
onMounted(() => {
|
||||
getProductdatatableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -1,182 +1,151 @@
|
||||
<template>
|
||||
<div class="equipment-rate-container">
|
||||
<h2>设备开机率统计(当日)</h2>
|
||||
<div class="table-container">
|
||||
<div class="table-header">
|
||||
<div class="cell">产线名称</div>
|
||||
<div class="cell">产线编码</div>
|
||||
<div class="cell">实际工作时间(小时)</div>
|
||||
<div class="cell">开机率</div>
|
||||
</div>
|
||||
<!-- <h2>设备开机率统计(当日)</h2> -->
|
||||
<el-form :model="queryParams" label-position="right" inline ref="queryRef" @submit.prevent>
|
||||
<el-form-item label="搜索时间" prop="DateTimeRange">
|
||||
<el-date-picker v-model="queryParams.DateTimeRange" type="daterange" :clearable="false" unlink-panels
|
||||
range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" :shortcuts="shortcuts" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
|
||||
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData" v-loading="loading" ref="table" border highlight-current-row
|
||||
@sort-change="sortChange">
|
||||
<el-table-column label="序号" type="index" width="70" align="center"></el-table-column>
|
||||
<el-table-column prop="lineName" label="产线名称" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="lineCode" label="产线编码" align="center" />
|
||||
<el-table-column prop="poweronHours" label="实际工作时间(小时)" align="center" />
|
||||
<el-table-column prop="poweronRate" label="开机率" align="center" :show-overflow-tooltip="true" />
|
||||
</el-table>
|
||||
|
||||
<div class="scroll-wrapper" v-if="dataLoaded && workingLines.length > 0">
|
||||
<vue3-seamless-scroll :list="workingLines" :step="0.3" :hover="true" direction="up" :singleHeight="60"
|
||||
:isWatch="true" class="scroll-content">
|
||||
|
||||
<div class="table-row" v-for="(line, index) in workingLines" :key="index">
|
||||
<div class="cell">{{ line.lineName }}</div>
|
||||
<div class="cell">{{ line.lineCode }}</div>
|
||||
|
||||
<div class="cell">{{ line.poweronHours }}</div>
|
||||
<div class="cell">
|
||||
{{ line.poweronRate }}
|
||||
</div>
|
||||
</div>
|
||||
</vue3-seamless-scroll>
|
||||
</div>
|
||||
<div v-else class="empty-tip">暂无有派工的产线数据</div>
|
||||
<div style="margin-top: 20px; display: flex; justify-content: end;">
|
||||
<el-pagination v-model:current-page="queryParams.pageNum" background
|
||||
v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :disabled="total === 0"
|
||||
:layout="`total, sizes, prev, pager, next, jumper`" :total="total" @size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
|
||||
import { getProductdatatable } from '@/api/equipmentStartupRate/index.js'
|
||||
const dataLoaded = ref(false)
|
||||
const workingLines = ref([])
|
||||
const getProductdatatableData = () => {
|
||||
getProductdatatable().then(res => {
|
||||
if (res.code === 200) {
|
||||
console.log('设备开机率', res);
|
||||
workingLines.value = res.data.map(item => ({
|
||||
lineName: item.lineName,
|
||||
lineCode: item.lineCode,
|
||||
poweronHours: item.poweronHours,
|
||||
poweronRate: item.poweronRate
|
||||
}));
|
||||
import { start } from 'nprogress';
|
||||
|
||||
dataLoaded.value = true;
|
||||
}
|
||||
})
|
||||
const loading = ref(false)
|
||||
const rawDataList = ref([])
|
||||
// 查询参数
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
DateTimeRange: [
|
||||
new Date(),
|
||||
new Date()
|
||||
]
|
||||
})
|
||||
|
||||
// 计算总条数
|
||||
const total = computed(() => rawDataList.value.length)
|
||||
|
||||
const tableData = computed(() => {
|
||||
const start = (queryParams.pageNum - 1) * queryParams.pageSize
|
||||
const end = start + queryParams.pageSize
|
||||
return rawDataList.value.slice(start, end)
|
||||
})
|
||||
|
||||
const formatDateToYYYYMMDD = (date) => {
|
||||
if (!date) return ''
|
||||
const d = new Date(date)
|
||||
const year = d.getFullYear()
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
// 获取数据列表
|
||||
const getProductdatatableData = () => {
|
||||
let data = {
|
||||
startTime: formatDateToYYYYMMDD(queryParams.DateTimeRange[0]),
|
||||
endTime: formatDateToYYYYMMDD(queryParams.DateTimeRange[1])
|
||||
}
|
||||
console.log('c', data);
|
||||
loading.value = true,
|
||||
getProductdatatable(data).then(res => {
|
||||
loading.value = false
|
||||
if (res.code === 200) {
|
||||
console.log('设备开机率', res);
|
||||
// 保存原始完整数据
|
||||
rawDataList.value = res.data || []
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
rawDataList.value = []
|
||||
})
|
||||
}
|
||||
getProductdatatableData()
|
||||
|
||||
// 每页条数改变时触发
|
||||
const handleSizeChange = (val) => {
|
||||
queryParams.pageSize = val
|
||||
// 条数变化后重置页码为1
|
||||
queryParams.pageNum = 1
|
||||
}
|
||||
|
||||
// 当前页码改变时触发
|
||||
const handleCurrentChange = (val) => {
|
||||
queryParams.pageNum = val
|
||||
}
|
||||
const sortChange = (params) => {
|
||||
console.log('排序参数', params);
|
||||
const { prop, order } = params
|
||||
if (prop && order) {
|
||||
const sortType = order === 'ascending' ? 1 : -1
|
||||
rawDataList.value.sort((a, b) => {
|
||||
if (!isNaN(Number(a[prop])) && !isNaN(Number(b[prop]))) {
|
||||
return (Number(a[prop]) - Number(b[prop])) * sortType
|
||||
}
|
||||
return a[prop].localeCompare(b[prop]) * sortType
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.DateTimeRange = [
|
||||
new Date(),
|
||||
new Date()
|
||||
]
|
||||
getProductdatatableData()
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
getProductdatatableData()
|
||||
}
|
||||
onMounted(() => {
|
||||
getProductdatatableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.equipment-rate-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: "Microsoft YaHei", sans-serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0 0 16px 0;
|
||||
/* margin: 0 0 16px 0; */
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.summary-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.summary-item .label {
|
||||
color: #666;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.summary-item .value {
|
||||
color: #1f2937;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background: #eef2f7;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
font-weight: 600;
|
||||
.el-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cell {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.scroll-wrapper {
|
||||
height: 71vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scroll-content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
transition: background 0.2s;
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background: #f9fafb;
|
||||
}
|
||||
|
||||
.rate-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.rate-tag.success {
|
||||
background: #d1fae5;
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
.rate-tag.warning {
|
||||
background: #fed7aa;
|
||||
color: #c05621;
|
||||
}
|
||||
|
||||
.rate-tag.danger {
|
||||
background: #fee2e2;
|
||||
color: #991b1b;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
height: 71vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cell {
|
||||
padding: 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
/* 分页组件样式优化 */
|
||||
:deep(.el-pagination) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
</style>
|
||||
@ -116,7 +116,7 @@
|
||||
<el-dialog v-model="exportDialog.open" :title="exportDialog.title" width="500" draggable
|
||||
:close-on-click-modal="false">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="导出日期" prop="searchDate">
|
||||
<el-form-item label="日期" prop="searchDate">
|
||||
<el-date-picker v-model="exportDialog.params.searchDate" type="month" placeholder="选择月份"
|
||||
format="YYYY年MM月" value-format="YYYY-MM" class="month-picker" />
|
||||
</el-form-item>
|
||||
@ -225,8 +225,8 @@ const getList = debounce(async () => {
|
||||
|
||||
try {
|
||||
const params = {
|
||||
// SearchYearMonth: selectedMonth.value,
|
||||
SearchYearMonth: '2025-11',
|
||||
SearchYearMonth: selectedMonth.value,
|
||||
// SearchYearMonth: '2025-11',
|
||||
pageNum: queryParams.pageNum,
|
||||
pageSize: queryParams.pageSize,
|
||||
};
|
||||
|
||||
@ -1,8 +1,3 @@
|
||||
<!--
|
||||
* @Descripttion: (生产工单/pro_workorder)
|
||||
* @Author: (admin)
|
||||
* @Date: (2024-07-16)
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
|
||||
@ -32,13 +27,13 @@
|
||||
<el-form-item label="产品名称" prop="productionName">
|
||||
<el-input v-model.trim="queryParams.productionName" clearable placeholder="请输入产品名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="工单状态暂停" prop="customCode">
|
||||
<!-- <el-form-item label="工单状态暂停" prop="customCode">
|
||||
<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>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
<template>
|
||||
<div class="production-completion-rate">
|
||||
<div class="tab-container">
|
||||
<!-- <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> -->
|
||||
<!-- <h2>实时产出(当日)</h2> -->
|
||||
<el-form :model="queryParams" label-position="right" inline ref="queryRef">
|
||||
<el-form-item label="小组">
|
||||
<el-input v-model="queryParams.groupName" placeholder="请输入小组名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
|
||||
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="table-container">
|
||||
<div v-if="loading" style="text-align: center; padding: 20px;">
|
||||
<el-icon size="20">
|
||||
@ -12,108 +22,201 @@
|
||||
<span style="margin-left: 8px;">加载中...</span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="hourlyProductionList.length === 0"
|
||||
style="text-align: center; padding: 20px; color: #909399;">
|
||||
<div v-else-if="displayList.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: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>
|
||||
<th>工单状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<el-table :data="displayList" class="production-table">
|
||||
<el-table-column prop="groupName" label="小组" min-width="100" />
|
||||
<el-table-column prop="orderNo" label="工单编号" min-width="120" />
|
||||
<el-table-column prop="model" label="型号" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row.model || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="shiftTime" label="排班时段" min-width="120" />
|
||||
|
||||
<!-- 表格内容:无缝滚动 -->
|
||||
<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.shiftTime }}</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>
|
||||
<el-progress :percentage="item.completionRate" :width="80" :show-text="false" />
|
||||
<span style="margin-left: 5px;">{{ item.completionRate }}%</span>
|
||||
</td>
|
||||
<td>
|
||||
<el-tag :type="getStatusTagType(item.status)">
|
||||
{{ item.status }}
|
||||
</el-tag>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Vue3SeamlessScroll>
|
||||
<el-table-column label="8:00目标" prop="8:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['8:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="8:00实际" prop="8:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['8:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="9:00目标" prop="9:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['9:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="9:00实际" prop="9:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['9:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="10:00目标" prop="10:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['10:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="10:00实际" prop="10:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['10:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="11:00目标" prop="11:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['11:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="11:00实际" prop="11:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['11:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="12:00目标" prop="12:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['12:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="12:00实际" prop="12:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['12:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="13:00目标" prop="13:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['13:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="13:00实际" prop="13:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['13:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="14:00目标" prop="14:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['14:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="14:00实际" prop="14:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['14:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="15:00目标" prop="15:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['15:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="15:00实际" prop="15:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['15:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="16:00目标" prop="16:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['16:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="16:00实际" prop="16:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['16:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="17:00目标" prop="17:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['17:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="17:00实际" prop="17:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['17:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="18:00目标" prop="18:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['18:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="18:00实际" prop="18:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['18:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="19:00目标" prop="19:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['19:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="19:00实际" prop="19:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['19:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="20:00目标" prop="20:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['20:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="20:00实际" prop="20:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['20:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="21:00目标" prop="21:00Target" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['21:00Target'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="21:00实际" prop="21:00Actual" min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row['21:00Actual'] || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="dailyTarget" label="当日总目标" min-width="120" />
|
||||
<el-table-column prop="dailyActual" label="当日实际" min-width="100" />
|
||||
|
||||
<el-table-column label="完成率" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-progress :percentage="row.completionRate" :width="80" :show-text="false" />
|
||||
<span style="margin-left: 5px;">{{ row.completionRate }}%</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="工单状态" min-width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusTagType(row.status)">
|
||||
{{ getStatusText(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div class="pagination-container">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
|
||||
:current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="totalRecords" background>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -124,9 +227,34 @@ import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { Loading } from '@element-plus/icons-vue'
|
||||
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
|
||||
import { ProPlanAchievementrate, getProductdatatable } from "@/api/productManagement/analysisOfProductionCompletionRate"
|
||||
const queryParams = reactive({
|
||||
groupName: null,
|
||||
})
|
||||
const activeTab = ref('day')
|
||||
const loading = ref(false)
|
||||
const hourlyProductionList = ref([])
|
||||
const allProductionList = ref([])
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
|
||||
// 计算属性:当前页显示的数据
|
||||
const displayList = computed(() => {
|
||||
const start = (currentPage.value - 1) * pageSize.value
|
||||
const end = start + pageSize.value
|
||||
return allProductionList.value.slice(start, end)
|
||||
})
|
||||
|
||||
// 总记录数
|
||||
const totalRecords = computed(() => allProductionList.value.length)
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
// 处理当前页变化
|
||||
const handleCurrentChange = (val) => {
|
||||
currentPage.value = val
|
||||
}
|
||||
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
@ -185,30 +313,37 @@ const transformApiData = (apiData) => {
|
||||
|
||||
const getProductionData = () => {
|
||||
loading.value = true
|
||||
ProPlanAchievementrate().then(res => {
|
||||
ProPlanAchievementrate(queryParams).then(res => {
|
||||
loading.value = false
|
||||
if (res && res.code === 200 && Array.isArray(res.data)) {
|
||||
hourlyProductionList.value = transformApiData(res.data)
|
||||
allProductionList.value = transformApiData(res.data)
|
||||
currentPage.value = 1 // 重置到第一页
|
||||
console.log('接口数据加载成功:', res.data)
|
||||
} else {
|
||||
hourlyProductionList.value = []
|
||||
allProductionList.value = []
|
||||
console.error('接口返回格式异常:', res)
|
||||
}
|
||||
}).catch(err => {
|
||||
loading.value = false
|
||||
hourlyProductionList.value = []
|
||||
allProductionList.value = []
|
||||
console.error('接口请求失败:', err)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const handleQuery = () => {
|
||||
getProductionData()
|
||||
}
|
||||
const resetQuery = () => {
|
||||
queryParams.groupName = null
|
||||
getProductionData()
|
||||
}
|
||||
const switchTab = (tab) => {
|
||||
activeTab.value = tab
|
||||
if (tab === 'day') {
|
||||
getProductionData()
|
||||
} else {
|
||||
hourlyProductionList.value = []
|
||||
|
||||
allProductionList.value = []
|
||||
currentPage.value = 1
|
||||
// getProductdatatable().then(res => {
|
||||
// if (res.code === 200) {
|
||||
// console.log('月生产总数', res);
|
||||
@ -224,11 +359,12 @@ onMounted(() => {
|
||||
|
||||
<style scoped>
|
||||
.production-completion-rate {
|
||||
/* padding: 10px; */
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/*
|
||||
.tab-container {
|
||||
display: flex;
|
||||
|
||||
@ -251,7 +387,6 @@ onMounted(() => {
|
||||
|
||||
.table-container {
|
||||
background-color: #fff;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
@ -267,72 +402,34 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.production-table-header {
|
||||
.production-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
min-width: 120px;
|
||||
position: relative;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.production-table-header th {
|
||||
border: 1px solid #ebeef5;
|
||||
border-bottom: none;
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
min-width: 100px;
|
||||
background-color: #eef2f7;
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 999 !important;
|
||||
}
|
||||
|
||||
.seamless-scroll {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.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 {
|
||||
.scroll-wrapper ::v-deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.scroll-wrapper::-webkit-scrollbar-thumb {
|
||||
.scroll-wrapper ::v-deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background-color: #dcdfe6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.scroll-wrapper::-webkit-scrollbar-track {
|
||||
.scroll-wrapper ::v-deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background-color: #f5f7fa;
|
||||
} */
|
||||
h2 {
|
||||
margin: 0 0 16px 0;
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user