This commit is contained in:
sheng
2026-06-22 16:27:16 +08:00
7 changed files with 331 additions and 3 deletions

View 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)
})
}

View File

@@ -1179,6 +1179,35 @@
"enter_semi_finished_id": "Enter semi-finished ID",
"start_time": "Start 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": {

View File

@@ -1179,6 +1179,35 @@
"enter_semi_finished_id": "请输入半成品ID",
"start_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": {

View File

@@ -44,6 +44,12 @@ export default {
meta: { ...meta, cache: true, title: '预警中心' },
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',
name: `${pre}monitor-tray_manage`,

View File

@@ -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>