|
|
@@ -0,0 +1,324 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ :title="dialogTitle"
|
|
|
+ :visible.sync="visible"
|
|
|
+ width="80%"
|
|
|
+ append-to-body
|
|
|
+ top="6vh"
|
|
|
+ >
|
|
|
+ <dotLineDetail
|
|
|
+ v-if="detailType === 'plan'"
|
|
|
+ :workOrderInfo="workOrderInfo"
|
|
|
+ ></dotLineDetail>
|
|
|
+
|
|
|
+ <div v-else v-loading="taskLoading" class="task-dot-line">
|
|
|
+ <el-empty
|
|
|
+ v-if="processList.length === 0 && !taskLoading"
|
|
|
+ description="暂无任务布点详情"
|
|
|
+ ></el-empty>
|
|
|
+ <template v-else>
|
|
|
+ <el-tabs
|
|
|
+ v-model="activeProcessId"
|
|
|
+ v-loading="tabsLoading"
|
|
|
+ type="border-card"
|
|
|
+ class="process_list"
|
|
|
+ style="margin-bottom: 20px"
|
|
|
+ >
|
|
|
+ <el-tab-pane
|
|
|
+ v-for="item in processList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :name="item.id"
|
|
|
+ >
|
|
|
+ <span style="color: green">
|
|
|
+ 工序编码:{{ item.code }},所属班组:{{
|
|
|
+ item.teamName
|
|
|
+ }},执行模式:{{ item.executionTypeLabel }}
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <div class="toolbar-wrap">
|
|
|
+ <div
|
|
|
+ style="display: inline-block"
|
|
|
+ v-if="item.hasDispatched"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ class="text"
|
|
|
+ style="font-weight: bold; font-size: 14px; margin-right: 8px"
|
|
|
+ >指派:</span>
|
|
|
+ <el-radio-group
|
|
|
+ :value="item.assignType"
|
|
|
+ size="mini"
|
|
|
+ disabled
|
|
|
+ >
|
|
|
+ <el-radio-button
|
|
|
+ v-if="item.assignType === 1"
|
|
|
+ :label="1"
|
|
|
+ >工位</el-radio-button>
|
|
|
+ <el-radio-button
|
|
|
+ v-if="item.assignType === 2"
|
|
|
+ :label="2"
|
|
|
+ >人员</el-radio-button>
|
|
|
+ <el-radio-button
|
|
|
+ v-if="item.assignType === 3"
|
|
|
+ :label="3"
|
|
|
+ >产线</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="item.allDispatched"
|
|
|
+ class="describe"
|
|
|
+ style="color: #67c23a"
|
|
|
+ >
|
|
|
+ 该工序已完成派单!
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="item.startDate && item.endDate"
|
|
|
+ style="margin-left: 50px; display: inline-block"
|
|
|
+ >
|
|
|
+ 时间段: {{ item.startDate }} ----- {{ item.endDate }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table
|
|
|
+ v-if="item.hasDispatched"
|
|
|
+ :data="item.list"
|
|
|
+ border
|
|
|
+ size="small"
|
|
|
+ class="task-table"
|
|
|
+ max-height="420"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ type="index"
|
|
|
+ label="序号"
|
|
|
+ width="55"
|
|
|
+ align="center"
|
|
|
+ fixed="left"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="assigneeName"
|
|
|
+ :label="getAssignLabel(item.assignType)"
|
|
|
+ min-width="150"
|
|
|
+ align="center"
|
|
|
+ show-overflow-tooltip
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="statusDesc"
|
|
|
+ label="状态"
|
|
|
+ min-width="100"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="disposalStatusLabel"
|
|
|
+ label="接收状态"
|
|
|
+ min-width="100"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="quantity"
|
|
|
+ label="数量"
|
|
|
+ min-width="100"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="weight"
|
|
|
+ :label="weightColumnLabel"
|
|
|
+ min-width="100"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="startTime"
|
|
|
+ label="计划开始时间"
|
|
|
+ min-width="170"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="endTime"
|
|
|
+ label="计划完成时间"
|
|
|
+ min-width="170"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <el-empty
|
|
|
+ v-if="!item.hasDispatched"
|
|
|
+ description="该工序未派单"
|
|
|
+ ></el-empty>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import { listPlanDotLine } from '@/api/produceOrder/index';
|
|
|
+ import { listByMesWorkOrder } from '@/api/mainData/index.js';
|
|
|
+ import dotLineDetail from './dotLineDetail.vue';
|
|
|
+
|
|
|
+ const EXEC_TYPE_MAP = { 0: '自制', 1: '请托', 2: '委外' };
|
|
|
+ const ASSIGN_TYPE_LABEL = { 1: '工位名称', 2: '人员名称', 3: '产线名称' };
|
|
|
+
|
|
|
+ export default {
|
|
|
+ components: { dotLineDetail },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ visible: false,
|
|
|
+ detailType: 'plan',
|
|
|
+ workOrderInfo: {},
|
|
|
+ taskLoading: false,
|
|
|
+ tabsLoading: false,
|
|
|
+ processList: [],
|
|
|
+ activeProcessId: ''
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ dialogTitle() {
|
|
|
+ return this.detailType === 'plan' ? '计划布点详情' : '任务布点详情';
|
|
|
+ },
|
|
|
+ weightColumnLabel() {
|
|
|
+ const u = this.workOrderInfo.weightUnit;
|
|
|
+ return u ? `重量(${u})` : '重量';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ open(type, row) {
|
|
|
+ this.detailType = type;
|
|
|
+ this.workOrderInfo = { ...row };
|
|
|
+ this.visible = true;
|
|
|
+ if (type === 'task') {
|
|
|
+ this.loadTaskDetail();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ getAssignLabel(assignType) {
|
|
|
+ return ASSIGN_TYPE_LABEL[assignType] || '名称';
|
|
|
+ },
|
|
|
+
|
|
|
+ async loadTaskDetail() {
|
|
|
+ const {
|
|
|
+ productionPlanId,
|
|
|
+ produceRoutingId,
|
|
|
+ apsWorkOrderId,
|
|
|
+ categoryId,
|
|
|
+ id
|
|
|
+ } = this.workOrderInfo;
|
|
|
+
|
|
|
+ if (!productionPlanId || !produceRoutingId) {
|
|
|
+ this.processList = [];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.taskLoading = true;
|
|
|
+ try {
|
|
|
+ const [allRes, existRes] = await Promise.all([
|
|
|
+ listPlanDotLine({
|
|
|
+ planId: productionPlanId,
|
|
|
+ routingId: produceRoutingId
|
|
|
+ }),
|
|
|
+ listByMesWorkOrder({
|
|
|
+ apsWorkOrderId,
|
|
|
+ categoryId,
|
|
|
+ mesWorkOrderId: id,
|
|
|
+ produceRoutingId
|
|
|
+ }).catch(() => [])
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if (!allRes || allRes.length === 0) {
|
|
|
+ this.processList = [];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const assignMap = {};
|
|
|
+ (existRes || []).forEach((item) => {
|
|
|
+ if (item.assignees && item.assignees.length > 0) {
|
|
|
+ assignMap[item.taskId] = item.assignees;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ this.processList = allRes.map((item, index) => {
|
|
|
+ const allAssignees = assignMap[item.sourceTaskId] || [];
|
|
|
+
|
|
|
+ const dispatchedList = allAssignees
|
|
|
+ .filter((a) => a.status && a.status.code == 1)
|
|
|
+ .map((a) => ({
|
|
|
+ ...a,
|
|
|
+ assigneeName: a.assigneeName || '',
|
|
|
+ statusDesc: a.status?.desc || '',
|
|
|
+ disposalStatusLabel:
|
|
|
+ a.disposalStatus == 1
|
|
|
+ ? '已接收'
|
|
|
+ : a.disposalStatus == 2
|
|
|
+ ? '已拒绝'
|
|
|
+ : '未接收',
|
|
|
+ quantity: a.quantity ?? '',
|
|
|
+ weight: a.weight ?? '',
|
|
|
+ startTime: a.startTime || '',
|
|
|
+ endTime: a.endTime || ''
|
|
|
+ }));
|
|
|
+
|
|
|
+ let assignType = 1;
|
|
|
+ if (dispatchedList.length > 0) {
|
|
|
+ assignType = dispatchedList[0].assigneeType?.code || 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ const starts = dispatchedList
|
|
|
+ .map((a) => a.startTime)
|
|
|
+ .filter(Boolean);
|
|
|
+ const ends = dispatchedList
|
|
|
+ .map((a) => a.endTime)
|
|
|
+ .filter(Boolean);
|
|
|
+
|
|
|
+ return {
|
|
|
+ id: item.sourceTaskId,
|
|
|
+ name: item.taskName || `工序${index + 1}`,
|
|
|
+ code: item.taskCode || '',
|
|
|
+ teamName: item.executionTeamName || '',
|
|
|
+ executionType: item.executionType,
|
|
|
+ executionTypeLabel: EXEC_TYPE_MAP[item.executionType] ?? '',
|
|
|
+ assignType,
|
|
|
+ hasDispatched: dispatchedList.length > 0,
|
|
|
+ allDispatched:
|
|
|
+ allAssignees.length > 0 &&
|
|
|
+ allAssignees.every((a) => a.status?.code == 1),
|
|
|
+ list: dispatchedList,
|
|
|
+ startDate: starts.length ? starts.sort()[0] : '',
|
|
|
+ endDate: ends.length ? ends.sort().reverse()[0] : ''
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.processList.length > 0) {
|
|
|
+ this.activeProcessId = this.processList[0].id;
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ this.processList = [];
|
|
|
+ this.$message.error(err.message || '获取任务布点详情失败');
|
|
|
+ } finally {
|
|
|
+ this.taskLoading = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .task-dot-line {
|
|
|
+ min-height: 300px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .toolbar-wrap {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin: 12px 0;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .describe {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .task-table {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+</style>
|