Merge remote-tracking branch 'origin/dev_新疆_新高电力' into dev_新疆_新高电力
| | |
| | | |
| | | /** 物料分页查询参数 */ |
| | | export interface PageParams extends PageParam { |
| | | excludeIds?: string; |
| | | code?: string; |
| | | name?: string; |
| | | categoryId?: number; |
| | |
| | | `/mes/pro/work-order-bom/item-list-by-work-order-id?workOrderId=${workOrderId}`, |
| | | ); |
| | | } |
| | | |
| | | /** 查询生产任务所在工序的投入物料 */ |
| | | export function getWorkOrderBomListByTaskId(taskId: number) { |
| | | return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom[]>( |
| | | '/mes/pro/work-order-bom/list-by-task-id', |
| | | { params: { taskId } }, |
| | | ); |
| | | } |
| | |
| | | const selectedRows = ref<MdmItemApi.Item[]>([]); // 已选物料列表 |
| | | const preSelectedIds = ref<number[]>([]); // 预选物料编号列表 |
| | | const categoryList = ref<MesMdItemTypeApi.ItemType[]>([]); // 分类列表缓存 |
| | | const excludeIds = ref<number[]>([]); |
| | | |
| | | const TAG_COLORS = ['green', 'orange', 'blue', 'purple', 'cyan', 'magenta', 'geekblue', 'volcano', 'gold', 'lime'] as const; |
| | | |
| | |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | excludeIds: excludeIds.value.length ? excludeIds.value.join(',') : undefined, |
| | | }); |
| | | }, |
| | | }, |
| | |
| | | /** 打开物料选择弹窗 */ |
| | | async function openModal( |
| | | selectedIds?: number[], |
| | | options?: { multiple?: boolean }, |
| | | options?: { multiple?: boolean; excludeIds?: number[] }, |
| | | ) { |
| | | open.value = true; |
| | | multiple.value = options?.multiple ?? true; |
| | | preSelectedIds.value = selectedIds || []; |
| | | excludeIds.value = options?.excludeIds || []; |
| | | await nextTick(); |
| | | gridApi.setGridOptions({ |
| | | columns: useMdmItemSelectGridColumns(multiple.value), |
| | |
| | | modelValue?: number; |
| | | placeholder?: string; |
| | | label?: string; |
| | | excludeIds?: number[]; |
| | | }>(), |
| | | { |
| | | allowClear: true, |
| | |
| | | const selectedIds = ( |
| | | props.modelValue === null ? [] : [props.modelValue] |
| | | ) as number[]; |
| | | dialogRef.value?.open(selectedIds, { multiple: false }); |
| | | dialogRef.value?.open(selectedIds, { multiple: false, excludeIds: props.excludeIds }); |
| | | } |
| | | |
| | | /** 回填选中的物料 */ |
| | |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { Button, Card, message, Popconfirm, Steps } from 'ant-design-vue'; |
| | | import { Card, message, Steps } from 'ant-design-vue'; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { getRouteProcessListByProduct } from '#/api/mes/pro/route/process'; |
| | | import { finishWorkOrder, getWorkOrder } from '#/api/mes/pro/workorder'; |
| | | import { getWorkOrder } from '#/api/mes/pro/workorder'; |
| | | import { getWorkOrderProcessListByWorkOrderId } from '#/api/mes/pro/workorder/process'; |
| | | |
| | | import { useScheduleFormSchema } from '../data'; |
| | | import TaskList from './task-list.vue'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formType = ref<'detail' | 'schedule'>('schedule'); |
| | | const workOrder = ref<MesProWorkOrderApi.WorkOrder>(); // 当前订单详情 |
| | | /** 排产工序列表 */ |
| | |
| | | routeProcessList.value = [...woProcesses].toSorted( |
| | | (a, b) => (a.sort ?? 0) - (b.sort ?? 0), |
| | | ); |
| | | } |
| | | |
| | | /** 完成订单 */ |
| | | async function handleFinish() { |
| | | if (!workOrder.value?.id) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | await finishWorkOrder(workOrder.value.id); |
| | | message.success('订单已完成'); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | |
| | | /> |
| | | </Card> |
| | | </template> |
| | | </template> |
| | | <template #prepend-footer> |
| | | <div class="flex flex-auto items-center gap-2"> |
| | | <template v-if="formType === 'schedule'"> |
| | | <Popconfirm |
| | | v-if="routeProcessList.length > 0" |
| | | title="确认要完成该订单吗?完成后订单下所有任务将标记为已完成。" |
| | | @confirm="handleFinish" |
| | | > |
| | | <Button type="primary">完成</Button> |
| | | </Popconfirm> |
| | | <span v-else class="text-gray-400 text-sm"> |
| | | 当前订单未配置工序,请先在工单中维护工序信息后再完成 |
| | | </span> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | </Modal> |
| | | </template> |
| | |
| | | |
| | | import { z } from '#/adapter/form'; |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { getItemPage } from '#/api/mdm/item'; |
| | | import { MdmItemSelect } from '#/views/basicData/mdm/components'; |
| | | import { MdUnitMeasureSelect } from '#/views/mes/md/unitmeasure/components'; |
| | | import { QcIndicatorSelect } from '#/views/mes/qc/indicator/components'; |
| | | |
| | |
| | | } |
| | | |
| | | /** 产品关联子表的表单 */ |
| | | export function useItemFormSchema(): VbenFormSchema[] { |
| | | export function useItemFormSchema(excludeIds: number[] = []): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'id', |
| | |
| | | { |
| | | fieldName: 'itemId', |
| | | label: '产品物料', |
| | | component: 'ApiSelect', |
| | | component: markRaw(MdmItemSelect), |
| | | componentProps: { |
| | | placeholder: '请选择产品物料', |
| | | allowClear: true, |
| | | showSearch: true, |
| | | api: getItemPage, |
| | | resultField: 'list', |
| | | labelField: 'name', |
| | | valueField: 'id', |
| | | optionRender: (option: any) => { |
| | | const item = option.data; |
| | | return `${item.code} - ${item.name}`; |
| | | }, |
| | | excludeIds, |
| | | }, |
| | | formItemClass: 'col-span-3', |
| | | rules: 'required', |
| | |
| | | import { |
| | | createTemplateItem, |
| | | getTemplateItem, |
| | | getTemplateItemPage, |
| | | updateTemplateItem, |
| | | } from '#/api/mes/qc/template/item'; |
| | | import { $t } from '#/locales'; |
| | |
| | | MesQcTemplateItemApi.TemplateItem & { templateId: number } |
| | | >(); |
| | | templateId.value = data.templateId; |
| | | if (!data?.id) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | formData.value = await getTemplateItem(data.id); |
| | | formData.value = data.id ? await getTemplateItem(data.id) : undefined; |
| | | const boundItems: MesQcTemplateItemApi.TemplateItem[] = []; |
| | | let pageNo = 1; |
| | | const pageSize = 200; |
| | | let total: number; |
| | | do { |
| | | const page = await getTemplateItemPage({ templateId: data.templateId, pageNo, pageSize }); |
| | | boundItems.push(...page.list); |
| | | total = page.total; |
| | | pageNo++; |
| | | if (page.list.length === 0) break; |
| | | } while (boundItems.length < total); |
| | | const excludeIds = boundItems |
| | | .filter(item => item.id !== data.id && item.itemId != null) |
| | | .map(item => item.itemId!); |
| | | await formApi.updateSchema(useItemFormSchema(excludeIds)); |
| | | // 设置到 values |
| | | await formApi.setValues(formData.value); |
| | | if (formData.value) await formApi.setValues(formData.value); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { MesWmProductIssueLineApi } from '#/api/mes/wm/productissue/line'; |
| | | |
| | | import { computed, markRaw, ref } from 'vue'; |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { getWorkOrderBomListByTaskId } from '#/api/mes/pro/workorder/bom'; |
| | | import { getProductIssue } from '#/api/mes/wm/productissue'; |
| | | import { |
| | | createProductIssueLine, |
| | | getProductIssueLine, |
| | | updateProductIssueLine, |
| | | } from '#/api/mes/wm/productissue/line'; |
| | | import { MdItemSelect } from '#/views/mes/md/item/components'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formData = ref<MesWmProductIssueLineApi.ProductIssueLine>(); |
| | |
| | | }); |
| | | |
| | | /** 物料行表单 schema */ |
| | | function buildLineFormSchema(): VbenFormSchema[] { |
| | | function buildLineFormSchema(options: { label: string; value: number }[] = []): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'itemId', |
| | | label: '产品物料', |
| | | component: markRaw(MdItemSelect), |
| | | componentProps: { placeholder: '请选择产品物料' }, |
| | | component: 'Select', |
| | | componentProps: { |
| | | options, |
| | | showSearch: true, |
| | | optionFilterProp: 'label', |
| | | placeholder: options.length ? '请选择当前工序物料' : '请先维护当前工序投入物料', |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | |
| | | } |
| | | const data = modalApi.getData<{ id?: number; issueId: number }>(); |
| | | issueId.value = data.issueId; |
| | | if (!data.id) { |
| | | await formApi.resetForm(); |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | formData.value = await getProductIssueLine(data.id); |
| | | await formApi.setValues(formData.value); |
| | | const issue = await getProductIssue(data.issueId); |
| | | const boms = issue.taskId ? await getWorkOrderBomListByTaskId(issue.taskId) : []; |
| | | const optionMap = new Map<number, { label: string; value: number }>(); |
| | | for (const item of boms) { |
| | | if (item.itemId != null) { |
| | | optionMap.set(item.itemId, { |
| | | value: item.itemId, |
| | | label: `${item.itemCode ?? ''} ${item.itemName ?? ''}`.trim(), |
| | | }); |
| | | } |
| | | } |
| | | const options = [...optionMap.values()]; |
| | | await formApi.updateSchema(buildLineFormSchema(options)); |
| | | await formApi.resetForm(); |
| | | if (data.id) { |
| | | formData.value = await getProductIssueLine(data.id); |
| | | await formApi.setValues(formData.value); |
| | | } |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |