src/views/productionManagement/workOrder/components/ProductionRecordForm.vue
@@ -1,22 +1,31 @@
<script setup lang="ts">
import {computed, reactive, ref, watch} from "vue";
import {computed, reactive, ref, watch, withDefaults} from "vue";
defineOptions({
  name: "ProductionRecordForm"
});
const props = defineProps({
  list: {
    type: Array,
    default() {
      return [];
    }
  },
  labelWidth: {
    type: Number,
    default: 120
type DeviceOption = {
  id: string | number;
  deviceName: string;
  deviceCode?: string | number | null;
  rpm?: string | number | null;
};
const props = withDefaults(
  defineProps<{
    list: any[];
    labelWidth: number;
    deviceOptions: DeviceOption[];
    selectedDeviceId: string | number | null;
  }>(),
  {
    list: () => [],
    labelWidth: 120,
    deviceOptions: () => [],
    selectedDeviceId: null,
  }
});
);
const formRef = ref();
const formData = reactive({
@@ -32,6 +41,76 @@
const getType = (item: any) => item.type || "文本格式";
const machineSelectItem = computed(() => {
  return formData.list.find(item => getType(item) === '机台选择') || null;
});
const selectedDevice = computed(() => {
  const machineValue = machineSelectItem.value?.value;
  if (machineValue === null || machineValue === undefined || machineValue === '') return null;
  return props.deviceOptions.find(device => String(device.id) === String(machineValue)) || null;
});
const AUTO_DEVICE_CODE_ID = "__auto_deviceCode__";
const AUTO_RPM_ID = "__auto_rpm__";
let isSyncingAutoFields = false;
const syncAutoDeviceFields = () => {
  if (isSyncingAutoFields) return;
  isSyncingAutoFields = true;
  try {
    const machineIndex = formData.list.findIndex(item => getType(item) === "机台选择");
    if (machineIndex === -1) return;
  const removeById = (id: string) => {
    const idx = formData.list.findIndex(x => x?.id === id);
    if (idx !== -1) formData.list.splice(idx, 1);
  };
  removeById(AUTO_DEVICE_CODE_ID);
  removeById(AUTO_RPM_ID);
  const dev = selectedDevice.value as any;
  let insertPos = machineIndex + 1;
  const hasCode =
    dev &&
    dev.deviceCode !== null &&
    dev.deviceCode !== undefined &&
    String(dev.deviceCode) !== "";
  const hasRpm = dev && dev.rpm !== null && dev.rpm !== undefined;
    if (hasCode) {
    formData.list.splice(insertPos, 0, {
      id: AUTO_DEVICE_CODE_ID,
      parameterItem: "设备编号",
      value: dev.deviceCode,
      // 只读展示:避免影响后端参数结构(submitData 会过滤)
      readonly: true,
      isRequired: "0",
      __autoExtra: true,
    });
    insertPos++;
  }
    if (hasRpm) {
    formData.list.splice(insertPos, 0, {
      id: AUTO_RPM_ID,
      parameterItem: "转数",
      value: dev.rpm,
      readonly: true,
      isRequired: "0",
      __autoExtra: true,
    });
  }
  } finally {
    isSyncingAutoFields = false;
  }
};
const rules = computed(() => {
  const result: Record<string, any[]> = {};
  formData.list.forEach((item, index) => {
@@ -43,10 +122,15 @@
});
const initData = () => {
  formData.list = props.list || [];
  // 重要:不要直接复用 props.list 的引用,否则后续 splice formData.list 会触发 props watch,导致递归更新
  formData.list = (props.list || []).map(item => ({ ...item }));
  formData.list.forEach(item => {
    if (item.value === undefined) {
      item.value = null;
    }
    // 如果参数中存在“机台选择”,则使用父组件传入的默认机台回填
    if (getType(item) === '机台选择' && (item.value === null || item.value === undefined || item.value === '')) {
      item.value = props.selectedDeviceId ?? item.value;
    }
  });
};
@@ -55,7 +139,8 @@
  const valid = await formRef.value.validate().catch(() => false)
  if (valid) {
    return formData.list
    // 自动插入的只读字段不参与提交,避免后端参数结构变化
    return formData.list.filter(item => !item.__autoExtra)
  } else {
    return null
  }
@@ -65,8 +150,18 @@
    () => props.list,
    () => {
      initData();
      // 初始化后再同步自动插入字段
      syncAutoDeviceFields();
    },
    {immediate: true, deep: true}
);
watch(
  () => selectedDevice.value,
  () => {
    syncAutoDeviceFields();
  },
  { immediate: true }
);
defineExpose({
@@ -76,9 +171,11 @@
<template>
  <el-form ref="formRef" :model="formData" :rules="rules" :label-width="`${labelWidth}px`">
    <el-row :gutter="30">
      <el-col :span="12" v-for="(item, index) in formData.list"
    :key="item.id">
    <el-form-item
        v-for="(item, index) in formData.list"
        :key="item.id"
        :label="fieldLabel(item)"
        :prop="`list.${index}.value`"
    >
@@ -117,12 +214,29 @@
        <el-option label="是" value="是"/>
        <el-option label="否" value="否"/>
      </el-select>
      <el-select
          v-else-if="getType(item) === '机台选择'"
          v-model="item.value"
          placeholder="请选择"
          clearable
          style="width: 100%"
      >
        <el-option
          v-for="device in props.deviceOptions"
          :key="device.id"
          :label="device.deviceName"
          :value="device.id"
        />
      </el-select>
      <el-input
          v-else
          v-model="item.value"
          placeholder="请输入"
          clearable
          :disabled="item.readonly"
          :clearable="!item.readonly"
      />
    </el-form-item>
  </el-col>
    </el-row>
  </el-form>
</template>