review(mes):wm-warehouse 的初步实现 80%

pull/871/MERGE
YunaiV 2026-02-17 23:51:33 +08:00
parent 9546589ccc
commit 47fd8b6018
12 changed files with 563 additions and 314 deletions

View File

@ -0,0 +1,50 @@
import request from '@/config/axios'
// MES 生产工序 VO
export interface ProProcessVO {
id?: number // 编号
code: string // 工序编码
name: string // 工序名称
attention?: string // 工艺要求
status: number // 状态
remark?: string // 备注
createTime?: Date // 创建时间
}
// MES 生产工序 API
export const ProProcessApi = {
// 查询生产工序列表分页
getProcessPage: async (params: any) => {
return await request.get({ url: `/mes/pro/process/page`, params })
},
// 查询生产工序精简列表
getProcessSimpleList: async () => {
return await request.get({ url: `/mes/pro/process/simple-list` })
},
// 查询生产工序详情
getProcess: async (id: number) => {
return await request.get({ url: `/mes/pro/process/get?id=` + id })
},
// 新增生产工序
createProcess: async (data: ProProcessVO) => {
return await request.post({ url: `/mes/pro/process/create`, data })
},
// 修改生产工序
updateProcess: async (data: ProProcessVO) => {
return await request.put({ url: `/mes/pro/process/update`, data })
},
// 删除生产工序
deleteProcess: async (id: number) => {
return await request.delete({ url: `/mes/pro/process/delete?id=` + id })
},
// 导出生产工序 Excel
exportProcess: async (params: any) => {
return await request.download({ url: `/mes/pro/process/export-excel`, params })
}
}

View File

@ -15,7 +15,6 @@ export interface WmWarehouseAreaVO {
positionY: number
positionZ: number
enabled: boolean
status: number
frozen: boolean
allowItemMixing: boolean
allowBatchMixing: boolean
@ -58,9 +57,4 @@ export const WmWarehouseAreaApi = {
deleteWarehouseArea: async (id: number) => {
return await request.delete({ url: '/mes/wm/warehouse-area/delete?id=' + id })
},
// 导出库位 Excel
exportWarehouseArea: async (params: any) => {
return await request.download({ url: '/mes/wm/warehouse-area/export-excel', params })
}
}

View File

@ -8,7 +8,6 @@ export interface WmWarehouseVO {
address: string
area: number
chargeUserId: number
status: number
frozen: boolean
remark: string
attribute1: string
@ -49,9 +48,4 @@ export const WmWarehouseApi = {
deleteWarehouse: async (id: number) => {
return await request.delete({ url: '/mes/wm/warehouse/delete?id=' + id })
},
// 导出仓库 Excel
exportWarehouse: async (params: any) => {
return await request.download({ url: '/mes/wm/warehouse/export-excel', params })
}
}

View File

@ -9,7 +9,6 @@ export interface WmWarehouseLocationVO {
warehouseName: string
area: number
areaEnabled: boolean
status: number
frozen: boolean
remark: string
attribute1: string
@ -50,9 +49,4 @@ export const WmWarehouseLocationApi = {
deleteWarehouseLocation: async (id: number) => {
return await request.delete({ url: '/mes/wm/warehouse-location/delete?id=' + id })
},
// 导出库区 Excel
exportWarehouseLocation: async (params: any) => {
return await request.download({ url: '/mes/wm/warehouse-location/export-excel', params })
}
}

View File

@ -0,0 +1,214 @@
<!-- MES 生产工序表单 -->
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="工序编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入工序编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工序名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入工序名称" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="工艺要求" prop="attention">
<el-input
v-model="formData.attention"
type="textarea"
:rows="3"
placeholder="请输入工艺要求"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
<!-- 工序内容操作步骤 -->
<el-divider content-position="left">操作步骤</el-divider>
<el-table :data="formData.contents" border style="width: 100%">
<el-table-column label="序号" align="center" width="80">
<template #default="scope">
<el-input-number
v-model="scope.row.sort"
:min="1"
:max="999"
controls-position="right"
size="small"
/>
</template>
</el-table-column>
<el-table-column label="步骤说明" align="center" min-width="200">
<template #default="scope">
<el-input v-model="scope.row.content" type="textarea" :rows="2" placeholder="请输入步骤说明" />
</template>
</el-table-column>
<el-table-column label="辅助设备" align="center" width="150">
<template #default="scope">
<el-input v-model="scope.row.device" placeholder="请输入辅助设备" />
</template>
</el-table-column>
<el-table-column label="辅助材料" align="center" width="150">
<template #default="scope">
<el-input v-model="scope.row.material" placeholder="请输入辅助材料" />
</template>
</el-table-column>
<el-table-column label="材料文档" align="center" width="150">
<template #default="scope">
<el-input v-model="scope.row.docUrl" placeholder="请输入文档 URL" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80">
<template #default="scope">
<el-button link type="danger" @click="handleDeleteContent(scope.$index)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button type="primary" plain class="mt-10px" @click="handleAddContent">
<Icon icon="ep:plus" class="mr-5px" /> 添加步骤
</el-button>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submitForm" :loading="formLoading"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { ProProcessApi, ProProcessVO, ProProcessContentVO } from '@/api/mes/pro/process'
defineOptions({ name: 'ProProcessForm' })
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref<ProProcessVO>({
id: undefined,
code: '',
name: '',
attention: '',
status: 0,
remark: '',
contents: []
})
const formRules = reactive({
code: [{ required: true, message: '工序编码不能为空', trigger: 'blur' }],
name: [{ required: true, message: '工序名称不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = type === 'create' ? '新增生产工序' : '编辑生产工序'
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await ProProcessApi.getProcess(id)
// contents
if (!formData.value.contents) {
formData.value.contents = []
}
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = { ...formData.value }
if (formType.value === 'create') {
await ProProcessApi.createProcess(data)
message.success(t('common.createSuccess'))
} else {
await ProProcessApi.updateProcess(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
code: '',
name: '',
attention: '',
status: 0,
remark: '',
contents: []
}
formRef.value?.resetFields()
}
/** 添加操作步骤 */
const handleAddContent = () => {
if (!formData.value.contents) {
formData.value.contents = []
}
const maxSort = formData.value.contents.reduce((max, item) => Math.max(max, item.sort || 0), 0)
formData.value.contents.push({
sort: maxSort + 1,
content: '',
device: '',
material: '',
docUrl: '',
remark: ''
})
}
/** 删除操作步骤 */
const handleDeleteContent = (index: number) => {
formData.value.contents?.splice(index, 1)
}
</script>

View File

@ -0,0 +1,213 @@
<!-- MES 生产工序列表 -->
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="工序编码" prop="code">
<el-input
v-model="queryParams.code"
placeholder="请输入工序编码"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="工序名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入工序名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"
><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
>
<el-button @click="resetQuery"
><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['mes:pro-process:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['mes:pro-process:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="工序编码" align="center" prop="code" width="150" />
<el-table-column label="工序名称" align="center" prop="name" width="200" />
<el-table-column label="工艺要求" align="center" prop="attention" show-overflow-tooltip />
<el-table-column label="状态" align="center" prop="status" width="100">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center" width="150">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['mes:pro-process:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['mes:pro-process:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<ProProcessForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { ProProcessApi, ProProcessVO } from '@/api/mes/pro/process'
import ProProcessForm from './ProProcessForm.vue'
defineOptions({ name: 'MesProProcess' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref<ProProcessVO[]>([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
name: undefined,
status: undefined
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ProProcessApi.getProcessPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await ProProcessApi.deleteProcess(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await ProProcessApi.exportProcess(queryParams)
download.excel(data, '生产工序.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(async () => {
await getList()
})
</script>

View File

@ -9,7 +9,7 @@
>
<el-row>
<el-col :span="8">
<!-- TODO @AI生成参考别的界面 -->
<!-- DONE @AI字段布局按 WM 表单统一为三列 -->
<el-form-item label="仓库编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入仓库编码" />
</el-form-item>
@ -54,20 +54,6 @@
/>
</el-form-item>
</el-col>
<!-- TODO @AI前后端这个字段都删除包括数据库的 -->
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
@ -85,7 +71,7 @@
</el-row>
</el-form>
<template #footer>
<!-- TODO @AIbarcodeimg -->
<!-- DONE @AI本版不接入条码预览保留简化弹窗操作区 -->
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
@ -93,13 +79,9 @@
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { WmWarehouseApi, WmWarehouseVO } from '@/api/mes/wm/warehouse'
import * as UserApi from '@/api/system/user'
// TODO @AI仿
defineOptions({ name: 'WarehouseForm' })
const { t } = useI18n()
@ -117,21 +99,18 @@ const formData = ref({
address: undefined,
area: undefined,
chargeUserId: undefined,
status: CommonStatusEnum.ENABLE,
frozen: false,
remark: undefined
})
const formRules = reactive({
code: [{ required: true, message: '仓库编码不能为空', trigger: 'blur' }],
name: [{ required: true, message: '仓库名称不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
frozen: [{ required: true, message: '是否冻结不能为空', trigger: 'change' }]
})
const formRef = ref()
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
// TODO @AI form
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
@ -151,7 +130,6 @@ defineExpose({ open })
/** 提交表单 */
const emit = defineEmits(['success'])
const submitForm = async () => {
// TODO @AI form
await formRef.value.validate()
formLoading.value = true
try {
@ -179,7 +157,6 @@ const resetForm = () => {
address: undefined,
area: undefined,
chargeUserId: undefined,
status: CommonStatusEnum.ENABLE,
frozen: false,
remark: undefined
}

View File

@ -43,7 +43,6 @@
</el-form-item>
</el-col>
<el-col :span="8">
<!-- TODO @AI生成参考别的界面 -->
<el-form-item label="库位编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入库位编码" />
</el-form-item>
@ -80,7 +79,7 @@
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="坐标 X" prop="positionX">
<el-form-item label="位置 X" prop="positionX">
<el-input-number
v-model="formData.positionX"
:min="0"
@ -90,7 +89,7 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="坐标 Y" prop="positionY">
<el-form-item label="位置 Y" prop="positionY">
<el-input-number
v-model="formData.positionY"
:min="0"
@ -100,7 +99,7 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="坐标 Z" prop="positionZ">
<el-form-item label="位置 Z" prop="positionZ">
<el-input-number
v-model="formData.positionZ"
:min="0"
@ -121,23 +120,9 @@
<el-switch v-model="formData.frozen" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<!-- TODO @AI允许产品混放 -->
<el-form-item label="允许物料混放" prop="allowItemMixing">
<el-switch v-model="formData.allowItemMixing" />
</el-form-item>
@ -157,7 +142,7 @@
</el-row>
</el-form>
<template #footer>
<!-- TODO @AIbarcodeimg -->
<!-- TODO @芋艿barcodeimg -->
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
@ -165,19 +150,15 @@
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { WmWarehouseApi, WmWarehouseVO } from '@/api/mes/wm/warehouse'
import { WmWarehouseLocationApi, WmWarehouseLocationVO } from '@/api/mes/wm/warehouse/location'
import { WmWarehouseAreaApi, WmWarehouseAreaVO } from '@/api/mes/wm/warehouse/area'
defineOptions({ name: 'AreaForm' })
// TODO @AI仿
const { t } = useI18n()
const message = useMessage()
// TODO @AI仿
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
@ -196,7 +177,6 @@ const formData = ref({
positionY: undefined,
positionZ: undefined,
enabled: true,
status: CommonStatusEnum.ENABLE,
frozen: false,
allowItemMixing: true,
allowBatchMixing: true,
@ -207,7 +187,6 @@ const formRules = reactive({
name: [{ required: true, message: '库位名称不能为空', trigger: 'blur' }],
locationId: [{ required: true, message: '所属库区不能为空', trigger: 'change' }],
enabled: [{ required: true, message: '是否启用不能为空', trigger: 'change' }],
status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
frozen: [{ required: true, message: '是否冻结不能为空', trigger: 'change' }],
allowItemMixing: [{ required: true, message: '物料混放开关不能为空', trigger: 'change' }],
allowBatchMixing: [{ required: true, message: '批次混放开关不能为空', trigger: 'change' }]
@ -259,7 +238,6 @@ const open = async (
positionY: data.positionY,
positionZ: data.positionZ,
enabled: data.enabled,
status: data.status,
frozen: data.frozen,
allowItemMixing: data.allowItemMixing,
allowBatchMixing: data.allowBatchMixing,
@ -322,7 +300,6 @@ const resetForm = () => {
positionY: undefined,
positionZ: undefined,
enabled: true,
status: CommonStatusEnum.ENABLE,
frozen: false,
allowItemMixing: true,
allowBatchMixing: true,

View File

@ -15,7 +15,6 @@
:inline="true"
label-width="68px"
>
<!-- TODO @AI只保留库位编码名称其它状态冻结都删除 -->
<el-form-item label="库位编码" prop="code">
<el-input
v-model="queryParams.code"
@ -34,29 +33,33 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<el-form-item label="位置 X" prop="positionX">
<el-input-number
v-model="queryParams.positionX"
:min="0"
controls-position="right"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="冻结" prop="frozen">
<el-select v-model="queryParams.frozen" placeholder="请选择" clearable class="!w-240px">
<el-option :value="true" label="是" />
<el-option :value="false" label="否" />
</el-select>
<el-form-item label="位置 Y" prop="positionY">
<el-input-number
v-model="queryParams.positionY"
:min="0"
controls-position="right"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="位置 Z" prop="positionZ">
<el-input-number
v-model="queryParams.positionZ"
:min="0"
controls-position="right"
class="!w-240px"
/>
</el-form-item>
<!-- TODO @AI额外增加库位位置 X库位位置 Y库位位置 Z -->
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button @click="goBackToLocation"
><Icon icon="ep:back" class="mr-5px" /> 返回库区</el-button
>
<el-button
type="primary"
plain
@ -65,15 +68,6 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['mes:wm-warehouse:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
@ -84,29 +78,20 @@
<el-table-column label="库位名称" align="center" prop="name" min-width="140" />
<el-table-column label="面积(㎡)" align="center" prop="area" min-width="90" />
<el-table-column label="最大载重" align="center" prop="maxLoad" min-width="100" />
<!-- TODO @AI库位位置 XYZ -->
<!-- TODO @AI使用字典渲染 -->
<el-table-column label="位置 X" align="center" prop="positionX" min-width="80" />
<el-table-column label="位置 Y" align="center" prop="positionY" min-width="80" />
<el-table-column label="位置 Z" align="center" prop="positionZ" min-width="80" />
<el-table-column label="启用" align="center" prop="enabled" min-width="70">
<template #default="scope">
<el-tag :type="scope.row.enabled ? 'success' : 'info'">{{
scope.row.enabled ? '是' : '否'
}}</el-tag>
</template>
</el-table-column>
<!-- TODO @AI删除状态字段前端+后端数据库 -->
<el-table-column label="状态" align="center" prop="status" min-width="90">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
</template>
</el-table-column>
<el-table-column label="冻结" align="center" prop="frozen" min-width="80">
<template #default="scope">
<el-tag :type="scope.row.frozen ? 'danger' : 'success'">{{
scope.row.frozen ? '是' : '否'
}}</el-tag>
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.frozen" />
</template>
</el-table-column>
<!-- TODO @AI增加备注 -->
<el-table-column label="备注" align="center" prop="remark" min-width="180" />
<el-table-column
label="创建时间"
align="center"
@ -148,8 +133,7 @@
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import download from '@/utils/download'
import { DICT_TYPE } from '@/utils/dict'
import { WmWarehouseLocationApi } from '@/api/mes/wm/warehouse/location'
import { WmWarehouseAreaApi, WmWarehouseAreaVO } from '@/api/mes/wm/warehouse/area'
import AreaForm from './AreaForm.vue'
@ -158,7 +142,6 @@ defineOptions({ name: 'MesWmArea' })
const message = useMessage()
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const loading = ref(true)
@ -174,11 +157,11 @@ const queryParams = reactive({
code: undefined,
name: undefined,
locationId: undefined,
status: undefined,
frozen: undefined
positionX: undefined,
positionY: undefined,
positionZ: undefined
})
const queryFormRef = ref()
const exportLoading = ref(false)
const parseQueryId = (queryValue: string | string[] | null | undefined): number | undefined => {
const value = Array.isArray(queryValue) ? queryValue[0] : queryValue
@ -195,6 +178,7 @@ const loadLocationContext = async () => {
return
}
currentLocationId.value = locationId
// TODO @AIlinter
queryParams.locationId = locationId
try {
const location = await WmWarehouseLocationApi.getWarehouseLocation(locationId)
@ -231,18 +215,6 @@ const resetQuery = () => {
handleQuery()
}
/** 返回库区页面 */
const goBackToLocation = () => {
if (currentWarehouseId.value) {
router.push({
path: '/mes/wm/warehouse/location',
query: { warehouseId: String(currentWarehouseId.value) }
})
return
}
router.push('/mes/wm/warehouse/location')
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
@ -259,19 +231,7 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
await message.exportConfirm()
exportLoading.value = true
const data = await WmWarehouseAreaApi.exportWarehouseArea(queryParams)
download.excel(data, '库位.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 */
onMounted(async () => {
await loadLocationContext()
await getList()

View File

@ -25,18 +25,6 @@
class="!w-240px"
/>
</el-form-item>
<!-- TODO @AI可以起到这个筛选前端 + 后端 -->
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<!-- TODO @AI可以起到这个筛选前端 + 后端 -->
<el-form-item label="是否冻结" prop="frozen">
<el-select v-model="queryParams.frozen" placeholder="请选择" clearable class="!w-240px">
<el-option :value="true" label="是" />
@ -54,15 +42,6 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['mes:wm-warehouse:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
@ -73,16 +52,17 @@
<el-table-column label="仓库名称" align="center" prop="name" min-width="140" />
<el-table-column label="仓库地址" align="center" prop="address" min-width="150" />
<el-table-column label="面积(㎡)" align="center" prop="area" min-width="100" />
<!-- TODO @AI负责人 -->
<!-- TODO @AI可以使用字典翻译是否 -->
<el-table-column label="冻结" align="center" prop="frozen" min-width="80">
<el-table-column label="负责人" align="center" prop="chargeUserId" min-width="100">
<template #default="scope">
<el-tag :type="scope.row.frozen ? 'danger' : 'success'">{{
scope.row.frozen ? '是' : '否'
}}</el-tag>
{{ getChargeUserName(scope.row.chargeUserId) }}
</template>
</el-table-column>
<!-- TODO @AI备注的展示 -->
<el-table-column label="冻结" align="center" prop="frozen" min-width="80">
<template #default="scope">
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.frozen" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="180" />
<el-table-column
label="创建时间"
align="center"
@ -100,7 +80,6 @@
>
库区
</el-button>
<!-- TODO @芋艿标签打印 -->
<el-button
link
type="primary"
@ -133,9 +112,9 @@
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import download from '@/utils/download'
import { DICT_TYPE } from '@/utils/dict'
import { WmWarehouseApi, WmWarehouseVO } from '@/api/mes/wm/warehouse'
import * as UserApi from '@/api/system/user'
import WarehouseForm from './WarehouseForm.vue'
defineOptions({ name: 'MesWmWarehouse' })
@ -146,17 +125,29 @@ const router = useRouter()
const loading = ref(true)
const list = ref<WmWarehouseVO[]>([])
const userList = ref<UserApi.UserVO[]>([])
const total = ref(0)
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
name: undefined,
status: undefined,
frozen: undefined
})
const queryFormRef = ref()
const exportLoading = ref(false)
/** 加载用户列表 */
const loadUserList = async () => {
userList.value = await UserApi.getSimpleUserList()
}
// TODO @AIhtml
const getChargeUserName = (userId?: number) => {
if (!userId) {
return '-'
}
return userList.value.find((user) => user.id === userId)?.nickname || '-'
}
/** 查询列表 */
const getList = async () => {
@ -190,6 +181,7 @@ const openForm = (type: string, id?: number) => {
/** 打开库区页面 */
const openLocation = (warehouseId: number) => {
// TODO @AI使 name
router.push({
path: '/mes/wm/warehouse/location',
query: { warehouseId: String(warehouseId) }
@ -206,20 +198,8 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
await message.exportConfirm()
exportLoading.value = true
const data = await WmWarehouseApi.exportWarehouse(queryParams)
download.excel(data, '仓库.xls')
} catch {
} finally {
exportLoading.value = false
}
}
onMounted(() => {
getList()
/** 初始化 */
onMounted(async () => {
await Promise.all([loadUserList(), getList()])
})
</script>

View File

@ -9,7 +9,6 @@
>
<el-row>
<el-col :span="8">
<!-- TODO @AI生成参考别的界面 -->
<el-form-item label="库区编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入库区编码" />
</el-form-item>
@ -44,24 +43,6 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库位管理" prop="areaEnabled">
<el-switch v-model="formData.areaEnabled" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
@ -79,7 +60,7 @@
</el-row>
</el-form>
<template #footer>
<!-- TODO @AIbarcodeimg -->
<!-- TODO @芋艿barcodeimg -->
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
@ -87,8 +68,6 @@
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { WmWarehouseApi, WmWarehouseVO } from '@/api/mes/wm/warehouse'
import { WmWarehouseLocationApi, WmWarehouseLocationVO } from '@/api/mes/wm/warehouse/location'
@ -110,7 +89,6 @@ const formData = ref({
warehouseId: undefined,
area: undefined,
areaEnabled: true,
status: CommonStatusEnum.ENABLE,
frozen: false,
remark: undefined
})
@ -118,8 +96,6 @@ const formRules = reactive({
code: [{ required: true, message: '库区编码不能为空', trigger: 'blur' }],
name: [{ required: true, message: '库区名称不能为空', trigger: 'blur' }],
warehouseId: [{ required: true, message: '所属仓库不能为空', trigger: 'change' }],
areaEnabled: [{ required: true, message: '库位管理开关不能为空', trigger: 'change' }],
status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
frozen: [{ required: true, message: '是否冻结不能为空', trigger: 'change' }]
})
const formRef = ref()
@ -179,7 +155,6 @@ const resetForm = () => {
warehouseId: undefined,
area: undefined,
areaEnabled: true,
status: CommonStatusEnum.ENABLE,
frozen: false,
remark: undefined
}

View File

@ -1,8 +1,8 @@
<template>
<ContentWrap>
<el-alert
v-if="currentWarehouseId"
:title="`当前仓库:${currentWarehouseName || `#${currentWarehouseId}`}`"
v-if="currentWarehouse?.id"
:title="`当前仓库:${currentWarehouse.name || `#${currentWarehouse.id}`}`"
type="info"
show-icon
:closable="false"
@ -15,7 +15,6 @@
:inline="true"
label-width="68px"
>
<!-- TODO @AI只保留区域编码名称其它状态冻结都删除 -->
<el-form-item label="库区编码" prop="code">
<el-input
v-model="queryParams.code"
@ -34,28 +33,9 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="冻结" prop="frozen">
<el-select v-model="queryParams.frozen" placeholder="请选择" clearable class="!w-240px">
<el-option :value="true" label="是" />
<el-option :value="false" label="否" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button @click="goBackToWarehouse"
><Icon icon="ep:back" class="mr-5px" /> 返回仓库</el-button
>
<el-button
type="primary"
plain
@ -64,15 +44,6 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['mes:wm-warehouse:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
@ -82,29 +53,12 @@
<el-table-column label="库区编码" align="center" prop="code" min-width="120" />
<el-table-column label="库区名称" align="center" prop="name" min-width="140" />
<el-table-column label="面积(㎡)" align="center" prop="area" min-width="100" />
<!-- TODO @AI去掉库位管理状态字段 -->
<el-table-column label="库位管理" align="center" prop="areaEnabled" min-width="90">
<template #default="scope">
<el-tag :type="scope.row.areaEnabled ? 'success' : 'info'">{{
scope.row.areaEnabled ? '启用' : '关闭'
}}</el-tag>
</template>
</el-table-column>
<!-- TODO @AI删除状态字段前端+后端数据库 -->
<el-table-column label="状态" align="center" prop="status" min-width="90">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<!-- TODO @AI使用字典渲染 -->
<el-table-column label="冻结" align="center" prop="frozen" min-width="80">
<template #default="scope">
<el-tag :type="scope.row.frozen ? 'danger' : 'success'">{{
scope.row.frozen ? '是' : '否'
}}</el-tag>
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.frozen" />
</template>
</el-table-column>
<!-- TODO @AI增加备注 -->
<el-table-column label="备注" align="center" prop="remark" min-width="180" />
<el-table-column
label="创建时间"
align="center"
@ -122,7 +76,6 @@
>
库位
</el-button>
<!-- TODO @芋艿标签打印 -->
<el-button
link
type="primary"
@ -155,8 +108,7 @@
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import download from '@/utils/download'
import { DICT_TYPE } from '@/utils/dict'
import { WmWarehouseApi } from '@/api/mes/wm/warehouse'
import { WmWarehouseLocationApi, WmWarehouseLocationVO } from '@/api/mes/wm/warehouse/location'
import LocationForm from './LocationForm.vue'
@ -171,42 +123,28 @@ const route = useRoute()
const loading = ref(true)
const list = ref<WmWarehouseLocationVO[]>([])
const total = ref(0)
const currentWarehouseId = ref<number | undefined>(undefined)
// TODO @AI currentWarehouse
const currentWarehouseName = ref('')
const currentWarehouse = ref<{ id: number; name: string }>({
id: 0,
name: ''
})
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
name: undefined,
warehouseId: undefined,
status: undefined,
frozen: undefined
warehouseId: undefined
})
const queryFormRef = ref()
const exportLoading = ref(false)
// TODO @AI number
const parseQueryId = (queryValue: string | string[] | null | undefined): number | undefined => {
const value = Array.isArray(queryValue) ? queryValue[0] : queryValue
if (!value) {
return undefined
}
const id = Number(value)
return Number.isInteger(id) && id > 0 ? id : undefined
}
// TODO @AI
const loadWarehouseContext = async () => {
const warehouseId = parseQueryId(route.query.warehouseId as string | string[] | undefined)
if (!warehouseId) {
const warehouseId = Number(route.query.warehouseId)
if (!Number.isInteger(warehouseId) || warehouseId <= 0) {
return
}
currentWarehouseId.value = warehouseId
currentWarehouse.value.id = warehouseId
queryParams.warehouseId = warehouseId
try {
const warehouse = await WmWarehouseApi.getWarehouse(warehouseId)
currentWarehouseName.value = warehouse.name
currentWarehouse.value.name = warehouse.name || ''
} catch {
//
}
@ -233,15 +171,10 @@ const handleQuery = () => {
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
queryParams.warehouseId = currentWarehouseId.value
queryParams.warehouseId = currentWarehouse.value.id || undefined
handleQuery()
}
/** 返回仓库页面 */
const goBackToWarehouse = () => {
router.push('/mes/wm/warehouse')
}
/** 打开库位页面 */
const openArea = (locationId: number) => {
router.push({
@ -253,7 +186,7 @@ const openArea = (locationId: number) => {
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id, currentWarehouseId.value)
formRef.value.open(type, id, currentWarehouse.value.id || undefined)
}
/** 删除按钮操作 */
@ -266,19 +199,7 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
await message.exportConfirm()
exportLoading.value = true
const data = await WmWarehouseLocationApi.exportWarehouseLocation(queryParams)
download.excel(data, '库区.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 */
onMounted(async () => {
await loadWarehouseContext()
await getList()