张诺
11 小时以前 1985fe8e217b28f89eb9501e6dd6635aaa4ec741
src/views/productionManagement/productionOrder/BindRouteDialog.vue
@@ -1,188 +1,225 @@
<template>
  <FormDialog
    v-model="visible"
    :title="type === 'add' ? '绑定工艺路线' : '编辑工艺路线'"
    width="1400px"
    :operation-type="type"
    :column="8"
    @close="handleClose"
    @confirm="handleConfirm"
    @cancel="handleClose"
      v-model="visible"
      :title="type === 'add' ? '绑定工艺路线' : type === 'detail' ? '查看工艺路线' : '编辑工艺路线'"
      width="1400px"
      :operation-type="type"
      :column="8"
      @close="handleClose"
      @confirm="handleConfirm"
      @cancel="handleClose"
  >
    <!-- ================= 基本信息 ================= -->
    <el-descriptions :column="3">
      <el-descriptions-item label="编号" align="center" v-if="formData.productOrderList">
        {{ formData.productOrderList.salesContractNo || "暂无数据" }}
      </el-descriptions-item>
    <div :class="{ 'is-detail': isDetail }">
      <!-- ================= 基本信息 ================= -->
      <el-descriptions :column="3">
        <el-descriptions-item label="编号" align="center" v-if="formData.productOrderList">
          {{ formData.productOrderList.salesContractNo || "暂无数据" }}
        </el-descriptions-item>
      <el-descriptions-item label="制单日期" align="center" v-if="formData.productOrderList">
        {{ formData.productOrderList.entryDate || "暂无数据" }}
      </el-descriptions-item>
        <el-descriptions-item label="制单日期" align="center" v-if="formData.productOrderList">
          {{ formData.productOrderList.entryDate || "暂无数据" }}
        </el-descriptions-item>
      <el-descriptions-item label="交付日期" align="center" v-if="formData.productOrderList">
        {{ formData.productOrderList.deliveryDate || "暂无数据" }}
      </el-descriptions-item>
    </el-descriptions>
        <el-descriptions-item label="交付日期" align="center" v-if="formData.productOrderList">
          {{ formData.productOrderList.deliveryDate || "暂无数据" }}
        </el-descriptions-item>
      </el-descriptions>
    <el-descriptions border :column="4">
      <el-descriptions-item label="委托单位" :span="2" align="center">
        {{formData.clientName || "--"}}
      </el-descriptions-item>
      <el-descriptions border :column="4">
        <el-descriptions-item label="委托单位" :span="2" align="center">
          {{ formData.clientName || "--" }}
        </el-descriptions-item>
      <el-descriptions-item label="数量" :span="1" align="center">
        {{formData.orderQty || "--"}}
      </el-descriptions-item>
        <el-descriptions-item label="数量" :span="1" align="center">
          {{ formData.orderQty || "--" }}
        </el-descriptions-item>
      <el-descriptions-item label="成品尺寸" :span="1" align="center">
        {{formData.specificationModel || "--"}}
      </el-descriptions-item>
        <el-descriptions-item label="成品尺寸" :span="1" align="center">
          <el-input v-model="formData.finishedSize" placeholder="成品尺寸" :disabled="isDetail">
          </el-input>
        </el-descriptions-item>
      <el-descriptions-item label="产品名称" :span="2" align="center">
        {{formData.productName || "--"}}
      </el-descriptions-item>
        <el-descriptions-item label="产品名称" :span="2" align="center">
          {{ formData.productName || "--" }}
        </el-descriptions-item>
      <el-descriptions-item label="单据类型" :span="2" align="center">
        <el-checkbox-group v-model="introductionLetterList">
          <el-checkbox label="介绍信" value="介绍信" />
          <el-checkbox label="商标注册书" value="商标注册书" />
          <el-checkbox label="委印单" value="委印单" />
        </el-checkbox-group>
      </el-descriptions-item>
    </el-descriptions>
        <el-descriptions-item label="单据类型" :span="2" align="center">
          <el-checkbox-group v-model="introductionLetterList" :disabled="isDetail">
            <el-checkbox label="介绍信" value="介绍信"/>
            <el-checkbox label="商标注册" value="商标注册"/>
            <el-checkbox label="委印单" value="委印单"/>
            <el-checkbox label="书号" value="书号"/>
          </el-checkbox-group>
        </el-descriptions-item>
      </el-descriptions>
    <!-- ================= 材料表 ================= -->
    <div class="process-table-header">
     <div class="section-title">材料信息</div>
      <el-button type="primary" size="small" @click="addMaterialRow">新增一行</el-button>
    </div>
    <el-table border :data="formData.materialInfo" style="width: 100%">
      <el-table-column label="材料名称">
        <template #default="{ row }">
          <el-tree-select
            v-model="row.productId"
            placeholder="请选择"
            clearable
            check-strictly
            @change="(val) => getModels(val, row)"
            :data="productOptions"
            :render-after-expand="false"
            style="width: 100%"
          />
        </template>
      </el-table-column>
      <el-table-column label="规格">
        <template #default="{ row }">
          <el-select
            v-model="row.productModelId"
            placeholder="请选择规格"
            filterable
            clearable
            @change="(val) => handleMaterialModelChange(val, row)"
          >
            <el-option
              v-for="item in row.modelOptions || []"
              :key="item.id"
              :label="item.model"
              :value="item.id"
      <!-- ================= 材料表 ================= -->
      <div class="process-table-header">
        <div class="section-title">材料信息</div>
        <el-button v-if="!isDetail" type="primary" size="small" @click="addMaterialRow">新增一行</el-button>
      </div>
      <el-table border :data="formData.materialInfo" style="width: 100%">
        <el-table-column label="材料名称">
          <template #default="{ row, $index }">
            <el-tree-select
                v-if="!isDetail"
                v-model="row.productById"
                placeholder="请选择"
                clearable
                check-strictly
                @change="(val) => getModels(val, row, $index)"
                :data="productOptions"
                :render-after-expand="false"
                :disabled="isDetail"
                style="width: 100%"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="数量">
        <template #default="{ row }">
          <el-input v-model="row.num" placeholder="数量">
            <template #append>{{ row.numSuffix }}</template>
          </el-input>
        </template>
      </el-table-column>
      <el-table-column label="计量单位">
        <template #default="{ row }">
          <el-input v-model="row.unit" placeholder="计量单位" />
        </template>
      </el-table-column>
      <el-table-column label="单价">
        <template #default="{ row }">
          <el-input v-model="row.price" placeholder="单价">
            <template #append>{{ row.unitSuffix }}</template>
          </el-input>
        </template>
      </el-table-column>
      <el-table-column label="金额">
        <template #default="{ row }">
          <el-input v-model="row.totalAmount" placeholder="金额" />
        </template>
      </el-table-column>
      <el-table-column label="操作" width="80">
        <template #default="{ $index }">
          <el-button type="danger" size="small" @click="removeMaterialRow($index)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-descriptions border :column="2" :span="2">
      <el-descriptions-item
          label="注意事项"
          :span="2"
          align="center"
          style="white-space: pre-line; word-break: break-all; min-height: 60px;"
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column>
          <template #header>
            <span class="required">*</span>规格
          </template>
          <template #default="{ row }">
            <el-select
                v-if="!isDetail"
                v-model="row.productModelId"
                placeholder="请选择规格"
                filterable
                clearable
                @change="(val) => handleMaterialModelChange(val, row)"
                :disabled="isDetail"
            >
              <el-option
                  v-for="item in row.modelOptions"
                  :key="item.id"
                  :label="item.model"
                  :value="item.id"
              />
            </el-select>
            <span v-else>{{ row.model }}</span>
          </template>
        </el-table-column>
        <el-table-column label="数量">
          <template #default="{ row }">
            <el-input v-model="row.num" placeholder="数量" :disabled="isDetail">
            </el-input>
          </template>
        </el-table-column>
        <el-table-column label="计量单位">
          <template #default="{ row }">
            <el-input v-model="row.unit" placeholder="计量单位" :disabled="isDetail"/>
          </template>
        </el-table-column>
        <el-table-column label="单价">
          <template #default="{ row }">
            <el-input v-model="row.price" placeholder="单价" :disabled="isDetail">
            </el-input>
          </template>
        </el-table-column>
        <el-table-column label="金额">
          <template #default="{ row }">
            <el-input v-model="row.totalAmount" placeholder="金额" :disabled="isDetail"/>
          </template>
        </el-table-column>
        <el-table-column v-if="!isDetail" label="操作" width="80">
          <template #default="{ $index }">
            <el-button type="danger" size="small" @click="removeMaterialRow($index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-descriptions border :column="2" :span="2">
        <el-descriptions-item
            label="切料图示选择"
            :span="1"
            align="center"
            style="white-space: pre-line; word-break: break-all; min-height: 60px;"
        >
          <el-radio-group v-model="formData.cuttingDiagramCheckout">
            <el-radio value="平张">平张</el-radio>
            <el-radio value="卷筒">卷筒</el-radio>
          </el-radio-group>
        </el-descriptions-item>
        <el-descriptions-item
            label="切料注意事项"
            :span="1"
            align="center"
            style="white-space: pre-line; word-break: break-all; min-height: 60px;"
        >
          <el-input
              v-model="formData.productDescription"
              :autosize="{ minRows: 2, maxRows: 4 }"
              type="textarea"
              placeholder="请输入注意事项"
              :disabled="isDetail"
          />
        </el-descriptions-item>
      </el-descriptions>
      <!-- ================= 切料图示 ================= -->
      <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;"
          v-model:file-list="formData.cuttingFileVo"
          :action="upload.url"
          :headers="upload.headers"
          :multiple="false"
          :limit="1"
          :replaceOnExceed="true"
          :disabled="isDetail"
          :name="'files'"
          :onSuccess="onSuccess"
          :onDownload="onDownload"
          :onRemove="onRemove"
          :onPreview="onPreview"
          :onView="type!=='detail'"
          :tip-text="type === 'detail' ? '' : '支持图片(jpg, jpeg, png)格式'"
      />
      <el-image
          v-if="formData.cuttingFileVo.length > 0"
          style="width: 100px; height: 100px"
          :src="resolveFileUrl(getUploadFileUrl(formData.cuttingFileVo[0]))"
          fit="cover"
      />
      <!-- ================= 切料信息 ================= -->
      <el-descriptions
          border
          :column="6"
          direction="vertical"
          style="width: 100%"
          class="fixed-desc"
      >
        <el-input
            v-model="formData.productDescription"
            :autosize="{ minRows: 2, maxRows: 4 }"
            type="textarea"
            placeholder="请输入注意事项"
        />
      </el-descriptions-item>
    </el-descriptions>
    <hr>
    <!-- ================= 切料图示 ================= -->
    <div class="section-title">切料图示</div>
    <ActionFileUpload
        style="width: 50%;"
        v-model:file-list="fileList"
        :action="upload.url"
        :headers="upload.headers"
        :multiple="false"
        :name="'files'"
        :onSuccess="uploadSuccess"
    tip-text="支持图片(jpg, jpeg, png)格式"
    />
    <!-- ================= 切料信息 ================= -->
    <el-descriptions
      border
      :column="6"
      direction="vertical"
      style="width: 100%"
      class="fixed-desc"
    >
      <el-descriptions-item label="切料尺寸" align="center">
        <el-input v-model="formData.cutNum" placeholder="切料尺寸" />
      </el-descriptions-item>
      <el-descriptions-item label="切料数量" align="center">
        <el-input v-model="formData.cutSize" placeholder="切料尺寸" />
      </el-descriptions-item>
      <el-descriptions-item label="中盒数量" align="center">
        <el-input v-model="formData.mediumBoxQty" placeholder="中盒数量" />
      </el-descriptions-item>
      <el-descriptions-item label="小盒数量" align="center">
        <el-input v-model="formData.smallBoxQty" placeholder="小盒数量" />
      </el-descriptions-item>
      <el-descriptions-item label="正数" align="center">
        <el-input v-model="formData.positiveQty" placeholder="正数" />
      </el-descriptions-item>
      <el-descriptions-item label="加放数" align="center">
        <el-input v-model="formData.allowanceQty" placeholder="加放数" />
      </el-descriptions-item>
    </el-descriptions>
        <el-descriptions-item label="切料尺寸" align="center">
          <el-input v-model="formData.cutNum" placeholder="切料尺寸" :disabled="isDetail"/>
        </el-descriptions-item>
        <el-descriptions-item label="切料数量" align="center">
          <el-input v-model="formData.cutSize" placeholder="切料数量" :disabled="isDetail"/>
        </el-descriptions-item>
        <el-descriptions-item label="中盒数量" align="center">
          <el-input v-model="formData.mediumBoxQty" placeholder="中盒数量" :disabled="isDetail"/>
        </el-descriptions-item>
        <el-descriptions-item label="小盒数量" align="center">
          <el-input v-model="formData.smallBoxQty" placeholder="小盒数量" :disabled="isDetail"/>
        </el-descriptions-item>
        <el-descriptions-item label="正数" align="center">
          <el-input v-model="formData.positiveQty" placeholder="正数" :disabled="isDetail"/>
        </el-descriptions-item>
        <el-descriptions-item label="加放数" align="center">
          <el-input v-model="formData.allowanceQty" placeholder="加放数" :disabled="isDetail"/>
        </el-descriptions-item>
      </el-descriptions>
    <div class="middle-sheet-table">
      <table class="middle-sheet-table__inner">
        <tbody>
      <div class="middle-sheet-table">
        <table class="middle-sheet-table__inner">
          <tbody>
          <tr>
            <th>软片版:</th>
            <th colspan="2">开张色</th>
            <th>晒板</th>
            <th colspan="2">开拼</th>
            <th>别刀版</th>
            <th>刖刀版</th>
            <th>联色块</th>
          </tr>
          <tr>
@@ -191,174 +228,193 @@
            <th>拼版费</th>
            <th>出片费</th>
            <th>打样费</th>
            <th>别刀版费</th>
            <th>刖刀版费</th>
            <th>烫/凸版费</th>
            <th>小计</th>
          </tr>
          <tr v-for="(plate, index) in formData.plateMaking" :key="index">
            <td>
              <el-input v-model="plate.designProductionFee" placeholder="请输入设计制作费" />
              <el-input v-model="plate.designProductionFee" placeholder="请输入设计制作费" :disabled="isDetail"/>
            </td>
            <td>
              <el-input v-model="plate.impositionFee" placeholder="请输入拼版费" />
              <el-input v-model="plate.impositionFee" placeholder="请输入拼版费" :disabled="isDetail"/>
            </td>
            <td>
              <el-input v-model="plate.filmOutputFee" placeholder="请输入出片费" />
              <el-input v-model="plate.filmOutputFee" placeholder="请输入出片费" :disabled="isDetail"/>
            </td>
            <td>
              <el-input v-model="plate.proofingFee" placeholder="请输入打样费" />
              <el-input v-model="plate.proofingFee" placeholder="请输入打样费" :disabled="isDetail"/>
            </td>
            <td>
              <el-input v-model="plate.doctorBladePlateFee" placeholder="请输入别刀版费" />
              <el-input v-model="plate.doctorBladePlateFee" placeholder="请输入刖刀版费" :disabled="isDetail"/>
            </td>
            <td>
              <el-input v-model="plate.hotEmbossingPlateFee" placeholder="请输入烫/凸版费" />
              <el-input v-model="plate.hotEmbossingPlateFee" placeholder="请输入烫/凸版费" :disabled="isDetail"/>
            </td>
            <td>
              <el-input v-model="plate.subtotalFee" placeholder="请输入小计" />
              <el-input v-model="plate.subtotalFee" placeholder="请输入小计" :disabled="isDetail"/>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
<!--  class="section-title" -->
    <!-- ================= 工艺加工 ================= -->
    <div class="process-table-header">
     <div class="section-title">工艺加工</div>
      <el-button type="primary" size="small" @click="addProcessRow">新增一行</el-button>
    </div>
    <el-table border :data="formData.processContent" style="width: 100%" :span-method="objectSpanMethod">
      <el-table-column label="工序" width="140">
        <template #default="{ row }">
          <el-table-column label="工序" width="140">
            <template #default="{ row }">
              <el-select
                  v-model="row.processId"
                  placeholder="请选择工序"
                  @change="(val) => onProcessChange(val, row)"
              >
                <el-option
                    v-for="item in processOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                />
              </el-select>
            </template>
          </el-table-column>
        </template>
      </el-table-column>
      <el-table-column label="开数">
        <template #default="{ row }">
          <el-input v-model="row.openCount" placeholder="请输入开数" />
        </template>
      </el-table-column>
      <el-table-column label="工艺正数">
        <template #default="{ row }">
          <el-input v-model="row.processPositive" placeholder="请输入工艺正数" />
        </template>
      </el-table-column>
      <el-table-column label="加放数">
        <template #default="{ row }">
          <el-input v-model="row.allowanceQty" placeholder="请输入加放数" />
        </template>
      </el-table-column>
      <el-table-column label="机台" width="180">
        <template #default="{ row }">
          <el-select
            v-model="row.deviceId"
            placeholder="请选择机台"
            filterable
            clearable
            @change="(val) => handleDeviceChange(val, row)"
          >
            <el-option
              v-for="item in deviceOptions"
              :key="item.id"
              :label="item.deviceName"
              :value="item.id"
          </tbody>
        </table>
      </div>
      <!--  class="section-title" -->
      <!-- ================= 工艺加工 ================= -->
      <div class="process-table-header">
        <div class="section-title">工艺加工</div>
        <el-button v-if="!isDetail" type="primary" size="small" @click="addProcessRow">新增一行</el-button>
      </div>
      <el-table border :data="formData.processContent" style="width: 100%" :span-method="objectSpanMethod">
        <el-table-column label="工序" width="140">
          <template #default="{ row }">
            <el-select
                v-model="row.processId"
                placeholder="请选择工序"
                @change="(val) => onProcessChange(val, row)"
                :disabled="isDetail"
            >
              <el-option
                  v-for="item in processOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
              />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="开数">
          <template #default="{ row }">
            <el-input v-model="row.openCount" placeholder="请输入开数" :disabled="isDetail"/>
          </template>
        </el-table-column>
        <el-table-column label="工艺正数">
          <template #default="{ row }">
            <el-input v-model="row.processPositive" placeholder="请输入工艺正数" :disabled="isDetail"/>
          </template>
        </el-table-column>
        <el-table-column label="加放数">
          <template #default="{ row }">
            <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 label="工艺要求">
          <template #default="{ rowIndex }">
            <el-input
                v-model="formData.processRequirement"
                type="textarea"
                :rows="6"
                placeholder="请输入工艺要求"
                :disabled="isDetail"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="报工人" width="220">
        <template #default="{ row }">
          <el-select
            v-model="row.reportUserIds"
            placeholder="请选择报工人"
            filterable
            clearable
            multiple
            collapse-tags
            collapse-tags-tooltip
            @change="(val) => handleReportUsersChange(val, row)"
          >
            <el-option
              v-for="item in userOptions"
              :key="item.userId"
              :label="item.nickName"
              :value="item.userId"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="工艺要求">
        <template #default="{ rowIndex }">
          <el-input
            v-model="formData.processRequirement"
            type="textarea"
            :rows="6"
            placeholder="请输入工艺要求"
          />
        </template>
      </el-table-column>
      <el-table-column label="操作" width="80">
        <template #default="{ $index }">
          <el-button type="danger" size="small" @click="removeProcessRow($index)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
          </template>
        </el-table-column>
        <el-table-column v-if="!isDetail" label="操作" width="80">
          <template #default="{ $index }">
            <el-button type="danger" size="small" @click="removeProcessRow($index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    <!-- ================= 包装信息 ================= -->
    <el-descriptions border :column="3" class="mt">
      <el-descriptions-item label="送货地点" align="center">
        <el-input v-model="formData.deliveryAddress" placeholder="送货地点" />
      </el-descriptions-item>
      <!-- ================= 包装信息 ================= -->
      <el-descriptions border :column="3" class="mt">
        <el-descriptions-item label="送货地点" align="center">
          <el-input v-model="formData.deliveryAddress" placeholder="送货地点" :disabled="isDetail"/>
        </el-descriptions-item>
      <el-descriptions-item label="联系人" align="center">
        <el-input v-model="formData.contactName" placeholder="联系人" />
      </el-descriptions-item>
        <el-descriptions-item label="联系人" align="center">
          <el-input v-model="formData.contactName" placeholder="联系人" :disabled="isDetail"/>
        </el-descriptions-item>
      <el-descriptions-item label="包装要求" align="center">
        <el-input v-model="formData.packagingRequirement" placeholder="包装要求" />
      </el-descriptions-item>
        <el-descriptions-item label="包装要求" align="center">
          <el-input v-model="formData.packagingRequirement" placeholder="包装要求" :disabled="isDetail"/>
        </el-descriptions-item>
      <el-descriptions-item label="尺寸" align="center">
        <el-input v-model="formData.postProcessSize" placeholder="尺寸" />
      </el-descriptions-item>
        <el-descriptions-item label="尺寸" align="center">
          <el-input v-model="formData.postProcessSize" placeholder="尺寸" :disabled="isDetail"/>
        </el-descriptions-item>
      <el-descriptions-item label="定货数量" align="center">
        {{formData.orderQty || "--"}}
      </el-descriptions-item>
        <el-descriptions-item label="定货数量" align="center">
          {{ formData.orderQty || "--" }}
        </el-descriptions-item>
      <el-descriptions-item label="实交数量" :span="3" align="center">
        <el-input v-model="formData.actualDeliveryQty" placeholder="实交数量" />
      </el-descriptions-item>
    </el-descriptions>
        <el-descriptions-item label="实交数量" :span="3" align="center">
          <el-input v-model="formData.actualDeliveryQty" placeholder="实交数量" :disabled="isDetail"/>
        </el-descriptions-item>
      </el-descriptions>
    </div>
  </FormDialog>
  <filePreview ref="filePreviewRef"/>
</template>
<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue'
import {computed, getCurrentInstance, onMounted, reactive, ref, watch} from 'vue'
import dayjs from 'dayjs'
import FormDialog from '@/components/Dialog/FormDialog.vue'
import ActionFileUpload from "@/components/Upload/ActionFileUpload.vue";
import { list } from "@/api/productionManagement/productionProcess.js"
import { modelList, productTreeList } from "@/api/basicData/product.js"
import {list} from "@/api/productionManagement/productionProcess.js"
import {modelList, productTreeList} from "@/api/basicData/product.js"
import {getSalesLedgerWithProducts} from "@/api/salesManagement/salesLedger.js"
import { getDeviceLedger } from "@/api/equipmentManagement/ledger.js"
import { userListNoPageByTenantId } from "@/api/system/user.js"
import { getToken } from "@/utils/auth";
import {getDeviceLedger} from "@/api/equipmentManagement/ledger.js"
import {userListNoPageByTenantId} from "@/api/system/user.js"
import {getToken} from "@/utils/auth";
import filePreview from '@/components/filePreview/index.vue'
import {ElMessage} from "element-plus";
const props = defineProps({
  modelValue: {
@@ -380,38 +436,44 @@
})
const emit = defineEmits(['update:modelValue', 'confirm'])
const {proxy} = getCurrentInstance()
const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})
const isDetail = computed(() => props.type === 'detail')
const processOptions = ref([])
const deviceOptions = ref([])
const userOptions = ref([])
const reportWorkerList = ref([])
const productOptions = ref([])
const introductionLetterList = ref([])
const fileList = ref([])
const upload = reactive({
  url: import.meta.env.VITE_APP_BASE_API + '/basic/customer-follow/upload',
  headers: { Authorization: 'Bearer ' + getToken() }
  headers: {Authorization: 'Bearer ' + getToken()}
})
const showCuttingFile = computed(() => {
  return props.type === 'detail' && Array.isArray(formData.cuttingFileVo) && formData.cuttingFileVo.length > 0
})
const filePreviewRef = ref()
const formData = reactive({
  productOrderList:null,
  productOrderList: null,
  salesLedgerId: null,
  productOrderId: null,
  printOrderTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  fileList:[],
  cuttingFileVo: [],
  finishTime: "",
  no: "",
  productName: "",
  productDescription: "",
  cuttingDiagramCheckout: "",
  clientName: "",
  finishedSize: "",
  cutNum: "",
  cutSize:"",
  cutSize: "",
  mediumBoxQty: "",
  smallBoxQty: "",
  positiveQty: "",
@@ -430,7 +492,6 @@
  ],
  processContent: [
    {
      id: "1",
      processId: "",
      processName: "",
      mediumBoxQty: "",
@@ -438,15 +499,20 @@
      openCount: "",
      processPositive: "",
      allowanceQty: "",
      deviceId: "",
      deviceName: "",
      reportUserIds: [],
      reportWorkerList: []
      deviceId: "0",
      deviceName: "0",
      reportUserIds: [{
        userId: "0",
        userName: "0"
      }],
      reportWorkerList: [{
        userId: "0",
        userName: "0"
      }],
    }
  ],
  materialInfo: [
    {
      id: "1",
      productId: "",
      name: "",
      productModelId: "",
@@ -471,22 +537,164 @@
  technicalDept: "",
  warehouseDept: "",
  productModelId: "",
  specificationModel:"",
  specificationModel: "",
})
const getUploadFileUrl = (file) => {
  const response = file?.response
  const data = response?.data
  if (Array.isArray(data) && data.length) {
    return data[0]?.fileUrl || data[0]?.url || data[0]?.tempPath || ""
  }
  return file?.url || file?.fileUrl || data?.tempPath || data?.url || data?.fileUrl || ""
}
// 监听 checkbox group 变化并同步到 introductionLetter 字符串
watch(introductionLetterList, (val) => {
  formData.introductionLetter = val.join(',')
})
const onProcessChange = (processId, row) => {
  const selected = processOptions.find(item => item.id === processId)
  const selected = processOptions.value.find(item => item.id === processId)
  row.processName = selected?.name || ''
}
const cloneDeep = (val) => JSON.parse(JSON.stringify(val))
const uploadSuccess = (...args) => {
  console.log(...args)
const createDefaultFormData = () => ({
  productOrderList: null,
  salesLedgerId: null,
  productOrderId: null,
  printOrderTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  cuttingFileVo: [],
  finishTime: "",
  no: "",
  productName: "",
  productDescription: "",
  cuttingDiagramCheckout: "平张",
  clientName: "",
  finishedSize: "",
  cutNum: "",
  cutSize: "",
  mediumBoxQty: "",
  smallBoxQty: "",
  positiveQty: "",
  allowanceQty: "",
  introductionLetter: "",
  plateMaking: [
    {
      designProductionFee: "",
      impositionFee: "",
      filmOutputFee: "",
      proofingFee: "",
      doctorBladePlateFee: "",
      hotEmbossingPlateFee: "",
      subtotalFee: ""
    }
  ],
  processContent: [
    {
      processId: "",
      processName: "",
      mediumBoxQty: "",
      smallBoxQty: "",
      openCount: "",
      processPositive: "",
      allowanceQty: "",
      deviceId: "0",
      deviceName: "0",
      reportUserIds: [{
        userId: "0",
        userName: "0"
      }],
      reportWorkerList: [{
        userId: "0",
        userName: "0"
      }],
    }
  ],
  materialInfo: [
    {
      productId: "",
      name: "",
      productModelId: "",
      model: "",
      modelOptions: [],
      num: "",
      numSuffix: "张",
      unitSuffix: "元/kg",
      unit: "",
      price: "",
      totalAmount: ""
    }
  ],
  processRequirement: "",
  deliveryAddress: "",
  contactName: "",
  packagingRequirement: "",
  postProcessSize: "",
  orderQty: "",
  actualDeliveryQty: "",
  productionDept: "",
  technicalDept: "",
  warehouseDept: "",
  productModelId: "",
  specificationModel: "",
  cuttingFileId: ""
})
const resetForm = () => {
  const next = createDefaultFormData()
  Object.keys(next).forEach((key) => {
    formData[key] = Array.isArray(next[key]) ? cloneDeep(next[key]) : next[key]
  })
  introductionLetterList.value = []
}
const onSuccess = (response, uploadFile, uploadFiles) => {
  const data = response?.data
  if (uploadFile && !uploadFile.url) {
    uploadFile.url = (Array.isArray(data) ? data?.[0]?.fileUrl : data?.fileUrl) || data?.tempPath || data?.url || response?.url || ""
  }
  if (Array.isArray(uploadFiles) && uploadFiles.length) {
    formData.cuttingFileVo = [uploadFiles[uploadFiles.length - 1]]
    formData.cuttingFileId = data?.[0]?.id || ""
  }
}
const JavaApi = computed(() => proxy?.javaApi || "")
const onRemove = (file) => {
  formData.cuttingFileVo = []
  formData.cuttingFileId = ""
}
const resolveFileUrl = (rawUrl) => {
  const u = String(rawUrl || "")
  if (!u) return ""
  if (/^(https?:)?\/\//i.test(u)) return u
  if (/^(blob:|data:)/i.test(u)) return u
  const base = String(JavaApi.value || "").replace(/\/+$/, "")
  if (!base) return u
  if (u.startsWith("/")) return base + u
  return base + "/" + u
}
// 文件预览/下载
const onDownload = (file) => {
  const url = resolveFileUrl(getUploadFileUrl(file))
  if (!url) return
  proxy?.$modal?.loading?.("正在下载文件,请稍候...")
  proxy.$download.name(url);
  proxy?.$modal?.closeLoading?.()
}
const onPreview = (file) => {
  const url = resolveFileUrl(getUploadFileUrl(file))
  if (!url) return
  filePreviewRef.value?.openUrl?.(url);
}
const mergeRowDataToForm = (source) => {
  if (!source || typeof source !== 'object') {
@@ -498,6 +706,19 @@
      formData[key] = Array.isArray(source[key]) ? cloneDeep(source[key]) : source[key]
    }
  })
  if (formData.cuttingFileVo && !Array.isArray(formData.cuttingFileVo)) {
    formData.cuttingFileVo = [formData.cuttingFileVo]
  }
  if (Array.isArray(formData.cuttingFileVo)) {
    formData.cuttingFileVo = formData.cuttingFileVo
        .filter(Boolean)
        .map((f) => ({
          ...f,
          name: f?.name || f?.fileName || "",
          url: f?.url || f?.fileUrl || "",
        }))
  }
  // 兼容 index.vue 里常用字段名与弹窗字段名不一致的情况
  if (source.productName === undefined && source.productCategory !== undefined) {
@@ -515,34 +736,38 @@
  if (source.productOrderId === undefined && source.id !== undefined) {
    formData.productOrderId = source.id
  }
  introductionLetterList.value = String(formData.introductionLetter || "")
      .split(",")
      .map(s => s.trim())
      .filter(Boolean)
}
// 获取销售订单
const getProductOrder = () => {
  if(!formData.salesLedgerId) return
  if (!formData.salesLedgerId) return
  getSalesLedgerWithProducts({
    type: "1",
    id: formData.salesLedgerId
  }).then(res => {
    if(res){
    if (res) {
      formData.productOrderList = res
    }
    console.log(formData)
  })
}
watch(() => props.orderData, (val) => {
  mergeRowDataToForm(val)
}, { immediate: true, deep: true })
}, {immediate: true, deep: true})
watch(
  () => props.rowData,
  (val) => {
    mergeRowDataToForm(val)
    getProductOrder()
  },
  { immediate: true, deep: true }
    () => props.rowData,
    (val) => {
      mergeRowDataToForm(val)
      getProductOrder()
    },
    {immediate: true, deep: true}
)
const getProcessList = () => {
@@ -550,7 +775,6 @@
    processOptions.value = res.data
  })
}
const getDeviceList = () => {
@@ -596,11 +820,9 @@
}
const handleProcessChange = (val, row) => {
  console.log(row)
  const process = processOptions.value.find(item => item.id === val)
  if (process) {
    row.processName = process.name
    console.log(process)
    if (process.deviceId) {
      row.deviceId = process.deviceId || ""
      row.deviceName = process.deviceName || ""
@@ -624,24 +846,40 @@
  }))
}
const getModels = (val, row) => {
const getModels = async (val, row, index) => {
  const targetRow = formData.materialInfo[index]
  row.productId = val || ""
  row.productById = val || ""
  row.name = val ? findProductLabelById(productOptions.value, val) : ""
  row.productModelId = ""
  row.model = ""
  row.unit = ""
  row.modelOptions = []
  if (!val) {
    return
  if (!val) return
  const res = await modelList({id: val})
  formData.materialInfo[index] = {
    ...targetRow,
    modelOptions: Array.isArray(res) ? res :
        Array.isArray(res?.data) ? res.data :
            Array.isArray(res?.rows) ? res.rows :
                Array.isArray(res?.data?.records) ? res.data.records :
                    []
  }
  modelList({ id: val }).then(res => {
    row.modelOptions = Array.isArray(res) ? res : Array.isArray(res?.data) ? res.data : []
  })
  // row.modelOptions = Array.isArray(res) ? res :
  //     Array.isArray(res?.data) ? res.data :
  //         Array.isArray(res?.rows) ? res.rows :
  //             Array.isArray(res?.data?.records) ? res.data.records :
  //                 []
}
const handleMaterialModelChange = (val, row) => {
  const currentModel = (row.modelOptions || []).find(item => item.id === val)
  row.productModelId = val || ""
  row.productId = currentModel?.id || ""
  row.model = currentModel?.model || ""
  row.unit = currentModel?.unit || ""
}
@@ -670,16 +908,21 @@
const addProcessRow = () => {
  formData.processContent.push({
    id: Date.now().toString(),
    processId: "",
    processName: "",
    openCount: "",
    processPositive: "",
    allowanceQty: "",
    deviceId: "",
    deviceName: "",
    reportUserIds: [],
    reportWorkerList: []
    deviceId: "0",
    deviceName: "0",
    reportUserIds: [{
      userId: "0",
      userName: "0"
    }],
    reportWorkerList: [{
      userId: "0",
      userName: "0"
    }],
  })
}
@@ -687,7 +930,7 @@
  formData.processContent.splice(index, 1)
}
const objectSpanMethod = ({ column, rowIndex }) => {
const objectSpanMethod = ({column, rowIndex}) => {
  if (column.label === "工艺要求") {
    if (rowIndex === 0) {
      return {
@@ -707,7 +950,39 @@
}
const handleConfirm = () => {
  emit('confirm', JSON.parse(JSON.stringify(formData)))
  if (isDetail.value) {
    return
  }
  const materialRows = Array.isArray(formData.materialInfo) ? formData.materialInfo : []
  for (let i = 0; i < materialRows.length; i++) {
    const row = materialRows[i] || {}
    if (!row.productId) {
      ElMessage.warning(`材料信息第${i + 1}行:   规格必填`)
      return
    }
  }
  const rows = Array.isArray(formData.processContent) ? formData.processContent : []
  for (let i = 0; i < rows.length; i++) {
    const row = rows[i] || {}
    if (!row.deviceId) {
      ElMessage.warning(`工艺加工第${i + 1}行:机台必填`)
      return
    }
    if (!Array.isArray(row.reportUserIds) || row.reportUserIds.length === 0) {
      ElMessage.warning(`工艺加工第${i + 1}行:报工人必填`)
      return
    }
  }
  const payload = cloneDeep(formData)
  delete payload.productOrderList
  if (Array.isArray(payload.materialInfo)) {
    payload.materialInfo = payload.materialInfo.map((item) => {
      const {modelOptions, ...rest} = item || {}
      return rest
    })
  }
  emit('confirm', payload)
}
onMounted(() => {
@@ -717,7 +992,8 @@
  getMaterialProductOptions()
})
defineExpose({
  getProductOrder
  getProductOrder,
  resetForm
})
</script>
@@ -732,10 +1008,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;
@@ -778,6 +1056,7 @@
  display: flex;
  justify-content: space-between;
  align-items: center;
  span {
    font-size: 16px;
    font-weight: bold;
@@ -787,7 +1066,61 @@
.mt {
  margin-top: 20px;
}
:deep(.el-textarea__inner){
:deep(.required) {
  color: #f56c6c;
}
:deep(.el-textarea__inner) {
  box-shadow: none;
}
.is-detail {
  :deep(.el-input__wrapper) {
    box-shadow: none !important;
    background-color: transparent !important;
  }
  :deep(.el-input__inner) {
    color: var(--el-text-color-regular) !important;
    -webkit-text-fill-color: var(--el-text-color-regular) !important;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
  }
  :deep(.el-input-group__append),
  :deep(.el-input-group__prepend) {
    background-color: transparent !important;
    box-shadow: none !important;
    color: var(--el-text-color-regular) !important;
  }
  :deep(.el-select__wrapper) {
    box-shadow: none !important;
    background-color: transparent !important;
  }
  :deep(.el-select__selected-item) {
    color: var(--el-text-color-regular) !important;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
  }
  :deep(.el-select__caret) {
    display: none;
  }
  :deep(.el-textarea__inner) {
    box-shadow: none !important;
    background-color: transparent !important;
    color: var(--el-text-color-regular) !important;
    -webkit-text-fill-color: var(--el-text-color-regular) !important;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }
}
</style>