src/views/mes/workbench/components/tabs/FeedbackTab.vue
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import type { PendingTask } from '../../../types';
import type { PendingTask } from '../../types';
import type { FormType } from '../../../pro/feedback/data';
import { computed, ref, watch } from 'vue';
@@ -12,7 +12,7 @@
} from '@vben/constants';
import { useUserStore } from '@vben/stores';
import { Button, message, Modal, Popconfirm } from 'ant-design-vue';
import { Button, Input, message, Modal, Popconfirm } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { generateAutoCode } from '#/api/mes/md/autocode/record';
@@ -29,9 +29,13 @@
import { $t } from '#/locales';
import { useFormSchema } from '../../../pro/feedback/data';
import {
  loadParamDetails,
  paramDetails,
} from '../../../pro/feedback/param-state';
import BatchInputDialog from '../../../pro/feedback/modules/batch-input-dialog.vue';
const batchDialogRef = ref<InstanceType<typeof BatchInputDialog>>();
const batchActionType = ref<'submit' | 'approve'>('');
const batchActionType = ref<'' | 'submit' | 'approve'>('');
const pendingSubmitMode = ref<'saveAndSubmit' | 'submit'>('submit');
defineOptions({ name: 'WorkbenchFeedbackTab' });
@@ -73,26 +77,29 @@
  wrapperClass: 'grid-cols-3',
});
/** 根据 checkFlag 对齐数量 */
/** 提交前对齐数量:报工只填写报工数量,合格/不良/废品数量由质检确定,报工环节不采集 */
function alignQuantity(data: any) {
  if (data.checkFlag) {
    data.uncheckQuantity = data.feedbackQuantity;
    data.qualifiedQuantity = 0;
    data.unqualifiedQuantity = 0;
    data.laborScrapQuantity = 0;
    data.materialScrapQuantity = 0;
    data.otherScrapQuantity = 0;
  } else {
    data.feedbackQuantity =
      (data.qualifiedQuantity || 0) + (data.unqualifiedQuantity || 0);
    data.uncheckQuantity = 0;
  }
  data.uncheckQuantity = data.checkFlag ? data.feedbackQuantity : 0;
  delete data.qualifiedQuantity;
  delete data.unqualifiedQuantity;
  delete data.laborScrapQuantity;
  delete data.materialScrapQuantity;
  delete data.otherScrapQuantity;
}
async function getAlignedData() {
  const data = (await formApi.getValues()) as any;
  syncParamValues(data);
  alignQuantity(data);
  return data;
}
/** 同步工艺参数值到报工数据(与提交数据一同发送给后端) */
function syncParamValues(data: any) {
  data.paramValues = paramDetails.value.map((detail) => ({
    detailId: detail.id,
    value: detail.paramValue,
  }));
}
/** 加载 checkFlag */
@@ -117,6 +124,8 @@
  const code = await generateAutoCode(MesAutoCodeRuleCode.PRO_FEEDBACK_CODE);
  const checkFlag = await resolveCheckFlag(task.routeId, task.processId);
  // 加载任务绑定的工艺参数(必填参数校验 + 参数值回显)
  await loadParamDetails(task.id);
  await formApi.setValues({
    code,
@@ -133,6 +142,7 @@
    itemName: task.itemName,
    itemSpecification: task.itemSpecification,
    unitMeasureName: task.unitMeasureName,
    reportableQuantity: task.reportableQuantity,
    scheduledQuantity: task.quantity,
    feedbackApprove: task.feedbackApprove,
    checkFlag,
@@ -210,7 +220,7 @@
  pendingSubmitMode.value = 'saveAndSubmit';
  // 4. 调用提交接口
  const isDone = await handleOnSubmit(feedbackId.value!,props.task.feedbackApprove);
  const isDone = await handleOnSubmit(feedbackId.value!,props.task?.feedbackApprove);
  if (!isDone) return;
  feedbackId.value = record.id;
@@ -242,7 +252,7 @@
  }
  pendingSubmitMode.value = 'submit';
  const isDone = await handleOnSubmit(feedbackId.value!,props.task.feedbackApprove);
  const isDone = await handleOnSubmit(feedbackId.value!,props.task?.feedbackApprove);
  if (!isDone) return;
  message.success('报工单已提交');
@@ -328,13 +338,15 @@
  formType.value = 'update';
  formApi.setState({ schema: useFormSchema(formType.value, formApi) });
  const checkFlag = await resolveCheckFlag(data.routeId, data.processId);
  await loadParamDetails(data.taskId);
  await formApi.setValues({ ...data, checkFlag });
  originalSnapshot.value = JSON.stringify(await getAlignedData());
}
// 监听任务变更(仅当任务 ID 真正变化时才重置表单)
// 监听任务变更:任务对象变化(选择任务 / 列表刷新后同步的最新数据)时重置表单,
// 确保"可报工数量"等任务派生字段始终展示最新值
watch(
  () => props.task?.id,
  () => props.task,
  () => {
    if (props.task) {
      resetForTask(props.task);
@@ -364,6 +376,34 @@
      </div>
      <Form class="feedback-tab__form" />
      <!-- 工艺参数(任务绑定参数时展示,必填参数未填会被后端拦截) -->
      <div v-if="paramDetails.length" class="feedback-tab__params">
        <div class="feedback-tab__params-title">工艺参数</div>
        <div class="feedback-tab__params-grid">
          <div
            v-for="detail in paramDetails"
            :key="detail.id"
            class="feedback-tab__params-item"
          >
            <span class="feedback-tab__params-label">
              <span v-if="detail.required" class="feedback-tab__params-required"
                >*&nbsp;</span
              >
              {{ detail.paramName || detail.paramCode
              }}{{
                detail.unitMeasureName ? `(${detail.unitMeasureName})` : ''
              }}
            </span>
            <Input
              v-model:value="detail.paramValue"
              :disabled="!isEditable"
              placeholder="请输入参数值"
              class="feedback-tab__params-input"
            />
          </div>
        </div>
      </div>
      <div class="feedback-tab__actions">
        <Button
@@ -456,4 +496,48 @@
  border-top: 1px solid #f0f0f0;
  margin-top: 16px;
}
.feedback-tab__params {
  margin-top: 16px;
  padding: 14px 16px;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
  background: #fafbfc;
}
.feedback-tab__params-title {
  margin-bottom: 12px;
  font-size: 15px;
  font-weight: 600;
  color: #1a1a1a;
}
.feedback-tab__params-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 20px;
}
.feedback-tab__params-item {
  display: flex;
  align-items: center;
  gap: 10px;
}
.feedback-tab__params-label {
  flex-shrink: 0;
  width: 176px;
  text-align: right;
  font-size: 14px;
  color: #595959;
}
.feedback-tab__params-required {
  color: #ff4d4f;
}
.feedback-tab__params-input {
  flex: 1;
  min-width: 0;
}
</style>