Files
xgy-oa/klp-ui/src/views/wms/productionLine/GanttChart.vue

135 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<div class="gantt-chart-wrapper">
<div ref="ganttContainer" class="gantt-container"></div>
<div class="gantt-info">
<el-card class="task-table-card" shadow="never" style="margin-bottom: 16px;">
<div slot="header">生产任务列表</div>
<el-table :data="tasks" size="mini" stripe>
<el-table-column prop="remark" label="任务名称" min-width="120" />
<el-table-column prop="productId" label="产品ID" width="100" />
<el-table-column prop="startDate" label="开始时间" width="140">
<template slot-scope="scope">{{ formatDate(scope.row.startDate) }}</template>
</el-table-column>
<el-table-column prop="endDate" label="结束时间" width="140">
<template slot-scope="scope">{{ formatDate(scope.row.endDate) }}</template>
</el-table-column>
<el-table-column prop="quantity" label="数量" width="80" />
<el-table-column prop="orderId" label="订单编号" width="120" />
</el-table>
</el-card>
<el-card class="order-table-card" shadow="never">
<div slot="header">相关订单信息</div>
<el-table :data="orders" size="mini" stripe>
<el-table-column prop="orderCode" label="订单编号" width="120" />
<el-table-column prop="salesManager" label="负责人" width="120" />
<el-table-column prop="customerName" label="客户" width="120" />
<el-table-column prop="orderStatus" label="状态" width="100" />
</el-table>
</el-card>
</div>
</div>
</template>
<script>
import Gantt from 'frappe-gantt';
const colorClasses = [
'gantt-color-1', 'gantt-color-2', 'gantt-color-3', 'gantt-color-4', 'gantt-color-5',
'gantt-color-6', 'gantt-color-7', 'gantt-color-8', 'gantt-color-9', 'gantt-color-10'
];
function getColorClass(lineId, orderId, idx) {
// 先按产线分色,同产线下不同订单再细分
if (!lineId) return colorClasses[idx % colorClasses.length];
const base = Math.abs(Number(lineId)) % colorClasses.length;
if (!orderId) return colorClasses[base];
return colorClasses[(base + Math.abs(Number(orderId)) % colorClasses.length) % colorClasses.length];
}
export default {
name: 'GanttChart',
props: {
tasks: {
type: Array,
default: () => []
},
orders: {
type: Array,
default: () => []
}
},
watch: {
tasks: {
handler() {
this.renderGantt();
},
deep: true
}
},
mounted() {
this.renderGantt();
},
methods: {
renderGantt() {
if (!this.$refs.ganttContainer) return;
this.$refs.ganttContainer.innerHTML = '';
if (!this.tasks || this.tasks.length === 0) return;
const data = this.tasks.map((item, idx) => ({
id: String(item.detailId || idx),
name: item.remark || `任务${idx+1}`,
start: item.startDate ? this.formatDate(item.startDate) : '',
end: item.endDate ? this.formatDate(item.endDate) : '',
progress: 100,
custom_class: getColorClass(item.lineId, item.orderId, idx),
}));
// 调试打印data确认custom_class
console.log('Gantt data:', data);
new Gantt(this.$refs.ganttContainer, data, {
view_mode: 'Month',
language: 'zh',
custom_popup_html: null
});
},
formatDate(val) {
if (!val) return '';
const d = typeof val === 'string' ? new Date(val) : val;
return d.toISOString().slice(0, 10);
}
}
};
</script>
<style scoped>
.gantt-chart-wrapper {
width: 100%;
min-height: 400px;
}
.gantt-container {
width: 100%;
min-height: 220px;
height: auto;
overflow: visible;
position: relative;
}
.gantt-container svg {
display: block;
width: 100% !important;
height: auto !important;
}
.gantt-info {
margin-top: 8px;
}
.order-info {
margin-bottom: 8px;
}
</style>
<style>
.bar.gantt-color-1 { fill: #409EFF !important; }
.bar.gantt-color-2 { fill: #67C23A !important; }
.bar.gantt-color-3 { fill: #E6A23C !important; }
.bar.gantt-color-4 { fill: #F56C6C !important; }
.bar.gantt-color-5 { fill: #909399 !important; }
.bar.gantt-color-6 { fill: #13C2C2 !important; }
.bar.gantt-color-7 { fill: #B37FEB !important; }
.bar.gantt-color-8 { fill: #FF85C0 !important; }
.bar.gantt-color-9 { fill: #36CBCB !important; }
.bar.gantt-color-10 { fill: #FFC53D !important; }
</style>