<template>
  <div class="page card h-100 flex-gap-10 overflow-hidden flex">
    <div
      class="order-status-wrapper"
      :class="{ 'is-collapsed': statusSidebarCollapsed }"
    >
      <div class="order-status">
        <ElTree
          ref="treeRef"
          default-expand-all
          :expand-on-click-node="false"
          :default-expanded-keys="['ALL']"
          :highlight-current="true"
          node-key="status"
          :data="statusTree"
          :props="{ children: 'children', label: 'statusName' }"
          class="status-tree"
          @node-click="handleStatusNodeClick"
        >
          <template #default="{ node, data }">
            <div class="tree-node">
              <div class="tree-node-label-wrapper">
                <span class="tree-node-label">{{ data.statusName }}</span>
                <span
                  v-if="
                    data.status !== 'ALL' &&
                    (data.quantity || data.quantity === 0)
                  "
                  class="tree-node-count"
                >
                  {{ `(${data.quantity}${data.unit ?? '单'})` }}
                </span>
              </div>
              <span
                v-if="data.children && data.children.length"
                class="tree-node-expand"
                @click.stop="toggleExpand(node)"
              >
                <el-icon
                  ><ArrowUp v-if="node.expanded" /><ArrowDown v-else
                /></el-icon>
              </span>
            </div>
          </template>
        </ElTree>
      </div>
      <div
        class="sidebar-toggle"
        title="收起/展开"
        @click="toggleStatusSidebar"
      >
        <span
          class="sidebar-toggle-icon"
          :class="{ 'is-collapsed': statusSidebarCollapsed }"
        />
      </div>
    </div>
    <div class="order-content flex-1 flex-column overflow-hidden">
      <div v-if="!isSpecialLayout" class="header">
        <div class="header-filter-form">
          <ElForm
            class="search-form"
            :model="searchForm"
            :inline="true"
            label-width="70px"
          >
            <ElFormItem v-if="status === 'ALL'" label="订单状态">
              <ElTreeSelect
                v-model="searchFormStatusSelect"
                :data="statusTreeChildren"
                :props="{
                  value: 'status',
                  label: 'statusName',
                  children: 'children',
                }"
                node-key="status"
                placeholder="请选择"
                collapse-tags
                multiple
                clearable
                filterable
                check-strictly
                style="width: 180px"
              />
            </ElFormItem>
            <ElFormItem label="平台">
              <ElSelect
                v-model="searchForm.platform"
                placeholder="请选择"
                clearable
                filterable
                popper-class="customize-select-style"
                style="width: 140px"
              >
                <ElOption
                  v-for="(item, index) in platformJson"
                  :key="index"
                  :label="item.type"
                  :value="item.type"
                  style="width: 160px"
                >
                  <img
                    :src="`/images/icon/${item.icon.split('/').pop()}`"
                    style="height: 20px; margin: 5px 10px 0 0"
                  />
                  <span :title="item.type">{{ item.type }}</span>
                </ElOption>
              </ElSelect>
            </ElFormItem>

            <ElFormItem label="库存SKU">
              <ElInput
                v-model.trim="searchForm.thirdSkuCode"
                placeholder="库存SKU"
                clearable
                style="width: 140px"
              />
            </ElFormItem>
            <ElFormItem label="店铺单号">
              <ElInput
                v-model.trim="searchForm.shopNumber"
                placeholder="店铺单号"
                clearable
                style="width: 150px"
              />
            </ElFormItem>
            <ElFormItem
              v-if="cardLayoutStatuses.includes(status)"
              label="批次号"
            >
              <ElInput
                v-model.trim="searchForm.batchArrangeNumber"
                placeholder="批次号"
                clearable
                style="width: 140px"
              />
            </ElFormItem>

            <ElFormItem
              v-if="
                cardLayoutStatuses.includes(status) ||
                [
                  'ALL',
                  'PICKING',
                  'PENDING_DELIVERY',
                  'COMPLETED',
                  'SUSPEND',
                  'CANCELLED',
                ].includes(status)
              "
              label="操作单号"
            >
              <ElInput
                v-model.trim="searchForm.operationNo"
                placeholder="多个操作单号,分隔"
                clearable
                style="width: 140px"
                @keydown.enter.prevent="handleOperationNoScanEnter"
              />
            </ElFormItem>

            <ElFormItem label="商品类型">
              <ProductTypeFilter
                v-model="searchForm.productMarkList"
                :options="productTypeGroups"
                :multiple="true"
                placeholder="请选择商品类型"
                width="140px"
              />
            </ElFormItem>

            <ElFormItem label="工艺" label-width="50px">
              <LogisticsWaySelect
                v-model="searchForm.craftCode"
                :company-list="podCraftList"
                :start-width="'150px'"
                search-placeholder="搜索工艺名称"
                start-placeholder="请选择工艺名称"
              ></LogisticsWaySelect>
            </ElFormItem>
            <ElFormItem
              v-if="status === 'PICKING'"
              label="操作单状态"
              label-width="100px"
            >
              <ElSelect
                v-model="searchFormOperationStatusSelect"
                placeholder="请选择"
                clearable
                multiple
                collapse-tags
                filterable
                style="width: 170px"
              >
                <ElOption
                  v-for="(item, index) in statusList"
                  :key="index"
                  :value="item.status"
                  :label="item.statusName"
                ></ElOption>
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="数量">
              <el-radio-group v-model="searchForm.multi">
                <el-radio-button :value="false" @click="toggleMulti(false)"
                  >单件</el-radio-button
                >
                <el-radio-button :value="true" @click="toggleMulti(true)"
                  >多件</el-radio-button
                >
              </el-radio-group>
            </ElFormItem>

            <ElFormItem>
              <ElPopover placement="bottom" width="600" trigger="click">
                <ElForm
                  ref="searchFormPopoverRef"
                  :model="searchForm"
                  size="default"
                  inline
                  label-width="100px"
                >
                  <ElFormItem style="width: 100%; padding-right: 40px">
                    <div style="width: 100%; display: flex; flex-wrap: nowrap">
                      <el-select
                        v-model="searchForm.timeType"
                        clearable
                        :teleported="false"
                        placeholder="时间类型"
                        style="flex: 1; margin-right: 10px"
                      >
                        <el-option :value="1" label="创建时间"></el-option>
                        <el-option :value="2" label="确认时间"></el-option>
                        <el-option :value="3" label="完成时间"></el-option>
                      </el-select>
                      <el-date-picker
                        v-model="dateRange"
                        :teleported="false"
                        :default-time="[
                          new Date(0, 0, 0, 0, 0, 0),
                          new Date(0, 0, 0, 23, 59, 59),
                        ]"
                        value-format="YYYY-MM-DD HH:mm:ss"
                        type="datetimerange"
                        style="width: 280px"
                        :shortcuts="pickerOptions.shortcuts"
                        start-placeholder="开始时间"
                        end-placeholder="结束时间"
                        clearable
                      />
                    </div>
                  </ElFormItem>
                  <ElFormItem label="订单编号">
                    <ElInput
                      v-model.trim="searchForm.factoryOrderNumber"
                      placeholder="订单编号"
                      clearable
                      style="width: 150px"
                    />
                  </ElFormItem>
                  <ElFormItem label="客户">
                    <el-select
                      v-model="searchForm.userMark"
                      clearable
                      filterable
                      :teleported="false"
                      style="width: 150px"
                      placeholder="客户"
                    >
                      <el-option
                        v-for="item in userMarkList"
                        :key="item"
                        :value="item"
                        :label="item"
                      ></el-option>
                    </el-select>
                  </ElFormItem>
                  <ElFormItem v-if="status === 'ALL'" label="客户交运单号">
                    <ElInput
                      v-model.trim="searchForm.customerNo"
                      placeholder="客户交运单号"
                      clearable
                      style="width: 150px"
                    />
                  </ElFormItem>
                  <ElFormItem label="Variant SKU">
                    <ElInput
                      v-model.trim="searchForm.sku"
                      placeholder="Variant SKU"
                      clearable
                      style="width: 150px"
                    />
                  </ElFormItem>
                  <ElFormItem label="款号">
                    <ElInput
                      v-model.trim="searchForm.supplierProductNo"
                      placeholder="款号"
                      clearable
                      style="width: 150px"
                    />
                  </ElFormItem>
                  <ElFormItem label="物流跟踪号">
                    <ElInput
                      v-model.trim="searchForm.trackingNumber"
                      placeholder="物流跟踪号"
                      clearable
                      style="width: 150px"
                    />
                  </ElFormItem>
                  <ElFormItem
                    v-if="!cardLayoutStatuses.includes(status)"
                    label="收件国家"
                  >
                    <ElSelect
                      v-model="searchForm.receiverCountry"
                      placeholder="收件国家"
                      clearable
                      multiple
                      :teleported="false"
                      style="width: 150px"
                      filterable
                      @change="changeReplaceShipment"
                    >
                      <ElOption
                        v-for="item in receiverCountryList"
                        :key="item.countryCode"
                        :value="item.countryCode"
                        :label="item.nameCn + '(' + item.countryCode + ')'"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem label="物流类型">
                    <ElSelect
                      v-model="searchForm.shipmentType"
                      placeholder="物流类型"
                      clearable
                      :teleported="false"
                      style="width: 150px"
                    >
                      <ElOption
                        v-for="(item, index) in [
                          '自有物流',
                          '九猫统筹物流',
                          '自提',
                        ]"
                        :key="index"
                        :value="index"
                        :label="item"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem label="尺码筛选">
                    <ElSelect
                      v-model="searchForm.size"
                      multiple
                      collapse-tags
                      collapse-tags-tooltip
                      placeholder="请选择"
                      clearable
                      filterable
                      :teleported="false"
                      style="width: 150px"
                    >
                      <ElOption
                        v-for="(item, index) in sizes"
                        :key="index"
                        :value="item"
                        :label="item"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem label="客户标签">
                    <ElSelect
                      v-model="searchForm.tagsIdArr"
                      placeholder="请选择客户标签"
                      clearable
                      filterable
                      multiple
                      collapse-tags
                      collapse-tags-tooltip
                      :teleported="false"
                      style="width: 150px"
                    >
                      <ElOption
                        v-for="item in customTagList"
                        :key="item.id"
                        :value="item.id"
                        :label="item.name"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem v-if="status === 'ALL'" label="物流方式">
                    <ElSelect
                      v-model="searchForm.logisticsWayId"
                      placeholder="请选择"
                      clearable
                      :teleported="false"
                      style="width: 150px"
                    >
                      <ElOption
                        v-for="(item, index) in logisticsWayList"
                        :key="index"
                        :value="item.id"
                        :label="item.name"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem label="自有物流公司">
                    <ElSelect
                      v-model="searchForm.logisticsCompanyCode"
                      placeholder="请选择"
                      clearable
                      filterable
                      :teleported="false"
                      style="width: 150px"
                    >
                      <ElOption
                        v-for="(item, index) in allCodelist"
                        :key="index"
                        :value="item.code"
                        :label="item.basicsName"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem label="规范素材">
                    <ElSelect
                      v-model="searchForm.newStandard"
                      placeholder="请选择"
                      clearable
                      filterable
                      style="width: 150px"
                    >
                      <ElOption
                        v-for="(_, index) in ['否', '是']"
                        :key="index"
                        :value="index"
                        :label="index === 0 ? '否' : '是'"
                      ></ElOption>
                    </ElSelect>
                  </ElFormItem>
                </ElForm>
                <template #reference>
                  <el-button
                    type="warning"
                    @click="searchVisible = !searchVisible"
                  >
                    <el-icon v-if="searchVisible">
                      <CaretTop />
                    </el-icon>
                    <el-icon v-else>
                      <CaretBottom />
                    </el-icon>
                  </el-button>
                </template>
              </ElPopover>
            </ElFormItem>

            <ElFormItem>
              <ElButton type="primary" @click="() => refreshCurrentView()">
                查询
              </ElButton>
              <ElButton @click="reset"> 重置 </ElButton>
            </ElFormItem>
          </ElForm>
        </div>
      </div>
      <!-- ====== 操作按钮栏 ====== -->
      <div v-if="!isSpecialLayout" class="operation-list">
        <span v-if="status === 'ALL'" class="item">
          <ElButton type="success" @click="exportData"> 导出 </ElButton>
        </span>
        <span v-if="status === 'PENDING_RECEIVE'" class="item">
          <ElButton type="success" @click="handleConfirmOrder">
            {{
              pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK'
                ? '重新接单'
                : '确认接单'
            }}
          </ElButton>
        </span>
        <span
          v-if="
            status === 'PENDING_RECEIVE' ||
            (status === 'SUSPEND' && suspendedSubTab === 4)
          "
          class="item"
        >
          <ElButton type="danger" @click="handleCancelOrder">取消订单</ElButton>
        </span>

        <ElDropdown
          v-if="
            [
              'ALL',
              'PENDING_RECEIVE',
              'PENDING_CREATE_LOGISTICS',
              'PENDING_SCHEDULE',
              'PICKING',
              'PENDING_DELIVERY',
              'SUSPEND',
            ].includes(status)
          "
          trigger="click"
          @command="handleLogisticsCommand"
        >
          <span class="item">
            <ElButton type="warning">
              物流接口 <el-icon class="el-icon--right"><ArrowDown /></el-icon>
            </ElButton>
          </span>
          <template #dropdown>
            <ElDropdownMenu>
              <ElDropdownItem
                command="createLogistic"
                :disabled="isShowLogisticsButton"
                >创建物流订单</ElDropdownItem
              >
              <ElDropdownItem
                command="getTrackingNumber"
                :disabled="isShowLogisticsButton"
                >获取跟踪号</ElDropdownItem
              >
              <ElDropdownItem
                command="getPrintOrder"
                :disabled="isShowLogisticsButton"
                >获取打印面单</ElDropdownItem
              >
              <ElDropdownItem
                command="cancelLogistic"
                :disabled="isShowLogisticsButton"
                >取消物流订单</ElDropdownItem
              >
            </ElDropdownMenu>
          </template>
        </ElDropdown>

        <span v-if="status === 'PENDING_CREATE_LOGISTICS'" class="item">
          <ElButton type="success" @click="handleUpdateCustomsInfo"
            >更新报关信息</ElButton
          >
        </span>
        <span v-if="status === 'PENDING_CREATE_LOGISTICS'" class="item">
          <ElButton type="primary" @click="handleTransferToArrange">
            转至待排单
          </ElButton>
        </span>
        <span v-if="status === 'PENDING_SCHEDULE'" class="item">
          <ElButton type="primary" @click="handleArrange">排单</ElButton>
        </span>

        <ElDropdown
          v-if="
            status === 'PENDING_PICK' ||
            status === 'PENDING_REPLENISH' ||
            status === 'IN_PRODUCTION'
          "
          trigger="click"
          @command="handleDtfCommand"
        >
          <span class="item">
            <ElButton type="primary">
              DTF排版 <el-icon class="el-icon--right"><ArrowDown /></el-icon>
            </ElButton>
          </span>
          <template #dropdown>
            <ElDropdownMenu>
              <!-- <ElDropdownItem command="tiff_42">TIF(40+2cm)</ElDropdownItem>
              <ElDropdownItem command="tiff_60">TIF(60cm)</ElDropdownItem> -->
              <ElDropdownItem command="png_42">PNG(40+2cm)</ElDropdownItem>
              <ElDropdownItem command="png_60">PNG(60cm)</ElDropdownItem>
            </ElDropdownMenu>
          </template>
        </ElDropdown>
        <span
          v-if="
            status === 'PENDING_PICK' ||
            status === 'PENDING_REPLENISH' ||
            status === 'IN_PRODUCTION'
          "
          class="item"
        >
          <ElButton type="success" @click="handlePrintProductionOrder"
            >打印操作单</ElButton
          >
        </span>
        <span v-if="status === 'PENDING_PICK'" class="item">
          <ElButton type="warning" @click="handlePrintPickOrder"
            >打印拣货单</ElButton
          >
        </span>
        <span v-if="status === 'PENDING_PICK'" class="item">
          <ElButton type="success" @click="handlePickComplete"
            >拣胚完成</ElButton
          >
        </span>

        <span v-if="status === 'PENDING_PICK'" class="item">
          <ElButton type="danger" @click="handlePickFail">拣胚失败</ElButton>
        </span>
        <span v-if="status === 'PENDING_REPLENISH'" class="item">
          <ElButton type="success" @click="handleReplenishComplete"
            >补胚完成</ElButton
          >
        </span>
        <span v-if="status === 'PENDING_REPLENISH'" class="item">
          <ElButton type="danger" @click="handleReplenishFail"
            >补胚失败</ElButton
          >
        </span>
        <span
          v-if="status === 'PENDING_PACKING' && isEnableSorting"
          class="item"
        >
          <ElButton type="primary" @click="handleSeedingWall('sort')"
            >配货分拣</ElButton
          >
        </span>
        <span
          v-if="status === 'PENDING_PACKING' || !isEnableSorting"
          class="item"
        >
          <ElButton type="success" @click="handleSeedingWall('print')"
            >配货打单</ElButton
          >
        </span>
        <span v-if="status === 'PENDING_PACKING'" class="item">
          <ElButton type="primary" @click="handleSinglePrint"
            >单件打单</ElButton
          >
        </span>

        <span
          v-if="status === 'IN_PRODUCTION' || status === 'PENDING_PACKING'"
          class="item"
        >
          <ElButton type="warning" @click="handleApplyReplenish"
            >申请补胚</ElButton
          >
        </span>
        <span v-if="['IN_PRODUCTION'].includes(status)" class="item">
          <ElButton
            type="success"
            @click="handleQuickProduction('productionScan')"
            >快捷生产</ElButton
          >
        </span>
        <span v-if="status === 'IN_PRODUCTION'" class="item">
          <ElButton type="warning" @click="handleProductionComplete"
            >生产完成</ElButton
          >
        </span>

        <span v-if="status === 'PENDING_DELIVERY'" class="item">
          <ElButton type="primary" @click="handleWeightSort">称重分拣</ElButton>
          <ElButton type="success" @click="handleCompleteDelivery"
            >完成发货</ElButton
          >
        </span>
        <!-- 已完成 -->
        <template v-if="status === 'COMPLETED'">
          <span class="item">
            <ElButton type="success" @click="handleArchiveOrder"
              >订单归档</ElButton
            >
          </span>
          <span class="item">
            <ElButton type="primary" @click="handleGetTrackingNumber"
              >获取跟踪号</ElButton
            >
          </span>
          <span class="item">
            <ElButton type="warning" @click="handleStatusPush"
              >状态推送</ElButton
            >
          </span>
        </template>
        <!-- 挂起 -->
        <template v-if="status === 'SUSPEND'">
          <span v-if="suspendedSubTab !== 1" class="item">
            <ElButton type="warning" @click="() => handleCancelSuspend()"
              >取消挂起</ElButton
            >
          </span>
          <span v-if="suspendedSubTab === 1" class="item">
            <ElButton type="success" @click="() => handleInterceptionSuccess()"
              >处理拦截</ElButton
            >
          </span>
          <span v-if="suspendedSubTab === 1" class="item">
            <ElButton type="danger" @click="() => handleInterceptionFail()"
              >取消拦截</ElButton
            >
          </span>
          <span class="item">
            <ElButton type="primary" @click="handleSyncAddress"
              >同步收货地址</ElButton
            >
          </span>
        </template>
        <span
          v-if="
            [
              'PENDING_CREATE_LOGISTICS',
              'PENDING_SCHEDULE',
              'PENDING_DELIVERY',
              'PICKING',
            ].includes(status)
          "
          class="item"
        >
          <ElButton type="danger" @click="handleSuspend">挂起</ElButton>
        </span>
        <span v-if="['PICKING'].includes(status)" class="item">
          <ElButton type="success" @click="handleDeliveryComplete"
            >配货完成</ElButton
          >
        </span>
        <span v-if="status === 'PENDING_PACKING'" class="item">
          <ElButton type="success" @click="handlePrintWarehouseSkuTag"
            >打印库存SKU标签</ElButton
          >
        </span>
        <span
          v-if="
            status === 'PENDING_SCHEDULE' ||
            status === 'PENDING_REPLENISH' ||
            status === 'IN_PRODUCTION' ||
            status === 'PENDING_DELIVERY' ||
            status === 'SUSPEND' ||
            status === 'PENDING_PICK' ||
            status === 'PENDING_PACKING'
          "
          class="item"
        >
          <ElButton type="success" @click="handleDownloadMaterial"
            >下载素材</ElButton
          >
        </span>
        <span
          v-if="
            [
              'PENDING_RECEIVE',
              'PENDING_CREATE_LOGISTICS',
              'PENDING_SCHEDULE',
              'PENDING_PICK',
              'PENDING_REPLENISH',
              'IN_PRODUCTION',
              'PENDING_PACKING',
            ].includes(status)
          "
          class="item"
        >
          <ElButton type="primary" @click="handleRefreshProductInfo"
            >刷新商品信息</ElButton
          >
        </span>
        <span
          v-if="
            status === 'PENDING_RECEIVE' &&
            pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK'
          "
          class="item"
        >
          <ElButton type="success" @click="handleGetOrderInventoryDetail"
            >订单库存明细</ElButton
          >
        </span>
        <!-- 待质检 -->
        <span v-if="status === 'PENDING_QUALITY'" class="item">
          <ElButton
            type="primary"
            @click="handleQuickProduction('qualityScan')"
          >
            快捷质检
          </ElButton>
        </span>
        <span v-if="status === 'PENDING_QUALITY'" class="item">
          <ElButton type="success" @click="handleQuality(true)">
            质检通过
          </ElButton>
        </span>
        <span
          v-if="
            status === 'PENDING_QUALITY' && qualitySubTab === 'PENDING_QUALITY'
          "
          class="item"
        >
          <ElButton type="danger" @click="handleQuality(false)">
            质检不通过
          </ElButton>
        </span>
        <span v-if="status === 'PENDING_QUALITY'" class="item">
          <ElButton type="success" @click="handleGetOrderInventoryDetail">
            打印操作单
          </ElButton>
        </span>
        <span
          v-if="status === 'PENDING_QUALITY' && qualitySubTab === 'NO_QUALITY'"
          class="item"
        >
          <ElButton type="warning" @click="handleApplyReplenish">
            申请补胚
          </ElButton>
        </span>
        <span
          v-if="status === 'PENDING_QUALITY' && qualitySubTab === 'NO_QUALITY'"
          class="item"
        >
          <ElButton type="warning" @click="handleRemanufacture">
            重新生产
          </ElButton>
        </span>
      </div>
      <div v-if="status === 'SUSPEND'" class="status-subtabs">
        <div
          v-for="tab in suspendedTabs"
          :key="tab.value"
          class="status-subtab"
          :class="{ active: suspendedSubTab === tab.value }"
          @click="handleSuspendTabClick(tab.value)"
        >
          {{ tab.label }}({{ tab.count || 0 }})
        </div>
      </div>

      <!-- <div v-if="status === 'CANCELLED'" class="status-subtabs">
        <div
          v-for="tab in cancelledTabs"
          :key="tab.value"
          class="status-subtab"
          :class="{ active: cancelledSubTab === tab.value }"
          @click="handleCancelledTabClick(tab.value)"
        >
          {{ tab.label }}({{ tab.count || 0 }})
        </div>
      </div> -->

      <div v-if="status === 'PENDING_RECEIVE'" class="status-subtabs">
        <div
          class="status-subtab"
          :class="{ active: pendingAcceptSubTab === 'PENDING_RECEIVE' }"
          @click="handlePendingAcceptTabClick('PENDING_RECEIVE')"
        >
          待接单<span> ({{ pendingAcceptCounts.pendingCount }}) </span>
        </div>
        <div
          class="status-subtab"
          :class="{
            active: pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK',
          }"
          @click="handlePendingAcceptTabClick('ACCEPT_FAIL_OUT_OF_STOCK')"
        >
          接单失败-缺货<span>
            ({{ pendingAcceptCounts?.acceptedOutOfStockCount || 0 }})
          </span>
        </div>
      </div>

      <div v-if="status === 'PENDING_QUALITY'" class="status-subtabs">
        <div
          class="status-subtab"
          :class="{ active: qualitySubTab === 'PENDING_QUALITY' }"
          @click="handleQualityTabClick('PENDING_QUALITY')"
        >
          待质检<span> ({{ qualityCounts.qualityCount || 0 }}) </span>
        </div>
        <div
          class="status-subtab"
          :class="{ active: qualitySubTab === 'NO_QUALITY' }"
          @click="handleQualityTabClick('NO_QUALITY')"
        >
          质检不通过<span> ({{ qualityCounts.noQualityCount || 0 }}) </span>
        </div>
      </div>
      <!-- 批次管理 -->
      <BatchManageTable v-if="status === 'BATCH_MANAGE'" ref="batchManageRef" />

      <!-- 等待补货 -->
      <WaitingRestockTable
        v-if="status === 'AWAITING_RESTOCK'"
        ref="waitingRestockRef"
      />

      <!-- 到派单、配货中子状态 -->
      <div v-if="isCardLayout" :key="status" class="card-content">
        <CardLayout
          ref="cardLayoutRef"
          :status="listQueryStatus"
          :query-payload="getListQueryPayload()"
          :tag-list="customTagList"
          @selection-change="handleCardSelectionChange"
          @view-detail="handleViewDetail"
        />
      </div>

      <!-- 表格布局 -->
      <div v-if="isTableLayout" class="table-content">
        <splitDiv size="55">
          <template #top>
            <div
              v-loading="loading"
              element-loading-text="加载中..."
              class="table-list flex-1 overflow-hidden"
              @contextmenu.prevent="rightClick"
            >
              <TableView
                ref="tableRef"
                highlight-current-row
                :paginated-data="tableData"
                :columns="mainColumns"
                serial-numberable
                selectionable
                @selection-change="handleMainSelectionChange"
                @sort-change="handleMainTableSortChange"
                @row-click="handleRowClick"
              >
                <template #operation="{ row }">
                  <div
                    v-if="
                      !(
                        status === 'ALL' &&
                        ([, '已取消', '已完成', '已归档'].includes(
                          row.statusName,
                        ) ||
                          row.pause)
                      )
                    "
                    class="main-table-operation"
                  >
                    <span v-if="status === 'PENDING_RECEIVE'" class="item">
                      <ElButton
                        type="primary"
                        link
                        size="small"
                        @click.stop="handleSingleConfirmOrder(row)"
                      >
                        {{
                          pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK'
                            ? '重新接单'
                            : '接单'
                        }}
                      </ElButton>
                    </span>
                    <span
                      v-if="
                        showPendingLogisticsUpdateAddress() &&
                        row.shipmentType === 1
                      "
                      class="item"
                    >
                      <ElButton
                        type="primary"
                        link
                        size="small"
                        @click.stop="openUpdateReceiverAddress(row)"
                      >
                        修改地址
                      </ElButton>
                    </span>
                    <span v-if="showChangeLogistics(row)" class="item">
                      <ElButton
                        type="warning"
                        link
                        size="small"
                        @click.stop="handleChangeLogistics(row)"
                      >
                        更换物流方式
                      </ElButton>
                    </span>
                    <span
                      v-if="showPendingLogisticsUpdateAddress()"
                      class="item"
                    >
                      <ElButton
                        type="success"
                        link
                        size="small"
                        @click.stop="handleRefreshReceiverAddress(row)"
                      >
                        {{
                          row.shipmentType === 0 ? '同步物流/地址' : '同步地址'
                        }}
                      </ElButton>
                    </span>
                    <span
                      v-if="status === 'SUSPEND' && suspendedSubTab !== 1"
                      class="item"
                    >
                      <ElButton
                        type="warning"
                        link
                        size="small"
                        @click.stop="handleCancelSuspend(row)"
                      >
                        取消挂起
                      </ElButton>
                    </span>
                    <span
                      v-if="status === 'SUSPEND' && suspendedSubTab === 1"
                      class="item"
                    >
                      <ElButton
                        type="success"
                        link
                        size="small"
                        @click.stop="handleInterceptionSuccess(row)"
                      >
                        处理拦截
                      </ElButton>
                    </span>
                    <span
                      v-if="status === 'SUSPEND' && suspendedSubTab === 1"
                      class="item"
                    >
                      <ElButton
                        type="danger"
                        link
                        size="small"
                        @click.stop="handleInterceptionFail(row)"
                      >
                        取消拦截
                      </ElButton>
                    </span>
                  </div>
                </template>
              </TableView>
            </div>
            <div class="table-pagination-bar">
              <div class="selected-count-text">
                已选择
                <strong style="color: red">{{ selectedRows.length }}</strong>
                条数据
              </div>
              <ElPagination
                v-model:current-page="currentPage"
                v-model:page-size="pageSize"
                :page-sizes="[50, 100, 200, 300]"
                background
                layout="total, sizes, prev, pager, next, jumper"
                :total="total"
                style="margin: 0 auto"
                @size-change="onPageSizeChange"
                @current-change="onCurrentPageChange"
              />
            </div>
          </template>
          <template #bottom>
            <el-tabs
              v-model="activeTab"
              class="tabs-wrapper"
              @tab-click="handleTabClick"
            >
              <el-tab-pane name="product" label="包含商品">
                <div
                  v-loading="subLoading"
                  element-loading-text="加载中..."
                  class="sub-table-wrapper"
                >
                  <TableView
                    :paginated-data="productList"
                    :columns="productColumns"
                    serial-numberable
                  />
                </div>
              </el-tab-pane>
              <el-tab-pane name="operation" label="操作单">
                <div
                  v-loading="subLoading"
                  element-loading-text="加载中..."
                  class="sub-table-wrapper"
                >
                  <TableView
                    :paginated-data="operationOrderList"
                    :columns="operationOrderColumns"
                    serial-numberable
                    @row-contextmenu="handleOperationOrderContextMenu"
                  />
                </div>
              </el-tab-pane>
              <el-tab-pane name="log" label="操作日志">
                <div
                  v-loading="subLoading"
                  element-loading-text="加载中..."
                  class="detail-table-content"
                >
                  <LogList style="height: 100%" :log-list="logList" />
                  <div v-if="!logList.length" class="empty-content">
                    暂无数据
                  </div>
                </div>
              </el-tab-pane>
            </el-tabs>
          </template>
        </splitDiv>
      </div>
    </div>
    <ConfirmOrderDialog
      ref="confirmOrderDialogRef"
      @success="(data) => openResultInfoDialog(data)"
    />
    <CancelOrderDialog
      ref="cancelOrderDialogRef"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <SuspendDialog
      ref="suspendDialogRef"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <PickCompleteDialog
      ref="pickCompleteDialogRef"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <PickFailDialog
      ref="pickFailDialogRef"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <QualityFailDialog
      ref="qualityFailDialogRef"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />

    <CreateLogisticDialog
      ref="createLogisticDialogRef"
      :new-order-selection="selectedRows"
      @show-result="createLogisticsSuccess"
    />
    <UpdateCustomDeclarationInfoDialog
      ref="updateCustomsDialogRef"
      v-model="updateCustomsDialogVisible"
      :order-selection="selectedRows"
      :is-new-order="true"
      @refresh-table="refreshCurrentView"
    />
    <WeightDialog
      ref="weightDialogRef"
      :is-new-order="true"
      :list-by-no-api="listByNoPodOrderApi"
      :order-weighing-api="orderWeighingPodOrderApi"
      :build-order-weighing-payload="
        (rows) => ({ podOrderWeighingParams: rows })
      "
      @update-list="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <FastProduction
      v-model:detail-visible="detailVisible"
      :is-new-order="true"
      :detail-data="detailData"
      :fast-key="fastKey"
      :default-auto-sure="true"
      :show-operation-no-row="true"
      :is-limit-scan="isLimitScan"
      limit-scan-message="G和CB类的操作单无效操作"
      not-found-message="操作单不存在"
      pending-order-label="操作单号"
      please-scan-tip="请扫码操作单号"
      search-input-audio-tip="请录入操作单号"
      history-storage-key="historyFactoryOrderNewData"
      tracking-placeholder="扫描枪输入操作单号"
      :query-api="getOperationByNo"
      :complete-api="completeOperationById"
      :download-api="downloadOperationById"
      :print-api="printOperationById"
      @on-success="handleFastProductionSuccess"
      @close="fastClose"
    />

    <ArrangeDialog
      ref="arrangeDialogRef"
      :submit-api="submitArrangeFinishApi"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />

    <OperateDetailsDialog
      ref="operateDetailsDialogRef"
      title="申请补胚"
      @adjust-pick-order-success="adjustPickOrderSuccess"
    />

    <PodMakeOrder
      v-model="podOrderVisible"
      :print-order="printOrder"
      :warehouse-list="warehouseList"
      :title="wallType === 'print' ? '配货打单' : '配货分拣'"
      :is-new-order="true"
      :wall-type="wallType"
      :ws-open-code="
        wallType === 'print' ? 'STARTORDERNEWPOD' : 'STARTORDERNEWPODTOP'
      "
      :ws-close-code="
        wallType === 'print' ? 'ENDORDERNEWPOD' : 'ENDORDERNEWPODTOP'
      "
      init-url="factory/podOrderPacking/local/getPodBoxOrderDetails"
      @set-printer="handlePrinterChange"
      @set-warehouse-id="handleWarehouseIdChange"
      @refresh="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <PodDistributionOrder
      v-model="podDistributionOrderVisible"
      :is-new-order="true"
      :print-order="printOrder"
      :warehouse-list="warehouseList"
      :query-api="getSingleQueryPodOrderApi"
      :submit-complete-api="submitPodPrintOrderComplete"
      :print-label-api="getPrintLogisticLabelFactory"
      :map-order-param-list-to-submit-items="mapOrderParamListToSubmitItems"
      warehouse-session-key="locaclFactorySingel"
      @set-printer="handlePrinterChange"
      @refresh="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <PrintWarehouseSkuTag ref="printWarehouseSkuDialogRef" />
    <ResultInfo
      ref="resultRefs"
      :list="resultInfo"
      @confirm="() => refreshCurrentView({ isRefreshTree: true })"
    ></ResultInfo>
    <UpdateAddress
      v-if="updateReceiverAddressVisible"
      v-model:form="receiverAddressForm"
      v-model:visible="updateReceiverAddressVisible"
      :country-list="receiverCountryList"
      :submit-address-api="submitFactoryOrderReceiverAddress"
      @success="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <ChangeWayDialog
      ref="changeWayDialogRef"
      :row-data="changeWayCurrentItem"
      :get-table-fn="getLogisticsCalculation"
      :change-logistics-api="changeLogisticsApi"
      @confirm="() => refreshCurrentView({ isRefreshTree: true })"
    />
    <ElDialog
      v-model="interceptSuccessDialogVisible"
      title="处理拦截"
      width="480px"
      :close-on-click-modal="false"
    >
      <ElForm ref="interceptSuccessFormRef" :model="interceptSuccessForm">
        <ElFormItem
          label="处理拦截类型"
          prop="blockSuccessType"
          :rules="[
            {
              required: true,
              message: '请选择处理拦截类型',
              trigger: 'change',
            },
          ]"
        >
          <ElSelect
            v-model="interceptSuccessForm.blockSuccessType"
            placeholder="请选择"
            style="width: 100%"
            clearable
          >
            <ElOption
              v-for="opt in interceptSuccessTypeOptions"
              :key="opt.value"
              :label="opt.label"
              :value="opt.value"
            />
          </ElSelect>
        </ElFormItem>
      </ElForm>
      <p style="padding-left: 12px">
        拦截成功，订单会流转到已取消，确认是否通过拦截申请？
      </p>
      <template #footer>
        <div class="dialog-footer" style="text-align: center">
          <ElButton @click="interceptSuccessDialogVisible = false"
            >取消</ElButton
          >
          <ElButton type="primary" @click="submitInterceptSuccess"
            >确定</ElButton
          >
        </div>
      </template>
    </ElDialog>
    <ElDialog
      v-model="exportVisible"
      title="导出选项"
      width="500px"
      :close-on-click-modal="false"
    >
      <el-form :model="exportForm" label-width="80px">
        <el-form-item label="" prop="resource">
          <el-radio-group v-model="exportForm.resource">
            <el-radio :label="0">导出本页</el-radio>
            <el-radio :label="1">导出选中</el-radio>
            <el-radio :label="2">全部</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="exportVisible = false">取消</el-button>
          <el-button type="primary" @click="submitExportForm">确认</el-button>
        </span>
      </template>
    </ElDialog>
    <OrderInventoryDetailDialog
      v-model:visible="orderInventoryDetailVisible"
      :warehouse-list="warehouseList"
      :selected-rows="selectedRows"
    />
    <RightClickMenu
      ref="rightMenuRef"
      :show-copy-count="false"
      :show-copy-sub-shop-number="false"
      :show-copy-shop-number="rightClickContext === 'main'"
      :show-selection-menu="rightClickContext === 'main'"
      @on-change="rightChange"
    >
      <template #default>
        <div
          v-if="rightClickContext === 'main'"
          class="menu-item"
          @click="rightChange('order-number')"
        >
          复制订单编号
        </div>
        <div
          v-if="rightClickContext === 'operation'"
          class="menu-item"
          @click="rightChange('operationNo')"
        >
          复制操作单号
        </div>
      </template>
    </RightClickMenu>
  </div>
</template>

<script setup lang="tsx">
import dayjs from 'dayjs'
import {
  ArrowDown,
  ArrowUp,
  CaretTop,
  CaretBottom,
  Edit,
  DocumentCopy,
  WarningFilled,
} from '@element-plus/icons-vue'
import { computed, nextTick, onMounted, ref } from 'vue'
import splitDiv from '@/components/splitDiv/splitDiv.vue'
import TableView from '@/components/TableView.vue'
import RightClickMenu from '@/components/RightClickMenu.vue'
import ResultInfo from '@/views/order/components/ResultInfo.vue'
import type { BaseRespData } from '@/types/api'
import type {
  FactoryOrderNewListData,
  ProductListData,
  CraftData,
  ExportParams,
  operateOrderListData,
} from '@/types/api/order/factoryOrderNew'
import type { AddressInfo, CraftListData } from '@/types/api/podCnOrder'
import platformJson from '../../../json/platform.json'
import {
  refreshProductInfoApi,
  // transferOldFlowApi,
  cancelSuspendApi,
  archiveOrderApi,
  printPickOrderApi,
  applyReplenishApi,
  getTrackingNumberApi,
  getfaceSimplexFileApi,
  cancelLogisticsOrderApi,
  updateLogisticsToArrangeApi,
  downloadMaterialApi,
  downloadOperationMaterialApi,
  composingNewPodOrderDesignImages,
  printNewPodOrderProductionOrderApi,
  syncReceiverAddress,
  getLogisticsCalculation,
  changeLogisticsApi,
  updateReceiverAddressApi,
  updateRemarkApi,
  completeDeliveryApi,
  productionScanApi,
  getByOperationNoLogApi,
  getQualityScanByOperationNoApi,
  listByNoPodOrderApi,
  orderWeighingPodOrderApi,
  finishShipmentPodOrderApi,
  getSingleQueryPodOrderApi,
  submitPodPrintOrderCompleteApi,
  getFactoryOrderNewOperateDetailApi,
  statusPushApi,
  arrangeFinishApi,
  exportFactoryOrderInfo,
  interceptUpdateApi,
  interceptSuccessApi,
  deliveryCompleteApi,
  getStatusPushApi,
  remanufactureApi,
} from '@/api/factoryOrderNew'
import { getConfigApi } from '@/api/order'
import { getLogisticsWayApi } from '@/api/podUsOrder'
import BigNumber from 'bignumber.js'
import { filePath } from '@/api/axios'
import { OrderData } from '@/types/api/podMakeOrder'
import useLodop, { LODOPObject } from '@/utils/hooks/useLodop'
import LogisticsWaySelect from '@/views/logistics/components/LogisticsWaySelect'
import ProductTypeFilter from './component/ProductTypeFilter.vue'
import ConfirmOrderDialog from './component/ConfirmOrderDialog.vue'
import CancelOrderDialog from './component/CancelOrderDialog.vue'
import SuspendDialog from './component/SuspendDialog.vue'
import PickCompleteDialog from './component/PickCompleteDialog.vue'
import PickFailDialog from './component/PickFailDialog.vue'
import QualityFailDialog from './component/QualityFailDialog.vue'
import CardLayout from './component/CardLayout.vue'
import BatchManageTable from './component/BatchManageTable.vue'
import WaitingRestockTable from './component/WaitingRestockTable.vue'
import ArrangeDialog from './component/ArrangeDialog.vue'
import OperateDetailsDialog from './component/OperateDetailsDialog.vue'
import CreateLogisticDialog from '@/views/order/components/CreateLogisticDialog.vue'
import UpdateCustomDeclarationInfoDialog from '@/views/order/components/UpdateCustomDeclarationInfoDialog.vue'
import WeightDialog from '@/views/order/components/WeightDialog.vue'
import FastProduction from '@/views/order/components/FastProduction.vue'
import PodMakeOrder from '@/views/order/podUs/PodMakeOrder.vue'
import PodDistributionOrder from '@/views/order/podCN/PodDistributionOrder.vue'
import PrintWarehouseSkuTag from '@/views/order/components/printWarehouseSkuTag.vue'
import UpdateAddress from '@/views/order/podCN/components/updateAddress.vue'
import ChangeWayDialog from '@/views/order/podCN/components/ChangeWayDialog.vue'
import { ResultInfoDataItem } from '@/types/api/order/common'
import type { FactoryOrderSearchQueryVisibilityContext } from '@/types/api/factoryOrderNew/searchQueryVisibility'
import type { StatusTreeNode } from '@/types/api/order/factoryOrderNew'
import type { StatusListNode } from '@/types/api/factoryOrderNew'
import { useOrderDictionaries } from './hooks/useOrderDictionaries'
import { useOrderSearchForm } from './hooks/useOrderSearchForm'
import { useOrderStatusTree } from './hooks/useOrderStatusTree'
import {
  getDefaultCreateTimeSortParams,
  useOrderListAndDetail,
} from './hooks/useOrderListAndDetail'
import { useOrderBatchActions } from './hooks/useOrderBatchActions'
import { ElButton, ElTag } from 'element-plus'
import OrderInventoryDetailDialog from './component/OrderInventoryDialog.vue'
import { downloadByUrl } from '@/utils/index.ts'
import { getPodOrderCraftApi } from '@/api/podCnOrder.ts'

const resultInfo = ref<ResultInfoDataItem[]>([])
const resultRefs = ref()
const podCraftList = ref<CraftData[]>([])
const statusSidebarCollapsed = ref(false)
const toggleStatusSidebar = () => {
  statusSidebarCollapsed.value = !statusSidebarCollapsed.value
}
const orderInventoryDetailVisible = ref(false)
const batchManageRef = ref<InstanceType<typeof BatchManageTable>>()
const waitingRestockRef = ref<InstanceType<typeof WaitingRestockTable>>()
const cardLayoutRef = ref<InstanceType<typeof CardLayout>>()
const exportVisible = ref(false)
const exportForm = ref({
  resource: '',
})

const interceptSuccessDialogVisible = ref(false)
const interceptSuccessFormRef = ref()
const interceptSuccessTypeOptions = [
  { label: '生产拦截成功', value: 1 },
  { label: '发货拦截成功', value: 2 },
]
const interceptSuccessForm = ref<{ blockSuccessType: number | undefined }>({
  blockSuccessType: undefined,
})
const interceptSuccessRows = ref<FactoryOrderNewListData[]>([])
const sizes = ['FS', 'XS', 'S', 'M', 'L', 'XL', 'XXL', '3XL', '4XL', '5XL']
const {
  userMarkList,
  receiverCountryList,
  customTagList,
  allCodelist,
  warehouseList,
  processTypeMap,
  productTypeGroups,
  getReceiverCountryList,
  loadWarehouseList,
  loadAllDictionaries,
} = useOrderDictionaries(true)

const refreshCurrentViewProxy = ref<() => void>(() => {})
let getFactoryOrderSearchVisibilityContext: () => FactoryOrderSearchQueryVisibilityContext =
  () => ({
    status: 'PENDING_RECEIVE',
    isCardLayout: false,
  })
const {
  searchForm,
  dateRange,
  searchVisible,
  pickerOptions,
  toggleMulti,
  changeReplaceShipment,
  getQueryPayload,
  handleOperationNoScanEnter,
  reset,
} = useOrderSearchForm(
  () => refreshCurrentViewProxy.value(),
  () => getFactoryOrderSearchVisibilityContext(),
)

const statusCurrentPageRef = ref(1)
const statusPageSizeRef = ref(50)
const {
  cardLayoutStatuses,
  statusTree,
  status,
  pendingAcceptSubTab,
  pendingAcceptCounts,
  qualitySubTab,
  qualityCounts,
  suspendedTabs,
  suspendedSubTab,
  // cancelledTabs,
  cancelledSubTab,
  treeRef,
  isCardLayout,
  isSpecialLayout,
  isTableLayout,
  getListPageAcceptedSubStatus,
  getListPageQualitySubStatus,
  getPendingReceiveCounts,
  getQualityCounts,
  getSuspendCounts,
  // getCancelledCounts,
  loadStatusTreeCounts,
  handlePendingAcceptTabClick: handlePendingAcceptTabClickRaw,
  handleQualityTabClick: handleQualityTabClickRaw,
  toggleExpand,
} = useOrderStatusTree({
  getQueryPayload,
  currentPage: statusCurrentPageRef,
  pageSize: statusPageSizeRef,
})
// 查询状态树
const statusTreeChildren = computed((): StatusTreeNode[] => {
  const tree = JSON.parse(JSON.stringify(statusTree.value?.[0]?.children)) as
    | StatusTreeNode[]
    | undefined
  if (!tree) return []
  tree.forEach((item) => {
    if (item.status === 'PICKING') item.children = []
  })
  return tree.filter(
    (item) =>
      item.status !== 'AWAITING_RESTOCK' && item.status !== 'BATCH_MANAGE',
  )
})

const searchFormStatusSelect = computed({
  get() {
    const val = searchForm.value.status
    if (!val) return []
    return String(val).split(',').filter(Boolean)
  },
  set(val: string | string[] | undefined) {
    const arr = Array.isArray(val) ? val : val ? [val] : []
    searchForm.value.status = arr.length ? arr.join(',') : undefined
  },
})
const searchFormOperationStatusSelect = computed({
  get() {
    const val = searchForm.value.operationStatus
    if (!val) return []
    return String(val).split(',').filter(Boolean)
  },
  set(val: string | string[] | undefined) {
    const arr = Array.isArray(val) ? val : val ? [val] : []
    searchForm.value.operationStatus = arr.length ? arr.join(',') : undefined
  },
})
getFactoryOrderSearchVisibilityContext = () => ({
  status: searchForm.value.status ?? status.value,
  isCardLayout: isCardLayout.value,
})

// 全部状态下列表/导出请求status参数
const listQueryStatus = computed(() => {
  if (status.value === 'ALL' && searchForm.value.status) {
    return searchForm.value.status
  }
  return status.value
})

const getListQueryPayload = () => {
  const payload = { ...getQueryPayload() }
  if (status.value === 'ALL' && searchForm.value.status) {
    payload.status = searchForm.value.status
  } else {
    delete payload.status
  }
  // 添加默认时间排序参数
  const defaultSort = getDefaultCreateTimeSortParams(status.value)
  if (defaultSort) {
    payload.prop = defaultSort.prop
    payload.order = defaultSort.order
  }
  const qualityPassed = getListPageQualitySubStatus()
  if (qualityPassed !== undefined) {
    payload.qualityPassed = qualityPassed
  }
  return payload
}

const getCraft = async () => {
  const res = await getPodOrderCraftApi()
  const data: CraftListData[] = res.data
  podCraftList.value = data.map((item: CraftListData) => ({
    id: item.craftCode,
    name: item.craftName,
    warehouseName: processTypeMap[item.craftType] ?? '其他',
  }))
}
getCraft()

const {
  subLoading,
  activeTab,
  productList,
  operationOrderList,
  logList,
  tableRef,
  currentRow,
  selectedRows,
  cardSelectList,
  loading,
  currentPage,
  pageSize,
  total,
  tableData,
  onCurrentPageChange,
  onPageSizeChange,
  refreshTableList,
  getSelectedIds,
  clearTableState,
  handleMainSelectionChange,
  handleCardSelectionChange,
  getOrderDetailsById,
  handleRowClick,
  handleTabClick,
  handleMainTableSortChange,
} = useOrderListAndDetail({
  status: listQueryStatus,
  treeStatus: status,
  isCardLayout,
  isTableLayout,
  getQueryPayload: getListQueryPayload,
  getListPageAcceptedSubStatus,
  suspendedSubTab,
  cancelledSubTab,
})
statusCurrentPageRef.value = currentPage.value
statusPageSizeRef.value = pageSize.value
const exportData = () => {
  exportVisible.value = true
  exportForm.value.resource = ''
}
const submitExportForm = async () => {
  if (exportForm.value.resource === '') {
    return ElMessage.error('请选择导出类型')
  }
  const resourceType = Number(exportForm.value.resource)
  const params: ExportParams = {
    exportAll: false,
    idList: [],
  }
  const mapIds = (items: FactoryOrderNewListData[]) =>
    items.map((el) => Number(el.id))
  switch (resourceType) {
    case 0:
      params.idList = mapIds(tableData.value as FactoryOrderNewListData[])
      break
    case 1:
      if (selectedRows.value.length === 0) {
        return ElMessage.error('请选择要导出的订单')
      }
      params.idList = mapIds(selectedRows.value)
      break
    case 2:
      params.exportAll = true
      params.idList = undefined
      break
    default:
      console.error('未知的资源类型:', resourceType)
  }
  const loading = ElLoading.service({
    text: '导出中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    await exportFactoryOrderInfo({
      ...params,
      ...(resourceType === 2 ? getListQueryPayload() : {}),
    } as ExportParams)
    ElMessage.success('请求成功，请稍后到右上角[我的下载]中查看')
    exportVisible.value = false
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const refreshCurrentView = (options?: { isRefreshTree?: boolean }) => {
  if (options?.isRefreshTree) void loadStatusTreeCounts()
  if (isSpecialLayout.value) {
    if (status.value === 'BATCH_MANAGE') batchManageRef.value?.refresh()
    if (status.value === 'AWAITING_RESTOCK') waitingRestockRef.value?.refresh()
    return
  }
  if (isCardLayout.value) {
    if (status.value === 'PENDING_QUALITY') {
      statusCurrentPageRef.value = currentPage.value
      statusPageSizeRef.value = pageSize.value
      void getQualityCounts()
    }
    cardLayoutRef.value?.clearSelection()
    nextTick(() => {
      cardLayoutRef.value?.refresh(true)
    })
    return
  }
  if (status.value === 'PENDING_RECEIVE') {
    statusCurrentPageRef.value = currentPage.value
    statusPageSizeRef.value = pageSize.value
    void getPendingReceiveCounts()
  }
  if (status.value === 'SUSPEND') {
    void getSuspendCounts()
  }
  // if (status.value === 'CANCELLED') {
  //   void getCancelledCounts()
  // }
  refreshTableList()
}
refreshCurrentViewProxy.value = () => refreshCurrentView()

const updateReceiverAddressVisible = ref(false)
const receiverAddressForm = ref<AddressInfo>({
  receiverName: '',
  rfcNumber: '',
  receiverPhone: '',
  receiverCountry: '',
  receiverProvince: '',
  receiverCity: '',
  receiverDistrict: '',
  receiverAddress1: '',
  receiverAddress2: '',
  receiverPostCode: '',
})

const showPendingLogisticsUpdateAddress = () =>
  status.value === 'ALL' ||
  status.value === 'PENDING_CREATE_LOGISTICS' ||
  (status.value === 'SUSPEND' && suspendedSubTab.value === 2)

const showChangeLogistics = (row: FactoryOrderNewListData) =>
  (status.value === 'ALL' ||
    (status.value === 'SUSPEND' && suspendedSubTab.value === 2)) &&
  row.shipmentType === 1

const submitFactoryOrderReceiverAddress = (data: AddressInfo) =>
  updateReceiverAddressApi(data)

const changeWayDialogRef = ref<InstanceType<typeof ChangeWayDialog>>()
const changeWayCurrentItem = ref<FactoryOrderNewListData | null>(null)

const handleChangeLogistics = (row: FactoryOrderNewListData) => {
  changeWayCurrentItem.value = row
  nextTick(() => {
    changeWayDialogRef.value?.showDialog()
  })
}

const openUpdateReceiverAddress = (row: FactoryOrderNewListData) => {
  receiverAddressForm.value = {
    rfcNumber: '',
    receiverName: '',
    receiverPhone: '',
    receiverCountry: '',
    receiverProvince: '',
    receiverCity: '',
    receiverDistrict: '',
    receiverAddress1: '',
    receiverAddress2: '',
    receiverPostCode: '',
    ...JSON.parse(JSON.stringify(row)),
  } as AddressInfo
  updateReceiverAddressVisible.value = true
}

const handleRefreshReceiverAddress = async (row: FactoryOrderNewListData) => {
  try {
    await ElMessageBox.confirm(
      row.shipmentType === 0 ? '确定同步物流/地址吗?' : '确定同步地址吗?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )
  } catch {
    return
  }
  await syncReceiverAddress([row.id])
  if (row.shipmentType === 1) {
    await ElMessageBox.alert(
      '请修改/刷新地址后取消物流或者更换物流再重新创建物流订单、获取跟踪号、获取打印面单',
      '提示',
      {
        type: 'warning',
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        showCancelButton: true,
      },
    )
  } else {
    ElMessage.success('操作成功')
  }
  refreshCurrentView({ isRefreshTree: true })
}

const handleStatusNodeClick = (node: { status: string }) => {
  status.value = node.status
  if (node.status !== 'PENDING_RECEIVE') {
    pendingAcceptSubTab.value = 'PENDING_RECEIVE'
  }
  if (node.status !== 'PENDING_QUALITY') {
    qualitySubTab.value = 'PENDING_QUALITY'
  }
  if (node.status !== 'SUSPEND') {
    suspendedSubTab.value = 1
  }
  if (node.status !== 'CANCELLED') {
    cancelledSubTab.value = 1
  }
  if (node.status === 'PICKING') {
    getOrderStatus()
  }
  clearTableState()
  if (!isSpecialLayout.value) {
    refreshCurrentView()
  }
}
const statusList = ref<StatusListNode[]>([])
const getOrderStatus = async () => {
  try {
    const res = await getStatusPushApi()
    if (res.code === 200) {
      statusList.value = res.data
    } else {
      ElMessage.error(res.message)
    }
  } catch (error) {
    console.error(error)
    ElMessage.error('订单状态刷新失败')
  }
}
const handlePendingAcceptTabClick = (
  tab: 'PENDING_RECEIVE' | 'ACCEPT_FAIL_OUT_OF_STOCK',
) => handlePendingAcceptTabClickRaw(tab, refreshTableList)

const handleQualityTabClick = (tab: 'PENDING_QUALITY' | 'NO_QUALITY') =>
  handleQualityTabClickRaw(tab, () => {
    cardLayoutRef.value?.clearSelection()
    nextTick(() => {
      cardLayoutRef.value?.refresh(true)
    })
  })

const handleSuspendTabClick = (value: number) => {
  if (suspendedSubTab.value === value) return
  suspendedSubTab.value = value
  currentPage.value = 1
  statusCurrentPageRef.value = 1
  refreshTableList()
}
// const handleCancelledTabClick = (value: number) => {
//   if (cancelledSubTab.value === value) return
//   cancelledSubTab.value = value
//   currentPage.value = 1
//   statusCurrentPageRef.value = 1
//   refreshTableList()
// }
const handleCopyCell = (e: Event | null, text?: string) => {
  e && e.stopPropagation()
  if (text) window.navigator.clipboard.writeText(text)
  ElMessage.success('复制成功')
}

const rightMenuRef = ref()
const rightClickContext = ref<'main' | 'operation'>('main')
const operationRightClickItem = ref<operateOrderListData | null>(null)

const rightClick = (e: MouseEvent) => {
  rightClickContext.value = 'main'
  operationRightClickItem.value = null
  rightMenuRef.value?.setPosition({
    x: e.clientX,
    y: e.clientY,
  })
}

const handleOperationOrderContextMenu = (
  _row: unknown,
  _column: unknown,
  event: Event,
) => {
  event.preventDefault()
  rightClickContext.value = 'operation'
  operationRightClickItem.value = null
  rightMenuRef.value?.setPosition({
    x: (event as MouseEvent).clientX,
    y: (event as MouseEvent).clientY,
  })
}

const rightChange = async (code: string) => {
  if (code === 'select-all') {
    tableRef.value?.toggleAllSelection()
    return
  }
  if (code === 'cancel-select') {
    tableRef.value?.clearSelection()
    return
  }

  const targetRows = selectedRows.value

  if (code === 'copy_shopNumber') {
    const str = targetRows
      .map((item) => item.shopNumber)
      .filter(Boolean)
      .join(',')
    handleCopyCell(null, str)
  } else if (code === 'order-number') {
    const str = targetRows
      .map((item) => item.factoryOrderNumber)
      .filter(Boolean)
      .join(',')
    handleCopyCell(null, str)
  } else if (code === 'operationNo') {
    const str = operationOrderList.value
      .map((item) => item?.operationNo)
      .filter(Boolean)
      .join(',')
    if (!str) return ElMessage.warning('当前数据没有操作单号')
    handleCopyCell(null, str)
  }
}

const mainColumns = computed(() => [
  {
    prop: 'factoryOrderNumber',
    label: '订单编号',
    minWidth: 160,
    align: 'center',
    render: (row: FactoryOrderNewListData) => {
      if (status.value === 'SUSPEND' && row.pauseStatus === 2) {
        return (
          <span
            class="text-clickable"
            onClick={(e: Event) => handleCopyCell(e, row.factoryOrderNumber)}
          >
            {row.factoryOrderNumber}
            <el-tooltip content="客户已确认" placement="top">
              <span
                style="
                  color: #ff6700;
                  font-weight: bold;
                  font-size: 12px;
                  padding: 1px 4px;
                  border: 1px solid #ff6700;
                  border-radius: 4px;
                  margin-left: 4px;
                  line-height: 1.2;
                "
              >
                确
              </span>
            </el-tooltip>
          </span>
        )
      }
      return (
        <span
          class="text-clickable"
          onClick={(e: Event) => handleCopyCell(e, row.factoryOrderNumber)}
        >
          {row.factoryOrderNumber}
        </span>
      )
    },
  },
  {
    prop: 'thirdOrderNumber',
    label: '客户单号',
    minWidth: 160,
    align: 'center',
    render: (row: FactoryOrderNewListData) => {
      return (
        <span
          class="text-clickable"
          onClick={(e: Event) => handleCopyCell(e, row.thirdOrderNumber)}
        >
          {row.thirdOrderNumber}
        </span>
      )
    },
  },
  {
    prop: 'shopNumber',
    label: '店铺单号',
    minWidth: 240,
    render: (row: FactoryOrderNewListData) => {
      return (
        <span
          class="text-clickable"
          onClick={(e: Event) => handleCopyCell(e, row.shopNumber)}
        >
          {row.shopNumber}
        </span>
      )
    },
  },
  {
    prop: 'statusName',
    label: '挂起前状态',
    minWidth: 120,
    hidden: status.value !== 'SUSPEND',
    align: 'center',
  },
  {
    prop: 'statusName',
    hidden: status.value === 'SUSPEND',
    label: '订单状态',
    minWidth: 120,
    align: 'center',
    render: (row: FactoryOrderNewListData) => {
      return <span>{row.pause ? '挂起' : row.statusName}</span>
    },
  },
  {
    label: '客户标签',
    minWidth: 120,
    align: 'center',
    render: (row: FactoryOrderNewListData) => {
      return (
        <div style="display: flex; flex-direction: column; gap: 5px;">
          {row?.customTagList?.map((item) => {
            return (
              <div key={item.id} class="tag-item">
                <ElTag type="success">{item.name}</ElTag>
              </div>
            )
          })}
        </div>
      )
    },
  },
  {
    prop: 'shipmentsNote',
    label: '客户发货备注',
    width: 140,
    align: 'center',
  },
  // 订单状态为已取消时隐藏延期时间列
  ...(status.value === 'CANCELLED'
    ? []
    : [
        {
          prop: 'createTime',
          label: '延期时间',
          width: 140,
          align: 'center',
          render: (row: FactoryOrderNewListData) => {
            const delayText = getOrderDelayText(
              row.createTime ?? '',
              row.finishTime ?? '',
              row.status ?? '',
            )
            return (
              <div style={{ color: 'red', fontWeight: 'bolder' }}>
                {delayText}
              </div>
            )
          },
        },
      ]),
  {
    prop: 'logisticsWayName',
    label: '物流类型',
    width: 140,
    align: 'center',
    render: (row: FactoryOrderNewListData) => {
      return (
        <div>
          {row.shipmentType === 0 && <span>自有物流</span>}
          {row.shipmentType === 1 && <span>九猫统筹物流</span>}
          {row.shipmentType === 2 && <span>自提</span>}
        </div>
      )
    },
  },
  {
    prop: 'logisticsWayName',
    label: '物流方式',
    width: 140,
    align: 'center',
  },
  {
    prop: 'trackingNumber',
    label: '物流跟踪号',
    minWidth: 200,
    align: 'left',
    render: (row: FactoryOrderNewListData) => {
      if (!row.trackingNumber) return null
      return (
        <div class="tracking-number-container">
          <div
            class="tracking-number-text text-clickable"
            title={row.trackingNumber}
            onClick={(e: Event) => {
              e.stopPropagation()
              if (row.expressSheet) {
                window.open(filePath + row.expressSheet, '_blank')
              } else {
                ElMessage.warning('未获取到物流面单，请获取后再打印！')
              }
            }}
          >
            {row.trackingNumber}
          </div>
          <el-icon
            style="cursor:pointer;flex-shrink:0"
            onClick={(e: Event) => handleCopyCell(e, row.trackingNumber)}
          >
            <DocumentCopy />
          </el-icon>
        </div>
      )
    },
  },
  { prop: 'weight', label: '总克重(g)', minWidth: 120, align: 'right' },
  {
    prop: 'productNum',
    label: '商品总数量',
    minWidth: 120,
    align: 'right',
  },
  { prop: 'receiverName', label: '收货人', align: 'center', minWidth: 120 },
  {
    prop: 'receiverPhone',
    label: '收货人电话',
    minWidth: 140,
    align: 'center',
  },
  {
    prop: 'receiverPostCode',
    label: '收货人邮编',
    minWidth: 140,
    align: 'center',
  },
  {
    label: '收货地址',
    minWidth: 220,
    align: 'left',
    render: (row: FactoryOrderNewListData) => {
      return (
        <div>
          <span>{row?.receiverCountry || ''}</span>
          <span>{row?.receiverProvince || ''}</span>
          <span>{row?.receiverCity || ''}</span>
          <span>{row?.receiverDistrict || ''}</span>
          <span>{row?.receiverAddress1 || ''}</span>
          <span>{row?.receiverAddress2 || ''}</span>
        </div>
      )
    },
  },
  {
    prop: 'createTime',
    label: '创建时间',
    minWidth: 180,
    align: 'center',
    sortable: 'custom',
  },
  {
    prop: 'startStockingTime',
    label: '接单时间',
    sortable: 'custom',
    minWidth: 180,
    align: 'center',
  },
  {
    prop: 'finishTime',
    label: '完成时间',
    sortable: 'custom',
    minWidth: 180,
    align: 'center',
  },
  {
    prop: 'operation',
    label: '操作',
    minWidth: 100,
    align: 'center',
    slot: 'operation',
    fixed: 'right',
  },
])

const showProductInventoryColumns = computed(
  () =>
    status.value == 'PENDING_RECEIVE' &&
    pendingAcceptSubTab.value !== 'PENDING_RECEIVE',
)

// 操作单tab表格 - 状态字段：全部、待接单、配货中、待发货、已完成、已取消、已归档 显示
const showOperationStatusColumn = computed(() =>
  [
    'ALL',
    'PENDING_RECEIVE',
    'PICKING',
    'PENDING_DELIVERY',
    'COMPLETED',
    'CANCELLED',
    'ARCHIVE',
  ].includes(status.value),
)
function parseOperationOrderImageAry(
  imageAry?: string | null | unknown,
): { url: string; title?: string }[] {
  if (typeof imageAry !== 'string' || !imageAry.trim()) return []
  try {
    const list = JSON.parse(imageAry) as { url?: string; title?: string }[]
    if (!Array.isArray(list)) return []
    return list
      .filter((x) => x?.url)
      .map((x) => ({ url: x.url as string, title: x.title }))
  } catch {
    return []
  }
}

function getOperationOrderMarkLabel(row: operateOrderListData): string {
  const mark = row.customizedQuantity
  if (mark === 1) return '单面'
  if (mark === 2) return '双面'
  return ''
}

const operationOrderColumns = computed(() => [
  {
    key: 'operationNo',
    prop: 'operationNo',
    label: '操作单号',
    minWidth: 160,
    align: 'center',
    showOverflowTooltip: true,
  },
  {
    key: 'statusName',
    prop: 'statusName',
    label: '状态',
    minWidth: 100,
    align: 'center',
    showColumn: showOperationStatusColumn.value,
    render: (row: operateOrderListData) => {
      return <span>{row?.statusName ?? ''}</span>
    },
  },
  {
    key: 'imageAry',
    prop: 'imageAry',
    label: '商品图片',
    minWidth: 180,
    align: 'center',
    render: (row: operateOrderListData) => {
      const list = parseOperationOrderImageAry(row.imageAry)
      if (!list.length) {
        return (
          <div style="display:flex;gap:4px;">
            <el-image
              src={row.variantImage}
              style="width:50px;height:50px"
              previewSrcList={[row.variantImage ?? '']}
              previewTeleported
            />
          </div>
        )
      }
      const urls = list.map((i) => i.url)
      return (
        <div style="display:flex;gap:4px;">
          {list.map((img, idx) => (
            <el-image
              key={idx}
              src={img.url}
              previewSrcList={urls}
              previewTeleported={true}
              initialIndex={idx}
              style="width:50px;height:50px"
              title={img.title ?? ''}
            />
          ))}
        </div>
      )
    },
  },
  {
    key: 'productName',
    prop: 'productName',
    label: '商品名称',
    minWidth: 180,
    align: 'left',
    showOverflowTooltip: true,
  },
  {
    key: 'variantSku',
    prop: 'variantSku',
    label: '变体SKU',
    minWidth: 140,
    align: 'center',
    showOverflowTooltip: true,
  },
  {
    key: 'thirdSkuCode',
    prop: 'thirdSkuCode',
    label: '库存SKU',
    minWidth: 160,
    align: 'center',
    showOverflowTooltip: false,
    render: (row: operateOrderListData) => {
      const displaySku = row.thirdSkuCode || '-'
      const originSku = row.originThirdSkuCode as string | undefined
      const tipSku = originSku || row.thirdSkuCode || ''

      return (
        <div class="third-sku-cell">
          {originSku && originSku !== row.thirdSkuCode && (
            <el-tooltip
              effect="dark"
              placement="top-start"
              teleported
              v-slots={{
                content: () => (
                  <div>
                    <div>{`库存SKU: ${row.thirdSkuCode}`}</div>
                    <div>{`下单库存SKU: ${tipSku}`}</div>
                    <div>(共享库存替代)</div>
                  </div>
                ),
              }}
            >
              <el-icon style="color:#409EFF;cursor:pointer;">
                <WarningFilled />
              </el-icon>
            </el-tooltip>
          )}
          <span class="ellipsis">{displaySku}</span>
        </div>
      )
    },
  },
  {
    key: 'productMark',
    prop: 'productMark',
    label: '类型',
    width: 72,
    align: 'center',
    render: (row: operateOrderListData) => {
      const label = getOperationOrderMarkLabel(row)
      if (!label) return <span />
      return <ElTag type="primary">{label}</ElTag>
    },
  },
  {
    key: 'statusName',
    prop: 'statusName',
    label: '挂起前状态',
    minWidth: 120,
    align: 'center',
    showOverflowTooltip: true,
    showColumn: currentRow.value?.pause === true,
  },
  {
    key: 'craftName',
    prop: 'craftName',
    label: '工艺',
    minWidth: 100,
    align: 'center',
    showOverflowTooltip: true,
  },
  {
    key: 'supplierProductNo',
    prop: 'supplierProductNo',
    label: '款号',
    minWidth: 120,
    align: 'center',
    showOverflowTooltip: true,
  },
  {
    key: 'batchArrangeNumber',
    prop: 'batchArrangeNumber',
    label: '批次号',
    minWidth: 120,
    align: 'center',
    showOverflowTooltip: true,
  },
])

const baseProductColumns = computed(() => [
  {
    key: 'variantImage',
    prop: 'variantImage',
    label: '商品图片',
    minWidth: 90,
    align: 'center',
    render: (row: ProductListData) => {
      return (
        <div>
          <el-image
            src={row?.variantImage ?? ''}
            previewSrcList={[row?.variantImage ?? '']}
            style="width: 50px; height: 50px"
            previewTeleported
          />
        </div>
      )
    },
  },
  {
    key: 'productName',
    prop: 'productName',
    label: '商品名称',
    minWidth: 200,
    showOverflowTooltip: true,
  },
  {
    key: 'variantSku',
    prop: 'variantSku',
    label: '变体SKU',
    minWidth: 160,
    align: 'center',
  },
  {
    key: 'thirdSkuCode',
    prop: 'thirdSkuCode',
    label: '库存SKU',
    minWidth: 160,
    align: 'center',
  },
  {
    key: 'craftCode',
    prop: 'craftCode',
    label: '工艺',
    minWidth: 100,
    align: 'center',
  },
  {
    prop: 'supplierProductNo',
    label: '款号',
    minWidth: 140,
    align: 'center',
  },
  {
    key: 'categoryName',
    prop: 'categoryName',
    label: '商品类目',
    minWidth: 160,
    align: 'center',
  },
  {
    prop: 'price',
    label: '价格',
    minWidth: 100,
    align: 'right',
    render: (row: ProductListData) => {
      return (
        <span>
          {new BigNumber(row.templatePrice ?? 0)
            .plus(row.craftPrice ?? 0)
            .toString()}
        </span>
      )
    },
  },
  {
    prop: 'num',
    label: '数量',
    minWidth: 100,
    align: 'right',
  },
  {
    prop: 'weight',
    label: '克重(g)',
    minWidth: 100,
    align: 'right',
  },
  {
    label: '可用数量',
    minWidth: 100,
    align: 'right',
    showColumn: showProductInventoryColumns.value,
    render: (row: ProductListData) => {
      const available = new BigNumber(row.inventory ?? 0)
        .minus(row.occupyInventory ?? 0)
        .minus(row.freezeInventory ?? 0)
        .toNumber()
      return <span>{available}</span>
    },
  },
  {
    prop: 'inventory',
    label: '库存数量',
    minWidth: 100,
    align: 'right',
    showColumn: showProductInventoryColumns.value,
    render: (row: ProductListData) => {
      return <span>{row.inventory || 0}</span>
    },
  },
  {
    prop: 'occupyInventory',
    label: '占用数量',
    minWidth: 100,
    align: 'right',
    showColumn: showProductInventoryColumns.value,
    render: (row: ProductListData) => {
      return <span>{row.occupyInventory || 0}</span>
    },
  },
  {
    prop: 'freezeInventory',
    label: '冻结数量',
    minWidth: 100,
    align: 'right',
    showColumn: showProductInventoryColumns.value,
    render: (row: ProductListData) => {
      return <span>{row.freezeInventory || 0}</span>
    },
  },
  {
    prop: 'customsNameEnglish',
    label: '英文报关名称',
    width: 160,
    align: 'center',
  },
  {
    prop: 'customsNameChinese',
    label: '中文报关名称',
    width: 160,
    align: 'center',
  },
  {
    prop: 'customsWeight',
    label: '申报重量(g)',
    width: 100,
    align: 'right',
  },
  {
    prop: 'customsValue',
    label: '申报价值($)',
    width: 100,
    align: 'right',
  },
  {
    key: 'remark',
    prop: 'remark',
    label: '备注',
    width: 160,
    align: 'center',
    render: (row: ProductListData) => {
      return (
        <div style="display:flex;align-items:center;justify-content:center;gap:4px">
          <span>{row?.remark ?? ''}</span>
          <el-icon
            style="cursor:pointer;color:#409eff;flex-shrink:0"
            onClick={(e: Event) => {
              e.stopPropagation()
              handleEditRemark(row)
            }}
          >
            <Edit />
          </el-icon>
        </div>
      )
    },
  },
])

const productColumns = computed(() => {
  if (status.value === 'PENDING_DELIVERY') {
    return [
      ...baseProductColumns.value,
      {
        key: 'operation',
        prop: 'operation',
        label: '操作',
        width: 160,
        align: 'center',
        fixed: 'right',
        render: (row: ProductListData) => {
          return (
            <div>
              <span class="item">
                <el-button
                  type="primary"
                  link
                  size="small"
                  onClick={(e: Event) => {
                    e.stopPropagation()
                    handleSubApplyReplenish(row)
                  }}
                >
                  申请补胚
                </el-button>
              </span>

              <span class="item">
                <el-button
                  type="primary"
                  link
                  size="small"
                  onClick={(e: Event) => {
                    e.stopPropagation()
                    handleDownloadMaterialByProduct(row)
                  }}
                >
                  下载素材
                </el-button>
              </span>
            </div>
          )
        },
      },
    ]
  }
  return baseProductColumns.value
})

const confirmOrderDialogRef = ref<InstanceType<typeof ConfirmOrderDialog>>()
const cancelOrderDialogRef = ref<InstanceType<typeof CancelOrderDialog>>()
const suspendDialogRef = ref<InstanceType<typeof SuspendDialog>>()
const pickCompleteDialogRef = ref<InstanceType<typeof PickCompleteDialog>>()
const pickFailDialogRef = ref<InstanceType<typeof PickFailDialog>>()
const qualityFailDialogRef = ref<InstanceType<typeof QualityFailDialog>>()
const operateDetailsDialogRef = ref()
const arrangeDialogRef = ref<InstanceType<typeof ArrangeDialog>>()
const createLogisticDialogRef = ref()
const printWarehouseSkuDialogRef =
  ref<InstanceType<typeof PrintWarehouseSkuTag>>()
const updateCustomsDialogVisible = ref(false)
const weightDialogRef = ref()
const detailVisible = ref(false)
const fastKey = ref('')
const detailData = ref<Record<string, unknown>>({})
const { ensureSelection, executeBatchAction } = useOrderBatchActions({
  getIds: getSelectedIds,
  refreshCurrentView,
})
const handleEditRemark = async (row: ProductListData) => {
  try {
    const { value } = await ElMessageBox.prompt('请输入备注', '提示', {
      inputValue: row.remark || '',
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      inputPattern: /.+/,
      inputErrorMessage: '请输入备注',
    })
    try {
      const res = await updateRemarkApi(row.id, value)
      if (res.code !== 200) return
      ElMessage.success('备注修改成功')
      getOrderDetailsById('product')
    } catch (e) {
      console.error(e)
    }
  } catch {
    // cancelled
  }
}

const handleSubApplyReplenish = (row: ProductListData) => {
  operateDetailsDialogRef.value?.open({
    row,
    ids: [row.id],
    url: 'factory/podOrderOperation/getListByPodProductId',
  })
}

const handleConfirmOrder = () => {
  if (!ensureSelection()) return
  confirmOrderDialogRef.value?.open(getSelectedIds())
}
const openResultInfoDialog = (data: ResultInfoDataItem[]) => {
  nextTick(() => {
    const isSuccess = data.every((item) => item.status)
    if (!isSuccess) {
      resultInfo.value = data.filter((item) => !item.status)
      resultRefs.value?.showDialog()
    } else {
      ElMessage.success('操作成功')
      refreshCurrentView({ isRefreshTree: true })
    }
  })
}
const handleCancelOrder = () => {
  if (!ensureSelection()) return
  cancelOrderDialogRef.value?.open(getSelectedIds())
}
const handleRefreshProductInfo = async () => {
  if (!ensureSelection()) return
  try {
    await ElMessageBox.confirm('确定刷新商品信息吗？', '提示', {
      type: 'warning',
      confirmButtonText: '确认',
      cancelButtonText: '取消',
    })
  } catch {
    return
  }
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await refreshProductInfoApi({
      orderIds: !isCardLayout.value ? getSelectedIds().join(',') : undefined,
      productIds: isCardLayout.value
        ? cardSelectList.value
            .map((row) => row.podOrderProductId ?? 0)
            .join(',')
        : undefined,
    })
    if (res.code !== 200) return
    ElMessage.success('刷新商品信息成功')
    refreshCurrentView()
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const handleLogisticsCommand = async (command: string) => {
  if (!ensureSelection()) return
  const ids = getSelectedIds()
  if (command === 'createLogistic') {
    createLogisticDialogRef.value?.showDialog(ids)
    return
  }
  const apiMap: Record<
    string,
    (data: (number | string)[]) => Promise<BaseRespData<unknown>>
  > = {
    getTrackingNumber: getTrackingNumberApi,
    getPrintOrder: getfaceSimplexFileApi,
    cancelLogistic: cancelLogisticsOrderApi,
  }
  const labelMap: Record<string, string> = {
    getTrackingNumber: '获取跟踪号',
    getPrintOrder: '获取打印面单',
    cancelLogistic: '取消物流订单',
  }
  const api = apiMap[command]
  if (!api) return
  try {
    await ElMessageBox.confirm(`确定${labelMap[command]}吗？`, '提示', {
      type: 'warning',
    })
  } catch {
    return
  }
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await api(ids)
    if (res.code === 200) {
      if (Array.isArray(res.data)) {
        const isSuccess = res.data.every((item) => item.status)
        if (!isSuccess) {
          resultInfo.value = res.data.filter((item) => !item.status)

          resultRefs.value?.showDialog()
        } else {
          ElMessage.success('操作成功')
          refreshCurrentView()
        }
      } else if (typeof res.data === 'string') {
        window.open(filePath + res.data)
      }
    }
  } catch (e: unknown) {
    resultInfo.value = []
    console.error(e)
  } finally {
    loading.close()
  }
}
const handleSuspend = () => {
  if (!ensureSelection()) return
  let ids: (number | string)[]
  if (isCardLayout.value) {
    ids = cardSelectList.value.map((row) => row.podOrderId as number)
  } else {
    ids = selectedRows.value.map((row) => row.id)
  }
  suspendDialogRef.value?.open(ids)
}
const updateCustomsDialogRef = ref()
const handleUpdateCustomsInfo = async () => {
  if (!ensureSelection()) return
  updateCustomsDialogVisible.value = true
  await nextTick()
  updateCustomsDialogRef.value?.resetForm()
}
// 值为空：已取消状态
const NULL_STATUSES = ['CANCELLED']
// 终态订单：已完成/已归档
const TERMINAL_ORDER_STATUSES = ['COMPLETED', 'ARCHIVE']
const getOrderDelayText = (
  createTime?: string | null,
  finishTime?: string | null,
  statusValue?: string | null,
) => {
  if (!createTime) return ''
  const currentStatus = statusValue ?? ''
  if (TERMINAL_ORDER_STATUSES.includes(currentStatus) && !finishTime) return ''
  const createAt = dayjs(createTime)
  if (!createAt.isValid()) return ''

  // 终态订单用 finishTime - createTime 的差值
  // 其他状态用 当前时间 - createTime 的差值
  const endTime =
    TERMINAL_ORDER_STATUSES.includes(currentStatus) && finishTime
      ? dayjs(finishTime)
      : dayjs()
  const diffMinutes = Math.max(0, endTime.diff(createAt, 'minute'))
  const baseHours = Math.floor(diffMinutes / 60)
  const remainMinutes = diffMinutes % 60
  const hours = baseHours + (remainMinutes > 30 ? 1 : 0)
  const result = !NULL_STATUSES.includes(currentStatus) ? `${hours}h` : ''
  return result
}

const handleTransferToArrange = async () => {
  if (!ensureSelection('请选择订单')) return
  try {
    await ElMessageBox.confirm('确定转至待排单吗?', '提示', {
      type: 'warning',
    })
  } catch {
    return
  }
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const ids = getSelectedIds().join(',')
    const res = await updateLogisticsToArrangeApi({ ids })
    if (res.code !== 200) return
    if (Array.isArray(res.data)) {
      const isSuccess = res.data.every(
        (item: { status?: boolean }) => item.status,
      )
      if (!isSuccess) {
        resultInfo.value = res.data.filter(
          (item: { status?: boolean }) => !item.status,
        )
        resultRefs.value?.showDialog()
      } else {
        ElMessage.success('操作成功')
        refreshCurrentView({ isRefreshTree: true })
      }
    } else {
      ElMessage.success('操作成功')
      refreshCurrentView({ isRefreshTree: true })
    }
  } catch (e: unknown) {
    resultInfo.value = []
    console.error(e)
  } finally {
    loading.close()
  }
}
const handleArrange = async () => {
  if (!ensureSelection()) return
  const productIdList = getSelectedIds()
    .map((v) => Number(v))
    .filter((n) => Number.isFinite(n)) as number[]
  const productMarks = Array.from(
    new Set(
      cardSelectList.value
        .map((item) => item.productMark)
        .filter(Boolean)
        .map((mark) =>
          mark === 'custom_normal' || mark === 'normal' ? 'normal_group' : mark,
        ),
    ),
  )
  if (productMarks.length > 1) {
    return await ElMessageBox.confirm(
      '无法排单，你选择的操作单包含多种商品类型，排单不支持多种商品类型混排，请选择同一类型的商品对应的生产单后再试!',
      '错误提示',
      {
        confirmButtonText: '确定',
        type: 'warning',
      },
    )
  }
  if (productMarks[0] === 'custom_part') {
    const craftTypes = Array.from(
      new Set(
        cardSelectList.value.map((item) => item.craftType).filter(Boolean),
      ),
    )
    if (craftTypes.length > 1) {
      await ElMessageBox.confirm(
        '选中排单的操作单存在多个工艺类型, 是否继续排单?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        },
      )
    }
    arrangeDialogRef.value?.open({
      productIdList,
      showAutoSwitch: true,
    })
    return
  }

  await ElMessageBox.confirm('确认对所选择的操作单进行排单?', '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  })
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await submitArrangeFinishApi({ productIdList })
    if (res.code !== 200) return
    ElMessage.success(res.message)
    refreshCurrentView({ isRefreshTree: true })
  } catch (e: unknown) {
    console.error(e)
  } finally {
    loading.close()
  }
}

const submitArrangeFinishApi = (params: {
  productIdList?: number[]
  templateWidth?: number
  type?: string
}) =>
  arrangeFinishApi({
    productIdList: params.productIdList || [],
    templateWidth: params.templateWidth,
    type: params.type,
  })

const handleSingleConfirmOrder = (row: FactoryOrderNewListData) => {
  confirmOrderDialogRef.value?.open([row.id])
}
const podOrderVisible = ref(false)
const podDistributionOrderVisible = ref(false)
const sheetPrinter = ref('')
const handlePrinterChange = (value: string) => {
  sheetPrinter.value = value
  localStorage.setItem('sheetPrinter', JSON.stringify(value))
}
const handleWarehouseIdChange = (
  value:
    | string
    | { warehouseId: string | number; sortingAreaId: string | number },
) => {
  if (wallType.value === 'print') {
    localStorage.setItem('localNewWarehouseId', JSON.stringify(value))
  } else if (wallType.value === 'sort') {
    localStorage.setItem('localSortingAreaId', JSON.stringify(value))
  }
}
const mapOrderParamListToSubmitItems = (
  orderParamList: { id: number; dataVersion?: number }[],
) => orderParamList.map((item) => ({ id: item.id }))

const submitPodPrintOrderComplete = (
  data: { id: number; version?: number }[],
  warehouseId: number | string,
) =>
  submitPodPrintOrderCompleteApi(
    {
      orderParamList: data.map((item) => ({ id: item.id })),
    },
    warehouseId,
  )

const getPrintLogisticLabelFactory = (id?: number) =>
  getfaceSimplexFileApi([id ?? 0])

const { getCLodop } = useLodop()
const wallType = ref<'print' | 'sort'>('print')
const handleSeedingWall = (type: 'print' | 'sort') => {
  wallType.value = type
  const lodop = getCLodop(null, null)
  if (!lodop) return
  sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
  podOrderVisible.value = true
}

/** LODOP 单例不可并发，打印串行 */
let printOrderChain: Promise<void> = Promise.resolve()

const printOrder = (data: OrderData, callback: (status: boolean) => void) => {
  const run = async () => {
    const lodop = getCLodop(null, null)
    if (!lodop) {
      callback && callback(false)
      return
    }
    lodop.PRINT_INIT('打印内容')
    const printerIndex = lodop.SET_PRINTER_INDEX(sheetPrinter.value)
    console.log(
      'printerIndex',
      printerIndex,
      `sheetPrinter.value:${sheetPrinter.value}`,
    )
    if (!printerIndex) {
      ElMessage.error('打印机设置失败')
      callback && callback(false)
      return
    }
    if (data.filePath) {
      const strURL = filePath + data.filePath
      const isHttpsPdf = /(https):\/\/([^/]+)/i.test(strURL)
      console.log('[printOrder] label source', {
        id: data.id,
        hasFilePath: !!data.filePath,
        hasFileData: !!data.fileData,
        isHttpsPdf,
        strURL,
      })
      const pdfPayload = isHttpsPdf ? downloadPDF(strURL) : strURL
      console.log('[printOrder] pdf payload meta', {
        mode: isHttpsPdf ? 'base64' : 'url',
        length: pdfPayload?.length || 0,
        preview: pdfPayload?.slice(0, 30),
      })
      lodop.ADD_PRINT_PDF(0, 0, '100%', '100%', pdfPayload)
    } else {
      console.log('[printOrder] raw payload meta', {
        id: data.id,
        hasFilePath: !!data.filePath,
        fileDataLength: data.fileData?.length || 0,
        fileDataPreview: data.fileData?.slice(0, 30),
      })
      lodop.SEND_PRINT_RAWDATA(data.fileData || '')
    }
    console.log('lodop.CVERSION', lodop.CVERSION)
    if (lodop.CVERSION) {
      const startTime = Date.now()
      const jobCode = await lodopCall((lodop) => {
        lodop.SET_PRINT_MODE('CATCH_PRINT_STATUS', true)
        return lodop.PRINT()
      })
      console.log('jobCode', jobCode)
      // eslint-disable-next-line no-constant-condition
      while (true) {
        const ok = await lodopCall((lodop) =>
          lodop.GET_VALUE('PRINT_STATUS_OK', jobCode),
        )
        console.log('PRINT_STATUS_OK:', jobCode, `ok: ${ok}`)
        if (ok == 1) {
          console.log('打印成功')
          callback && callback(true)
          return
        }
        const exist = await lodopCall((lodop) =>
          lodop.GET_VALUE('PRINT_STATUS_EXIST', jobCode),
        )
        console.log(
          '[LODOP] PRINT_STATUS OK,EXIST',
          jobCode,
          `ok:${ok}`,
          `exist:${exist}`,
          `jobCode:${jobCode}`,
          `(${Date.now() - startTime}ms)`,
        )
        if (exist == 0) {
          console.log('任务不存在了', `exist:${exist}`)
          callback && callback(true)
          return
        }

        await new Promise((r) => setTimeout(r, 500))
        if (Date.now() - startTime >= 30000) {
          console.log('打印超时(30秒)')
          ElMessage.error('打印超时(30秒)')
          callback && callback(false)
          return
        }
      }
    } else {
      lodop.PRINT()
      callback && callback(false)
    }
  }

  printOrderChain = printOrderChain.then(run, run)
}
let _lodop: LODOPObject | null = null
let _lodopCallback: { [key: string]: (value: string) => void } = {}
const lodopCall = (fn: (lodop: LODOPObject) => string) => {
  if (!_lodop) {
    _lodop = getCLodop(null, null)
    if (!_lodop) return
    _lodop.On_Return_Remain = true
    _lodop.SET_PRINT_MODE('CATCH_PRINT_STATUS', true)
    _lodopCallback = {}
    _lodop.On_Return = (id, value) => {
      console.log('lodopCall return', id, JSON.stringify(value))
      const cb = _lodopCallback[id]
      if (!cb) return
      delete _lodopCallback[id]
      cb(value)
    }
  }

  return new Promise((resolve) => {
    if (!_lodop) return
    const id = fn(_lodop)
    console.log('lodopCall', id)
    _lodopCallback[id] = resolve
  })
}
const downloadPDF = (url: string) => {
  if (!/^https?:/i.test(url)) return url
  let xhr,
    arrybuffer = false,
    dataArray = null
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest()
  } else {
    xhr = new window.ActiveXObject('MSXML2.XMLHTTP')
  }
  xhr.open('GET', url, false) //同步方式
  if (xhr.overrideMimeType)
    try {
      xhr.responseType = 'arraybuffer'
      arrybuffer = true
    } catch (err) {
      xhr.overrideMimeType('text/plain; charset=x-user-defined')
    }
  xhr.send(null)
  console.log('[downloadPDF] response meta', {
    url,
    status: xhr.status,
    readyState: xhr.readyState,
    contentType: xhr.getResponseHeader?.('content-type'),
    responseType: xhr.responseType,
  })
  const data = xhr.response || xhr.responseBody
  const dataByteLength = arrybuffer
    ? (data as ArrayBuffer | null)?.byteLength || 0
    : (data as string | null)?.length || 0
  console.log('[downloadPDF] data length', {
    url,
    arrybuffer,
    dataByteLength,
  })
  if (typeof Uint8Array !== 'undefined') {
    if (arrybuffer) {
      dataArray = new Uint8Array(data)
    } else {
      dataArray = new Uint8Array(data.length)
      for (let i = 0; i < dataArray.length; i++) {
        dataArray[i] = data.charCodeAt(i)
      }
    }
  } else {
    dataArray = window.VBS_BinaryToArray(data).toArray() //兼容IE低版本
  }
  const digits =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
  let strData = ''
  for (let i = 0, ii = dataArray.length; i < ii; i += 3) {
    if (isNaN(dataArray[i])) break
    const b1 = dataArray[i] & 0xff,
      b2 = dataArray[i + 1] & 0xff,
      b3 = dataArray[i + 2] & 0xff
    const d1 = b1 >> 2,
      d2 = ((b1 & 3) << 4) | (b2 >> 4)
    const d3 = i + 1 < ii ? ((b2 & 0xf) << 2) | (b3 >> 6) : 64
    const d4 = i + 2 < ii ? b3 & 0x3f : 64
    strData +=
      digits.substring(d1, d1 + 1) +
      digits.substring(d2, d2 + 1) +
      digits.substring(d3, d3 + 1) +
      digits.substring(d4, d4 + 1)
  }
  console.log('[downloadPDF] base64 meta', {
    url,
    base64Length: strData.length,
    base64Preview: strData.slice(0, 30),
  })
  return strData
}
const handleDownloadMaterial = async () => {
  if (!ensureSelection()) return
  const usePodOrderDownloadStatuses = ['PENDING_DELIVERY', 'SUSPEND']
  const usePodOrderDownload = usePodOrderDownloadStatuses.includes(status.value)
  const ids = usePodOrderDownload
    ? selectedRows.value.map((row) => row.id)
    : cardSelectList.value.map((row) => row.podOrderProductId)
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = usePodOrderDownload
      ? await downloadMaterialApi(ids as number[])
      : await downloadOperationMaterialApi(ids as number[])
    if (res.code !== 200) return
    downloadByUrl(
      filePath + res.message,
      res.message?.split('/').pop() || 'download',
    )
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const handleDownloadMaterialByProduct = async (row: ProductListData) => {
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await downloadOperationMaterialApi([row.id])
    if (res.code !== 200) return
    downloadByUrl(
      filePath + res.message,
      res.message?.split('/').pop() || 'download',
    )
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const handleDtfCommand = async (command: string) => {
  if (!ensureSelection()) return
  const ids = getSelectedIds()
  const [type, widthStr] = command.split('_')
  const templateWidth = Number(widthStr)
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await composingNewPodOrderDesignImages(
      ids as number[],
      type,
      templateWidth,
    )
    if (res.message) {
      const filePathUrl =
        type === 'tiff'
          ? res.message?.startsWith('/temp')
            ? `https://factory.jomalls.com/upload/factory` + res.message
            : `https://ps.jomalls.com/tiff/` + res.message
          : filePath + res.message
      window.open(filePathUrl, '_blank')
    }
    ElMessage.success('DTF排版成功')
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const handlePrintProductionOrder = async () => {
  if (!ensureSelection()) return
  const ids = getSelectedIds()
  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await printNewPodOrderProductionOrderApi(ids as number[])
    if (res.message) {
      window.open(filePath + res.message, '_blank')
    }
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const handlePrintPickOrder = async () => {
  if (!ensureSelection()) return
  const ids = getSelectedIds()
  try {
    const res = await printPickOrderApi(ids as number[])
    if (res.code !== 200) return
    window.open(filePath + res.message, '_blank')
  } catch (e) {
    console.error(e)
  }
}
const handlePickComplete = () => {
  if (!ensureSelection()) return
  pickCompleteDialogRef.value?.open(getSelectedIds())
}
const handleDeliveryComplete = () => {
  if (!ensureSelection()) return
  ElMessageBox.confirm('确定完成发货吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
  })
    .then(async () => {
      const params = selectedRows.value.map((row) => ({
        id: row.id,
        version: row.version,
      }))
      const loading = ElLoading.service({
        fullscreen: true,
        text: '操作中...',
        background: 'rgba(0, 0, 0, 0.3)',
      })
      try {
        const res = await deliveryCompleteApi(params)
        if (res.code !== 200) return
        ElMessage.success('操作成功')
      } catch (e) {
        console.error(e)
      } finally {
        loading.close()
        refreshCurrentView({ isRefreshTree: true })
      }
    })
    .catch(() => {})
}
const handlePickFail = () => {
  if (!ensureSelection()) return
  pickFailDialogRef.value?.open(getSelectedIds(), {
    title: '拣胚失败',
    submitType: 'pick',
  })
}
const handleApplyReplenish = async () => {
  await executeBatchAction({
    getIds: getSelectedIds,
    api: applyReplenishApi,
    confirmText: '确定申请补胚吗?',
    successText: '申请补胚成功',
    refreshTree: true,
  })
}
const handleRemanufacture = () => {
  if (!ensureSelection()) return
  const rows = isCardLayout.value ? cardSelectList.value : selectedRows.value
  ElMessageBox.confirm('确定重新生产吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      const loading = ElLoading.service({
        fullscreen: true,
        text: '操作中...',
        background: 'rgba(0, 0, 0, 0.3)',
      })
      try {
        const res = await remanufactureApi({
          updateParams: rows.map((row) => ({
            id: row.id,
            version: row.version,
          })),
        })
        if (res.code !== 200) return
        ElMessage.success('重新生产成功')
        refreshCurrentView({ isRefreshTree: true })
      } catch (e) {
        console.error(e)
      } finally {
        loading.close()
      }
    })
    .catch(() => {})
}
const adjustPickOrderSuccess = async (
  _: unknown,
  selectionOperationIds: number[],
) => {
  try {
    const res = await applyReplenishApi(selectionOperationIds)
    if (res.code !== 200) return
    ElMessage.success('申请补胚成功')
    refreshCurrentView({ isRefreshTree: true })
  } catch (e) {
    console.error(e)
  }
}
const handleProductionComplete = async () => {
  await executeBatchAction({
    getIds: getSelectedIds,
    api: completeDeliveryApi,
    confirmText: '确定生产完成吗？',
    onSuccess: (res) => {
      const data = Array.isArray(res.data)
        ? (res.data as ResultInfoDataItem[])
        : []
      openResultInfoDialog(data)
    },
  })
}
const handleWeightSort = () => {
  weightDialogRef.value?.open()
}
const handleCompleteDelivery = () => {
  if (!ensureSelection()) return
  ElMessageBox.confirm(
    `<div>确定完成发货吗？</div>
    <div style="color: #ff2626; margin-top: 8px; font-size: 13px;">注意：完成发货前请先核对商品重量</div>`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      dangerouslyUseHTMLString: true,
    },
  )
    .then(async () => {
      const params = {
        podOrderWeighingParams: selectedRows.value.map((row) => ({
          id: String(row.id),
          outWarehouseWeight:
            row.weight != null ? String(row.weight) : undefined,
        })),
      }
      const loading = ElLoading.service({
        fullscreen: true,
        text: '操作中...',
        background: 'rgba(0, 0, 0, 0.3)',
      })
      try {
        const res = await finishShipmentPodOrderApi(params)
        if (res.code !== 200) return
        ElMessage.success('操作成功')
      } catch (e) {
        console.error(e)
      } finally {
        loading.close()
        refreshCurrentView({ isRefreshTree: true })
      }
    })
    .catch(() => {})
}
const handleArchiveOrder = async () => {
  await executeBatchAction({
    getIds: getSelectedIds,
    api: (ids) => archiveOrderApi(ids.join(',')),
    confirmText: '确定订单归档吗？',
    successText: '订单归档成功',
    refreshTree: true,
  })
}
const handleCancelSuspend = async (row?: FactoryOrderNewListData) => {
  let ids: (number | string)[]
  if (row) {
    ids = [row.id]
  } else {
    ids = getSelectedIds()
  }
  await executeBatchAction({
    getIds: () => ids,
    api: (ids) => cancelSuspendApi(ids as number[]),
    confirmText: '确定取消挂起吗?',
    successText: '取消挂起成功',
    refreshTree: true,
  })
}
const handleSyncAddress = async () => {
  await executeBatchAction({
    getIds: getSelectedIds,
    api: (ids) => syncReceiverAddress(ids as number[]),
    confirmText: '确定同步收货地址吗?',
    successText: '同步收货地址成功',
    refreshTree: true,
  })
}
const handleReplenishComplete = () => {
  if (!ensureSelection()) return
  pickCompleteDialogRef.value?.open(getSelectedIds(), undefined, undefined, {
    title: '补胚完成',
    submitType: 'replenish',
  })
}
const handleReplenishFail = () => {
  if (!ensureSelection()) return
  pickFailDialogRef.value?.open(getSelectedIds(), {
    title: '补胚失败',
    submitType: 'replenish',
  })
}
const getOperationByNo = (operationNo: string) =>
  (fastKey.value === 'qualityScan'
    ? getQualityScanByOperationNoApi(operationNo)
    : getByOperationNoLogApi(operationNo)) as Promise<{ data?: unknown }>
const completeOperationById = (
  ids: number[],
  detailData?: Record<string, unknown>,
  trigger: 'manual' | 'auto' = 'manual',
) => {
  if (trigger === 'auto') {
    const detailStatus = String(detailData?.status ?? '')
    return productionScanApi(ids[0], detailStatus, 'web')
  }
  return completeDeliveryApi(ids)
}

const downloadOperationById = (ids: number[]) =>
  downloadOperationMaterialApi(ids)
const printOperationById = (ids: number[]) =>
  printNewPodOrderProductionOrderApi(ids) as Promise<{
    code?: number
    message?: string
  }>
const handleFastProductionSuccess = (data: ResultInfoDataItem[]) => {
  if (fastKey.value === 'productionScan' || fastKey.value === 'qualityScan') {
    ElMessage.success('操作成功')
    return
  }
  const result = data[0]
  if (!result.status) {
    ElMessageBox.alert(
      `操作单号 ${result.factoryOrderNumber} ${result.message}`,
      '提示',
      {
        type: 'error',
      },
    )
    return
  } else {
    ElMessage.success('操作成功')
  }
}
const createLogisticsSuccess = (data: ResultInfoDataItem[]) => {
  const isSuccess = data.every((item) => item.status)
  if (!isSuccess) {
    resultInfo.value = data.filter((item) => !item.status)
    resultRefs.value?.showDialog()
  } else {
    ElMessage.success('操作成功')
    refreshCurrentView()
  }
}
const fastClose = () => {
  detailVisible.value = false
  if (fastKey.value === 'detail') return
  refreshCurrentView({ isRefreshTree: true })
}
const handleViewDetail = async (item: operateOrderListData) => {
  isLimitScan.value = false
  const loading = ElLoading.service({
    fullscreen: true,
    text: '加载中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  try {
    const res = await getFactoryOrderNewOperateDetailApi(item.id)
    if (res.code !== 200) return
    detailData.value = res.data
    fastKey.value = 'detail'
    detailVisible.value = true
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}
const isLimitScan = ref(false)
const handleQuickProduction = (key: string) => {
  fastKey.value = key
  isLimitScan.value = true
  detailData.value = {}
  detailVisible.value = true
}
const handleSinglePrint = () => {
  podDistributionOrderVisible.value = true
}
const handlePrintWarehouseSkuTag = async () => {
  if (!ensureSelection()) return
  const ids = cardSelectList.value.map((item) => item.id).join(',')
  await printWarehouseSkuDialogRef.value?.open(3, ids)
}
const handleGetTrackingNumber = async () => {
  await executeBatchAction({
    getIds: getSelectedIds,
    api: (ids) => getTrackingNumberApi(ids as number[]),
    confirmText: '确定获取跟踪号吗？',
    successText: '获取跟踪号成功',
  })
}
const handleStatusPush = async () => {
  await executeBatchAction({
    getIds: getSelectedIds,
    api: (ids) => statusPushApi(ids as number[]),
    confirmText: '确定推送至ERP吗？',
    successText: '状态推送成功',
  })
}
const logisticsWayList = ref<{ name: string; id: number }[]>([])
const getLogisticsWay = async () => {
  const { data } = await getLogisticsWayApi()
  logisticsWayList.value = data
}

const handleInterceptionSuccess = (row?: FactoryOrderNewListData) => {
  if (row) {
    interceptSuccessRows.value = [row]
  } else {
    if (!ensureSelection()) return
    interceptSuccessRows.value = [...selectedRows.value]
  }
  interceptSuccessForm.value.blockSuccessType = undefined
  interceptSuccessDialogVisible.value = true
  nextTick(() => interceptSuccessFormRef.value?.clearValidate())
}

const submitInterceptSuccess = async () => {
  const form = interceptSuccessFormRef.value
  if (!form) return
  try {
    await form.validate()
  } catch {
    return
  }
  const blockSuccessType = interceptSuccessForm.value.blockSuccessType
  if (blockSuccessType === undefined) return

  const loading = ElLoading.service({
    fullscreen: true,
    text: '操作中...',
    background: 'rgba(0, 0, 0, 0.3)',
  })
  const rows = interceptSuccessRows.value
  const data = rows.map((item: FactoryOrderNewListData) => {
    return {
      factoryOrderNumber: item.factoryOrderNumber as string,
      blockSuccessType,
    }
  }) as { factoryOrderNumber: string; blockSuccessType: number }[]
  try {
    const res = await interceptSuccessApi(data)
    if (res.code !== 200) return
    interceptSuccessDialogVisible.value = false
    const resultData = Array.isArray(res.data)
      ? (res.data as ResultInfoDataItem[])
      : []
    openResultInfoDialog(resultData)
  } catch (e) {
    console.error(e)
  } finally {
    loading.close()
  }
}

const handleInterceptionFail = async (row?: FactoryOrderNewListData) => {
  await executeBatchAction({
    getIds: () =>
      row
        ? [row.factoryOrderNumber as string]
        : selectedRows.value.map(
            (item: FactoryOrderNewListData) =>
              item.factoryOrderNumber as string,
          ),
    api: (ids) => interceptUpdateApi(ids as string[]),
    confirmText: '取消拦截,订单会恢复到拦截前的状态，确认是否拒绝拦截申请?',
    onSuccess: (res) => {
      const data = Array.isArray(res.data)
        ? (res.data as ResultInfoDataItem[])
        : []
      openResultInfoDialog(data)
    },
  })
}
const handleGetOrderInventoryDetail = async () => {
  orderInventoryDetailVisible.value = true
}

const handleQuality = (qualityPassed: boolean) => {
  if (!ensureSelection()) return
  const rows = isCardLayout.value ? cardSelectList.value : selectedRows.value
  qualityFailDialogRef.value?.open(rows, qualityPassed, 0)
}

const isEnableSorting = ref(false)
// 获取功能开关
const getFunctionSwitch = async () => {
  const res = await getConfigApi()
  if (res.code !== 200) return
  isEnableSorting.value = res.data.enable
}
// 物流接口是否展示
const isShowLogisticsButton = computed(() => {
  if (isCardLayout.value) {
    return cardSelectList.value.find((item) => item.shipmentType !== 1)
  } else {
    return selectedRows.value.find((item) => item.shipmentType !== 1)
  }
})

onMounted(() => {
  loadStatusTreeCounts()
  loadAllDictionaries()
  getLogisticsWay()
  getReceiverCountryList()
  loadWarehouseList()
  getFunctionSwitch()
  void treeRef.value
  void tableRef.value
  if (status.value === 'PENDING_RECEIVE') {
    getPendingReceiveCounts()
  } else if (status.value === 'PENDING_QUALITY') {
    void getQualityCounts()
  }
})
</script>

<style scoped lang="scss">
.page {
  display: flex;
}
.main-table-operation {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.order-status-wrapper {
  position: relative;
  flex-shrink: 0;
  width: 180px;
  transition: width 0.3s ease;

  &.is-collapsed {
    width: 0;

    .order-status {
      opacity: 0;
      visibility: hidden;
    }
  }
}

.sidebar-toggle {
  position: absolute;
  top: 50%;
  right: -12px;
  transform: translateY(-50%);
  z-index: 10;
  width: 12px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 1px solid #dcdfe6;
  border-left: none;
  border-radius: 0 4px 4px 0;
  cursor: pointer;
  box-shadow: 1px 0 4px rgba(0, 0, 0, 0.06);
  user-select: none;

  &:hover {
    background: #f5f7fa;

    .sidebar-toggle-icon {
      border-right-color: #409eff;

      &.is-collapsed {
        border-right-color: transparent;
        border-left-color: #409eff;
      }
    }
  }
}

.sidebar-toggle-icon {
  display: block;
  width: 0;
  height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 6px solid #909399;
  transition: border-color 0.2s;

  &.is-collapsed {
    border-right: none;
    border-left: 6px solid #909399;
  }
}

.order-status-wrapper {
  position: relative;
  flex-shrink: 0;
  width: 180px;
  transition: width 0.3s ease;

  &.is-collapsed {
    width: 0;

    .order-status {
      opacity: 0;
      visibility: hidden;
    }
  }
}

.sidebar-toggle {
  position: absolute;
  top: 50%;
  right: -12px;
  transform: translateY(-50%);
  z-index: 10;
  width: 12px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 1px solid #dcdfe6;
  border-left: none;
  border-radius: 0 4px 4px 0;
  cursor: pointer;
  box-shadow: 1px 0 4px rgba(0, 0, 0, 0.06);
  user-select: none;

  &:hover {
    background: #f5f7fa;

    .sidebar-toggle-icon {
      border-right-color: #409eff;

      &.is-collapsed {
        border-right-color: transparent;
        border-left-color: #409eff;
      }
    }
  }
}

.sidebar-toggle-icon {
  display: block;
  width: 0;
  height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 6px solid #909399;
  transition: border-color 0.2s;

  &.is-collapsed {
    border-right: none;
    border-left: 6px solid #909399;
  }
}

.order-status {
  width: 180px;
  height: 100%;
  overflow: auto;
  transition: opacity 0.3s ease;

  :deep(.el-tree-node__content) {
    height: 30px;
    line-height: 30px;
  }

  :deep(.el-tree-node__expand-icon) {
    display: none;
  }

  :deep(.status-tree .el-tree-node.is-current > .el-tree-node__content) {
    background-color: #ecf5ff !important;
    color: #409eff !important;

    .tree-node-label,
    .tree-node-count {
      color: #409eff !important;
    }
    .el-icon {
      color: #409eff !important;
    }
  }
}

.tree-node {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  color: #333;
  font-weight: 500;
  width: 100%;
  justify-content: space-between;
}

.tree-node-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tree-node-count {
  flex-shrink: 0;
}

.tree-node-expand {
  flex-shrink: 0;
  cursor: pointer;
  display: inline-flex;

  &:hover {
    color: #409eff;
  }
}

.status-subtabs {
  display: flex;
  align-items: center;
  gap: 10px;
  border-top: 1px solid #e5e6eb;
  border-bottom: 1px solid #e5e6eb;
  margin-top: 10px;
}

.status-subtab {
  font-size: 14px;
  line-height: 32px;
  padding: 0 12px;
  cursor: pointer;
  user-select: none;
  color: #333;
  position: relative;
  border-bottom: 2px solid transparent;
  box-sizing: border-box;

  &.active {
    background: #ecf5ff;
    color: #409eff;
    border-bottom-color: #409eff;
  }
}

.operation-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.table-content {
  flex: 1;
  margin-top: 10px;
  overflow: hidden;
  :deep(#top) {
    height: 100%;
  }
  :deep(.text-clickable) {
    cursor: pointer;
    &:hover {
      text-decoration: underline;
    }
  }
  :deep(.tracking-number-container) {
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 4px;
  }
  :deep(.tracking-number-text) {
    flex: 1;
    color: #409eff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  :deep(.third-sku-cell) {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    vertical-align: middle;
  }
  :deep(.ellipsis) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.table-pagination-bar {
  margin-top: 10px;
  display: flex;
  align-items: center;
}

.selected-count-text {
  font-size: 14px;
  color: #606266;
  white-space: nowrap;
}

.card-content {
  flex: 1;
  margin-top: 10px;
  overflow: hidden;
}

.header-filter-form {
  width: 100%;
  min-width: 0;
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0;
  min-width: 0;

  :deep(.el-form-item) {
    margin-right: 10px;
    margin-bottom: 10px;
  }

  :deep(.el-form-item__content) {
    min-width: 0;
  }
}

.tabs-wrapper {
  height: 100%;

  :deep(.el-tabs__content) {
    height: calc(100% - 40px);
  }

  :deep(.el-tab-pane) {
    height: 100%;
    display: flex;
    flex-direction: column;
  }
}

.sub-table-wrapper,
.log-table-wrapper {
  flex: 1;
  overflow: hidden;
}
.detail-table-content {
  height: 100%;
  overflow: hidden;
}
</style>
<style lang="scss">
.customize-select-style {
  .el-select-dropdown__list {
    width: 500px;
    display: flex;
    flex-wrap: wrap;
  }
}
</style>
