feat: migrate tray management module
- add V2 tray management page for planning production monitoring - add tray management API, route, and i18n entries - update migration task list status for tray management
This commit is contained in:
@@ -3,8 +3,8 @@
|
|||||||
> 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。
|
> 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。
|
||||||
|
|
||||||
- 总功能数:79
|
- 总功能数:79
|
||||||
- 已迁移:20
|
- 已迁移:21
|
||||||
- 未迁移:59
|
- 未迁移:58
|
||||||
|
|
||||||
| 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 |
|
| 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 |
|
||||||
|:---:|---|---|---|---|---|
|
|:---:|---|---|---|---|---|
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
| ⬜ | 计划与生产 (Planning & Production) | 预警中心 (Alert Center) | 预警中心 (Alert Center) | 预警中心 | 待确认 |
|
| ⬜ | 计划与生产 (Planning & Production) | 预警中心 (Alert Center) | 预警中心 (Alert Center) | 预警中心 | 待确认 |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 物料监控 (Material Monitoring) | 物料监控 | 待确认 |
|
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 物料监控 (Material Monitoring) | 物料监控 | 待确认 |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池复投管理 (Rework Management) | 返工管理 | 待确认 |
|
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池复投管理 (Rework Management) | 返工管理 | 待确认 |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 托盘管理 (Tray Management) | 托盘管理 | 待确认 |
|
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 托盘管理 (Tray Management) | 托盘管理 | `src/views/planning-production/production-monitoring/tray-management/` |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 托盘登录 (Tray Registration) | 托盘登记 | 待确认 |
|
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 托盘登录 (Tray Registration) | 托盘登记 | 待确认 |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 设备监控 (Equipment Monitoring) | 设备监控 | 待确认 |
|
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 设备监控 (Equipment Monitoring) | 设备监控 | 待确认 |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池工序管理 (Process Execution) | 工序管理 | 待确认 |
|
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池工序管理 (Process Execution) | 工序管理 | 待确认 |
|
||||||
|
|||||||
67
src/api/planning-production/tray-management.js
Normal file
67
src/api/planning-production/tray-management.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { request } from '@/api/_service'
|
||||||
|
|
||||||
|
const BASE = 'planning_production/produce/tray_manage/'
|
||||||
|
|
||||||
|
function apiParams (method, data = {}) {
|
||||||
|
return {
|
||||||
|
method,
|
||||||
|
platform: 'background',
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTrayManageInfo (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'list',
|
||||||
|
method: 'get',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_list', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeFlowProcess (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'change',
|
||||||
|
method: 'put',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_change', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inactiveTray (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'inactive',
|
||||||
|
method: 'put',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_inactive', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function trayNg (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'ng',
|
||||||
|
method: 'put',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_ng', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rangeNgAndRC (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'ngrc',
|
||||||
|
method: 'put',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_ngrc', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rangeFx (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'fenx',
|
||||||
|
method: 'put',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_fenx', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function cleanTrayNg (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'clean',
|
||||||
|
method: 'put',
|
||||||
|
params: apiParams('planning_production_produce_traymanage_clean', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -922,6 +922,48 @@
|
|||||||
"incomplete": "Incomplete",
|
"incomplete": "Incomplete",
|
||||||
"batch_defect_detail": "Batch Defect Report Details"
|
"batch_defect_detail": "Batch Defect Report Details"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"production_monitoring": {
|
||||||
|
"tray_management": {
|
||||||
|
"tray_code": "Tray Code",
|
||||||
|
"tray_code_placeholder": "Enter tray code",
|
||||||
|
"enter_tray_to_query": "Enter tray code to query",
|
||||||
|
"query": "Search",
|
||||||
|
"reset": "Reset",
|
||||||
|
"current_process": "Current Process",
|
||||||
|
"start_time": "Start Time",
|
||||||
|
"end_time": "End Time",
|
||||||
|
"device_code": "Device Code",
|
||||||
|
"batch": "Batch",
|
||||||
|
"lot": "LOT",
|
||||||
|
"input_battery_count": "Input Battery Count",
|
||||||
|
"input_time": "Input Time",
|
||||||
|
"previous_process": "Previous Process",
|
||||||
|
"status": "Status",
|
||||||
|
"activated": "Activated",
|
||||||
|
"not_activated": "Not Activated",
|
||||||
|
"tray_ng": "Full Tray NG",
|
||||||
|
"prompt": "Notice",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"stop_tray": "Stop Tray",
|
||||||
|
"capacity_sorting": "Capacity Sorting",
|
||||||
|
"clear_tray_ng": "Clear Tray NG",
|
||||||
|
"confirm_stop_tray": "Stop this tray? It and its batteries will be deactivated. Proceed?",
|
||||||
|
"confirm_full_tray_ng": "Mark entire tray as NG?",
|
||||||
|
"full_tray_ng_success": "Tray marked as NG successfully",
|
||||||
|
"confirm_clear_tray_ng": "Clear tray NG status?",
|
||||||
|
"confirm_capacity_resort": "Re-sort capacity?",
|
||||||
|
"cannot_adjust_to_initial_process": "Cannot revert to initial process",
|
||||||
|
"confirm_adjust_tray_process": "Adjust tray process?",
|
||||||
|
"adjust_process_success": "Process adjusted successfully",
|
||||||
|
"operation_success": "Operation successful",
|
||||||
|
"operation_cancelled": "Operation canceled",
|
||||||
|
"battery_id": "Battery Barcode",
|
||||||
|
"grade": "Grade",
|
||||||
|
"activation_status": "Activation Status",
|
||||||
|
"channel_battery_info": "Channel {index} Battery Info"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -922,6 +922,48 @@
|
|||||||
"incomplete": "未完成",
|
"incomplete": "未完成",
|
||||||
"batch_defect_detail": "批次不良报表详情"
|
"batch_defect_detail": "批次不良报表详情"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"production_monitoring": {
|
||||||
|
"tray_management": {
|
||||||
|
"tray_code": "托盘编码",
|
||||||
|
"tray_code_placeholder": "输入托盘编码",
|
||||||
|
"enter_tray_to_query": "请输入托盘编码后查询",
|
||||||
|
"query": "查询",
|
||||||
|
"reset": "重置",
|
||||||
|
"current_process": "当前工序",
|
||||||
|
"start_time": "开始时间",
|
||||||
|
"end_time": "结束时间",
|
||||||
|
"device_code": "设备编码",
|
||||||
|
"batch": "批次",
|
||||||
|
"lot": "LOT",
|
||||||
|
"input_battery_count": "投入电池",
|
||||||
|
"input_time": "投入时间",
|
||||||
|
"previous_process": "上一工序",
|
||||||
|
"status": "状态",
|
||||||
|
"activated": "激活",
|
||||||
|
"not_activated": "未激活",
|
||||||
|
"tray_ng": "整盘NG",
|
||||||
|
"prompt": "提示",
|
||||||
|
"confirm": "确定",
|
||||||
|
"cancel": "取消",
|
||||||
|
"stop_tray": "停止托盘",
|
||||||
|
"capacity_sorting": "容量分选",
|
||||||
|
"clear_tray_ng": "清除托盘NG",
|
||||||
|
"confirm_stop_tray": "是否要停止托盘?停止后托盘和其中的电池都会取消激活!请注意!",
|
||||||
|
"confirm_full_tray_ng": "是否进行整盘NG操作?",
|
||||||
|
"full_tray_ng_success": "整盘NG操作成功",
|
||||||
|
"confirm_clear_tray_ng": "是否进行清除托盘NG操作?",
|
||||||
|
"confirm_capacity_resort": "是否要进行容量再分选操作?",
|
||||||
|
"cannot_adjust_to_initial_process": "无法调整到初始工序",
|
||||||
|
"confirm_adjust_tray_process": "是否将该托盘调整工序?",
|
||||||
|
"adjust_process_success": "调整工序成功",
|
||||||
|
"operation_success": "操作成功!",
|
||||||
|
"operation_cancelled": "已取消操作",
|
||||||
|
"battery_id": "电池条码",
|
||||||
|
"grade": "等级",
|
||||||
|
"activation_status": "激活状态",
|
||||||
|
"channel_battery_info": "通道 {index} 电池信息"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ export default {
|
|||||||
name: `${pre}production_batch_management-bad`,
|
name: `${pre}production_batch_management-bad`,
|
||||||
meta: { ...meta, cache: true, title: '生产批次不良报表' },
|
meta: { ...meta, cache: true, title: '生产批次不良报表' },
|
||||||
component: _import('planning-production/batch-management/batch-defect-report')
|
component: _import('planning-production/batch-management/batch-defect-report')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'produce/monitor/tray_manage',
|
||||||
|
name: `${pre}monitor-tray_manage`,
|
||||||
|
meta: { ...meta, cache: true, title: '托盘管理' },
|
||||||
|
component: _import('planning-production/production-monitoring/tray-management')
|
||||||
}
|
}
|
||||||
])('planning_production-')
|
])('planning_production-')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,562 @@
|
|||||||
|
<template>
|
||||||
|
<d2-container>
|
||||||
|
<template #header>
|
||||||
|
<div class="search-bar">
|
||||||
|
<el-form ref="searchForm" :inline="true" :model="search" size="mini">
|
||||||
|
<el-form-item :label="$t(key('tray_code'))" prop="tray">
|
||||||
|
<el-input
|
||||||
|
v-model="search.tray"
|
||||||
|
prefix-icon="el-icon-search"
|
||||||
|
:placeholder="$t(key('tray_code_placeholder'))"
|
||||||
|
clearable
|
||||||
|
style="width:220px"
|
||||||
|
@keyup.enter.native="onSearch"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">
|
||||||
|
{{ $t(key('query')) }}
|
||||||
|
</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">
|
||||||
|
{{ $t(key('reset')) }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div v-loading="loading" class="tray-management">
|
||||||
|
<el-empty v-if="!hasTrayData" :description="$t(key('enter_tray_to_query'))" />
|
||||||
|
<el-container v-else class="tray-layout">
|
||||||
|
<el-aside width="260px" class="process-aside">
|
||||||
|
<el-menu :default-active="activeProcessIndex" @select="selectProcess">
|
||||||
|
<el-menu-item
|
||||||
|
v-for="(item, index) in dateLog"
|
||||||
|
:key="index"
|
||||||
|
:index="String(index)"
|
||||||
|
>
|
||||||
|
<div class="process-item">
|
||||||
|
<p class="process-title">
|
||||||
|
{{ item.flow_process_code || item.name }}
|
||||||
|
<span v-if="Number(item.idx) === Number(trayData.process_idx) + 1">
|
||||||
|
[{{ $t(key('current_process')) }}]
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p>{{ $t(key('start_time')) }}: {{ item.beginTime }}</p>
|
||||||
|
<p>{{ $t(key('end_time')) }}: {{ item.endTime }}</p>
|
||||||
|
<p>{{ $t(key('device_code')) }}: {{ item.device_code }}</p>
|
||||||
|
</div>
|
||||||
|
</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</el-aside>
|
||||||
|
|
||||||
|
<el-container>
|
||||||
|
<el-header height="auto" class="tray-header">
|
||||||
|
<el-form label-width="90px" size="small">
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('batch'))">
|
||||||
|
<el-input :value="trayData.batch" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('lot'))">
|
||||||
|
<el-input :value="trayData.lot" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('input_battery_count'))">
|
||||||
|
<el-input :value="trayData.actual_input_battery_count" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('input_time'))">
|
||||||
|
<el-input :value="trayData.create_time" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="10">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('previous_process'))">
|
||||||
|
<el-input :value="trayData.process_code" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('current_process'))">
|
||||||
|
<el-input :value="trayData.next_process_code" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('status'))">
|
||||||
|
<el-input :value="trayData.process_code ? $t(key('activated')) : ''" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item :label="$t(key('tray_ng'))">
|
||||||
|
<el-input
|
||||||
|
:value="trayData.ngclassname"
|
||||||
|
:class="{ 'is-ng': Number(trayData.is_ng) === 1 }"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-header>
|
||||||
|
|
||||||
|
<el-main class="tray-main">
|
||||||
|
<div class="actions">
|
||||||
|
<el-button v-if="auth.stop" type="danger" size="mini" @click="handleStopTray">
|
||||||
|
{{ $t(key('stop_tray')) }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="auth.ALLNG" type="warning" size="mini" @click="handleNgTray">
|
||||||
|
{{ $t(key('tray_ng')) }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="auth.FX" type="primary" size="mini" @click="handleRangeFx">
|
||||||
|
{{ $t(key('capacity_sorting')) }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-if="auth.TRAY_NG" type="danger" size="mini" @click="handleCleanTrayNg">
|
||||||
|
{{ $t(key('clear_tray_ng')) }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tray-grid-wrap">
|
||||||
|
<div class="tray-row tray-head">
|
||||||
|
<div :class="breachClass('left_top')" />
|
||||||
|
<div class="tray-cols">
|
||||||
|
<span v-for="item in trayCol" :key="item">{{ item }}</span>
|
||||||
|
</div>
|
||||||
|
<div :class="breachClass('right_top')" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="(row, rowIndex) in trayRows"
|
||||||
|
:key="rowIndex"
|
||||||
|
class="tray-row"
|
||||||
|
:style="{ height: cellHeight + 'px' }"
|
||||||
|
>
|
||||||
|
<div class="row-label">{{ rowIndex + 1 }}</div>
|
||||||
|
<div class="tray-cells">
|
||||||
|
<div
|
||||||
|
v-for="idx in row"
|
||||||
|
:key="idx"
|
||||||
|
class="tray-cell"
|
||||||
|
:style="{ background: batteryBackground(batteryInfo[idx - 1]) }"
|
||||||
|
@click="openBattery(idx)"
|
||||||
|
>
|
||||||
|
<span class="cell-index">{{ idx }}</span>
|
||||||
|
<span v-if="batteryInfo[idx - 1] && batteryInfo[idx - 1].classname" class="cell-class">
|
||||||
|
{{ batteryInfo[idx - 1].classname }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row-label">{{ rowIndex + 1 }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tray-row tray-head">
|
||||||
|
<div :class="breachClass('left_bottom')" />
|
||||||
|
<div class="tray-cols">
|
||||||
|
<span v-for="item in trayCol" :key="item">{{ item }}</span>
|
||||||
|
</div>
|
||||||
|
<div :class="breachClass('right_bottom')" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</el-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog :title="batteryDialogTitle" :visible.sync="batteryDialogVisible" width="420px">
|
||||||
|
<el-descriptions :column="1" border size="mini">
|
||||||
|
<el-descriptions-item :label="$t(key('battery_id'))">
|
||||||
|
{{ selectedBattery.battery_id }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t(key('grade'))">
|
||||||
|
{{ selectedBattery.classname }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t(key('activation_status'))">
|
||||||
|
{{ Number(selectedBattery.active) === 1 ? $t(key('activated')) : $t(key('not_activated')) }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<span slot="footer">
|
||||||
|
<el-button size="mini" @click="batteryDialogVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</d2-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { i18nMixin } from '@/composables/useI18n'
|
||||||
|
import {
|
||||||
|
getTrayManageInfo,
|
||||||
|
changeFlowProcess,
|
||||||
|
trayNg,
|
||||||
|
rangeFx,
|
||||||
|
cleanTrayNg
|
||||||
|
} from '@/api/planning-production/tray-management'
|
||||||
|
import { sendWorkerman } from '@/api/production-master-data/workerman'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'planning-production-tray-management',
|
||||||
|
mixins: [i18nMixin('page.planning_production.production_monitoring.tray_management')],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
search: {
|
||||||
|
tray: this.$route.query.tray || ''
|
||||||
|
},
|
||||||
|
trayData: {},
|
||||||
|
auth: {
|
||||||
|
stop: false,
|
||||||
|
ALLNG: false,
|
||||||
|
FX: false,
|
||||||
|
TRAY_NG: false
|
||||||
|
},
|
||||||
|
batteryDialogVisible: false,
|
||||||
|
batteryDialogTitle: '',
|
||||||
|
selectedBattery: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasTrayData () {
|
||||||
|
return !!(this.trayData && this.trayData.tray)
|
||||||
|
},
|
||||||
|
dateLog () {
|
||||||
|
const value = this.trayData.date_log
|
||||||
|
if (Array.isArray(value)) return value
|
||||||
|
if (!value) return []
|
||||||
|
try {
|
||||||
|
return JSON.parse(value)
|
||||||
|
} catch (e) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trayFormat () {
|
||||||
|
return this.trayData.tary_format_data || {}
|
||||||
|
},
|
||||||
|
trayCol () {
|
||||||
|
return Number(this.trayFormat.tray_col || 14)
|
||||||
|
},
|
||||||
|
trayRow () {
|
||||||
|
return Number(this.trayFormat.tray_row || 14)
|
||||||
|
},
|
||||||
|
breach () {
|
||||||
|
return this.trayFormat.breach || 'left_bottom'
|
||||||
|
},
|
||||||
|
dataBreach () {
|
||||||
|
return this.trayFormat.data_breach || 'left_top'
|
||||||
|
},
|
||||||
|
direction () {
|
||||||
|
return this.trayFormat.direction || 'horizontal'
|
||||||
|
},
|
||||||
|
shape () {
|
||||||
|
return this.trayFormat.shape || 'NU'
|
||||||
|
},
|
||||||
|
cellHeight () {
|
||||||
|
return Number(this.trayFormat.cellheight || 35)
|
||||||
|
},
|
||||||
|
batteryInfo () {
|
||||||
|
return this.trayData.battery_info || []
|
||||||
|
},
|
||||||
|
activeProcessIndex () {
|
||||||
|
return String(Number(this.trayData.process_idx || 0) + 1)
|
||||||
|
},
|
||||||
|
trayRows () {
|
||||||
|
const rows = []
|
||||||
|
for (let x = 0; x < this.trayRow; x++) {
|
||||||
|
const row = []
|
||||||
|
for (let y = 0; y < this.trayCol; y++) {
|
||||||
|
let idx
|
||||||
|
if (this.direction === 'vertical') {
|
||||||
|
idx = x + 1 + this.trayRow * y
|
||||||
|
if (this.shape !== 'NU' && y % 2 === 1) {
|
||||||
|
idx = this.trayRow - x + this.trayRow * y
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idx = this.trayCol * x + y + 1
|
||||||
|
}
|
||||||
|
row.push(idx)
|
||||||
|
}
|
||||||
|
if (this.direction === 'horizontal' && this.shape !== 'NU' && x % 2 === 1) {
|
||||||
|
row.reverse()
|
||||||
|
}
|
||||||
|
rows.push(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.dataBreach === 'left_bottom') {
|
||||||
|
rows.reverse()
|
||||||
|
} else if (this.dataBreach === 'right_top') {
|
||||||
|
rows.forEach(row => row.reverse())
|
||||||
|
} else if (this.dataBreach === 'right_bottom') {
|
||||||
|
rows.reverse()
|
||||||
|
rows.forEach(row => row.reverse())
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$route.query.tray' (tray) {
|
||||||
|
this.search.tray = tray || ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.initAuth()
|
||||||
|
if (this.search.tray) this.fetchData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initAuth () {
|
||||||
|
const can = key => (this.$permission ? this.$permission(key) : true)
|
||||||
|
this.auth.stop = can('/produce/monitor/trayManage/stop')
|
||||||
|
this.auth.ALLNG = can('/produce/monitor/trayManage/ALLNG')
|
||||||
|
this.auth.FX = can('/produce/monitor/trayManage/FX')
|
||||||
|
this.auth.TRAY_NG = can('/produce/monitor/trayManage/TRAY_NG')
|
||||||
|
},
|
||||||
|
fetchData () {
|
||||||
|
if (!this.search.tray) {
|
||||||
|
this.trayData = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loading = true
|
||||||
|
getTrayManageInfo({ ...this.search })
|
||||||
|
.then(res => {
|
||||||
|
const payload = res && res.data ? res.data : res
|
||||||
|
this.trayData = payload && payload.data ? payload.data : (payload || {})
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onSearch () {
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
onReset () {
|
||||||
|
this.$refs.searchForm.resetFields()
|
||||||
|
this.trayData = {}
|
||||||
|
},
|
||||||
|
refreshTray () {
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
confirmAction (message, handler) {
|
||||||
|
this.$confirm(message, this.$t(this.key('prompt')), {
|
||||||
|
confirmButtonText: this.$t(this.key('confirm')),
|
||||||
|
cancelButtonText: this.$t(this.key('cancel')),
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
.then(handler)
|
||||||
|
.catch(() => {
|
||||||
|
this.$message.info(this.$t(this.key('operation_cancelled')))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleStopTray () {
|
||||||
|
this.confirmAction(this.$t(this.key('confirm_stop_tray')), () => {
|
||||||
|
return sendWorkerman({
|
||||||
|
sendData: {
|
||||||
|
action: 'set_tray_inactivity',
|
||||||
|
param: { tray: this.trayData.tray }
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
|
this.refreshTray()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleNgTray () {
|
||||||
|
this.confirmAction(this.$t(this.key('confirm_full_tray_ng')), () => {
|
||||||
|
return trayNg({ tray: this.trayData.tray }).then(() => {
|
||||||
|
this.$message.success(this.$t(this.key('full_tray_ng_success')))
|
||||||
|
this.refreshTray()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCleanTrayNg () {
|
||||||
|
this.confirmAction(this.$t(this.key('confirm_clear_tray_ng')), () => {
|
||||||
|
return cleanTrayNg({
|
||||||
|
lot: this.trayData.lot,
|
||||||
|
subbatch: this.trayData.subbatch,
|
||||||
|
tray: this.trayData.tray,
|
||||||
|
next_process_code: this.trayData.next_process_code
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
|
this.refreshTray()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleRangeFx () {
|
||||||
|
this.confirmAction(this.$t(this.key('confirm_capacity_resort')), () => {
|
||||||
|
return rangeFx({
|
||||||
|
lot: this.trayData.lot,
|
||||||
|
subbatch: this.trayData.subbatch,
|
||||||
|
tray: this.trayData.tray
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success(this.$t(this.key('operation_success')))
|
||||||
|
this.refreshTray()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
selectProcess (index) {
|
||||||
|
const currentIndex = Number(this.trayData.process_idx || 0) + 1
|
||||||
|
if (Number(index) === currentIndex) return
|
||||||
|
if (Number(index) === 0) {
|
||||||
|
this.$message.info(this.$t(this.key('cannot_adjust_to_initial_process')))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.confirmAction(this.$t(this.key('confirm_adjust_tray_process')), () => {
|
||||||
|
const prev = this.dateLog[Number(index) - 1] || {}
|
||||||
|
const next = this.dateLog[Number(index)] || {}
|
||||||
|
return changeFlowProcess({
|
||||||
|
variable: 1,
|
||||||
|
lot: this.trayData.lot,
|
||||||
|
subbatch: this.trayData.subbatch,
|
||||||
|
tray: this.trayData.tray,
|
||||||
|
process_code: prev.flow_process_code || '',
|
||||||
|
process_idx: prev.idx || 0,
|
||||||
|
next_process_code: next.flow_process_code || '',
|
||||||
|
clear_ng: false
|
||||||
|
}).then(() => {
|
||||||
|
this.$message.success(this.$t(this.key('adjust_process_success')))
|
||||||
|
this.refreshTray()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
batteryBackground (item = {}) {
|
||||||
|
if (item && item.battery_id) {
|
||||||
|
if (Number(item.active) === 1) {
|
||||||
|
if (item.class === 'NG') return '#F56C6C'
|
||||||
|
if (item.class === 'RC') return 'yellowgreen'
|
||||||
|
return '#317894'
|
||||||
|
}
|
||||||
|
return '#908D8D'
|
||||||
|
}
|
||||||
|
return '#F5F7FA'
|
||||||
|
},
|
||||||
|
openBattery (idx) {
|
||||||
|
const battery = this.batteryInfo[idx - 1]
|
||||||
|
if (!battery || !battery.battery_id) return
|
||||||
|
this.selectedBattery = battery
|
||||||
|
this.batteryDialogTitle = this.$t(this.key('channel_battery_info'), { index: idx })
|
||||||
|
this.batteryDialogVisible = true
|
||||||
|
},
|
||||||
|
breachClass (position) {
|
||||||
|
return this.breach === position ? `tray-breach tray-breach--${position}` : 'tray-corner'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search-bar {
|
||||||
|
margin-bottom: -18px;
|
||||||
|
}
|
||||||
|
.tray-management,
|
||||||
|
.tray-layout {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.process-aside {
|
||||||
|
background: #eef1f6;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.process-item {
|
||||||
|
line-height: 22px;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
.process-item p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.process-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.tray-header {
|
||||||
|
padding: 10px 12px 0;
|
||||||
|
}
|
||||||
|
.tray-header ::v-deep .el-form-item {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.tray-header ::v-deep .is-ng .el-input__inner {
|
||||||
|
color: #F56C6C;
|
||||||
|
}
|
||||||
|
.tray-main {
|
||||||
|
padding: 10px 12px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.tray-grid-wrap {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 760px;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
border-left: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
.tray-row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.tray-head {
|
||||||
|
height: 28px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.tray-corner,
|
||||||
|
.tray-breach {
|
||||||
|
width: 26px;
|
||||||
|
flex: 0 0 26px;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.tray-breach {
|
||||||
|
background: #303133;
|
||||||
|
}
|
||||||
|
.tray-cols,
|
||||||
|
.tray-cells {
|
||||||
|
flex: 1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--tray-col), 1fr);
|
||||||
|
}
|
||||||
|
.tray-cols {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.tray-cols span {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
.row-label {
|
||||||
|
width: 26px;
|
||||||
|
flex: 0 0 26px;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background: #fafafa;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.tray-cells {
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(24px, 1fr));
|
||||||
|
}
|
||||||
|
.tray-cell {
|
||||||
|
position: relative;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.cell-index {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
.cell-class {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user