<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
      <el-form-item label="订单编号" prop="orderNo">
        <el-input
          v-model="queryParams.orderNo"
          placeholder="请输入订单编号"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="品牌方" prop="brandTenantId">
        <el-select v-model="queryParams.brandTenantId" placeholder="请选择品牌方" clearable filterable>
          <el-option
            v-for="item in brandTenantList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="镜片厂" prop="lensFactoryTenantId">
        <el-select v-model="queryParams.lensFactoryTenantId" placeholder="请选择镜片厂" clearable filterable>
          <el-option
            v-for="item in lensFactoryList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="订单状态" prop="orderStatus">
        <el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable @change="handleOrderStatusChange">
          <el-option
            v-for="dict in dict.type.jy_order_status"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="采购结算" prop="purchaseSettleStatus">
        <el-select v-model="queryParams.purchaseSettleStatus" placeholder="请选择" clearable>
          <el-option
            v-for="dict in dict.type.jy_purchase_settle_status"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="销售结算" prop="saleSettleStatus">
        <el-select v-model="queryParams.saleSettleStatus" placeholder="请选择" clearable>
          <el-option
            v-for="dict in dict.type.jy_sale_settle_status"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="收货人" prop="receiverName">
        <el-input
          v-model="queryParams.receiverName"
          placeholder="请输入收货人姓名"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['jysystem:order:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['jysystem:order:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['jysystem:order:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="el-icon-document"
          size="mini"
          @click="handleGenerateSettlement"
          v-hasPermi="['jysystem:feeSettlement:generate']"
        >生成费用结算单</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          :disabled="multiple"
          @click="handleBatchExportExcel"
          v-hasPermi="['jysystem:order:export']"
        >批量导出Excel</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="el-icon-download"
          size="mini"
          :disabled="multiple"
          @click="handleBatchExportPdf"
          v-hasPermi="['jysystem:order:export']"
        >批量导出PDF</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['jysystem:order:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          :type="activeQuickFilter === 'pendingAssign' ? 'primary' : ''"
          plain
          size="mini"
          @click="handleQuickFilter('pendingAssign')"
        >待分配</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          :type="activeQuickFilter === 'exchangeApply' ? 'primary' : ''"
          plain
          size="mini"
          @click="handleQuickFilter('exchangeApply')"
        >换货申请</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          :type="activeQuickFilter === 'exchangeRejected' ? 'primary' : ''"
          plain
          size="mini"
          @click="handleQuickFilter('exchangeRejected')"
        >拒绝换货申请</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="orderList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="订单编号" align="center" prop="orderNo" min-width="200" show-overflow-tooltip />
      <el-table-column label="品牌方" align="center" prop="brandTenantName" min-width="110" show-overflow-tooltip />
      <el-table-column label="镜片厂" align="center" min-width="110" show-overflow-tooltip>
        <template slot-scope="scope">
          <span>{{ formatLensFactory(scope.row) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="通用镜片" align="center" min-width="140" show-overflow-tooltip>
        <template slot-scope="scope">
          <span>{{ formatLens(scope.row) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="B价格" align="center" width="90">
        <template slot-scope="scope">
          <span>{{ formatPriceAmount(formatPriceB(scope.row)) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="C价格" align="center" width="90">
        <template slot-scope="scope">
          <span>{{ formatPriceAmount(formatPriceC(scope.row)) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="物流费用" align="center" width="90">
        <template slot-scope="scope">
          <span>{{ formatPriceAmount(formatLogisticsFee(scope.row)) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="渐进多焦点价格" align="center" width="120">
        <template slot-scope="scope">
          <span>{{ formatPriceAmount(formatProgressiveMultifocalPrice(scope.row)) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="订单状态" align="center" prop="orderStatus" width="130">
        <template slot-scope="scope">
          <el-select
            v-if="canEditOrderStatus"
            v-model="scope.row.orderStatus"
            size="mini"
            class="order-status-select"
            @visible-change="visible => handleStatusSelectVisible(scope.row, visible)"
            @change="handleOrderStatusChange(scope.row)"
          >
            <el-option
              v-for="dict in dict.type.jy_order_status"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
          <dict-tag v-else :options="dict.type.jy_order_status" :value="scope.row.orderStatus"/>
        </template>
      </el-table-column>
      <el-table-column label="采购结算" align="center" prop="purchaseSettleStatus" width="90">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.jy_purchase_settle_status" :value="scope.row.purchaseSettleStatus"/>
        </template>
      </el-table-column>
      <el-table-column label="销售结算" align="center" prop="saleSettleStatus" width="90">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.jy_sale_settle_status" :value="scope.row.saleSettleStatus"/>
        </template>
      </el-table-column>
      <el-table-column label="收货人" align="center" prop="receiverName" width="90" />
      <el-table-column label="手机号" align="center" prop="receiverPhone" width="120" />
      <el-table-column label="收货地址" align="center" prop="receiverAddress" min-width="160" show-overflow-tooltip />
      <el-table-column label="创建时间" align="center" prop="createTime" width="160" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="420" fixed="right">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleDetail(scope.row)"
            v-hasPermi="['jysystem:order:query']"
          >详情</el-button>
          <el-button
            v-if="canViewLogistics(scope.row)"
            size="mini"
            type="text"
            @click="handleViewLogistics(scope.row)"
            v-hasPermi="['jysystem:order:query']"
          >查看物流</el-button>
          <el-button
            v-if="scope.row.orderStatus === ORDER_STATUS_SUBMITTED || scope.row.orderStatus === ORDER_STATUS_REJECTED || scope.row.orderStatus === ORDER_STATUS_CANCELLED || scope.row.orderStatus === ORDER_STATUS_WITHDRAWN"
            size="mini"
            type="text"
            icon="el-icon-s-check"
            @click="handleAssign(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >分配</el-button>
          <el-button
            v-if="scope.row.orderStatus === ORDER_STATUS_SUBMITTED"
            size="mini"
            type="text"
            icon="el-icon-close"
            @click="handleReject(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >驳回</el-button>
          <el-button
            v-if="scope.row.orderStatus === ORDER_STATUS_WITHDRAWN"
            size="mini"
            type="text"
            icon="el-icon-circle-close"
            @click="handleClose(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >关闭</el-button>
          <el-button
            v-if="canCompleteOrder(scope.row)"
            size="mini"
            type="text"
            icon="el-icon-check"
            @click="handleComplete(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >完成</el-button>
          <el-button
            v-if="scope.row.orderStatus === ORDER_STATUS_EXCHANGE_APPLY"
            size="mini"
            type="text"
            icon="el-icon-check"
            style="color: #67c23a"
            @click="handleAgreeExchange(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >同意换货申请</el-button>
          <el-button
            v-if="scope.row.orderStatus === ORDER_STATUS_EXCHANGE_APPLY"
            size="mini"
            type="text"
            icon="el-icon-close"
            style="color: #f56c6c"
            @click="handleRejectExchange(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >拒绝换货申请</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['jysystem:order:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['jysystem:order:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <el-dialog
      :visible.sync="open"
      width="1200px"
      append-to-body
      destroy-on-close
      custom-class="lens-order-form-dialog"
    >
      <div slot="title" class="lens-dialog-header">
        <div class="lens-dialog-title-wrap">
          <h3 class="lens-dialog-title">{{ title }}</h3>
          <p class="lens-dialog-subtitle">{{ formDialogSubtitle }}</p>
        </div>
      </div>
      <el-form ref="form" :model="form" :rules="rules" label-width="110px" class="lens-order-form">
        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">01</span>
            <div class="section-text">
              <h4>订单信息</h4>
              <p>订单基础信息、品牌方与镜片配置</p>
            </div>
          </div>
          <el-row :gutter="20" class="section-body">
            <el-col :span="12">
              <el-form-item label="订单编号" prop="orderNo">
                <el-input v-model="form.orderNo" placeholder="留空则自动生成" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="订单状态" prop="orderStatus">
                <el-select v-model="form.orderStatus" placeholder="请选择订单状态" style="width: 100%">
                  <el-option
                    v-for="dict in dict.type.jy_order_status"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="品牌方" prop="brandTenantId">
                <el-select v-model="form.brandTenantId" placeholder="请选择品牌方" clearable filterable style="width: 100%">
                  <el-option
                    v-for="item in brandTenantList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="镜片厂" prop="lensFactoryTenantId">
                <el-select v-model="form.lensFactoryTenantId" placeholder="请选择镜片厂" clearable filterable style="width: 100%" @change="handleFormLensFactoryChange">
                  <el-option
                    v-for="item in lensFactoryList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="产品">
                <el-input :value="formatProduct(form)" disabled />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="通用镜片" prop="lensId">
                <el-select v-model="form.lensId" placeholder="请选择通用镜片" clearable filterable style="width: 100%">
                  <el-option
                    v-for="item in lensList"
                    :key="item.id"
                    :label="formatLensOption(item)"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">02</span>
            <div class="section-text">
              <h4>价格与结算</h4>
              <p>价格信息及采购、销售结算状态</p>
            </div>
          </div>
          <el-row :gutter="20" class="section-body">
            <el-col :span="8">
              <el-form-item label="B价格" prop="priceB">
                <el-input-number v-model="form.priceB" :precision="2" :min="0" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="C价格" prop="priceC">
                <el-input-number v-model="form.priceC" :precision="2" :min="0" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="物流费用" prop="logisticsFee">
                <el-input-number v-model="form.logisticsFee" :precision="2" :min="0" controls-position="right" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="渐进多焦点">
                <el-switch
                  v-model="form.progressiveMultifocal"
                  :active-value="1"
                  :inactive-value="0"
                  active-text="是"
                  inactive-text="否"
                  @change="handleProgressiveMultifocalChange"
                />
              </el-form-item>
            </el-col>
            <el-col v-if="form.progressiveMultifocal === 1" :span="8">
              <el-form-item label="渐进多焦点价格" prop="progressiveMultifocalPrice">
                <el-input-number
                  v-model="form.progressiveMultifocalPrice"
                  :precision="2"
                  :min="0"
                  controls-position="right"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="采购结算" prop="purchaseSettleStatus">
                <el-radio-group v-model="form.purchaseSettleStatus">
                  <el-radio
                    v-for="dict in dict.type.jy_purchase_settle_status"
                    :key="dict.value"
                    :label="dict.value"
                  >{{ dict.label }}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="销售结算" prop="saleSettleStatus">
                <el-radio-group v-model="form.saleSettleStatus">
                  <el-radio
                    v-for="dict in dict.type.jy_sale_settle_status"
                    :key="dict.value"
                    :label="dict.value"
                  >{{ dict.label }}</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">03</span>
            <div class="section-text">
              <h4>收货信息</h4>
              <p>镜片寄送地址与联系方式</p>
            </div>
          </div>
          <el-row :gutter="20" class="section-body">
            <el-col :span="8">
              <el-form-item label="收货人姓名" prop="receiverName">
                <el-input v-model="form.receiverName" placeholder="请输入收货人姓名" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="收货人手机号" prop="receiverPhone">
                <el-input v-model="form.receiverPhone" placeholder="请输入收货人手机号" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="收货人地址" prop="receiverAddress">
                <el-input v-model="form.receiverAddress" placeholder="请输入收货人地址" />
              </el-form-item>
            </el-col>
          </el-row>
        </section>

        <section class="lens-form-section lens-form-section--optometry">
          <div class="section-head">
            <span class="section-index">04</span>
            <div class="section-text">
              <h4>验光参数</h4>
              <p>录入左右眼验光数据</p>
            </div>
          </div>
          <div class="section-body">
            <el-table :data="form.optometryList" class="lens-optometry-table" size="small">
              <el-table-column label="左右" align="center" width="100">
                <template slot-scope="scope">
                  <span>{{ scope.row.eyeSide === 'OS' ? '左眼(OS)' : '右眼(OD)' }}</span>
                </template>
              </el-table-column>
              <el-table-column label="球镜S（度）" align="center" min-width="90">
                <template slot-scope="scope">
                  <el-input-number v-model="scope.row.sphereS" :precision="2" :step="0.25" controls-position="right" style="width: 100%" @change="val => onSphereSChange(val, scope.row)" />
                </template>
              </el-table-column>
              <el-table-column label="柱镜C（度）" align="center" min-width="90">
                <template slot-scope="scope">
                  <el-input-number
                    v-model="scope.row.cylinderC"
                    :precision="2"
                    :step="0.25"
                    :min="getCylinderCMin(scope.row)"
                    :max="getCylinderCMax(scope.row)"
                    controls-position="right"
                    style="width: 100%"
                    @change="val => onCylinderCChange(val, scope.row)"
                  />
                </template>
              </el-table-column>
              <el-table-column label="轴位A（度）" align="center" min-width="80">
                <template slot-scope="scope">
                  <el-input-number v-model="scope.row.axisA" :min="0" :max="180" :disabled="!isAxisAEditable(scope.row)" controls-position="right" style="width: 100%" />
                </template>
              </el-table-column>
              <el-table-column label="瞳距(mm)" align="center" min-width="90">
                <template slot-scope="scope">
                  <el-input-number v-model="scope.row.pd" :precision="2" :min="0" controls-position="right" style="width: 100%" />
                </template>
              </el-table-column>
              <el-table-column v-if="form.progressiveMultifocal === 1" label="瞳高(mm)" align="center" min-width="80">
                <template slot-scope="scope">
                  <el-input-number v-model="scope.row.pupilHeight" :precision="2" :min="0" controls-position="right" style="width: 100%" />
                </template>
              </el-table-column>
              <el-table-column label="远用VA(视力值)" align="center" min-width="90">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.distanceVa" placeholder="远用VA" />
                </template>
              </el-table-column>
              <el-table-column v-if="form.progressiveMultifocal === 1" label="近用ADD(屈光度)" align="center" min-width="100">
                <template slot-scope="scope">
                  <el-input-number v-model="scope.row.nearAdd" :precision="2" :step="0.25" :min="0.75" :max="4" controls-position="right" style="width: 100%" />
                </template>
              </el-table-column>
            </el-table>
          </div>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">05</span>
            <div class="section-text">
              <h4>附件与备注</h4>
              <p>上传相关资料并补充说明</p>
            </div>
          </div>
          <el-row :gutter="20" class="section-body">
            <el-col :span="24">
              <el-form-item label="附件" prop="attachment">
                <file-upload v-model="form.attachment" :limit="5" :file-type="attachmentFileTypes" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="备注" prop="remark">
                <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
              </el-form-item>
            </el-col>
          </el-row>
        </section>
      </el-form>
      <div slot="footer" class="lens-dialog-footer">
        <el-button class="lens-btn-ghost" @click="cancel">取 消</el-button>
        <el-button class="lens-btn-primary" @click="submitForm">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog title="驳回订单" :visible.sync="rejectOpen" width="520px" append-to-body>
      <el-form ref="rejectForm" :model="rejectForm" :rules="rejectRules" label-width="80px">
        <el-form-item label="订单编号">
          <span>{{ rejectForm.orderNo || '-' }}</span>
        </el-form-item>
        <el-form-item label="驳回原因" prop="reason">
          <el-input
            v-model="rejectForm.reason"
            type="textarea"
            :rows="5"
            placeholder="请输入驳回原因"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="danger" :loading="rejectLoading" @click="submitReject">确 定</el-button>
        <el-button @click="rejectOpen = false">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog title="拒绝换货申请" :visible.sync="exchangeRejectOpen" width="520px" append-to-body>
      <el-form ref="exchangeRejectForm" :model="exchangeRejectForm" :rules="exchangeRejectRules" label-width="110px">
        <el-form-item label="订单编号">
          <span>{{ exchangeRejectForm.orderNo || '-' }}</span>
        </el-form-item>
        <el-form-item label="拒绝原因" prop="reason">
          <el-input
            v-model="exchangeRejectForm.reason"
            type="textarea"
            :rows="5"
            placeholder="请输入拒绝换货申请原因"
            maxlength="500"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="danger" :loading="exchangeRejectLoading" @click="submitExchangeReject">确 定</el-button>
        <el-button @click="exchangeRejectOpen = false">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :key="assignDialogKey"
      :visible.sync="assignOpen"
      width="720px"
      append-to-body
      destroy-on-close
      custom-class="lens-order-detail-dialog"
      @closed="resetAssignDialog"
    >
      <div slot="title" class="lens-dialog-header">
        <div class="lens-dialog-title-wrap">
          <h3 class="lens-dialog-title">分配镜片厂</h3>
          <p class="lens-dialog-subtitle">{{ assignDialogSubtitle }}</p>
        </div>
      </div>
      <el-form ref="assignForm" :model="assignForm" :rules="assignRules" label-width="110px" class="lens-order-detail">
        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">01</span>
            <div class="section-text">
              <h4>订单信息</h4>
              <p>待分配订单的基础信息</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="2" border size="small" class="detail-descriptions">
              <el-descriptions-item label="订单编号">{{ assignForm.orderNo || '-' }}</el-descriptions-item>
              <el-descriptions-item label="渐进多焦点">{{ assignForm.progressiveMultifocal === 1 ? '是' : '否' }}</el-descriptions-item>
              <el-descriptions-item label="通用镜片" :span="2">{{ assignForm.lensText || '-' }}</el-descriptions-item>
            </el-descriptions>
          </div>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">02</span>
            <div class="section-text">
              <h4>分配镜片厂</h4>
              <p>选择承接该订单的镜片厂</p>
            </div>
          </div>
          <div class="section-body">
            <el-form-item label="镜片厂" prop="lensFactoryTenantId">
              <el-select
                v-model="assignForm.lensFactoryTenantId"
                placeholder="请选择镜片厂"
                clearable
                filterable
                style="width: 100%"
                @change="handleAssignFactoryChange"
              >
                <el-option
                  v-for="item in assignLensFactoryList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
          </div>
        </section>

        <section v-if="hasAssignPreview" class="lens-form-section">
          <div class="section-head">
            <span class="section-index">03</span>
            <div class="section-text">
              <h4>分配价格</h4>
              <p>根据镜片厂自动核算的价格信息</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="2" border size="small" class="detail-descriptions detail-descriptions--price">
              <el-descriptions-item v-if="assignPreview.priceB != null" label="B价格">
                {{ formatPriceAmount(assignPreview.priceB) }}
              </el-descriptions-item>
              <el-descriptions-item v-if="assignPreview.priceC != null" label="C价格">
                {{ formatPriceAmount(assignPreview.priceC) }}
              </el-descriptions-item>
              <el-descriptions-item
                v-if="assignForm.progressiveMultifocal === 1 && assignPreview.progressiveMultifocalPrice != null"
                label="渐进多焦点价格"
                :span="2"
              >
                {{ formatPriceAmount(assignPreview.progressiveMultifocalPrice) }}
              </el-descriptions-item>
            </el-descriptions>
          </div>
        </section>
      </el-form>
      <div slot="footer" class="lens-dialog-footer">
        <el-button class="lens-btn-ghost" @click="assignOpen = false">取 消</el-button>
        <el-button class="lens-btn-primary" :loading="assignLoading" @click="submitAssign">保 存</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :visible.sync="detailOpen"
      width="1200px"
      append-to-body
      custom-class="lens-order-detail-dialog"
    >
      <div slot="title" class="lens-dialog-header">
        <div class="lens-dialog-title-wrap">
          <h3 class="lens-dialog-title">订单详情</h3>
          <p class="lens-dialog-subtitle">{{ detailDialogSubtitle }}</p>
        </div>
      </div>
      <div class="lens-order-detail">
        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">01</span>
            <div class="section-text">
              <h4>订单信息</h4>
              <p>订单基础信息、品牌方与镜片配置</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="2" border size="small" class="detail-descriptions">
              <el-descriptions-item label="订单编号">{{ detail.orderNo }}</el-descriptions-item>
              <el-descriptions-item label="订单状态">
                <dict-tag :options="dict.type.jy_order_status" :value="detail.orderStatus" />
              </el-descriptions-item>
              <el-descriptions-item label="品牌方">{{ detail.brandTenantName || '-' }}</el-descriptions-item>
              <el-descriptions-item label="产品">{{ formatProduct(detail) }}</el-descriptions-item>
              <el-descriptions-item label="镜片厂">
                <el-tag
                  v-if="isPendingTagText(formatLensFactory(detail))"
                  type="danger"
                  size="small"
                  :disable-transitions="true"
                >{{ formatLensFactory(detail) }}</el-tag>
                <span v-else>{{ formatLensFactory(detail) }}</span>
              </el-descriptions-item>
              <el-descriptions-item label="通用镜片">{{ formatLens(detail) }}</el-descriptions-item>
              <el-descriptions-item label="采购结算">
                <dict-tag :options="dict.type.jy_purchase_settle_status" :value="detail.purchaseSettleStatus" />
              </el-descriptions-item>
              <el-descriptions-item label="销售结算">
                <dict-tag :options="dict.type.jy_sale_settle_status" :value="detail.saleSettleStatus" />
              </el-descriptions-item>
            </el-descriptions>
          </div>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">02</span>
            <div class="section-text">
              <h4>收货信息</h4>
              <p>镜片寄送地址与联系方式</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="2" border size="small" class="detail-descriptions">
              <el-descriptions-item label="收货人">{{ detail.receiverName || '-' }}</el-descriptions-item>
              <el-descriptions-item label="手机号">{{ detail.receiverPhone || '-' }}</el-descriptions-item>
              <el-descriptions-item label="收货地址" :span="2">{{ detail.receiverAddress || '-' }}</el-descriptions-item>
            </el-descriptions>
          </div>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">03</span>
            <div class="section-text">
              <h4>价格与结算</h4>
              <p>价格信息及合计金额</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="2" border size="small" class="detail-descriptions detail-descriptions--price">
              <el-descriptions-item label="B价格">
                <el-tag
                  v-if="isPendingTagText(formatPriceAmount(formatPriceB(detail)))"
                  type="danger"
                  size="small"
                  :disable-transitions="true"
                >{{ formatPriceAmount(formatPriceB(detail)) }}</el-tag>
                <span v-else>{{ formatPriceAmount(formatPriceB(detail)) }}</span>
              </el-descriptions-item>
              <el-descriptions-item label="C价格">
                <el-tag
                  v-if="isPendingTagText(formatPriceAmount(formatPriceC(detail)))"
                  type="danger"
                  size="small"
                  :disable-transitions="true"
                >{{ formatPriceAmount(formatPriceC(detail)) }}</el-tag>
                <span v-else>{{ formatPriceAmount(formatPriceC(detail)) }}</span>
              </el-descriptions-item>
              <el-descriptions-item label="物流费用">{{ formatPriceAmount(formatDetailLogisticsFee(detail)) }}</el-descriptions-item>
              <el-descriptions-item label="渐进多焦点">{{ detail.progressiveMultifocal === 1 ? '是' : '否' }}</el-descriptions-item>
              <el-descriptions-item v-if="detail.progressiveMultifocal === 1" label="渐进多焦点价格">
                <el-tag
                  v-if="isPendingTagText(formatPriceAmount(formatProgressiveMultifocalPrice(detail)))"
                  type="danger"
                  size="small"
                  :disable-transitions="true"
                >{{ formatPriceAmount(formatProgressiveMultifocalPrice(detail)) }}</el-tag>
                <span v-else>{{ formatPriceAmount(formatProgressiveMultifocalPrice(detail)) }}</span>
              </el-descriptions-item>
              <el-descriptions-item label="B合计">
                <el-tag
                  v-if="isPendingTagText(formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')))"
                  type="danger"
                  size="small"
                  :disable-transitions="true"
                >{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')) }}</el-tag>
                <span v-else class="price-total-value">{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')) }}</span>
              </el-descriptions-item>
              <el-descriptions-item label="C合计">
                <el-tag
                  v-if="isPendingTagText(formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')))"
                  type="danger"
                  size="small"
                  :disable-transitions="true"
                >{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')) }}</el-tag>
                <span v-else class="price-total-value">{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')) }}</span>
              </el-descriptions-item>
            </el-descriptions>
            <div class="detail-logistics-fee-block">
              <el-table :data="detailLogisticsLogList" class="lens-detail-table detail-logistics-fee-table" size="small">
                <el-table-column label="物流公司" align="center" prop="expressCompany" min-width="120" show-overflow-tooltip />
                <el-table-column label="物流单号" align="center" prop="expressNo" min-width="160" show-overflow-tooltip />
                <el-table-column label="物流费用" align="center" width="100">
                  <template slot-scope="scope">
                    <span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="发货日期" align="center" width="120">
                  <template slot-scope="scope">
                    <span>{{ formatShipDate(scope.row.operateTime) }}</span>
                  </template>
                </el-table-column>
              </el-table>
              <div v-if="!detailLogisticsLogList.length" class="detail-empty-tip">暂无物流费用记录</div>
            </div>
          </div>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">04</span>
            <div class="section-text">
              <h4>附件与备注</h4>
              <p>订单相关资料与补充说明</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="2" border size="small" class="detail-descriptions">
              <el-descriptions-item label="附件" :span="2">
                <template v-if="parseAttachment(detail.attachment).length">
                  <template v-for="(url, index) in parseAttachment(detail.attachment)">
                    <el-link
                      v-if="isAttachmentImage(url)"
                      :key="'preview-' + index"
                      type="primary"
                      class="detail-attachment-link"
                      @click="handleAttachmentPreview(url)"
                    >{{ getAttachmentName(url) }}</el-link>
                    <el-link
                      v-else
                      :key="'link-' + index"
                      :href="getAttachmentUrl(url)"
                      target="_blank"
                      type="primary"
                      class="detail-attachment-link"
                    >{{ getAttachmentName(url) }}</el-link>
                  </template>
                </template>
                <span v-else>-</span>
              </el-descriptions-item>
              <el-descriptions-item label="备注" :span="2">{{ detail.remark || '-' }}</el-descriptions-item>
            </el-descriptions>
          </div>
        </section>

        <section class="lens-form-section lens-form-section--optometry">
          <div class="section-head">
            <span class="section-index">05</span>
            <div class="section-text">
              <h4>验光参数</h4>
              <p>左右眼验光数据明细</p>
            </div>
          </div>
          <div class="section-body">
            <el-table
              :data="detailOptometryList"
              :span-method="detailOptometrySpanMethod"
              class="lens-optometry-table"
              size="small"
            >
              <el-table-column label="左右" align="center" width="100">
                <template slot-scope="scope">
                  <span>{{ scope.row.eyeSide === 'OS' ? '左眼(OS)' : '右眼(OD)' }}</span>
                </template>
              </el-table-column>
              <el-table-column label="球镜S（度）" align="center" min-width="90">
                <template slot-scope="scope">
                  <span>{{ formatDetailOptometryDecimal(scope.row.sphereS) }}</span>
                </template>
              </el-table-column>
              <el-table-column label="柱镜C（度）" align="center" min-width="90">
                <template slot-scope="scope">
                  <span>{{ formatDetailOptometryDecimal(scope.row.cylinderC) }}</span>
                </template>
              </el-table-column>
              <el-table-column align="center" min-width="80">
                <template slot="header">
                  <span>轴位A（度）</span>
                </template>
                <template slot-scope="scope">
                  <span>{{ scope.row.axisA != null ? scope.row.axisA : '-' }}</span>
                </template>
              </el-table-column>
              <el-table-column label="瞳距(mm)" align="center" min-width="90">
                <template slot-scope="scope">
                  <span>{{ formatDetailPdValue(scope.row, scope.$index) }}</span>
                </template>
              </el-table-column>
              <el-table-column v-if="detail.progressiveMultifocal === 1" label="瞳高(mm)" align="center" min-width="80">
                <template slot-scope="scope">
                  <span>{{ scope.row.pupilHeight != null ? scope.row.pupilHeight : '-' }}</span>
                </template>
              </el-table-column>
              <el-table-column label="远用VA(视力值)" align="center" min-width="90">
                <template slot-scope="scope">
                  <span>{{ scope.row.distanceVa != null && scope.row.distanceVa !== '' ? scope.row.distanceVa : '-' }}</span>
                </template>
              </el-table-column>
              <el-table-column v-if="detail.progressiveMultifocal === 1" label="近用ADD(屈光度)" align="center" min-width="100">
                <template slot-scope="scope">
                  <span>{{ formatDetailNearAdd(scope.row.nearAdd) }}</span>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </section>

        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">06</span>
            <div class="section-text">
              <h4>状态变更记录</h4>
              <p>订单全流程状态流转轨迹</p>
            </div>
          </div>
          <div class="section-body">
            <el-table :data="detail.statusLogList || []" class="lens-detail-table" size="small">
              <el-table-column label="订单状态" align="center" prop="orderStatus" width="120">
                <template slot-scope="scope">
                  <dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" />
                </template>
              </el-table-column>
              <el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip />
              <el-table-column label="操作人" align="center" prop="operator" width="100" />
              <el-table-column label="操作时间" align="center" prop="operateTime" width="160" />
            </el-table>
          </div>
        </section>
      </div>
    </el-dialog>

    <el-dialog :visible.sync="attachmentPreviewVisible" title="图片预览" width="800px" append-to-body>
      <img :src="attachmentPreviewUrl" style="max-width: 100%; display: block; margin: 0 auto;" />
    </el-dialog>

    <el-dialog
      :visible.sync="logisticsDialogVisible"
      width="720px"
      append-to-body
      custom-class="lens-order-detail-dialog"
    >
      <div slot="title" class="lens-dialog-header">
        <div class="lens-dialog-title-wrap">
          <h3 class="lens-dialog-title">物流信息</h3>
          <p class="lens-dialog-subtitle">{{ logisticsDialogSubtitle }}</p>
        </div>
      </div>
      <div class="lens-order-detail">
        <section v-if="logisticsBasic" class="lens-form-section">
          <div class="section-head">
            <span class="section-index">01</span>
            <div class="section-text">
              <h4>物流概要</h4>
              <p>订单关联的物流公司与单号</p>
            </div>
          </div>
          <div class="section-body">
            <el-descriptions :column="1" border size="small" class="detail-descriptions">
              <el-descriptions-item label="订单编号">{{ logisticsBasic.orderNo }}</el-descriptions-item>
              <el-descriptions-item label="物流公司">{{ logisticsBasic.expressCompany }}</el-descriptions-item>
              <el-descriptions-item label="物流单号">{{ logisticsBasic.expressNo }}</el-descriptions-item>
            </el-descriptions>
          </div>
        </section>
        <section class="lens-form-section">
          <div class="section-head">
            <span class="section-index">02</span>
            <div class="section-text">
              <h4>物流轨迹</h4>
              <p>最新物流动态与时间记录</p>
            </div>
          </div>
          <div class="section-body">
            <div v-if="logisticsDetail && logisticsDetail.traces && logisticsDetail.traces.length > 0" class="logistics-traces">
              <el-timeline>
                <el-timeline-item
                  v-for="(item, idx) in logisticsDetail.traces"
                  :key="idx"
                  :timestamp="item.timeDesc || ''"
                >
                  {{ item.line }}
                </el-timeline-item>
              </el-timeline>
            </div>
            <div v-else class="detail-empty-tip">未查到物流轨迹</div>
          </div>
        </section>
      </div>
      <div slot="footer" class="lens-dialog-footer">
        <el-button class="lens-btn-ghost" @click="logisticsDialogVisible = false">关 闭</el-button>
      </div>
    </el-dialog>

    <el-dialog title="生成费用结算单" :visible.sync="settlementGenerateOpen" width="480px" append-to-body>
      <el-form ref="settlementGenerateForm" :model="settlementGenerateForm" :rules="settlementGenerateRules" label-width="100px">
        <el-form-item label="结算年月" prop="settleYearMonth">
          <el-date-picker
            v-model="settlementGenerateForm.settleYearMonth"
            type="month"
            value-format="yyyy-MM"
            placeholder="选择年月"
            style="width: 100%"
          />
        </el-form-item>
        <el-alert
          title="仅汇总所选年月内已完成或换货完成状态的订单；品牌方生成应收(AR)，镜片厂生成应付(AP)。"
          type="info"
          :closable="false"
          show-icon
        />
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="settlementGenerateOpen = false">取 消</el-button>
        <el-button type="primary" :loading="settlementGenerateLoading" @click="submitGenerateSettlement">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { isExternal } from '@/utils/validate'
import { listOrder, getOrder, getOrderLogistics, delOrder, addOrder, updateOrder, previewAssignPrice, assignOrder, rejectOrder, closeOrder, completeOrder, agreeExchangeOrder, rejectExchangeOrder, changeOrderStatus } from "@/api/jysystem/order";
import { checkPermi } from "@/utils/permission";
import { listBrandTenant, listLensFactoryTenant } from "@/api/jysystem/tenant";
import { listLensOptions } from "@/api/jysystem/lens";
import { checkFeeSettlement, generateFeeSettlement } from "@/api/jysystem/feeSettlement";

export default {
  name: "Order",
  dicts: ['jy_order_status', 'jy_purchase_settle_status', 'jy_sale_settle_status'],
  data() {
    return {
      loading: true,
      ids: [],
      single: true,
      multiple: true,
      showSearch: true,
      total: 0,
      orderList: [],
      brandTenantList: [],
      lensFactoryList: [],
      assignLensFactoryList: [],
      lensList: [],
      title: "",
      open: false,
      detailOpen: false,
      detail: {},
      detailPdMode: 'single',
      PD_TYPE_SINGLE: '1',
      PD_TYPE_DUAL: '2',
      OPTOMETRY_PD_COLUMN_INDEX: 4,
      assignOpen: false,
      assignLoading: false,
      assignDialogKey: 0,
      assignDialogToken: 0,
      assignForm: {
        orderId: null,
        orderNo: null,
        lensId: null,
        lensText: '',
        progressiveMultifocal: 0,
        lensFactoryTenantId: null
      },
      assignPreview: {},
      assignRules: {
        lensFactoryTenantId: [{ required: true, message: '请选择镜片厂', trigger: 'change' }]
      },
      rejectOpen: false,
      rejectLoading: false,
      rejectForm: {
        orderId: null,
        orderNo: '',
        reason: ''
      },
      rejectRules: {
        reason: [{ required: true, message: '请输入驳回原因', trigger: 'blur' }]
      },
      exchangeRejectOpen: false,
      exchangeRejectLoading: false,
      exchangeRejectForm: {
        orderId: null,
        orderNo: '',
        reason: ''
      },
      exchangeRejectRules: {
        reason: [{ required: true, message: '请输入拒绝换货申请原因', trigger: 'blur' }]
      },
      ORDER_STATUS_DRAFT: '1',
      ORDER_STATUS_SUBMITTED: '2',
      ORDER_STATUS_REJECTED: '5',
      ORDER_STATUS_CANCELLED: '18',
      ORDER_STATUS_WITHDRAWN: '20',
      ORDER_STATUS_SHIPPED: '8',
      ORDER_STATUS_COMPLETED: '9',
      ORDER_STATUS_EXCHANGE_APPLY: '12',
      ORDER_STATUS_EXCHANGE_AGREED: '13',
      ORDER_STATUS_EXCHANGE_LOGISTICS: '15',
      ORDER_STATUS_EXCHANGE_COMPLETED: '17',
      ORDER_STATUS_EXCHANGE_REJECTED: '21',
      logisticsDialogVisible: false,
      logisticsBasic: null,
      logisticsDetail: null,
      attachmentPreviewVisible: false,
      attachmentPreviewUrl: '',
      settlementGenerateOpen: false,
      settlementGenerateLoading: false,
      settlementGenerateForm: {
        settleYearMonth: undefined
      },
      settlementGenerateRules: {
        settleYearMonth: [{ required: true, message: '请选择结算年月', trigger: 'change' }]
      },
      activeQuickFilter: null,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        orderNo: null,
        brandTenantId: null,
        lensFactoryTenantId: null,
        orderStatus: null,
        orderStatusIn: null,
        purchaseSettleStatus: null,
        saleSettleStatus: null,
        receiverName: null
      },
      form: {},
      rules: {},
      baseUrl: process.env.VUE_APP_BASE_API,
      attachmentFileTypes: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf', 'png', 'jpg', 'jpeg', 'zip']
    };
  },
  computed: {
    formDialogSubtitle() {
      if (this.form && this.form.id) {
        return '更新订单完整信息、价格结算与验光参数';
      }
      return '填写订单信息、价格结算与验光参数';
    },
    detailDialogSubtitle() {
      if (this.detail && this.detail.orderNo) {
        return `订单编号 ${this.detail.orderNo} · 查看订单完整信息与流转记录`;
      }
      return '查看订单完整信息、价格结算与流转记录';
    },
    logisticsDialogSubtitle() {
      if (this.logisticsBasic && this.logisticsBasic.orderNo) {
        return `订单编号 ${this.logisticsBasic.orderNo} · 查看物流公司与轨迹信息`;
      }
      return '查看物流公司与轨迹信息';
    },
    assignDialogSubtitle() {
      if (this.assignForm && this.assignForm.orderNo) {
        return `订单编号 ${this.assignForm.orderNo} · 选择镜片厂并确认分配价格`;
      }
      return '选择镜片厂并确认分配价格';
    },
    hasAssignPreview() {
      const preview = this.assignPreview || {};
      return preview.priceB != null
        || preview.priceC != null
        || (this.assignForm.progressiveMultifocal === 1 && preview.progressiveMultifocalPrice != null);
    },
    detailPdLabel() {
      return this.detailPdMode === 'single' ? '单瞳距' : '瞳距';
    },
    detailLogisticsLogList() {
      return this.buildDetailLogisticsLogList(this.detail);
    },
    detailOptometryList() {
      return this.sortOptometryList((this.detail && this.detail.optometryList) || []);
    },
    canEditOrderStatus() {
      return checkPermi(['jysystem:order:edit']);
    }
  },
  created() {
    this.getList();
    this.loadBrandTenants();
    this.loadLensFactoryList();
    this.loadLensList();
  },
  methods: {
    getList() {
      this.loading = true;
      listOrder(this.queryParams).then(response => {
        this.orderList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    loadBrandTenants() {
      listBrandTenant().then(response => {
        this.brandTenantList = response.data || [];
      });
    },
    loadLensFactoryList() {
      listLensFactoryTenant().then(response => {
        this.lensFactoryList = response.data || [];
      });
    },
    loadLensList() {
      listLensOptions().then(response => {
        this.lensList = response.data || [];
      });
    },
    isPendingTagText(text) {
      return text === '未分配' || text === '未核算';
    },
    formatLensOption(item) {
      if (!item) return '-';
      const name = item.productName || '';
      const material = item.material || '';
      return material ? `${name}(${material})` : name;
    },
    formatProduct(row) {
      if (!row) {
        return '-';
      }
      if (row.productModel || row.productName) {
        const model = row.productModel || '';
        const name = row.productName || '';
        return model ? `${model}(${name})` : name || '-';
      }
      return '-';
    },
    formatLens(row) {
      if (!row) {
        return '-';
      }
      if (row.lensProductName || row.lensMaterial) {
        return this.formatLensOption({ productName: row.lensProductName, material: row.lensMaterial });
      }
      return '-';
    },
    isPendingAssign(row) {
      if (!row) return false;
      const status = String(row.orderStatus);
      return status === this.ORDER_STATUS_DRAFT
        || status === this.ORDER_STATUS_SUBMITTED
        || status === this.ORDER_STATUS_REJECTED
        || status === this.ORDER_STATUS_CANCELLED
        || status === this.ORDER_STATUS_WITHDRAWN;
    },
    formatLensFactory(row) {
      if (!row) return '-';
      if (this.isPendingAssign(row)) return '未分配';
      return row.lensFactoryTenantName || '-';
    },
    formatPriceB(row) {
      if (!row) return '-';
      if (this.isExchangeOrder(row)) return '-';
      if (this.isPendingAssign(row)) return '未核算';
      return row.priceB != null ? row.priceB : '-';
    },
    formatPriceC(row) {
      if (!row) return '-';
      if (this.isExchangeOrder(row)) return '-';
      if (this.isPendingAssign(row)) return '未核算';
      return row.priceC != null ? row.priceC : '-';
    },
    formatProgressiveMultifocalPrice(row) {
      if (!row) return '-';
      if (this.isExchangeOrder(row)) return '-';
      if (Number(row.progressiveMultifocal) !== 1) return '-';
      if (this.isPendingAssign(row)) return '未核算';
      return row.progressiveMultifocalPrice != null ? row.progressiveMultifocalPrice : '-';
    },
    isExchangeOrder(row) {
      if (!row) return false;
      if (row.orderNo && String(row.orderNo).startsWith('HH')) return true;
      const status = row.orderStatus != null ? String(row.orderStatus) : '';
      return status === this.ORDER_STATUS_EXCHANGE_APPLY
        || status === this.ORDER_STATUS_EXCHANGE_AGREED
        || status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
        || status === this.ORDER_STATUS_EXCHANGE_COMPLETED;
    },
    formatDetailPriceTotal(detail, priceKey) {
      if (this.isExchangeOrder(detail)) return this.formatDetailLogisticsFee(detail);
      return this.formatPriceTotal(detail, priceKey);
    },
    formatLogisticsFee(row) {
      if (!row) return '-';
      if (!this.isExchangeOrder(row)) return '-';
      const fee = this.parseLogisticsFeeValue(row.logisticsFee);
      return fee != null ? fee : '-';
    },
    formatPriceBC(row) {
      return `${this.formatPriceB(row)} / ${this.formatPriceC(row)}`;
    },
    formatPriceAmount(value) {
      if (value == null || value === '' || value === '-') return '-';
      if (value === '未核算') return '未核算';
      const num = Number(value);
      if (Number.isNaN(num)) return value;
      return num.toFixed(2);
    },
    buildDetailLogisticsLogList(detail) {
      const list = (detail && detail.statusLogList) || [];
      return list
        .filter(item => item.expressNo != null && String(item.expressNo).trim() !== '')
        .sort((a, b) => {
          const timeA = a.operateTime ? new Date(a.operateTime).getTime() : 0;
          const timeB = b.operateTime ? new Date(b.operateTime).getTime() : 0;
          return timeB - timeA;
        });
    },
    parseLogisticsFeeValue(value) {
      if (value == null || value === '') return null;
      const num = Number(value);
      return Number.isNaN(num) ? null : num;
    },
    formatLogisticsLogFee(log, detail) {
      if (!log) return '-';
      const fee = this.parseLogisticsFeeValue(log.logisticsFee);
      if (fee != null) return fee;
      const logs = this.buildDetailLogisticsLogList(detail);
      if (logs.length === 1 && detail && detail.logisticsFee != null) {
        const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee);
        if (legacyFee != null) return legacyFee;
      }
      return '-';
    },
    sumDetailLogisticsFee(detail) {
      if (!detail) return '-';
      const logs = this.buildDetailLogisticsLogList(detail);
      let sum = 0;
      let hasFee = false;
      logs.forEach(log => {
        const fee = this.parseLogisticsFeeValue(log.logisticsFee);
        if (fee != null) {
          sum += fee;
          hasFee = true;
        }
      });
      if (!hasFee && detail.logisticsFee != null) {
        const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee);
        if (legacyFee != null) return legacyFee;
      }
      if (!hasFee) return '-';
      return sum;
    },
    formatDetailLogisticsFee(detail) {
      return this.sumDetailLogisticsFee(detail);
    },
    formatShipDate(time) {
      if (!time) {
        return '-';
      }
      const text = String(time);
      return text.length >= 10 ? text.substring(0, 10) : text;
    },
    formatPriceTotal(row, priceKey) {
      if (!row) return '-';
      if (this.isPendingAssign(row)) return '未核算';
      const base = row[priceKey] != null ? Number(row[priceKey]) : 0;
      const logisticsRaw = this.sumDetailLogisticsFee(row);
      const logistics = logisticsRaw === '-' ? 0 : Number(logisticsRaw);
      const pmf = row.progressiveMultifocalPrice != null ? Number(row.progressiveMultifocalPrice) : 0;
      if ([base, logistics, pmf].some(value => Number.isNaN(value))) return '-';
      return (base + logistics + pmf).toFixed(2);
    },
    parseAttachment(attachment) {
      if (!attachment) return [];
      return String(attachment).split(',').map(item => item.trim()).filter(item => item !== '');
    },
    getAttachmentName(url) {
      if (!url) return '';
      const index = url.lastIndexOf('/');
      return index > -1 ? url.slice(index + 1) : url;
    },
    getAttachmentUrl(url) {
      if (!url) return '';
      if (isExternal(url)) return url;
      return this.baseUrl + url;
    },
    isAttachmentImage(url) {
      const fileName = this.getAttachmentName(url);
      const ext = (fileName.split('.').pop() || '').toLowerCase();
      return ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg'].includes(ext);
    },
    handleAttachmentPreview(url) {
      this.attachmentPreviewUrl = this.getAttachmentUrl(url);
      this.attachmentPreviewVisible = true;
    },
    sortOptometryList(list) {
      const order = { OS: 0, OD: 1 };
      return [...list].sort((a, b) => {
        const aOrder = order[a.eyeSide] != null ? order[a.eyeSide] : 99;
        const bOrder = order[b.eyeSide] != null ? order[b.eyeSide] : 99;
        return aOrder - bOrder;
      });
    },
    createDefaultOptometryList() {
      return [
        { eyeSide: 'OS', sphereS: 0, cylinderC: null, axisA: null, pd: null, dualPd: null, pupilHeight: null, distanceVa: null, nearAdd: null },
        { eyeSide: 'OD', sphereS: 0, cylinderC: null, axisA: null, pd: null, dualPd: null, pupilHeight: null, distanceVa: null, nearAdd: null }
      ];
    },
    detectPdMode(optometryList) {
      if (!optometryList || !optometryList.length) {
        return 'single';
      }
      const pdType = optometryList[0].pdType;
      if (pdType === this.PD_TYPE_DUAL) return 'dual';
      if (pdType === this.PD_TYPE_SINGLE) return 'single';
      const hasDual = optometryList.some(item => item.dualPd != null);
      return hasDual ? 'dual' : 'single';
    },
    detailOptometrySpanMethod({ rowIndex, columnIndex }) {
      if (columnIndex !== this.OPTOMETRY_PD_COLUMN_INDEX || this.detailPdMode !== 'single') {
        return { rowspan: 1, colspan: 1 };
      }
      if (rowIndex === 0) {
        return { rowspan: 2, colspan: 1 };
      }
      return { rowspan: 0, colspan: 0 };
    },
    formatDetailPdValue(row, rowIndex) {
      if (!row) return '-';
      if (this.detailPdMode === 'dual') {
        return row.dualPd != null ? row.dualPd : '-';
      }
      if (rowIndex > 0) return '';
      const list = this.detailOptometryList;
      const pdRow = list.find(item => item.pd != null) || list[0];
      return pdRow && pdRow.pd != null ? pdRow.pd : '-';
    },
    formatDetailOptometryDecimal(value) {
      if (value == null || value === '') return '-';
      const num = Number(value);
      if (Number.isNaN(num)) return String(value);
      return num.toFixed(2);
    },
    formatDetailNearAdd(value) {
      if (value == null || value === '') return '-';
      const num = Number(value);
      if (Number.isNaN(num)) return String(value);
      return '+' + num.toFixed(2);
    },
    isAxisAEditable(row) {
      const val = row && row.cylinderC;
      if (val == null || val === '') return false;
      const num = Number(val);
      return !Number.isNaN(num) && num !== 0;
    },
    getSphereSign(sphereS) {
      if (sphereS == null || sphereS === '') return 0;
      const num = Number(sphereS);
      if (Number.isNaN(num) || num === 0) return 0;
      return num > 0 ? 1 : -1;
    },
    getCylinderCMin(row) {
      return this.getSphereSign(row && row.sphereS) > 0 ? 0 : -10;
    },
    getCylinderCMax(row) {
      return this.getSphereSign(row && row.sphereS) < 0 ? 0 : 10;
    },
    alignCylinderSignWithSphere(row) {
      if (!row || row.cylinderC == null || row.cylinderC === '') return;
      let cylinder = Number(row.cylinderC);
      if (Number.isNaN(cylinder) || cylinder === 0) return;
      const sphereSign = this.getSphereSign(row.sphereS);
      if (sphereSign > 0 && cylinder < 0) cylinder = Math.abs(cylinder);
      else if (sphereSign < 0 && cylinder > 0) cylinder = -Math.abs(cylinder);
      row.cylinderC = Math.min(this.getCylinderCMax(row), Math.max(this.getCylinderCMin(row), cylinder));
    },
    onSphereSChange(val, row) {
      this.alignCylinderSignWithSphere(row);
      if (!this.isAxisAEditable(row)) row.axisA = null;
    },
    onCylinderCChange(val, row) {
      if (val == null || val === '' || Number(val) === 0) {
        row.axisA = null;
        return;
      }
      this.alignCylinderSignWithSphere(row);
      if (!this.isAxisAEditable(row)) row.axisA = null;
    },
    cancel() {
      this.open = false;
      this.reset();
    },
    handleProgressiveMultifocalChange(value) {
      if (Number(value) !== 1) {
        this.form.progressiveMultifocalPrice = 0;
        if (this.form.optometryList) {
          this.form.optometryList.forEach(row => {
            row.nearAdd = null;
            row.pupilHeight = null;
          });
        }
        return;
      }
      if (!this.form.lensFactoryTenantId) {
        this.$modal.msgWarning("请先选择镜片厂");
        this.form.progressiveMultifocalPrice = 0;
        return;
      }
      this.refreshFormPricesByFactory(this.form.lensFactoryTenantId, { progressiveOnly: true });
    },
    handleFormLensFactoryChange(lensFactoryTenantId) {
      this.refreshFormPricesByFactory(lensFactoryTenantId);
    },
    refreshFormPricesByFactory(lensFactoryTenantId, options = {}) {
      const progressiveOnly = options.progressiveOnly === true;
      if (!lensFactoryTenantId) {
        if (!progressiveOnly) {
          this.form.priceB = 0;
          this.form.priceC = 0;
        }
        this.form.progressiveMultifocalPrice = 0;
        return;
      }
      if (!this.form.id) {
        if (Number(this.form.progressiveMultifocal) === 1) {
          this.form.progressiveMultifocalPrice = this.getProgressiveMultifocalPriceByFactory(lensFactoryTenantId);
        }
        return;
      }
      previewAssignPrice(this.form.id, lensFactoryTenantId).then(response => {
        this.applyAssignPreviewPrices(response.data || {}, { progressiveOnly });
      }).catch(() => {
        if (!progressiveOnly) {
          this.form.priceB = 0;
          this.form.priceC = 0;
        }
        this.form.progressiveMultifocalPrice = 0;
        this.$modal.msgWarning("未能获取该镜片厂价格，请确认镜片厂已配置对应镜片价格");
      });
    },
    applyAssignPreviewPrices(preview, options = {}) {
      const progressiveOnly = options.progressiveOnly === true;
      if (!progressiveOnly) {
        if (preview.priceB != null) {
          this.form.priceB = Number(preview.priceB);
        }
        if (preview.priceC != null) {
          this.form.priceC = Number(preview.priceC);
        }
      }
      if (Number(this.form.progressiveMultifocal) === 1) {
        if (preview.progressiveMultifocalPrice != null) {
          this.form.progressiveMultifocalPrice = Number(preview.progressiveMultifocalPrice);
        } else {
          this.form.progressiveMultifocalPrice = this.getProgressiveMultifocalPriceByFactory(this.form.lensFactoryTenantId);
        }
      } else {
        this.form.progressiveMultifocalPrice = 0;
      }
    },
    getProgressiveMultifocalPriceByFactory(lensFactoryTenantId) {
      if (lensFactoryTenantId == null || lensFactoryTenantId === "") {
        return 0;
      }
      const factory = (this.lensFactoryList || []).find(item => String(item.id) === String(lensFactoryTenantId));
      if (!factory || factory.progressiveMultifocalPrice == null) {
        return 0;
      }
      const num = Number(factory.progressiveMultifocalPrice);
      return Number.isNaN(num) ? 0 : num;
    },
    resolveProgressiveMultifocalPrice() {
      const price = this.form.progressiveMultifocalPrice;
      if (price != null && Number(price) > 0) {
        return Number(price);
      }
      return this.getProgressiveMultifocalPriceByFactory(this.form.lensFactoryTenantId);
    },
    reset() {
      this.form = {
        id: null,
        orderNo: null,
        brandTenantId: null,
        lensFactoryTenantId: null,
        lensId: null,
        progressiveMultifocal: 0,
        progressiveMultifocalPrice: 0,
        priceB: 0,
        priceC: 0,
        logisticsFee: null,
        orderStatus: '1',
        purchaseSettleStatus: '0',
        saleSettleStatus: '0',
        receiverName: null,
        receiverPhone: null,
        receiverAddress: null,
        attachment: null,
        remark: null,
        optometryList: this.createDefaultOptometryList()
      };
      this.resetForm("form");
    },
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    handleOrderStatusChange() {
      this.activeQuickFilter = null;
      this.queryParams.orderStatusIn = null;
    },
    handleQuickFilter(type) {
      if (this.activeQuickFilter === type) {
        this.activeQuickFilter = null;
        this.queryParams.orderStatusIn = null;
      } else {
        this.activeQuickFilter = type;
        this.queryParams.orderStatus = null;
        if (type === 'pendingAssign') {
          this.queryParams.orderStatusIn = `${this.ORDER_STATUS_SUBMITTED},${this.ORDER_STATUS_WITHDRAWN}`;
        } else if (type === 'exchangeApply') {
          this.queryParams.orderStatusIn = this.ORDER_STATUS_EXCHANGE_APPLY;
        } else if (type === 'exchangeRejected') {
          this.queryParams.orderStatusIn = this.ORDER_STATUS_EXCHANGE_REJECTED;
        }
      }
      this.handleQuery();
    },
    resetQuery() {
      this.resetForm("queryForm");
      this.activeQuickFilter = null;
      this.queryParams.orderStatusIn = null;
      this.handleQuery();
    },
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加订单";
    },
    handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids;
      getOrder(id).then(response => {
        this.form = response.data;
        this.form.progressiveMultifocal = this.form.progressiveMultifocal != null
          ? Number(this.form.progressiveMultifocal) : 0;
        this.form.progressiveMultifocalPrice = this.form.progressiveMultifocalPrice != null
          ? Number(this.form.progressiveMultifocalPrice) : 0;
        if (Number(this.form.progressiveMultifocal) !== 1) {
          this.form.progressiveMultifocalPrice = 0;
        }
        if (!this.form.optometryList || this.form.optometryList.length === 0) {
          this.form.optometryList = this.createDefaultOptometryList();
        }
        this.open = true;
        this.title = "修改订单";
      });
    },
    handleDetail(row) {
      getOrder(row.id).then(response => {
        this.detail = response.data || {};
        this.detailPdMode = this.detectPdMode(this.detail.optometryList);
        this.detailOpen = true;
      });
    },
    canViewLogistics(row) {
      if (!row || row.orderStatus == null) return false;
      const status = String(row.orderStatus);
      return status === this.ORDER_STATUS_SHIPPED
        || status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
        || status === this.ORDER_STATUS_COMPLETED
        || status === this.ORDER_STATUS_EXCHANGE_COMPLETED;
    },
    canCompleteOrder(row) {
      if (!row || row.orderStatus == null) return false;
      const status = String(row.orderStatus);
      return status === this.ORDER_STATUS_SHIPPED
        || status === this.ORDER_STATUS_EXCHANGE_LOGISTICS;
    },
    handleViewLogistics(row) {
      if (!row || !row.id) return;
      const noLogisticsTip = '未查到物流信息';
      getOrderLogistics(row.id).then((body) => {
        const data = body && body.data;
        if (!data || !data.expressNo) {
          this.$message.info(noLogisticsTip);
          return;
        }
        const orderNo = data.orderNo || row.orderNo;
        const expressCompany = data.expressCompany || '未知物流公司';
        const expressNo = data.expressNo;
        const mobile = data.receiverPhone || row.receiverPhone;
        const base = process.env.VUE_APP_BASE_API || '';
        return axios.get(`${base}/tool/express/query`, {
          params: { expressNo, mobile: mobile || undefined },
          headers: {
            Authorization: getToken() ? 'Bearer ' + getToken() : ''
          },
          timeout: 15000
        }).then((res) => {
          const pkg = res.data;
          this.logisticsBasic = { orderNo, expressCompany, expressNo };
          if (!pkg || Number(pkg.code) !== 200) {
            this.logisticsDetail = null;
            this.logisticsDialogVisible = true;
            return;
          }
          const detailRaw = pkg.data && pkg.data.data ? pkg.data.data : pkg.data;
          if (!detailRaw) {
            this.logisticsDetail = null;
            this.logisticsDialogVisible = true;
            return;
          }
          const traceRawList = detailRaw.logisticsTraceDetailList;
          const traceList = Array.isArray(traceRawList) ? traceRawList.slice() : [];
          traceList.sort((a, b) => (Number(b.time) || 0) - (Number(a.time) || 0));
          const traces = traceList.map(item => ({
            timeDesc: item.timeDesc || '',
            line: [item.timeDesc, item.desc].filter(Boolean).join(' ')
          })).filter(t => t.line);
          this.logisticsDetail = traces.length > 0 ? { traces } : null;
          this.logisticsDialogVisible = true;
        }).catch(() => {
          this.logisticsBasic = { orderNo, expressCompany, expressNo };
          this.logisticsDetail = null;
          this.logisticsDialogVisible = true;
        });
      }).catch(() => {
        this.$message.info(noLogisticsTip);
      });
    },
    handleStatusSelectVisible(row, visible) {
      if (visible) {
        row._prevOrderStatus = row.orderStatus;
      }
    },
    handleOrderStatusChange(row) {
      if (!row || !row.id) {
        return;
      }
      if (row.orderStatus === row._prevOrderStatus) {
        return;
      }
      const label = this.selectDictLabel(this.dict.type.jy_order_status, row.orderStatus);
      this.$modal.confirm(`确认将订单"${row.orderNo}"状态变更为"${label}"吗？`).then(() => {
        return changeOrderStatus({
          orderId: row.id,
          orderStatus: row.orderStatus
        });
      }).then(() => {
        row._prevOrderStatus = row.orderStatus;
        this.$modal.msgSuccess('状态更新成功');
      }).catch(() => {
        row.orderStatus = row._prevOrderStatus;
      });
    },
    handleReject(row) {
      if (!row || !row.id) {
        return;
      }
      this.rejectForm = {
        orderId: row.id,
        orderNo: row.orderNo,
        reason: ''
      };
      this.rejectOpen = true;
      this.$nextTick(() => {
        if (this.$refs.rejectForm) {
          this.$refs.rejectForm.clearValidate();
        }
      });
    },
    submitReject() {
      this.$refs.rejectForm.validate(valid => {
        if (!valid) {
          return;
        }
        this.rejectLoading = true;
        rejectOrder({
          orderId: this.rejectForm.orderId,
          reason: this.rejectForm.reason
        }).then(() => {
          this.$modal.msgSuccess('驳回成功');
          this.rejectOpen = false;
          this.getList();
        }).finally(() => {
          this.rejectLoading = false;
        });
      });
    },
    handleClose(row) {
      if (!row || !row.id) {
        return;
      }
      this.$modal.confirm(`确认关闭订单"${row.orderNo}"吗？`).then(() => {
        return closeOrder({ orderId: row.id });
      }).then(() => {
        this.$modal.msgSuccess('关闭成功');
        this.getList();
      }).catch(() => {});
    },
    handleComplete(row) {
      if (!row || !row.id) {
        return;
      }
      this.$modal.confirm(`确认完成订单"${row.orderNo}"吗？`).then(() => {
        return completeOrder({ orderId: row.id });
      }).then(() => {
        this.$modal.msgSuccess('操作成功');
        this.getList();
      }).catch(() => {});
    },
    handleAgreeExchange(row) {
      if (!row || !row.id) {
        return;
      }
      this.$modal.confirm(`确认同意订单"${row.orderNo}"的换货申请吗？`).then(() => {
        return agreeExchangeOrder({ orderId: row.id });
      }).then(() => {
        this.$modal.msgSuccess('已同意换货申请');
        this.getList();
      }).catch(() => {});
    },
    handleRejectExchange(row) {
      if (!row || !row.id) {
        return;
      }
      this.exchangeRejectForm = {
        orderId: row.id,
        orderNo: row.orderNo,
        reason: ''
      };
      this.exchangeRejectOpen = true;
      this.$nextTick(() => {
        if (this.$refs.exchangeRejectForm) {
          this.$refs.exchangeRejectForm.clearValidate();
        }
      });
    },
    submitExchangeReject() {
      this.$refs.exchangeRejectForm.validate(valid => {
        if (!valid) {
          return;
        }
        this.exchangeRejectLoading = true;
        rejectExchangeOrder({
          orderId: this.exchangeRejectForm.orderId,
          reason: this.exchangeRejectForm.reason
        }).then(() => {
          this.$modal.msgSuccess('已拒绝换货申请');
          this.exchangeRejectOpen = false;
          this.getList();
        }).finally(() => {
          this.exchangeRejectLoading = false;
        });
      });
    },
    loadAssignLensFactoryList(lensId, token) {
      if (!lensId) {
        this.assignLensFactoryList = [];
        return;
      }
      listLensFactoryTenant(lensId).then(response => {
        if (token !== this.assignDialogToken) {
          return;
        }
        this.assignLensFactoryList = response.data || [];
      });
    },
    resetAssignDialog() {
      this.assignDialogToken += 1;
      this.assignPreview = {};
      this.assignLensFactoryList = [];
      this.assignLoading = false;
      this.assignForm = {
        orderId: null,
        orderNo: null,
        lensId: null,
        lensText: '',
        progressiveMultifocal: 0,
        lensFactoryTenantId: null
      };
    },
    handleAssign(row) {
      this.assignDialogToken += 1;
      const token = this.assignDialogToken;
      this.assignDialogKey += 1;
      this.assignPreview = {};
      this.assignLensFactoryList = [];
      this.assignForm = {
        orderId: row.id,
        orderNo: row.orderNo,
        lensId: row.lensId,
        lensText: this.formatLens(row),
        progressiveMultifocal: row.progressiveMultifocal,
        lensFactoryTenantId: null
      };
      this.assignOpen = true;
      this.loadAssignLensFactoryList(row.lensId, token);
      this.$nextTick(() => {
        if (this.$refs.assignForm) {
          this.resetForm('assignForm');
        }
      });
    },
    handleAssignFactoryChange(lensFactoryTenantId) {
      if (!lensFactoryTenantId) {
        this.assignPreview = {};
        return;
      }
      const token = this.assignDialogToken;
      const orderId = this.assignForm.orderId;
      previewAssignPrice(orderId, lensFactoryTenantId).then(response => {
        if (token !== this.assignDialogToken || this.assignForm.orderId !== orderId) {
          return;
        }
        this.assignPreview = response.data || {};
      }).catch(() => {
        if (token !== this.assignDialogToken || this.assignForm.orderId !== orderId) {
          return;
        }
        this.assignPreview = {};
      });
    },
    submitAssign() {
      this.$refs.assignForm.validate(valid => {
        if (!valid) {
          return;
        }
        this.assignLoading = true;
        assignOrder({
          orderId: this.assignForm.orderId,
          lensFactoryTenantId: this.assignForm.lensFactoryTenantId
        }).then(() => {
          this.$modal.msgSuccess('分配成功');
          this.assignOpen = false;
          this.getList();
        }).finally(() => {
          this.assignLoading = false;
        });
      });
    },
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          const payload = {
            ...this.form,
            progressiveMultifocal: this.form.progressiveMultifocal != null
              ? Number(this.form.progressiveMultifocal) : 0,
            progressiveMultifocalPrice: Number(this.form.progressiveMultifocal) === 1
              ? this.resolveProgressiveMultifocalPrice()
              : 0
          };
          if (Number(payload.progressiveMultifocal) !== 1 && payload.optometryList) {
            payload.optometryList.forEach(row => {
              row.nearAdd = null;
              row.pupilHeight = null;
            });
          }
          if (payload.optometryList) {
            payload.optometryList.forEach(row => {
              if (!this.isAxisAEditable(row)) {
                row.axisA = null;
              }
            });
          }
          if (Number(payload.progressiveMultifocal) === 1) {
            if (!payload.lensFactoryTenantId) {
              this.$modal.msgWarning("选择渐进多焦点时需先选择镜片厂");
              return;
            }
            if (!payload.progressiveMultifocalPrice || Number(payload.progressiveMultifocalPrice) <= 0) {
              this.$modal.msgWarning("所选镜片厂未配置渐进多焦点价格");
              return;
            }
          }
          if (this.form.id != null) {
            updateOrder(payload).then(() => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addOrder(payload).then(() => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal.confirm('是否确认删除订单编号为"' + ids + '"的数据项？').then(function() {
        return delOrder(ids);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    handleGenerateSettlement() {
      this.settlementGenerateForm = { settleYearMonth: undefined };
      this.settlementGenerateOpen = true;
      this.$nextTick(() => {
        if (this.$refs.settlementGenerateForm) {
          this.$refs.settlementGenerateForm.clearValidate();
        }
      });
    },
    submitGenerateSettlement() {
      this.$refs.settlementGenerateForm.validate(valid => {
        if (!valid) return;
        const yearMonth = this.settlementGenerateForm.settleYearMonth;
        this.settlementGenerateLoading = true;
        checkFeeSettlement(yearMonth).then(res => {
          const check = res.data || {};
          if (check.exists) {
            const nos = (check.settlementNos || []).join('、');
            return this.$modal.confirm(
              `该年月已存在 ${check.count} 张费用结算单${nos ? '（' + nos + '）' : ''}，是否删除后重新生成？`
            ).then(() => {
              return generateFeeSettlement({ settleYearMonth: yearMonth, forceRegenerate: true });
            });
          }
          return generateFeeSettlement({ settleYearMonth: yearMonth, forceRegenerate: false });
        }).then(res => {
          if (res) {
            this.$modal.msgSuccess(res.msg || '生成成功');
            this.settlementGenerateOpen = false;
          }
        }).catch(() => {}).finally(() => {
          this.settlementGenerateLoading = false;
        });
      });
    },
    handleExport() {
      this.download('jysystem/order/export', {
        ...this.queryParams
      }, `order_${new Date().getTime()}.xlsx`);
    },
    handleBatchExportExcel() {
      if (!this.ids.length) {
        this.$modal.msgWarning('请先选择要导出的订单');
        return;
      }
      this.download('jysystem/order/export/batch/' + this.ids.join(','), {}, `order_batch_${new Date().getTime()}.xlsx`);
    },
    handleBatchExportPdf() {
      if (!this.ids.length) {
        this.$modal.msgWarning('请先选择要导出的订单');
        return;
      }
      this.download('jysystem/order/exportPdf/batch/' + this.ids.join(','), {}, `order_batch_${new Date().getTime()}.pdf`);
    }
  }
};
</script>

<style scoped>
.degree-sup {
  font-size: 10px;
  line-height: 1;
  vertical-align: super;
}

.price-total-value {
  font-weight: 700;
  font-size: 16px;
  color: #f56c6c;
}
</style>

<style lang="scss">
.lens-order-form-dialog,
.lens-order-detail-dialog {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 24px 48px rgba(37, 99, 235, 0.12), 0 8px 24px rgba(15, 23, 42, 0.08);

  .el-dialog__header {
    padding: 20px 28px 18px;
    background: linear-gradient(135deg, rgba(37, 99, 235, 0.08) 0%, rgba(147, 51, 234, 0.06) 100%);
    border-bottom: 1px solid rgba(37, 99, 235, 0.12);
  }

  .el-dialog__headerbtn {
    top: 22px;
    right: 24px;

    .el-dialog__close {
      color: #64748b;
      font-size: 18px;

      &:hover {
        color: #2563eb;
      }
    }
  }

  .el-dialog__body {
    padding: 20px 28px 8px;
    background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%);
    overflow: visible;
  }

  .el-dialog__footer {
    padding: 16px 28px 22px;
    background: #fff;
    border-top: 1px solid rgba(37, 99, 235, 0.08);
  }
}

.lens-dialog-header {
  .lens-dialog-title {
    margin: 0 0 6px;
    font-size: 20px;
    font-weight: 700;
    background: linear-gradient(90deg, #2563eb 0%, #7c3aed 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }

  .lens-dialog-subtitle {
    margin: 0;
    font-size: 13px;
    color: #64748b;
    letter-spacing: 0.02em;
  }
}

.lens-order-form,
.lens-order-detail {
  .lens-form-section {
    margin-bottom: 18px;
    padding: 18px 20px 8px;
    background: #fff;
    border: 1px solid rgba(37, 99, 235, 0.1);
    border-radius: 12px;
    box-shadow: 0 4px 16px rgba(15, 23, 42, 0.04);
    position: relative;
    overflow: hidden;

    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 3px;
      background: linear-gradient(90deg, #2563eb 0%, #9333ea 100%);
      opacity: 0.85;
    }

    &--optometry {
      padding-bottom: 16px;
    }
  }

  .section-head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 16px;
  }

  .section-index {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    line-height: 36px;
    text-align: center;
    font-size: 13px;
    font-weight: 700;
    color: #2563eb;
    background: linear-gradient(135deg, rgba(37, 99, 235, 0.12) 0%, rgba(147, 51, 234, 0.1) 100%);
    border: 1px solid rgba(37, 99, 235, 0.15);
    border-radius: 10px;
  }

  .section-text {
    h4 {
      margin: 0 0 4px;
      font-size: 15px;
      font-weight: 600;
      color: #1e293b;
    }

    p {
      margin: 0;
      font-size: 12px;
      color: #94a3b8;
    }
  }

  .section-body {
    padding-left: 2px;
  }

  .lens-optometry-table {
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid rgba(37, 99, 235, 0.12);

    &::before {
      display: none;
    }

    th {
      background: linear-gradient(90deg, #eff6ff 0%, #f5f3ff 100%) !important;
      color: #334155 !important;
      font-weight: 600;
      border-color: rgba(37, 99, 235, 0.1) !important;
    }

    td {
      border-color: rgba(148, 163, 184, 0.2) !important;
      background: #fff;
    }

    tr:hover > td {
      background: rgba(239, 246, 255, 0.5) !important;
    }
  }

  .el-input__inner,
  .el-textarea__inner {
    border-radius: 8px;
    border-color: rgba(37, 99, 235, 0.15);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;

    &:focus {
      border-color: #2563eb;
      box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
    }
  }

  .el-form-item__label {
    color: #475569;
    font-weight: 500;
  }
}

.lens-order-detail {
  .detail-descriptions {
    border-radius: 10px;
    overflow: hidden;

    .el-descriptions__table {
      table-layout: fixed;
      width: 100%;
    }

    .el-descriptions-item__label {
      width: 116px;
      min-width: 116px;
      background: linear-gradient(90deg, #eff6ff 0%, #f5f3ff 100%) !important;
      color: #475569 !important;
      font-weight: 600;
      border-color: rgba(37, 99, 235, 0.1) !important;
    }

    .el-descriptions-item__content {
      color: #1e293b;
      border-color: rgba(37, 99, 235, 0.1) !important;
    }
  }

  .detail-descriptions--price {
    .el-descriptions-item__content {
      font-variant-numeric: tabular-nums;
    }
  }

  .detail-attachment-link {
    margin-right: 12px;
    font-weight: 500;
  }

  .price-total-value {
    font-weight: 700;
    font-size: 16px;
    color: #ef4444;
  }

  .lens-detail-table {
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid rgba(37, 99, 235, 0.12);

    &::before {
      display: none;
    }

    th {
      background: linear-gradient(90deg, #eff6ff 0%, #f5f3ff 100%) !important;
      color: #334155 !important;
      font-weight: 600;
      border-color: rgba(37, 99, 235, 0.1) !important;
    }

    td {
      border-color: rgba(148, 163, 184, 0.2) !important;
      background: #fff;
      color: #334155;
    }

    tr:hover > td {
      background: rgba(239, 246, 255, 0.5) !important;
    }
  }

  .detail-logistics-fee-block {
    margin-top: 12px;
  }

  .detail-empty-tip {
    margin-top: 10px;
    padding: 14px;
    text-align: center;
    font-size: 13px;
    color: #94a3b8;
    background: linear-gradient(90deg, rgba(239, 246, 255, 0.6) 0%, rgba(245, 243, 255, 0.6) 100%);
    border: 1px dashed rgba(37, 99, 235, 0.15);
    border-radius: 10px;
  }
}

.logistics-traces {
  max-height: 360px;
  overflow-y: auto;
  padding: 4px 8px 0;
}

.lens-dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;

  .lens-btn-ghost {
    border-color: #cbd5e1;
    color: #64748b;
    border-radius: 8px;
    padding: 10px 20px;

    &:hover {
      color: #2563eb;
      border-color: #93c5fd;
      background: #f8fafc;
    }
  }

  .lens-btn-primary {
    border: none;
    color: #fff;
    background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
    border-radius: 8px;
    padding: 10px 24px;
    box-shadow: 0 6px 16px rgba(37, 99, 235, 0.28);

    &:hover {
      background: linear-gradient(135deg, #1d4ed8 0%, #6d28d9 100%);
      box-shadow: 0 8px 20px rgba(37, 99, 235, 0.35);
    }
  }
}
</style>
