`
This commit is contained in:
@@ -35,6 +35,7 @@ const dateRange = ref<[string, string] | []>([])
|
||||
const editorOpen = ref(false)
|
||||
const detailOpen = ref(false)
|
||||
const editingId = ref<string>()
|
||||
const openingEditor = ref(false)
|
||||
const detailId = ref<string>()
|
||||
const saving = ref(false)
|
||||
const detailLoading = ref(false)
|
||||
@@ -42,6 +43,19 @@ const detailError = ref('')
|
||||
const editorBaseline = ref('')
|
||||
let cargoSequence = 0
|
||||
|
||||
function formatDateTime(value: string) {
|
||||
const date = new Date(value)
|
||||
if (Number.isNaN(date.getTime())) return value || '-'
|
||||
return date.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
})
|
||||
}
|
||||
|
||||
function emptyDraft(): FirstLegOrderDraft {
|
||||
return {
|
||||
referenceNo: '',
|
||||
@@ -97,7 +111,9 @@ const emptyDescription = computed(() => hasActiveFilters.value ? '没有符合
|
||||
|
||||
async function loadPageData() {
|
||||
try {
|
||||
await Promise.all([store.load(), firstLegPartySource.load()])
|
||||
const requests: Promise<unknown>[] = [store.load(), firstLegPartySource.load()]
|
||||
if (auth.hasPermission('company:profile:view')) requests.push(tenantStore.loadCompanyContext())
|
||||
await Promise.all(requests)
|
||||
availableShippers.value = firstLegPartySource.listAvailable('SHIPPER')
|
||||
availableConsignees.value = firstLegPartySource.listAvailable('CONSIGNEE')
|
||||
} catch (error) {
|
||||
@@ -127,8 +143,17 @@ function markEditorClean() {
|
||||
editorBaseline.value = serializedDraft.value
|
||||
}
|
||||
|
||||
function cloneDraft(draft: FirstLegOrderDraft): FirstLegOrderDraft {
|
||||
return {
|
||||
...draft,
|
||||
shipperPartySnapshot: draft.shipperPartySnapshot ? { ...draft.shipperPartySnapshot } : null,
|
||||
consigneePartySnapshot: draft.consigneePartySnapshot ? { ...draft.consigneePartySnapshot } : null,
|
||||
items: draft.items.map((item) => ({ ...item })),
|
||||
}
|
||||
}
|
||||
|
||||
function replaceForm(draft: FirstLegOrderDraft) {
|
||||
Object.assign(form, structuredClone(draft))
|
||||
Object.assign(form, cloneDraft(draft))
|
||||
markEditorClean()
|
||||
}
|
||||
|
||||
@@ -142,10 +167,10 @@ function draftFromOrder(order: FirstLegOrder): FirstLegOrderDraft {
|
||||
receivingWarehouseId: order.receivingWarehouseId,
|
||||
expectedDepartureDate: order.expectedDepartureDate,
|
||||
shipperPartyId: order.shipperPartyId,
|
||||
shipperPartySnapshot: order.shipperPartySnapshot ? structuredClone(order.shipperPartySnapshot) : null,
|
||||
shipperPartySnapshot: order.shipperPartySnapshot ? { ...order.shipperPartySnapshot } : null,
|
||||
shipper: order.shipper,
|
||||
consigneePartyId: order.consigneePartyId,
|
||||
consigneePartySnapshot: order.consigneePartySnapshot ? structuredClone(order.consigneePartySnapshot) : null,
|
||||
consigneePartySnapshot: order.consigneePartySnapshot ? { ...order.consigneePartySnapshot } : null,
|
||||
consignee: order.consignee,
|
||||
priority: order.priority,
|
||||
customerRemark: order.customerRemark,
|
||||
@@ -160,7 +185,7 @@ function draftFromOrder(order: FirstLegOrder): FirstLegOrderDraft {
|
||||
destinationType: order.destinationType,
|
||||
amazonWarehouseCode: order.amazonWarehouseCode,
|
||||
shipmentId: order.shipmentId,
|
||||
items: structuredClone(order.items),
|
||||
items: order.items.map((item) => ({ ...item })),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,12 +251,27 @@ function openCreate() {
|
||||
editorOpen.value = true
|
||||
}
|
||||
|
||||
function openEdit(order: FirstLegOrder) {
|
||||
if (!canEditOrder.value || !canClientEditFirstLegOrder(order.status)) return
|
||||
editingId.value = order.id
|
||||
replaceForm(draftFromOrder(order))
|
||||
detailOpen.value = false
|
||||
editorOpen.value = true
|
||||
async function openEdit(order: FirstLegOrder) {
|
||||
if (openingEditor.value || !canEditOrder.value || !canClientEditFirstLegOrder(order.status)) return
|
||||
openingEditor.value = true
|
||||
try {
|
||||
const detailedOrder = await store.loadDetail(order.id)
|
||||
const draft = draftFromOrder(detailedOrder)
|
||||
const warehouseAvailable = availableWarehouses.value.some((item) => item.id === detailedOrder.receivingWarehouseId)
|
||||
if (!warehouseAvailable) {
|
||||
draft.receivingWarehouseId = ''
|
||||
ElMessage.warning('原平台收货仓当前不可用,请重新选择可用收货仓')
|
||||
}
|
||||
editingId.value = detailedOrder.id
|
||||
replaceForm(draft)
|
||||
if (warehouseAvailable) void loadSelectedWarehouse(detailedOrder.receivingWarehouseId)
|
||||
detailOpen.value = false
|
||||
editorOpen.value = true
|
||||
} catch (error) {
|
||||
ElMessage.error(error instanceof Error ? error.message : '订单详情加载失败,暂时无法编辑')
|
||||
} finally {
|
||||
openingEditor.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function openDetail(order: FirstLegOrder) {
|
||||
@@ -300,7 +340,7 @@ async function saveDraft() {
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
const order = await store.saveDraft(structuredClone(form), tenantStore.company.companyName, editingId.value)
|
||||
const order = await store.saveDraft(cloneDraft(form), tenantStore.company.companyName, editingId.value)
|
||||
editingId.value = order.id
|
||||
markEditorClean()
|
||||
editorOpen.value = false
|
||||
@@ -338,7 +378,7 @@ async function submitOrder() {
|
||||
|
||||
try {
|
||||
saving.value = true
|
||||
const order = await store.submit(structuredClone(form), tenantStore.company.companyName, editingId.value, tenantStore.company.auditStatus)
|
||||
const order = await store.submit(cloneDraft(form), tenantStore.company.companyName, editingId.value, tenantStore.company.auditStatus)
|
||||
markEditorClean()
|
||||
editorOpen.value = false
|
||||
detailId.value = order.id
|
||||
@@ -392,7 +432,21 @@ function resetFilters() {
|
||||
</div>
|
||||
|
||||
<div v-loading="store.loading" class="client-card order-table-card">
|
||||
<div v-if="store.loadError" class="order-load-state" role="alert">
|
||||
<AlertTriangle :size="24" />
|
||||
<div><strong>订单数据加载失败</strong><span>{{ store.loadError }}</span></div>
|
||||
<el-button :loading="store.loading" @click="loadPageData">重新加载</el-button>
|
||||
</div>
|
||||
<template v-else>
|
||||
<el-table v-if="filteredOrders.length" class="desktop-order-table" :data="filteredOrders" row-key="id">
|
||||
<el-table-column label="操作" width="180" fixed="left">
|
||||
<template #default="{ row }">
|
||||
<div class="order-row-actions">
|
||||
<el-button link type="primary" @click="openDetail(row as FirstLegOrder)"><Eye :size="15" />详情</el-button>
|
||||
<el-button v-if="canEditOrder && canClientEditFirstLegOrder((row as FirstLegOrder).status)" link type="primary" :loading="openingEditor" @click="openEdit(row as FirstLegOrder)"><Pencil :size="15" />编辑</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单" min-width="190">
|
||||
<template #default="{ row }">
|
||||
<button class="order-number-link" type="button" @click="openDetail(row as FirstLegOrder)">{{ (row as FirstLegOrder).orderNo || '未提交草稿' }}</button>
|
||||
@@ -410,30 +464,23 @@ function resetFilters() {
|
||||
<template #default="{ row }"><el-tag :type="getFirstLegStatusTone((row as FirstLegOrder).status)" effect="light">{{ getFirstLegStatusLabel((row as FirstLegOrder).status) }}</el-tag></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="负责人" prop="operatorName" width="110" />
|
||||
<el-table-column label="更新时间" prop="updatedAt" width="155" />
|
||||
<el-table-column label="操作" width="180">
|
||||
<template #default="{ row }">
|
||||
<div class="order-row-actions">
|
||||
<el-button link type="primary" @click="openDetail(row as FirstLegOrder)"><Eye :size="15" />详情</el-button>
|
||||
<el-button v-if="canEditOrder && canClientEditFirstLegOrder((row as FirstLegOrder).status)" link type="primary" @click="openEdit(row as FirstLegOrder)"><Pencil :size="15" />编辑</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" width="155"><template #default="{ row }">{{ formatDateTime((row as FirstLegOrder).updatedAt) }}</template></el-table-column>
|
||||
</el-table>
|
||||
<div v-if="filteredOrders.length" class="mobile-order-list">
|
||||
<article v-for="order in filteredOrders" :key="order.id" class="mobile-order-card">
|
||||
<header><button type="button" @click="openDetail(order)">{{ order.orderNo || '未提交草稿' }}</button><el-tag :type="getFirstLegStatusTone(order.status)" effect="light">{{ getFirstLegStatusLabel(order.status) }}</el-tag></header>
|
||||
<span class="order-reference">{{ order.referenceNo || '无客户参考号' }}</span>
|
||||
<dl><div><dt>运输路线</dt><dd>{{ order.origin }} → {{ order.destination }}</dd></div><div><dt>收货仓</dt><dd>{{ order.receivingWarehouseName }}</dd></div><div><dt>货物</dt><dd>{{ order.items[0]?.cargoNameCn || '-' }}<span v-if="order.items.length > 1">等 {{ order.items.length }} 项</span></dd></div><div><dt>负责人</dt><dd>{{ order.operatorName }}</dd></div></dl>
|
||||
<footer><span>更新于 {{ order.updatedAt }}</span><div><el-button link type="primary" @click="openDetail(order)"><Eye :size="15" />详情</el-button><el-button v-if="canEditOrder && canClientEditFirstLegOrder(order.status)" link type="primary" @click="openEdit(order)"><Pencil :size="15" />编辑</el-button></div></footer>
|
||||
<footer><span>更新于 {{ formatDateTime(order.updatedAt) }}</span><div><el-button link type="primary" @click="openDetail(order)"><Eye :size="15" />详情</el-button><el-button v-if="canEditOrder && canClientEditFirstLegOrder(order.status)" link type="primary" :loading="openingEditor" @click="openEdit(order)"><Pencil :size="15" />编辑</el-button></div></footer>
|
||||
</article>
|
||||
</div>
|
||||
<el-empty v-else description="没有符合条件的头程订单">
|
||||
<el-empty v-else :description="emptyDescription">
|
||||
<el-button v-if="auth.hasPermission('order:first-leg:create')" type="primary" :disabled="availableWarehouses.length === 0" @click="openCreate"><Plus :size="16" />{{ availableWarehouses.length ? '创建第一笔订单' : '暂无可用收货仓' }}</el-button>
|
||||
</el-empty>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<el-drawer v-model="editorOpen" class="first-leg-editor" :title="editingId ? '编辑订单草稿' : '创建头程订单'" size="760px" destroy-on-close>
|
||||
<el-drawer v-model="editorOpen" class="first-leg-editor" :title="editingId ? '编辑订单草稿' : '创建头程订单'" size="760px" destroy-on-close :before-close="requestCloseEditor">
|
||||
<el-form label-position="top" class="order-form">
|
||||
<section class="order-form-section">
|
||||
<h3>运输信息</h3>
|
||||
@@ -442,7 +489,7 @@ function resetFilters() {
|
||||
<el-form-item label="业务类型" required><el-radio-group v-model="form.businessType"><el-radio-button value="EXPORT">出口</el-radio-button><el-radio-button value="IMPORT">进口</el-radio-button></el-radio-group></el-form-item>
|
||||
<el-form-item label="起运地" required><el-input v-model="form.origin" placeholder="例如:宁波" /></el-form-item>
|
||||
<el-form-item label="目的地" required><el-input v-model="form.destination" placeholder="例如:洛杉矶" /></el-form-item>
|
||||
<el-form-item label="平台收货仓" required><el-select v-model="form.receivingWarehouseId" filterable placeholder="请选择送货仓库"><el-option v-for="warehouse in availableWarehouses" :key="warehouse.id" :label="`${warehouse.name} · ${warehouse.city}`" :value="warehouse.id" /></el-select></el-form-item>
|
||||
<el-form-item label="平台收货仓" required><el-select v-model="form.receivingWarehouseId" filterable placeholder="请选择送货仓库" @change="loadSelectedWarehouse"><el-option v-for="warehouse in availableWarehouses" :key="warehouse.id" :label="`${warehouse.name} · ${warehouse.city}`" :value="warehouse.id" /></el-select></el-form-item>
|
||||
<el-form-item label="期望出发日期"><el-date-picker v-model="form.expectedDepartureDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" /></el-form-item>
|
||||
<el-form-item label="客户参考号"><el-input v-model="form.referenceNo" maxlength="100" placeholder="贵司内部单号(选填)" /></el-form-item>
|
||||
<el-form-item label="优先级"><el-select v-model="form.priority"><el-option label="普通" value="NORMAL" /><el-option label="紧急" value="URGENT" /><el-option label="加急" value="EXPEDITED" /></el-select></el-form-item>
|
||||
@@ -467,6 +514,7 @@ function resetFilters() {
|
||||
<header><span><Building2 :size="17" /><strong>发货单位</strong></span><small>必填</small></header>
|
||||
<el-form-item label="选择发货单位" required>
|
||||
<el-select v-model="form.shipperPartyId" filterable clearable placeholder="请选择已启用的发货单位" @change="selectShipper" @clear="clearShipper">
|
||||
<el-option v-if="form.shipperPartySnapshot && !availableShippers.some((party) => party.id === form.shipperPartyId)" :label="`${form.shipperPartySnapshot.name} · 历史快照`" :value="form.shipperPartyId" disabled />
|
||||
<el-option v-for="party in availableShippers" :key="party.id" :label="`${party.name} · ${party.code}`" :value="party.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -484,6 +532,7 @@ function resetFilters() {
|
||||
<header><span><Building2 :size="17" /><strong>收货单位</strong></span><small>必填</small></header>
|
||||
<el-form-item label="选择收货单位" required>
|
||||
<el-select v-model="form.consigneePartyId" filterable clearable placeholder="请选择已启用的收货单位" @change="selectConsignee" @clear="clearConsignee">
|
||||
<el-option v-if="form.consigneePartySnapshot && !availableConsignees.some((party) => party.id === form.consigneePartyId)" :label="`${form.consigneePartySnapshot.name} · 历史快照`" :value="form.consigneePartyId" disabled />
|
||||
<el-option v-for="party in availableConsignees" :key="party.id" :label="`${party.name} · ${party.code}`" :value="party.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -530,11 +579,17 @@ function resetFilters() {
|
||||
<el-form-item label="客户备注"><el-input v-model="form.customerRemark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="平台工作人员可以看到该备注" /></el-form-item>
|
||||
</section>
|
||||
</el-form>
|
||||
<template #footer><div class="editor-actions"><el-button :disabled="saving" @click="editorOpen = false">返回</el-button><el-button v-if="editingId ? canEditOrder : canCreateOrder" :loading="saving" @click="saveDraft">保存草稿</el-button><el-button v-if="auth.hasPermission('order:first-leg:submit')" type="primary" :loading="saving" @click="submitOrder"><Send :size="16" />{{ companyApproved ? '提交审核' : '提交前需完成资料审核' }}</el-button></div></template>
|
||||
<template #footer><div class="editor-actions"><el-button :disabled="saving" @click="closeEditor">返回</el-button><el-button v-if="editingId ? canEditOrder : canCreateOrder" :loading="saving" @click="saveDraft">保存草稿</el-button><el-button v-if="auth.hasPermission('order:first-leg:submit')" type="primary" :loading="saving" @click="submitOrder"><Send :size="16" />{{ companyApproved ? '提交审核' : '提交前需完成资料审核' }}</el-button></div></template>
|
||||
</el-drawer>
|
||||
|
||||
<el-drawer v-model="detailOpen" v-loading="detailLoading" class="first-leg-detail" title="订单详情" size="680px">
|
||||
<template v-if="detailOrder">
|
||||
<el-drawer v-model="detailOpen" class="first-leg-detail" title="订单详情" size="680px">
|
||||
<div v-loading="detailLoading" class="order-detail-content">
|
||||
<div v-if="detailError" class="order-load-state is-compact" role="alert">
|
||||
<AlertTriangle :size="24" />
|
||||
<div><strong>订单详情加载失败</strong><span>{{ detailError }}</span></div>
|
||||
<el-button :loading="detailLoading" @click="retryDetail">重新加载</el-button>
|
||||
</div>
|
||||
<template v-else-if="detailOrder">
|
||||
<div class="order-detail-heading">
|
||||
<div><span>{{ getFirstLegTransportModeLabel(detailOrder.transportMode) }}</span><h2>{{ detailOrder.orderNo || '未提交草稿' }}</h2><p>{{ detailOrder.origin }} → {{ detailOrder.destination }}</p></div>
|
||||
<el-tag :type="getFirstLegStatusTone(detailOrder.status)" effect="light">{{ getFirstLegStatusLabel(detailOrder.status) }}</el-tag>
|
||||
@@ -554,7 +609,8 @@ function resetFilters() {
|
||||
<section class="detail-section"><h3>货物汇总</h3><div v-if="detailSummary" class="cargo-summary"><div><Box :size="18" /><span>明细</span><strong>{{ detailOrder.items.length }} 项</strong></div><div><span>件数</span><strong>{{ detailSummary.pieces }}</strong></div><div><span>毛重</span><strong>{{ detailSummary.grossWeightKg.toLocaleString() }} kg</strong></div><div><span>体积</span><strong>{{ detailSummary.volumeCbm }} m³</strong></div></div><ul class="cargo-detail-list"><li v-for="item in detailOrder.items" :key="item.id"><strong>{{ item.cargoNameCn }}</strong><span>{{ item.sku || '无 SKU' }} · {{ item.pieces }} 件 · {{ item.grossWeightKg }} kg</span></li></ul></section>
|
||||
<section class="detail-section"><h3>处理时间线</h3><el-timeline><el-timeline-item v-for="item in [...detailOrder.timeline].reverse()" :key="item.id" :timestamp="item.occurredAt" placement="top"><strong>{{ item.title }}</strong><p>{{ item.description }}</p><span>{{ item.operatorName }}</span></el-timeline-item></el-timeline></section>
|
||||
</template>
|
||||
<template #footer><div v-if="detailOrder" class="editor-actions"><el-button @click="detailOpen = false">关闭</el-button><el-button v-if="canEditOrder && canClientEditFirstLegOrder(detailOrder.status)" @click="openEdit(detailOrder)"><Pencil :size="16" />编辑草稿</el-button></div></template>
|
||||
</div>
|
||||
<template #footer><div v-if="detailOrder" class="editor-actions"><el-button @click="detailOpen = false">关闭</el-button><el-button v-if="canEditOrder && canClientEditFirstLegOrder(detailOrder.status)" :loading="openingEditor" @click="openEdit(detailOrder)"><Pencil :size="16" />编辑草稿</el-button></div></template>
|
||||
</el-drawer>
|
||||
</section>
|
||||
</template>
|
||||
@@ -576,6 +632,12 @@ function resetFilters() {
|
||||
.order-filters { display: grid; width: 100%; grid-template-columns: minmax(190px, 1.35fr) minmax(130px, .65fr) minmax(150px, .75fr) minmax(230px, 1fr); gap: 10px; }
|
||||
.order-toolbar-actions, .order-row-actions, .editor-actions { display: flex; justify-content: flex-end; gap: 8px; }
|
||||
.order-table-card { padding: 0; overflow: hidden; }
|
||||
.order-load-state { display: grid; min-height: 220px; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 14px; padding: 28px; color: #9a5a09; }
|
||||
.order-load-state > div { display: flex; min-width: 0; flex-direction: column; gap: 5px; }
|
||||
.order-load-state strong { color: var(--navy); font-size: 14px; }
|
||||
.order-load-state span { overflow-wrap: anywhere; color: var(--muted); font-size: 12px; line-height: 1.55; }
|
||||
.order-load-state.is-compact { min-height: 180px; }
|
||||
.order-detail-content { min-height: 180px; }
|
||||
.mobile-order-list { display: none; }
|
||||
.order-number-link { display: block; padding: 0; border: 0; background: none; color: var(--primary); cursor: pointer; font-weight: 700; text-align: left; }
|
||||
.order-number-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
|
||||
@@ -641,6 +703,21 @@ function resetFilters() {
|
||||
:deep(.el-timeline-item__content p) { margin: 5px 0; font-size: 12px; }
|
||||
:deep(.el-timeline-item__content > span) { font-size: 11px; }
|
||||
@media (max-width: 1100px) { .order-toolbar-actions { align-self: flex-end; } .order-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||
@media (max-width: 1280px) {
|
||||
.desktop-order-table { display: none; }
|
||||
.mobile-order-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; padding: 10px; }
|
||||
.mobile-order-card { min-width: 0; padding: 14px; border: 1px solid var(--border); background: #fff; }
|
||||
.mobile-order-card header, .mobile-order-card footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
||||
.mobile-order-card header button { min-width: 0; overflow: hidden; padding: 0; border: 0; background: none; color: var(--primary); font-weight: 750; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.mobile-order-card header button:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
|
||||
.mobile-order-card dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 14px 0; }
|
||||
.mobile-order-card dl div { min-width: 0; }
|
||||
.mobile-order-card dt, .mobile-order-card footer > span { color: var(--muted); font-size: 10px; }
|
||||
.mobile-order-card dd { overflow: hidden; margin: 4px 0 0; font-size: 12px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.mobile-order-card dd span { margin-left: 4px; color: var(--muted); font-weight: 400; }
|
||||
.mobile-order-card footer { align-items: flex-end; padding-top: 10px; border-top: 1px solid var(--border); }
|
||||
.mobile-order-card footer > div { display: flex; }
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.order-eligibility { flex-wrap: wrap; }
|
||||
.order-eligibility .el-button { width: 100%; min-height: 44px; }
|
||||
@@ -651,7 +728,9 @@ function resetFilters() {
|
||||
.order-toolbar-actions :deep(.el-button) { min-height: 44px; flex: 1; }
|
||||
.editor-actions :deep(.el-button) { min-height: 44px; }
|
||||
.desktop-order-table { display: none; }
|
||||
.mobile-order-list { display: grid; gap: 10px; padding: 10px; }
|
||||
.order-load-state { min-height: 240px; grid-template-columns: 1fr; justify-items: start; }
|
||||
.order-load-state .el-button { width: 100%; min-height: 44px; }
|
||||
.mobile-order-list { grid-template-columns: 1fr; }
|
||||
.mobile-order-card { padding: 14px; border: 1px solid var(--border); background: #fff; }
|
||||
.mobile-order-card header, .mobile-order-card footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
||||
.mobile-order-card header button { padding: 0; border: 0; background: none; color: var(--primary); font-weight: 750; }
|
||||
|
||||
Reference in New Issue
Block a user