<template>
  <view class="admin-page">
    <view class="admin-sections" @click="closeDropdowns">
      <!-- 筛选区域 -->
      <view class="admin-card filter-card">
        <view class="filter-row">
          <view class="filter-item">
            <text class="label">订单类型：</text>
            <view class="mock-select">
              <text>全部订单</text>
              <view class="arrow-down"></view>
            </view>
          </view>
          <view class="filter-item">
            <text class="label">支付方式：</text>
            <view class="mock-select">
              <text>全部</text>
              <view class="arrow-down"></view>
            </view>
          </view>
          <view class="filter-item long">
            <text class="label">创建时间：</text>
            <view class="mock-date-range">
              <image class="cal-icon" src="/static/icons/calendar.png" mode="aspectFit" />
              <text class="placeholder">开始日期  -  结束日期</text>
            </view>
          </view>
          <view class="filter-item search">
            <text class="label">订单搜索：</text>
            <view class="search-group">
              <view class="search-select">
                <text>全部</text>
                <view class="arrow-down"></view>
              </view>
              <input class="search-input" v-model="searchKeyword" placeholder="请输入订单号/手机号" />
            </view>
          </view>
        </view>
        <view class="btn-row">
          <button class="btn btn-primary" @click="fetchData">查询</button>
          <button class="btn btn-default" @click="resetQuery">重置</button>
        </view>
      </view>

      <!-- 列表数据区域 -->
      <view class="admin-card content-card">
        <!-- 状态 Tabs -->
        <view class="status-tabs">
          <view 
            v-for="(tab, index) in statusTabs" 
            :key="index"
            class="tab-item"
            :class="{ active: activeTab === index }"
            @click="handleTabClick(index)"
          >
            <text class="tab-text">{{ tab.name }}</text>
            <text v-if="tab.count !== null" class="tab-count">({{ tab.count }})</text>
          </view>
        </view>

        <!-- 操作按钮 -->
        <view class="action-bar">
          <button class="action-btn btn-blue">订单核销</button>
          <button class="action-btn btn-outline">批量发货</button>
          <button class="action-btn btn-outline">批量删除</button>
          <button class="action-btn btn-outline">订单导出</button>
        </view>

        <!-- 数据表格 -->
        <view class="order-table">
          <view class="thead">
            <view class="th col-expand"></view>
            <view class="th col-check">
              <checkbox :checked="false" color="#1890ff" />
            </view>
            <view class="th col-order">订单号 | 类型</view>
            <view class="th col-product">商品信息</view>
            <view class="th col-user">用户信息</view>
            <view class="th col-price">实际支付</view>
            <view class="th col-pay">支付状态</view>
            <view class="th col-time">支付时间</view>
            <view class="th col-status">订单状态</view>
            <view class="th col-op">操作</view>
          </view>
          
          <view class="tbody">
            <!-- Loading 状态 -->
            <view v-if="loading" class="loading-state">
              <text>加载中...</text>
            </view>

            <!-- 错误状态 -->
            <view v-else-if="fetchError != ''" class="error-state">
              <text class="error-text">{{ fetchError }}</text>
              <button class="retry-btn" @click="fetchData">重新加载</button>
            </view>

            <!-- 无数据状态 -->
            <view v-else-if="filteredOrders.length === 0" class="empty-state">
              <text>暂无订单数据</text>
            </view>

            <view v-for="(item, index) in filteredOrders" :key="index" class="tr">
              <view class="td col-expand">
                <text class="expand-arrow">›</text>
              </view>
              <view class="td col-check">
                <checkbox :checked="false" color="#1890ff" />
              </view>
              <!-- 订单号|类型 -->
              <view class="td col-order">
                <text class="order-sn">{{ item['sn'] }}</text>
                <text class="order-type" :class="item['typeColor']">[{{ item['typeName'] }}]</text>
                <text class="order-time">{{ item['created_at'] }}</text>
                <text v-if="item['cancelStatus'] != ''" class="cancel-text">{{ item['cancelStatus'] }}</text>
              </view>
              <!-- 商品信息 -->
              <view class="td col-product">
                <view class="product-info-list" v-if="item['items'] != null">
                   <view v-for="(prod, pidx) in (item['items'] as UTSJSONObject[])" :key="pidx" class="product-info-wrap">
                    <image class="p-img" :src="prod['image'] != null ? (prod['image'] as string) : '/static/logo.png'" mode="aspectFill" />
                    <text class="p-name">{{ prod['name'] }}</text>
                  </view>
                </view>
                <view v-else class="product-info-wrap">
                  <image class="p-img" :src="item['product']['img']" mode="aspectFill" />
                  <text class="p-name">{{ item['product']['name'] }}</text>
                </view>
              </view>
              <!-- 用户信息 -->
              <view class="td col-user">
                <text class="u-info">{{ item['user']['name'] }} | {{ item['user']['id'] || '--' }}</text>
              </view>
              <!-- 实际支付 -->
              <view class="td col-price">
                <text class="price-val">{{ item['isPaid'] === true ? '¥' + item['actualPrice'] : '未支付' }}</text>
              </view>
              <!-- 支付方式 -->
              <view class="td col-pay">
                <text class="pay-text">{{ item['payMethod'] }}</text>
              </view>
              <!-- 支付时间 -->
              <view class="td col-time">
                <text class="time-text">{{ item['payTime'] }}</text>
              </view>
              <!-- 订单状态 -->
              <view class="td col-status">
                <text class="status-text" :style="{ color: item['statusColor'] }">{{ item['statusName'] }}</text>
              </view>
              <!-- 操作 -->
              <view class="td col-op overflow-visible no-wrap">
                <view class="op-links">
                  <text class="op-link primary" @click.stop="viewDetail(item)">详情</text>
                  <template v-if="(item['orderStatus'] as number) === 2">
                    <view class="divider-v"></view>
                    <text class="op-link primary" @click.stop="shipOrder(item)">发货</text>
                  </template>
                  <view class="divider-v"></view>
                  <view class="op-dropdown-container" @mouseenter="activeDropdownId = (item['sn'] as string)" @mouseleave="activeDropdownId = ''">
                    <view class="op-link-more">
                      <text class="more-text">更多</text>
                      <view :class="{ 'arrow-up-blue': activeDropdownId === item['sn'], 'arrow-down-blue': activeDropdownId !== item['sn'] }"></view>
                    </view>
                    <!-- 浮动菜单 -->
                    <view v-if="activeDropdownId === (item['sn'] as string)" class="dropdown-menu">
                      <view class="dropdown-item" @click.stop="handleMore('print_receipt', item)">
                        <text class="item-text">小票打印</text>
                      </view>
                      <view class="dropdown-item" @click.stop="handleMore('edit_address', item)">
                        <text class="item-text">修改地址</text>
                      </view>
                      <view class="dropdown-item" @click.stop="handleMore('remark', item)">
                        <text class="item-text">订单备注</text>
                      </view>
                      <view class="dropdown-item" @click.stop="handleMore('refund', item)">
                        <text class="item-text">立即退款</text>
                      </view>
                      <view class="dropdown-item item-danger" @click.stop="deleteOrder(item)">
                        <text class="item-text text-red">删除订单</text>
                      </view>
                      <view class="dropdown-item" @click.stop="handleMore('packing_slip', item)">
                        <text class="item-text">配货单打印</text>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>

        <!-- 分页 -->
        <CommonPagination
          v-if="filteredOrders.length > 0 || loading"
          :total="filteredOrders.length"
          :loading="loading"
          :currentPage="currentPage"
          :pageSize="pageSize"
          :pageSizeOptionLabels="pageSizeOptionLabels"
          :pageSizeIndex="pageSizeIndex"
          :visiblePages="visiblePages"
          :totalPage="totalPage"
          :jumpPageInput="jumpPageInput"
          @page-size-change="handlePageSizeChange"
          @page-change="handlePageChange"
          @update:jumpPageInput="(val : string) => { jumpPageInput = val }"
          @jump-page="handleJumpPage"
        />
      </view>
    </view>

    <!-- 抽屉详情 -->
    <OrderDetailDrawer 
      v-model:visible="showDetail" 
      :order-info="selectedOrder" 
    />
  </view>
</template>

<script setup lang="uts">
import { ref, computed, onMounted } from 'vue'
import { supabase } from '@/components/supadb/aksupainstance.uts'
import OrderDetailDrawer from './components/OrderDetailDrawer.uvue'
import CommonPagination from '@/components/CommonPagination/CommonPagination.uvue'

const activeTab = ref(0)
const loading = ref(false)
const searchKeyword = ref('')

// 分页状态适配层
const currentPage = ref(1)
const pageSize = ref(10)
let jumpPageInput = ''
const pageSizeOptions = [10, 20, 30, 50, 100]
const pageSizeOptionLabels = computed((): string[] => pageSizeOptions.map((s: number): string => `${s} 条/页`))
const pageSizeIndex = computed((): number => {
  const i = pageSizeOptions.indexOf(pageSize.value)
  return i === -1 ? 0 : i
})
const totalPage = computed((): number => Math.ceil(filteredOrders.value.length / pageSize.value))
const visiblePages = computed((): number[] => {
  const cur = currentPage.value
  const tot = totalPage.value
  if (tot <= 7) {
    const pages: number[] = []
    for (let i = 1; i <= tot; i++) pages.push(i)
    return pages
  }
  if (cur <= 4) return [1, 2, 3, 4, 5, -1, tot]
  if (cur >= tot - 3) return [1, -1, tot - 4, tot - 3, tot - 2, tot - 1, tot]
  return [1, -1, cur - 1, cur, cur + 1, -1, tot]
})
const handlePageChange = (p: number) => {
  if (loading.value || p < 1 || p > totalPage.value || p === currentPage.value) return
  currentPage.value = p
  jumpPageInput = ''
}
const handlePageSizeChange = (e: any) => {
  if (loading.value) return
  let val = 0
  if (typeof e.detail.value === 'string') val = parseInt(e.detail.value)
  else val = e.detail.value as number
  pageSize.value = pageSizeOptions[val]
  currentPage.value = 1
}
const handleJumpPage = () => {
  if (loading.value) return
  let jumpTo = parseInt(jumpPageInput)
  if (isNaN(jumpTo)) return
  if (jumpTo < 1) jumpTo = 1
  if (jumpTo > totalPage.value) jumpTo = totalPage.value
  jumpPageInput = String(jumpTo)
  if (jumpTo !== currentPage.value) currentPage.value = jumpTo
}

// Dropdown 状态
const activeDropdownId = ref('')
const showDetail = ref(false)
const selectedOrder = ref<UTSJSONObject>({} as UTSJSONObject)
const fetchError = ref('')

// 时间显示格式化
const formatTime = (timeStr : string | null) : string => {
  if (timeStr == null || timeStr == '' || timeStr == '--') return '--'
  if (timeStr.indexOf('T') > -1) {
    const parts = timeStr.split('T')
    const date = parts[0]
    const timeFull = parts[1]
    const time = timeFull.split('.')[0]
    return date + ' ' + time
  }
  return timeStr
}

const statusTabs = [
  { name: '全部', count: null, status: 0 },
  { name: '待支付', count: null, status: 1 },
  { name: '待发货', count: null, status: 2 },
  { name: '待收货', count: null, status: 3 },
  { name: '已完成', count: null, status: 4 },
  { name: '已取消', count: null, status: 5 },
  { name: '退款中', count: null, status: 6 },
  { name: '已退款', count: null, status: 7 }
]

const orderData = ref<UTSJSONObject[]>([])

// 订单状态颜色映射
const getStatusColor = (status : number) : string => {
  if (status === 1) return '#faad14'
  if (status === 2) return '#1890ff'
  if (status === 3) return '#1890ff'
  if (status === 4) return '#52c41a'
  if (status === 5) return '#999999'
  if (status === 6) return '#fa8c16'
  if (status === 7) return '#f5222d'
  return '#333333'
}

const filteredOrders = computed<UTSJSONObject[]>(() => {
  let list = orderData.value
  
  // Tab 过滤
  if (activeTab.value > 0) {
    const targetStatus = statusTabs[activeTab.value].status
    list = list.filter((o : UTSJSONObject) : boolean => (o['orderStatus'] as number) === targetStatus)
  }
  
  // 搜索过滤
  if (searchKeyword.value.trim() !== '') {
    const kw = searchKeyword.value.toLowerCase()
    list = list.filter((o : UTSJSONObject) : boolean => {
      const sn = o['sn'] != null ? (o['sn'] as string).toLowerCase() : ''
      const user = o['user'] as UTSJSONObject
      const phone = (user != null && user['phone'] != null) ? (user['phone'] as string) : ''
      return sn.includes(kw) || phone.includes(kw)
    })
  }
  
  return list
})

const fetchData = async () => {
  loading.value = true
  fetchError.value = ''

  // 获取当前商家 ID（merchant_id = ak_users.id = Supabase Auth UUID）
  const currentMerchantId = supabase.getSession().user?.getString('id')
  if (currentMerchantId == null || currentMerchantId == '') {
    loading.value = false
    fetchError.value = '未获取到商家身份信息，请重新登录后再试'
    return
  }

  try {
    const res = await supabase
      .from('ml_orders_detail_view')
      .select('*')
      .eq('merchant_id', currentMerchantId)
      .order('created_at', { ascending: false })
      .execute()

    if (res.error == null && res.data != null) {
      const rawData = res.data as UTSJSONObject[]
      orderData.value = rawData.map((item: UTSJSONObject) : UTSJSONObject => {
        // 解析 shipping_address JSONB（含 receiver_name/receiver_phone/province/city/district/address_detail）
        const rawAddr = item['shipping_address']
        let receiverName = item['customer_name'] != null ? (item['customer_name'] as string) : ''
        let receiverPhone = item['customer_phone'] != null ? (item['customer_phone'] as string) : ''
        let fullAddress = '暂无地址信息'
        if (rawAddr != null) {
          const addr = rawAddr as UTSJSONObject
          const rn = addr['receiver_name']
          const rp = addr['receiver_phone']
          if (rn != null && rn !== '') receiverName = rn as string
          if (rp != null && rp !== '') receiverPhone = rp as string
          const prov = addr['province'] != null ? (addr['province'] as string) : ''
          const cit = addr['city'] != null ? (addr['city'] as string) : ''
          const dist = addr['district'] != null ? (addr['district'] as string) : ''
          const det = addr['address_detail'] != null ? (addr['address_detail'] as string) : ''
          const combined = prov + cit + dist + det
          if (combined !== '') fullAddress = combined
        }

        const orderStatusNum = item['order_status'] as number

        // cancelStatus：取消原因展示
        let cancelStatus = ''
        if (orderStatusNum === 5) {
          const reason = item['cancel_reason']
          cancelStatus = (reason != null && reason !== '') ? ('已取消：' + (reason as string)) : '用户已取消'
        }

        return {
          id: item['id'] != null ? (item['id'] as string) : '',
          sn: item['order_no'] != null ? item['order_no'] : '--',
          typeName: '普通订单',
          typeColor: 'green',
          orderStatus: orderStatusNum,
          cancelStatus: cancelStatus,
          product: {
            img: '/static/logo.png',
            name: '订单详情查看'
          } as UTSJSONObject,
          items: null, // ml_orders_detail_view 视图未聚合 order_items，详情抽屉另行处理
          user: {
            name: (item['customer_name'] || '未知用户') as string,
            id: (item['user_id'] || '--') as string,
            phone: receiverPhone != '' ? receiverPhone : (item['customer_phone'] != null ? (item['customer_phone'] as string) : '--')
          } as UTSJSONObject,
          isPaid: item['payment_status'] === 2,
          actualPrice: item['paid_amount'] != null ? item['paid_amount'] : 0,  // 已付金额（修正：原为 total_amount）
          paidAmount: item['paid_amount'] != null ? item['paid_amount'] : 0,
          payMethod: item['payment_status_name'] != null ? (item['payment_status_name'] as string) : '--',  // 支付状态（ml_orders 表无支付方式字段）
          payTime: formatTime(item['paid_at'] as string | null),
          created_at: formatTime(item['created_at'] as string | null),
          statusName: item['order_status_name'] != null ? (item['order_status_name'] as string) : '未知',
          statusColor: getStatusColor(orderStatusNum),
          primaryAction: orderStatusNum === 1 ? '立即支付' : '',
          total_num: 0,
          total_price: item['product_amount'] != null ? item['product_amount'] : 0,
          coupon_price: item['discount_amount'] != null ? item['discount_amount'] : 0,
          shipping_fee: item['shipping_fee'] != null ? item['shipping_fee'] : 0,
          deduction_price: 0,
          user_address: fullAddress,
          real_name: receiverName,
          user_phone: receiverPhone,
          delivery_name: item['merchant_name'] != null ? (item['merchant_name'] as string) : '--',
          store_name: item['shop_name'] != null ? (item['shop_name'] as string) : '--',
          mark: item['remark'] != null ? (item['remark'] as string) : '-',
          remark: item['merchant_memo'] != null ? (item['merchant_memo'] as string) : '-',
          shipped_at: item['shipped_at'] != null ? (item['shipped_at'] as string) : '',
          delivered_at: item['delivered_at'] != null ? (item['delivered_at'] as string) : '',
          completed_at: item['completed_at'] != null ? (item['completed_at'] as string) : ''
        } as UTSJSONObject
      })

      // 更新统计数据
      updateTabCounts()
    } else {
      fetchError.value = '加载订单失败，请检查网络后重试'
      console.error('Fetch orders error:', res.error)
    }
  } catch (e) {
    fetchError.value = '加载订单时发生异常，请检查网络后重试'
    console.error('Fetch orders exception:', e)
  } finally {
    loading.value = false
  }
}

const updateTabCounts = () => {
  statusTabs.forEach((tab, index) => {
    if (index === 0) {
      tab.count = orderData.value.length
    } else {
      tab.count = orderData.value.filter((o : UTSJSONObject) : boolean => (o['orderStatus'] as number) === tab.status).length
    }
  })
}

const handleTabClick = (index: number) => {
  activeTab.value = index
}

const resetQuery = () => {
  searchKeyword.value = ''
  activeTab.value = 0
  fetchData()
}

// 更多菜单控制
const toggleDropdown = (id: string) => {
  if (activeDropdownId.value === id) {
    activeDropdownId.value = ''
  } else {
    activeDropdownId.value = id
  }
}

// 关闭下拉
const closeDropdowns = () => {
  activeDropdownId.value = ''
}

// 查看详情
const viewDetail = (order: UTSJSONObject) => {
  selectedOrder.value = order
  showDetail.value = true
  closeDropdowns()
}

// 发货操作
const shipOrder = async (order: UTSJSONObject) => {
  uni.showModal({
    title: '确认发货',
    content: `确定将订单 ${order['sn']} 标记为已发货？`,
    success: async (res) => {
      if (res.confirm) {
        try {
          const result = await supabase
            .from('ml_orders')
            .update({ order_status: 3, shipping_status: 2, shipped_at: new Date().toISOString() } as UTSJSONObject)
            .eq('order_no', order['sn'] as string)
            .execute()
          if (result.error == null) {
            uni.showToast({ title: '发货成功' })
            fetchData()
          } else {
            uni.showToast({ title: '操作失败', icon: 'none' })
          }
        } catch (e) {
          console.error('shipOrder error:', e)
        }
      }
    }
  })
}

// 更多菜单操作（功能待接入）
const handleMore = (_action: string, _order: UTSJSONObject) => {
  closeDropdowns()
  uni.showToast({ title: '功能开发中', icon: 'none' })
}

// 删除订单 (权限占位代码)
const deleteOrder = async (order: UTSJSONObject) => {
  closeDropdowns()
  // 模拟权限验证: admin-order-storeOrder-index
  const hasAuth = true // 实际项目中应通过 store 读取权限
  if (!hasAuth) {
    uni.showToast({ title: '无权限操作', icon: 'none' })
    return
  }

  uni.showModal({
    title: '确认删除',
    content: `确定要删除订单 ${order['sn']} 吗？删除后不可恢复。`,
    success: async (res) => {
      if (res.confirm) {
        try {
          const { error } = await supabase
            .from('ml_orders')
            .delete()
            .eq('order_no', order['sn'])
            .execute()
          
          if (!error) {
            uni.showToast({ title: '删除成功' })
            fetchData()
          } else {
            uni.showToast({ title: '删除失败: ' + error.message, icon: 'none' })
          }
        } catch (e) {
          console.error(e)
        }
      }
    }
  })
}

onMounted(() => {
  fetchData()
  // 点击空白处关闭下拉
  // uni.onWindowClick(() => closeDropdowns()) 
  // UVUE 不支持 window click，可用 view 遮罩或在主容器加点击
})
</script>

<style scoped lang="scss">
.admin-page {
  /* 基础背景由 Layout 提供 */
  min-height: calc(100vh - 120px);
  padding: 16px;
}

.admin-card {
  background-color: #ffffff;
  border-radius: 4px;
  margin-bottom: 16px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
  overflow: visible !important; /* 关键：确保内部内容不被裁切 */
}

.content-card {
  overflow: visible !important;
}

.filter-card {
  padding: 24px;
}

.filter-row {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 24px;
}

.filter-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  
  .label {
    font-size: 14px;
    color: #333;
    width: 80px;
    flex-shrink: 0;
  }
}

.mock-select {
  width: 160px;
  height: 32px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 0 12px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  text { font-size: 14px; color: #595959; }
}

.mock-date-range {
  width: 240px;
  height: 32px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 0 12px;
  display: flex;
  flex-direction: row;
  align-items: center;
  .cal-icon { width: 14px; height: 14px; margin-right: 8px; opacity: 0.4; }
  .placeholder { font-size: 14px; color: #bfbfbf; }
}

.search-group {
  display: flex;
  flex-direction: row;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  height: 32px;
  overflow: hidden;
}

.search-select {
  width: 80px;
  border-right: 1px solid #d9d9d9;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background-color: #fafafa;
  text { font-size: 14px; color: #595959; }
}

.search-input {
  flex: 1;
  border: none;
  padding: 0 12px;
  font-size: 14px;
  width: 180px;
}

.arrow-down {
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid #bfbfbf;
}

.btn-row {
  margin-top: 16px;
  display: flex;
  flex-direction: row;
  gap: 8px;
}

.btn {
  height: 32px;
  padding: 0 16px;
  font-size: 14px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
}

.btn-primary { background-color: #1890ff; color: #fff; border: none; }
.btn-default { background-color: #fff; color: #595959; border: 1px solid #d9d9d9; }

.status-tabs {
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid #f0f0f0;
  padding: 0 16px;
}

.tab-item {
  padding: 16px 20px;
  cursor: pointer;
  position: relative;
  display: flex;
  flex-direction: row;
  gap: 2px;
  
  .tab-text { font-size: 14px; color: #595959; }
  .tab-count { font-size: 14px; color: #595959; }
  
  &.active {
    .tab-text, .tab-count { color: #1890ff; font-weight: 500; }
    &::after {
      content: '';
      position: absolute; bottom: 0; left: 0; right: 0; height: 2px; background: #1890ff;
    }
  }
}

.action-bar {
  padding: 16px 20px;
  display: flex;
  flex-direction: row;
  gap: 12px;
}

.action-btn {
  height: 32px;
  padding: 0 16px;
  font-size: 14px;
  border-radius: 4px;
  margin: 0;
  display: flex;
  align-items: center;
}

.btn-blue { background-color: #1890ff; color: #fff; border: none; }
.btn-outline { background-color: #fff; color: #595959; border: 1px solid #d9d9d9; }

/* 表格样式 */
.order-table {
  width: 100%;
  overflow-x: auto;
  overflow-y: visible !important; /* 关键：确保垂直方向不被裁切 */
  position: relative;
}

.thead {
  display: flex;
  flex-direction: row;
  background-color: #f0f7ff;
  min-width: 1300px;
  position: relative;
  z-index: 10;
}

.th {
  padding: 12px 8px;
  font-size: 14px;
  color: #595959;
  font-weight: 500;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start; /* 左对齐内容 */
}

.tbody {
  overflow: visible !important;
}

.tr {
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid #f0f0f0;
  min-width: 1300px;
  position: relative; /* 定位参考 */
  z-index: 10;
  overflow: visible !important; /* 关键：确保子菜单可溢出 */
  &:hover { background-color: #fafafa; z-index: 100; } 
}

.td {
  padding: 16px 8px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start; /* 左对齐内容 */
}

.no-wrap {
  flex-direction: row !important;
  flex-wrap: nowrap;
  align-items: center;
}

.overflow-visible {
  overflow: visible !important;
}

/* 更多下拉菜单 */
.op-dropdown-container {
  position: relative;
  display: inline-block;
  cursor: pointer;
}

.dropdown-menu {
  position: absolute;
  top: 100%;
  right: 0;
  width: 100px;
  background-color: #ffffff;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  margin-top: 5px;
  z-index: 99999; /* 极大层级 */
  border: 1px solid #f0f0f0;
  pointer-events: auto;
  display: block; /* 显式设置为 block */
}

.dropdown-item {
  height: 36px;
  padding: 0 12px;
  display: flex;
  flex-direction: row;
  align-items: center;
  transition: background-color 0.2s;
  cursor: pointer;
  
  .item-text { font-size: 13px; color: #595959; }

  &:hover {
    background-color: #f5f5f5;
  }
}

.text-red { color: #ff4d4f !important; }

.loading-state, .empty-state {
  padding: 40px;
  text-align: center;
  color: #999;
  font-size: 14px;
}

/* 列宽控制 */
.col-expand { width: 40px; justify-content: center; align-items: center; }
.expand-arrow { color: #bfbfbf; font-size: 18px; }

.col-check { width: 50px; justify-content: center; align-items: center; }
.col-order { width: 220px; }
.col-product { flex: 1; min-width: 300px; }
.col-user { width: 180px; }
.col-price { width: 100px; }
.col-pay { width: 100px; }
.col-time { width: 160px; }
.col-status { width: 100px; }
.col-op { width: 160px; }

.order-sn { font-size: 13px; color: #262626; margin-bottom: 4px; text-align: left; }
.order-type { font-size: 12px; text-align: left; }

.product-info-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.product-info-wrap {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 12px; /* 间距拉开一点 */
  text-align: left;
}

.p-img { width: 44px; height: 44px; border-radius: 4px; background-color: #f5f5f5; flex-shrink: 0; }
.p-name { font-size: 13px; color: #595959; line-height: 1.5; }

.u-info { font-size: 13px; color: #595959; }
.price-val { font-size: 14px; color: #262626; }
.pay-text, .time-text, .status-text { font-size: 13px; color: #595959; }

.op-links {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.op-link { font-size: 13px; cursor: pointer; }
.primary { color: #1890ff; padding-right: 8px; }

.divider-v {
  width: 1px;
  height: 12px;
  background-color: #dcdfe6;
  margin: 0 8px;
}

.op-dropdown-container {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  cursor: pointer;
  padding-left: 0px;
}

.op-link-more {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 4px;
}
.more-text { font-size: 13px; color: #1890ff; }

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 110px;
  background-color: #ffffff;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  margin-top: 8px;
  z-index: 100000;
  border: 1px solid #ebeef5;
  display: flex;
  flex-direction: column;
}

.dropdown-item {
  height: 32px;
  padding: 0 16px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
  cursor: pointer;
  
  .item-text { font-size: 13px; color: #606266; text-align: center; }

  &:hover {
    background-color: #f5f7fa;
    .item-text { color: #1890ff; }
  }
}

.item-danger:hover {
  .item-text { color: #ff4d4f !important; }
}

.text-red { color: #ff4d4f !important; }

/* 箭头 */
.arrow-down-blue {
  width: 0; height: 0;
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 4px solid #1890ff;
  margin-top: 1px;
}

.arrow-up-blue {
  width: 0; height: 0;
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-bottom: 4px solid #1890ff;
  margin-bottom: 3px;
}
.order-time {
  font-size: 12px;
  color: #999;
  margin-top: 2px;
  display: block;
}

.price-unpaid {
  color: #f5222d;
}

.error-state {
  padding: 40px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.error-text {
  font-size: 14px;
  color: #f5222d;
}

.retry-btn {
  height: 32px;
  padding: 0 16px;
  font-size: 14px;
  border-radius: 4px;
  background-color: #fff;
  color: #1890ff;
  border: 1px solid #1890ff;
  margin: 0;
}
</style>

