' + escapeHtml(order.product_name || "订单") + "
流水号 " + escapeHtml(order.order_number) + "
/** * Knowledge-payment order center interactions. * * @package AKSRT */ (function () { "use strict"; var instances = new WeakMap(); function request(path, body, method, operationKey) { var options = { method: method || "POST" }; if (body !== undefined) options.body = JSON.stringify(body || {}); if (operationKey) options.headers = { "Idempotency-Key": operationKey }; return window.AksrtRequest.request(path, options); } function orderPath(orderNumber, suffix) { return "/orders/" + encodeURIComponent(orderNumber || "") + (suffix || ""); } function errorMessage(error, fallback) { if (error && error.message) return String(error.message); return fallback || "请求失败"; } function escapeHtml(value) { return String(value == null ? "" : value) .replace(/&/g, "&").replace(//g, ">").replace(/\"/g, """) .replace(/'/g, "'"); } function formatMoney(order) { var raw = String(order && order.amount != null ? order.amount : "0"); if (order && order.is_points) { return escapeHtml(order.currency_symbol || "积分") + " " + (/^\d+$/.test(raw) ? raw : "0"); } var match = /^(0|[1-9]\d*)(?:\.(\d{1,2}))?$/.exec(raw); var amount = match ? match[1] + "." + (match[2] || "").padEnd(2, "0") : "0.00"; return "¥" + amount; } function orderTag(orderNumber) { return "order:" + String(orderNumber || "").toLowerCase(); } function invalidateOrder(orderNumber, order) { var tags = order && Array.isArray(order.invalidation_tags) ? order.invalidation_tags : [ "orders", orderTag(orderNumber), ]; window.AksrtModalRuntime.invalidate(tags); } function activeDetail(state, number) { return state.detailOrderNumber === number && !!state.detailSession && !state.detailSession.closed && state.detailSession.options && state.detailSession.options.kind === "orders" && window.AksrtModalRuntime.getActive() === state.detailSession.shell; } function detailSkeleton() { return '
' + escapeHtml(meta.desc) + "
"; if (status === "pending" && timeLeft > 0) { html += '剩余支付时间 ' + timeLeft + " 秒"; } html += "支付状态可能仍在同步,请刷新后查看。
"; html += ''; html += "订单不存在
'; return; } renderDetail(state, data, session); }, onData: function (data) { if (refresh) { delete state.operationKeys[actionKey]; invalidateOrder(orderNumber, data); } }, }; } function openDetail(state, orderNumber) { if (!orderNumber) return; state.detailSession = null; state.detailReplacement = false; state.detailReplacementSession = null; state.detailOrderNumber = orderNumber; window.AksrtModalRuntime.openRemote(detailOptions(state, orderNumber, false)); } function refreshDetail(state, orderNumber) { if (!orderNumber || !activeDetail(state, orderNumber)) return; state.detailReplacement = true; state.detailReplacementSession = state.detailSession; var refreshPromise = window.AksrtModalRuntime.openRemote(detailOptions(state, orderNumber, true)); refreshPromise.then(function () { state.detailReplacement = false; state.detailReplacementSession = null; }, function () { state.detailReplacement = false; state.detailReplacementSession = null; }); } function currentViewPath(state) { var query = new URLSearchParams(); if (state.query.status && state.query.status !== "all") query.set("order_status", state.query.status); if (state.query.type) query.set("order_type", state.query.type); if (state.query.orderNumber) query.set("order_number", state.query.orderNumber); if (Number(state.query.page) > 1) query.set("order_page", String(state.query.page)); return "/orders/view" + (query.toString() ? "?" + query.toString() : ""); } function actionHtml(order) { var allowedActions = order.allowed_actions || {}; var html = ''; if (allowedActions.can_cancel) html += ''; if (allowedActions.can_pay) html += ''; return html; } function cardHtml(order) { var image = order.image ? '流水号 " + escapeHtml(order.order_number) + "
换个条件试试,或清除当前筛选。
'; list.classList.remove("aksrt-orders-page__list"); list.classList.add("aksrt-orders-page__empty"); } else { list.classList.remove("aksrt-orders-page__empty"); list.classList.add("aksrt-orders-page__list"); list.innerHTML = items.map(cardHtml).join(""); } renderPagination(state, view); syncControls(state); updateCountdowns(state); } function syncControls(state) { state.root.querySelectorAll("[data-aksrt-order-filter]").forEach(function (button) { var field = button.getAttribute("data-aksrt-order-filter"); var expected = field === "status" ? state.query.status : state.query.type; var active = button.getAttribute("data-aksrt-order-filter-value") === expected; button.classList.toggle("is-active", active); button.setAttribute("aria-pressed", active ? "true" : "false"); }); var input = state.root.querySelector("#aksrt-order-number"); if (input && input.value !== state.query.orderNumber) input.value = state.query.orderNumber; } function setViewLoading(state, loading) { state.root.classList.toggle("is-loading", loading); state.root.setAttribute("aria-busy", loading ? "true" : "false"); } function loadView(state, patch) { Object.keys(patch || {}).forEach(function (key) { state.query[key] = patch[key]; }); var requestId = ++state.viewRequest; setViewLoading(state, true); return request(currentViewPath(state), undefined, "GET").then(function (result) { if (requestId !== state.viewRequest) return null; if (!result || !result.data) throw new Error("刷新失败"); renderView(state, result.data); return result.data; }).catch(function (error) { if (requestId === state.viewRequest) notyf(errorMessage(error, "订单加载失败,请稍后重试"), "danger"); return null; }).finally(function () { if (requestId === state.viewRequest) setViewLoading(state, false); }); } function refreshView(state) { return loadView(state); } function startPayment(state, button) { var number = button.getAttribute("data-aksrt-order-pay") || ""; var method = button.getAttribute("data-aksrt-order-method") || ""; if (!number || button.disabled) return; var actionKey = "pay:" + number; if (!state.operationKeys[actionKey]) state.operationKeys[actionKey] = window.AksrtRequest.createIdempotencyKey(); button.disabled = true; request(orderPath(number, "/pay"), method ? { payment_method: method } : {}, "POST", state.operationKeys[actionKey]).then(function (result) { delete state.operationKeys[actionKey]; var data = result.data || {}; invalidateOrder(number, data.order); if (data.redirect && data.payment_url) { window.location.assign(data.payment_url); return; } notyf(data.message || "支付成功", "success"); refreshView(state); if (activeDetail(state, number)) openDetail(state, number); }).catch(function (error) { button.disabled = false; notyf(errorMessage(error, "网络错误,请稍后重试"), "danger"); }); } function closeOrder(state, button) { var number = button.getAttribute("data-aksrt-order-cancel") || ""; if (!number || button.disabled) return; if (button.getAttribute("data-aksrt-confirm") !== "true") { button.setAttribute("data-aksrt-confirm", "true"); button.textContent = "确认关闭"; return; } button.disabled = true; var actionKey = "cancel:" + number; if (!state.operationKeys[actionKey]) state.operationKeys[actionKey] = window.AksrtRequest.createIdempotencyKey(); request(orderPath(number, "/cancel"), {}, "POST", state.operationKeys[actionKey]).then(function (result) { delete state.operationKeys[actionKey]; var data = result.data || {}; invalidateOrder(number, data.order); notyf("订单已关闭", "success"); refreshView(state); if (activeDetail(state, number)) openDetail(state, number); }).catch(function (error) { button.disabled = false; button.removeAttribute("data-aksrt-confirm"); button.textContent = "关闭订单"; notyf(errorMessage(error, "网络错误,请稍后重试"), "danger"); }); } function copyOrderValue(button) { var value = button.getAttribute("data-aksrt-order-copy") || ""; if (!value) return; var icon = button.querySelector("i"); var settle = function (ok) { notyf(ok ? "流水号已复制" : "复制失败,请手动选择复制", ok ? "success" : "danger"); if (!ok) return; button.classList.add("is-copied"); if (icon) icon.className = "fa fas fa-check"; window.setTimeout(function () { button.classList.remove("is-copied"); if (icon) icon.className = "fa fas fa-copy"; }, 1600); }; var fallback = function () { try { var field = document.createElement("textarea"); field.value = value; field.setAttribute("readonly", "readonly"); field.style.position = "fixed"; field.style.top = "-1000px"; field.style.opacity = "0"; document.body.appendChild(field); field.select(); document.execCommand("copy"); document.body.removeChild(field); settle(true); } catch (error) { settle(false); } }; if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(value).then(function () { settle(true); }, fallback); return; } fallback(); } function closest(target, selector) { return target && target.closest ? target.closest(selector) : null; } function initRoot(root) { if (instances.has(root)) return; var state = { root: root, detailOrderNumber: "", detailSession: null, detailReplacement: false, detailReplacementSession: null, countdownTimer: null, operationKeys: {}, query: { status: "all", type: "", orderNumber: "", page: 1 }, viewRequest: 0, }; state.onRootClick = function (event) { var filterToggle = closest(event.target, "[data-aksrt-orders-filter-toggle]"); if (filterToggle && root.contains(filterToggle)) { var panel = root.querySelector("[data-aksrt-orders-filter-panel]"); var expanded = filterToggle.getAttribute("aria-expanded") === "true"; filterToggle.setAttribute("aria-expanded", String(!expanded)); if (panel) panel.hidden = expanded; return; } var filter = closest(event.target, "[data-aksrt-order-filter]"); if (filter && root.contains(filter)) { event.preventDefault(); var field = filter.getAttribute("data-aksrt-order-filter"); var patch = { page: 1 }; patch[field] = filter.getAttribute("data-aksrt-order-filter-value") || ""; loadView(state, patch); return; } var page = closest(event.target, "[data-aksrt-order-page]"); if (page && root.contains(page)) { event.preventDefault(); loadView(state, { page: Math.max(1, Number(page.getAttribute("data-aksrt-order-page") || 1)) }); return; } var clear = closest(event.target, "[data-aksrt-orders-clear]"); if (clear && root.contains(clear)) { event.preventDefault(); loadView(state, { status: "all", type: "", orderNumber: "", page: 1 }); return; } var detail = closest(event.target, "[data-aksrt-order-detail]"); if (detail && root.contains(detail)) { openDetail(state, detail.getAttribute("data-aksrt-order-detail")); return; } var pay = closest(event.target, "[data-aksrt-order-pay]"); if (pay && root.contains(pay)) { event.preventDefault(); startPayment(state, pay); return; } var cancel = closest(event.target, "[data-aksrt-order-cancel]"); if (cancel && root.contains(cancel)) { event.preventDefault(); closeOrder(state, cancel); } }; state.onRootSubmit = function (event) { var form = closest(event.target, "[data-aksrt-orders-search]"); if (!form || !root.contains(form)) return; event.preventDefault(); var input = form.querySelector("#aksrt-order-number"); loadView(state, { orderNumber: input ? String(input.value || "").trim() : "", page: 1 }); }; state.onModalClose = function (event) { var detail = event && event.detail ? event.detail : {}; if (!state.detailSession || detail.session !== state.detailSession) return; if (detail.reason === "replace" && state.detailReplacement && detail.session === state.detailReplacementSession) return; state.detailSession = null; state.detailOrderNumber = ""; state.detailReplacement = false; state.detailReplacementSession = null; }; state.onDocumentClick = function (event) { if (!state.detailSession || window.AksrtModalRuntime.getActive() !== state.detailSession.shell) return; var copy = closest(event.target, "[data-aksrt-order-copy]"); if (copy) { event.preventDefault(); copyOrderValue(copy); return; } var refresh = closest(event.target, "[data-aksrt-order-refresh]"); if (refresh) { event.preventDefault(); refreshDetail(state, refresh.getAttribute("data-aksrt-order-refresh") || ""); return; } var pay = closest(event.target, "[data-aksrt-order-pay]"); if (pay && !root.contains(pay)) { event.preventDefault(); startPayment(state, pay); return; } var cancel = closest(event.target, "[data-aksrt-order-cancel]"); if (cancel && !root.contains(cancel)) { event.preventDefault(); closeOrder(state, cancel); } }; root.addEventListener("click", state.onRootClick); root.addEventListener("submit", state.onRootSubmit); document.addEventListener("aksrt:modal:close", state.onModalClose); document.addEventListener("click", state.onDocumentClick); state.countdownTimer = window.setInterval(function () { updateCountdowns(state); }, 1000); instances.set(root, state); } function rootsIn(root) { if (!root) return []; var roots = []; if (root.matches && root.matches("[data-aksrt-order-center]")) roots.push(root); if (root.querySelectorAll) root.querySelectorAll("[data-aksrt-order-center]").forEach(function (item) { roots.push(item); }); return roots; } function init(root) { rootsIn(root || document).forEach(initRoot); } function destroy(root) { rootsIn(root).forEach(function (item) { var state = instances.get(item); if (!state) return; if (activeDetail(state, state.detailOrderNumber)) window.AksrtModalRuntime.close("replace"); item.removeEventListener("click", state.onRootClick); item.removeEventListener("submit", state.onRootSubmit); document.removeEventListener("aksrt:modal:close", state.onModalClose); document.removeEventListener("click", state.onDocumentClick); window.clearInterval(state.countdownTimer); instances.delete(item); }); } window.AKSRTOrderCenter = { init: init, destroy: destroy }; jQuery(document).off("auto_fun.aksrt-order-center").on("auto_fun.aksrt-order-center", function () { init(document); }); }());