Merge branch 'master' of http://119.91.43.128:3001/sheng/mes-ui-d2
This commit is contained in:
36
docs/功能测试-电池复投管理.md
Normal file
36
docs/功能测试-电池复投管理.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# 功能测试 - 电池复投管理
|
||||||
|
|
||||||
|
> 模块:计划与生产 / 生产监控 / 电池复投管理 (Rework Management)
|
||||||
|
> 路由:`/planning_production/produce/monitor/set_battery_rebatch`
|
||||||
|
|
||||||
|
## 测试前置条件
|
||||||
|
|
||||||
|
- 测试账号具备访问“电池复投管理”的菜单权限。
|
||||||
|
- 准备至少 3 个可用于验证的电池条码,其中包含:
|
||||||
|
- 允许复投的电池条码。
|
||||||
|
- 不允许复投或不存在的电池条码。
|
||||||
|
- 已激活和未激活状态各一条。
|
||||||
|
- 后端 Workerman 服务可用,接口 `production_configuration/workerman/send` 可正常响应。
|
||||||
|
|
||||||
|
## 测试任务列表
|
||||||
|
|
||||||
|
| 序号 | 测试项 | 操作步骤 | 预期结果 |
|
||||||
|
|---:|---|---|---|
|
||||||
|
| 1 | 页面入口 | 从菜单进入“电池复投管理”页面,或直接访问 `/planning_production/produce/monitor/set_battery_rebatch` | 页面正常打开,显示电池条码输入框、验证数据、重置、复投激活按钮和空表格 |
|
||||||
|
| 2 | 单个电池验证 | 在电池条码输入框输入一条有效电池条码,点击“验证数据” | 表格展示该电池的批次、托盘、流水号、激活状态、档位、上一工序和当前工序 |
|
||||||
|
| 3 | 多电池粘贴验证 | 在输入框输入多个条码,使用逗号、空格或换行分隔,点击“验证数据” | 系统可自动规范化输入并返回多行电池数据 |
|
||||||
|
| 4 | 多电池弹窗输入 | 点击输入框右侧导入按钮,在弹窗中每行输入一个电池条码,点击“确定”后再点击“验证数据” | 输入框自动填入逗号分隔条码,表格展示对应验证数据 |
|
||||||
|
| 5 | 空输入校验 | 清空电池条码,点击“验证数据” | 页面提示“请输入电池条码数据”,不发起有效验证 |
|
||||||
|
| 6 | 重置功能 | 输入条码并验证出表格数据后,点击“重置” | 输入框、表格数据和已选行清空 |
|
||||||
|
| 7 | 全部复投激活 | 验证出多条可复投电池数据,不勾选表格行,点击“复投激活”并确认 | 请求提交表格内全部电池条码,成功后提示复投激活操作成功 |
|
||||||
|
| 8 | 选中行复投激活 | 验证出多条电池数据,勾选其中一部分,点击“复投激活”并确认 | 仅提交被勾选的电池条码,成功后提示复投激活操作成功 |
|
||||||
|
| 9 | 未验证直接复投 | 输入电池条码但不点击“验证数据”,直接点击“复投激活” | 页面提示需要先验证电池数据,不提交 Workerman 复投请求 |
|
||||||
|
| 10 | 复投取消 | 验证出表格数据,点击“复投激活”,在确认框点击取消 | 不提交复投请求,页面数据保持不变 |
|
||||||
|
| 11 | 后端失败提示 | 使用后端会返回失败的电池数据执行复投 | 页面显示后端错误信息或“复投激活失败”提示 |
|
||||||
|
| 12 | 国际化检查 | 切换中英文语言后重新进入页面 | 页面按钮、表格列和提示文案随语言切换显示 |
|
||||||
|
|
||||||
|
## 回归关注点
|
||||||
|
|
||||||
|
- 验证接口返回空数据时,表格应显示空态且页面不报错。
|
||||||
|
- 表格行勾选后再重置,已选状态应同步清空。
|
||||||
|
- 复投激活接口调用参数中的 `action` 应为 `set_battery_rebatch`,`battery_ids` 应与测试输入或勾选行一致。
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
> 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。
|
> 根据 `后台Webman界面截图对照表.md` 生成。状态以当前 V2 项目中已落地的页面目录为准。
|
||||||
|
|
||||||
- 总功能数:79
|
- 总功能数:79
|
||||||
- 已迁移:26
|
- 已迁移:27
|
||||||
- 未迁移:53
|
- 未迁移:52
|
||||||
|
|
||||||
| 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 |
|
| 状态 | 一级模块 | 二级模块 | 三级模块 | 功能说明 | V2 目标路径 |
|
||||||
|:---:|---|---|---|---|---|
|
|:---:|---|---|---|---|---|
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
| ✅ | 计划与生产 (Planning & Production) | 生产批次管理 (Batch Management) | 生产批次不良报表 (Batch Defect Report) | 不良报表 | `src/views/planning-production/batch-management/batch-defect-report/` |
|
| ✅ | 计划与生产 (Planning & Production) | 生产批次管理 (Batch Management) | 生产批次不良报表 (Batch Defect Report) | 不良报表 | `src/views/planning-production/batch-management/batch-defect-report/` |
|
||||||
| ✅ | 计划与生产 (Planning & Production) | 预警中心 (Alert Center) | 预警中心 (Alert Center) | 预警中心 | `src/views/planning-production/alert-center/` |
|
| ✅ | 计划与生产 (Planning & Production) | 预警中心 (Alert Center) | 预警中心 (Alert Center) | 预警中心 | `src/views/planning-production/alert-center/` |
|
||||||
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 物料监控 (Material Monitoring) | 物料监控 | `src/views/planning-production/production-monitoring/material-monitoring/` |
|
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 物料监控 (Material Monitoring) | 物料监控 | `src/views/planning-production/production-monitoring/material-monitoring/` |
|
||||||
| ⬜ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池复投管理 (Rework Management) | 返工管理 | 待确认 |
|
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 电池复投管理 (Rework Management) | 返工管理 | `src/views/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 Management) | 托盘管理 | `src/views/planning-production/production-monitoring/tray-management/` |
|
||||||
| ✅ | 计划与生产 (Planning & Production) | 生产监控 (Production Monitoring) | 托盘登录 (Tray Registration) | 托盘登记 | `src/views/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) | 设备监控 (Equipment Monitoring) | 设备监控 | `src/views/planning-production/production-monitoring/equipment-monitoring/` |
|
||||||
|
|||||||
19
src/api/planning-production/rework-management.js
Normal file
19
src/api/planning-production/rework-management.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { request } from '@/api/_service'
|
||||||
|
|
||||||
|
const BASE = 'planning_production/produce/set_battery_rebatch/'
|
||||||
|
|
||||||
|
function apiParams (method, data = {}) {
|
||||||
|
return {
|
||||||
|
method,
|
||||||
|
platform: 'background',
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function verifyBatteryRebatchInfo (data) {
|
||||||
|
return request({
|
||||||
|
url: BASE + 'verify',
|
||||||
|
method: 'get',
|
||||||
|
params: apiParams('planning_production_produce_change_battery_process_verify', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1179,6 +1179,35 @@
|
|||||||
"enter_semi_finished_id": "Enter semi-finished ID",
|
"enter_semi_finished_id": "Enter semi-finished ID",
|
||||||
"start_time": "Start Time",
|
"start_time": "Start Time",
|
||||||
"end_time": "End Time"
|
"end_time": "End Time"
|
||||||
|
},
|
||||||
|
"rework_management": {
|
||||||
|
"active": "Activated",
|
||||||
|
"not_activated": "Inactive",
|
||||||
|
"reset": "Reset",
|
||||||
|
"battery_id": "Battery Barcode",
|
||||||
|
"enter_battery_id": "Enter battery barcode",
|
||||||
|
"verify_data": "Verify Data",
|
||||||
|
"input_rule": "Rule: One barcode per line",
|
||||||
|
"re_activate": "Re-activate",
|
||||||
|
"multi_battery_input": "Multi-Battery Input",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"enter_battery_id_before_action": "Enter battery barcode first!",
|
||||||
|
"enter_battery_data": "Enter battery barcode data",
|
||||||
|
"sort": "No.",
|
||||||
|
"batch": "Batch",
|
||||||
|
"tray": "Tray",
|
||||||
|
"lot": "No.",
|
||||||
|
"class_type": "Grade Type",
|
||||||
|
"class": "Grade",
|
||||||
|
"previous_process": "Previous Process",
|
||||||
|
"current_process": "Current Process",
|
||||||
|
"active_status": "Activation Status",
|
||||||
|
"prompt": "Notice",
|
||||||
|
"re_activate_success": "Re-activation successful",
|
||||||
|
"rethrow_activation_failed": "Re-activation failed",
|
||||||
|
"re_activate_warning": "Activating will skip current process. Proceed?",
|
||||||
|
"verify_data_before_action": "Verify battery data before re-activation"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"alert_center": {
|
"alert_center": {
|
||||||
|
|||||||
@@ -1179,6 +1179,35 @@
|
|||||||
"enter_semi_finished_id": "请输入半成品ID",
|
"enter_semi_finished_id": "请输入半成品ID",
|
||||||
"start_time": "开始时间",
|
"start_time": "开始时间",
|
||||||
"end_time": "结束时间"
|
"end_time": "结束时间"
|
||||||
|
},
|
||||||
|
"rework_management": {
|
||||||
|
"active": "激活",
|
||||||
|
"not_activated": "未激活",
|
||||||
|
"reset": "重置",
|
||||||
|
"battery_id": "电池条码",
|
||||||
|
"enter_battery_id": "请输入电池条码",
|
||||||
|
"verify_data": "验证数据",
|
||||||
|
"input_rule": "输入规则:每个电池条码占一行输入",
|
||||||
|
"re_activate": "复投激活",
|
||||||
|
"multi_battery_input": "多电池条码输入",
|
||||||
|
"confirm": "确定",
|
||||||
|
"cancel": "取消",
|
||||||
|
"enter_battery_id_before_action": "请输入电池条码后再执行此操作!",
|
||||||
|
"enter_battery_data": "请输入电池条码数据",
|
||||||
|
"sort": "序号",
|
||||||
|
"batch": "批次",
|
||||||
|
"tray": "托盘",
|
||||||
|
"lot": "流水号",
|
||||||
|
"class_type": "档位类型",
|
||||||
|
"class": "档位",
|
||||||
|
"previous_process": "上一工序",
|
||||||
|
"current_process": "当前工序",
|
||||||
|
"active_status": "激活状态",
|
||||||
|
"prompt": "提示!",
|
||||||
|
"re_activate_success": "复投激活操作成功!",
|
||||||
|
"rethrow_activation_failed": "复投激活失败",
|
||||||
|
"re_activate_warning": "确认后电池将激活,激活后只能从下一工序开始生产,不能重新做当前工序!",
|
||||||
|
"verify_data_before_action": "请先验证电池数据后再执行复投激活"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"alert_center": {
|
"alert_center": {
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ export default {
|
|||||||
meta: { ...meta, cache: true, title: '预警中心' },
|
meta: { ...meta, cache: true, title: '预警中心' },
|
||||||
component: _import('planning-production/alert-center')
|
component: _import('planning-production/alert-center')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'produce/monitor/set_battery_rebatch',
|
||||||
|
name: `${pre}monitor-set_battery_rebatch`,
|
||||||
|
meta: { ...meta, cache: true, title: '电池复投管理' },
|
||||||
|
component: _import('planning-production/production-monitoring/rework-management')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'produce/monitor/tray_manage',
|
path: 'produce/monitor/tray_manage',
|
||||||
name: `${pre}monitor-tray_manage`,
|
name: `${pre}monitor-tray_manage`,
|
||||||
|
|||||||
@@ -0,0 +1,209 @@
|
|||||||
|
<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('battery_id'))" prop="battery_ids">
|
||||||
|
<el-input
|
||||||
|
v-model="form.battery_ids"
|
||||||
|
:placeholder="$t(key('enter_battery_id'))"
|
||||||
|
class="battery-input"
|
||||||
|
clearable
|
||||||
|
@keyup.enter.native="verifyData"
|
||||||
|
>
|
||||||
|
<el-button slot="append" icon="el-icon-document-add" @click="openBatchInput" />
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-search"
|
||||||
|
:disabled="loading"
|
||||||
|
:loading="loading"
|
||||||
|
@click="verifyData"
|
||||||
|
>
|
||||||
|
{{ $t(key('verify_data')) }}
|
||||||
|
</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" :disabled="loading" @click="resetForm">
|
||||||
|
{{ $t(key('reset')) }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="warning" :disabled="loading" @click="setBatteryRebatch">
|
||||||
|
{{ $t(key('re_activate')) }}
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<page-table
|
||||||
|
:columns="columns"
|
||||||
|
:data="tableData"
|
||||||
|
:loading="loading"
|
||||||
|
:toolbar-buttons="[]"
|
||||||
|
:row-buttons="[]"
|
||||||
|
:pagination="null"
|
||||||
|
:table-attrs="{ size: 'mini', rowKey: 'battery_id', highlightCurrentRow: true }"
|
||||||
|
auto-height
|
||||||
|
@selection-change="onSelectionChange"
|
||||||
|
>
|
||||||
|
<template #col-active="{ row }">
|
||||||
|
<el-tag :type="Number(row.active) === 0 ? 'info' : 'success'" size="mini">
|
||||||
|
{{ Number(row.active) === 0 ? $t(key('not_activated')) : $t(key('active')) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #empty>
|
||||||
|
<el-empty :description="$t('暂无数据')" :image-size="80" />
|
||||||
|
</template>
|
||||||
|
</page-table>
|
||||||
|
|
||||||
|
<el-dialog :title="$t(key('multi_battery_input'))" :visible.sync="dialogVisible" width="520px">
|
||||||
|
<el-form>
|
||||||
|
<el-form-item :label="$t(key('input_rule'))">
|
||||||
|
<el-input v-model="dialogBatteryIds" type="textarea" :rows="8" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer">
|
||||||
|
<el-button size="mini" @click="dialogVisible = false">{{ $t(key('cancel')) }}</el-button>
|
||||||
|
<el-button size="mini" type="primary" @click="confirmBatchInput">{{ $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 { verifyBatteryRebatchInfo } from '@/api/planning-production/rework-management'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'planning-production-rework-management',
|
||||||
|
components: { PageTable },
|
||||||
|
mixins: [i18nMixin('page.planning_production.production_monitoring.rework_management')],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
form: {
|
||||||
|
battery_ids: ''
|
||||||
|
},
|
||||||
|
tableData: [],
|
||||||
|
selectedRows: [],
|
||||||
|
dialogVisible: false,
|
||||||
|
dialogBatteryIds: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
columns () {
|
||||||
|
return useTableColumns([
|
||||||
|
{ prop: 'battery_id', label: this.key('battery_id'), minWidth: 180, showOverflowTooltip: true },
|
||||||
|
{ prop: 'batch', label: this.key('batch'), minWidth: 150, showOverflowTooltip: true },
|
||||||
|
{ prop: 'tray', label: this.key('tray'), minWidth: 110, showOverflowTooltip: true },
|
||||||
|
{ prop: 'lot', label: this.key('lot'), minWidth: 90, showOverflowTooltip: true },
|
||||||
|
{ prop: 'active', label: this.key('active_status'), width: 120, slot: 'active' },
|
||||||
|
{ prop: 'class', label: this.key('class_type'), minWidth: 90, showOverflowTooltip: true },
|
||||||
|
{ prop: 'classname', label: this.key('class'), minWidth: 90, showOverflowTooltip: true },
|
||||||
|
{ prop: 'process_code', label: this.key('previous_process'), minWidth: 180, showOverflowTooltip: true },
|
||||||
|
{ prop: 'next_process_code', label: this.key('current_process'), minWidth: 180, showOverflowTooltip: true }
|
||||||
|
], {
|
||||||
|
selectionWidth: 55,
|
||||||
|
indexWidth: 55
|
||||||
|
}).map(col => {
|
||||||
|
if (col.type === 'index') col.label = this.key('sort')
|
||||||
|
return col
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
normalizeBatteryIds (value) {
|
||||||
|
return String(value || '')
|
||||||
|
.split(/[\n,,\s]+/)
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(',')
|
||||||
|
},
|
||||||
|
ensureBatteryInput () {
|
||||||
|
this.form.battery_ids = this.normalizeBatteryIds(this.form.battery_ids)
|
||||||
|
if (this.form.battery_ids) return true
|
||||||
|
this.$message.warning(this.$t(this.key('enter_battery_data')))
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
openBatchInput () {
|
||||||
|
this.form.battery_ids = ''
|
||||||
|
this.dialogBatteryIds = ''
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
confirmBatchInput () {
|
||||||
|
this.form.battery_ids = this.normalizeBatteryIds(this.dialogBatteryIds)
|
||||||
|
this.dialogVisible = false
|
||||||
|
},
|
||||||
|
verifyData () {
|
||||||
|
if (!this.ensureBatteryInput()) return
|
||||||
|
this.loading = true
|
||||||
|
verifyBatteryRebatchInfo(this.form)
|
||||||
|
.then(res => {
|
||||||
|
const data = res && res.data ? res.data : res
|
||||||
|
this.tableData = data.data || []
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setBatteryRebatch () {
|
||||||
|
if (!this.ensureBatteryInput()) return
|
||||||
|
const sourceRows = this.selectedRows.length ? this.selectedRows : this.tableData
|
||||||
|
const batteryIds = sourceRows.map(item => item.battery_id).filter(Boolean)
|
||||||
|
if (!batteryIds.length) {
|
||||||
|
this.$message.warning(this.$t(this.key('verify_data_before_action')))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$confirm(this.$t(this.key('re_activate_warning')), this.$t(this.key('prompt')), {
|
||||||
|
confirmButtonText: this.$t(this.key('confirm')),
|
||||||
|
cancelButtonText: this.$t(this.key('cancel')),
|
||||||
|
type: 'warning',
|
||||||
|
closeOnClickModal: false
|
||||||
|
}).then(() => {
|
||||||
|
this.loading = true
|
||||||
|
return sendWorkerman({
|
||||||
|
sendData: {
|
||||||
|
action: 'set_battery_rebatch',
|
||||||
|
param: {
|
||||||
|
battery_ids: batteryIds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
const data = res && res.data ? res.data : res
|
||||||
|
if (data.code !== undefined && Number(data.code) !== 0) {
|
||||||
|
this.$message.warning(data.errmsg || data.msg || this.$t(this.key('rethrow_activation_failed')))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$message.success(this.$t(this.key('re_activate_success')))
|
||||||
|
}).catch(error => {
|
||||||
|
this.$message.warning(`${this.$t(this.key('rethrow_activation_failed'))}: ${error}`)
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
resetForm () {
|
||||||
|
if (this.$refs.form) this.$refs.form.resetFields()
|
||||||
|
this.tableData = []
|
||||||
|
this.selectedRows = []
|
||||||
|
this.dialogBatteryIds = ''
|
||||||
|
},
|
||||||
|
onSelectionChange (rows) {
|
||||||
|
this.selectedRows = rows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.search-bar {
|
||||||
|
margin-bottom: -18px;
|
||||||
|
}
|
||||||
|
.battery-input {
|
||||||
|
width: 360px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user