张诺
12 小时以前 0a7e971b4f7ff2ce09a0db0db50ac745ff8747a5
阳光印刷Web: 新增工艺路线绑定对话框组件

- 实现 BindRouteDialog 组件,支持绑定、查看和编辑工艺路线功能
- 集成基本信息展示,包括编号、制单日期、交付日期等字段
- 添加材料信息表格,支持动态新增和删除材料行
- 实现切料图示上传功能,支持图片格式文件上传预览
- 添加工艺加工表格,支持工序选择和工艺参数配置
- 集成制版费用明细表格,包含设计制作费、拼版费等项目
- 实现包装信息录入,包含送货地点、联系人等字段
- 添加表单验证逻辑,确保关键字段必填校验
- 集成文件上传和预览功能,支持多种文件格式处理
已修改3个文件
340 ■■■■■ 文件已修改
src/views/basicData/product/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/BindRouteDialog.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrder/index.vue 174 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/index.vue
@@ -206,7 +206,7 @@
    prop: "model",
  },
  {
    label: "单位",
    label: "计量单位",
    prop: "unit",
  },
  {
src/views/productionManagement/productionOrder/BindRouteDialog.vue
@@ -155,7 +155,9 @@
      </el-descriptions-item>
    </el-descriptions>
    <!-- ================= 切料图示 ================= -->
    <div class="section-title" v-if="type === 'add' || (type === 'detail' && formData.cuttingFileVo.length > 0)">切料图示</div>
      <div class="section-title" v-if="type === 'add' || (type === 'detail' && formData.cuttingFileVo.length > 0)">
        切料图示
      </div>
    <ActionFileUpload
        v-if="type === 'add' || (type === 'detail' && formData.cuttingFileVo.length > 0)"
        style="width: 50%;float: left;"
@@ -294,62 +296,62 @@
          <el-input v-model="row.allowanceQty" placeholder="请输入加放数" :disabled="isDetail" />
        </template>
      </el-table-column>
      <el-table-column width="180">
        <template #header>
          <span class="required">*</span>机台
        </template>
        <template #default="{ row }">
          <el-select
            v-model="row.deviceId"
            placeholder="请选择机台"
            filterable
            clearable
            @change="(val) => handleDeviceChange(val, row)"
            :disabled="isDetail"
          >
            <el-option
              v-for="item in deviceOptions"
              :key="item.id"
              :label="item.deviceName"
              :value="item.id"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column width="220">
        <template #header>
          <span class="required">*</span>报工人
        </template>
        <template #default="{ row }">
          <el-select
          v-if="!isDetail"
            v-model="row.reportUserIds"
            placeholder="请选择报工人"
            filterable
            clearable
            multiple
            collapse-tags
            collapse-tags-tooltip
            @change="(val) => handleReportUsersChange(val, row)"
            :disabled="isDetail"
          >
            <el-option
              v-for="item in userOptions"
              :key="item.userId"
              :label="item.nickName"
              :value="item.userId"
            />
          </el-select>
  <el-tag
  v-else
    v-for="item in row.reportWorkerList"
    :key="item.id"
  >
    {{ item.userName }}
  </el-tag>
        </template>
      </el-table-column>
        <!--      <el-table-column width="180">-->
        <!--        <template #header>-->
        <!--          <span class="required">*</span>机台-->
        <!--        </template>-->
        <!--        <template #default="{ row }">-->
        <!--          <el-select-->
        <!--            v-model="row.deviceId"-->
        <!--            placeholder="请选择机台"-->
        <!--            filterable-->
        <!--            clearable-->
        <!--            @change="(val) => handleDeviceChange(val, row)"-->
        <!--            :disabled="isDetail"-->
        <!--          >-->
        <!--            <el-option-->
        <!--              v-for="item in deviceOptions"-->
        <!--              :key="item.id"-->
        <!--              :label="item.deviceName"-->
        <!--              :value="item.id"-->
        <!--            />-->
        <!--          </el-select>-->
        <!--        </template>-->
        <!--      </el-table-column>-->
        <!--      <el-table-column width="220">-->
        <!--        <template #header>-->
        <!--          <span class="required">*</span>报工人-->
        <!--        </template>-->
        <!--        <template #default="{ row }">-->
        <!--          <el-select-->
        <!--          v-if="!isDetail"-->
        <!--            v-model="row.reportUserIds"-->
        <!--            placeholder="请选择报工人"-->
        <!--            filterable-->
        <!--            clearable-->
        <!--            multiple-->
        <!--            collapse-tags-->
        <!--            collapse-tags-tooltip-->
        <!--            @change="(val) => handleReportUsersChange(val, row)"-->
        <!--            :disabled="isDetail"-->
        <!--          >-->
        <!--            <el-option-->
        <!--              v-for="item in userOptions"-->
        <!--              :key="item.userId"-->
        <!--              :label="item.nickName"-->
        <!--              :value="item.userId"-->
        <!--            />-->
        <!--          </el-select>-->
        <!--  <el-tag-->
        <!--  v-else-->
        <!--    v-for="item in row.reportWorkerList"-->
        <!--    -->
        <!--    :key="item.id"-->
        <!--  >-->
        <!--    {{ item.userName }}-->
        <!--  </el-tag>-->
        <!--        </template>-->
        <!--      </el-table-column>-->
      <el-table-column label="工艺要求">
        <template #default="{ rowIndex }">
          <el-input
@@ -496,10 +498,16 @@
      openCount: "",
      processPositive: "",
      allowanceQty: "",
      deviceId: "",
      deviceName: "",
      reportUserIds: [],
      reportWorkerList: []
      deviceId: "0",
      deviceName: "0",
      reportUserIds: [{
        userId: "0",
        userName: "0"
      }],
      reportWorkerList: [{
        userId: "0",
        userName: "0"
      }],
    }
  ],
  materialInfo: [
@@ -591,10 +599,16 @@
      openCount: "",
      processPositive: "",
      allowanceQty: "",
      deviceId: "",
      deviceName: "",
      reportUserIds: [],
      reportWorkerList: []
      deviceId: "0",
      deviceName: "0",
      reportUserIds: [{
        userId: "0",
        userName: "0"
      }],
      reportWorkerList: [{
        userId: "0",
        userName: "0"
      }],
    }
  ],
  materialInfo: [
@@ -762,7 +776,6 @@
}
const getDeviceList = () => {
  getDeviceLedger().then(res => {
    deviceOptions.value = Array.isArray(res?.data) ? res.data : []
@@ -899,10 +912,16 @@
    openCount: "",
    processPositive: "",
    allowanceQty: "",
    deviceId: "",
    deviceName: "",
    reportUserIds: [],
    reportWorkerList: []
    deviceId: "0",
    deviceName: "0",
    reportUserIds: [{
      userId: "0",
      userName: "0"
    }],
    reportWorkerList: [{
      userId: "0",
      userName: "0"
    }],
  })
}
@@ -988,10 +1007,12 @@
.fixed-desc {
  margin-top: 20px;
  :deep(.el-descriptions__table) {
    table-layout: fixed;
    width: 100%;
  }
  :deep(.el-descriptions__cell) {
    width: 25%;
    word-break: break-word;
@@ -1034,6 +1055,7 @@
  display: flex;
  justify-content: space-between;
  align-items: center;
  span {
    font-size: 16px;
    font-weight: bold;
@@ -1043,9 +1065,11 @@
.mt {
  margin-top: 20px;
}
:deep(.required) {
  color: #f56c6c;
}
:deep(.el-textarea__inner){
  box-shadow: none;
}
src/views/productionManagement/workOrder/index.vue
@@ -13,7 +13,8 @@
        </div>
        <div class="search-item">
          <el-button type="primary"
                     @click="handleQuery">搜索</el-button>
                     @click="handleQuery">搜索
          </el-button>
        </div>
      </div>
    </div>
@@ -161,51 +162,68 @@
      margin-bottom: 40px;">
        <el-button type="primary"
                   style="margin-top: 20px;"
                   @click="printTransferCard">打印流转卡</el-button>
                   @click="printTransferCard">打印流转卡
        </el-button>
      </div>
    </el-dialog>
    <el-dialog v-model="reportDialogVisible"
               :title="`报工(机台:${currentReportRowData?.deviceName || '-'})`"
               width="500px">
      <el-form ref="reportFormRef"
               :title="`报工(工单编号:${currentReportRowData?.workOrderNo || '-'})`"
               width="1000px">
      <el-form
          ref="reportFormRef"
               :model="reportForm"
               :rules="reportFormRules"
               label-width="120px">
          label-width="120px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
        <el-form-item label="待生产数量">
          <el-input v-model="reportForm.planQuantity"
                    readonly
                    style="width: 300px" />
              <el-input v-model="reportForm.planQuantity" readonly disabled/>
        </el-form-item>
        <el-form-item label="本次生产数量"
                      prop="quantity">
          <el-input v-model.number="reportForm.quantity"
          </el-col>
          <el-col :span="12">
            <el-form-item label="本次生产数量" prop="quantity">
              <el-input
                  v-model.number="reportForm.quantity"
                    type="number"
                    min="1"
                    step="1"
                    style="width: 300px"
                    placeholder="请输入本次生产数量"
                    @input="handleQuantityInput" />
                  style="width: 100%"
                  @input="handleQuantityInput"
              />
        </el-form-item>
        <el-form-item label="补产数量"
                      prop="replenishQty">
          <el-input v-model.number="reportForm.replenishQty"
          </el-col>
          <el-col :span="12">
            <el-form-item label="补产数量" prop="replenishQty">
              <el-input
                  v-model.number="reportForm.replenishQty"
                    type="number"
                    min="0"
                    step="1"
                    style="width: 300px"
                    placeholder="请输入补产数量" />
                  placeholder="请输入补产数量"
              />
        </el-form-item>
        <el-form-item label="报废数量"
                      prop="scrapQty">
          <el-input v-model.number="reportForm.scrapQty"
          </el-col>
          <el-col :span="12">
            <el-form-item label="报废数量" prop="scrapQty">
              <el-input
                  v-model.number="reportForm.scrapQty"
                    type="number"
                    min="0"
                    step="1"
                    style="width: 300px"
                    placeholder="请输入报废数量"
                    @input="handleScrapQtyInput" />
                  @input="handleScrapQtyInput"
              />
        </el-form-item>
        <el-form-item label="班组信息">
          </el-col>
          <el-col :span="12">
            <el-form-item label="班组信息" prop="teamList">
          <el-select
              v-model="reportForm.teamList"
              multiple
@@ -214,7 +232,6 @@
              collapse-tags
              value-key="userId"
              placeholder="请选择班组成员"
              style="width: 300px"
          >
            <el-option
                v-for="user in userTeamOptions"
@@ -224,39 +241,74 @@
            />
          </el-select>
        </el-form-item>
        <el-form-item label="开始时间"
                      prop="startTime">
          <el-date-picker v-model="reportForm.startTime"
          </el-col>
          <el-col :span="12">
            <el-form-item label="机台" prop="machineId">
              <el-select
                  v-model="reportForm.machineId"
                  placeholder="请选择机台"
                  filterable
                  clearable
                  @change="(val) => handleDeviceChange(val)"
                  :disabled="isDetail"
              >
                <el-option
                    v-for="item in deviceOptions"
                    :key="item.id"
                    :label="item.deviceName"
                    :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="开始时间" prop="startTime">
              <el-date-picker
                  v-model="reportForm.startTime"
                          type="datetime"
                          value-format="YYYY-MM-DD HH:mm:ss"
                          format="YYYY-MM-DD HH:mm:ss"
                          style="width: 300px"
                          placeholder="请选择开始时间"
                          clearable />
                  style="width: 100%"
              />
        </el-form-item>
        <el-form-item label="结束时间"
                      prop="endTime">
          <el-date-picker v-model="reportForm.endTime"
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束时间" prop="endTime">
              <el-date-picker
                  v-model="reportForm.endTime"
                          type="datetime"
                          value-format="YYYY-MM-DD HH:mm:ss"
                          format="YYYY-MM-DD HH:mm:ss"
                          style="width: 300px"
                          placeholder="请选择结束时间"
                          clearable />
                  style="width: 100%"
              />
        </el-form-item>
          </el-col>
          <el-col :span="12">
        <el-form-item label="审核人" prop="auditUserId">
          <el-select v-model="reportForm.auditUserId"
                     style="width: 300px"
              <el-select
                  v-model="reportForm.auditUserId"
                     placeholder="请选择审核人"
                     clearable
                     filterable
                     @change="handleReviewerIdChange">
            <el-option v-for="user in userOptions"
                  @change="handleReviewerIdChange"
              >
                <el-option
                    v-for="user in userOptions"
                       :key="user.userId"
                       :label="user.nickName"
                       :value="user.userId" />
                    :value="user.userId"
                />
          </el-select>
        </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
@@ -318,9 +370,12 @@
  import QRCode from "qrcode";
  import { getCurrentInstance, reactive, toRefs } from "vue";
  import FilesDia from "./components/filesDia.vue";
import {getDeviceLedger} from "@/api/equipmentManagement/ledger.js";
  const { proxy } = getCurrentInstance();
  const currentUserId = ref("");
const deviceOptions = ref([])
  const currentUserName = ref("");
  const ensureCurrentUser = async () => {
@@ -335,6 +390,19 @@
      console.error("获取用户信息失败", err);
    }
  };
// 机台获取
const getDeviceList = () => {
  getDeviceLedger().then(res => {
    deviceOptions.value = Array.isArray(res?.data) ? res.data : []
  })
}
const handleDeviceChange = (val) => {
  const device = deviceOptions.value.find(item => item.id === val)
  reportForm.machineName = device?.deviceName || ""
  reportForm.machineId = val || ""
}
  const normalizeArray = (val) => {
    if (val === null || val === undefined) return [];
@@ -432,9 +500,13 @@
      label: "工序名称",
      prop: "processName",
    },
  // {
  //   label: "机台名称",
  //   prop: "deviceName",
  // },
    {
      label: "机台名称",
      prop: "deviceName",
    prop: "deviceNames",
    },
    {
      label: "需求数量",
@@ -558,7 +630,8 @@
    productProcessRouteItemId: "",
    userId: "",
    productMainId: null,
    teamList:[]
  teamList: [],
  machineId: null,
  });
  // 本次生产数量验证规则
@@ -654,6 +727,8 @@
    startTime: [{ required: true, message: "请选择开始时间", trigger: "change" }],
    endTime: [{ required: true, message: "请选择结束时间", trigger: "change" }],
    auditUserId: [{ required: true, message: "请选择审核人", trigger: "change" }],
  teamList: [{required: true, message: "请选择班组", trigger: "change"}],
  machineId: [{required: true, message: "请选择设备", trigger: "change"}],
  };
  // 处理本次生产数量输入,限制必须大于等于1
@@ -1020,16 +1095,19 @@
    ensureCurrentUser();
    getList();
    getUserList();
  getDeviceList();
  });
</script>
<style scoped lang="scss">
  .search_form {
    margin-bottom: 20px;
    .search-row {
      display: flex;
      gap: 20px;
      align-items: center;
      .search-item {
        display: flex;
        align-items: center;
@@ -1049,26 +1127,32 @@
    display: flex;
    gap: 20px;
    height: 350px;
    .transfer-card-info {
      flex: 1;
      overflow: auto;
      .info-group {
        width: 50%;
        float: left;
      }
      .info-item {
        display: flex;
        margin-bottom: 15px;
        .info-label {
          width: 120px;
          font-weight: bold;
          margin-right: 20px;
        }
        .info-value {
          flex: 1;
        }
      }
    }
    .transfer-card-qr {
      width: 240px;
      display: flex;
@@ -1127,20 +1211,24 @@
    }
    .transfer-card-info {
      flex: 1;
      .info-group {
        width: 100%;
        float: none;
        margin-bottom: 20px;
      }
      .info-item {
        display: flex;
        margin-bottom: 10px;
        .info-label {
          width: 100px;
          font-weight: bold;
          margin-right: 15px;
          white-space: nowrap;
        }
        .info-value {
          flex: 1;
          word-break: break-word;