zhangwencui
2026-04-29 8d172bf41d2b802d5782df559e236a71a3d31c2c
src/pages/productionManagement/productionReport/index.vue
@@ -41,6 +41,58 @@
                   suffix-icon="arrow-down" />
        </u-form-item>
      </view>
      <!-- 动态参数区域 -->
      <view class="form-section"
            v-if="params.length > 0">
        <view class="section-title">工序参数</view>
        <u-form-item v-for="param in params"
                     :key="param.id"
                     :label="param.paramName"
                     :label-width="110"
                     :required="param.required === '1'">
          <!-- 数字类型 -->
          <template v-if="param.paramType == '1'">
            <u-input v-model="form.paramGroups[param.id]"
                     type="number"
                     :placeholder="'请输入' + param.paramName"
                     :key="param.id" />
            <text v-if="param.unit && param.unit != '/'"
                  class="param-unit">{{ param.unit }}</text>
          </template>
          <!-- 文本类型 -->
          <template v-else-if="param.paramType == '2'">
            <u-input v-model="form.paramGroups[param.id]"
                     :placeholder="'请输入' + param.paramName"
                     :key="param.id" />
            <text v-if="param.unit && param.unit != '/'"
                  class="param-unit">{{ param.unit }}</text>
          </template>
          <!-- 选择类型 -->
          <template v-else-if="param.paramType == '3'">
            <u-input v-model="form.paramGroups[param.id]"
                     readonly
                     :placeholder="'请选择' + param.paramName"
                     @click="openParamSelect(param)"
                     suffix-icon="arrow-down" />
          </template>
          <!-- 日期类型 -->
          <template v-else-if="param.paramType == '4'">
            <u-input v-model="form.paramGroups[param.id]"
                     readonly
                     :placeholder="'请选择' + param.paramName"
                     @click="openDateParamPicker(param)"
                     suffix-icon="arrow-down" />
            <text v-if="param.unit && param.unit != '/'"
                  class="param-unit">{{ param.unit }}</text>
          </template>
          <!-- 默认文本 -->
          <template v-else>
            <u-input v-model="form.paramGroups[param.id]"
                     :placeholder="'请输入' + param.paramName"
                     :key="param.id" />
          </template>
        </u-form-item>
      </view>
      <!-- 使用FooterButtons组件 -->
      <FooterButtons @cancel="goBack"
                     @confirm="submitForm"
@@ -54,6 +106,18 @@
                     title="选择生产人"
                     @select="onProducerConfirm"
                     @close="showProducerPicker = false" />
    <!-- 参数选择器 -->
    <up-action-sheet :show="showParamSelect"
                     :actions="paramOptions"
                     :title="currentParam?.paramName || '选择'"
                     @select="onParamConfirm"
                     @close="showParamSelect = false" />
    <!-- 日期选择器 -->
    <up-datetime-picker :show="showDatePicker"
                        v-model="datePickerValue"
                        :mode="datePickerMode"
                        @confirm="onDateConfirm"
                        @cancel="showDatePicker = false" />
  </view>
</template>
@@ -71,11 +135,12 @@
  import { addProductMain } from "@/api/productionManagement/productionReporting";
  import { getInfo } from "@/api/login";
  import { userListNoPageByTenantId } from "@/api/system/user";
  import { findProcessParamListOrder } from "@/api/productionManagement/productProcessRoute.js";
  import { getDicts } from "@/api/system/dict/data";
  import { formatDateToYMD, parseTime } from "@/utils/ruoyi";
  // 表单引用
  const formRef = ref();
  // 表单数据
  let form = ref({
    planQuantity: "",
    quantity: "",
@@ -85,20 +150,32 @@
    productProcessRouteItemId: "",
    userId: "",
    schedulingUserId: "",
    reportWork: "",
    productMainId: null,
    productionOrderRoutingOperationId: "",
    productionOrderId: "",
    paramGroups: {},
  });
  // 生产人选择器状态
  const showProducerPicker = ref(false);
  const producerList = ref([]);
  // 打开生产人选择器
  const params = ref([]);
  const dictOptions = ref({});
  const showParamSelect = ref(false);
  const currentParam = ref(null);
  const paramOptions = ref([]);
  const showDatePicker = ref(false);
  const datePickerValue = ref(Date.now());
  const datePickerMode = ref("date");
  const currentDateParam = ref(null);
  const openProducerPicker = async () => {
    if (producerList.value.length === 0) {
      // 如果列表为空,先加载用户列表
      try {
        const res = await userListNoPageByTenantId();
        const users = res.data || [];
        // 转换为 action-sheet 需要的格式
        producerList.value = users.map(user => ({
          name: user.nickName || user.userName,
          value: user.userId,
@@ -112,102 +189,236 @@
    showProducerPicker.value = true;
  };
  // 生产人选择确认
  const onProducerConfirm = e => {
    form.value.schedulingUserId = e.value;
    form.value.userName = e.name;
    form.value.userId = e.value; // 同时更新 userId
    form.value.userId = e.value;
    showProducerPicker.value = false;
  };
  // 提交状态
  const openParamSelect = async param => {
    currentParam.value = param;
    if (param.paramType == "3" && param.paramFormat) {
      const options = await getDictOptions(param.paramFormat);
      paramOptions.value = options.map(opt => ({
        name: opt.dictLabel,
        value: opt.dictLabel,
      }));
    }
    showParamSelect.value = true;
  };
  const onParamConfirm = e => {
    if (currentParam.value) {
      form.value.paramGroups[currentParam.value.id] = e.value;
    }
    showParamSelect.value = false;
  };
  const openDateParamPicker = param => {
    currentDateParam.value = param;
    const currentValue = form.value.paramGroups[param.id];
    datePickerValue.value = currentValue
      ? new Date(currentValue).getTime()
      : Date.now();
    // 参照 PC 端逻辑:如果格式是 yyyy-MM-dd 则为 date 模式,否则为 datetime 模式
    datePickerMode.value =
      param.paramFormat === "yyyy-MM-dd" ? "date" : "datetime";
    showDatePicker.value = true;
  };
  const onDateConfirm = e => {
    if (currentDateParam.value) {
      const format =
        currentDateParam.value.paramFormat === "yyyy-MM-dd"
          ? "{y}-{m}-{d}"
          : "{y}-{m}-{d} {h}:{i}:{s}";
      form.value.paramGroups[currentDateParam.value.id] = parseTime(
        e.value,
        format
      );
    }
    showDatePicker.value = false;
  };
  const getDictOptions = async dictType => {
    if (!dictType) return [];
    if (dictOptions.value[dictType]) return dictOptions.value[dictType];
    try {
      const res = await getDicts(dictType);
      if (res.code === 200) {
        dictOptions.value[dictType] = res.data;
        return res.data;
      }
      return [];
    } catch (error) {
      console.error("获取字典数据失败:", error);
      return [];
    }
  };
  const loadParams = (productionOrderRoutingOperationId, productionOrderId) => {
    findProcessParamListOrder({
      productionOrderRoutingOperationId,
      productionOrderId,
    })
      .then(res => {
        if (res.code === 200) {
          console.log(res.data, "res.data========");
          const paramList = res.data || [];
          params.value = paramList;
          form.value.paramGroups = {};
          paramList.forEach(param => {
            if (!form.value.paramGroups[param.id]) {
              form.value.paramGroups[param.id] = "";
            }
            if (param.paramType == "3" && param.paramFormat) {
              getDictOptions(param.paramFormat);
            }
          });
        }
      })
      .catch(err => {
        console.error("获取工序参数失败:", err);
      });
  };
  const submitting = ref(false);
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
  };
  // 提交表单
  const submitForm = async () => {
    submitting.value = true;
    // 校验表单
    if (!form.value.quantity) {
      submitting.value = false;
      showToast("请输入本次生产数量");
      return;
    }
    if (!form.value.schedulingUserId) {
      submitting.value = false;
      showToast("请选择生产人");
      return;
    }
    // 转换为数字进行比较
    const quantity = Number(form.value.quantity) || 0;
    const scrapQty = Number(form.value.scrapQty) || 0;
    const planQuantity = Number(form.value.planQuantity);
    // 验证生产数量和报废数量的和不能超过待生产数量
    if (quantity <= 0) {
      submitting.value = false;
      showToast("本次生产数量必须大于0");
      return;
    }
    if (quantity + scrapQty > planQuantity) {
      submitting.value = false;
      showToast("生产数量和报废数量的和不能超过待生产数量");
      return;
    }
    if (quantity > planQuantity) {
    if (scrapQty < 0) {
      submitting.value = false;
      showToast("本次生产数量不能大于待生产数量");
      showToast("报废数量不能小于0");
      return;
    }
    // 准备提交数据,确保数量字段为数字类型
    if (scrapQty > quantity) {
      submitting.value = false;
      showToast("报废数量不能大于本次生产数量");
      return;
    }
    const productionOperationParamList = params.value.map(param => ({
      ...param,
      inputValue: form.value.paramGroups[param.id] ?? "",
    }));
    const submitData = {
      ...form.value,
      quantity: Number(form.value.quantity),
      scrapQty: Number(form.value.scrapQty) || 0,
      planQuantity: Number(form.value.planQuantity) || 0,
      quantity: quantity,
      scrapQty: scrapQty,
      userId: form.value.userId,
      userName: form.value.userName,
      productionOperationTaskId: form.value.workOrderId,
      productProcessRouteItemId: form.value.productProcessRouteItemId,
      reportWork: form.value.reportWork,
      productMainId: form.value.productMainId,
      productionOrderRoutingOperationId:
        form.value.productionOrderRoutingOperationId,
      productionOrderId: form.value.productionOrderId,
      productionOperationParamList: productionOperationParamList,
    };
    console.log(submitData, "submitData");
    addProductMain(submitData).then(res => {
      if (res.code === 200) {
        showToast("报工成功");
    addProductMain(submitData)
      .then(res => {
        if (res.code === 200) {
          showToast("报工成功");
          submitting.value = false;
          setTimeout(() => {
            goBack();
          }, 1000);
        } else {
          showToast(res.msg || "报工失败");
          submitting.value = false;
        }
      })
      .catch(() => {
        showToast("报工失败");
        submitting.value = false;
        setTimeout(() => {
          goBack();
        }, 1000);
      } else {
        showToast(res.msg || "报工失败");
        submitting.value = false;
      }
    });
      });
  };
  // 页面加载时初始化数据
  onLoad(options => {
    console.log(options, "options");
    // 如果没有 orderRow 参数,说明是从首页直接跳转,需要用户手动选择订单
    if (!options.orderRow) {
      console.log("从首页跳转,无订单数据");
      getInfo().then(res => {
        // 默认使用当前登录用户
        form.value.userId = res.user.userId;
        form.value.userName = res.user.userName;
        form.value.userName = res.user.nickName || res.user.userName;
        form.value.schedulingUserId = res.user.userId;
      });
      return;
    }
    try {
      const orderRow = JSON.parse(options.orderRow);
      const orderRow = JSON.parse(decodeURIComponent(options.orderRow));
      console.log("构造的orderRow:", orderRow);
      console.log(orderRow, "orderRow======########");
      // 确保 planQuantity 转换为字符串,以便在 u-input 中正确显示
      form.value.planQuantity = orderRow.planQuantity != null ? String(orderRow.planQuantity) : "";
      form.value.productProcessRouteItemId = orderRow.productProcessRouteItemId || "";
      form.value.planQuantity =
        orderRow.planQuantity != null ? String(orderRow.planQuantity) : "";
      form.value.productProcessRouteItemId =
        orderRow.productProcessRouteItemId || "";
      form.value.workOrderId = orderRow.id || "";
      form.value.reportWork = orderRow.reportWork || "";
      form.value.productMainId = orderRow.productMainId || null;
      form.value.productionOrderRoutingOperationId =
        orderRow.productionOrderRoutingOperationId || "";
      form.value.productionOrderId = orderRow.productionOrderId || "";
      getInfo().then(res => {
        // 默认使用当前登录用户,但允许用户修改
        form.value.userId = res.user.userId;
        form.value.userName = res.user.userName;
        form.value.userName = res.user.nickName || res.user.userName;
        form.value.schedulingUserId = res.user.userId;
      });
      // 使用 nextTick 确保 DOM 更新
      console.log(orderRow, "orderRow=====");
      if (
        orderRow.productionOrderRoutingOperationId &&
        orderRow.productionOrderId
      ) {
        nextTick(() => {
          loadParams(
            orderRow.productionOrderRoutingOperationId,
            orderRow.productionOrderId
          );
        });
      }
      nextTick(() => {
        console.log("form.value after assignment:", form.value);
      });
@@ -215,13 +426,30 @@
      console.error("订单解析失败:", error);
      showToast("订单解析失败");
      goBack();
      return;
    }
  });
</script>
<style scoped lang="scss">
  @import "@/static/scss/form-common.scss";
  .form-section {
    background: #fff;
    margin-bottom: 12px;
    padding: 0 16px;
  }
  .section-title {
    font-size: 28rpx;
    font-weight: bold;
    color: #303133;
    padding: 24rpx 0 16rpx;
    border-bottom: 1px solid #f0f0f0;
  }
  .param-unit {
    margin-left: 8rpx;
    color: #909399;
    font-size: 24rpx;
  }
</style>