feat(mes): 基础参数与工序绑定前端 + 报工填写参数字段
- 工序设置页新增「工艺参数」绑定弹窗(添加/必填/排序/备注)
- 基础参数页新增「关联工序」入口
- 报工表单按任务参数记录渲染参数字段、必填星号、客户端校验
- 报工详情/列表回显参数值
Co-Authored-By: Claude <noreply@anthropic.com>
| | |
| | | export interface ParamValue { |
| | | detailId: number; |
| | | value?: string; |
| | | // ---- 忾忮µï¼æ¥å·¥è¯¦æ
/å表è¿åï¼ ---- |
| | | paramCode?: string; |
| | | paramName?: string; |
| | | paramType?: number; |
| | | unitMeasureName?: string; |
| | | paramValue?: string; |
| | | required?: boolean; |
| | | } |
| | | |
| | | /** MES ç产æ¥å·¥å页æ¥è¯¢åæ° */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace MesProProcessParamApi { |
| | | /** å·¥åº-å·¥èºåæ°ç»å® */ |
| | | export interface ProcessParam { |
| | | id?: number; |
| | | processId?: number; |
| | | processParamId?: number; |
| | | paramCode?: string; |
| | | paramName?: string; |
| | | paramType?: number; |
| | | unitMeasureId?: number; |
| | | unitMeasureName?: string; |
| | | required?: boolean; |
| | | sort?: number; |
| | | remark?: string; |
| | | } |
| | | |
| | | /** ä¿åç»å®é¡¹ */ |
| | | export interface SaveItem { |
| | | processParamId: number; |
| | | required?: boolean; |
| | | sort?: number; |
| | | remark?: string; |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢å·¥åºç»å®çå·¥èºåæ°å表 */ |
| | | export function getProcessParamListByProcess(processId: number) { |
| | | return requestClient.get<MesProProcessParamApi.ProcessParam[]>( |
| | | '/mes/pro/process-param/list-by-process', |
| | | { params: { processId } }, |
| | | ); |
| | | } |
| | | |
| | | /** å
¨éè¦çä¿åå·¥åºç»å®çå·¥èºåæ° */ |
| | | export function updateProcessParams( |
| | | processId: number, |
| | | items: MesProProcessParamApi.SaveItem[], |
| | | ) { |
| | | return requestClient.post('/mes/pro/process-param/update-bindings', { |
| | | processId, |
| | | items, |
| | | }); |
| | | } |
| | | |
| | | /** æ¥è¯¢æå·¥èºåæ°è¢«åªäºå·¥åºç»å® */ |
| | | export function getProcessListByParam(paramId: number) { |
| | | return requestClient.get< |
| | | { id: number; code?: string; name?: string; attention?: string }[] |
| | | >('/mes/pro/process-param/list-by-param', { params: { paramId } }); |
| | | } |
| | |
| | | unitMeasureId?: number; |
| | | unitMeasureName?: string; |
| | | paramValue?: string; |
| | | required?: boolean; |
| | | remark?: string; |
| | | } |
| | | |
| | |
| | | |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { getRouteProcessByRouteAndProcess } from '#/api/mes/pro/route/process'; |
| | | import { getWorkOrderParamRecordPage } from '#/api/mes/pro/workorderparamrecord'; |
| | | import { getSimpleUserList } from '#/api/system/user'; |
| | | import { loadParamDetails } from './param-state'; |
| | | import { getRangePickerDefaultProps } from '#/utils'; |
| | | import { MdItemSelect } from '#/views/mes/md/item/components'; |
| | | import { MdWorkstationSelect } from '#/views/mes/md/workstation/components'; |
| | |
| | | workstationId: values.workstationId, |
| | | }), |
| | | }, |
| | | // ä»»å¡åæ´ï¼èªå¨å¡«å
å
³èåæ®µã产åä¿¡æ¯ãcheckFlag |
| | | // ä»»å¡åæ´ï¼èªå¨å¡«å
å
³èåæ®µã产åä¿¡æ¯ãcheckFlagï¼å¹¶å 载任å¡ç»å®çå·¥èºåæ° |
| | | componentProps: { |
| | | onChange: async (task?: MesProTaskApi.Task) => { |
| | | await loadParamDetails(task?.id); |
| | | if (!task) { |
| | | return; |
| | | } |
| | |
| | | import { Page } from '@vben/common-ui'; |
| | | import { useTabs } from '@vben/hooks'; |
| | | |
| | | import { Card, Tabs } from 'ant-design-vue'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | |
| | | import { Card, Table, Tabs } from 'ant-design-vue'; |
| | | |
| | | import { TableAction } from '#/adapter/vxe-table'; |
| | | import { getFeedback } from '#/api/mes/pro/feedback'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | import { useDetailSchema } from '../data'; |
| | | import ItemConsumeList from '../modules/item-consume-list.vue'; |
| | | import ProductProduceList from '../modules/product-produce-list.vue'; |
| | | |
| | | const paramColumns = [ |
| | | { title: 'åæ°åç§°', dataIndex: 'paramName', key: 'paramName' }, |
| | | { title: 'åæ°ç¼ç ', dataIndex: 'paramCode', key: 'paramCode' }, |
| | | { title: 'åæ°ç±»å', dataIndex: 'paramType', key: 'paramType' }, |
| | | { title: 'åä½', dataIndex: 'unitMeasureName', key: 'unitMeasureName' }, |
| | | { title: 'åæ°å¼', dataIndex: 'paramValue', key: 'paramValue' }, |
| | | { title: 'æ¯å¦å¿
å¡«', dataIndex: 'required', key: 'required' }, |
| | | ]; |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | |
| | | <Card class="min-h-[10%]"> |
| | | <Descriptions :data="feedback" /> |
| | | </Card> |
| | | <Card v-if="feedback.paramValues && feedback.paramValues.length > 0" class="mt-3" title="å·¥èºåæ°"> |
| | | <Table |
| | | :columns="paramColumns" |
| | | :data-source="feedback.paramValues" |
| | | :pagination="false" |
| | | row-key="detailId" |
| | | size="small" |
| | | > |
| | | <template #bodyCell="{ column, record }"> |
| | | <template v-if="column.key === 'paramType'"> |
| | | <DictTag |
| | | v-if="record.paramType !== undefined && record.paramType !== null" |
| | | :type="DICT_TYPE.MES_PD_PARAM_TYPE" |
| | | :value="record.paramType" |
| | | /> |
| | | </template> |
| | | <template v-else-if="column.key === 'required'"> |
| | | <DictTag |
| | | :type="DICT_TYPE.INFRA_BOOLEAN_STRING" |
| | | :value="record.required ? 'true' : 'false'" |
| | | /> |
| | | </template> |
| | | </template> |
| | | </Table> |
| | | </Card> |
| | | |
| | | </Page> |
| | | </template> |
| | |
| | | } from '#/api/mes/pro/feedback'; |
| | | import { getRouteProcessByRouteAndProcess } from '#/api/mes/pro/route/process'; |
| | | import { getWorkOrder } from '#/api/mes/pro/workorder'; |
| | | import { getWorkOrderParamRecordPage } from '#/api/mes/pro/workorderparamrecord'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useFormSchema } from '../data'; |
| | | import { findMissingRequiredParams, loadParamDetails, paramDetails } from '../param-state'; |
| | | import BatchInputDialog from './batch-input-dialog.vue'; |
| | | import ItemConsumeList from './item-consume-list.vue'; |
| | | import ProductProduceList from './product-produce-list.vue'; |
| | |
| | | const userStore = useUserStore(); |
| | | const subTabsName = ref('itemConsume'); |
| | | const originalSnapshot = ref(''); // 表ååå§æ°æ®å¿«ç
§ï¼ç¨äº submit æ¶è·³è¿æªåæ´çä¿åè¯·æ± |
| | | const paramDetails = ref<Array<{ id: number; paramName?: string; paramCode?: string; unitMeasureName?: string; paramValue?: string }>>([]); |
| | | |
| | | const isEditable = computed(() => |
| | | ['create', 'submit', 'update'].includes(formType.value), |
| | |
| | | if (!valid) { |
| | | return; |
| | | } |
| | | if (!checkRequiredParams()) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | const data = await getAlignedData(); |
| | |
| | | const batchDialogRef = ref<InstanceType<typeof BatchInputDialog>>(); |
| | | const batchActionType = ref<'submit' | 'approve'>(''); |
| | | |
| | | async function loadParamDetails(taskId?: number) { |
| | | paramDetails.value = []; |
| | | if (!taskId) return; |
| | | const page = await getWorkOrderParamRecordPage({ taskId, pageNo: 1, pageSize: 1 }); |
| | | const record = page.list?.[0]; |
| | | paramDetails.value = (record?.details ?? []).map((detail) => ({ |
| | | id: detail.id!, |
| | | paramCode: detail.paramCode, |
| | | paramName: detail.paramName, |
| | | unitMeasureName: detail.unitMeasureName, |
| | | paramValue: detail.paramValue, |
| | | })); |
| | | } |
| | | |
| | | function syncParamValues(data: MesProFeedbackApi.Feedback) { |
| | | data.paramValues = paramDetails.value.map((detail) => ({ |
| | | detailId: detail.id, |
| | | value: detail.paramValue, |
| | | })); |
| | | } |
| | | |
| | | /** æ ¡éªå¿
å¡«åæ°æ¯å¦å¡«å宿´ */ |
| | | function checkRequiredParams(): boolean { |
| | | const missing = findMissingRequiredParams(); |
| | | if (missing.length > 0) { |
| | | message.warning(`å¿
å¡«åæ°æªå¡«åï¼${missing.join('ã')}`); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** æ§è¡æäº¤ï¼å«æ¹æ¬¡å±æ§ï¼ */ |
| | |
| | | async function handleSubmit() { |
| | | const { valid } = await formApi.validate(); |
| | | if (!valid) { |
| | | return; |
| | | } |
| | | if (!checkRequiredParams()) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | |
| | | formData.value = undefined; |
| | | subTabsName.value = 'itemConsume'; |
| | | originalSnapshot.value = ''; |
| | | paramDetails.value = []; |
| | | return; |
| | | } |
| | | // å è½½æ°æ® |
| | |
| | | <div class="mb-3 font-medium">å·¥èºåæ°</div> |
| | | <div class="grid grid-cols-2 gap-3"> |
| | | <div v-for="detail in paramDetails" :key="detail.id" class="flex items-center gap-2"> |
| | | <span class="w-40 text-right text-sm text-gray-600"> |
| | | <span class="w-44 text-right text-sm text-gray-600"> |
| | | <span v-if="detail.required" class="text-red-500">* </span> |
| | | {{ detail.paramName || detail.paramCode }}{{ detail.unitMeasureName ? `ï¼${detail.unitMeasureName}ï¼` : '' }} |
| | | </span> |
| | | <Input v-model:value="detail.paramValue" :disabled="!isEditable" placeholder="请è¾å
¥åæ°å¼" /> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { getWorkOrderParamRecordPage } from '#/api/mes/pro/workorderparamrecord'; |
| | | |
| | | /** æ¥å·¥è¡¨åè¦å¡«åçåæ°é¡¹ï¼æ¥èªä»»å¡åæ°è®°å½å¿«ç
§ï¼ */ |
| | | export interface ParamDetailItem { |
| | | id: number; |
| | | paramCode?: string; |
| | | paramName?: string; |
| | | paramType?: number; |
| | | unitMeasureName?: string; |
| | | paramValue?: string; |
| | | required?: boolean; |
| | | } |
| | | |
| | | /** å½åæ¥å·¥è¡¨åçåæ°æç»ï¼å
±äº«ç»è¡¨åä¸ä»»å¡éæ©èå¨ï¼ */ |
| | | export const paramDetails = ref<ParamDetailItem[]>([]); |
| | | |
| | | /** æä»»å¡å è½½åæ°æç»ï¼ä»»å¡æ åæ°è®°å½æ¶ä¸ºç©ºæ°ç»ï¼ */ |
| | | export async function loadParamDetails(taskId?: number) { |
| | | paramDetails.value = []; |
| | | if (!taskId) { |
| | | return; |
| | | } |
| | | const page = await getWorkOrderParamRecordPage({ |
| | | taskId, |
| | | pageNo: 1, |
| | | pageSize: 1, |
| | | }); |
| | | const record = page.list?.[0]; |
| | | paramDetails.value = (record?.details ?? []).map((detail) => ({ |
| | | id: detail.id!, |
| | | paramCode: detail.paramCode, |
| | | paramName: detail.paramName, |
| | | paramType: detail.paramType, |
| | | unitMeasureName: detail.unitMeasureName, |
| | | paramValue: detail.paramValue, |
| | | required: detail.required, |
| | | })); |
| | | } |
| | | |
| | | /** æ ¡éªå¿
å¡«åæ°æ¯å¦é½å·²å¡«åï¼è¿åæªå¡«åçåæ°å */ |
| | | export function findMissingRequiredParams(): string[] { |
| | | return paramDetails.value |
| | | .filter((detail) => detail.required && !detail.paramValue?.trim()) |
| | | .map((detail) => detail.paramName || detail.paramCode || ''); |
| | | } |
| | |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | import ProcessLinkDialog from './modules/process-link-dialog.vue'; |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [ProcessLinkModal, processLinkModalApi] = useVbenModal({ |
| | | connectedComponent: ProcessLinkDialog, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | /** å·æ°è¡¨æ ¼ */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** æ¥çè¯¥åæ°è¢«åªäºå·¥åºç»å® */ |
| | | function handleViewProcessLink(row: MesPdParameterApi.Parameter) { |
| | | processLinkModalApi |
| | | .setData({ paramId: row.id, paramName: row.paramName }) |
| | | .open(); |
| | | } |
| | | |
| | | /** å建工èºåæ° */ |
| | |
| | | |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | <ProcessLinkModal /> |
| | | <Grid table-title="å·¥èºåæ°å表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'å
³èå·¥åº', |
| | | type: 'link', |
| | | icon: ACTION_ICON.LINK, |
| | | auth: ['mes:pd:parameter:update'], |
| | | onClick: handleViewProcessLink.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { Table } from 'ant-design-vue'; |
| | | |
| | | import { getProcessListByParam } from '#/api/mes/pro/processdesign/processparam'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | |
| | | const paramId = ref<number>(); |
| | | const paramName = ref<string>(''); |
| | | const loading = ref(false); |
| | | const processList = ref<{ id: number; code?: string; name?: string; attention?: string }[]>([]); |
| | | |
| | | const getTitle = computed(() => `å
³èå·¥åº - ${paramName.value || ''}`); |
| | | |
| | | async function loadData() { |
| | | if (!paramId.value) { |
| | | return; |
| | | } |
| | | loading.value = true; |
| | | try { |
| | | processList.value = await getProcessListByParam(paramId.value); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | await modalApi.close(); |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | paramId.value = undefined; |
| | | processList.value = []; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ paramId: number; paramName?: string }>(); |
| | | paramId.value = data.paramId; |
| | | paramName.value = data.paramName || ''; |
| | | await loadData(); |
| | | }, |
| | | }); |
| | | |
| | | const columns = [ |
| | | { title: 'å·¥åºç¼ç ', dataIndex: 'code', key: 'code' }, |
| | | { title: 'å·¥åºåç§°', dataIndex: 'name', key: 'name' }, |
| | | { title: 'å·¥èºè¦æ±', dataIndex: 'attention', key: 'attention' }, |
| | | ]; |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal :title="getTitle" class="w-2/5"> |
| | | <Table |
| | | :columns="columns" |
| | | :data-source="processList" |
| | | :loading="loading" |
| | | :pagination="false" |
| | | row-key="id" |
| | | size="small" |
| | | > |
| | | <template #emptyText> |
| | | {{ loading ? 'å è½½ä¸â¦' : 'è¯¥åæ°ææªè¢«ä»»ä½å·¥åºç»å®' }} |
| | | </template> |
| | | </Table> |
| | | </Modal> |
| | | </template> |
| | |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | import ParamManage from './modules/param-manage.vue'; |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [ParamManageModal, paramManageModalApi] = useVbenModal({ |
| | | connectedComponent: ParamManage, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | /** å·æ°è¡¨æ ¼ */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** 管çå·¥åºç»å®çå·¥èºåæ° */ |
| | | function handleParamManage(row: MesProProcessApi.Process) { |
| | | paramManageModalApi |
| | | .setData({ processId: row.id, processName: row.name }) |
| | | .open(); |
| | | } |
| | | |
| | | /** å建çäº§å·¥åº */ |
| | |
| | | |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | <ParamManageModal @success="handleRefresh" /> |
| | | <Grid table-title="ç产工åºå表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'å·¥èºåæ°', |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['mes:pro-process:update'], |
| | | onClick: handleParamManage.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdParameterApi } from '#/api/mes/pro/processdesign/parameter'; |
| | | import type { MesProProcessParamApi } from '#/api/mes/pro/processdesign/processparam'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { Button, Input, InputNumber, message, Switch } from 'ant-design-vue'; |
| | | |
| | | import { |
| | | getProcessParamListByProcess, |
| | | updateProcessParams, |
| | | } from '#/api/mes/pro/processdesign/processparam'; |
| | | import { $t } from '#/locales'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | |
| | | import ParameterSelectDialog from '../../template/modules/parameter-select-dialog.vue'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | |
| | | const processId = ref<number>(); |
| | | const processName = ref<string>(''); |
| | | const loading = ref(false); |
| | | const boundList = ref<MesProProcessParamApi.ProcessParam[]>([]); |
| | | const parameterSelectDialogRef = |
| | | ref<InstanceType<typeof ParameterSelectDialog>>(); |
| | | |
| | | const getTitle = computed(() => `å·¥èºåæ°ç»å® - ${processName.value || ''}`); |
| | | |
| | | /** å 载工åºå·²ç»å®çåæ° */ |
| | | async function loadData() { |
| | | if (!processId.value) { |
| | | return; |
| | | } |
| | | loading.value = true; |
| | | try { |
| | | boundList.value = await getProcessParamListByProcess(processId.value); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | /** æå¼å·¥èºåæ°éæ©å¼¹çª */ |
| | | function handleSelectParameters() { |
| | | parameterSelectDialogRef.value?.open( |
| | | boundList.value |
| | | .map((item) => item.processParamId) |
| | | .filter((id): id is number => id !== undefined), |
| | | ); |
| | | } |
| | | |
| | | /** æ¥æ¶éä¸çåæ°ï¼è¿½å å°ç»å®å表ï¼å¿
å¡«/æåºèµ°é»è®¤å¼ï¼ */ |
| | | function onParametersSelected(rows: MesPdParameterApi.Parameter[]) { |
| | | const existingIds = new Set( |
| | | boundList.value |
| | | .map((item) => item.processParamId) |
| | | .filter((id): id is number => id !== undefined), |
| | | ); |
| | | const newRows = rows |
| | | .filter((row) => row.id !== undefined && !existingIds.has(row.id!)) |
| | | .map((row, index) => ({ |
| | | processParamId: row.id, |
| | | paramCode: row.paramCode, |
| | | paramName: row.paramName, |
| | | paramType: row.paramType, |
| | | unitMeasureName: row.unitMeasureName, |
| | | required: row.required, |
| | | sort: boundList.value.length + index + 1, |
| | | remark: row.remark, |
| | | })); |
| | | boundList.value = [...boundList.value, ...newRows]; |
| | | } |
| | | |
| | | /** ç§»é¤ç»å® */ |
| | | function removeItem(index: number) { |
| | | boundList.value.splice(index, 1); |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | if (processId.value === undefined) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | await updateProcessParams( |
| | | processId.value, |
| | | boundList.value.map((item, index) => ({ |
| | | processParamId: item.processParamId!, |
| | | required: item.required, |
| | | sort: item.sort ?? index + 1, |
| | | remark: item.remark, |
| | | })), |
| | | ); |
| | | message.success($t('ui.actionMessage.operationSuccess')); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | processId.value = undefined; |
| | | boundList.value = []; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ processId: number; processName?: string }>(); |
| | | processId.value = data.processId; |
| | | processName.value = data.processName || ''; |
| | | await loadData(); |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal :title="getTitle" class="w-4/5"> |
| | | <div class="mx-4"> |
| | | <div class="mb-2 flex items-center justify-between"> |
| | | <span class="text-sm font-medium">å·²ç»å®å·¥èºåæ°</span> |
| | | <Button type="primary" size="small" @click="handleSelectParameters"> |
| | | æ·»å åæ° |
| | | </Button> |
| | | </div> |
| | | <div v-if="boundList.length > 0" class="rounded border border-gray-200"> |
| | | <div |
| | | class="grid grid-cols-12 gap-2 border-b border-gray-200 bg-gray-50 p-2 text-xs font-medium" |
| | | > |
| | | <div class="col-span-3">åæ°åç§°</div> |
| | | <div class="col-span-2">åæ°ç¼ç </div> |
| | | <div class="col-span-2">åæ°ç±»å</div> |
| | | <div class="col-span-1">åä½</div> |
| | | <div class="col-span-1 text-center">æ¯å¦å¿
å¡«</div> |
| | | <div class="col-span-1">æåº</div> |
| | | <div class="col-span-1">夿³¨</div> |
| | | <div class="col-span-1 text-center">æä½</div> |
| | | </div> |
| | | <div |
| | | v-for="(item, index) in boundList" |
| | | :key="item.processParamId || index" |
| | | class="grid grid-cols-12 items-center gap-2 border-b border-gray-100 p-2" |
| | | > |
| | | <div class="col-span-3 text-sm">{{ item.paramName }}</div> |
| | | <div class="col-span-2 text-sm text-gray-500">{{ item.paramCode }}</div> |
| | | <div class="col-span-2"> |
| | | <DictTag |
| | | v-if="item.paramType !== undefined" |
| | | :type="DICT_TYPE.MES_PD_PARAM_TYPE" |
| | | :value="item.paramType" |
| | | /> |
| | | </div> |
| | | <div class="col-span-1 text-sm">{{ item.unitMeasureName }}</div> |
| | | <div class="col-span-1 flex items-center justify-center"> |
| | | <Switch v-model:checked="item.required" size="small" /> |
| | | </div> |
| | | <div class="col-span-1"> |
| | | <InputNumber |
| | | v-model:value="item.sort" |
| | | :min="1" |
| | | size="small" |
| | | class="w-full" |
| | | /> |
| | | </div> |
| | | <div class="col-span-1"> |
| | | <Input |
| | | v-model:value="item.remark" |
| | | placeholder="夿³¨" |
| | | size="small" |
| | | /> |
| | | </div> |
| | | <div class="col-span-1 flex items-center justify-center"> |
| | | <Button type="text" danger size="small" @click="removeItem(index)"> |
| | | å é¤ |
| | | </Button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div |
| | | v-else |
| | | class="rounded border border-dashed border-gray-300 p-4 text-center text-gray-400" |
| | | > |
| | | {{ loading ? 'å è½½ä¸â¦' : 'ææªç»å®åæ°' }} |
| | | </div> |
| | | </div> |
| | | <ParameterSelectDialog |
| | | ref="parameterSelectDialogRef" |
| | | @selected="onParametersSelected" |
| | | /> |
| | | </Modal> |
| | | </template> |