zhangwencui
昨天 8e70dcadbe5a0fe2526e019607eaf8fcd8f1fc88
src/views/salesManagement/salesQuotation/index.vue
@@ -2,306 +2,444 @@
  <div class="app-container">
    <el-card class="box-card">
      <!-- 搜索区域 -->
      <el-row :gutter="20" class="search-row">
        <el-col :span="6">
          <el-input
            v-model="searchForm.quotationNo"
            placeholder="请输入报价单号"
            clearable
            @keyup.enter="handleSearch"
          >
      <el-row :gutter="20"
              class="search-row">
        <el-col :span="8">
          <el-input v-model="searchForm.quotationNo"
                    placeholder="请输入报价单号"
                    clearable
                    @keyup.enter="handleSearch">
            <template #prefix>
              <el-icon><Search /></el-icon>
              <el-icon>
                <Search />
              </el-icon>
            </template>
          </el-input>
        </el-col>
        <el-col :span="6">
          <el-select v-model="searchForm.customer" placeholder="请选择客户" clearable>
            <el-option label="上海科技有限公司" value="上海科技有限公司"></el-option>
            <el-option label="深圳电子有限公司" value="深圳电子有限公司"></el-option>
            <el-option label="北京贸易公司" value="北京贸易公司"></el-option>
        <el-col :span="8">
          <el-select v-model="searchForm.customer"
                     placeholder="请选择客户"
                     clearable>
            <el-option v-for="item in customerOption"
                       :key="item.id"
                       :label="item.customerName"
                       :value="item.customerName">
              {{
                        item.customerName + "——" + item.taxpayerIdentificationNumber
                     }}
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="6">
          <el-select v-model="searchForm.status" placeholder="请选择报价状态" clearable>
            <el-option label="草稿" value="草稿"></el-option>
            <el-option label="已发送" value="已发送"></el-option>
            <el-option label="客户确认" value="客户确认"></el-option>
            <el-option label="已过期" value="已过期"></el-option>
          </el-select>
        </el-col>
        <el-col :span="6">
          <el-button type="primary" @click="handleSearch">搜索</el-button>
        <!--        <el-col :span="6">-->
        <!--          <el-select v-model="searchForm.status" placeholder="请选择报价状态" clearable>-->
        <!--            <el-option label="草稿" value="草稿"></el-option>-->
        <!--            <el-option label="已发送" value="已发送"></el-option>-->
        <!--            <el-option label="客户确认" value="客户确认"></el-option>-->
        <!--            <el-option label="已过期" value="已过期"></el-option>-->
        <!--          </el-select>-->
        <!--        </el-col>-->
        <el-col :span="8">
          <el-button type="primary"
                     @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <el-button style="float: right;" type="primary" @click="handleAdd">
          <el-button style="float: right;"
                     type="primary"
                     @click="handleAdd">
            新增报价
          </el-button>
        </el-col>
      </el-row>
      <!-- 报价列表 -->
      <el-table
        :data="filteredList"
        style="width: 100%"
        v-loading="loading"
        border
        stripe
        height="calc(100vh - 22em)"
      >
        <el-table-column prop="id" label="ID" width="80" align="center"/>
        <el-table-column prop="quotationNo" label="报价单号" width="150" />
        <el-table-column prop="customer" label="客户名称" />
        <el-table-column prop="salesperson" label="业务员" width="100" />
        <el-table-column prop="quotationDate" label="报价日期" width="120" />
        <el-table-column prop="validDate" label="有效期至" width="120" />
        <el-table-column prop="totalAmount" label="报价金额" width="120">
      <el-table :data="filteredList"
                style="width: 100%"
                v-loading="loading"
                border
                stripe
                height="calc(100vh - 22em)">
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60" />
        <el-table-column prop="quotationNo"
                         label="报价单号" />
        <el-table-column prop="customer"
                         label="客户名称" />
        <el-table-column prop="salesperson"
                         label="业务员"
                         width="100" />
        <el-table-column prop="quotationDate"
                         label="报价日期"
                         width="120" />
        <el-table-column prop="validDate"
                         label="有效期至"
                         width="120" />
        <el-table-column prop="status"
                         label="审批状态"
                         width="120"
                         align="center">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)"
                    disable-transitions>
              {{ row.status || '--' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="totalAmount"
                         label="报价金额"
                         width="120">
          <template #default="scope">
            ¥{{ scope.row.totalAmount.toFixed(2) }}
          </template>
        </el-table-column>
        <el-table-column prop="status" label="报价状态" width="100">
        <el-table-column label="操作"
                         width="200"
                         fixed="right"
                         align="center">
          <template #default="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ scope.row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="250" fixed="right" align="center">
          <template #default="scope">
            <el-button link type="primary" @click="handleView(scope.row)">查看</el-button>
            <el-button link type="primary" @click="handleEdit(scope.row)" v-if="scope.row.status === '草稿'">编辑</el-button>
            <el-button link type="danger" @click="handleDelete(scope.row)" v-if="scope.row.status === '草稿'">删除</el-button>
            <el-button link
                       type="primary"
                       @click="handleEdit(scope.row)"
                       :disabled="!['待审批','拒绝'].includes(scope.row.status)">编辑</el-button>
            <el-button link
                       type="primary"
                       @click="handleView(scope.row)"
                       style="color: #67C23A">查看</el-button>
            <el-button link
                       type="danger"
                       @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <pagination
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        :page="pagination.currentPage"
        :limit="pagination.pageSize"
        @pagination="handleCurrentChange"
      />
      <pagination :total="pagination.total"
                  layout="total, sizes, prev, pager, next, jumper"
                  :page="pagination.currentPage"
                  :limit="pagination.pageSize"
                  @pagination="handleCurrentChange" />
    </el-card>
    <!-- 新增/编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="900px" :close-on-click-modal="false">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
        <!-- 基本信息 -->
        <el-card class="form-card" shadow="never">
          <template #header>
            <span class="card-title">基本信息</span>
          </template>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="客户名称" prop="customer">
                <el-select v-model="form.customer" placeholder="请选择客户" style="width: 100%" @change="handleCustomerChange">
                  <el-option label="上海科技有限公司" value="上海科技有限公司"></el-option>
                  <el-option label="深圳电子有限公司" value="深圳电子有限公司"></el-option>
                  <el-option label="北京贸易公司" value="北京贸易公司"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="业务员" prop="salesperson">
                <el-select v-model="form.salesperson" placeholder="请选择业务员" style="width: 100%">
                  <el-option label="陈志强" value="陈志强"></el-option>
                  <el-option label="刘雅婷" value="刘雅婷"></el-option>
                  <el-option label="王建国" value="王建国"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="报价日期" prop="quotationDate">
                <el-date-picker
                  v-model="form.quotationDate"
                  type="date"
                  placeholder="选择报价日期"
                  style="width: 100%"
                  format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="有效期至" prop="validDate">
                <el-date-picker
                  v-model="form.validDate"
                  type="date"
                  placeholder="选择有效期"
                  style="width: 100%"
                  format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="付款方式" prop="paymentMethod">
                <el-select v-model="form.paymentMethod" placeholder="请选择付款方式" style="width: 100%">
                  <el-option label="全款到付" value="全款到付"></el-option>
                  <el-option label="分期付款" value="分期付款"></el-option>
                  <el-option label="月结" value="月结"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="交货期" prop="deliveryPeriod">
                <el-input v-model="form.deliveryPeriod" placeholder="请输入交货期" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-card>
        <!-- 产品信息 -->
        <el-card class="form-card" shadow="never">
          <template #header>
            <div class="card-header">
              <span class="card-title">产品信息</span>
              <el-button type="primary" size="small" @click="addProduct">添加产品</el-button>
    <FormDialog v-model="dialogVisible"
                :title="dialogTitle"
                width="85%"
                :close-on-click-modal="false"
                @close="dialogVisible = false"
                @confirm="handleSubmit"
                @cancel="dialogVisible = false">
      <div class="quotation-form-container">
        <el-form :model="form"
                 :rules="rules"
                 ref="formRef"
                 label-width="120px"
                 class="quotation-form">
          <!-- 基本信息 -->
          <el-card class="form-card"
                   shadow="hover">
            <template #header>
              <div class="card-header-wrapper">
                <el-icon class="card-icon">
                  <Document />
                </el-icon>
                <span class="card-title">基本信息</span>
              </div>
            </template>
            <div class="form-content">
              <el-row :gutter="24">
                <el-col :span="12">
                  <el-form-item label="客户名称"
                                prop="customer">
                    <el-select v-model="form.customer"
                               placeholder="请选择客户"
                               style="width: 100%"
                               @change="handleCustomerChange"
                               clearable>
                      <el-option v-for="item in customerOption"
                                 :key="item.id"
                                 :label="item.customerName"
                                 :value="item.customerName">
                        {{
                        item.customerName + "——" + item.taxpayerIdentificationNumber
                      }}
                      </el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="业务员"
                                prop="salesperson">
                    <el-select v-model="form.salesperson"
                               placeholder="请选择业务员"
                               style="width: 100%"
                               clearable>
                      <el-option v-for="item in userList"
                                 :key="item.nickName"
                                 :label="item.nickName"
                                 :value="item.nickName" />
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="24">
                <el-col :span="12">
                  <el-form-item label="报价日期"
                                prop="quotationDate">
                    <el-date-picker v-model="form.quotationDate"
                                    type="date"
                                    placeholder="选择报价日期"
                                    style="width: 100%"
                                    format="YYYY-MM-DD"
                                    value-format="YYYY-MM-DD"
                                    clearable />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="有效期至"
                                prop="validDate">
                    <el-date-picker v-model="form.validDate"
                                    type="date"
                                    placeholder="选择有效期"
                                    style="width: 100%"
                                    format="YYYY-MM-DD"
                                    value-format="YYYY-MM-DD"
                                    clearable />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="24">
                <el-col :span="12">
                  <el-form-item label="付款方式"
                                prop="paymentMethod">
                    <el-input v-model="form.paymentMethod"
                              placeholder="请输入付款方式"
                              clearable />
                  </el-form-item>
                </el-col>
              </el-row>
            </div>
          </template>
          <el-table :data="form.products" border style="width: 100%">
            <el-table-column prop="productName" label="产品名称" width="200">
              <template #default="scope">
                <el-input v-model="scope.row.productName" placeholder="请输入产品名称" />
              </template>
            </el-table-column>
            <el-table-column prop="specification" label="规格型号" width="150">
              <template #default="scope">
                <el-input v-model="scope.row.specification" placeholder="规格型号" />
              </template>
            </el-table-column>
            <el-table-column prop="quantity" label="数量" width="100">
              <template #default="scope">
                <el-input-number v-model="scope.row.quantity" :min="1" :precision="0" style="width: 100%" />
              </template>
            </el-table-column>
            <el-table-column prop="unit" label="单位" width="80">
              <template #default="scope">
                <el-input v-model="scope.row.unit" placeholder="单位" />
              </template>
            </el-table-column>
            <el-table-column prop="unitPrice" label="单价" width="120">
              <template #default="scope">
                <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" @change="calculateAmount(scope.row)" />
              </template>
            </el-table-column>
            <el-table-column prop="amount" label="金额" width="120">
              <template #default="scope">
                <span>¥{{ scope.row.amount.toFixed(2) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" align="center">
              <template #default="scope">
                <el-button link type="danger" @click="removeProduct(scope.$index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
        <!-- 费用信息 -->
        <el-card class="form-card" shadow="never">
          <template #header>
            <span class="card-title">费用信息</span>
          </template>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item label="产品小计">
                <el-input-number v-model="form.subtotal" :precision="2" :min="0" style="width: 100%" readonly />
          </el-card>
          <!-- 审批人信息 -->
          <el-card class="form-card"
                   shadow="hover">
            <template #header>
              <div class="card-header-wrapper">
                <el-icon class="card-icon">
                  <UserFilled />
                </el-icon>
                <span class="card-title">审批人选择</span>
                <el-button type="primary"
                           size="small"
                           @click="addApproverNode"
                           class="header-btn">
                  <el-icon>
                    <Plus />
                  </el-icon>
                  新增节点
                </el-button>
              </div>
            </template>
            <div class="form-content">
              <el-row>
                <el-col :span="24">
                  <el-form-item>
                    <div class="approver-nodes-container">
                      <div v-for="(node, index) in approverNodes"
                           :key="node.id"
                           class="approver-node-item">
                        <div class="approver-node-label">
                          <span class="node-step">{{ index + 1 }}</span>
                          <span class="node-text">审批人</span>
                          <el-icon class="arrow-icon">
                            <ArrowRight />
                          </el-icon>
                        </div>
                        <el-select v-model="node.userId"
                                   placeholder="选择人员"
                                   class="approver-select"
                                   clearable>
                          <el-option v-for="user in userListApprove"
                                     :key="user.userId"
                                     :label="user.userName"
                                     :value="user.userId" />
                        </el-select>
                        <el-button type="danger"
                                   size="small"
                                   :icon="Delete"
                                   @click="removeApproverNode(index)"
                                   v-if="approverNodes.length > 1"
                                   class="remove-btn">删除</el-button>
                      </div>
                    </div>
                  </el-form-item>
                </el-col>
              </el-row>
            </div>
          </el-card>
          <!-- 产品信息 -->
          <el-card class="form-card"
                   shadow="hover">
            <template #header>
              <div class="card-header-wrapper">
                <el-icon class="card-icon">
                  <Box />
                </el-icon>
                <span class="card-title">产品信息</span>
                <el-button type="primary"
                           size="small"
                           @click="addProduct"
                           class="header-btn">
                  <el-icon>
                    <Plus />
                  </el-icon>
                  添加产品
                </el-button>
              </div>
            </template>
            <div class="form-content">
              <el-table :data="form.products"
                        border
                        style="width: 100%"
                        class="product-table"
                        v-if="form.products.length > 0">
                <el-table-column prop="product"
                                 label="产品名称"
                                 width="200">
                  <template #default="scope">
                    <el-form-item :prop="`products.${scope.$index}.productId`"
                                  class="product-table-form-item">
                      <el-tree-select v-model="scope.row.productId"
                                      placeholder="请选择"
                                      clearable
                                      check-strictly
                                      @change="getModels($event, scope.row)"
                                      :data="productOptions"
                                      :render-after-expand="false"
                                      style="width: 100%" />
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column prop="specification"
                                 label="规格型号"
                                 width="200">
                  <template #default="scope">
                    <el-form-item :prop="`products.${scope.$index}.specificationId`"
                                  class="product-table-form-item">
                      <el-select v-model="scope.row.specificationId"
                                 placeholder="请选择"
                                 clearable
                                 @change="getProductModel($event, scope.row)"
                                 style="width: 100%">
                        <el-option v-for="item in scope.row.modelOptions || []"
                                   :key="item.id"
                                   :label="item.model"
                                   :value="item.id" />
                      </el-select>
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column prop="unit"
                                 label="单位">
                  <template #default="scope">
                    <el-form-item :prop="`products.${scope.$index}.unit`"
                                  class="product-table-form-item">
                      <el-input v-model="scope.row.unit"
                                placeholder="单位"
                                clearable />
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column prop="unitPrice"
                                 label="单价">
                  <template #default="scope">
                    <el-form-item :prop="`products.${scope.$index}.unitPrice`"
                                  class="product-table-form-item">
                      <el-input-number v-model="scope.row.unitPrice"
                                       :min="0"
                                       :precision="2"
                                       style="width: 100%" />
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column label="操作"
                                 width="80"
                                 align="center">
                  <template #default="scope">
                    <el-button link
                               type="danger"
                               @click="removeProduct(scope.$index)">删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
              <el-empty v-else
                        description="暂无产品,请点击添加产品"
                        :image-size="80" />
            </div>
          </el-card>
          <!-- 备注信息 -->
          <el-card class="form-card"
                   shadow="hover">
            <template #header>
              <div class="card-header-wrapper">
                <el-icon class="card-icon">
                  <EditPen />
                </el-icon>
                <span class="card-title">备注信息</span>
              </div>
            </template>
            <div class="form-content">
              <el-form-item label="备注"
                            prop="remark">
                <el-input type="textarea"
                          v-model="form.remark"
                          placeholder="请输入备注信息(选填)"
                          :rows="4"
                          maxlength="500"
                          show-word-limit></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="运费">
                <el-input-number v-model="form.freight" :precision="2" :min="0" style="width: 100%" @change="calculateTotal" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="其他费用">
                <el-input-number v-model="form.otherFee" :precision="2" :min="0" style="width: 100%" @change="calculateTotal" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item label="折扣率(%)">
                <el-input-number v-model="form.discountRate" :precision="2" :min="0" :max="100" style="width: 100%" @change="calculateTotal" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="折扣金额">
                <el-input-number v-model="form.discountAmount" :precision="2" :min="0" style="width: 100%" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="报价总额">
                <el-input-number v-model="form.totalAmount" :precision="2" :min="0" style="width: 100%" readonly />
              </el-form-item>
            </el-col>
          </el-row>
        </el-card>
        <!-- 备注信息 -->
        <el-card class="form-card" shadow="never">
          <template #header>
            <span class="card-title">备注信息</span>
          </template>
          <el-form-item label="备注" prop="remark">
            <el-input type="textarea" v-model="form.remark" placeholder="请输入备注信息" rows="3"></el-input>
          </el-form-item>
        </el-card>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="handleSubmit">确 定</el-button>
        </div>
      </template>
    </el-dialog>
            </div>
          </el-card>
        </el-form>
      </div>
    </FormDialog>
    <!-- 查看详情对话框 -->
    <el-dialog v-model="viewDialogVisible" title="报价详情" width="800px">
      <el-descriptions :column="2" border>
    <el-dialog v-model="viewDialogVisible"
               title="报价详情"
               width="800px">
      <el-descriptions :column="2"
                       border>
        <el-descriptions-item label="报价单号">{{ currentQuotation.quotationNo }}</el-descriptions-item>
        <el-descriptions-item label="客户名称">{{ currentQuotation.customer }}</el-descriptions-item>
        <el-descriptions-item label="业务员">{{ currentQuotation.salesperson }}</el-descriptions-item>
        <el-descriptions-item label="报价日期">{{ currentQuotation.quotationDate }}</el-descriptions-item>
        <el-descriptions-item label="有效期至">{{ currentQuotation.validDate }}</el-descriptions-item>
        <el-descriptions-item label="付款方式">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
        <el-descriptions-item label="交货期">{{ currentQuotation.deliveryPeriod }}</el-descriptions-item>
        <el-descriptions-item label="报价状态">
          <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="报价总额" :span="2">
        <!--        <el-descriptions-item label="报价状态">-->
        <!--          <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>-->
        <!--        </el-descriptions-item>-->
        <el-descriptions-item label="报价总额"
                              :span="2">
          <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">¥{{ currentQuotation.totalAmount?.toFixed(2) }}</span>
        </el-descriptions-item>
      </el-descriptions>
      <div style="margin-top: 20px;">
      <div style="margin: 20px 0;">
        <h4>产品明细</h4>
        <el-table :data="currentQuotation.products" border style="width: 100%">
          <el-table-column prop="productName" label="产品名称" />
          <el-table-column prop="specification" label="规格型号" />
          <el-table-column prop="quantity" label="数量" />
          <el-table-column prop="unit" label="单位" />
          <el-table-column prop="unitPrice" label="单价">
        <el-table :data="currentQuotation.products"
                  border
                  style="width: 100%">
          <el-table-column prop="product"
                           label="产品名称" />
          <el-table-column prop="specification"
                           label="规格型号" />
          <el-table-column prop="unit"
                           label="单位" />
          <el-table-column prop="unitPrice"
                           label="单价">
            <template #default="scope">
              ¥{{ scope.row.unitPrice.toFixed(2) }}
            </template>
          </el-table-column>
          <el-table-column prop="amount" label="金额">
            <template #default="scope">
              ¥{{ scope.row.amount.toFixed(2) }}
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-if="currentQuotation.remark" style="margin-top: 20px;">
      <div v-if="currentQuotation.remark"
           style="margin-top: 20px;">
        <h4>备注</h4>
        <p>{{ currentQuotation.remark }}</p>
      </div>
@@ -310,295 +448,782 @@
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import Pagination from '@/components/PIMTable/Pagination.vue'
  import { ref, reactive, computed, onMounted, markRaw, shallowRef } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import {
    Search,
    Document,
    UserFilled,
    Box,
    EditPen,
    Plus,
    ArrowRight,
    Delete,
  } from "@element-plus/icons-vue";
  import Pagination from "@/components/PIMTable/Pagination.vue";
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import {
    getQuotationList,
    addQuotation,
    updateQuotation,
    deleteQuotation,
  } from "@/api/salesManagement/salesQuotation.js";
  import { userListNoPage } from "@/api/system/user.js";
  import { approveUserList } from "@/api/collaborativeApproval/approvalProcess.js";
// 响应式数据
const loading = ref(false)
const searchForm = reactive({
  quotationNo: '',
  customer: '',
  status: ''
})
  import { customerList } from "@/api/salesManagement/salesLedger.js";
  import { modelList, productTreeList } from "@/api/basicData/product.js";
const quotationList = ref([
  {
    id: 1,
    quotationNo: 'QT202312001',
    customer: '上海科技有限公司',
    salesperson: '陈志强',
    quotationDate: '2023-12-01',
    validDate: '2023-12-31',
    totalAmount: 50000.00,
    paymentMethod: '全款到付',
    deliveryPeriod: '30天',
    status: '已发送',
    remark: '重要客户报价',
    products: [
      { productName: '工业传感器', specification: 'SEN-001', quantity: 10, unit: '个', unitPrice: 5000, amount: 50000 }
    ]
  },
  {
    id: 2,
    quotationNo: 'QT202312002',
    customer: '深圳电子有限公司',
    salesperson: '刘雅婷',
    quotationDate: '2023-12-02',
    validDate: '2023-12-31',
    totalAmount: 35000.00,
    paymentMethod: '分期付款',
    deliveryPeriod: '20天',
    status: '客户确认',
    remark: '常规报价',
    products: [
      { productName: '控制模块', specification: 'CTL-002', quantity: 5, unit: '个', unitPrice: 7000, amount: 35000 }
    ]
  },
  {
    id: 3,
    quotationNo: 'QT202312003',
    customer: '北京贸易公司',
    salesperson: '王建国',
    quotationDate: '2023-12-03',
    validDate: '2023-12-31',
    totalAmount: 28000.00,
    paymentMethod: '月结',
    deliveryPeriod: '15天',
    status: '草稿',
    remark: '新客户报价',
    products: [
      { productName: '数据采集器', specification: 'DAQ-003', quantity: 4, unit: '个', unitPrice: 7000, amount: 28000 }
    ]
  // 响应式数据
  const loading = ref(false);
  const searchForm = reactive({
    quotationNo: "",
    customer: "",
    status: "",
  });
  const quotationList = ref([]);
  const productOptions = ref([]);
  const modelOptions = ref([]);
  const pagination = reactive({
    total: 3,
    currentPage: 1,
    pageSize: 100,
  });
  const dialogVisible = ref(false);
  const viewDialogVisible = ref(false);
  const dialogTitle = ref("新增报价");
  const form = reactive({
    quotationNo: "",
    customer: "",
    salesperson: "",
    quotationDate: "",
    validDate: "",
    paymentMethod: "",
    status: "草稿",
    remark: "",
    products: [],
    subtotal: 0,
    freight: 0,
    otherFee: 0,
    discountRate: 0,
    discountAmount: 0,
    totalAmount: 0,
  });
  const baseRules = {
    customer: [{ required: true, message: "请选择客户", trigger: "change" }],
    salesperson: [{ required: true, message: "请选择业务员", trigger: "change" }],
    quotationDate: [
      { required: true, message: "请选择报价日期", trigger: "change" },
    ],
    validDate: [{ required: true, message: "请选择有效期", trigger: "change" }],
    paymentMethod: [
      { required: true, message: "请输入付款方式", trigger: "blur" },
    ],
  };
  const productRowRules = {
    productId: [{ required: true, message: "请选择产品名称", trigger: "change" }],
    specificationId: [
      { required: true, message: "请选择规格型号", trigger: "change" },
    ],
    unit: [{ required: true, message: "请填写单位", trigger: "blur" }],
    unitPrice: [{ required: true, message: "请填写单价", trigger: "change" }],
  };
  const rules = computed(() => {
    const r = { ...baseRules };
    (form.products || []).forEach((_, i) => {
      r[`products.${i}.productId`] = productRowRules.productId;
      r[`products.${i}.specificationId`] = productRowRules.specificationId;
      r[`products.${i}.unit`] = productRowRules.unit;
      r[`products.${i}.unitPrice`] = productRowRules.unitPrice;
    });
    return r;
  });
  const userList = ref([]);
  const userListApprove = ref([]);
  const customerOption = ref([]);
  // 审批人节点相关
  const approverNodes = ref([{ id: 1, userId: null }]);
  let nextApproverId = 2;
  const isEdit = ref(false);
  const editId = ref(null);
  const currentQuotation = ref({});
  const formRef = ref();
  // 添加审批人节点
  function addApproverNode() {
    approverNodes.value.push({ id: nextApproverId++, userId: null });
  }
])
const pagination = reactive({
  total: 3,
  currentPage: 1,
  pageSize: 10
})
const dialogVisible = ref(false)
const viewDialogVisible = ref(false)
const dialogTitle = ref('新增报价')
const form = reactive({
  customer: '',
  salesperson: '',
  quotationDate: '',
  validDate: '',
  paymentMethod: '',
  deliveryPeriod: '',
  status: '草稿',
  remark: '',
  products: [],
  subtotal: 0,
  freight: 0,
  otherFee: 0,
  discountRate: 0,
  discountAmount: 0,
  totalAmount: 0
})
const rules = {
  customer: [{ required: true, message: '请选择客户', trigger: 'change' }],
  salesperson: [{ required: true, message: '请选择业务员', trigger: 'change' }],
  quotationDate: [{ required: true, message: '请选择报价日期', trigger: 'change' }],
  validDate: [{ required: true, message: '请选择有效期', trigger: 'change' }],
  paymentMethod: [{ required: true, message: '请选择付款方式', trigger: 'change' }],
  deliveryPeriod: [{ required: true, message: '请输入交货期', trigger: 'blur' }]
}
const isEdit = ref(false)
const editId = ref(null)
const currentQuotation = ref({})
const formRef = ref()
// 计算属性
const filteredList = computed(() => {
  let list = quotationList.value
  if (searchForm.quotationNo) {
    list = list.filter(item => item.quotationNo.includes(searchForm.quotationNo))
  // 删除审批人节点
  function removeApproverNode(index) {
    approverNodes.value.splice(index, 1);
  }
  if (searchForm.customer) {
    list = list.filter(item => item.customer === searchForm.customer)
  }
  if (searchForm.status) {
    list = list.filter(item => item.status === searchForm.status)
  }
  return list
})
// 方法
const getStatusType = (status) => {
  const statusMap = {
    '草稿': 'info',
    '已发送': 'primary',
    '客户确认': 'success',
    '已过期': 'danger'
  }
  return statusMap[status] || 'info'
}
  // 计算属性
  const filteredList = computed(() => {
    let list = quotationList.value;
    return list;
  });
const handleSearch = () => {
  // 搜索逻辑已在computed中处理
}
  // 方法
  const getStatusType = status => {
    const statusMap = {
      待审批: "info",
      审核中: "primary",
      通过: "success",
      拒绝: "danger",
    };
    return statusMap[status] || "info";
  };
const resetSearch = () => {
  searchForm.quotationNo = ''
  searchForm.customer = ''
  searchForm.status = ''
}
  const resetSearch = () => {
    searchForm.quotationNo = "";
    searchForm.customer = "";
    searchForm.status = "";
    // 重置到第一页并重新查询
    pagination.currentPage = 1;
    handleSearch();
  };
const handleAdd = () => {
  dialogTitle.value = '新增报价'
  isEdit.value = false
  resetForm()
  dialogVisible.value = true
}
const handleView = (row) => {
  currentQuotation.value = row
  viewDialogVisible.value = true
}
const handleEdit = (row) => {
  dialogTitle.value = '编辑报价'
  isEdit.value = true
  editId.value = row.id
  Object.assign(form, row)
  dialogVisible.value = true
}
const handleDelete = (row) => {
  ElMessageBox.confirm('确认删除该报价单吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const index = quotationList.value.findIndex(item => item.id === row.id)
    if (index > -1) {
      quotationList.value.splice(index, 1)
      pagination.total--
      ElMessage.success('删除成功')
    }
  })
}
const resetForm = () => {
  form.customer = ''
  form.salesperson = ''
  form.quotationDate = ''
  form.validDate = ''
  form.paymentMethod = ''
  form.deliveryPeriod = ''
  form.status = '草稿'
  form.remark = ''
  form.products = []
  form.subtotal = 0
  form.freight = 0
  form.otherFee = 0
  form.discountRate = 0
  form.discountAmount = 0
  form.totalAmount = 0
}
const addProduct = () => {
  form.products.push({
    productName: '',
    specification: '',
    quantity: 1,
    unit: '',
    unitPrice: 0,
    amount: 0
  })
}
const removeProduct = (index) => {
  form.products.splice(index, 1)
  calculateSubtotal()
}
const calculateAmount = (product) => {
  product.amount = product.quantity * product.unitPrice
  calculateSubtotal()
}
const calculateSubtotal = () => {
  form.subtotal = form.products.reduce((sum, product) => sum + product.amount, 0)
  calculateTotal()
}
const calculateTotal = () => {
  form.discountAmount = form.subtotal * (form.discountRate / 100)
  form.totalAmount = form.subtotal + form.freight + form.otherFee - form.discountAmount
}
const handleCustomerChange = () => {
  // 可以根据客户信息自动填充一些默认值
}
const handleSubmit = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      if (form.products.length === 0) {
        ElMessage.warning('请至少添加一个产品')
        return
  const handleAdd = async () => {
    dialogTitle.value = "新增报价";
    isEdit.value = false;
    resetForm();
    // 重置审批人节点
    approverNodes.value = [{ id: 1, userId: null }];
    nextApproverId = 2;
    dialogVisible.value = true;
    let userLists = await userListNoPage();
    // 只复制需要的字段,避免将组件引用放入响应式对象
    userList.value = (userLists.data || []).map(item => ({
      userId: item.userId,
      nickName: item.nickName || "",
      userName: item.userName || "",
    }));
    approveUserList({ approveType: 6 }).then(res => {
      userListApprove.value = res.data;
    });
    getProductOptions();
    customerList().then(res => {
      // 只复制需要的字段,避免将组件引用放入响应式对象
      customerOption.value = (Array.isArray(res) ? res : []).map(item => ({
        id: item.id,
        customerName: item.customerName || "",
        taxpayerIdentificationNumber: item.taxpayerIdentificationNumber || "",
      }));
    });
  };
  const getProductOptions = () => {
    // 返回 Promise,便于编辑时 await 确保能反显
    return productTreeList().then(res => {
      productOptions.value = convertIdToValue(res);
      return productOptions.value;
    });
  };
  function convertIdToValue(data) {
    return data.map(item => {
      const { id, children, ...rest } = item;
      const newItem = {
        ...rest,
        value: id, // 将 id 改为 value
      };
      if (children && children.length > 0) {
        newItem.children = convertIdToValue(children);
      }
      if (isEdit.value) {
        // 编辑
        const index = quotationList.value.findIndex(item => item.id === editId.value)
        if (index > -1) {
          quotationList.value[index] = { ...form, id: editId.value }
          ElMessage.success('编辑成功')
      return newItem;
    });
  }
  // 根据名称反查节点 id,便于仅存名称时的反显
  function findNodeIdByLabel(nodes, label) {
    if (!label) return null;
    for (let i = 0; i < nodes.length; i++) {
      const node = nodes[i];
      if (node.label === label) return node.value;
      if (node.children && node.children.length > 0) {
        const found = findNodeIdByLabel(node.children, label);
        if (found !== null && found !== undefined) return found;
      }
    }
    return null;
  }
  const getModels = (value, row) => {
    if (!row) return;
    // 如果清空选择,则清空相关字段
    if (!value) {
      row.productId = "";
      row.product = "";
      row.modelOptions = [];
      row.specificationId = "";
      row.specification = "";
      row.unit = "";
      return;
    }
    // 更新 productId(v-model 已经自动更新,这里确保一致性)
    row.productId = value;
    // 找到对应的 label 并赋值给 row.product
    const label = findNodeById(productOptions.value, value);
    if (label) {
      row.product = label;
    }
    // 获取规格型号列表,设置到当前行的 modelOptions
    modelList({ id: value }).then(res => {
      row.modelOptions = res || [];
    });
  };
  const getProductModel = (value, row) => {
    if (!row) return;
    // 如果清空选择,则清空相关字段
    if (!value) {
      row.specificationId = "";
      row.specification = "";
      row.unit = "";
      return;
    }
    // 更新 specificationId(v-model 已经自动更新,这里确保一致性)
    row.specificationId = value;
    const modelOptions = row.modelOptions || [];
    const index = modelOptions.findIndex(item => item.id === value);
    if (index !== -1) {
      row.specification = modelOptions[index].model;
      row.unit = modelOptions[index].unit;
    } else {
      row.specification = "";
      row.unit = "";
    }
  };
  const findNodeById = (nodes, productId) => {
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].value === productId) {
        return nodes[i].label; // 找到节点,返回 label
      }
      if (nodes[i].children && nodes[i].children.length > 0) {
        const foundLabel = findNodeById(nodes[i].children, productId);
        if (foundLabel) {
          return foundLabel; // 在子节点中找到,返回 label
        }
      } else {
        // 新增
        const newId = Math.max(...quotationList.value.map(item => item.id)) + 1
        const quotationNo = `QT${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(new Date().getDate()).padStart(2, '0')}${String(newId).padStart(3, '0')}`
        quotationList.value.push({
          ...form,
          id: newId,
          quotationNo: quotationNo
        })
        pagination.total++
        ElMessage.success('新增成功')
      }
      dialogVisible.value = false
    }
  })
}
    return null; // 没有找到节点,返回null
  };
  const handleView = row => {
    // 只复制需要的字段,避免将组件引用放入响应式对象
    currentQuotation.value = {
      quotationNo: row.quotationNo || "",
      customer: row.customer || "",
      salesperson: row.salesperson || "",
      quotationDate: row.quotationDate || "",
      validDate: row.validDate || "",
      paymentMethod: row.paymentMethod || "",
      status: row.status || "",
      remark: row.remark || "",
      products: row.products
        ? row.products.map(product => ({
            productId: product.productId || "",
            product: product.product || product.productName || "",
            specificationId: product.specificationId || "",
            specification: product.specification || "",
            quantity: product.quantity || 0,
            unit: product.unit || "",
            unitPrice: product.unitPrice || 0,
            amount: product.amount || 0,
          }))
        : [],
      totalAmount: row.totalAmount || 0,
    };
    viewDialogVisible.value = true;
  };
const handleCurrentChange = (val) => {
  pagination.currentPage = val.page
  pagination.pageSize = val.limit
}
  const handleEdit = async row => {
    dialogTitle.value = "编辑报价";
    isEdit.value = true;
    editId.value = row.id;
    form.id = row.id || form.id || null;
    // 先加载产品树数据,否则 el-tree-select 无法反显产品名称
    await getProductOptions();
    // 只复制需要的字段,避免将组件引用放入响应式对象
    form.quotationNo = row.quotationNo || "";
    form.customer = row.customer || "";
    form.salesperson = row.salesperson || "";
    form.quotationDate = row.quotationDate || "";
    form.validDate = row.validDate || "";
    form.paymentMethod = row.paymentMethod || "";
    form.status = row.status || "草稿";
    form.remark = row.remark || "";
    form.products = row.products
      ? await Promise.all(
          row.products.map(async product => {
            const productName = product.product || product.productName || "";
            // 优先用 productId;如果只有名称,尝试反查 id 以便树选择器反显
            const resolvedProductId = product.productId
              ? Number(product.productId)
              : findNodeIdByLabel(productOptions.value, productName) || "";
            // 如果有产品ID,加载对应的规格型号列表
            let modelOptions = [];
            let resolvedSpecificationId = product.specificationId || "";
            if (resolvedProductId) {
              try {
                const res = await modelList({ id: resolvedProductId });
                modelOptions = res || [];
                // 如果返回的数据没有 specificationId,但有 specification 名称,根据名称查找 ID
                if (!resolvedSpecificationId && product.specification) {
                  const foundModel = modelOptions.find(
                    item => item.model === product.specification
                  );
                  if (foundModel) {
                    resolvedSpecificationId = foundModel.id;
                  }
                }
              } catch (error) {
                console.error("加载规格型号失败:", error);
              }
            }
            return {
              productId: resolvedProductId,
              product: productName,
              specificationId: resolvedSpecificationId,
              specification: product.specification || "",
              quantity: product.quantity || 0,
              unit: product.unit || "",
              unitPrice: product.unitPrice || 0,
              amount: product.amount || 0,
              modelOptions: modelOptions, // 为每行添加独立的规格型号列表
            };
          })
        )
      : [];
    form.subtotal = row.subtotal || 0;
    form.freight = row.freight || 0;
    form.otherFee = row.otherFee || 0;
    form.discountRate = row.discountRate || 0;
    form.discountAmount = row.discountAmount || 0;
    form.totalAmount = row.totalAmount || 0;
    // 反显审批人
    if (row.approveUserIds) {
      const userIds = row.approveUserIds.split(",");
      approverNodes.value = userIds.map((userId, idx) => ({
        id: idx + 1,
        userId: parseInt(userId.trim()),
      }));
      nextApproverId = userIds.length + 1;
    } else {
      approverNodes.value = [{ id: 1, userId: null }];
      nextApproverId = 2;
    }
    // 加载用户列表
    let userLists = await userListNoPage();
    userList.value = (userLists.data || []).map(item => ({
      userId: item.userId,
      nickName: item.nickName || "",
      userName: item.userName || "",
    }));
    dialogVisible.value = true;
  };
  const handleDelete = row => {
    ElMessageBox.confirm("确认删除该报价单吗?", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }).then(() => {
      const index = quotationList.value.findIndex(item => item.id === row.id);
      if (index > -1) {
        deleteQuotation(row.id).then(res => {
          // console.log(res)
          if (res.code === 200) {
            ElMessage.success("删除成功");
            handleSearch();
          }
        });
        // quotationList.value.splice(index, 1)
        // pagination.total--
        // ElMessage.success('删除成功')
      }
    });
  };
  const resetForm = () => {
    form.customer = "";
    form.salesperson = "";
    form.quotationDate = "";
    form.validDate = "";
    form.paymentMethod = "";
    form.status = "草稿";
    form.remark = "";
    form.products = [];
    form.subtotal = 0;
    form.freight = 0;
    form.otherFee = 0;
    form.discountRate = 0;
    form.discountAmount = 0;
    form.totalAmount = 0;
  };
  const addProduct = () => {
    form.products.push({
      productId: "",
      product: "",
      productName: "",
      specificationId: "",
      specification: "",
      quantity: 1,
      unit: "",
      unitPrice: 0,
      amount: 0,
      modelOptions: [], // 为每行添加独立的规格型号列表
    });
  };
  const removeProduct = index => {
    form.products.splice(index, 1);
    calculateSubtotal();
  };
  const calculateAmount = product => {
    product.amount = product.quantity * product.unitPrice;
    calculateSubtotal();
  };
  const calculateSubtotal = () => {
    form.subtotal = form.products.reduce(
      (sum, product) => sum + product.amount,
      0
    );
    calculateTotal();
  };
  const calculateTotal = () => {
    form.discountAmount = form.subtotal * (form.discountRate / 100);
    form.totalAmount =
      form.subtotal + form.freight + form.otherFee - form.discountAmount;
  };
  const handleCustomerChange = () => {
    // 可以根据客户信息自动填充一些默认值
  };
  const handleSubmit = () => {
    formRef.value.validate(valid => {
      if (valid) {
        if (form.products.length === 0) {
          ElMessage.warning("请至少添加一个产品");
          return;
        }
        // 审批人必填校验
        const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
        if (hasEmptyApprover) {
          ElMessage.error("请为所有审批节点选择审批人!");
          return;
        }
        // 收集所有节点的审批人id
        form.approveUserIds = approverNodes.value
          .map(node => node.userId)
          .join(",");
        // 计算所有产品的单价总和
        form.totalAmount = form.products.reduce((sum, product) => {
          const price = Number(product.unitPrice) || 0;
          return sum + price;
        }, 0);
        if (isEdit.value) {
          // 编辑
          const index = quotationList.value.findIndex(
            item => item.id === editId.value
          );
          if (index > -1) {
            updateQuotation(form).then(res => {
              // console.log(res)
              if (res.code === 200) {
                ElMessage.success("编辑成功");
                dialogVisible.value = false;
                handleSearch();
              }
            });
          }
        } else {
          // 新增
          addQuotation(form).then(res => {
            if (res.code === 200) {
              ElMessage.success("新增成功");
              dialogVisible.value = false;
              handleSearch();
            }
          });
        }
      }
    });
  };
  const handleCurrentChange = val => {
    pagination.currentPage = val.page;
    pagination.pageSize = val.limit;
    // 分页变化时重新查询列表
    handleSearch();
  };
  const handleSearch = () => {
    const params = {
      // 后端分页参数:current / size
      current: pagination.currentPage,
      size: pagination.pageSize,
      ...searchForm,
    };
    getQuotationList(params).then(res => {
      // console.log(res)
      if (res.code === 200) {
        // 只复制需要的字段,避免将组件引用或其他对象放入响应式对象
        quotationList.value = (res.data.records || []).map(item => ({
          id: item.id,
          quotationNo: item.quotationNo || "",
          customer: item.customer || "",
          salesperson: item.salesperson || "",
          quotationDate: item.quotationDate || "",
          validDate: item.validDate || "",
          paymentMethod: item.paymentMethod || "",
          status: item.status || "草稿",
          // 审批人(用于编辑时反显)
          approveUserIds: item.approveUserIds || "",
          remark: item.remark || "",
          products: item.products
            ? item.products.map(product => ({
                productId: product.productId || "",
                product: product.product || product.productName || "",
                specificationId: product.specificationId || "",
                specification: product.specification || "",
                quantity: product.quantity || 0,
                unit: product.unit || "",
                unitPrice: product.unitPrice || 0,
                amount: product.amount || 0,
              }))
            : [],
          subtotal: item.subtotal || 0,
          freight: item.freight || 0,
          otherFee: item.otherFee || 0,
          discountRate: item.discountRate || 0,
          discountAmount: item.discountAmount || 0,
          totalAmount: item.totalAmount || 0,
        }));
        pagination.total = res.data.total;
      }
    });
    customerList().then(res => {
      // 只复制需要的字段,避免将组件引用放入响应式对象
      customerOption.value = (Array.isArray(res) ? res : []).map(item => ({
        id: item.id,
        customerName: item.customerName || "",
        taxpayerIdentificationNumber: item.taxpayerIdentificationNumber || "",
      }));
    });
  };
  onMounted(() => {
    handleSearch();
  });
</script>
<style scoped>
.search-row {
  margin-bottom: 20px;
}
<style scoped lang="scss">
  .search-row {
    margin-bottom: 20px;
  }
.form-card {
  margin-bottom: 20px;
}
  .quotation-form-container {
    padding: 10px 0;
    max-height: calc(100vh - 200px);
    overflow-y: auto;
.card-title {
  font-weight: bold;
  color: #303133;
}
    &::-webkit-scrollbar {
      width: 6px;
      height: 6px;
    }
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
    &::-webkit-scrollbar-thumb {
      background: #c1c1c1;
      border-radius: 3px;
.dialog-footer {
  text-align: right;
}
      &:hover {
        background: #a8a8a8;
      }
    }
  }
  .quotation-form {
    .el-form-item {
      margin-bottom: 22px;
    }
  }
  .form-card {
    margin-bottom: 24px;
    border-radius: 8px;
    transition: all 0.3s ease;
    &:hover {
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08) !important;
    }
    :deep(.el-card__header) {
      padding: 16px 20px;
      background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
      border-bottom: 1px solid #ebeef5;
    }
    :deep(.el-card__body) {
      padding: 20px;
    }
  }
  .card-header-wrapper {
    display: flex;
    align-items: center;
    gap: 8px;
    .card-icon {
      font-size: 18px;
      color: #409eff;
    }
    .card-title {
      font-weight: 600;
      font-size: 16px;
      color: #303133;
      flex: 1;
    }
    .header-btn {
      margin-left: auto;
    }
  }
  .form-content {
    padding: 8px 0;
  }
  .product-table-form-item {
    margin-bottom: 0;
    :deep(.el-form-item__content) {
      margin-left: 0 !important;
    }
    :deep(.el-form-item__label) {
      width: auto;
      min-width: auto;
    }
  }
  .approver-nodes-container {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    padding: 12px 0;
  }
  .approver-node-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: #f8f9fa;
    border-radius: 8px;
    border: 1px solid #e4e7ed;
    transition: all 0.3s ease;
    min-width: 180px;
    &:hover {
      border-color: #409eff;
      background: #f0f7ff;
      box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
    }
  }
  .approver-node-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: #606266;
    .node-step {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 24px;
      height: 24px;
      background: #409eff;
      color: #fff;
      border-radius: 50%;
      font-size: 12px;
      font-weight: 600;
    }
    .node-text {
      font-weight: 500;
    }
    .arrow-icon {
      color: #909399;
      font-size: 14px;
    }
  }
  .approver-select {
    width: 100%;
    min-width: 150px;
  }
  .remove-btn {
    margin-top: 4px;
  }
  .product-table {
    :deep(.el-table__header) {
      background-color: #f5f7fa;
      th {
        background-color: #f5f7fa !important;
        color: #606266;
        font-weight: 600;
      }
    }
    :deep(.el-table__row) {
      &:hover {
        background-color: #f5f7fa;
      }
    }
    :deep(.el-table__cell) {
      padding: 12px 0;
    }
  }
  .dialog-footer {
    text-align: right;
  }
  // 响应式优化
  @media (max-width: 1200px) {
    .approver-nodes-container {
      gap: 16px;
    }
    .approver-node-item {
      min-width: 160px;
    }
  }
</style>