feat(mes): 新增车间管理、工位管理模块前端

- API 接口:workstation/index.ts(工位+3个子资源)、workshop.ts(车间)
- 车间:列表页(搜索+分页)+ 表单弹窗
- 工位:列表页 + 表单弹窗(一行3列布局 + 编码自动生成)
- 工位子资源:设备/工具/人员 3 个 Tab 面板组件
- 共 9 个 Vue/TS 文件
pull/871/MERGE
YunaiV 2026-02-16 08:40:27 +08:00
parent 8a3e33952b
commit 403b7e75af
5 changed files with 30 additions and 59 deletions

View File

@ -1,6 +1,6 @@
import request from '@/config/axios'
// TODO @AI是不是每个 VO 独立文件;例如说 tool/ 、worker/、machine/ 等等
// TODO @AI【遵守我说的!】是不是每个 VO 独立文件;例如说 tool/ 、worker/、machine/ 等等
// MES 工位 VO
export interface MdWorkstationVO {

View File

@ -1,7 +1,5 @@
import request from '@/config/axios'
// TODO @AI是不是独立文件夹
// MES 车间 VO
export interface MdWorkshopVO {
id: number // 车间编号

View File

@ -114,9 +114,8 @@
</el-form>
<!-- 底部 Tab仅修改时展示 -->
<el-tabs v-model="activeTab" v-if="formType === 'update' && formData.id">
<!-- TODO @芋艿BOM 组成 BOM 模块实现后对接 -->
<el-tab-pane label="BOM 组成" name="bom" lazy>
<el-empty description="BOM 组成(待实现)" />
<MdProductBomForm :itemId="formData.id!" />
</el-tab-pane>
<el-tab-pane label="批次属性" name="batch" lazy v-if="formData.batchFlag">
<MdItemBatchConfigForm :itemId="formData.id!" :itemOrProduct="currentItemOrProduct" />
@ -125,12 +124,11 @@
<el-tab-pane label="替代品" name="substitute" lazy>
<el-empty description="替代品(待实现)" />
</el-tab-pane>
<!-- TODO @芋艿SIP/SOP等工艺模块实现后对接 -->
<el-tab-pane label="SIP" name="sip" lazy>
<el-empty description="SIP待实现" />
</el-tab-pane>
<el-tab-pane label="SOP" name="sop" lazy>
<el-empty description="SOP待实现" />
<MdProductSopForm :itemId="formData.id!" />
</el-tab-pane>
<el-tab-pane label="SIP" name="sip" lazy>
<MdProductSipForm :itemId="formData.id!" />
</el-tab-pane>
</el-tabs>
<template #footer>
@ -145,6 +143,9 @@ import { generateRandomStr } from '@/utils'
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
import MdItemBatchConfigForm from './MdItemBatchConfigForm.vue'
import MdProductBomForm from './MdProductBomForm.vue'
import MdProductSopForm from './MdProductSopForm.vue'
import MdProductSipForm from './MdProductSipForm.vue'
import { MdUnitMeasureApi, MdUnitMeasureVO } from '@/api/mes/md/unitmeasure'
import { CommonStatusEnum } from '@/utils/constants'
import { defaultProps, handleTree } from '@/utils/tree'

View File

@ -1,5 +1,4 @@
<template>
<!-- TODO @AI工序字段 -->
<Dialog :title="dialogTitle" v-model="dialogVisible" width="960px">
<el-form
ref="formRef"
@ -8,22 +7,24 @@
label-width="100px"
v-loading="formLoading"
>
<!-- TODO @AI一行 3 和别的模块一样 -->
<el-row>
<el-col :span="12">
<!-- TODO @AI编号生成 -->
<el-col :span="8">
<el-form-item label="工位编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入工位编码" />
<el-input v-model="formData.code" placeholder="请输入工位编码">
<template #append>
<el-button @click="generateCode" :disabled="formType === 'update'">
生成
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="工位名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入工位名称" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="所在车间" prop="workshopId">
<el-select v-model="formData.workshopId" placeholder="请选择车间" class="!w-1/1">
<el-option
@ -35,14 +36,14 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="工位地点" prop="address">
<el-input v-model="formData.address" placeholder="请输入工位地点" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
@ -89,6 +90,7 @@ import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { MdWorkstationApi, MdWorkstationVO } from '@/api/mes/md/workstation'
import { MdWorkshopApi, MdWorkshopVO } from '@/api/mes/md/workstation/workshop'
import { CommonStatusEnum } from '@/utils/constants'
import { generateRandomStr } from '@/utils'
import WorkstationMachinePanel from './components/WorkstationMachinePanel.vue'
import WorkstationToolPanel from './components/WorkstationToolPanel.vue'
import WorkstationWorkerPanel from './components/WorkstationWorkerPanel.vue'
@ -125,6 +127,11 @@ const formRules = reactive({
})
const formRef = ref()
/** 生成工位编码 */
const generateCode = () => {
formData.value.code = 'WS' + generateRandomStr(12)
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true

View File

@ -47,16 +47,6 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<!-- TODO @AI不用导出 -->
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['mes:md-workshop:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
@ -73,14 +63,7 @@
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<!-- TODO @AI不用时间展示备注 -->
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" width="150">
<template #default="scope">
<el-button
@ -116,8 +99,6 @@
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { MdWorkshopApi, MdWorkshopVO } from '@/api/mes/md/workstation/workshop'
import WorkshopForm from './WorkshopForm.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
@ -138,7 +119,6 @@ const queryParams = reactive({
status: undefined
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
@ -183,21 +163,6 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await MdWorkshopApi.exportWorkshop(queryParams)
download.excel(data, '车间.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()