WMS主数据结构升级,支持仓库/物料类型等新实体

后端:重构WmsController/WmsService,新增仓库、库区、货位、物料类型等实体及其增删改查接口,支持批量生成网格货位、货位/容器锁定与启用、物料归档与批量清理。数据库模型新增Warehouse、MaterialType、StockEvent等表,调整索引和字段,支持SQLite自动补表/补列及数据迁移,接口兼容旧语义。

前端:wms.ts/types/wms.ts全面适配新结构,升级API路由和类型定义。WarehouseManagementView.vue重构,支持仓库、物料类型管理、货位网格可视化、库存事件展示等。WmsEntityDialog.vue支持新字段编辑及联动选择。新增AreaFacadePanel.vue实现库区网格立面可视化。wmsOptions.ts新增相关常量及UI优化。

兼容性:后端自动迁移旧数据,接口兼容旧绑定语义,提升灵活性、可维护性和可视化能力。
This commit is contained in:
2026-07-24 10:19:36 +08:00
parent ce66da772e
commit bdcd88608c
12 changed files with 1794 additions and 288 deletions
@@ -1,8 +1,10 @@
import http from './http'
import type {
WarehouseArea, Storage, Container, Material,
Warehouse, WarehouseArea, Storage, Container, Material, MaterialType,
ContainerLocation, ContainerMaterial, ContainerLocationHistory, ContainerMaterialHistory,
MasterDataPayload, StoragePayload, MaterialPayload, ContainerLocationPayload, ContainerMaterialPayload,
InventoryMaterialRow, StockEvent,
MasterDataPayload, AreaPayload, StoragePayload, ContainerPayload, MaterialPayload, MaterialTypePayload,
ContainerLocationPayload, BindMaterialPayload, GenerateBinsPayload,
WmsTransportRule, WmsTransportTask, TransportRulePayload, TransportRequestQuery, TransportCandidatePreview
} from '@/types/wms'
@@ -10,11 +12,25 @@ function q<T extends object>(params?: T) {
return { params }
}
export async function listAreas(keyword?: string) {
const { data } = await http.get<WarehouseArea[]>('/wms/areas', q({ q: keyword }))
export async function listWarehouses(keyword?: string) {
const { data } = await http.get<Warehouse[]>('/wms/warehouses', q({ q: keyword }))
return data
}
export async function saveArea(payload: MasterDataPayload) {
export async function saveWarehouse(payload: MasterDataPayload) {
const { data } = payload.id
? await http.put<Warehouse>(`/wms/warehouses/${payload.id}`, payload)
: await http.post<Warehouse>('/wms/warehouses', payload)
return data
}
export async function deleteWarehouse(id: string, version?: number) {
await http.delete(`/wms/warehouses/${id}`, q({ version }))
}
export async function listAreas(keyword?: string, warehouseId?: string) {
const { data } = await http.get<WarehouseArea[]>('/wms/areas', q({ q: keyword, warehouseId }))
return data
}
export async function saveArea(payload: AreaPayload) {
const { data } = payload.id
? await http.put<WarehouseArea>(`/wms/areas/${payload.id}`, payload)
: await http.post<WarehouseArea>('/wms/areas', payload)
@@ -24,8 +40,8 @@ export async function deleteArea(id: string, version?: number) {
await http.delete(`/wms/areas/${id}`, q({ version }))
}
export async function listStorages(keyword?: string) {
const { data } = await http.get<Storage[]>('/wms/storages', q({ q: keyword }))
export async function listStorages(keyword?: string, areaId?: string, locationKind?: string) {
const { data } = await http.get<Storage[]>('/wms/storages', q({ q: keyword, areaId, locationKind }))
return data
}
export async function saveStorage(payload: StoragePayload) {
@@ -37,12 +53,32 @@ export async function saveStorage(payload: StoragePayload) {
export async function deleteStorage(id: string, version?: number) {
await http.delete(`/wms/storages/${id}`, q({ version }))
}
export async function generateBins(areaId: string, payload: GenerateBinsPayload) {
const { data } = await http.post<{ created: number }>(`/wms/areas/${areaId}/generate-bins`, payload)
return data
}
export async function lockStorage(id: string, version?: number) {
const { data } = await http.post<Storage>(`/wms/storages/${id}/lock`, null, q({ version }))
return data
}
export async function unlockStorage(id: string, version?: number) {
const { data } = await http.post<Storage>(`/wms/storages/${id}/unlock`, null, q({ version }))
return data
}
export async function enableStorage(id: string, version?: number) {
const { data } = await http.post<Storage>(`/wms/storages/${id}/enable`, null, q({ version }))
return data
}
export async function disableStorage(id: string, version?: number) {
const { data } = await http.post<Storage>(`/wms/storages/${id}/disable`, null, q({ version }))
return data
}
export async function listContainers(keyword?: string) {
const { data } = await http.get<Container[]>('/wms/containers', q({ q: keyword }))
return data
}
export async function saveContainer(payload: MasterDataPayload) {
export async function saveContainer(payload: ContainerPayload) {
const { data } = payload.id
? await http.put<Container>(`/wms/containers/${payload.id}`, payload)
: await http.post<Container>('/wms/containers', payload)
@@ -52,8 +88,22 @@ export async function deleteContainer(id: string, version?: number) {
await http.delete(`/wms/containers/${id}`, q({ version }))
}
export async function listMaterials(keyword?: string) {
const { data } = await http.get<Material[]>('/wms/materials', q({ q: keyword }))
export async function listMaterialTypes(keyword?: string) {
const { data } = await http.get<MaterialType[]>('/wms/material-types', q({ q: keyword }))
return data
}
export async function saveMaterialType(payload: MaterialTypePayload) {
const { data } = payload.id
? await http.put<MaterialType>(`/wms/material-types/${payload.id}`, payload)
: await http.post<MaterialType>('/wms/material-types', payload)
return data
}
export async function deleteMaterialType(id: string, version?: number) {
await http.delete(`/wms/material-types/${id}`, q({ version }))
}
export async function listMaterials(params?: { q?: string; lifecycle?: string; onlyUnbound?: boolean; onlyBound?: boolean }) {
const { data } = await http.get<Material[]>('/wms/materials', q(params))
return data
}
export async function saveMaterial(payload: MaterialPayload) {
@@ -65,6 +115,13 @@ export async function saveMaterial(payload: MaterialPayload) {
export async function deleteMaterial(id: string, version?: number) {
await http.delete(`/wms/materials/${id}`, q({ version }))
}
export async function archiveMaterial(id: string, version?: number) {
const { data } = await http.post<Material>(`/wms/materials/${id}/archive`, null, q({ version }))
return data
}
export async function purgeArchivedMaterials(take = 200) {
await http.post('/wms/materials/purge-archived', null, q({ take }))
}
export async function listContainerLocations(params?: { locationType?: string; q?: string }) {
const { data } = await http.get<ContainerLocation[]>('/wms/container-locations', q(params))
@@ -78,18 +135,29 @@ export async function deleteContainerLocation(containerId: string, reason?: stri
await http.delete(`/wms/container-locations/${containerId}`, q({ reason }))
}
export async function listContainerMaterials(keyword?: string) {
const { data } = await http.get<ContainerMaterial[]>('/wms/container-materials', q({ q: keyword }))
export async function listContainerMaterials(params?: { q?: string; containerId?: string }) {
const { data } = await http.get<ContainerMaterial[]>('/wms/container-materials', q(params))
return data
}
export async function saveContainerMaterial(payload: ContainerMaterialPayload) {
const { data } = payload.id
? await http.put<ContainerMaterial>(`/wms/container-materials/${payload.id}`, payload)
: await http.post<ContainerMaterial>('/wms/container-materials', payload)
export async function bindMaterial(payload: BindMaterialPayload) {
const { data } = await http.post<ContainerMaterial>('/wms/container-materials/bind', payload)
return data
}
export async function deleteContainerMaterial(id: string, reason?: string) {
await http.delete(`/wms/container-materials/${id}`, q({ reason }))
/** @deprecated 使用 bindMaterial */
export async function saveContainerMaterial(payload: BindMaterialPayload) {
return bindMaterial(payload)
}
export async function deleteContainerMaterial(id: string, reason?: string, archive = false) {
await http.delete(`/wms/container-materials/${id}`, q({ reason, archive }))
}
export async function listInventoryMaterials(params?: { areaId?: string; storageId?: string; q?: string }) {
const { data } = await http.get<InventoryMaterialRow[]>('/wms/inventory/materials', q(params))
return data
}
export async function listStockEvents(params?: { eventType?: string; materialId?: string; containerId?: string }) {
const { data } = await http.get<StockEvent[]>('/wms/stock-events', q(params))
return data
}
export async function listContainerLocationHistory(containerId?: string) {