新增MES库区管理功能,包含免密接口、数据处理逻辑及相关控制器、服务和实体的实现。支持库区的增删改查操作,优化用户体验并增强系统的实时数据同步能力。
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user