209 lines
6.1 KiB
Vue
209 lines
6.1 KiB
Vue
<template>
|
||
<BasicModal
|
||
v-bind="$attrs"
|
||
@register="registerModal"
|
||
destroyOnClose
|
||
:title="title"
|
||
:width="700"
|
||
:confirmLoading="submitting"
|
||
@ok="handleSubmit"
|
||
>
|
||
<div style="margin-bottom: 10px; display: flex; justify-content: space-between; align-items: center">
|
||
<span style="color: #666; font-size: 13px">共 {{ rows.length }} 条</span>
|
||
<a-button type="primary" size="small" preIcon="ant-design:plus-outlined" @click="addRow">新增行</a-button>
|
||
</div>
|
||
|
||
<a-table
|
||
:columns="tableColumns"
|
||
:data-source="rows"
|
||
:pagination="false"
|
||
size="small"
|
||
bordered
|
||
row-key="__key"
|
||
:scroll="{ y: 380 }"
|
||
>
|
||
<template #bodyCell="{ column, record, index }">
|
||
<template v-if="column.key === 'seq'">
|
||
{{ index + 1 }}
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'areaCode'">
|
||
<a-input
|
||
v-model:value="record.areaCode"
|
||
placeholder="库区编码(必填)"
|
||
size="small"
|
||
:status="record.__codeError ? 'error' : ''"
|
||
@change="onAreaCodeChange(record)"
|
||
@blur="validateCode(record)"
|
||
/>
|
||
<div v-if="record.__codeError" style="color: #ff4d4f; font-size: 12px; margin-top: 2px">
|
||
{{ record.__codeError }}
|
||
</div>
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'areaName'">
|
||
<a-input v-model:value="record.areaName" placeholder="默认同库区编码" size="small" />
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'maxCapacity'">
|
||
<a-input-number
|
||
v-model:value="record.maxCapacity"
|
||
:min="0"
|
||
:precision="0"
|
||
placeholder="最大存放量"
|
||
size="small"
|
||
style="width: 100%"
|
||
/>
|
||
</template>
|
||
|
||
<template v-else-if="column.key === 'action'">
|
||
<a-button danger type="link" size="small" @click="removeRow(index)">删除</a-button>
|
||
</template>
|
||
</template>
|
||
</a-table>
|
||
|
||
<div v-if="rows.length === 0" style="text-align: center; color: #999; padding: 24px 0; font-size: 13px">
|
||
暂无库区明细,点击「新增行」添加
|
||
</div>
|
||
</BasicModal>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ref, computed } from 'vue';
|
||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||
import { useMessage } from '/@/hooks/web/useMessage';
|
||
import { batchAddAreas } from '/@/views/xslmes/mesXslWarehouseArea/MesXslWarehouseArea.api';
|
||
|
||
const { createMessage } = useMessage();
|
||
|
||
const emit = defineEmits(['register', 'success']);
|
||
|
||
const warehouseId = ref('');
|
||
const warehouseName = ref('');
|
||
const warehouseCategory = ref<string | undefined>(undefined);
|
||
const tenantId = ref<number | undefined>(undefined);
|
||
const submitting = ref(false);
|
||
|
||
let _rowKey = 0;
|
||
|
||
interface AreaRow {
|
||
__key: number;
|
||
__codeError: string;
|
||
__prevCode: string;
|
||
areaCode: string;
|
||
areaName: string;
|
||
maxCapacity: number | undefined;
|
||
}
|
||
|
||
const rows = ref<AreaRow[]>([]);
|
||
|
||
const title = computed(() =>
|
||
warehouseName.value ? `批量添加库区 — ${warehouseName.value}` : '批量添加库区'
|
||
);
|
||
|
||
const tableColumns = [
|
||
{ title: '序号', key: 'seq', width: 52, align: 'center' },
|
||
{ title: '库区编码 *', key: 'areaCode', width: 180 },
|
||
{ title: '库区名称', key: 'areaName', width: 180 },
|
||
{ title: '最大存放量', key: 'maxCapacity', width: 130 },
|
||
{ title: '操作', key: 'action', width: 60, align: 'center' },
|
||
];
|
||
|
||
const [registerModal, { setModalProps, closeModal }] = useModalInner((data) => {
|
||
rows.value = [];
|
||
_rowKey = 0;
|
||
warehouseId.value = data?.record?.id ?? '';
|
||
warehouseName.value = data?.record?.warehouseName ?? '';
|
||
warehouseCategory.value = data?.record?.warehouseCategory ?? undefined;
|
||
tenantId.value = data?.record?.tenantId ?? undefined;
|
||
addRow();
|
||
});
|
||
|
||
function addRow() {
|
||
rows.value.push({
|
||
__key: _rowKey++,
|
||
__codeError: '',
|
||
__prevCode: '',
|
||
areaCode: '',
|
||
areaName: '',
|
||
maxCapacity: undefined,
|
||
});
|
||
}
|
||
|
||
function removeRow(index: number) {
|
||
rows.value.splice(index, 1);
|
||
}
|
||
|
||
function onAreaCodeChange(record: AreaRow) {
|
||
if (!record.areaName || record.areaName === record.__prevCode) {
|
||
record.areaName = record.areaCode;
|
||
}
|
||
record.__prevCode = record.areaCode;
|
||
record.__codeError = '';
|
||
}
|
||
|
||
function validateCode(record: AreaRow) {
|
||
if (!record.areaCode || !record.areaCode.trim()) {
|
||
record.__codeError = '库区编码不能为空';
|
||
} else {
|
||
record.__codeError = '';
|
||
}
|
||
}
|
||
|
||
async function handleSubmit() {
|
||
if (rows.value.length === 0) {
|
||
createMessage.warning('请至少添加一条库区记录');
|
||
return;
|
||
}
|
||
|
||
// Validate all rows
|
||
let hasError = false;
|
||
const codeSet = new Set<string>();
|
||
for (const row of rows.value) {
|
||
const code = (row.areaCode || '').trim();
|
||
if (!code) {
|
||
row.__codeError = '库区编码不能为空';
|
||
hasError = true;
|
||
continue;
|
||
}
|
||
if (codeSet.has(code)) {
|
||
row.__codeError = '库区编码重复';
|
||
hasError = true;
|
||
continue;
|
||
}
|
||
codeSet.add(code);
|
||
row.__codeError = '';
|
||
}
|
||
|
||
if (hasError) {
|
||
createMessage.error('请修正红色标记的错误后再提交');
|
||
return;
|
||
}
|
||
|
||
const payload = rows.value.map((row) => ({
|
||
areaCode: row.areaCode.trim(),
|
||
areaName: (row.areaName || row.areaCode).trim() || row.areaCode.trim(),
|
||
maxCapacity: row.maxCapacity ?? undefined,
|
||
warehouseId: warehouseId.value,
|
||
warehouseName: warehouseName.value,
|
||
warehouseCategory: warehouseCategory.value,
|
||
tenantId: tenantId.value,
|
||
status: '0',
|
||
}));
|
||
|
||
try {
|
||
submitting.value = true;
|
||
setModalProps({ confirmLoading: true });
|
||
await batchAddAreas(payload);
|
||
createMessage.success(`批量添加成功,共创建 ${payload.length} 个库区!`);
|
||
closeModal();
|
||
emit('success');
|
||
} catch {
|
||
// error handled by global interceptor
|
||
} finally {
|
||
submitting.value = false;
|
||
setModalProps({ confirmLoading: false });
|
||
}
|
||
}
|
||
</script>
|