feat(mes): 提交 wm outsource 相关的迁移(代码优化)
parent
b6d1154b8f
commit
79af870afe
|
|
@ -42,3 +42,38 @@ export function getCardPage(params: MesProCardApi.PageParams) {
|
||||||
export function getCard(id: number) {
|
export function getCard(id: number) {
|
||||||
return requestClient.get<MesProCardApi.Card>(`/mes/pro/card/get?id=${id}`);
|
return requestClient.get<MesProCardApi.Card>(`/mes/pro/card/get?id=${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 新增生产流转卡 */
|
||||||
|
export function createCard(data: MesProCardApi.Card) {
|
||||||
|
return requestClient.post<number>('/mes/pro/card/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改生产流转卡 */
|
||||||
|
export function updateCard(data: MesProCardApi.Card) {
|
||||||
|
return requestClient.put('/mes/pro/card/update', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除生产流转卡 */
|
||||||
|
export function deleteCard(id: number) {
|
||||||
|
return requestClient.delete(`/mes/pro/card/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出生产流转卡 */
|
||||||
|
export function exportCard(params: any) {
|
||||||
|
return requestClient.download('/mes/pro/card/export-excel', { params });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 提交生产流转卡 */
|
||||||
|
export function submitCard(id: number) {
|
||||||
|
return requestClient.put(`/mes/pro/card/submit?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 完成生产流转卡 */
|
||||||
|
export function finishCard(id: number) {
|
||||||
|
return requestClient.put(`/mes/pro/card/finish?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 取消生产流转卡 */
|
||||||
|
export function cancelCard(id: number) {
|
||||||
|
return requestClient.put(`/mes/pro/card/cancel?id=${id}`);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
export namespace MesProCardProcessApi {
|
||||||
|
/** MES 流转卡工序记录 */
|
||||||
|
export interface CardProcess {
|
||||||
|
id?: number; // 编号
|
||||||
|
cardId?: number; // 流转卡编号
|
||||||
|
sort?: number; // 序号
|
||||||
|
processId?: number; // 工序编号
|
||||||
|
processCode?: string; // 工序编码
|
||||||
|
processName?: string; // 工序名称
|
||||||
|
inputTime?: number; // 进入工序时间
|
||||||
|
outputTime?: number; // 出工序时间
|
||||||
|
inputQuantity?: number; // 投入数量
|
||||||
|
outputQuantity?: number; // 产出数量
|
||||||
|
unqualifiedQuantity?: number; // 不合格品数量
|
||||||
|
workstationId?: number; // 工位编号
|
||||||
|
workstationCode?: string; // 工位编码
|
||||||
|
workstationName?: string; // 工位名称
|
||||||
|
userId?: number; // 操作人编号
|
||||||
|
nickname?: string; // 操作人名称
|
||||||
|
ipqcId?: number; // 过程检验单编号
|
||||||
|
remark?: string; // 备注
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MES 流转卡工序记录分页查询参数 */
|
||||||
|
export interface PageParams extends PageParam {
|
||||||
|
cardId?: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询流转卡工序记录分页 */
|
||||||
|
export function getCardProcessPage(params: MesProCardProcessApi.PageParams) {
|
||||||
|
return requestClient.get<PageResult<MesProCardProcessApi.CardProcess>>(
|
||||||
|
'/mes/pro/card-process/page',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询流转卡工序记录详情 */
|
||||||
|
export function getCardProcess(id: number) {
|
||||||
|
return requestClient.get<MesProCardProcessApi.CardProcess>(
|
||||||
|
`/mes/pro/card-process/get?id=${id}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增流转卡工序记录 */
|
||||||
|
export function createCardProcess(data: MesProCardProcessApi.CardProcess) {
|
||||||
|
return requestClient.post('/mes/pro/card-process/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改流转卡工序记录 */
|
||||||
|
export function updateCardProcess(data: MesProCardProcessApi.CardProcess) {
|
||||||
|
return requestClient.put('/mes/pro/card-process/update', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除流转卡工序记录 */
|
||||||
|
export function deleteCardProcess(id: number) {
|
||||||
|
return requestClient.delete(`/mes/pro/card-process/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
@ -48,6 +48,8 @@ export namespace MesProTaskApi {
|
||||||
name?: string;
|
name?: string;
|
||||||
workOrderId?: number;
|
workOrderId?: number;
|
||||||
workstationId?: number;
|
workstationId?: number;
|
||||||
|
routeId?: number;
|
||||||
|
processId?: number;
|
||||||
itemId?: number;
|
itemId?: number;
|
||||||
statuses?: number[];
|
statuses?: number[];
|
||||||
status?: number;
|
status?: number;
|
||||||
|
|
@ -66,3 +68,28 @@ export function getTaskPage(params: MesProTaskApi.PageParams) {
|
||||||
export function getTask(id: number) {
|
export function getTask(id: number) {
|
||||||
return requestClient.get<MesProTaskApi.Task>(`/mes/pro/task/get?id=${id}`);
|
return requestClient.get<MesProTaskApi.Task>(`/mes/pro/task/get?id=${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 新增生产任务 */
|
||||||
|
export function createTask(data: MesProTaskApi.Task) {
|
||||||
|
return requestClient.post('/mes/pro/task/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改生产任务 */
|
||||||
|
export function updateTask(data: MesProTaskApi.Task) {
|
||||||
|
return requestClient.put('/mes/pro/task/update', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除生产任务 */
|
||||||
|
export function deleteTask(id: number) {
|
||||||
|
return requestClient.delete(`/mes/pro/task/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出生产任务 */
|
||||||
|
export function exportTask(params: any) {
|
||||||
|
return requestClient.download('/mes/pro/task/export-excel', { params });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询甘特图任务列表(非分页) */
|
||||||
|
export function getGanttTaskList(params: any) {
|
||||||
|
return requestClient.get<any[]>('/mes/pro/task/gantt-list', { params });
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
|
||||||
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
|
export namespace MesProWorkOrderBomApi {
|
||||||
|
/** MES 生产工单 BOM */
|
||||||
|
export interface WorkOrderBom {
|
||||||
|
id?: number; // 编号
|
||||||
|
workOrderId?: number; // 生产工单编号
|
||||||
|
itemId?: number; // BOM 物料编号
|
||||||
|
itemName?: string; // 物料名称
|
||||||
|
itemCode?: string; // 物料编码
|
||||||
|
itemSpecification?: string; // 规格型号
|
||||||
|
unitMeasureId?: number; // 单位编号
|
||||||
|
unitMeasureName?: string; // 单位名称
|
||||||
|
quantity?: number; // 预计使用量
|
||||||
|
remark?: string; // 备注
|
||||||
|
itemOrProduct?: string; // 物料产品标识
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MES 生产工单 BOM 分页查询参数 */
|
||||||
|
export interface PageParams extends PageParam {
|
||||||
|
workOrderId?: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询工单 BOM 分页 */
|
||||||
|
export function getWorkOrderBomPage(params: MesProWorkOrderBomApi.PageParams) {
|
||||||
|
return requestClient.get<PageResult<MesProWorkOrderBomApi.WorkOrderBom>>(
|
||||||
|
'/mes/pro/work-order-bom/page',
|
||||||
|
{ params },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询工单 BOM 详情 */
|
||||||
|
export function getWorkOrderBom(id: number) {
|
||||||
|
return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom>(
|
||||||
|
`/mes/pro/work-order-bom/get?id=${id}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增工单 BOM */
|
||||||
|
export function createWorkOrderBom(data: MesProWorkOrderBomApi.WorkOrderBom) {
|
||||||
|
return requestClient.post('/mes/pro/work-order-bom/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改工单 BOM */
|
||||||
|
export function updateWorkOrderBom(data: MesProWorkOrderBomApi.WorkOrderBom) {
|
||||||
|
return requestClient.put('/mes/pro/work-order-bom/update', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除工单 BOM */
|
||||||
|
export function deleteWorkOrderBom(id: number) {
|
||||||
|
return requestClient.delete(`/mes/pro/work-order-bom/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询工单物料需求列表 */
|
||||||
|
export function getWorkOrderBomItemListByWorkOrderId(workOrderId: number) {
|
||||||
|
return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom[]>(
|
||||||
|
`/mes/pro/work-order-bom/item-list-by-work-order-id?workOrderId=${workOrderId}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -5,37 +5,48 @@ import { requestClient } from '#/api/request';
|
||||||
export namespace MesProWorkOrderApi {
|
export namespace MesProWorkOrderApi {
|
||||||
/** MES 生产工单 */
|
/** MES 生产工单 */
|
||||||
export interface WorkOrder {
|
export interface WorkOrder {
|
||||||
id?: number;
|
id?: number; // 编号
|
||||||
code?: string; // 工单编码
|
code?: string; // 工单编码
|
||||||
name?: string; // 工单名称
|
name?: string; // 工单名称
|
||||||
type?: number; // 工单类型
|
type?: number; // 工单类型
|
||||||
status?: number; // 工单状态
|
orderSourceType?: number; // 来源类型
|
||||||
sourceType?: number;
|
orderSourceCode?: string; // 来源单据编号
|
||||||
productId?: number; // 产品物料编号
|
productId?: number; // 产品编号
|
||||||
productCode?: string;
|
productName?: string; // 产品名称
|
||||||
productName?: string;
|
productCode?: string; // 产品编码
|
||||||
productSpecification?: string;
|
productSpecification?: string; // 规格型号
|
||||||
quantity?: number;
|
unitMeasureName?: string; // 单位名称
|
||||||
unitName?: string;
|
quantity?: number; // 生产数量
|
||||||
routeId?: number;
|
quantityProduced?: number; // 已生产数量
|
||||||
routeName?: string;
|
quantityChanged?: number; // 调整数量
|
||||||
clientId?: number;
|
quantityScheduled?: number; // 已排产数量
|
||||||
clientName?: string;
|
clientId?: number; // 客户编号
|
||||||
|
clientCode?: string; // 客户编码
|
||||||
|
clientName?: string; // 客户名称
|
||||||
vendorId?: number; // 供应商编号
|
vendorId?: number; // 供应商编号
|
||||||
vendorName?: string; // 供应商名称
|
vendorName?: string; // 供应商名称
|
||||||
planStartTime?: number | string;
|
vendorCode?: string; // 供应商编码
|
||||||
planEndTime?: number | string;
|
batchCode?: string; // 批次号
|
||||||
actualStartTime?: number | string;
|
requestDate?: number; // 需求日期
|
||||||
actualEndTime?: number | string;
|
parentId?: number; // 父工单编号
|
||||||
remark?: string;
|
parentCode?: string; // 父工单编码
|
||||||
createTime?: number | string;
|
finishDate?: number; // 完成时间
|
||||||
|
cancelDate?: number; // 取消时间
|
||||||
|
status?: number; // 工单状态
|
||||||
|
remark?: string; // 备注
|
||||||
|
createTime?: number; // 创建时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** MES 生产工单分页查询参数 */
|
||||||
export interface PageParams extends PageParam {
|
export interface PageParams extends PageParam {
|
||||||
code?: string;
|
code?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
orderSourceCode?: string;
|
||||||
|
productId?: number;
|
||||||
|
clientId?: number;
|
||||||
status?: number;
|
status?: number;
|
||||||
type?: number;
|
type?: number;
|
||||||
|
requestDate?: number[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,3 +64,38 @@ export function getWorkOrder(id: number) {
|
||||||
`/mes/pro/work-order/get?id=${id}`,
|
`/mes/pro/work-order/get?id=${id}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 新增生产工单 */
|
||||||
|
export function createWorkOrder(data: MesProWorkOrderApi.WorkOrder) {
|
||||||
|
return requestClient.post<number>('/mes/pro/work-order/create', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改生产工单 */
|
||||||
|
export function updateWorkOrder(data: MesProWorkOrderApi.WorkOrder) {
|
||||||
|
return requestClient.put('/mes/pro/work-order/update', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除生产工单 */
|
||||||
|
export function deleteWorkOrder(id: number) {
|
||||||
|
return requestClient.delete(`/mes/pro/work-order/delete?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出生产工单 */
|
||||||
|
export function exportWorkOrder(params: any) {
|
||||||
|
return requestClient.download('/mes/pro/work-order/export-excel', { params });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 完成工单 */
|
||||||
|
export function finishWorkOrder(id: number) {
|
||||||
|
return requestClient.put(`/mes/pro/work-order/finish?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 取消工单 */
|
||||||
|
export function cancelWorkOrder(id: number) {
|
||||||
|
return requestClient.put(`/mes/pro/work-order/cancel?id=${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 确认工单 */
|
||||||
|
export function confirmWorkOrder(id: number) {
|
||||||
|
return requestClient.put(`/mes/pro/work-order/confirm?id=${id}`);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export namespace MesWmOutsourceReceiptLineApi {
|
||||||
expireDate?: number; // 有效期
|
expireDate?: number; // 有效期
|
||||||
lotNumber?: string; // 生产批号
|
lotNumber?: string; // 生产批号
|
||||||
iqcCheckFlag?: boolean; // 是否需要质检
|
iqcCheckFlag?: boolean; // 是否需要质检
|
||||||
|
qualityStatus?: number; // 质量状态
|
||||||
remark?: string; // 备注
|
remark?: string; // 备注
|
||||||
createTime?: Date; // 创建时间
|
createTime?: Date; // 创建时间
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,15 @@ const routes: RouteRecordRaw[] = [
|
||||||
},
|
},
|
||||||
component: () => import('#/views/mes/wm/barcode/config/index.vue'),
|
component: () => import('#/views/mes/wm/barcode/config/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'pro/task/edit',
|
||||||
|
name: 'MesProTaskGanttEdit',
|
||||||
|
meta: {
|
||||||
|
title: '甘特图编辑',
|
||||||
|
activePath: '/mes/pro/task',
|
||||||
|
},
|
||||||
|
component: () => import('#/views/mes/pro/task/edit/index.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,12 @@ export const MesProWorkOrderTypeEnum = {
|
||||||
PURCHASE: 3, // 采购
|
PURCHASE: 3, // 采购
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
/** MES 工单来源类型枚举 */
|
||||||
|
export const MesProWorkOrderSourceTypeEnum = {
|
||||||
|
ORDER: 1, // 客户订单
|
||||||
|
STORE: 2, // 库存备货
|
||||||
|
} as const;
|
||||||
|
|
||||||
/** MES 生产任务状态枚举 */
|
/** MES 生产任务状态枚举 */
|
||||||
export const MesProTaskStatusEnum = {
|
export const MesProTaskStatusEnum = {
|
||||||
PREPARE: MesOrderStatusConstants.DRAFT,
|
PREPARE: MesOrderStatusConstants.DRAFT,
|
||||||
|
|
|
||||||
|
|
@ -38,25 +38,19 @@ const canSubmit = computed(() => // 是否可提交
|
||||||
formType.value === 'update' &&
|
formType.value === 'update' &&
|
||||||
formData.value?.status === MesWmOutsourceIssueStatusEnum.PREPARE,
|
formData.value?.status === MesWmOutsourceIssueStatusEnum.PREPARE,
|
||||||
);
|
);
|
||||||
// TODO @AI:标题的代码风格;
|
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['外协发料单']);
|
||||||
return $t('ui.actionTitle.view', ['外协发料单']);
|
|
||||||
}
|
|
||||||
case 'finish': {
|
|
||||||
return '执行领出';
|
|
||||||
}
|
|
||||||
case 'stock': {
|
|
||||||
return '执行拣货';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['外协发料单']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['外协发料单']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'stock') {
|
||||||
|
return '执行拣货';
|
||||||
|
}
|
||||||
|
if (formType.value === 'finish') {
|
||||||
|
return '执行领出';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['外协发料单'])
|
||||||
|
: $t('ui.actionTitle.create', ['外协发料单']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
@ -138,7 +132,6 @@ async function handleFinish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
// TODO @AI:方法注释,缺少“// 关闭并提示”;看看其他 form.vue 或者 xxx-form.vue 有没类似的情况;
|
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
if (!isEditable.value) {
|
if (!isEditable.value) {
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,9 @@ const props = defineProps<{
|
||||||
issueId: number;
|
issueId: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// TODO @AI:// 是否可编辑明细行 拿到 “computed(() =>”;
|
const isEditable = computed(() => // 是否可编辑明细行
|
||||||
const isEditable = computed(() =>
|
|
||||||
['create', 'update'].includes(props.formType),
|
['create', 'update'].includes(props.formType),
|
||||||
); // 是否可编辑明细行
|
);
|
||||||
const isStock = computed(() => props.formType === 'stock'); // 是否为拣货模式
|
const isStock = computed(() => props.formType === 'stock'); // 是否为拣货模式
|
||||||
const detailMap = reactive<
|
const detailMap = reactive<
|
||||||
Record<number, MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]>
|
Record<number, MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]>
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,9 @@ const emit = defineEmits<{
|
||||||
refresh: [];
|
refresh: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// TODO @AI:放到 “// 是否可维护收货明细(编辑或上架态)” 到 computed( 后面
|
const isEditable = computed(() => // 是否可维护收货明细(编辑或上架态)
|
||||||
const isEditable = computed(
|
['create', 'stock', 'update'].includes(props.formType),
|
||||||
() => ['create', 'stock', 'update'].includes(props.formType),
|
);
|
||||||
); // 是否可维护收货明细(编辑或上架态)
|
|
||||||
|
|
||||||
/** 添加收货明细 */
|
/** 添加收货明细 */
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
|
|
|
||||||
|
|
@ -37,25 +37,19 @@ const canSubmit = computed(() => // 是否可提交
|
||||||
formType.value === 'update' &&
|
formType.value === 'update' &&
|
||||||
formData.value?.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
|
formData.value?.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
|
||||||
);
|
);
|
||||||
// TODO @AI:方法的代码风格;
|
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['外协入库单']);
|
||||||
return $t('ui.actionTitle.view', ['外协入库单']);
|
|
||||||
}
|
|
||||||
case 'finish': {
|
|
||||||
return '完成入库';
|
|
||||||
}
|
|
||||||
case 'stock': {
|
|
||||||
return '执行上架';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['外协入库单']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['外协入库单']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'stock') {
|
||||||
|
return '执行上架';
|
||||||
|
}
|
||||||
|
if (formType.value === 'finish') {
|
||||||
|
return '完成入库';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['外协入库单'])
|
||||||
|
: $t('ui.actionTitle.create', ['外协入库单']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ const emit = defineEmits(['success']);
|
||||||
const formData = ref<MesWmOutsourceReceiptLineApi.OutsourceReceiptLine>();
|
const formData = ref<MesWmOutsourceReceiptLineApi.OutsourceReceiptLine>();
|
||||||
const receiptId = ref<number>(); // 所属入库单编号
|
const receiptId = ref<number>(); // 所属入库单编号
|
||||||
|
|
||||||
// TODO @AI:如果 getTitle 方法的前面,也是 const 变量,不用空行?是不是更符合项目规范?如果是,写到 style vue 文件里;
|
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
return formData.value?.id
|
return formData.value?.id
|
||||||
? $t('ui.actionTitle.edit', ['外协入库单行'])
|
? $t('ui.actionTitle.edit', ['外协入库单行'])
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ const props = defineProps<{
|
||||||
receiptId: number;
|
receiptId: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isEditable = computed(() =>
|
const isEditable = computed(() => // 是否可编辑明细行
|
||||||
['create', 'update'].includes(props.formType),
|
['create', 'update'].includes(props.formType),
|
||||||
); // 是否可编辑明细行
|
);
|
||||||
const isStock = computed(() => props.formType === 'stock'); // 是否为上架模式
|
const isStock = computed(() => props.formType === 'stock'); // 是否为上架模式
|
||||||
const detailMap = reactive<
|
const detailMap = reactive<
|
||||||
Record<number, MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail[]>
|
Record<number, MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail[]>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { MesWmStockTakingPlanParamApi } from '#/api/mes/wm/stocktaking/plan/param';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
import {
|
||||||
|
deleteStockTakingPlanParam,
|
||||||
|
getStockTakingPlanParamPage,
|
||||||
|
} from '#/api/mes/wm/stocktaking/plan/param';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
|
import { useParamGridColumns } from '../data';
|
||||||
|
import ParamForm from './param-form.vue';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
disabled: boolean; // 是否只读(详情态)
|
||||||
|
planId: number; // 所属方案编号
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const [ParamFormModal, paramFormModalApi] = useVbenModal({
|
||||||
|
connectedComponent: ParamForm,
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 刷新表格 */
|
||||||
|
function handleRefresh() {
|
||||||
|
gridApi.query();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加条件 */
|
||||||
|
function handleCreate() {
|
||||||
|
paramFormModalApi.setData({ planId: props.planId }).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 编辑条件 */
|
||||||
|
function handleEdit(row: MesWmStockTakingPlanParamApi.StockTakingPlanParam) {
|
||||||
|
paramFormModalApi.setData({ id: row.id, planId: props.planId }).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除条件 */
|
||||||
|
async function handleDelete(
|
||||||
|
row: MesWmStockTakingPlanParamApi.StockTakingPlanParam,
|
||||||
|
) {
|
||||||
|
const hideLoading = message.loading({
|
||||||
|
content: $t('ui.actionMessage.deleting', [row.valueName]),
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
await deleteStockTakingPlanParam(row.id!);
|
||||||
|
message.success($t('ui.actionMessage.deleteSuccess', [row.valueName]));
|
||||||
|
handleRefresh();
|
||||||
|
} finally {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
|
gridOptions: {
|
||||||
|
columns: useParamGridColumns(!props.disabled),
|
||||||
|
height: 320,
|
||||||
|
keepSource: true,
|
||||||
|
proxyConfig: {
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }) => {
|
||||||
|
if (!props.planId) {
|
||||||
|
return { list: [], total: 0 };
|
||||||
|
}
|
||||||
|
return await getStockTakingPlanParamPage({
|
||||||
|
pageNo: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
planId: props.planId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rowConfig: {
|
||||||
|
keyField: 'id',
|
||||||
|
isHover: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
refresh: true,
|
||||||
|
},
|
||||||
|
} as VxeTableGridOptions<MesWmStockTakingPlanParamApi.StockTakingPlanParam>,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ParamFormModal @success="handleRefresh" />
|
||||||
|
<Grid table-title="盘点参数">
|
||||||
|
<template v-if="!disabled" #toolbar-tools>
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
label: '添加条件',
|
||||||
|
type: 'primary',
|
||||||
|
icon: ACTION_ICON.ADD,
|
||||||
|
onClick: handleCreate,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #actions="{ row }">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{
|
||||||
|
label: $t('common.edit'),
|
||||||
|
type: 'link',
|
||||||
|
icon: ACTION_ICON.EDIT,
|
||||||
|
onClick: handleEdit.bind(null, row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: $t('common.delete'),
|
||||||
|
type: 'link',
|
||||||
|
danger: true,
|
||||||
|
icon: ACTION_ICON.DELETE,
|
||||||
|
popConfirm: {
|
||||||
|
title: $t('ui.actionMessage.deleteConfirm', [row.valueName]),
|
||||||
|
confirm: handleDelete.bind(null, row),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -19,6 +19,7 @@ export namespace MesWmOutsourceReceiptLineApi {
|
||||||
expireDate?: number; // 有效期
|
expireDate?: number; // 有效期
|
||||||
lotNumber?: string; // 生产批号
|
lotNumber?: string; // 生产批号
|
||||||
iqcCheckFlag?: boolean; // 是否需要质检
|
iqcCheckFlag?: boolean; // 是否需要质检
|
||||||
|
qualityStatus?: number; // 质量状态
|
||||||
remark?: string; // 备注
|
remark?: string; // 备注
|
||||||
createTime?: Date; // 创建时间
|
createTime?: Date; // 创建时间
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,431 @@
|
||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { MesProCardApi } from '#/api/mes/pro/card';
|
import type { MesProCardApi } from '#/api/mes/pro/card';
|
||||||
|
import type { MesProCardProcessApi } from '#/api/mes/pro/card/process';
|
||||||
|
|
||||||
import { markRaw } from 'vue';
|
import { h, markRaw } from 'vue';
|
||||||
|
|
||||||
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
|
|
||||||
|
import { ElButton } from 'element-plus';
|
||||||
|
|
||||||
|
import { generateAutoCode } from '#/api/mes/md/autocode/record';
|
||||||
import { MdItemSelect } from '#/views/mes/md/item/components';
|
import { MdItemSelect } from '#/views/mes/md/item/components';
|
||||||
|
import { MdWorkstationSelect } from '#/views/mes/md/workstation/components';
|
||||||
|
import { ProProcessSelect } from '#/views/mes/pro/process/components';
|
||||||
import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
|
import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
|
||||||
|
import {
|
||||||
|
MesAutoCodeRuleCode,
|
||||||
|
MesProWorkOrderStatusEnum,
|
||||||
|
} from '#/views/mes/utils/constants';
|
||||||
|
import { UserSelect } from '#/views/system/user/components';
|
||||||
|
|
||||||
|
/** 表单类型 */
|
||||||
|
export type FormType = 'create' | 'detail' | 'finish' | 'update';
|
||||||
|
|
||||||
|
/** 表头是否只读(完成、详情态) */
|
||||||
|
function isHeaderReadonly(formType: FormType): boolean {
|
||||||
|
return formType === 'detail' || formType === 'finish';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增/修改的表单 */
|
||||||
|
export function useFormSchema(
|
||||||
|
formType: FormType,
|
||||||
|
formApi?: VbenFormApi,
|
||||||
|
): VbenFormSchema[] {
|
||||||
|
const headerReadonly = isHeaderReadonly(formType);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'id',
|
||||||
|
component: 'Input',
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: [''],
|
||||||
|
show: () => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'status',
|
||||||
|
component: 'Input',
|
||||||
|
dependencies: {
|
||||||
|
triggerFields: [''],
|
||||||
|
show: () => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'code',
|
||||||
|
label: '流转卡编码',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
disabled: headerReadonly,
|
||||||
|
placeholder: '请输入流转卡编码',
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
suffix:
|
||||||
|
formType === 'create' || formType === 'update'
|
||||||
|
? () =>
|
||||||
|
h(
|
||||||
|
ElButton,
|
||||||
|
{
|
||||||
|
onClick: async () => {
|
||||||
|
const code = await generateAutoCode(
|
||||||
|
MesAutoCodeRuleCode.PRO_CARD_CODE,
|
||||||
|
);
|
||||||
|
await formApi?.setFieldValue('code', code);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ default: () => '生成' },
|
||||||
|
)
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'workOrderId',
|
||||||
|
label: '生产工单',
|
||||||
|
component: markRaw(ProWorkOrderSelect),
|
||||||
|
componentProps: {
|
||||||
|
disabled: headerReadonly,
|
||||||
|
placeholder: '请选择生产工单',
|
||||||
|
status: MesProWorkOrderStatusEnum.CONFIRMED,
|
||||||
|
},
|
||||||
|
rules: 'selectRequired',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'itemId',
|
||||||
|
label: '产品',
|
||||||
|
component: markRaw(MdItemSelect),
|
||||||
|
componentProps: {
|
||||||
|
disabled: headerReadonly,
|
||||||
|
placeholder: '请选择产品',
|
||||||
|
},
|
||||||
|
rules: 'selectRequired',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'transferedQuantity',
|
||||||
|
label: '流转数量',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
disabled: headerReadonly,
|
||||||
|
min: 0,
|
||||||
|
placeholder: '请输入流转数量',
|
||||||
|
precision: 2,
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'batchCode',
|
||||||
|
label: '批次号',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
disabled: headerReadonly,
|
||||||
|
placeholder: '请输入批次号',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
component: 'Textarea',
|
||||||
|
formItemClass: 'col-span-3',
|
||||||
|
componentProps: {
|
||||||
|
disabled: headerReadonly,
|
||||||
|
placeholder: '请输入备注',
|
||||||
|
rows: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表的搜索表单 */
|
||||||
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'code',
|
||||||
|
label: '流转卡编码',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '请输入流转卡编码',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'workOrderId',
|
||||||
|
label: '生产工单',
|
||||||
|
component: markRaw(ProWorkOrderSelect),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择生产工单',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'itemId',
|
||||||
|
label: '产品',
|
||||||
|
component: markRaw(MdItemSelect),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择产品',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'batchCode',
|
||||||
|
label: '批次号',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
clearable: true,
|
||||||
|
placeholder: '请输入批次号',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 列表的字段 */
|
||||||
|
export function useGridColumns(): VxeTableGridOptions<MesProCardApi.Card>['columns'] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field: 'code',
|
||||||
|
title: '流转卡编码',
|
||||||
|
width: 160,
|
||||||
|
slots: { default: 'code' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'workOrderCode',
|
||||||
|
title: '生产工单编号',
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'workOrderName',
|
||||||
|
title: '工单名称',
|
||||||
|
minWidth: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'batchCode',
|
||||||
|
title: '批次号',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'itemCode',
|
||||||
|
title: '产品物料编码',
|
||||||
|
width: 140,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'itemName',
|
||||||
|
title: '产品物料名称',
|
||||||
|
minWidth: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'specification',
|
||||||
|
title: '规格型号',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'unitMeasureName',
|
||||||
|
title: '单位',
|
||||||
|
width: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'transferedQuantity',
|
||||||
|
title: '流转数量',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '单据状态',
|
||||||
|
minWidth: 100,
|
||||||
|
cellRender: {
|
||||||
|
name: 'CellDict',
|
||||||
|
props: { type: DICT_TYPE.MES_PRO_WORK_ORDER_STATUS },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 240,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'actions' },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 工序记录子表的字段 */
|
||||||
|
export function useProcessGridColumns(
|
||||||
|
editable: boolean,
|
||||||
|
): VxeTableGridOptions<MesProCardProcessApi.CardProcess>['columns'] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field: 'sort',
|
||||||
|
title: '序号',
|
||||||
|
width: 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'processName',
|
||||||
|
title: '工序名称',
|
||||||
|
minWidth: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'processCode',
|
||||||
|
title: '工序编码',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inputTime',
|
||||||
|
title: '进入工序时间',
|
||||||
|
width: 180,
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'outputTime',
|
||||||
|
title: '出工序时间',
|
||||||
|
width: 180,
|
||||||
|
formatter: 'formatDateTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'inputQuantity',
|
||||||
|
title: '投入数量',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'outputQuantity',
|
||||||
|
title: '产出数量',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'unqualifiedQuantity',
|
||||||
|
title: '不良品数量',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'workstationCode',
|
||||||
|
title: '工位编码',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'workstationName',
|
||||||
|
title: '工位名称',
|
||||||
|
minWidth: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'nickname',
|
||||||
|
title: '操作人',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
...(editable
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 160,
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'actions' },
|
||||||
|
} as const,
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 工序记录新增/修改的表单 */
|
||||||
|
export function useProcessFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'sort',
|
||||||
|
label: '序号',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
min: 0,
|
||||||
|
placeholder: '请输入序号',
|
||||||
|
precision: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'processId',
|
||||||
|
label: '工序',
|
||||||
|
component: markRaw(ProProcessSelect),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择工序',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'inputTime',
|
||||||
|
label: '进入工序时间',
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
placeholder: '请选择进入工序时间',
|
||||||
|
type: 'datetime',
|
||||||
|
valueFormat: 'x',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'outputTime',
|
||||||
|
label: '出工序时间',
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
placeholder: '请选择出工序时间',
|
||||||
|
type: 'datetime',
|
||||||
|
valueFormat: 'x',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'inputQuantity',
|
||||||
|
label: '投入数量',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
min: 0,
|
||||||
|
placeholder: '请输入投入数量',
|
||||||
|
precision: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'outputQuantity',
|
||||||
|
label: '产出数量',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
min: 0,
|
||||||
|
placeholder: '请输入产出数量',
|
||||||
|
precision: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'unqualifiedQuantity',
|
||||||
|
label: '不合格数量',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {
|
||||||
|
class: '!w-full',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
min: 0,
|
||||||
|
placeholder: '请输入不合格数量',
|
||||||
|
precision: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'workstationId',
|
||||||
|
label: '工位',
|
||||||
|
component: markRaw(MdWorkstationSelect),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择工位',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'userId',
|
||||||
|
label: '操作人',
|
||||||
|
component: markRaw(UserSelect),
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请选择操作人',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
component: 'Textarea',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入备注',
|
||||||
|
rows: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/** 流转卡选择弹窗的搜索表单 */
|
/** 流转卡选择弹窗的搜索表单 */
|
||||||
export function useCardSelectGridFormSchema(): VbenFormSchema[] {
|
export function useCardSelectGridFormSchema(): VbenFormSchema[] {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
export { default as ProWorkOrderSelectDialog } from './pro-work-order-select-dialog.vue';
|
||||||
export { default as ProWorkOrderSelect } from './pro-work-order-select.vue';
|
export { default as ProWorkOrderSelect } from './pro-work-order-select.vue';
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,16 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
|
import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
|
||||||
|
|
||||||
import { computed, onMounted, ref, watch } from 'vue';
|
import { computed, ref, useAttrs, watch } from 'vue';
|
||||||
|
|
||||||
import { ElOption, ElSelect, ElTag, ElTooltip } from 'element-plus';
|
import { CircleX, Search } from '@vben/icons';
|
||||||
|
|
||||||
import { getWorkOrder, getWorkOrderPage } from '#/api/mes/pro/workorder';
|
import { ElInput, ElTooltip } from 'element-plus';
|
||||||
|
|
||||||
|
import { getWorkOrder } from '#/api/mes/pro/workorder';
|
||||||
|
|
||||||
|
import ProWorkOrderSelectDialog from './pro-work-order-select-dialog.vue';
|
||||||
|
|
||||||
/**
|
|
||||||
* MES 生产工单选择器(轻量版)
|
|
||||||
*
|
|
||||||
* 当前用于安灯记录等只需要单选工单 ID 的业务页面:
|
|
||||||
* - 默认按 `status` 过滤拉取首页 100 条工单作为下拉
|
|
||||||
* - 编辑回显走 `getWorkOrder(id)`
|
|
||||||
* - 后续 `mes/pro/workorder` 完整迁移后,可替换为带弹窗的复杂选择器
|
|
||||||
*/
|
|
||||||
defineOptions({ name: 'ProWorkOrderSelect', inheritAttrs: false });
|
defineOptions({ name: 'ProWorkOrderSelect', inheritAttrs: false });
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
|
|
@ -22,7 +18,6 @@ const props = withDefaults(
|
||||||
clearable?: boolean;
|
clearable?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
modelValue?: number;
|
modelValue?: number;
|
||||||
pageSize?: number;
|
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
status?: number;
|
status?: number;
|
||||||
type?: number;
|
type?: number;
|
||||||
|
|
@ -31,7 +26,6 @@ const props = withDefaults(
|
||||||
clearable: true,
|
clearable: true,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
modelValue: undefined,
|
modelValue: undefined,
|
||||||
pageSize: 100,
|
|
||||||
placeholder: '请选择工单',
|
placeholder: '请选择工单',
|
||||||
status: undefined,
|
status: undefined,
|
||||||
type: undefined,
|
type: undefined,
|
||||||
|
|
@ -43,108 +37,102 @@ const emit = defineEmits<{
|
||||||
'update:modelValue': [value: number | undefined];
|
'update:modelValue': [value: number | undefined];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const allList = ref<MesProWorkOrderApi.WorkOrder[]>([]);
|
const attrs = useAttrs(); // 透传属性
|
||||||
const filteredList = ref<MesProWorkOrderApi.WorkOrder[]>([]);
|
const dialogRef = ref<InstanceType<typeof ProWorkOrderSelectDialog>>(); // 工单选择弹窗
|
||||||
const selectedItem = ref<MesProWorkOrderApi.WorkOrder>();
|
const hovering = ref(false); // 是否悬停
|
||||||
|
const selectedItem = ref<MesProWorkOrderApi.WorkOrder>(); // 当前选中工单
|
||||||
|
|
||||||
const selectValue = computed({
|
const displayLabel = computed(() => selectedItem.value?.code ?? ''); // 选择器展示编码
|
||||||
get: () => props.modelValue,
|
const showClear = computed(() => // 是否显示清空图标
|
||||||
set: (value: number | undefined) => {
|
props.clearable &&
|
||||||
emit('update:modelValue', value);
|
!props.disabled &&
|
||||||
},
|
hovering.value &&
|
||||||
});
|
props.modelValue != null,
|
||||||
|
);
|
||||||
|
|
||||||
function handleFilter(query: string) {
|
/** 根据编号单条查询工单信息(用于编辑回显) */
|
||||||
if (!query) {
|
async function resolveItemById(id: number | undefined) {
|
||||||
filteredList.value = allList.value;
|
if (id == null) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
const keyword = query.toLowerCase();
|
|
||||||
filteredList.value = allList.value.filter(
|
|
||||||
(item) =>
|
|
||||||
item.code?.toLowerCase().includes(keyword) ||
|
|
||||||
item.name?.toLowerCase().includes(keyword),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 同步选中工单详情,未在列表内时单独拉取 */
|
|
||||||
async function syncSelectedItem(value: number | undefined) {
|
|
||||||
if (value === undefined) {
|
|
||||||
selectedItem.value = undefined;
|
selectedItem.value = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const found = allList.value.find((item) => item.id === value);
|
if (selectedItem.value?.id === id) {
|
||||||
if (found) {
|
|
||||||
selectedItem.value = found;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
selectedItem.value = await getWorkOrder(id);
|
||||||
selectedItem.value = await getWorkOrder(value);
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('[ProWorkOrderSelect] resolveItemById failed:', error);
|
watch(() => props.modelValue, resolveItemById, { immediate: true });
|
||||||
|
|
||||||
|
/** 清空已选工单 */
|
||||||
|
function clearSelected() {
|
||||||
|
selectedItem.value = undefined;
|
||||||
|
emit('update:modelValue', undefined);
|
||||||
|
emit('change', undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开工单选择弹窗 */
|
||||||
|
function handleClick(event: MouseEvent) {
|
||||||
|
if (props.disabled) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (showClear.value && target.closest('.el-input__suffix')) {
|
||||||
|
event.stopPropagation();
|
||||||
|
clearSelected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
|
||||||
|
dialogRef.value?.open(selectedIds, { multiple: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 除 v-model 外,额外抛出完整工单对象给业务表单使用 */
|
/** 弹窗选中回调 */
|
||||||
function handleChange(value: number | undefined) {
|
function handleSelected(rows: MesProWorkOrderApi.WorkOrder[]) {
|
||||||
syncSelectedItem(value);
|
const item = rows[0];
|
||||||
emit('change', selectedItem.value);
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedItem.value = item;
|
||||||
|
emit('update:modelValue', item.id);
|
||||||
|
emit('change', item);
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
(value) => {
|
|
||||||
syncSelectedItem(value);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
const data = await getWorkOrderPage({
|
|
||||||
pageNo: 1,
|
|
||||||
pageSize: props.pageSize,
|
|
||||||
status: props.status,
|
|
||||||
type: props.type,
|
|
||||||
});
|
|
||||||
allList.value = data.list ?? [];
|
|
||||||
filteredList.value = allList.value;
|
|
||||||
syncSelectedItem(props.modelValue);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ElTooltip :disabled="!selectedItem" placement="top" :show-after="500">
|
<div
|
||||||
<template #content>
|
v-bind="attrs"
|
||||||
<div v-if="selectedItem" class="leading-6">
|
class="w-full"
|
||||||
<div>编码:{{ selectedItem.code || '-' }}</div>
|
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
|
||||||
<div>名称:{{ selectedItem.name || '-' }}</div>
|
@click="handleClick"
|
||||||
<div>产品:{{ selectedItem.productName || '-' }}</div>
|
@mouseenter="hovering = true"
|
||||||
<div>数量:{{ selectedItem.quantity ?? '-' }}</div>
|
@mouseleave="hovering = false"
|
||||||
</div>
|
>
|
||||||
</template>
|
<ElTooltip :disabled="!selectedItem" placement="top" :show-after="500">
|
||||||
<ElSelect
|
<template #content>
|
||||||
v-bind="$attrs"
|
<div v-if="selectedItem" class="leading-6">
|
||||||
v-model="selectValue"
|
<div>编码:{{ selectedItem.code || '-' }}</div>
|
||||||
:clearable="clearable"
|
<div>名称:{{ selectedItem.name || '-' }}</div>
|
||||||
:disabled="disabled"
|
<div>产品:{{ selectedItem.productName || '-' }}</div>
|
||||||
:filter-method="handleFilter"
|
<div>数量:{{ selectedItem.quantity ?? '-' }}</div>
|
||||||
:placeholder="placeholder"
|
|
||||||
class="w-full"
|
|
||||||
filterable
|
|
||||||
@change="handleChange"
|
|
||||||
>
|
|
||||||
<ElOption
|
|
||||||
v-for="item in filteredList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.code"
|
|
||||||
:value="item.id!"
|
|
||||||
>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<span>{{ item.code }}</span>
|
|
||||||
<ElTag v-if="item.name" size="small" type="info">
|
|
||||||
{{ item.name }}
|
|
||||||
</ElTag>
|
|
||||||
</div>
|
</div>
|
||||||
</ElOption>
|
</template>
|
||||||
</ElSelect>
|
<ElInput
|
||||||
</ElTooltip>
|
:disabled="disabled"
|
||||||
|
:model-value="displayLabel"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
readonly
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<CircleX v-if="showClear" class="size-4" />
|
||||||
|
<Search v-else class="size-4" />
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
</ElTooltip>
|
||||||
|
</div>
|
||||||
|
<ProWorkOrderSelectDialog
|
||||||
|
ref="dialogRef"
|
||||||
|
:status="status"
|
||||||
|
:type="type"
|
||||||
|
@selected="handleSelected"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -39,23 +39,18 @@ const canSubmit = computed(() => // 是否可提交
|
||||||
formData.value?.status === MesWmOutsourceIssueStatusEnum.PREPARE,
|
formData.value?.status === MesWmOutsourceIssueStatusEnum.PREPARE,
|
||||||
);
|
);
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['外协发料单']);
|
||||||
return $t('ui.actionTitle.view', ['外协发料单']);
|
|
||||||
}
|
|
||||||
case 'finish': {
|
|
||||||
return '执行领出';
|
|
||||||
}
|
|
||||||
case 'stock': {
|
|
||||||
return '执行拣货';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['外协发料单']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['外协发料单']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'stock') {
|
||||||
|
return '执行拣货';
|
||||||
|
}
|
||||||
|
if (formType.value === 'finish') {
|
||||||
|
return '执行领出';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['外协发料单'])
|
||||||
|
: $t('ui.actionTitle.create', ['外协发料单']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ const props = defineProps<{
|
||||||
issueId: number;
|
issueId: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isEditable = computed(() =>
|
const isEditable = computed(() => // 是否可编辑明细行
|
||||||
['create', 'update'].includes(props.formType),
|
['create', 'update'].includes(props.formType),
|
||||||
); // 是否可编辑明细行
|
);
|
||||||
const isStock = computed(() => props.formType === 'stock'); // 是否为拣货模式
|
const isStock = computed(() => props.formType === 'stock'); // 是否为拣货模式
|
||||||
const detailMap = reactive<
|
const detailMap = reactive<
|
||||||
Record<number, MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]>
|
Record<number, MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]>
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ const emit = defineEmits<{
|
||||||
refresh: [];
|
refresh: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isEditable = computed(
|
const isEditable = computed(() => // 是否可维护收货明细(编辑或上架态)
|
||||||
() => ['create', 'stock', 'update'].includes(props.formType),
|
['create', 'stock', 'update'].includes(props.formType),
|
||||||
); // 是否可维护收货明细(编辑或上架态)
|
);
|
||||||
|
|
||||||
/** 添加收货明细 */
|
/** 添加收货明细 */
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
|
|
|
||||||
|
|
@ -38,23 +38,18 @@ const canSubmit = computed(() => // 是否可提交
|
||||||
formData.value?.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
|
formData.value?.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
|
||||||
);
|
);
|
||||||
const getTitle = computed(() => {
|
const getTitle = computed(() => {
|
||||||
switch (formType.value) {
|
if (formType.value === 'detail') {
|
||||||
case 'detail': {
|
return $t('ui.actionTitle.view', ['外协入库单']);
|
||||||
return $t('ui.actionTitle.view', ['外协入库单']);
|
|
||||||
}
|
|
||||||
case 'finish': {
|
|
||||||
return '完成入库';
|
|
||||||
}
|
|
||||||
case 'stock': {
|
|
||||||
return '执行上架';
|
|
||||||
}
|
|
||||||
case 'update': {
|
|
||||||
return $t('ui.actionTitle.edit', ['外协入库单']);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return $t('ui.actionTitle.create', ['外协入库单']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (formType.value === 'stock') {
|
||||||
|
return '执行上架';
|
||||||
|
}
|
||||||
|
if (formType.value === 'finish') {
|
||||||
|
return '完成入库';
|
||||||
|
}
|
||||||
|
return formType.value === 'update'
|
||||||
|
? $t('ui.actionTitle.edit', ['外协入库单'])
|
||||||
|
: $t('ui.actionTitle.create', ['外协入库单']);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ const props = defineProps<{
|
||||||
receiptId: number;
|
receiptId: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const isEditable = computed(() =>
|
const isEditable = computed(() => // 是否可编辑明细行
|
||||||
['create', 'update'].includes(props.formType),
|
['create', 'update'].includes(props.formType),
|
||||||
); // 是否可编辑明细行
|
);
|
||||||
const isStock = computed(() => props.formType === 'stock'); // 是否为上架模式
|
const isStock = computed(() => props.formType === 'stock'); // 是否为上架模式
|
||||||
const detailMap = reactive<
|
const detailMap = reactive<
|
||||||
Record<number, MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail[]>
|
Record<number, MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail[]>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue