zhangwencui
2026-04-30 3fa1df3286670f5480fc1eca31ef81d30b6865f5
已结束订单的报工扫码限制,以及一些废弃接口处理
已修改5个文件
421 ■■■■ 文件已修改
src/pages/productionManagement/productionDispatching/components/DispatchModal.vue 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/components/formDia.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/index.vue 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionOrder/index.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/works.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/productionManagement/productionDispatching/components/DispatchModal.vue
@@ -1,149 +1,130 @@
<template>
    <up-popup
        v-model:show="show"
  <up-popup v-model:show="show"
        mode="bottom" 
        :round="20"
        :safeAreaInsetBottom="true"
        @close="handleClose"
        @open="handleOpen"
    >
            @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 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"
        <up-form :model="form"
                    ref="formRef"
                    :rules="rules"
                    labelWidth="120"
                >
                 labelWidth="120">
                    <!-- 项目基本信息 -->
                    <view class="form-section">
                        <text class="section-title">项目信息</text>
                        <up-form-item label="项目名称" prop="projectName">
                            <up-input
                                v-model="form.projectName"
            <up-form-item label="项目名称"
                          prop="projectName">
              <up-input v-model="form.projectName"
                                disabled 
                                placeholder="项目名称"
                            />
                        placeholder="项目名称" />
                        </up-form-item>
                        <up-form-item label="产品大类" prop="productCategory">
                            <up-input
                                v-model="form.productCategory"
            <up-form-item label="产品大类"
                          prop="productCategory">
              <up-input v-model="form.productCategory"
                                disabled 
                                placeholder="产品大类"
                            />
                        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"
            <up-form-item label="总数量"
                          prop="quantity">
              <up-input v-model="form.quantity"
                                disabled 
                                placeholder="总数量"
                            />
                        placeholder="总数量" />
                        </up-form-item>
                        <up-form-item label="待排产数量" prop="pendingQuantity">
                            <up-input
                                v-model="form.pendingQuantity"
            <up-form-item label="待排产数量"
                          prop="pendingQuantity">
              <up-input v-model="form.pendingQuantity"
                                disabled 
                                placeholder="待排产数量"
                            />
                        placeholder="待排产数量" />
                        </up-form-item>
                        <up-form-item label="本次排产数量" prop="schedulingNum" required>
                            <up-number-box
                                v-model="form.schedulingNum"
            <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"
                            />
                             @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"
            <up-form-item label="派工人"
                          prop="schedulingUserId"
                          required>
              <up-input v-model="selectedUserName"
                                placeholder="请选择派工人"
                                readonly
                                @click="showUserPicker = true"
                                suffixIcon="arrow-down"
                            />
                        suffixIcon="arrow-down" />
                        </up-form-item>
                        <up-form-item label="派工日期" prop="schedulingDate" required>
                            <up-input
                                v-model="form.schedulingDate"
            <up-form-item label="派工日期"
                          prop="schedulingDate"
                          required>
              <up-input v-model="form.schedulingDate"
                                placeholder="请选择派工日期"
                                readonly
                                @click="showDatePicker = true"
                                suffixIcon="calendar"
                            />
                        suffixIcon="calendar" />
                        </up-form-item>
                    </view>
                </up-form>
            </view>
            <!-- 底部按钮 -->
            <view class="modal-footer">
                <up-button
                    @click="handleClose"
        <up-button @click="handleClose"
                    text="取消"
                    type="info"
                    plain
                    :customStyle="{ marginRight: '12px', flex: 1 }"
                />
                <up-button
                    @click="handleConfirm"
                   :customStyle="{ marginRight: '12px', flex: 1 }" />
        <up-button @click="handleConfirm"
                    text="确认派工"
                    type="primary"
                    :customStyle="{ flex: 1 }"
                    :loading="submitting"
                />
                   :loading="submitting" />
            </view>
        </view>
        <!-- 人员选择器 -->
        <up-picker
            v-model="showUserPicker"
    <up-picker v-model="showUserPicker"
            :columns="userColumns"
            @confirm="handleUserSelect"
            @cancel="showUserPicker = false"
        />
               @cancel="showUserPicker = false" />
        <!-- 日期选择器 -->
        <up-datetime-picker
            v-model="showDatePicker"
    <up-datetime-picker v-model="showDatePicker"
            mode="date"
            @confirm="handleDateSelect"
            @cancel="showDatePicker = false"
        />
                        @cancel="showDatePicker = false" />
    </up-popup>
</template>
<script setup>
import { ref, reactive, computed, getCurrentInstance } from 'vue';
  import { ref, reactive, computed, getCurrentInstance } from "vue";
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { productionDispatch } from "@/api/productionManagement/productionOrder.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 emit = defineEmits(["confirm"]);
// 弹窗显示状态
const show = ref(false);
@@ -158,14 +139,14 @@
const userColumns = computed(() => [
    userList.value.map(user => ({
        label: user.nickName,
        value: user.userId
    }))
      value: user.userId,
    })),
]);
// 选中的用户名称(用于显示)
const selectedUserName = computed(() => {
    const user = userList.value.find(u => u.userId === form.schedulingUserId);
    return user ? user.nickName : '';
    return user ? user.nickName : "";
});
// 表单数据
@@ -177,27 +158,27 @@
    schedulingUserId: "",
    schedulingDate: "",
    pendingQuantity: 0,
    id: "" // 原始记录ID
    id: "", // 原始记录ID
});
// 表单验证规则
const rules = reactive({
    schedulingNum: [
        { required: true, message: "请输入排产数量", trigger: "blur" }
      { required: true, message: "请输入排产数量", trigger: "blur" },
    ],
    schedulingUserId: [
        { required: true, message: "请选择派工人", trigger: "change" }
      { required: true, message: "请选择派工人", trigger: "change" },
    ],
    schedulingDate: [
        { required: true, message: "请选择派工日期", trigger: "change" }
    ]
      { required: true, message: "请选择派工日期", trigger: "change" },
    ],
});
// 表单引用
const formRef = ref();
// 打开弹窗
const open = async (rowData) => {
  const open = async rowData => {
    try {
        // 加载用户列表
        const res = await userListNoPageByTenantId();
@@ -208,31 +189,31 @@
            ...rowData,
            schedulingNum: 0,
            schedulingUserId: userStore.id,
            schedulingDate: dayjs().format("YYYY-MM-DD")
        schedulingDate: dayjs().format("YYYY-MM-DD"),
        });
        
        show.value = true;
    } catch (error) {
        uni.showToast({
            title: '加载用户列表失败',
            icon: 'error'
        title: "加载用户列表失败",
        icon: "error",
        });
    }
};
// 处理数量变化
const handleNumChange = (value) => {
  const handleNumChange = value => {
    if (value > form.pendingQuantity) {
        form.schedulingNum = form.pendingQuantity;
        uni.showToast({
            title: '排产数量不可大于待排产数量',
            icon: 'none'
        title: "排产数量不可大于待排产数量",
        icon: "none",
        });
    }
};
// 处理用户选择
const handleUserSelect = (params) => {
  const handleUserSelect = params => {
    if (params.value && params.value.length > 0) {
        form.schedulingUserId = params.value[0];
    }
@@ -240,7 +221,7 @@
};
// 处理日期选择
const handleDateSelect = (params) => {
  const handleDateSelect = params => {
    if (params.value) {
        form.schedulingDate = dayjs(params.value).format("YYYY-MM-DD");
    }
@@ -256,8 +237,8 @@
        
        if (form.schedulingNum <= 0) {
            uni.showToast({
                title: '排产数量必须大于0',
                icon: 'none'
          title: "排产数量必须大于0",
          icon: "none",
            });
            return;
        }
@@ -265,20 +246,19 @@
        submitting.value = true;
        
        // 提交派工数据
        await productionDispatch(form);
      // await productionDispatch(form);
        
        uni.showToast({
            title: '派工成功',
            icon: 'success'
        title: "派工成功",
        icon: "success",
        });
        
        handleClose();
        emit('confirm');
      emit("confirm");
    } catch (error) {
        uni.showToast({
            title: '派工失败',
            icon: 'error'
        title: "派工失败",
        icon: "error",
        });
    } finally {
        submitting.value = false;
@@ -305,13 +285,13 @@
        schedulingUserId: "",
        schedulingDate: "",
        pendingQuantity: 0,
        id: ""
      id: "",
    });
};
// 暴露方法
defineExpose({
    open
    open,
});
</script>
src/pages/productionManagement/productionDispatching/components/formDia.vue
@@ -1,87 +1,101 @@
<template>
  <div>
    <el-dialog
        v-model="dialogFormVisible"
    <el-dialog v-model="dialogFormVisible"
        title="生产派工"
        width="50%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
               @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 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"
            <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%"
                            />
                               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"
            <el-form-item label="派工人:"
                          prop="schedulingUserId">
              <el-select v-model="form.schedulingUserId"
                                placeholder="选择人员"
                                style="width: 100%;"
                            >
                                <el-option
                                    v-for="user in userList"
                         style="width: 100%;">
                <el-option v-for="user in userList"
                                    :key="user.userId"
                                    :label="user.nickName"
                                    :value="user.userId"
                                />
                           :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"
            <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%"
              />
                              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>
@@ -91,16 +105,20 @@
<script setup>
import {ref} from "vue";
import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
  import {
    getStaffJoinInfo,
    staffJoinAdd,
    staffJoinUpdate,
  } from "@/api/personnelManagement/onboarding.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import {productionDispatch} from "@/api/productionManagement/productionOrder.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 { proxy } = getCurrentInstance();
  const emit = defineEmits(["close"]);
const dialogFormVisible = ref(false);
const operationType = ref('')
  const operationType = ref("");
const data = reactive({
  form: {
        projectName: "",
@@ -112,52 +130,54 @@
        pendingQuantity: "",
  },
  rules: {
        schedulingNum: [{ required: true, message: "请输入", trigger: "blur" },],
        schedulingUserId: [{ required: true, message: "请选择", trigger: "change" },],
        schedulingDate: [{ required: true, message: "请选择", trigger: "change" },],
      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 userList = ref([]);
  const userStore = useUserStore();
// 打开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
    userListNoPageByTenantId().then((res) => {
    userListNoPageByTenantId().then(res => {
        userList.value = res.data;
    });
    form.value = {...row}
    form.value.schedulingNum = 0
    form.value.schedulingUserId = userStore.id
    form.value = { ...row };
    form.value.schedulingNum = 0;
    form.value.schedulingUserId = userStore.id;
    form.value.schedulingDate = dayjs().format("YYYY-MM-DD");
}
  };
//
const changeNum = (value) => {
  const changeNum = value => {
    if (value > form.value.pendingQuantity) {
        form.value.schedulingNum = form.value.pendingQuantity;
        proxy.$modal.msgWarning('排产数量不可大于待排产数量')
      proxy.$modal.msgWarning("排产数量不可大于待排产数量");
    }
}
  };
// 提交产品表单
const submitForm = () => {
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
            productionDispatch(form.value).then(res => {
                proxy.$modal.msgSuccess("提交成功");
                closeDia();
            })
        // productionDispatch(form.value).then(res => {
        //     proxy.$modal.msgSuccess("提交成功");
        //     closeDia();
        // })
    }
  })
}
    });
  };
// 关闭弹框
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
  emit('close')
    emit("close");
};
defineExpose({
  openDialog,
@@ -165,5 +185,4 @@
</script>
<style scoped>
</style>
src/pages/productionManagement/productionDispatching/index.vue
@@ -1,40 +1,43 @@
<template>
    <view class="production-dispatching">
        <!-- 使用通用页面头部组件 -->
        <PageHeader title="生产派工" @back="goBack" />
    <PageHeader title="生产派工"
                @back="goBack" />
        <!-- 搜索区域 -->
        <view class="search-section">
            <view class="search-bar">
                <view class="search-input">
                    <up-input
                        class="search-text"
          <up-input class="search-text"
                        placeholder="请输入客户名称搜索"
                        v-model="searchForm.customerName"
                        @change="handleQuery"
                        clearable
                    />
                    clearable />
                </view>
                <view class="filter-button" @click="handleQuery">
                    <up-icon name="search" size="24" color="#999"></up-icon>
        <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-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>
                <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>
@@ -70,39 +73,38 @@
                        </view>
                        <view class="detail-row">
                            <text class="detail-label">待排数量</text>
                            <text class="detail-value" :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
              <text class="detail-value"
                    :class="{ 'danger': item.pendingQuantity <= 0 }">{{ item.pendingQuantity }}</text>
                        </view>
                    </view>
                    <!-- 操作按钮区域 -->
                    <view class="action-buttons">
                        <up-button
                            type="primary"
            <up-button type="primary"
                            size="small"
                            @click="handleDispatch(item)"
                            class="action-btn"
                            :disabled="item.pendingQuantity <= 0"
                        >
                       :disabled="item.pendingQuantity <= 0">
                            生产派工
                        </up-button>
                    </view>
                </view>
            </view>
        </view>
        <view v-else class="no-data">
    <view v-else
          class="no-data">
            <text>暂无生产派工数据</text>
        </view>
        <!-- 派工弹窗 -->
        <DispatchModal ref="dispatchModalRef" @confirm="handleDispatchConfirm" />
    <DispatchModal ref="dispatchModalRef"
                   @confirm="handleDispatchConfirm" />
    </view>
</template>
<script setup>
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
import { onShow } from '@dcloudio/uni-app';
  import { onShow } from "@dcloudio/uni-app";
import dayjs from "dayjs";
import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
  // import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
import PageHeader from "@/components/PageHeader.vue";
import DispatchModal from "./components/DispatchModal.vue";
const { proxy } = getCurrentInstance();
@@ -112,7 +114,6 @@
// 列表数据
const tableData = ref([]);
// 搜索表单数据
const data = reactive({
@@ -132,10 +133,10 @@
const dispatchModalRef = ref();
// 通用提示函数
const showLoadingToast = (message) => {
  const showLoadingToast = message => {
    uni.showLoading({
        title: message,
        mask: true
      mask: true,
    });
};
@@ -156,36 +157,36 @@
// 获取列表数据
const getList = () => {
    loading.value = true;
    showLoadingToast('加载中...');
    showLoadingToast("加载中...");
    
    // 构造请求参数
    const params = { ...searchForm.value, ...page };
    
    schedulingListPage(params).then((res) => {
        loading.value = false;
        closeToast();
    // 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'
        });
    });
    //     // 处理每条数据,增加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 handleDispatch = (item) => {
  const handleDispatch = item => {
    if (item.pendingQuantity <= 0) {
        uni.showToast({
            title: '该项目无需再派工',
            icon: 'none'
        title: "该项目无需再派工",
        icon: "none",
        });
        return;
    }
@@ -206,7 +207,7 @@
</script>
<style scoped lang="scss">
@import '@/styles/sales-common.scss';
  @import "@/styles/sales-common.scss";
// 生产派工页面样式
.production-dispatching {
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);