fix(orders): wire detail progress timeline and two-step cancel

Order progress was stuck on "订单创建" because timeline only read sparse
timestamp columns and status transitions didn't always stamp them.
Drive timeline from current status + related records, backfill lifecycle
timestamps on update_status, and replace window.confirm cancel with a
关闭订单 → 确认取消 button step in the detail modal.
This commit is contained in:
kate522 committed 2026-07-27 15:15:35 +08:00
1 parent 64d0dc66da
commit ad40d9a7ca
4 files changed
+327 -61

No files matched your search

+48 -7
View File
@@ -637,7 +637,8 @@
var footer = "";
// Status-aware footer. Top-right ✕ is the only generic dismiss control.
if (actions.can_cancel) {
footer += '<button type="button" class="btn-ghost" data-aksrt-order-cancel="' + escapeHtml(order.order_number) + '">关闭订单</button>';
// Two-step cancel inside the modal — no window.confirm.
footer += '<button type="button" class="btn-ghost" data-aksrt-order-cancel="' + escapeHtml(order.order_number) + '" data-aksrt-cancel-step="1">关闭订单</button>';
}
if (actions.can_receipt) {
footer += '<button type="button" class="btn-primary" data-aksrt-order-receipt="' + escapeHtml(order.order_number) + '">确认收货</button>';
@@ -919,21 +920,51 @@
return;
}
// Cancel
// Cancel — two-step in detail modal (关闭订单 → 确认取消), list card same.
var cancelButton = event.target.closest("[data-aksrt-order-cancel]");
if (cancelButton) {
var cancelOrderNumber = cancelButton.getAttribute("data-aksrt-order-cancel");
if (!window.confirm("确认关闭该订单?关闭后不可再支付。")) {
if (!cancelOrderNumber) return;
// First click: transform into "确认取消" (no browser confirm dialog).
var step = cancelButton.getAttribute("data-aksrt-cancel-step") || "1";
if (step !== "2") {
cancelButton.setAttribute("data-aksrt-cancel-step", "2");
cancelButton.classList.remove("btn-ghost");
cancelButton.classList.add("btn-primary", "is-cancel-confirm");
cancelButton.textContent = "确认取消";
// Auto-reset if user doesn't confirm within a few seconds.
if (cancelButton._aksrtCancelReset) {
window.clearTimeout(cancelButton._aksrtCancelReset);
}
cancelButton._aksrtCancelReset = window.setTimeout(function () {
if (!cancelButton.isConnected) return;
if (cancelButton.getAttribute("data-aksrt-cancel-step") !== "2") return;
cancelButton.setAttribute("data-aksrt-cancel-step", "1");
cancelButton.classList.add("btn-ghost");
cancelButton.classList.remove("btn-primary", "is-cancel-confirm");
// Detail modal uses "关闭订单"; list cards use "取消".
var inDetail = !!(detailModal && detailModal.contains(cancelButton));
cancelButton.textContent = inDetail ? "关闭订单" : "取消";
}, 5000);
return;
}
var cancelLabel = cancelButton.textContent || "取消";
if (cancelButton._aksrtCancelReset) {
window.clearTimeout(cancelButton._aksrtCancelReset);
cancelButton._aksrtCancelReset = null;
}
cancelButton.disabled = true;
cancelButton.textContent = "取消中...";
request(orderPath(cancelOrderNumber, "/cancel"))
.then(function (result) {
if (!result.success) {
cancelButton.disabled = false;
cancelButton.textContent = cancelLabel;
cancelButton.setAttribute("data-aksrt-cancel-step", "1");
cancelButton.classList.add("btn-ghost");
cancelButton.classList.remove("btn-primary", "is-cancel-confirm");
var inDetailFail = !!(detailModal && detailModal.contains(cancelButton));
cancelButton.textContent = inDetailFail ? "关闭订单" : "取消";
showToast(result.message || "取消失败。");
return;
}
@@ -941,12 +972,22 @@
var card = findOrderCard(cancelOrderNumber);
updateCardStatus(card, "cancelled", "已取消");
if (detailOrderNumber === cancelOrderNumber) {
closeOrderDetailModal();
// Refresh modal body with cancelled timeline, then close shortly.
if (result.data && result.data.order) {
renderOrderDetail(result.data.order);
}
window.setTimeout(function () {
closeOrderDetailModal();
}, 600);
}
})
.catch(function () {
cancelButton.disabled = false;
cancelButton.textContent = cancelLabel;
cancelButton.setAttribute("data-aksrt-cancel-step", "1");
cancelButton.classList.add("btn-ghost");
cancelButton.classList.remove("btn-primary", "is-cancel-confirm");
var inDetailErr = !!(detailModal && detailModal.contains(cancelButton));
cancelButton.textContent = inDetailErr ? "关闭订单" : "取消";
showToast("网络错误,请稍后重试。");
});
return;