zhangwencui
2026-04-30 3fa1df3286670f5480fc1eca31ef81d30b6865f5
已结束订单的报工扫码限制,以及一些废弃接口处理
已修改5个文件
1405 ■■■■ 文件已修改
src/pages/productionManagement/productionDispatching/components/DispatchModal.vue 708 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/components/formDia.vue 265 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/index.vue 421 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionOrder/index.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/works.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/components/DispatchModal.vue
@@ -1,399 +1,379 @@
<template>
    <up-popup
        v-model:show="show"
        mode="bottom"
        :round="20"
        :safeAreaInsetBottom="true"
        @close="handleClose"
        @open="handleOpen"
    >
        <view class="dispatch-modal">
            <!-- 头部 -->
            <view class="modal-header">
                <text class="modal-title">生产派工</text>
                <view class="close-btn" @click="handleClose">
                    <up-icon name="close" size="20" color="#999"></up-icon>
                </view>
            </view>
            <!-- 表单内容 -->
            <view class="modal-content">
                <up-form
                    :model="form"
                    ref="formRef"
                    :rules="rules"
                    labelWidth="120"
                >
                    <!-- 项目基本信息 -->
                    <view class="form-section">
                        <text class="section-title">项目信息</text>
                        <up-form-item label="项目名称" prop="projectName">
                            <up-input
                                v-model="form.projectName"
                                disabled
                                placeholder="项目名称"
                            />
                        </up-form-item>
                        <up-form-item label="产品大类" prop="productCategory">
                            <up-input
                                v-model="form.productCategory"
                                disabled
                                placeholder="产品大类"
                            />
                        </up-form-item>
                    </view>
                    <!-- 数量信息 -->
                    <view class="form-section">
                        <text class="section-title">数量信息</text>
                        <up-form-item label="总数量" prop="quantity">
                            <up-input
                                v-model="form.quantity"
                                disabled
                                placeholder="总数量"
                            />
                        </up-form-item>
                        <up-form-item label="待排产数量" prop="pendingQuantity">
                            <up-input
                                v-model="form.pendingQuantity"
                                disabled
                                placeholder="待排产数量"
                            />
                        </up-form-item>
                        <up-form-item label="本次排产数量" prop="schedulingNum" required>
                            <up-number-box
                                v-model="form.schedulingNum"
                                :min="0"
                                :max="form.pendingQuantity"
                                :step="0.1"
                                :precision="2"
                                @change="handleNumChange"
                            />
                        </up-form-item>
                    </view>
                    <!-- 派工信息 -->
                    <view class="form-section">
                        <text class="section-title">派工信息</text>
                        <up-form-item label="派工人" prop="schedulingUserId" required>
                            <up-input
                                v-model="selectedUserName"
                                placeholder="请选择派工人"
                                readonly
                                @click="showUserPicker = true"
                                suffixIcon="arrow-down"
                            />
                        </up-form-item>
                        <up-form-item label="派工日期" prop="schedulingDate" required>
                            <up-input
                                v-model="form.schedulingDate"
                                placeholder="请选择派工日期"
                                readonly
                                @click="showDatePicker = true"
                                suffixIcon="calendar"
                            />
                        </up-form-item>
                    </view>
                </up-form>
            </view>
            <!-- 底部按钮 -->
            <view class="modal-footer">
                <up-button
                    @click="handleClose"
                    text="取消"
                    type="info"
                    plain
                    :customStyle="{ marginRight: '12px', flex: 1 }"
                />
                <up-button
                    @click="handleConfirm"
                    text="确认派工"
                    type="primary"
                    :customStyle="{ flex: 1 }"
                    :loading="submitting"
                />
            </view>
        </view>
        <!-- 人员选择器 -->
        <up-picker
            v-model="showUserPicker"
            :columns="userColumns"
            @confirm="handleUserSelect"
            @cancel="showUserPicker = false"
        />
        <!-- 日期选择器 -->
        <up-datetime-picker
            v-model="showDatePicker"
            mode="date"
            @confirm="handleDateSelect"
            @cancel="showDatePicker = false"
        />
    </up-popup>
  <up-popup v-model:show="show"
            mode="bottom"
            :round="20"
            :safeAreaInsetBottom="true"
            @close="handleClose"
            @open="handleOpen">
    <view class="dispatch-modal">
      <!-- 头部 -->
      <view class="modal-header">
        <text class="modal-title">生产派工</text>
        <view class="close-btn"
              @click="handleClose">
          <up-icon name="close"
                   size="20"
                   color="#999"></up-icon>
        </view>
      </view>
      <!-- 表单内容 -->
      <view class="modal-content">
        <up-form :model="form"
                 ref="formRef"
                 :rules="rules"
                 labelWidth="120">
          <!-- 项目基本信息 -->
          <view class="form-section">
            <text class="section-title">项目信息</text>
            <up-form-item label="项目名称"
                          prop="projectName">
              <up-input v-model="form.projectName"
                        disabled
                        placeholder="项目名称" />
            </up-form-item>
            <up-form-item label="产品大类"
                          prop="productCategory">
              <up-input v-model="form.productCategory"
                        disabled
                        placeholder="产品大类" />
            </up-form-item>
          </view>
          <!-- 数量信息 -->
          <view class="form-section">
            <text class="section-title">数量信息</text>
            <up-form-item label="总数量"
                          prop="quantity">
              <up-input v-model="form.quantity"
                        disabled
                        placeholder="总数量" />
            </up-form-item>
            <up-form-item label="待排产数量"
                          prop="pendingQuantity">
              <up-input v-model="form.pendingQuantity"
                        disabled
                        placeholder="待排产数量" />
            </up-form-item>
            <up-form-item label="本次排产数量"
                          prop="schedulingNum"
                          required>
              <up-number-box v-model="form.schedulingNum"
                             :min="0"
                             :max="form.pendingQuantity"
                             :step="0.1"
                             :precision="2"
                             @change="handleNumChange" />
            </up-form-item>
          </view>
          <!-- 派工信息 -->
          <view class="form-section">
            <text class="section-title">派工信息</text>
            <up-form-item label="派工人"
                          prop="schedulingUserId"
                          required>
              <up-input v-model="selectedUserName"
                        placeholder="请选择派工人"
                        readonly
                        @click="showUserPicker = true"
                        suffixIcon="arrow-down" />
            </up-form-item>
            <up-form-item label="派工日期"
                          prop="schedulingDate"
                          required>
              <up-input v-model="form.schedulingDate"
                        placeholder="请选择派工日期"
                        readonly
                        @click="showDatePicker = true"
                        suffixIcon="calendar" />
            </up-form-item>
          </view>
        </up-form>
      </view>
      <!-- 底部按钮 -->
      <view class="modal-footer">
        <up-button @click="handleClose"
                   text="取消"
                   type="info"
                   plain
                   :customStyle="{ marginRight: '12px', flex: 1 }" />
        <up-button @click="handleConfirm"
                   text="确认派工"
                   type="primary"
                   :customStyle="{ flex: 1 }"
                   :loading="submitting" />
      </view>
    </view>
    <!-- 人员选择器 -->
    <up-picker v-model="showUserPicker"
               :columns="userColumns"
               @confirm="handleUserSelect"
               @cancel="showUserPicker = false" />
    <!-- 日期选择器 -->
    <up-datetime-picker v-model="showDatePicker"
                        mode="date"
                        @confirm="handleDateSelect"
                        @cancel="showDatePicker = false" />
  </up-popup>
</template>
<script setup>
import { ref, reactive, computed, getCurrentInstance } from 'vue';
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { productionDispatch } from "@/api/productionManagement/productionOrder.js";
import useUserStore from "@/store/modules/user";
import dayjs from "dayjs";
  import { ref, reactive, computed, getCurrentInstance } from "vue";
  import { userListNoPageByTenantId } from "@/api/system/user.js";
  // import { productionDispatch } from "@/api/productionManagement/productionOrder.js";
  import useUserStore from "@/store/modules/user";
  import dayjs from "dayjs";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const emit = defineEmits(['confirm']);
  const { proxy } = getCurrentInstance();
  const userStore = useUserStore();
  const emit = defineEmits(["confirm"]);
// 弹窗显示状态
const show = ref(false);
const submitting = ref(false);
  // 弹窗显示状态
  const show = ref(false);
  const submitting = ref(false);
// 选择器显示状态
const showUserPicker = ref(false);
const showDatePicker = ref(false);
  // 选择器显示状态
  const showUserPicker = ref(false);
  const showDatePicker = ref(false);
// 用户列表
const userList = ref([]);
const userColumns = computed(() => [
    userList.value.map(user => ({
        label: user.nickName,
        value: user.userId
    }))
]);
  // 用户列表
  const userList = ref([]);
  const userColumns = computed(() => [
    userList.value.map(user => ({
      label: user.nickName,
      value: user.userId,
    })),
  ]);
// 选中的用户名称(用于显示)
const selectedUserName = computed(() => {
    const user = userList.value.find(u => u.userId === form.schedulingUserId);
    return user ? user.nickName : '';
});
  // 选中的用户名称(用于显示)
  const selectedUserName = computed(() => {
    const user = userList.value.find(u => u.userId === form.schedulingUserId);
    return user ? user.nickName : "";
  });
// 表单数据
const form = reactive({
    projectName: "",
    productCategory: "",
    quantity: "",
    schedulingNum: 0,
    schedulingUserId: "",
    schedulingDate: "",
    pendingQuantity: 0,
    id: "" // 原始记录ID
});
  // 表单数据
  const form = reactive({
    projectName: "",
    productCategory: "",
    quantity: "",
    schedulingNum: 0,
    schedulingUserId: "",
    schedulingDate: "",
    pendingQuantity: 0,
    id: "", // 原始记录ID
  });
// 表单验证规则
const rules = reactive({
    schedulingNum: [
        { required: true, message: "请输入排产数量", trigger: "blur" }
    ],
    schedulingUserId: [
        { required: true, message: "请选择派工人", trigger: "change" }
    ],
    schedulingDate: [
        { required: true, message: "请选择派工日期", trigger: "change" }
    ]
});
  // 表单验证规则
  const rules = reactive({
    schedulingNum: [
      { required: true, message: "请输入排产数量", trigger: "blur" },
    ],
    schedulingUserId: [
      { required: true, message: "请选择派工人", trigger: "change" },
    ],
    schedulingDate: [
      { required: true, message: "请选择派工日期", trigger: "change" },
    ],
  });
// 表单引用
const formRef = ref();
  // 表单引用
  const formRef = ref();
// 打开弹窗
const open = async (rowData) => {
    try {
        // 加载用户列表
        const res = await userListNoPageByTenantId();
        userList.value = res.data || [];
        // 填充表单数据
        Object.assign(form, {
            ...rowData,
            schedulingNum: 0,
            schedulingUserId: userStore.id,
            schedulingDate: dayjs().format("YYYY-MM-DD")
        });
        show.value = true;
    } catch (error) {
        uni.showToast({
            title: '加载用户列表失败',
            icon: 'error'
        });
    }
};
  // 打开弹窗
  const open = async rowData => {
    try {
      // 加载用户列表
      const res = await userListNoPageByTenantId();
      userList.value = res.data || [];
// 处理数量变化
const handleNumChange = (value) => {
    if (value > form.pendingQuantity) {
        form.schedulingNum = form.pendingQuantity;
        uni.showToast({
            title: '排产数量不可大于待排产数量',
            icon: 'none'
        });
    }
};
      // 填充表单数据
      Object.assign(form, {
        ...rowData,
        schedulingNum: 0,
        schedulingUserId: userStore.id,
        schedulingDate: dayjs().format("YYYY-MM-DD"),
      });
// 处理用户选择
const handleUserSelect = (params) => {
    if (params.value && params.value.length > 0) {
        form.schedulingUserId = params.value[0];
    }
    showUserPicker.value = false;
};
      show.value = true;
    } catch (error) {
      uni.showToast({
        title: "加载用户列表失败",
        icon: "error",
      });
    }
  };
// 处理日期选择
const handleDateSelect = (params) => {
    if (params.value) {
        form.schedulingDate = dayjs(params.value).format("YYYY-MM-DD");
    }
    showDatePicker.value = false;
};
  // 处理数量变化
  const handleNumChange = value => {
    if (value > form.pendingQuantity) {
      form.schedulingNum = form.pendingQuantity;
      uni.showToast({
        title: "排产数量不可大于待排产数量",
        icon: "none",
      });
    }
  };
// 确认派工
const handleConfirm = async () => {
    try {
        // 表单验证
        const valid = await formRef.value?.validate();
        if (!valid) return;
        if (form.schedulingNum <= 0) {
            uni.showToast({
                title: '排产数量必须大于0',
                icon: 'none'
            });
            return;
        }
        submitting.value = true;
        // 提交派工数据
        await productionDispatch(form);
        uni.showToast({
            title: '派工成功',
            icon: 'success'
        });
        handleClose();
        emit('confirm');
    } catch (error) {
        uni.showToast({
            title: '派工失败',
            icon: 'error'
        });
    } finally {
        submitting.value = false;
    }
};
  // 处理用户选择
  const handleUserSelect = params => {
    if (params.value && params.value.length > 0) {
      form.schedulingUserId = params.value[0];
    }
    showUserPicker.value = false;
  };
// 弹窗打开事件
const handleOpen = () => {
    // 弹窗打开时的处理
};
  // 处理日期选择
  const handleDateSelect = params => {
    if (params.value) {
      form.schedulingDate = dayjs(params.value).format("YYYY-MM-DD");
    }
    showDatePicker.value = false;
  };
// 关闭弹窗
const handleClose = () => {
    show.value = false;
    showUserPicker.value = false;
    showDatePicker.value = false;
    // 重置表单
    Object.assign(form, {
        projectName: "",
        productCategory: "",
        quantity: "",
        schedulingNum: 0,
        schedulingUserId: "",
        schedulingDate: "",
        pendingQuantity: 0,
        id: ""
    });
};
  // 确认派工
  const handleConfirm = async () => {
    try {
      // 表单验证
      const valid = await formRef.value?.validate();
      if (!valid) return;
// 暴露方法
defineExpose({
    open
});
      if (form.schedulingNum <= 0) {
        uni.showToast({
          title: "排产数量必须大于0",
          icon: "none",
        });
        return;
      }
      submitting.value = true;
      // 提交派工数据
      // await productionDispatch(form);
      uni.showToast({
        title: "派工成功",
        icon: "success",
      });
      handleClose();
      emit("confirm");
    } catch (error) {
      uni.showToast({
        title: "派工失败",
        icon: "error",
      });
    } finally {
      submitting.value = false;
    }
  };
  // 弹窗打开事件
  const handleOpen = () => {
    // 弹窗打开时的处理
  };
  // 关闭弹窗
  const handleClose = () => {
    show.value = false;
    showUserPicker.value = false;
    showDatePicker.value = false;
    // 重置表单
    Object.assign(form, {
      projectName: "",
      productCategory: "",
      quantity: "",
      schedulingNum: 0,
      schedulingUserId: "",
      schedulingDate: "",
      pendingQuantity: 0,
      id: "",
    });
  };
  // 暴露方法
  defineExpose({
    open,
  });
</script>
<style scoped lang="scss">
.dispatch-modal {
    background: #ffffff;
    border-radius: 20px 20px 0 0;
    max-height: 80vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
  .dispatch-modal {
    background: #ffffff;
    border-radius: 20px 20px 0 0;
    max-height: 80vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 20px 0 20px;
    border-bottom: 1px solid #f0f0f0;
    padding-bottom: 16px;
    margin-bottom: 20px;
}
  .modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 20px 0 20px;
    border-bottom: 1px solid #f0f0f0;
    padding-bottom: 16px;
    margin-bottom: 20px;
  }
.modal-title {
    font-size: 18px;
    font-weight: 600;
    color: #333;
}
  .modal-title {
    font-size: 18px;
    font-weight: 600;
    color: #333;
  }
.close-btn {
    padding: 4px;
    &:active {
        opacity: 0.7;
    }
}
  .close-btn {
    padding: 4px;
.modal-content {
    flex: 1;
    padding: 0 20px;
    overflow-y: auto;
}
    &:active {
      opacity: 0.7;
    }
  }
.form-section {
    margin-bottom: 24px;
}
  .modal-content {
    flex: 1;
    padding: 0 20px;
    overflow-y: auto;
  }
.section-title {
    display: block;
    font-size: 16px;
    font-weight: 600;
    color: #333;
    margin-bottom: 16px;
    padding-left: 8px;
    border-left: 3px solid #2979ff;
}
  .form-section {
    margin-bottom: 24px;
  }
.modal-footer {
    display: flex;
    gap: 12px;
    padding: 20px;
    border-top: 1px solid #f0f0f0;
    background: #fafafa;
}
  .section-title {
    display: block;
    font-size: 16px;
    font-weight: 600;
    color: #333;
    margin-bottom: 16px;
    padding-left: 8px;
    border-left: 3px solid #2979ff;
  }
// uView 组件样式调整
:deep(.up-form-item) {
    margin-bottom: 20px;
}
  .modal-footer {
    display: flex;
    gap: 12px;
    padding: 20px;
    border-top: 1px solid #f0f0f0;
    background: #fafafa;
  }
:deep(.up-input) {
    background: #f8f9fa;
    border-radius: 8px;
}
  // uView 组件样式调整
  :deep(.up-form-item) {
    margin-bottom: 20px;
  }
:deep(.up-input--disabled) {
    background: #f0f0f0;
    color: #999;
}
  :deep(.up-input) {
    background: #f8f9fa;
    border-radius: 8px;
  }
:deep(.up-number-box) {
    background: #f8f9fa;
    border-radius: 8px;
}
  :deep(.up-input--disabled) {
    background: #f0f0f0;
    color: #999;
  }
  :deep(.up-number-box) {
    background: #f8f9fa;
    border-radius: 8px;
  }
</style>
src/pages/productionManagement/productionDispatching/components/formDia.vue
@@ -1,87 +1,101 @@
<template>
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        title="生产派工"
        width="50%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
    <el-dialog v-model="dialogFormVisible"
               title="生产派工"
               width="50%"
               @close="closeDia">
      <el-form :model="form"
               label-width="140px"
               label-position="top"
               :rules="rules"
               ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="项目名称:" prop="projectName">
              <el-input v-model="form.projectName" placeholder="请输入" clearable disabled/>
            <el-form-item label="项目名称:"
                          prop="projectName">
              <el-input v-model="form.projectName"
                        placeholder="请输入"
                        clearable
                        disabled />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="产品大类:" prop="productCategory">
              <el-input v-model="form.productCategory" placeholder="请输入" clearable disabled/>
            <el-form-item label="产品大类:"
                          prop="productCategory">
              <el-input v-model="form.productCategory"
                        placeholder="请输入"
                        clearable
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="总数量:" prop="quantity">
              <el-input v-model="form.quantity" placeholder="请输入" clearable disabled/>
            <el-form-item label="总数量:"
                          prop="quantity">
              <el-input v-model="form.quantity"
                        placeholder="请输入"
                        clearable
                        disabled />
            </el-form-item>
          </el-col>
          <el-col :span="12">
                        <el-form-item label="待排产数量:" prop="pendingQuantity">
                            <el-input v-model="form.pendingQuantity" placeholder="请输入" clearable disabled/>
                        </el-form-item>
            <el-form-item label="待排产数量:"
                          prop="pendingQuantity">
              <el-input v-model="form.pendingQuantity"
                        placeholder="请输入"
                        clearable
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
                        <el-form-item label="本次排产数量:" prop="schedulingNum">
                            <el-input-number
                                v-model="form.schedulingNum"
                                placeholder="请输入"
                                :min="0"
                                :step="0.1"
                                :precision="2"
                                clearable
                                @change="changeNum"
                                style="width: 100%"
                            />
                        </el-form-item>
            <el-form-item label="本次排产数量:"
                          prop="schedulingNum">
              <el-input-number v-model="form.schedulingNum"
                               placeholder="请输入"
                               :min="0"
                               :step="0.1"
                               :precision="2"
                               clearable
                               @change="changeNum"
                               style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="派工人:" prop="schedulingUserId">
                            <el-select
                                v-model="form.schedulingUserId"
                                placeholder="选择人员"
                                style="width: 100%;"
                            >
                                <el-option
                                    v-for="user in userList"
                                    :key="user.userId"
                                    :label="user.nickName"
                                    :value="user.userId"
                                />
                            </el-select>
                        </el-form-item>
                    </el-col>
          <el-col :span="12">
            <el-form-item label="派工日期:" prop="schedulingDate">
              <el-date-picker
                  v-model="form.schedulingDate"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            <el-form-item label="派工人:"
                          prop="schedulingUserId">
              <el-select v-model="form.schedulingUserId"
                         placeholder="选择人员"
                         style="width: 100%;">
                <el-option v-for="user in userList"
                           :key="user.userId"
                           :label="user.nickName"
                           :value="user.userId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="派工日期:"
                          prop="schedulingDate">
              <el-date-picker v-model="form.schedulingDate"
                              type="date"
                              placeholder="请选择日期"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              clearable
                              style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button type="primary"
                     @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
@@ -90,80 +104,85 @@
</template>
<script setup>
import {ref} from "vue";
import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
import useUserStore from "@/store/modules/user";
import dayjs from "dayjs";
const { proxy } = getCurrentInstance()
const emit = defineEmits(['close'])
  import { ref } from "vue";
  import {
    getStaffJoinInfo,
    staffJoinAdd,
    staffJoinUpdate,
  } from "@/api/personnelManagement/onboarding.js";
  import { userListNoPageByTenantId } from "@/api/system/user.js";
  // import {productionDispatch} from "@/api/productionManagement/productionOrder.js";
  import useUserStore from "@/store/modules/user";
  import dayjs from "dayjs";
  const { proxy } = getCurrentInstance();
  const emit = defineEmits(["close"]);
const dialogFormVisible = ref(false);
const operationType = ref('')
const data = reactive({
  form: {
        projectName: "",
        productCategory: "",
        quantity: "",
        schedulingNum: "",
        schedulingUserId: "",
        schedulingDate: "",
        pendingQuantity: "",
  },
  rules: {
        schedulingNum: [{ required: true, message: "请输入", trigger: "blur" },],
        schedulingUserId: [{ required: true, message: "请选择", trigger: "change" },],
        schedulingDate: [{ required: true, message: "请选择", trigger: "change" },],
  },
});
const { form, rules } = toRefs(data);
const userList = ref([])
const userStore = useUserStore()
  const dialogFormVisible = ref(false);
  const operationType = ref("");
  const data = reactive({
    form: {
      projectName: "",
      productCategory: "",
      quantity: "",
      schedulingNum: "",
      schedulingUserId: "",
      schedulingDate: "",
      pendingQuantity: "",
    },
    rules: {
      schedulingNum: [{ required: true, message: "请输入", trigger: "blur" }],
      schedulingUserId: [
        { required: true, message: "请选择", trigger: "change" },
      ],
      schedulingDate: [{ required: true, message: "请选择", trigger: "change" }],
    },
  });
  const { form, rules } = toRefs(data);
  const userList = ref([]);
  const userStore = useUserStore();
// 打开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
    userListNoPageByTenantId().then((res) => {
        userList.value = res.data;
    });
    form.value = {...row}
    form.value.schedulingNum = 0
    form.value.schedulingUserId = userStore.id
    form.value.schedulingDate = dayjs().format("YYYY-MM-DD");
}
  // 打开弹框
  const openDialog = (type, row) => {
    operationType.value = type;
    dialogFormVisible.value = true;
    userListNoPageByTenantId().then(res => {
      userList.value = res.data;
    });
    form.value = { ...row };
    form.value.schedulingNum = 0;
    form.value.schedulingUserId = userStore.id;
    form.value.schedulingDate = dayjs().format("YYYY-MM-DD");
  };
//
const changeNum = (value) => {
    if (value > form.value.pendingQuantity) {
        form.value.schedulingNum = form.value.pendingQuantity;
        proxy.$modal.msgWarning('排产数量不可大于待排产数量')
    }
}
// 提交产品表单
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
            productionDispatch(form.value).then(res => {
                proxy.$modal.msgSuccess("提交成功");
                closeDia();
            })
  //
  const changeNum = value => {
    if (value > form.value.pendingQuantity) {
      form.value.schedulingNum = form.value.pendingQuantity;
      proxy.$modal.msgWarning("排产数量不可大于待排产数量");
    }
  })
}
  };
  // 提交产品表单
  const submitForm = () => {
    proxy.$refs.formRef.validate(valid => {
      if (valid) {
        // productionDispatch(form.value).then(res => {
        //     proxy.$modal.msgSuccess("提交成功");
        //     closeDia();
        // })
      }
    });
  };
// 关闭弹框
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
  emit('close')
};
defineExpose({
  openDialog,
});
  // 关闭弹框
  const closeDia = () => {
    proxy.resetForm("formRef");
    dialogFormVisible.value = false;
    emit("close");
  };
  defineExpose({
    openDialog,
  });
</script>
<style scoped>
</style>
src/pages/productionManagement/productionDispatching/index.vue
@@ -1,235 +1,236 @@
<template>
    <view class="production-dispatching">
        <!-- 使用通用页面头部组件 -->
        <PageHeader title="生产派工" @back="goBack" />
        <!-- 搜索区域 -->
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <up-input
                        class="search-text"
                        placeholder="请输入客户名称搜索"
                        v-model="searchForm.customerName"
                        @change="handleQuery"
                        clearable
                    />
                </view>
                <view class="filter-button" @click="handleQuery">
                    <up-icon name="search" size="24" color="#999"></up-icon>
                </view>
            </view>
        </view>
        <!-- 生产派工列表 -->
        <view class="ledger-list" v-if="tableData.length > 0">
            <view v-for="(item, index) in tableData" :key="item.id || index">
                <view class="ledger-item">
                    <view class="item-header">
                        <view class="item-left">
                            <view class="document-icon">
                                <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
                            </view>
                            <text class="item-id">{{ item.salesContractNo }}</text>
                        </view>
                    </view>
                    <up-divider></up-divider>
                    <view class="item-details">
                        <view class="detail-row">
                            <text class="detail-label">录入日期</text>
                            <text class="detail-value">{{ item.entryDate }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">客户合同号</text>
                            <text class="detail-value">{{ item.customerContractNo }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">客户名称</text>
                            <text class="detail-value">{{ item.customerName }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">项目名称</text>
                            <text class="detail-value">{{ item.projectName }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">产品大类</text>
                            <text class="detail-value">{{ item.productCategory }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">规格型号</text>
                            <text class="detail-value">{{ item.specificationModel }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">总数量</text>
                            <text class="detail-value">{{ item.quantity }} {{ item.unit }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">排产数量</text>
                            <text class="detail-value highlight">{{ item.schedulingNum }}</text>
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">待排数量</text>
                            <text class="detail-value" :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
                        </view>
                    </view>
                    <!-- 操作按钮区域 -->
                    <view class="action-buttons">
                        <up-button
                            type="primary"
                            size="small"
                            @click="handleDispatch(item)"
                            class="action-btn"
                            :disabled="item.pendingQuantity <= 0"
                        >
                            生产派工
                        </up-button>
                    </view>
                </view>
            </view>
        </view>
        <view v-else class="no-data">
            <text>暂无生产派工数据</text>
        </view>
        <!-- 派工弹窗 -->
        <DispatchModal ref="dispatchModalRef" @confirm="handleDispatchConfirm" />
    </view>
  <view class="production-dispatching">
    <!-- 使用通用页面头部组件 -->
    <PageHeader title="生产派工"
                @back="goBack" />
    <!-- 搜索区域 -->
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <up-input class="search-text"
                    placeholder="请输入客户名称搜索"
                    v-model="searchForm.customerName"
                    @change="handleQuery"
                    clearable />
        </view>
        <view class="filter-button"
              @click="handleQuery">
          <up-icon name="search"
                   size="24"
                   color="#999"></up-icon>
        </view>
      </view>
    </view>
    <!-- 生产派工列表 -->
    <view class="ledger-list"
          v-if="tableData.length > 0">
      <view v-for="(item, index) in tableData"
            :key="item.id || index">
        <view class="ledger-item">
          <view class="item-header">
            <view class="item-left">
              <view class="document-icon">
                <up-icon name="file-text"
                         size="16"
                         color="#ffffff"></up-icon>
              </view>
              <text class="item-id">{{ item.salesContractNo }}</text>
            </view>
          </view>
          <up-divider></up-divider>
          <view class="item-details">
            <view class="detail-row">
              <text class="detail-label">录入日期</text>
              <text class="detail-value">{{ item.entryDate }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">客户合同号</text>
              <text class="detail-value">{{ item.customerContractNo }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">客户名称</text>
              <text class="detail-value">{{ item.customerName }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">项目名称</text>
              <text class="detail-value">{{ item.projectName }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">产品大类</text>
              <text class="detail-value">{{ item.productCategory }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">规格型号</text>
              <text class="detail-value">{{ item.specificationModel }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">总数量</text>
              <text class="detail-value">{{ item.quantity }} {{ item.unit }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">排产数量</text>
              <text class="detail-value highlight">{{ item.schedulingNum }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">待排数量</text>
              <text class="detail-value"
                    :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
            </view>
          </view>
          <!-- 操作按钮区域 -->
          <view class="action-buttons">
            <up-button type="primary"
                       size="small"
                       @click="handleDispatch(item)"
                       class="action-btn"
                       :disabled="item.pendingQuantity <= 0">
              生产派工
            </up-button>
          </view>
        </view>
      </view>
    </view>
    <view v-else
          class="no-data">
      <text>暂无生产派工数据</text>
    </view>
    <!-- 派工弹窗 -->
    <DispatchModal ref="dispatchModalRef"
                   @confirm="handleDispatchConfirm" />
  </view>
</template>
<script setup>
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
import { onShow } from '@dcloudio/uni-app';
import dayjs from "dayjs";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
import PageHeader from "@/components/PageHeader.vue";
import DispatchModal from "./components/DispatchModal.vue";
const { proxy } = getCurrentInstance();
  import { ref, reactive, toRefs, getCurrentInstance } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import dayjs from "dayjs";
  // import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
  import PageHeader from "@/components/PageHeader.vue";
  import DispatchModal from "./components/DispatchModal.vue";
  const { proxy } = getCurrentInstance();
// 加载状态
const loading = ref(false);
  // 加载状态
  const loading = ref(false);
// 列表数据
const tableData = ref([]);
  // 列表数据
  const tableData = ref([]);
  // 搜索表单数据
  const data = reactive({
    searchForm: {
      customerName: "",
    },
  });
  const { searchForm } = toRefs(data);
// 搜索表单数据
const data = reactive({
    searchForm: {
        customerName: "",
    },
});
const { searchForm } = toRefs(data);
  // 分页配置
  const page = reactive({
    current: -1,
    size: -1,
  });
// 分页配置
const page = reactive({
    current: -1,
    size: -1,
});
  // 派工弹窗引用
  const dispatchModalRef = ref();
// 派工弹窗引用
const dispatchModalRef = ref();
  // 通用提示函数
  const showLoadingToast = message => {
    uni.showLoading({
      title: message,
      mask: true,
    });
  };
// 通用提示函数
const showLoadingToast = (message) => {
    uni.showLoading({
        title: message,
        mask: true
    });
};
  const closeToast = () => {
    uni.hideLoading();
  };
const closeToast = () => {
    uni.hideLoading();
};
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
  };
// 返回上一页
const goBack = () => {
    uni.navigateBack();
};
  // 查询列表
  const handleQuery = () => {
    getList();
  };
// 查询列表
const handleQuery = () => {
    getList();
};
  // 获取列表数据
  const getList = () => {
    loading.value = true;
    showLoadingToast("加载中...");
// 获取列表数据
const getList = () => {
    loading.value = true;
    showLoadingToast('加载中...');
    // 构造请求参数
    const params = { ...searchForm.value, ...page };
    schedulingListPage(params).then((res) => {
        loading.value = false;
        closeToast();
        // 处理每条数据,增加pendingQuantity字段
        tableData.value = (res.data.records || []).map(item => ({
            ...item,
            pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
        }));
    }).catch(() => {
        loading.value = false;
        closeToast();
        uni.showToast({
            title: '加载失败',
            icon: 'error'
        });
    });
};
    // 构造请求参数
    const params = { ...searchForm.value, ...page };
// 处理派工操作
const handleDispatch = (item) => {
    if (item.pendingQuantity <= 0) {
        uni.showToast({
            title: '该项目无需再派工',
            icon: 'none'
        });
        return;
    }
    dispatchModalRef.value?.open(item);
};
    // schedulingListPage(params).then((res) => {
    //     loading.value = false;
    //     closeToast();
// 处理派工确认
const handleDispatchConfirm = () => {
    getList(); // 刷新列表
};
    //     // 处理每条数据,增加pendingQuantity字段
    //     tableData.value = (res.data.records || []).map(item => ({
    //         ...item,
    //         pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
    //     }));
    // }).catch(() => {
    //     loading.value = false;
    //     closeToast();
    //     uni.showToast({
    //         title: '加载失败',
    //         icon: 'error'
    //     });
    // });
  };
// 页面显示时加载数据
onShow(() => {
    // 加载列表数据
    getList();
});
  // 处理派工操作
  const handleDispatch = item => {
    if (item.pendingQuantity <= 0) {
      uni.showToast({
        title: "该项目无需再派工",
        icon: "none",
      });
      return;
    }
    dispatchModalRef.value?.open(item);
  };
  // 处理派工确认
  const handleDispatchConfirm = () => {
    getList(); // 刷新列表
  };
  // 页面显示时加载数据
  onShow(() => {
    // 加载列表数据
    getList();
  });
</script>
<style scoped lang="scss">
@import '@/styles/sales-common.scss';
  @import "@/styles/sales-common.scss";
// 生产派工页面样式
.production-dispatching {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
}
  // 生产派工页面样式
  .production-dispatching {
    min-height: 100vh;
    background: #f8f9fa;
    position: relative;
  }
// 列表项样式
.ledger-item {
    .detail-value.highlight {
        color: #ff6b35;
        font-weight: 600;
    }
    .detail-value.danger {
        color: #ee0a24;
        font-weight: 600;
    }
}
  // 列表项样式
  .ledger-item {
    .detail-value.highlight {
      color: #ff6b35;
      font-weight: 600;
    }
// 适配 uView 组件样式
:deep(.up-input) {
    background: transparent;
}
    .detail-value.danger {
      color: #ee0a24;
      font-weight: 600;
    }
  }
  // 适配 uView 组件样式
  :deep(.up-input) {
    background: transparent;
  }
</style>
src/pages/productionManagement/productionOrder/index.vue
@@ -154,6 +154,7 @@
      2: "进行中",
      3: "已完成",
      4: "已取消",
      5: "已结束",
    };
    return statusMap[status] || "未知";
  };
@@ -164,7 +165,8 @@
      1: "primary",
      2: "warning",
      3: "success",
      4: "danger",
      4: "info",
      5: "danger",
    };
    return typeMap[status] || "info";
  };
src/pages/works.vue
@@ -1051,7 +1051,7 @@
        factoryList.value = [];
      });
  }
  const getcode = () => {
  const getcode = async () => {
    uni.scanCode({
      success: async res => {
        // 解析二维码内容
@@ -1076,6 +1076,11 @@
              const workData = workRes.data;
              console.log("工单数据:", workData);
              if (workData.endOrder === true) {
                modal.msgError("该订单已结束,无法报工");
                return;
              }
              orderRow = JSON.stringify(workData);
              console.log("构造的orderRow:", orderRow);