Files
anxinyan/admin-web/src/pages/orders/index.vue
wushumin 9aac78b8da first
2026-05-11 15:28:27 +08:00

815 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { adminApi, type AdminOrderDetail, type AdminOrderListItem, type AdminOrderWarehouseOption } from "../../api/admin";
import OrderStatusTag from "../../components/OrderStatusTag.vue";
const loading = ref(false);
const detailLoading = ref(false);
const drawerVisible = ref(false);
const receiveSubmitting = ref(false);
const returnReceiveSubmitting = ref(false);
const warehouseSubmitting = ref(false);
const warehouseDialogVisible = ref(false);
const warehouseOptionsLoading = ref(false);
const warehouseOptions = ref<AdminOrderWarehouseOption[]>([]);
const selectedWarehouseId = ref(0);
const returnDialogVisible = ref(false);
const returnSubmitting = ref(false);
const returnExpressCompany = ref("");
const returnTrackingNo = ref("");
const keyword = ref("");
const serviceProvider = ref("");
const status = ref("");
const sourceChannel = ref("");
const orders = ref<AdminOrderListItem[]>([]);
const detail = ref<AdminOrderDetail | null>(null);
const providerOptions = [
{ label: "全部服务", value: "" },
{ label: "实物鉴定", value: "anxinyan" },
{ label: "中检鉴定", value: "zhongjian" },
];
const statusOptions = [
{ label: "全部状态", value: "" },
{ label: "待补资料", value: "pending_supplement" },
{ label: "待寄送", value: "pending_shipping" },
{ label: "鉴定中", value: "in_first_review" },
{ label: "待寄回", value: "report_published" },
{ label: "回寄途中", value: "returning" },
{ label: "已完成签收", value: "completed_signed" },
];
const sourceChannelOptions = [
{ label: "全部渠道", value: "" },
{ label: "小程序", value: "mini_program" },
{ label: "H5", value: "h5" },
{ label: "大客户推送订单", value: "enterprise_push" },
];
const usageStatusMap: Record<string, string> = {
new: "全新未使用",
light_use: "轻微使用痕迹",
used: "长期使用",
};
const usageStatusText = computed(() => {
const value = detail.value?.extra_info.usage_status || "";
return value ? usageStatusMap[value] || value : "-";
});
const productTitle = computed(() => {
if (!detail.value) {
return "待完善物品信息";
}
return detail.value.product_info.product_name || "待完善物品信息";
});
const productMetaText = computed(() => {
if (!detail.value) {
return "物品信息待完善";
}
const parts = [
detail.value.product_info.category_name,
detail.value.product_info.brand_name,
].filter(Boolean);
return parts.length ? parts.join(" / ") : "物品信息待完善";
});
const canMarkReceived = computed(() => {
if (!detail.value) {
return false;
}
if (detail.value.order_info.can_mark_received) {
return true;
}
return (
detail.value.order_info.order_status === "pending_shipping" &&
Boolean(detail.value.logistics_info?.tracking_no) &&
detail.value.logistics_info?.tracking_status !== "received"
);
});
const logisticsActionText = computed(() => {
if (!detail.value?.logistics_info) {
return "";
}
return canMarkReceived.value ? "用户已提交/寄出,待鉴定中心签收" : detail.value.logistics_info.tracking_status_text;
});
const canSubmitReturnLogistics = computed(() => Boolean(detail.value?.order_info.can_submit_return_logistics));
const returnLogisticsBlockReason = computed(() => detail.value?.order_info.return_logistics_block_reason || "");
const canMarkReturnReceived = computed(() => Boolean(detail.value?.order_info.can_mark_return_received));
async function fetchOrders() {
loading.value = true;
try {
const response = await adminApi.getOrders({
keyword: keyword.value,
service_provider: serviceProvider.value,
status: status.value,
source_channel: sourceChannel.value,
});
orders.value = response.data.list;
} catch (error) {
console.error(error);
ElMessage.error("订单列表加载失败");
} finally {
loading.value = false;
}
}
async function openDetail(row: AdminOrderListItem) {
detailLoading.value = true;
drawerVisible.value = true;
try {
const response = await adminApi.getOrderDetail(row.id);
detail.value = response.data;
} catch (error) {
console.error(error);
ElMessage.error("订单详情加载失败");
} finally {
detailLoading.value = false;
}
}
async function reloadDetail() {
if (!detail.value) return;
detailLoading.value = true;
try {
const response = await adminApi.getOrderDetail(detail.value.order_info.id);
detail.value = response.data;
} catch (error) {
console.error(error);
ElMessage.error("订单详情刷新失败");
} finally {
detailLoading.value = false;
}
}
async function markReceived() {
if (!detail.value) return;
receiveSubmitting.value = true;
try {
const response = await adminApi.receiveOrderLogistics(detail.value.order_info.id);
ElMessage.success(response.message || "已标记签收");
await reloadDetail();
await fetchOrders();
} catch (error) {
console.error(error);
ElMessage.error("标记签收失败");
} finally {
receiveSubmitting.value = false;
}
}
async function openWarehouseDialog() {
if (!detail.value) return;
warehouseOptionsLoading.value = true;
warehouseDialogVisible.value = true;
selectedWarehouseId.value = detail.value.shipping_target?.warehouse_id || 0;
try {
const response = await adminApi.getOrderWarehouseOptions(detail.value.order_info.id);
warehouseOptions.value = response.data.list;
} catch (error) {
console.error(error);
ElMessage.error("仓库列表加载失败");
} finally {
warehouseOptionsLoading.value = false;
}
}
async function submitWarehouseReassign() {
if (!detail.value || !selectedWarehouseId.value) {
ElMessage.warning("请先选择一个目标仓库");
return;
}
try {
await ElMessageBox.confirm("改派后,用户寄送页将展示新的收货仓库地址。确定继续吗?", "改派仓库", {
type: "warning",
confirmButtonText: "确认改派",
cancelButtonText: "取消",
});
} catch {
return;
}
warehouseSubmitting.value = true;
try {
const response = await adminApi.reassignOrderWarehouse(detail.value.order_info.id, selectedWarehouseId.value);
ElMessage.success(response.message || "仓库已改派");
warehouseDialogVisible.value = false;
await reloadDetail();
} catch (error) {
console.error(error);
ElMessage.error("仓库改派失败");
} finally {
warehouseSubmitting.value = false;
}
}
function openReturnDialog() {
if (!detail.value) return;
if (!canSubmitReturnLogistics.value) {
ElMessage.warning(returnLogisticsBlockReason.value || "当前订单暂不支持登记回寄运单");
return;
}
returnExpressCompany.value = detail.value.return_logistics?.express_company || "";
returnTrackingNo.value = detail.value.return_logistics?.tracking_no || "";
returnDialogVisible.value = true;
}
async function submitReturnLogistics() {
if (!canSubmitReturnLogistics.value) {
ElMessage.warning(returnLogisticsBlockReason.value || "当前订单暂不支持登记回寄运单");
return;
}
if (!detail.value || !returnExpressCompany.value.trim() || !returnTrackingNo.value.trim()) {
ElMessage.warning("请完整填写回寄快递公司和运单号");
return;
}
returnSubmitting.value = true;
try {
const response = await adminApi.saveOrderReturnLogistics({
id: detail.value.order_info.id,
express_company: returnExpressCompany.value.trim(),
tracking_no: returnTrackingNo.value.trim(),
});
ElMessage.success(response.message || "回寄运单已登记");
returnDialogVisible.value = false;
await reloadDetail();
await fetchOrders();
} catch (error) {
console.error(error);
ElMessage.error(error instanceof Error ? error.message : "回寄运单登记失败");
} finally {
returnSubmitting.value = false;
}
}
async function markReturnReceived() {
if (!detail.value) return;
returnReceiveSubmitting.value = true;
try {
const response = await adminApi.receiveOrderReturnLogistics(detail.value.order_info.id);
ElMessage.success(response.message || "已标记用户签收");
await reloadDetail();
await fetchOrders();
} catch (error) {
console.error(error);
ElMessage.error("标记用户签收失败");
} finally {
returnReceiveSubmitting.value = false;
}
}
onMounted(fetchOrders);
</script>
<template>
<el-card class="panel-card" shadow="never">
<div class="filters-row">
<el-input v-model="keyword" placeholder="搜索订单号 / 鉴定单号 / 商品名称" clearable style="width: 320px" />
<el-select v-model="serviceProvider" placeholder="服务类型" style="width: 160px">
<el-option v-for="item in providerOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="status" placeholder="订单状态" style="width: 160px">
<el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="sourceChannel" placeholder="下单渠道" style="width: 170px">
<el-option v-for="item in sourceChannelOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-button type="primary" @click="fetchOrders">查询</el-button>
</div>
</el-card>
<el-card class="panel-card orders-table" shadow="never">
<el-table v-loading="loading" :data="orders" stripe>
<el-table-column prop="order_no" label="订单号" min-width="170" />
<el-table-column prop="appraisal_no" label="鉴定单号" min-width="180" />
<el-table-column prop="product_name" label="商品名称" min-width="220" />
<el-table-column prop="service_provider_text" label="服务类型" min-width="120" />
<el-table-column label="下单渠道" min-width="150">
<template #default="{ row }">
<span>{{ row.source_channel_text }}</span>
<div v-if="row.source_customer_id" class="table-subtext">客户ID{{ row.source_customer_id }}</div>
</template>
</el-table-column>
<el-table-column label="订单状态" min-width="150">
<template #default="{ row }">
<OrderStatusTag :status="row.display_status" />
</template>
</el-table-column>
<el-table-column prop="estimated_finish_time" label="预计完成时间" min-width="170" />
<el-table-column prop="pay_amount" label="金额" min-width="100">
<template #default="{ row }">¥{{ row.pay_amount }}</template>
</el-table-column>
<el-table-column prop="created_at" label="创建时间" min-width="170" />
<el-table-column label="操作" fixed="right" width="110">
<template #default="{ row }">
<el-button link type="primary" @click="openDetail(row)">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-drawer v-model="drawerVisible" size="68%" title="订单详情">
<div v-loading="detailLoading" v-if="detail" class="order-detail-shell">
<div class="detail-card order-detail-hero">
<div class="order-detail-hero__main">
<div class="order-detail-hero__eyebrow">订单履约工作区</div>
<div class="order-detail-hero__title">{{ productTitle }}</div>
<div class="order-detail-hero__meta">{{ productMetaText }}</div>
</div>
<div class="order-detail-hero__side">
<div class="order-detail-hero__tags">
<OrderStatusTag :status="detail.order_info.display_status" />
<span class="order-detail-chip">{{ detail.order_info.service_provider_text }}</span>
</div>
<div class="order-detail-hero__actions">
<el-button
v-if="canMarkReceived"
type="primary"
:loading="receiveSubmitting"
@click="markReceived"
>
标记鉴定中心签收
</el-button>
<el-button
v-if="detail.order_info.can_reassign_warehouse"
type="primary"
plain
:loading="warehouseOptionsLoading"
@click="openWarehouseDialog"
>
手动改派仓库
</el-button>
<el-button
v-if="canSubmitReturnLogistics || returnLogisticsBlockReason"
type="primary"
plain
:disabled="!canSubmitReturnLogistics"
@click="openReturnDialog"
>
{{ detail.return_logistics?.tracking_no ? '更新回寄运单' : '登记回寄运单' }}
</el-button>
<el-button
v-if="canMarkReturnReceived"
type="primary"
:loading="returnReceiveSubmitting"
@click="markReturnReceived"
>
标记用户签收
</el-button>
</div>
</div>
</div>
<div class="detail-grid">
<div class="detail-card">
<div class="detail-card__title">订单概览</div>
<div class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">订单号</div>
<div class="order-detail-item__value">{{ detail.order_info.order_no }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">鉴定单号</div>
<div class="order-detail-item__value">{{ detail.order_info.appraisal_no }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">服务类型</div>
<div class="order-detail-item__value">{{ detail.order_info.service_provider_text }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">下单渠道</div>
<div class="order-detail-item__value">{{ detail.order_info.source_channel_text || "-" }}</div>
</div>
<div class="order-detail-item" v-if="detail.order_info.source_customer_id">
<div class="order-detail-item__label">大客户客户 ID</div>
<div class="order-detail-item__value">{{ detail.order_info.source_customer_id }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">当前状态</div>
<div class="order-detail-item__value"><OrderStatusTag :status="detail.order_info.display_status" /></div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">订单金额</div>
<div class="order-detail-item__value">¥{{ detail.order_info.pay_amount }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">预计完成</div>
<div class="order-detail-item__value">{{ detail.order_info.estimated_finish_time || "-" }}</div>
</div>
</div>
</div>
<div class="detail-card">
<div class="detail-card__title">商品信息</div>
<div class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">商品名称</div>
<div class="order-detail-item__value">{{ detail.product_info.product_name || "-" }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">品类 / 品牌</div>
<div class="order-detail-item__value">{{ detail.product_info.category_name || "-" }} / {{ detail.product_info.brand_name || "-" }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">颜色 / 规格</div>
<div class="order-detail-item__value">{{ detail.product_info.color || "-" }} / {{ detail.product_info.size_spec || "-" }}</div>
</div>
</div>
</div>
<div class="detail-card">
<div class="detail-card__title">补充信息</div>
<div class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">购买渠道</div>
<div class="order-detail-item__value">{{ detail.extra_info.purchase_channel || "-" }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">购买价格</div>
<div class="order-detail-item__value">¥{{ detail.extra_info.purchase_price }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">使用情况</div>
<div class="order-detail-item__value">{{ usageStatusText }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">补充说明</div>
<div class="order-detail-item__value">{{ detail.extra_info.condition_desc || detail.extra_info.remark || "-" }}</div>
</div>
</div>
</div>
<div class="detail-card" v-if="detail.shipping_target">
<div class="detail-card__title">收货仓库</div>
<div class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">仓库名称 / 编码</div>
<div class="order-detail-item__value">{{ detail.shipping_target.warehouse_name }} / {{ detail.shipping_target.warehouse_code }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">收件人 / 联系电话</div>
<div class="order-detail-item__value">{{ detail.shipping_target.receiver_name }} / {{ detail.shipping_target.receiver_mobile }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">收件地址</div>
<div class="order-detail-item__value">{{ detail.shipping_target.full_address }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">服务时间</div>
<div class="order-detail-item__value">{{ detail.shipping_target.service_time }}</div>
</div>
</div>
</div>
<div class="detail-card">
<div class="detail-card__title">寄回地址</div>
<div v-if="detail.return_address" class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">收件人 / 联系电话</div>
<div class="order-detail-item__value">{{ detail.return_address.consignee }} / {{ detail.return_address.mobile }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">寄回地址</div>
<div class="order-detail-item__value">{{ detail.return_address.full_address }}</div>
</div>
</div>
<el-empty v-else description="用户暂未确认寄回地址" :image-size="64" />
</div>
<div class="detail-card" v-if="detail.logistics_info">
<div class="detail-card__title">物流信息</div>
<div class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">快递公司 / 运单号</div>
<div class="order-detail-item__value">{{ detail.logistics_info.express_company || "-" }} / {{ detail.logistics_info.tracking_no || "-" }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">物流状态</div>
<div class="order-detail-item__value">{{ logisticsActionText }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">最新节点</div>
<div class="order-detail-item__value">{{ detail.logistics_info.latest_desc || "-" }}</div>
</div>
<div class="order-detail-item order-detail-item--full" v-if="detail.logistics_info.latest_time">
<div class="order-detail-item__label">最新更新时间</div>
<div class="order-detail-item__value">{{ detail.logistics_info.latest_time }}</div>
</div>
</div>
<div v-if="canMarkReceived" class="detail-card__desc" style="margin-top: 16px;">
<el-alert title="待签收操作" description="物流信息已提交,确认鉴定中心实际收货后再执行签收。" type="warning" :closable="false" show-icon />
</div>
</div>
<div class="detail-card" v-if="detail.return_logistics">
<div class="detail-card__title">回寄物流</div>
<div class="order-detail-grid">
<div class="order-detail-item">
<div class="order-detail-item__label">快递公司 / 运单号</div>
<div class="order-detail-item__value">{{ detail.return_logistics.express_company || "-" }} / {{ detail.return_logistics.tracking_no || "-" }}</div>
</div>
<div class="order-detail-item">
<div class="order-detail-item__label">物流状态</div>
<div class="order-detail-item__value">{{ detail.return_logistics.tracking_status_text }}</div>
</div>
<div class="order-detail-item order-detail-item--full">
<div class="order-detail-item__label">最新节点</div>
<div class="order-detail-item__value">{{ detail.return_logistics.latest_desc || "-" }}</div>
</div>
<div class="order-detail-item order-detail-item--full" v-if="detail.return_logistics.latest_time">
<div class="order-detail-item__label">最新更新时间</div>
<div class="order-detail-item__value">{{ detail.return_logistics.latest_time }}</div>
</div>
</div>
</div>
<div class="detail-card" v-if="detail.report_summary">
<div class="detail-card__title">报告信息</div>
<el-alert
v-if="returnLogisticsBlockReason"
type="warning"
:closable="false"
show-icon
:title="returnLogisticsBlockReason"
description="请先在报告中心发布订单报告,发布后再登记回寄运单。"
style="margin-top: 12px;"
/>
<div class="detail-card__desc">
<div class="detail-label">报告编号</div>
<div class="detail-value">{{ detail.report_summary.report_no }}</div>
</div>
<div class="detail-card__desc">
<div class="detail-label">报告标题</div>
<div class="detail-value">{{ detail.report_summary.report_title }}</div>
</div>
<div class="detail-card__desc">
<div class="detail-label">发布时间</div>
<div class="detail-value">{{ detail.report_summary.publish_time }}</div>
</div>
</div>
<div class="detail-card" style="grid-column: 1 / -1">
<div class="detail-card__title">时间轴</div>
<div class="timeline-list" style="margin-top: 14px">
<div v-for="item in detail.timeline" :key="`${item.node_text}-${item.occurred_at}`" class="timeline-node">
<div class="timeline-node__title">{{ item.node_text }}</div>
<div class="timeline-node__time">{{ item.occurred_at }}</div>
<div class="timeline-node__desc">{{ item.node_desc }}</div>
</div>
</div>
</div>
<div class="detail-card" v-if="detail.logistics_info" style="grid-column: 1 / -1">
<div class="detail-card__title">物流轨迹</div>
<div class="timeline-list" style="margin-top: 14px">
<div v-for="item in detail.logistics_info.nodes" :key="`${item.node_time}-${item.node_desc}`" class="timeline-node">
<div class="timeline-node__title">{{ item.node_desc }}</div>
<div class="timeline-node__time">{{ item.node_time }}</div>
<div class="timeline-node__desc">{{ item.node_location || "-" }}</div>
</div>
</div>
</div>
<div class="detail-card" v-if="detail.supplement_task" style="grid-column: 1 / -1">
<div class="detail-card__title">补图任务</div>
<div class="detail-card__desc">
<div class="detail-label">补图原因</div>
<div class="detail-value">{{ detail.supplement_task.reason }}</div>
</div>
<div class="detail-card__desc">
<div class="detail-label">截止时间</div>
<div class="detail-value">{{ detail.supplement_task.deadline }}</div>
</div>
<div class="timeline-list" style="margin-top: 14px">
<div v-for="item in detail.supplement_task.items" :key="item.item_name" class="timeline-node">
<div class="timeline-node__title">{{ item.item_name }}</div>
<div class="timeline-node__desc">{{ item.guide_text }}</div>
</div>
</div>
</div>
</div>
</div>
</el-drawer>
<el-dialog v-model="warehouseDialogVisible" title="改派收货仓库" width="720px">
<div v-loading="warehouseOptionsLoading" style="display: grid; gap: 14px;">
<div
v-for="item in warehouseOptions"
:key="item.id"
:style="{
border: selectedWarehouseId === item.id ? '1px solid #c8a45d' : '1px solid var(--admin-border)',
borderRadius: '14px',
padding: '16px 18px',
cursor: 'pointer',
background: selectedWarehouseId === item.id ? 'rgba(200, 164, 93, 0.08)' : '#fff',
}"
@click="selectedWarehouseId = item.id"
>
<div style="display:flex; justify-content:space-between; gap: 16px; align-items:center;">
<div style="font-weight:700;">{{ item.warehouse_name }}</div>
<div style="color: var(--admin-text-subtle);">{{ item.is_default ? '默认仓库' : '可选仓库' }}</div>
</div>
<div style="margin-top: 8px; color: var(--admin-text-subtle);">{{ item.service_provider_text }} / {{ item.warehouse_code }}</div>
<div style="margin-top: 8px;">{{ item.receiver_name }} / {{ item.receiver_mobile }}</div>
<div style="margin-top: 8px;">{{ item.full_address }}</div>
<div style="margin-top: 8px; color: var(--admin-text-subtle);">{{ item.service_time }}</div>
</div>
</div>
<template #footer>
<el-button @click="warehouseDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="warehouseSubmitting" @click="submitWarehouseReassign">确认改派</el-button>
</template>
</el-dialog>
<el-dialog v-model="returnDialogVisible" title="登记回寄运单" width="520px">
<el-form label-position="top">
<el-form-item label="回寄快递公司">
<el-input v-model="returnExpressCompany" placeholder="例如:顺丰速运" />
</el-form-item>
<el-form-item label="回寄运单号">
<el-input v-model="returnTrackingNo" placeholder="请输入回寄运单号" />
</el-form-item>
<el-alert
v-if="detail?.return_address"
type="info"
:closable="false"
show-icon
title="当前寄回地址"
:description="`${detail.return_address.consignee} / ${detail.return_address.mobile} / ${detail.return_address.full_address}`"
/>
<el-alert
v-else
type="warning"
:closable="false"
show-icon
title="用户尚未确认寄回地址"
description="请先提醒用户在订单详情中确认寄回地址,再登记回寄运单。"
/>
</el-form>
<template #footer>
<el-button @click="returnDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="returnSubmitting" :disabled="!canSubmitReturnLogistics" @click="submitReturnLogistics">确认登记</el-button>
</template>
</el-dialog>
</template>
<style scoped>
.order-detail-shell {
display: flex;
flex-direction: column;
gap: 18px;
}
.order-detail-hero {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
padding: 24px;
background:
radial-gradient(circle at top right, rgba(200, 164, 93, 0.12), transparent 30%),
linear-gradient(135deg, #fffdfa 0%, #fbf8f1 100%);
}
.order-detail-hero__main {
min-width: 0;
}
.order-detail-hero__eyebrow {
display: inline-flex;
align-items: center;
min-height: 28px;
padding: 0 12px;
border-radius: 999px;
background: rgba(200, 164, 93, 0.12);
color: #7a5a21;
font-size: 12px;
font-weight: 700;
}
.order-detail-hero__title {
margin-top: 14px;
color: var(--admin-text-main);
font-size: 28px;
font-weight: 800;
line-height: 1.2;
}
.order-detail-hero__meta {
margin-top: 10px;
color: var(--admin-text-subtle);
font-size: 14px;
line-height: 1.6;
}
.order-detail-hero__side {
min-width: 260px;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 14px;
}
.order-detail-hero__tags {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 10px;
}
.order-detail-hero__actions {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 12px;
}
.order-detail-chip {
display: inline-flex;
align-items: center;
min-height: 30px;
padding: 0 12px;
border-radius: 999px;
background: rgba(72, 104, 133, 0.1);
color: var(--admin-progress);
font-size: 12px;
font-weight: 700;
}
.table-subtext {
margin-top: 4px;
color: var(--admin-text-subtle);
font-size: 12px;
line-height: 1.4;
}
.order-detail-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
margin-top: 16px;
}
.order-detail-item {
padding: 14px 16px;
border: 1px solid #efe8d9;
border-radius: 16px;
background: #fcfaf5;
}
.order-detail-item--full {
grid-column: 1 / -1;
}
.order-detail-item__label {
color: var(--admin-text-subtle);
font-size: 12px;
}
.order-detail-item__value {
margin-top: 8px;
color: var(--admin-text-main);
font-size: 16px;
font-weight: 700;
line-height: 1.5;
word-break: break-word;
}
@media (max-width: 1280px) {
.order-detail-hero {
grid-template-columns: 1fr;
display: grid;
}
.order-detail-hero__side {
min-width: 0;
align-items: flex-start;
}
.order-detail-hero__tags,
.order-detail-hero__actions {
justify-content: flex-start;
}
}
@media (max-width: 960px) {
.order-detail-grid {
grid-template-columns: 1fr;
}
}
</style>