张诺
9 小时以前 8657873b0a4c57904bcecdab121f6b261c92ef6e
feat(productionProcess): 新增工序编辑和新增功能

- 创建 Edit.vue 组件实现工序编辑功能
- 创建 New.vue 组件实现工序新增功能
- 添加工序编号、名称、机台、报工人等表单字段
- 集成设备选择下拉框支持远程搜索和分页加载
- 实现报工人多选功能并关联用户列表
- 添加是否质检开关和备注文本域
- 在工序列表页面添加报工人列显示
已修改3个文件
144 ■■■■■ 文件已修改
src/views/productionManagement/productionProcess/Edit.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionProcess/New.vue 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionProcess/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionProcess/Edit.vue
@@ -74,6 +74,35 @@
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="报工人"
            prop="ids"
            :rules="[
              {
                required: true,
                message: '请选择报工人',
                trigger: 'change',
              }
            ]"
        >
          <el-select
              v-model="formState.ids"
              multiple
              filterable
              clearable
              collapse-tags
              collapse-tags-tooltip
              placeholder="请选择报工人"
              @change="handleReportUsersChange"
          >
            <el-option
                v-for="item in userOptions"
                :key="item.userId"
                :label="item.nickName"
                :value="item.userId"
            />
          </el-select>
        </el-form-item>
<!--        <el-form-item-->
<!--            label="工序类型"-->
<!--            prop="type"-->
@@ -110,9 +139,10 @@
</template>
<script setup>
import { ref, computed, getCurrentInstance, watch, reactive, nextTick, onBeforeUnmount } from "vue";
import { ref, computed, getCurrentInstance, watch, reactive, nextTick, onBeforeUnmount, onMounted } from "vue";
import { update } from "@/api/productionManagement/productionProcess.js";
import { getLedgerPage } from "@/api/equipmentManagement/ledger.js";
import { userListNoPageByTenantId } from "@/api/system/user.js";
const props = defineProps({
  visible: {
@@ -136,6 +166,8 @@
  no: props.record.no,
  deviceId: props.record.deviceId,
  deviceName: props.record.deviceName,
  ids: [],
  reportWorkerList: [],
  remark: props.record.remark,
  salaryQuota: props.record.salaryQuota,
  isQuality: props.record.isQuality,
@@ -152,6 +184,7 @@
const deviceQuery = ref("");
const deviceScrollWrap = ref(null);
const __deviceLoadMoreSentinel = "__deviceLoadMoreSentinel";
const userOptions = ref([]);
const deviceHasMore = computed(() => {
  const total = Number(page.total ?? 0);
@@ -163,6 +196,36 @@
const handleDeviceChange = (val) => {
  formState.value.deviceName = equipmentList.value.find(item => item.id === val)?.deviceName || "";
};
const normalizeReportUserIds = (record) => {
  const raw = record?.ids;
  if (Array.isArray(raw)) {
    return raw.map(item => item?.userId ?? item).filter(Boolean);
  }
  if (typeof raw === "string") {
    return raw.split(/[,,;;\s]+/g).map(item => item.trim()).filter(Boolean);
  }
  if (Array.isArray(record?.reportWorkerList)) {
    return record.reportWorkerList.map(item => item?.userId).filter(Boolean);
  }
  return [];
};
const handleReportUsersChange = (val) => {
  const userMap = new Map(userOptions.value.map(item => [item.userId, item.nickName]));
  formState.value.reportWorkerList = (val || []).map(userId => ({
    userId,
    userName: userMap.get(userId) || "",
  }));
};
const getUserOptions = async () => {
  const res = await userListNoPageByTenantId();
  userOptions.value = Array.isArray(res?.data) ? res.data : [];
  if (formState.value.ids?.length) {
    handleReportUsersChange(formState.value.ids);
  }
};
const isShow = computed({
@@ -278,6 +341,7 @@
};
const applyRecordToForm = (record) => {
  const ids = normalizeReportUserIds(record);
  formState.value = {
    id: record.id,
    name: record.name || "",
@@ -285,10 +349,15 @@
    type: record.type,
    deviceId: record.deviceId,
    deviceName: record.deviceName || "",
    ids,
    reportWorkerList: Array.isArray(record.reportWorkerList) ? record.reportWorkerList : [],
    remark: record.remark || "",
    salaryQuota: record.salaryQuota || "",
    isQuality: record.isQuality,
  };
  if (!formState.value.reportWorkerList.length && ids.length) {
    handleReportUsersChange(ids);
  }
  ensureSelectedDeviceOption();
};
@@ -306,6 +375,10 @@
let { proxy } = getCurrentInstance()
onMounted(() => {
  getUserOptions();
});
const closeModal = () => {
  isShow.value = false;
};
@@ -313,6 +386,7 @@
const handleSubmit = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      handleReportUsersChange(formState.value.ids);
      update(formState.value).then(() => {
        // 关闭模态框
        isShow.value = false;
src/views/productionManagement/productionProcess/New.vue
@@ -39,13 +39,6 @@
        </el-form-item>
        <el-form-item
            label="工序机台"
            prop="deviceId"
            :rules="[
                {
                required: true,
                message: '请选择工序机台',
              }
            ]"
        >
          <el-select
              v-model="formState.deviceId"
@@ -67,6 +60,35 @@
                :value="__deviceLoadMoreSentinel"
                label="加载更多…"
                disabled
            />
          </el-select>
        </el-form-item>
        <el-form-item
            label="报工人"
            prop="ids"
            :rules="[
              {
                required: true,
                message: '请选择报工人',
                trigger: 'change',
              }
            ]"
        >
          <el-select
              v-model="formState.ids"
              multiple
              filterable
              clearable
              collapse-tags
              collapse-tags-tooltip
              placeholder="请选择报工人"
              @change="handleReportUsersChange"
          >
            <el-option
                v-for="item in userOptions"
                :key="item.userId"
                :label="item.nickName"
                :value="item.userId"
            />
          </el-select>
        </el-form-item>
@@ -111,6 +133,7 @@
import { ref, computed, onMounted, getCurrentInstance, reactive, nextTick, onBeforeUnmount } from "vue";
import {add} from "@/api/productionManagement/productionProcess.js";
import {getLedgerPage} from "@/api/equipmentManagement/ledger.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
const props = defineProps({
  visible: {
@@ -123,7 +146,12 @@
// 响应式数据(替代选项式的 data)
const formState = ref({
  no: "",
  name: '',
  deviceId: "",
  deviceName: "",
  ids: [],
  reportWorkerList: [],
  type: 0,
  remark: '',
  salaryQuota:  '',
@@ -139,10 +167,26 @@
onMounted(() => {
  resetDeviceOptions();
  getUserOptions();
});
const handleDeviceChange = (val) => {
  formState.value.deviceName = equipmentList.value.find(item => item.id === val)?.deviceName || '';
};
const userOptions = ref([]);
const handleReportUsersChange = (val) => {
  const userMap = new Map(userOptions.value.map(item => [item.userId, item.nickName]));
  formState.value.reportWorkerList = (val || []).map(userId => ({
    userId,
    userName: userMap.get(userId) || "",
  }));
};
const getUserOptions = async () => {
  const res = await userListNoPageByTenantId();
  userOptions.value = Array.isArray(res?.data) ? res.data : [];
};
const isShow = computed({
@@ -269,6 +313,7 @@
const handleSubmit = () => {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      handleReportUsersChange(formState.value.ids);
      add(formState.value).then(res => {
        // 关闭模态框
        isShow.value = false;
src/views/productionManagement/productionProcess/index.vue
@@ -103,6 +103,15 @@
      label: "工序机台",
      prop: "deviceName",
    },
    {
      label: "报工人",
      prop: "userNames",
      dataType: 'tag',
      formatData: (params) => {
        if (!params) return []
        return params.split(',')
      }
    },
    // {
    //   label: "工资定额",
    //   prop: "salaryQuota",