docs: explain dashboard panels data and display boundaries

This commit is contained in:
cieanyau committed 2026-11-06 00:37:46 +08:00
1 parent 631fe30012
commit 145d04e9db
9 files changed
+39

No files matched your search

+8
View File
@@ -1,4 +1,8 @@
<script>
/**
* 首页消费趋势:账户汇总来自会话总览,折线图则仅将交易第一页最多 200 条记录按近六个月归集。
* 两者统计来源不同,图表不能作为完整账务报表使用。
*/
import "~/assets/styles/ChartBox.CYP_mhat.css";
import "~/assets/styles/HomeConsumeTrend.DfrmEdD9.css";
import { toDisplayString } from "vue";
@@ -67,6 +71,7 @@ var x = {
F = ref([]),
I = ref(!0),
L = ref(``);
// 月份键包含年份,跨年时不会把不同年份的同名月份合并。
function R(e) {
let t = new Date();
return Array.from(
@@ -86,6 +91,7 @@ var x = {
},
);
}
// 按秒级 create_time 归入本地月份;没有记录的月份保持为零,图表只反映此页返回的记录。
onMounted(async () => {
try {
let e = await g.get(`/transaction`, {
@@ -109,6 +115,7 @@ var x = {
I.value = !1;
}
});
// 图表选项随月份数据与主题更新,ChartBox 负责图表实例的生命周期。
let z = computed(() => (P.isDark.value ? `#618dff` : `#0052d9`)),
B = computed(() => ({
grid: {
@@ -155,6 +162,7 @@ var x = {
},
],
}));
// 顶部账户汇总与趋势请求分开显示,趋势失败不把账户累计消费改成零。
return (t, r) => {
let a = NuxtLink,
u = skeleton,
@@ -1,4 +1,5 @@
<script>
/** 首页到期提醒:查询未来 7 天内实例,按 due_time 升序展示最多 5 台,并再次过滤请求期间已到期的记录。 */
import "~/assets/styles/HomeExpiringPanel.Ckflw2Hv.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -54,6 +55,7 @@ var b = {
k = ref([]),
A = ref(!0),
j = ref(``);
// 分页收集到足够实例或达到返回总量后停止;最后按到期时间排序并裁剪,不把全部资源一次塞入首页。
onMounted(async () => {
try {
let e = Math.floor(Date.now() / 1e3),
@@ -98,9 +100,11 @@ var b = {
A.value = !1;
}
});
// 秒级到期时间转毫秒后向上取整为提示天数,不修改真实计费截止时间。
function M(e) {
return e ? Math.ceil((e * 1e3 - Date.now()) / 864e5) : 0;
}
// 骨架、错误、空态与有效实例互斥展示;列表每行进入实例详情。
return (n, i) => {
let d = skeleton,
h = ListEmpty,
+7
View File
@@ -1,4 +1,8 @@
<script>
/**
* 首页公告:最多 5 条,详情弹窗另行请求正文。列表与详情序号独立,卸载后废弃旧响应。
* 刷新失败保留旧列表但禁止交互,避免把旧内容当作最新成功结果。
*/
import "~/assets/styles/HomeNoticePanel.e5-qgzAs.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -76,6 +80,7 @@ var O = [`aria-busy`],
Y = ref(``),
X = ref(null),
Z = 0;
// 互斥加载;已加载标记区分首次失败与刷新失败,后者保留原数据并提供重试。
async function Q() {
if (W) return;
let e = ++G;
@@ -98,6 +103,7 @@ var O = [`aria-busy`],
onBeforeUnmount(() => {
(G++, Z++);
}));
// 切换详情先清空旧正文,再按最新请求序号接纳结果;已删除公告明确报错。
async function $(e) {
let t = ++Z;
((K.value = !0),
@@ -118,6 +124,7 @@ var O = [`aria-busy`],
t === Z && (J.value = !1);
}
}
// 正文经过公共 sanitizeHtml 清理再注入;列表出错时 inert 关闭旧条目交互。
return (n, r) => {
let a = NuxtLink,
m = button,
@@ -1,4 +1,5 @@
<script>
/** 首页推介摘要:区分申请权限、已开通和加载失败,永久关系模式额外展示邀请人数,所有入口转入完整推介页。 */
import "~/assets/styles/HomeReferralPanel.DsgN33ME.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -100,6 +101,7 @@ var x = [`aria-busy`],
value: I.value?.withdrawn_amount,
},
]);
// 金额固定两位小数,人数要求非负整数;缺失或非有限值显示占位,不冒充零值。
function W(e, t = !0) {
if (
(typeof e != `number` && typeof e != `string`) ||
@@ -115,6 +117,7 @@ var x = [`aria-busy`],
maximumFractionDigits: t ? 2 : 0,
});
}
// 请求有 10 秒截止时间;无链接时必须有明确的 0/1 权限,否则不展示错误的开通状态。
async function G() {
if (!z) {
((z = !0), (L.value = !0), (R.value = ``));
@@ -140,6 +143,7 @@ var x = [`aria-busy`],
}
return (
onMounted(G),
// 加载、错误、已开通和未开通分支互斥;未知金额不显示货币前缀。
(n, r) => {
let o = Icon,
f = NuxtLink,
+4
View File
@@ -1,4 +1,5 @@
<script>
/** 首页服务器:云/物理模块组各有查询器,每页 5 台;类型与页码形成签名,切换后不能沿用另一页的数据。 */
import "~/assets/styles/HomeServerPanel.Do7AgMDx.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -93,6 +94,7 @@ var ne = [`aria-busy`],
X = ref(0),
Z = 0,
Q = ``;
// 新查询清空不匹配的旧页;同一查询重试失败可保留旧数据,但只有最新代次可更新状态。
async function $() {
let e = ++Z,
t = JSON.stringify([W.value, Y.value]);
@@ -117,6 +119,7 @@ var ne = [`aria-busy`],
e === Z && (K.value = !1);
}
}
// 加载中或列表出错时不继续分页,零基分页器事件转换为接口一基页码。
function re(e) {
if (!(K.value || J.value)) return ((Y.value = e.page + 1), $());
}
@@ -128,6 +131,7 @@ var ne = [`aria-busy`],
onUnmounted(() => {
Z += 1;
}),
// 错误时旧列表/分页使用 inert 禁止交互,重试入口仍可用;各实例展示计费状态与到期日。
(n, r) => {
let a = NuxtLink,
s = button,
+3
View File
@@ -1,4 +1,5 @@
<script>
/** 首页工单:读取第一页最多 5 条,显示回复时间与服务端状态;请求代次隔离重试和卸载,已有数据的失败不伪装成空列表。 */
import "~/assets/styles/HomeTicketPanel.LxPesukM.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -58,6 +59,7 @@ var T = [`aria-busy`],
F = ref(!1),
I = ref(``),
L = 0;
// 仅当前请求可以更新列表与加载标记,离页时提升 L 使旧回调失效。
async function R() {
let e = ++L;
((P.value = !0), (I.value = ``));
@@ -80,6 +82,7 @@ var T = [`aria-busy`],
onBeforeUnmount(() => {
L++;
}),
// 出错时提供重试并锁定旧工单条目,创建与查看全部入口保留。
(n, r) => {
let a = NuxtLink,
p = button,
+3
View File
@@ -1,4 +1,5 @@
<script>
/** 首页工单统计:状态字典与数量映射按状态 ID 关联;只展示响应中实际包含的状态,点击进入相应筛选列表。 */
import "~/assets/styles/HomeTicketStat.C4kzybrY.css";
import { toDisplayString } from "vue";
import { renderList } from "vue";
@@ -51,6 +52,7 @@ var x = {
O = ref({}),
k = ref(!0),
A = ref(``);
// 名称、颜色和数量需同时加载成功,任一请求失败则展示错误,避免统计字典错配。
onMounted(async () => {
try {
let [e, t] = await Promise.all([
@@ -72,6 +74,7 @@ var x = {
count: O.value[e.id] ?? 0,
})),
);
// 区分加载、异常、空态和有效统计,不把缺失数量当成已确认零工单。
return (n, i) => {
let o = NuxtLink,
f = skeleton,
+4
View File
@@ -1,4 +1,5 @@
<script>
/** 首页钱包:余额来自当前会话总览,充值与提现入口分别读取配置;弹窗成功后重新查询余额,不在本地自行加减。 */
import "~/assets/styles/WithdrawDialog.ks0wdKEK.css";
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
import "~/assets/styles/RechargeDialog.DpsMly4r.css";
@@ -54,12 +55,15 @@ var C = {
{ enabled: j, load: M } = useWithdrawAvailability_t(),
N = ref(!1),
P = ref(!1);
// 配置控制入口展示,不能替代服务端对充值/提现请求的最终校验。
onMounted(() => {
(A().catch(() => {}), M());
});
// 两个弹窗共用刷新回调;刷新失败不猜测操作后的余额。
async function F() {
await v.refreshOverview().catch(() => {});
}
// 总览未返回时显示骨架而非零余额,充值/提现各自维护可见状态。
return (t, i) => {
let d = NuxtLink,
h = skeleton,
+2
View File
@@ -1,4 +1,5 @@
<script>
/** 首页装饰吉祥物:固定静态节点配合 CSS 绘制,不请求业务数据;aria-hidden 避免辅助技术重复朗读装饰。 */
import "~/assets/styles/RoxyMascot.CDqPSf2d.css";
import { createStaticVNode } from "vue";
import { createElementBlock } from "vue";
@@ -9,6 +10,7 @@ var i = {},
class: `roxy-mascot`,
"aria-hidden": `true`,
};
// 静态树使用渲染缓存复用,data-v 作用域与既有样式配套,不应单独移除。
function o(r, i) {
return (
openBlock(),