merge(dev_jacy): logistics detail page polish (v3.4.13)
This commit is contained in:
@@ -46,9 +46,20 @@ export function formatTrackNodeTime(node: OrderTrackNode) {
|
|||||||
return formatShanghaiDateTime(node.createTime || node.createdAt);
|
return formatShanghaiDateTime(node.createTime || node.createdAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sortTrackNodesNewestFirst(nodes: OrderTrackNode[]): OrderTrackNode[] {
|
||||||
|
return [...nodes].sort((a, b) => {
|
||||||
|
const ta = new Date(a.createTime || a.createdAt || 0).getTime();
|
||||||
|
const tb = new Date(b.createTime || b.createdAt || 0).getTime();
|
||||||
|
if (Number.isNaN(ta) && Number.isNaN(tb)) return 0;
|
||||||
|
if (Number.isNaN(ta)) return 1;
|
||||||
|
if (Number.isNaN(tb)) return -1;
|
||||||
|
return tb - ta;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function latestTrackNode(nodes: OrderTrackNode[]) {
|
export function latestTrackNode(nodes: OrderTrackNode[]) {
|
||||||
if (nodes.length === 0) return null;
|
const sorted = sortTrackNodesNewestFirst(nodes);
|
||||||
return nodes[0];
|
return sorted[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchOrderTrack(orderId: string) {
|
export async function fetchOrderTrack(orderId: string) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export default definePageConfig({
|
export default definePageConfig({
|
||||||
navigationBarTitleText: '物流追踪',
|
navigationStyle: 'custom',
|
||||||
|
navigationBarTitleText: '物流详情',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { View, Text } from '@tarojs/components';
|
import { View, Text } from '@tarojs/components';
|
||||||
import Taro, { useRouter } from '@tarojs/taro';
|
import Taro, { useRouter } from '@tarojs/taro';
|
||||||
import PageShell from '../../components/PageShell';
|
import PageShell from '../../components/PageShell';
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
fetchOrderTrack,
|
fetchOrderTrack,
|
||||||
formatTrackNodeTime,
|
formatTrackNodeTime,
|
||||||
shouldLoadOrderTrack,
|
shouldLoadOrderTrack,
|
||||||
|
sortTrackNodesNewestFirst,
|
||||||
type OrderDelivery,
|
type OrderDelivery,
|
||||||
type OrderTrackNode,
|
type OrderTrackNode,
|
||||||
} from '../../lib/order-logistics';
|
} from '../../lib/order-logistics';
|
||||||
@@ -21,16 +22,6 @@ type OrderDetail = {
|
|||||||
delivery?: OrderDelivery | null;
|
delivery?: OrderDelivery | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const STATUS_LABELS: Record<string, string> = {
|
|
||||||
PENDING_SHIP: '待发货',
|
|
||||||
OUT_WAREHOUSE: '出库中',
|
|
||||||
SHIPPING: '配送中',
|
|
||||||
SHIPPED: '配送中',
|
|
||||||
PENDING_RECEIVE: '待签收',
|
|
||||||
DELIVERED: '待签收',
|
|
||||||
COMPLETED: '已完成',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function OrderLogisticsPage() {
|
export default function OrderLogisticsPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const orderId = router.params.id ?? '';
|
const orderId = router.params.id ?? '';
|
||||||
@@ -39,6 +30,8 @@ export default function OrderLogisticsPage() {
|
|||||||
const [trackNodes, setTrackNodes] = useState<OrderTrackNode[]>([]);
|
const [trackNodes, setTrackNodes] = useState<OrderTrackNode[]>([]);
|
||||||
const [trackLoading, setTrackLoading] = useState(false);
|
const [trackLoading, setTrackLoading] = useState(false);
|
||||||
|
|
||||||
|
const sortedTrackNodes = useMemo(() => sortTrackNodesNewestFirst(trackNodes), [trackNodes]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!orderId) return;
|
if (!orderId) return;
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
@@ -89,19 +82,12 @@ export default function OrderLogisticsPage() {
|
|||||||
return (
|
return (
|
||||||
<PageShell variant="sub" className="order-logistics-page">
|
<PageShell variant="sub" className="order-logistics-page">
|
||||||
<SubPageHeader title="物流详情" />
|
<SubPageHeader title="物流详情" />
|
||||||
<View className="sub-page-body">
|
<View className="sub-page-body order-logistics-body">
|
||||||
{!order ? (
|
{!order ? (
|
||||||
<View className="u-empty">加载中…</View>
|
<View className="u-empty">加载中…</View>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<View className="order-card">
|
<View className="order-card order-logistics-info-card">
|
||||||
<Text className="order-card-title">配送状态</Text>
|
|
||||||
<Text className="order-list-status">
|
|
||||||
{STATUS_LABELS[order.status || ''] || order.status || '处理中'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View className="order-card">
|
|
||||||
<Text className="order-card-title">物流信息</Text>
|
<Text className="order-card-title">物流信息</Text>
|
||||||
<View className="order-row">
|
<View className="order-row">
|
||||||
<Text className="order-row-label">配送方式</Text>
|
<Text className="order-row-label">配送方式</Text>
|
||||||
@@ -133,11 +119,11 @@ export default function OrderLogisticsPage() {
|
|||||||
<Text className="order-card-title">物流动态</Text>
|
<Text className="order-card-title">物流动态</Text>
|
||||||
<Text className="u-muted">加载中…</Text>
|
<Text className="u-muted">加载中…</Text>
|
||||||
</View>
|
</View>
|
||||||
) : trackNodes.length > 0 ? (
|
) : sortedTrackNodes.length > 0 ? (
|
||||||
<View className="order-card">
|
<View className="order-card">
|
||||||
<Text className="order-card-title">物流动态</Text>
|
<Text className="order-card-title">物流动态</Text>
|
||||||
<View className="order-logistics-timeline">
|
<View className="order-logistics-timeline">
|
||||||
{trackNodes.map((node, index) => (
|
{sortedTrackNodes.map((node, index) => (
|
||||||
<View
|
<View
|
||||||
key={`${node.trackInfo}-${node.createTime}-${index}`}
|
key={`${node.trackInfo}-${node.createTime}-${index}`}
|
||||||
className={`order-logistics-timeline-item${index === 0 ? ' order-logistics-timeline-item--latest' : ''}`}
|
className={`order-logistics-timeline-item${index === 0 ? ' order-logistics-timeline-item--latest' : ''}`}
|
||||||
|
|||||||
@@ -494,6 +494,14 @@
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.order-logistics-body {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-logistics-info-card {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.order-logistics-link {
|
.order-logistics-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
|||||||
+1
-1
@@ -341,7 +341,7 @@ C2~C7、C14 见 §1.3。
|
|||||||
| H5 登录前端校验 | ✅ | partner/shop LoginPage |
|
| H5 登录前端校验 | ✅ | partner/shop LoginPage |
|
||||||
| mini-user 门店体验 | ✅ | 电话脱敏/埋点、门头 aspectFit、套餐折叠 |
|
| mini-user 门店体验 | ✅ | 电话脱敏/埋点、门头 aspectFit、套餐折叠 |
|
||||||
| mini-user 商品/提货 | ✅ | 去分享、首图 preview、提货确认弹框 |
|
| mini-user 商品/提货 | ✅ | 去分享、首图 preview、提货确认弹框 |
|
||||||
| mini-user 版本/物流 | ✅ | minClientVersion + UpdateManager;配送中最新路由摘要 + 物流详情时间线(小飞侠 `/track`) |
|
| mini-user 版本/物流 | ✅ | minClientVersion + UpdateManager;配送中摘要 + 物流详情(最新在上、custom 导航栏) |
|
||||||
| OSS 大图压缩 | ✅ | shared-ui compressImage;四端 upload + mini 头像 |
|
| OSS 大图压缩 | ✅ | shared-ui compressImage;四端 upload + mini 头像 |
|
||||||
| 文档 | ✅ | PRD §0.5 + v3.4.13 开发文档 |
|
| 文档 | ✅ | PRD §0.5 + v3.4.13 开发文档 |
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
| 页面 | 行为 |
|
| 页面 | 行为 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 订单详情 | 状态为**配送中**(`SHIPPING`/`SHIPPED`)时,状态下方展示最新一条路由信息;右侧「物流详情」进入详情页 |
|
| 订单详情 | 状态为**配送中**(`SHIPPING`/`SHIPPED`)时,状态下方展示最新一条路由信息;右侧「物流详情」进入详情页 |
|
||||||
| 物流详情 | 配送方式、运单号、完整物流动态时间线(状态名 + 描述 + 时间);最新节点高亮 |
|
| 物流详情 | 物流信息 + 完整动态时间线(**最新在上**);无顶部配送状态区块;自定义导航栏无顶空白 |
|
||||||
| 接口 | `GET /trade/orders/:id` + `GET /trade/orders/:id/track`;`shouldLoadOrderTrack`:有运单号或小飞侠 provider 时拉路由 |
|
| 接口 | `GET /trade/orders/:id` + `GET /trade/orders/:id/track`;`shouldLoadOrderTrack`:有运单号或小飞侠 provider 时拉路由 |
|
||||||
| 公共模块 | `apps/mini-user/src/lib/order-logistics.ts` |
|
| 公共模块 | `apps/mini-user/src/lib/order-logistics.ts` |
|
||||||
|
|
||||||
@@ -70,6 +70,6 @@
|
|||||||
- [ ] 技术支持可创建/筛选/编辑优先级
|
- [ ] 技术支持可创建/筛选/编辑优先级
|
||||||
- [ ] 合伙人/门店登录空字段前端提示;暂停合伙人微信登录被拒
|
- [ ] 合伙人/门店登录空字段前端提示;暂停合伙人微信登录被拒
|
||||||
- [ ] mini-user:电话脱敏、拨打埋点、提货确认、无分享按钮、首图 preview、门头/套餐正常
|
- [ ] mini-user:电话脱敏、拨打埋点、提货确认、无分享按钮、首图 preview、门头/套餐正常
|
||||||
- [ ] mini-user:低版本弹窗、UpdateManager;配送中展示最新物流 + 物流详情页完整时间线(小飞侠路由)
|
- [ ] mini-user:低版本弹窗、UpdateManager;配送中展示最新物流 + 物流详情页(最新在上、无顶空白)
|
||||||
- [ ] 各端上传 >10MB 图片自动压缩后可上传;仍超限有明确报错
|
- [ ] 各端上传 >10MB 图片自动压缩后可上传;仍超限有明确报错
|
||||||
- [ ] `pnpm lint` 无新增错误
|
- [ ] `pnpm lint` 无新增错误
|
||||||
|
|||||||
Reference in New Issue
Block a user