fix: 子卷包装关系新增判断erp卷号是否存在
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
message,
|
||||
Segmented,
|
||||
Select,
|
||||
Table,
|
||||
} from 'antdv-next';
|
||||
|
||||
import { batchCreateSubPackageRelation } from '#/api/lms/subpackagerelation';
|
||||
@@ -43,6 +44,31 @@ const viewOptions = [
|
||||
{ label: '▤ 卡片', value: 'card' },
|
||||
{ label: '▦ 表格', value: 'table' },
|
||||
];
|
||||
const batchTableColumns = [
|
||||
{ title: '序号', key: 'sequence', width: 70, fixed: 'left' as const },
|
||||
{ title: '木箱唯一码', key: 'packageBoxSn', width: 200 },
|
||||
{ title: '子卷号', key: 'containerName', width: 200 },
|
||||
{ title: '木箱类型', key: 'boxType', width: 190 },
|
||||
{ title: '木箱长', key: 'boxLength', width: 130 },
|
||||
{ title: '木箱宽', key: 'boxWidth', width: 130 },
|
||||
{ title: '木箱高', key: 'boxHigh', width: 130 },
|
||||
{
|
||||
title: '保质期(天)',
|
||||
key: 'qualityGuaranPeriod',
|
||||
width: 170,
|
||||
},
|
||||
{ title: '入库日期', key: 'dateOfFgInbound', width: 180 },
|
||||
{ title: '状态', key: 'status', width: 140 },
|
||||
{ title: '操作', key: 'operations', width: 150, fixed: 'right' as const },
|
||||
];
|
||||
const requiredColumnKeys = new Set([
|
||||
'boxType',
|
||||
'containerName',
|
||||
'dateOfFgInbound',
|
||||
'packageBoxSn',
|
||||
'qualityGuaranPeriod',
|
||||
'status',
|
||||
]);
|
||||
|
||||
const statusOptions = computed(() =>
|
||||
getDictOptions(DICT_TYPE.SUB_PACKAGE_STATUS).map((item) => ({
|
||||
@@ -50,6 +76,11 @@ const statusOptions = computed(() =>
|
||||
value: String(item.value),
|
||||
})),
|
||||
);
|
||||
const errorRowKeys = computed(() =>
|
||||
rows.value
|
||||
.filter((row) => rowErrors.value.has(row.clientKey))
|
||||
.map((row) => row.clientKey),
|
||||
);
|
||||
|
||||
function reset() {
|
||||
rows.value = [createBatchRow()];
|
||||
@@ -222,34 +253,37 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</Alert>
|
||||
|
||||
<div v-if="viewMode === 'table'" class="table-wrap">
|
||||
<table class="batch-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th><th><i>*</i> 木箱唯一码</th><th><i>*</i> 子卷号</th><th><i>*</i> 木箱类型</th>
|
||||
<th>木箱长</th><th>木箱宽</th><th>木箱高</th>
|
||||
<th><i>*</i> 保质期(天)</th><th><i>*</i> 入库日期</th>
|
||||
<th><i>*</i> 状态</th><th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-for="(row, index) in rows" :key="row.clientKey">
|
||||
<tr>
|
||||
<td class="sequence">{{ index + 1 }}</td>
|
||||
<td><Input v-model:value="row.packageBoxSn" :class="{ invalid: fieldError(index, 'packageBoxSn') }" placeholder="请输入木箱唯一码" @update:value="editField(index, 'packageBoxSn')" /><small>{{ fieldError(index, 'packageBoxSn') }}</small></td>
|
||||
<td><Input v-model:value="row.containerName" :class="{ invalid: fieldError(index, 'containerName') }" placeholder="请输入子卷号" @update:value="editField(index, 'containerName')" /><small>{{ fieldError(index, 'containerName') }}</small></td>
|
||||
<td><Input :value="row.boxType" readonly role="button" tabindex="0" aria-label="选择木箱类型" :class="{ invalid: fieldError(index, 'boxType') }" placeholder="请选择木箱类型" @click="selectBoxType(row.clientKey)" @keydown.enter="selectBoxType(row.clientKey)" @keydown.space.prevent="selectBoxType(row.clientKey)" /><small>{{ fieldError(index, 'boxType') }}</small></td>
|
||||
<td><Input v-model:value="row.boxLength" readonly placeholder="自动带出" /></td>
|
||||
<td><Input v-model:value="row.boxWidth" readonly placeholder="自动带出" /></td>
|
||||
<td><Input v-model:value="row.boxHigh" readonly placeholder="自动带出" /></td>
|
||||
<td><Input v-model:value="row.qualityGuaranPeriod" type="number" :class="{ invalid: fieldError(index, 'qualityGuaranPeriod') }" placeholder="例如:90" @update:value="editField(index, 'qualityGuaranPeriod')"><template #suffix><span class="input-unit">天</span></template></Input><small>{{ fieldError(index, 'qualityGuaranPeriod') }}</small></td>
|
||||
<td><DatePicker v-model:value="row.dateOfFgInbound" value-format="YYYY-MM-DD" format="YYYY-MM-DD" class="w-full" :class="{ invalid: fieldError(index, 'dateOfFgInbound') }" placeholder="请选择入库日期" @change="editField(index, 'dateOfFgInbound')" /><small>{{ fieldError(index, 'dateOfFgInbound') }}</small></td>
|
||||
<td><Select v-model:value="row.status" :options="statusOptions" :class="{ invalid: fieldError(index, 'status') }" @change="editField(index, 'status')" /><small>{{ fieldError(index, 'status') }}</small></td>
|
||||
<td class="operations"><Button type="link" @click="duplicateRow(index)"><template #icon><IconifyIcon icon="ant-design:copy-outlined" /></template>复制</Button><Button type="link" danger @click="removeRow(index)"><template #icon><IconifyIcon icon="ant-design:delete-outlined" /></template>删除</Button></td>
|
||||
</tr>
|
||||
<tr v-if="rowErrors.get(row.clientKey)" class="row-error"><td colspan="11">第 {{ index + 1 }} 行:{{ rowErrors.get(row.clientKey) }}</td></tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
<Table
|
||||
class="batch-table"
|
||||
bordered
|
||||
:columns="batchTableColumns"
|
||||
:data-source="rows"
|
||||
:expandable="{ showExpandColumn: false }"
|
||||
:expanded-row-keys="errorRowKeys"
|
||||
:pagination="false"
|
||||
row-key="clientKey"
|
||||
:scroll="{ x: 1690, y: 430 }"
|
||||
>
|
||||
<template #headerCell="{ column }">
|
||||
<i v-if="requiredColumnKeys.has(String(column.key))">*</i> {{ column.title }}
|
||||
</template>
|
||||
<template #bodyCell="{ column, record: row, index }">
|
||||
<span v-if="column.key === 'sequence'" class="sequence">{{ index + 1 }}</span>
|
||||
<template v-else-if="column.key === 'packageBoxSn'"><Input v-model:value="row.packageBoxSn" :class="{ invalid: fieldError(index, 'packageBoxSn') }" placeholder="请输入木箱唯一码" @update:value="editField(index, 'packageBoxSn')" /><small>{{ fieldError(index, 'packageBoxSn') }}</small></template>
|
||||
<template v-else-if="column.key === 'containerName'"><Input v-model:value="row.containerName" :class="{ invalid: fieldError(index, 'containerName') }" placeholder="请输入子卷号" @update:value="editField(index, 'containerName')" /><small>{{ fieldError(index, 'containerName') }}</small></template>
|
||||
<template v-else-if="column.key === 'boxType'"><Input :value="row.boxType" readonly role="button" tabindex="0" aria-label="选择木箱类型" :class="{ invalid: fieldError(index, 'boxType') }" placeholder="请选择木箱类型" @click="selectBoxType(row.clientKey)" @keydown.enter="selectBoxType(row.clientKey)" @keydown.space.prevent="selectBoxType(row.clientKey)" /><small>{{ fieldError(index, 'boxType') }}</small></template>
|
||||
<Input v-else-if="column.key === 'boxLength'" v-model:value="row.boxLength" readonly placeholder="自动带出" />
|
||||
<Input v-else-if="column.key === 'boxWidth'" v-model:value="row.boxWidth" readonly placeholder="自动带出" />
|
||||
<Input v-else-if="column.key === 'boxHigh'" v-model:value="row.boxHigh" readonly placeholder="自动带出" />
|
||||
<template v-else-if="column.key === 'qualityGuaranPeriod'"><Input v-model:value="row.qualityGuaranPeriod" type="number" :class="{ invalid: fieldError(index, 'qualityGuaranPeriod') }" placeholder="例如:90" @update:value="editField(index, 'qualityGuaranPeriod')"><template #suffix><span class="input-unit">天</span></template></Input><small>{{ fieldError(index, 'qualityGuaranPeriod') }}</small></template>
|
||||
<template v-else-if="column.key === 'dateOfFgInbound'"><DatePicker v-model:value="row.dateOfFgInbound" value-format="YYYY-MM-DD" format="YYYY-MM-DD" class="w-full" :class="{ invalid: fieldError(index, 'dateOfFgInbound') }" placeholder="请选择入库日期" @change="editField(index, 'dateOfFgInbound')" /><small>{{ fieldError(index, 'dateOfFgInbound') }}</small></template>
|
||||
<template v-else-if="column.key === 'status'"><Select v-model:value="row.status" class="w-full" :options="statusOptions" :class="{ invalid: fieldError(index, 'status') }" @change="editField(index, 'status')" /><small>{{ fieldError(index, 'status') }}</small></template>
|
||||
<div v-else-if="column.key === 'operations'" class="operations"><Button type="link" @click="duplicateRow(index)"><template #icon><IconifyIcon icon="ant-design:copy-outlined" /></template>复制</Button><Button type="link" danger @click="removeRow(index)"><template #icon><IconifyIcon icon="ant-design:delete-outlined" /></template>删除</Button></div>
|
||||
</template>
|
||||
<template #expandedRowRender="{ record, index }">
|
||||
<div class="row-error">第 {{ index + 1 }} 行:{{ rowErrors.get(record.clientKey) }}</div>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<div v-else class="card-list">
|
||||
@@ -359,7 +393,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
.table-wrap {
|
||||
flex: 1;
|
||||
min-height: 420px;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
background: hsl(var(--background));
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-radius: 10px;
|
||||
@@ -367,42 +401,31 @@ const [Modal, modalApi] = useVbenModal({
|
||||
|
||||
.batch-table {
|
||||
width: 100%;
|
||||
min-width: 1780px;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.batch-table th,
|
||||
.batch-table td {
|
||||
padding: 10px;
|
||||
vertical-align: top;
|
||||
background: hsl(var(--background));
|
||||
border-right: 1px solid hsl(var(--border));
|
||||
border-bottom: 1px solid hsl(var(--border));
|
||||
.batch-table :deep(.ant-table) {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.batch-table th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 3;
|
||||
.batch-table :deep(.ant-table-thead > tr > th) {
|
||||
height: 48px;
|
||||
color: #4b5870;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
background: #f3f6fb;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.batch-table th i {
|
||||
.batch-table :deep(.ant-table-tbody > tr > td) {
|
||||
padding: 10px;
|
||||
vertical-align: top;
|
||||
background: hsl(var(--background));
|
||||
}
|
||||
|
||||
.batch-table i {
|
||||
color: #ff4d4f;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.batch-table td {
|
||||
min-width: 145px;
|
||||
}
|
||||
|
||||
.batch-table :deep(.ant-input),
|
||||
.batch-table :deep(.ant-input-affix-wrapper),
|
||||
.batch-table :deep(.ant-picker),
|
||||
@@ -429,34 +452,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
|
||||
.batch-table .sequence {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
min-width: 64px;
|
||||
display: block;
|
||||
color: #788196;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.batch-table th:first-child {
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
min-width: 64px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.batch-table th:last-child,
|
||||
.batch-table .operations {
|
||||
position: sticky;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
min-width: 128px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
white-space: nowrap;
|
||||
box-shadow: -5px 0 12px rgb(21 35 62 / 6%);
|
||||
}
|
||||
|
||||
.batch-table th:last-child {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.batch-table small {
|
||||
@@ -474,7 +479,12 @@ const [Modal, modalApi] = useVbenModal({
|
||||
border-color: #ff4d4f;
|
||||
}
|
||||
|
||||
.row-error td {
|
||||
.batch-table :deep(.ant-table-expanded-row > td) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.row-error {
|
||||
padding: 9px 16px;
|
||||
color: #ff4d4f;
|
||||
background: #fff2f0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user