管理端开发日记①:订单列表与状态筛选

1500 字
8 分钟
管理端开发日记①:订单列表与状态筛选

订单列表看起来只是“搜索框加表格”,但它其实是管理端最重要的业务入口:审核、调度、配送、完成和异常都从这里分流。今天就把这个不起眼、但每天都要被点开很多次的页面拆开看看。

1. 页面承担的职责#

订单列表主要位于 src/views/manage/delivery-order/index.vue,接口封装位于 src/api/manage/deliveryOrder.js。页面没有把所有操作都塞进弹窗,而是负责四件事:

  1. 按订单号、船名和状态筛选订单;
  2. 以服务类型和状态标签快速呈现业务差异;
  3. 根据当前状态给出合法操作;
  4. 把复杂业务交给订单详情页继续处理。

这种分工很重要。列表页适合“找数据”和“做决策”,详情页才适合展示凭证、轨迹、流程日志等重信息。

2. 查询模型要和分页模型放在一起#

页面使用统一的查询对象保存筛选条件和分页信息:

const queryParams = reactive({
pageNum: 1,
pageSize: 10,
orderNo: undefined,
vesselName: undefined,
orderStatus: undefined,
orderByColumn: 'createTime',
isAsc: 'desc'
})

查询按钮并不是直接重新请求,而是先回到第一页:

function handleQuery() {
queryParams.pageNum = 1
getList()
}
async function getList() {
loading.value = true
try {
const response = await listDeliveryOrder(queryParams)
orderList.value = response.rows || []
total.value = Number(response.total || 0)
} finally {
loading.value = false
}
}

如果用户原本停在第 8 页,再加一个筛选条件后仍请求第 8 页,很容易得到“没有数据”的假象。把筛选条件与分页状态放在同一个模型中,可以明确每次请求到底携带了什么。

3. 状态不是文字,而是业务规则#

当前订单状态包括:

状态值页面含义主要操作
UNPAID待支付查看详情
PENDING_AUDIT待审核审核、驳回
WAIT_DISPATCH待调度取消、开始飞行
DELIVERING配送中完成配送、配送失败
COMPLETED已完成查看详情
DELIVERY_FAILED配送失败查看异常和流程
CANCELED已取消查看详情
REJECTED已驳回查看驳回原因

我最初容易把状态处理写成模板里的大量 v-if。后来将“标签颜色”和“允许操作”分别抽成映射,让模板只负责渲染:

const statusMeta = {
PENDING_AUDIT: { label: '待审核', type: 'warning' },
WAIT_DISPATCH: { label: '待调度', type: 'primary' },
DELIVERING: { label: '配送中', type: 'success' },
COMPLETED: { label: '已完成', type: 'info' }
}
const rowActions = {
PENDING_AUDIT: ['detail', 'audit'],
WAIT_DISPATCH: ['detail', 'startFlight'],
DELIVERING: ['detail', 'deliveryResult'],
COMPLETED: ['detail']
}

状态表的价值不只是少写几行代码。新增状态时,开发者可以从一个入口检查“显示什么、允许做什么”,不必在整张模板里寻找条件分支。

4. 表格字段体现业务优先级#

订单数据很多,但列表只展示快速判断所需的信息:订单号、来源单号或快递单号、服务类型、来源平台、船名、收货人、MMSI、手机号、状态和创建时间。

订单号设置为可点击文本,点击后进入详情。服务类型则把 EXPRESS、TAKEOUT 转成“快递配送”和“外卖配送”。类似转换不应散落在每个单元格中,可以统一封装:

function serviceTypeText(value) {
return value === 'EXPRESS' ? '快递配送'
: value === 'TAKEOUT' ? '外卖配送'
: '-'
}

列表中不直接展示数据库自增 ID。自增 ID 适合前后端定位记录,订单号才适合客服、调度员和用户沟通,这也是业务标识与技术标识必须区分的地方。

5. 操作入口为什么跳转详情页#

审核需要查看订单照片,起飞需要核对航线和无人机,配送完成需要上传或查看签收凭证。因此列表中的“审核”“开始飞行”最终都进入同一个详情页,只是详情页会根据状态展示不同按钮。

function openDetail(row) {
router.push(`/manage/delivery-order/detail/${row.orderId}`)
}

详情路由挂在管理端的 Layout 下面,并通过 activeMenu 保持订单菜单高亮。这样页面跳转后,顶部标题栏和侧边导航不会消失,用户也不会突然从管理系统的框架中“掉出去”。

6. 导出应复用当前筛选条件#

导出不是导出全部数据,而是导出用户当前看到的业务范围:

function handleExport() {
proxy.download(
'/manage/admin/delivery-order/export',
{ ...queryParams },
`订单_${Date.now()}.xlsx`
)
}

这能保证页面筛选和报表口径一致。若导出接口另写一套参数,很容易出现“列表 16 条、Excel 200 条”的尴尬场面。

7. 本篇小结#

在联调阶段,我还专门检查了几个很容易遗漏的边界:查询接口返回空 rows 时仍要保留正确的 total;删除最后一页唯一记录后需要退回上一页;手机号、MMSI 等敏感列要根据权限决定是否完整展示;连续点击查询时不让旧请求覆盖新结果。列表页虽然没有复杂动画,却是并发操作最频繁的页面之一。

接口层也保持“一个方法表达一个业务动作”,例如 approveDeliveryOrder、rejectDeliveryOrder、startFlight,而不是让页面到处调用通用 put。这样看到调用名就知道它会改变什么状态,也方便后续增加权限确认和敏感操作审计。

最后,我用下面这条数据流检查整个页面:

筛选表单 → queryParams → list API → rows/total
↓ ↓
重置页码 状态元数据
↓
表格标签与合法操作
↓
Layout 下的订单详情路由

订单列表真正困难的部分不是表格,而是把查询、分页、枚举、操作权限和路由上下文组织成一套稳定规则。写完后我对它的评价是:长得最朴素,管得却最多,像办公室里那个不声不响但谁都离不开的同事。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
管理端开发日记①:订单列表与状态筛选
https://firefly.cuteleaf.cn/posts/admin-dev-diary-1/
作者
Yore
发布于
2026-08-01
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Yore
Hello, I'm Yore.
公告
欢迎来到Yore的博客!本站基于原创作者夏叶的博客网站模版创作。
分类
标签
最新动态
站点统计
文章
51
分类
2
标签
124
总字数
94,115
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.15.0
文章许可
CC BY-NC-SA 4.0