Merge branch 'master' of http://119.91.43.128:3001/sheng/mes-ui-d2
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
> 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。
|
||||
|
||||
- 总功能数:79
|
||||
- 已迁移:24
|
||||
- 未迁移:55
|
||||
- 已迁移:25
|
||||
- 未迁移:54
|
||||
|
||||
| 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 |
|
||||
|:---:|---|---|---|---|---|
|
||||
@@ -50,7 +50,7 @@
|
||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 物料监控 (Material Monitoring) | 物料监控 | 待确认 |
|
||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池复投管理 (Rework 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) | 托盘登记 | `src/views/planning-production/production-monitoring/tray-registration/` |
|
||||
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 设备监控 (Equipment Monitoring) | 设备监控 | `src/views/planning-production/production-monitoring/equipment-monitoring/` |
|
||||
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池工序管理 (Process Execution) | 工序管理 | `src/views/planning-production/production-monitoring/process-execution/` |
|
||||
| ⬜ | 质量管理 (Quality Management) | 过程控制 (Process Control) | 检验类别管理 (Inspection Type Management) | | 待确认 |
|
||||
|
||||
51
src/api/planning-production/tray-registration.js
Normal file
51
src/api/planning-production/tray-registration.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import { request } from '@/api/_service'
|
||||
|
||||
const BASE = 'planning_production/produce/tray_login/'
|
||||
|
||||
function apiParams (method, data = {}) {
|
||||
return {
|
||||
method,
|
||||
platform: 'background',
|
||||
...data
|
||||
}
|
||||
}
|
||||
|
||||
export function getBatchAll (data) {
|
||||
return request({
|
||||
url: BASE + 'all',
|
||||
method: 'get',
|
||||
params: apiParams('planning_production_produce_traylogin_all', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function getBatchTrayFormatAll (data) {
|
||||
return request({
|
||||
url: BASE + 'trayformat_all',
|
||||
method: 'get',
|
||||
params: apiParams('planning_production_produce_trayformat_all', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function createBatchTrayFormat (data) {
|
||||
return request({
|
||||
url: BASE + 'create',
|
||||
method: 'get',
|
||||
params: apiParams('planning_production_produce_trayformat_create', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteBatchTrayFormat (data) {
|
||||
return request({
|
||||
url: BASE + 'delete',
|
||||
method: 'get',
|
||||
params: apiParams('planning_production_produce_trayformat_delete', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function checkBatteryid (data) {
|
||||
return request({
|
||||
url: BASE + 'check_batteryid',
|
||||
method: 'get',
|
||||
params: apiParams('planning_production_produce_trayformat_check_batteryid', data)
|
||||
})
|
||||
}
|
||||
@@ -1078,6 +1078,73 @@
|
||||
"exception": "Exception",
|
||||
"offline": "Offline",
|
||||
"idle": "Waiting for Material"
|
||||
},
|
||||
"tray_registration": {
|
||||
"query": "Search",
|
||||
"reset": "Reset",
|
||||
"login": "Register",
|
||||
"tray_unbind": "Unbind Tray",
|
||||
"tray_stop": "Stop Tray",
|
||||
"add": "Add",
|
||||
"delete": "Delete",
|
||||
"confirm": "Confirm",
|
||||
"cancel": "Cancel",
|
||||
"prompt": "Notice",
|
||||
"data_table": "Data Table",
|
||||
"process_channel": "Channel",
|
||||
"battery_id": "Battery ID",
|
||||
"previous_batch": "Previous Batch",
|
||||
"previous_tray": "Previous Tray",
|
||||
"completed_process": "Completed Process",
|
||||
"tray_barcode_format": "Tray Barcode Format",
|
||||
"battery_barcode_format": "Battery Barcode Format",
|
||||
"tray_battery_count": "Tray Capacity",
|
||||
"operation": "Actions",
|
||||
"batch_no": "Batch No.",
|
||||
"enter_batch_no": "Enter batch number",
|
||||
"tray_code": "Tray Code",
|
||||
"enter_tray_code": "Enter tray code",
|
||||
"battery_code": "Battery Code",
|
||||
"enter_battery_code": "Enter battery code",
|
||||
"tray_code_format": "Tray Code Format",
|
||||
"battery_code_format": "Battery Code Format",
|
||||
"tray_battery_format_edit": "Tray & Battery Format Editor",
|
||||
"format_dialog_title": "Tray & Battery Format",
|
||||
"submit_login": "Submit Registration",
|
||||
"add_format_title": "Add Format",
|
||||
"format_error": "Invalid format",
|
||||
"process_flow_name": "Process Flow Name",
|
||||
"format_error_exclamation": "Invalid format!",
|
||||
"insert_duplicate_battery": "Duplicate battery",
|
||||
"delete_confirm": "Delete this format?",
|
||||
"delete_success": "Deleted successfully",
|
||||
"add_tray_format": "Add tray format",
|
||||
"add_battery_format": "Add battery format",
|
||||
"add_battery_count": "Add battery count",
|
||||
"tray_unbind_desc": "Note: unbinding deactivates the tray, but batteries remain activated.",
|
||||
"tray_unbind_success": "Tray unbound successfully",
|
||||
"tray_stop_desc": "Note: stopping deactivates both tray and batteries.",
|
||||
"tray_stop_success": "Tray stopped successfully",
|
||||
"enter_tray_no": "Enter tray number",
|
||||
"batch_create_time": "Batch Create Time",
|
||||
"tray_load_battery_count": "Loaded Count",
|
||||
"batch_deactivate": "Batch Deactivate",
|
||||
"please_enter_tray_code": "Please enter tray code",
|
||||
"upload_success": "Upload successful",
|
||||
"no_batch_no": "No batch number",
|
||||
"has_active_battery_login_forbidden": "Cannot register: contains activated batteries.",
|
||||
"select_battery_to_deactivate": "Select batteries to deactivate",
|
||||
"battery_deactivate": "Battery Deactivation",
|
||||
"batch_battery_deactivate_success": "Batch deactivation successful",
|
||||
"channel": "Channel:",
|
||||
"select_format": "Select format",
|
||||
"select_format_first": "Select tray and battery format first",
|
||||
"activation_status": "Activation Status",
|
||||
"activated": "Activated",
|
||||
"not_activated": "Not Activated",
|
||||
"operation_success": "Operation successful",
|
||||
"operation_failed": "Operation failed",
|
||||
"format_rule": "Format rule: fixed characters are literal; use * for variable characters, e.g. A** or ******."
|
||||
}
|
||||
},
|
||||
"alert_center": {
|
||||
|
||||
@@ -1078,6 +1078,73 @@
|
||||
"exception": "异常中",
|
||||
"offline": "离线中",
|
||||
"idle": "待料中"
|
||||
},
|
||||
"tray_registration": {
|
||||
"query": "查询",
|
||||
"reset": "重置",
|
||||
"login": "登录",
|
||||
"tray_unbind": "托盘解绑",
|
||||
"tray_stop": "托盘停止",
|
||||
"add": "新增",
|
||||
"delete": "删除",
|
||||
"confirm": "确定",
|
||||
"cancel": "取消",
|
||||
"prompt": "提示",
|
||||
"data_table": "数据表",
|
||||
"process_channel": "通道",
|
||||
"battery_id": "电池ID",
|
||||
"previous_batch": "上一个批次",
|
||||
"previous_tray": "上一个托盘",
|
||||
"completed_process": "电池已完成工序",
|
||||
"tray_barcode_format": "托盘条码格式",
|
||||
"battery_barcode_format": "电池条码格式",
|
||||
"tray_battery_count": "托盘装载电池数量",
|
||||
"operation": "操作",
|
||||
"batch_no": "批次号",
|
||||
"enter_batch_no": "请输入批次号",
|
||||
"tray_code": "托盘编码",
|
||||
"enter_tray_code": "请输入托盘编码",
|
||||
"battery_code": "电池编码",
|
||||
"enter_battery_code": "请输入电池编码",
|
||||
"tray_code_format": "托盘编码格式",
|
||||
"battery_code_format": "电池编码格式",
|
||||
"tray_battery_format_edit": "托盘与电池格式编辑",
|
||||
"format_dialog_title": "托盘与电池格式",
|
||||
"submit_login": "提交登录",
|
||||
"add_format_title": "新增格式",
|
||||
"format_error": "格式不对",
|
||||
"process_flow_name": "工艺流程名称",
|
||||
"format_error_exclamation": "格式不对!",
|
||||
"insert_duplicate_battery": "插入重复电池",
|
||||
"delete_confirm": "删除这条格式?",
|
||||
"delete_success": "删除成功",
|
||||
"add_tray_format": "请添加托盘格式",
|
||||
"add_battery_format": "请添加电池格式",
|
||||
"add_battery_count": "请添加电池数量",
|
||||
"tray_unbind_desc": "说明:托盘解绑后,该托盘的状态是取消激活的,与它装载的电池还是激活状态",
|
||||
"tray_unbind_success": "托盘解绑成功",
|
||||
"tray_stop_desc": "说明:托盘停止后,该托盘和它装载的电池会一同取消激活",
|
||||
"tray_stop_success": "托盘停止成功",
|
||||
"enter_tray_no": "请输入托盘号",
|
||||
"batch_create_time": "批次创建时间",
|
||||
"tray_load_battery_count": "装载电池数量",
|
||||
"batch_deactivate": "批量取消激活",
|
||||
"please_enter_tray_code": "请填写托盘编码",
|
||||
"upload_success": "上传成功",
|
||||
"no_batch_no": "没有批次号",
|
||||
"has_active_battery_login_forbidden": "有电池属于激活状态,无法登录",
|
||||
"select_battery_to_deactivate": "请选择需要取消激活的电池",
|
||||
"battery_deactivate": "电池取消激活",
|
||||
"batch_battery_deactivate_success": "批量取消电池激活成功",
|
||||
"channel": "通道:",
|
||||
"select_format": "请选择格式",
|
||||
"select_format_first": "请先选择托盘与电池格式",
|
||||
"activation_status": "激活状态",
|
||||
"activated": "已激活",
|
||||
"not_activated": "未激活",
|
||||
"operation_success": "操作成功",
|
||||
"operation_failed": "操作失败",
|
||||
"format_rule": "格式规则:固定字符直接填写,可变字符使用 * 代替,例如 A** 或 ******。"
|
||||
}
|
||||
},
|
||||
"alert_center": {
|
||||
|
||||
@@ -44,6 +44,12 @@ export default {
|
||||
meta: { ...meta, cache: true, title: '托盘管理' },
|
||||
component: _import('planning-production/production-monitoring/tray-management')
|
||||
},
|
||||
{
|
||||
path: 'produce/monitor/tray_login',
|
||||
name: `${pre}monitor-tray_login`,
|
||||
meta: { ...meta, cache: true, title: '托盘登录' },
|
||||
component: _import('planning-production/production-monitoring/tray-registration')
|
||||
},
|
||||
{
|
||||
path: 'produce/monitor/device',
|
||||
name: `${pre}monitor-device`,
|
||||
|
||||
@@ -0,0 +1,695 @@
|
||||
<template>
|
||||
<d2-container>
|
||||
<template #header>
|
||||
<div class="search-bar">
|
||||
<el-form ref="form" :inline="true" :model="form" size="mini">
|
||||
<el-form-item :label="$t(key('batch_no'))" prop="batch">
|
||||
<el-input
|
||||
v-model="form.batch"
|
||||
:placeholder="$t(key('enter_batch_no'))"
|
||||
clearable
|
||||
readonly
|
||||
style="width:220px"
|
||||
@focus="openBatchDialog"
|
||||
>
|
||||
<el-button slot="append" icon="el-icon-search" @click="openBatchDialog" />
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('tray_code_format'))">
|
||||
<el-select
|
||||
v-model="selectedFormatId"
|
||||
:placeholder="$t(key('select_format'))"
|
||||
filterable
|
||||
style="width:220px"
|
||||
@change="selectFormat"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formatList"
|
||||
:key="item.id"
|
||||
:label="formatLabel(item)"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('tray_code'))" prop="tray">
|
||||
<el-input
|
||||
v-model="form.tray"
|
||||
:placeholder="$t(key('enter_tray_code'))"
|
||||
:disabled="!currentFormat"
|
||||
clearable
|
||||
style="width:220px"
|
||||
@keyup.enter.native="focusFirstChannel"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-check" :disabled="submitting" @click="openSubmitDialog">
|
||||
{{ $t(key('login')) }}
|
||||
</el-button>
|
||||
<el-button type="warning" icon="el-icon-unlock" :disabled="submitting" @click="unbindTray">
|
||||
{{ $t(key('tray_unbind')) }}
|
||||
</el-button>
|
||||
<el-button type="danger" icon="el-icon-switch-button" :disabled="submitting" @click="stopTray">
|
||||
{{ $t(key('tray_stop')) }}
|
||||
</el-button>
|
||||
<el-button icon="el-icon-edit" :disabled="loadingFormats" @click="openFormatDialog">
|
||||
{{ $t(key('tray_battery_format_edit')) }}
|
||||
</el-button>
|
||||
<el-button icon="el-icon-refresh" :disabled="submitting" @click="resetPage">
|
||||
{{ $t(key('reset')) }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="registration-layout">
|
||||
<section class="channel-panel">
|
||||
<div class="panel-head">
|
||||
<span>{{ $t(key('data_table')) }}</span>
|
||||
<el-tag size="mini">{{ loadedCount }} / {{ capacity }}</el-tag>
|
||||
</div>
|
||||
<el-empty v-if="!currentFormat" :description="$t(key('select_format_first'))" :image-size="80" />
|
||||
<div v-else class="channel-grid">
|
||||
<el-form label-width="74px" size="mini">
|
||||
<el-form-item
|
||||
v-for="channel in channelList"
|
||||
:key="channel"
|
||||
:label="$t(key('channel')) + channel"
|
||||
>
|
||||
<el-input
|
||||
:ref="inputRef(channel)"
|
||||
v-model="batteryInputs[channel]"
|
||||
:placeholder="$t(key('enter_battery_code'))"
|
||||
clearable
|
||||
@keyup.enter.native="scanBattery(channel)"
|
||||
@clear="removeBattery(channel)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="battery-panel">
|
||||
<div class="panel-head">
|
||||
<span>{{ $t(key('tray_load_battery_count')) }}</span>
|
||||
<el-button
|
||||
type="text"
|
||||
class="danger-action"
|
||||
:disabled="!selectedRows.length"
|
||||
@click="batchInactivity"
|
||||
>
|
||||
{{ $t(key('batch_deactivate')) }}
|
||||
</el-button>
|
||||
</div>
|
||||
<page-table
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:loading="loadingBattery"
|
||||
:toolbar-buttons="[]"
|
||||
:row-buttons="[]"
|
||||
:pagination="null"
|
||||
:table-attrs="{ size: 'mini', rowKey: 'index', highlightCurrentRow: true, rowClassName: rowClassName }"
|
||||
height="520px"
|
||||
@selection-change="selectedRows = $event"
|
||||
>
|
||||
<template #col-battery="{ row }">
|
||||
<span>{{ row.Battery || row.battery_id }}</span>
|
||||
</template>
|
||||
<template #col-active="{ row }">
|
||||
<el-tag :type="Number(row.active) === 1 ? 'danger' : 'success'" size="mini">
|
||||
{{ Number(row.active) === 1 ? $t(key('activated')) : $t(key('not_activated')) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #empty>
|
||||
<el-empty :description="$t('暂无数据')" :image-size="80" />
|
||||
</template>
|
||||
</page-table>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<el-dialog :title="$t(key('batch_no'))" :visible.sync="batchDialogVisible" width="760px">
|
||||
<page-table
|
||||
:columns="batchColumns"
|
||||
:data="batchList"
|
||||
:loading="loadingBatches"
|
||||
:toolbar-buttons="[]"
|
||||
:row-buttons="[]"
|
||||
:pagination="null"
|
||||
:table-attrs="{ size: 'mini', rowKey: 'batch', highlightCurrentRow: true }"
|
||||
height="420px"
|
||||
@row-dblclick="selectBatch"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="$t(key('format_dialog_title'))" :visible.sync="formatDialogVisible" width="820px">
|
||||
<el-button type="primary" size="mini" icon="el-icon-plus" @click="openFormatForm">
|
||||
{{ $t(key('add')) }}
|
||||
</el-button>
|
||||
<page-table
|
||||
class="format-table"
|
||||
:columns="formatColumns"
|
||||
:data="formatList"
|
||||
:loading="loadingFormats"
|
||||
:toolbar-buttons="[]"
|
||||
:row-buttons="[]"
|
||||
:pagination="null"
|
||||
:table-attrs="{ size: 'mini', rowKey: 'id', highlightCurrentRow: true }"
|
||||
height="360px"
|
||||
@row-dblclick="selectFormatRow"
|
||||
>
|
||||
<template #col-actions="{ row }">
|
||||
<el-button type="text" class="danger-action" @click="deleteFormat(row)">
|
||||
{{ $t(key('delete')) }}
|
||||
</el-button>
|
||||
</template>
|
||||
</page-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="$t(key('add_format_title'))" :visible.sync="formatFormVisible" width="620px">
|
||||
<el-form :model="formatForm" label-width="150px" size="mini">
|
||||
<el-form-item :label="$t(key('tray_barcode_format'))">
|
||||
<el-input v-model="formatForm.tray_format" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('battery_barcode_format'))">
|
||||
<el-input v-model="formatForm.battery_format" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('tray_battery_count'))">
|
||||
<el-input-number v-model="formatForm.battery_count" :min="1" :max="96" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-alert :title="$t(key('format_rule'))" type="warning" :closable="false" />
|
||||
<span slot="footer">
|
||||
<el-button size="mini" @click="formatFormVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||
<el-button size="mini" type="primary" @click="createFormat">{{ $t(key('confirm')) }}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="$t(key('submit_login'))" :visible.sync="submitDialogVisible" width="640px">
|
||||
<page-table
|
||||
:columns="submitColumns"
|
||||
:data="tableData"
|
||||
:loading="submitting"
|
||||
:toolbar-buttons="[]"
|
||||
:row-buttons="[]"
|
||||
:pagination="null"
|
||||
:table-attrs="{ size: 'mini', rowKey: 'index' }"
|
||||
height="360px"
|
||||
>
|
||||
<template #col-battery="{ row }">
|
||||
<span>{{ row.Battery || row.battery_id }}</span>
|
||||
</template>
|
||||
</page-table>
|
||||
<span slot="footer">
|
||||
<el-button size="mini" @click="submitDialogVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||
<el-button size="mini" type="primary" :disabled="submitting" @click="submitRegistration">
|
||||
{{ $t(key('confirm')) }}
|
||||
</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useTableColumns } from '@/composables/useTableColumns'
|
||||
import { i18nMixin } from '@/composables/useI18n'
|
||||
import PageTable from '@/components/page-table'
|
||||
import { sendWorkerman } from '@/api/production-master-data/workerman'
|
||||
import {
|
||||
getBatchAll,
|
||||
getBatchTrayFormatAll,
|
||||
createBatchTrayFormat,
|
||||
deleteBatchTrayFormat,
|
||||
checkBatteryid
|
||||
} from '@/api/planning-production/tray-registration'
|
||||
|
||||
export default {
|
||||
name: 'planning-production-tray-registration',
|
||||
components: { PageTable },
|
||||
mixins: [i18nMixin('page.planning_production.production_monitoring.tray_registration')],
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
batch: '',
|
||||
tray: ''
|
||||
},
|
||||
selectedFormatId: '',
|
||||
currentFormat: null,
|
||||
batteryInputs: {},
|
||||
tableData: [],
|
||||
batchList: [],
|
||||
formatList: [],
|
||||
selectedRows: [],
|
||||
batchDialogVisible: false,
|
||||
formatDialogVisible: false,
|
||||
formatFormVisible: false,
|
||||
submitDialogVisible: false,
|
||||
loadingBatches: false,
|
||||
loadingFormats: false,
|
||||
loadingBattery: false,
|
||||
submitting: false,
|
||||
formatForm: {
|
||||
tray_format: '',
|
||||
battery_format: '',
|
||||
battery_count: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
capacity () {
|
||||
return Number((this.currentFormat && this.currentFormat.battery_count) || 0)
|
||||
},
|
||||
loadedCount () {
|
||||
return this.tableData.length
|
||||
},
|
||||
channelList () {
|
||||
return Array.from({ length: this.capacity }, (_, index) => index + 1)
|
||||
},
|
||||
trayRegExp () {
|
||||
return this.createFormatRegExp(this.currentFormat && this.currentFormat.tray_format)
|
||||
},
|
||||
batteryRegExp () {
|
||||
return this.createFormatRegExp(this.currentFormat && this.currentFormat.battery_format)
|
||||
},
|
||||
columns () {
|
||||
return useTableColumns([
|
||||
{ prop: 'index', label: this.key('process_channel'), width: 90 },
|
||||
{ prop: 'Battery', label: this.key('battery_id'), minWidth: 180, slot: 'battery', showOverflowTooltip: true },
|
||||
{ prop: 'active', label: this.key('activation_status'), width: 110, slot: 'active' },
|
||||
{ prop: 'batch', label: this.key('previous_batch'), minWidth: 150, showOverflowTooltip: true },
|
||||
{ prop: 'tray', label: this.key('previous_tray'), minWidth: 150, showOverflowTooltip: true },
|
||||
{ prop: 'process_code', label: this.key('completed_process'), minWidth: 160, showOverflowTooltip: true }
|
||||
], {
|
||||
selectionWidth: 55,
|
||||
indexWidth: 0
|
||||
})
|
||||
},
|
||||
batchColumns () {
|
||||
return useTableColumns([
|
||||
{ prop: 'batch', label: this.key('batch_no'), minWidth: 200, showOverflowTooltip: true },
|
||||
{ prop: 'flow_name', label: this.key('process_flow_name'), minWidth: 200, showOverflowTooltip: true },
|
||||
{ prop: 'create_time', label: this.key('batch_create_time'), minWidth: 180, showOverflowTooltip: true }
|
||||
], {
|
||||
selectionWidth: 0,
|
||||
indexWidth: 55
|
||||
})
|
||||
},
|
||||
formatColumns () {
|
||||
return useTableColumns([
|
||||
{ prop: 'tray_format', label: this.key('tray_barcode_format'), minWidth: 160, showOverflowTooltip: true },
|
||||
{ prop: 'battery_format', label: this.key('battery_barcode_format'), minWidth: 180, showOverflowTooltip: true },
|
||||
{ prop: 'battery_count', label: this.key('tray_battery_count'), width: 140 },
|
||||
{ prop: 'actions', label: this.key('operation'), width: 90, slot: 'actions' }
|
||||
], {
|
||||
selectionWidth: 0,
|
||||
indexWidth: 55
|
||||
})
|
||||
},
|
||||
submitColumns () {
|
||||
return useTableColumns([
|
||||
{ prop: 'index', label: this.key('process_channel'), width: 120 },
|
||||
{ prop: 'Battery', label: this.key('battery_id'), minWidth: 220, slot: 'battery', showOverflowTooltip: true }
|
||||
], {
|
||||
selectionWidth: 0,
|
||||
indexWidth: 0
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchBatchList()
|
||||
this.fetchFormatList()
|
||||
},
|
||||
methods: {
|
||||
responseData (res) {
|
||||
const payload = res && res.data ? res.data : (res || {})
|
||||
return payload.data || payload
|
||||
},
|
||||
formatLabel (item) {
|
||||
return `${item.tray_format} / ${item.battery_format} / ${item.battery_count}`
|
||||
},
|
||||
inputRef (channel) {
|
||||
return `batteryInput${channel}`
|
||||
},
|
||||
createFormatRegExp (format) {
|
||||
if (!format) return null
|
||||
const escaped = String(format).replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[A-Z0-9-]')
|
||||
return new RegExp(`^${escaped}$`)
|
||||
},
|
||||
openBatchDialog () {
|
||||
this.batchDialogVisible = true
|
||||
if (!this.batchList.length) this.fetchBatchList()
|
||||
},
|
||||
selectBatch (row) {
|
||||
this.form.batch = row.batch
|
||||
this.batchDialogVisible = false
|
||||
},
|
||||
async fetchBatchList () {
|
||||
this.loadingBatches = true
|
||||
try {
|
||||
const res = await getBatchAll({ action: 'get_batch' })
|
||||
const data = this.responseData(res)
|
||||
this.batchList = Array.isArray(data) ? data : []
|
||||
} finally {
|
||||
this.loadingBatches = false
|
||||
}
|
||||
},
|
||||
async fetchFormatList () {
|
||||
this.loadingFormats = true
|
||||
try {
|
||||
const res = await getBatchTrayFormatAll({ action: 'get_login_format' })
|
||||
const data = this.responseData(res)
|
||||
this.formatList = Array.isArray(data) ? data : []
|
||||
if (!this.currentFormat && this.formatList.length) {
|
||||
this.selectFormat(this.formatList[0].id)
|
||||
}
|
||||
} finally {
|
||||
this.loadingFormats = false
|
||||
}
|
||||
},
|
||||
selectFormat (id) {
|
||||
const target = this.formatList.find(item => String(item.id) === String(id))
|
||||
if (!target) return
|
||||
this.currentFormat = target
|
||||
this.selectedFormatId = target.id
|
||||
this.tableData = []
|
||||
this.selectedRows = []
|
||||
this.batteryInputs = {}
|
||||
},
|
||||
selectFormatRow (row) {
|
||||
this.selectFormat(row.id)
|
||||
this.formatDialogVisible = false
|
||||
},
|
||||
focusFirstChannel () {
|
||||
if (!this.validateTray()) return
|
||||
this.$nextTick(() => {
|
||||
const refs = this.$refs[this.inputRef(1)]
|
||||
const input = Array.isArray(refs) ? refs[0] : refs
|
||||
if (input) input.focus()
|
||||
})
|
||||
},
|
||||
validateTray () {
|
||||
if (!this.currentFormat) {
|
||||
this.$message.warning(this.$t(this.key('select_format_first')))
|
||||
return false
|
||||
}
|
||||
if (!this.form.tray) {
|
||||
this.$message.warning(this.$t(this.key('please_enter_tray_code')))
|
||||
return false
|
||||
}
|
||||
if (this.trayRegExp && !this.trayRegExp.test(this.form.tray)) {
|
||||
this.$message.warning(this.$t(this.key('format_error_exclamation')))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
async scanBattery (channel) {
|
||||
if (!this.validateTray()) return
|
||||
const batteryId = this.batteryInputs[channel]
|
||||
if (!batteryId) {
|
||||
this.removeBattery(channel)
|
||||
return
|
||||
}
|
||||
if (this.batteryRegExp && !this.batteryRegExp.test(batteryId)) {
|
||||
this.$message.warning(this.$t(this.key('format_error')))
|
||||
this.removeBattery(channel)
|
||||
return
|
||||
}
|
||||
const duplicate = this.tableData.find(item => item.index !== channel && item.Battery === batteryId)
|
||||
if (duplicate) {
|
||||
this.$message.warning(this.$t(this.key('insert_duplicate_battery')))
|
||||
this.removeBattery(channel)
|
||||
return
|
||||
}
|
||||
this.loadingBattery = true
|
||||
try {
|
||||
const res = await checkBatteryid({
|
||||
action: 'check_elements_code',
|
||||
battery_id: batteryId
|
||||
})
|
||||
const payload = res && res.data ? res.data : (res || {})
|
||||
const data = payload.data || {}
|
||||
if (payload.code !== undefined && Number(payload.code) !== 0) {
|
||||
this.$message.error(payload.msg || payload.errmsg || this.$t(this.key('format_error')))
|
||||
this.removeBattery(channel)
|
||||
return
|
||||
}
|
||||
const row = {
|
||||
...data,
|
||||
Battery: batteryId,
|
||||
battery_id: data.battery_id || batteryId,
|
||||
index: channel
|
||||
}
|
||||
const exists = this.tableData.findIndex(item => item.index === channel)
|
||||
if (exists >= 0) {
|
||||
this.$set(this.tableData, exists, row)
|
||||
} else {
|
||||
this.tableData.push(row)
|
||||
}
|
||||
this.tableData.sort((a, b) => a.index - b.index)
|
||||
this.focusNextChannel(channel)
|
||||
} finally {
|
||||
this.loadingBattery = false
|
||||
}
|
||||
},
|
||||
focusNextChannel (channel) {
|
||||
const next = channel + 1
|
||||
if (next > this.capacity) return
|
||||
this.$nextTick(() => {
|
||||
const refs = this.$refs[this.inputRef(next)]
|
||||
const input = Array.isArray(refs) ? refs[0] : refs
|
||||
if (input) {
|
||||
input.focus()
|
||||
input.select()
|
||||
}
|
||||
})
|
||||
},
|
||||
removeBattery (channel) {
|
||||
this.$delete(this.batteryInputs, channel)
|
||||
this.tableData = this.tableData.filter(item => item.index !== channel)
|
||||
},
|
||||
openFormatDialog () {
|
||||
this.formatDialogVisible = true
|
||||
this.fetchFormatList()
|
||||
},
|
||||
openFormatForm () {
|
||||
this.formatForm = {
|
||||
tray_format: '',
|
||||
battery_format: '',
|
||||
battery_count: 1
|
||||
}
|
||||
this.formatFormVisible = true
|
||||
},
|
||||
async createFormat () {
|
||||
if (!this.formatForm.tray_format) {
|
||||
this.$message.warning(this.$t(this.key('add_tray_format')))
|
||||
return
|
||||
}
|
||||
if (!this.formatForm.battery_format) {
|
||||
this.$message.warning(this.$t(this.key('add_battery_format')))
|
||||
return
|
||||
}
|
||||
if (!this.formatForm.battery_count || Number(this.formatForm.battery_count) <= 0) {
|
||||
this.$message.warning(this.$t(this.key('add_battery_count')))
|
||||
return
|
||||
}
|
||||
await createBatchTrayFormat({
|
||||
action: 'set_login_format',
|
||||
...this.formatForm
|
||||
})
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.formatFormVisible = false
|
||||
this.fetchFormatList()
|
||||
},
|
||||
deleteFormat (row) {
|
||||
this.$confirm(this.$t(this.key('delete_confirm')), this.$t(this.key('prompt')), {
|
||||
confirmButtonText: this.$t(this.key('confirm')),
|
||||
cancelButtonText: this.$t(this.key('cancel')),
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
await deleteBatchTrayFormat({
|
||||
action: 'set_login_format',
|
||||
id: row.id
|
||||
})
|
||||
this.$message.success(this.$t(this.key('delete_success')))
|
||||
this.fetchFormatList()
|
||||
}).catch(() => {})
|
||||
},
|
||||
openSubmitDialog () {
|
||||
if (!this.validateSubmit()) return
|
||||
this.submitDialogVisible = true
|
||||
},
|
||||
validateSubmit () {
|
||||
if (!this.validateTray()) return false
|
||||
if (!this.form.batch) {
|
||||
this.$message.warning(this.$t(this.key('no_batch_no')))
|
||||
return false
|
||||
}
|
||||
if (!this.tableData.length) {
|
||||
this.$message.warning(this.$t(this.key('enter_battery_code')))
|
||||
return false
|
||||
}
|
||||
if (this.tableData.some(item => Number(item.active) === 1)) {
|
||||
this.$message.warning(this.$t(this.key('has_active_battery_login_forbidden')))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
batteryIdsForSubmit () {
|
||||
return this.channelList.map(channel => {
|
||||
const row = this.tableData.find(item => item.index === channel)
|
||||
return row ? row.Battery : '0'
|
||||
})
|
||||
},
|
||||
async submitRegistration () {
|
||||
if (!this.validateSubmit()) return
|
||||
this.submitting = true
|
||||
try {
|
||||
const res = await sendWorkerman({
|
||||
sendData: {
|
||||
action: 'set_tray_login',
|
||||
param: {
|
||||
workingsubclass: 'LOGIN',
|
||||
tray: this.form.tray,
|
||||
batch: this.form.batch,
|
||||
device_code: 'WEBMAN_LOGIN',
|
||||
direction_sign: '',
|
||||
lot: String(new Date().valueOf()),
|
||||
battery_ids: this.batteryIdsForSubmit(),
|
||||
Manual: true
|
||||
}
|
||||
}
|
||||
})
|
||||
const payload = res && res.data ? res.data : (res || {})
|
||||
if (payload.code !== undefined && Number(payload.code) !== 0) {
|
||||
this.$message.warning(payload.errmsg || payload.msg || this.$t(this.key('operation_failed')))
|
||||
return
|
||||
}
|
||||
this.$message.success(this.$t(this.key('upload_success')))
|
||||
this.submitDialogVisible = false
|
||||
this.resetPage()
|
||||
} finally {
|
||||
this.submitting = false
|
||||
}
|
||||
},
|
||||
unbindTray () {
|
||||
this.promptTray('tray_unbind_desc', 'tray_unbind', 'set_tray_unbinding', 'tray_unbind_success')
|
||||
},
|
||||
stopTray () {
|
||||
this.promptTray('tray_stop_desc', 'tray_stop', 'set_tray_inactivity', 'tray_stop_success')
|
||||
},
|
||||
promptTray (messageKey, titleKey, action, successKey) {
|
||||
this.$prompt(this.$t(this.key(messageKey)), this.$t(this.key(titleKey)), {
|
||||
confirmButtonText: this.$t(this.key('confirm')),
|
||||
cancelButtonText: this.$t(this.key('cancel')),
|
||||
inputValue: this.form.tray,
|
||||
inputValidator: value => {
|
||||
if (!value) return this.$t(this.key('enter_tray_no'))
|
||||
return true
|
||||
}
|
||||
}).then(async ({ value }) => {
|
||||
const param = action === 'set_tray_inactivity'
|
||||
? { data: [{ tray: value }] }
|
||||
: { tray: value }
|
||||
await sendWorkerman({
|
||||
sendData: {
|
||||
action,
|
||||
param
|
||||
}
|
||||
})
|
||||
this.$message.success(this.$t(this.key(successKey)))
|
||||
}).catch(() => {})
|
||||
},
|
||||
batchInactivity () {
|
||||
if (!this.selectedRows.length) {
|
||||
this.$message.warning(this.$t(this.key('select_battery_to_deactivate')))
|
||||
return
|
||||
}
|
||||
this.$confirm(this.$t(this.key('battery_deactivate')), this.$t(this.key('prompt')), {
|
||||
confirmButtonText: this.$t(this.key('confirm')),
|
||||
cancelButtonText: this.$t(this.key('cancel')),
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
await sendWorkerman({
|
||||
sendData: {
|
||||
action: 'set_battery_inactivity',
|
||||
param: {
|
||||
data: this.selectedRows.map(row => ({
|
||||
battery_id: row.Battery || row.battery_id,
|
||||
class: 'NG',
|
||||
classname: 'web_inactivity'
|
||||
}))
|
||||
}
|
||||
}
|
||||
})
|
||||
this.selectedRows.forEach(row => {
|
||||
const target = this.tableData.find(item => item.index === row.index)
|
||||
if (target) this.$set(target, 'active', 0)
|
||||
})
|
||||
this.$message.success(this.$t(this.key('batch_battery_deactivate_success')))
|
||||
}).catch(() => {})
|
||||
},
|
||||
rowClassName ({ row }) {
|
||||
return Number(row.active) === 1 ? 'is-active-battery' : ''
|
||||
},
|
||||
resetPage () {
|
||||
this.form.tray = ''
|
||||
this.batteryInputs = {}
|
||||
this.tableData = []
|
||||
this.selectedRows = []
|
||||
this.submitDialogVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.registration-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(360px, 1fr) minmax(520px, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.channel-panel,
|
||||
.battery-panel {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.panel-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 32px;
|
||||
margin-bottom: 8px;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.channel-grid {
|
||||
max-height: 560px;
|
||||
padding-right: 8px;
|
||||
overflow: auto;
|
||||
|
||||
::v-deep .el-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
||||
column-gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.format-table {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.danger-action {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
::v-deep .el-table .is-active-battery td {
|
||||
background-color: rgba(245, 108, 108, 0.12);
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.registration-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user