Files
console-dev/app/components/home/HomeConsumeTrend.vue
T

304 lines
9.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script>
/**
* 首页消费趋势:账户汇总来自会话总览,折线图则仅将交易第一页最多 200 条记录按近六个月归集。
* 两者统计来源不同,图表不能作为完整账务报表使用。
*/
import "~/assets/styles/ChartBox.CYP_mhat.css";
import "~/assets/styles/HomeConsumeTrend.DfrmEdD9.css";
import { toDisplayString } from "vue";
import { onMounted } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { computed } from "vue";
import { createElementBlock } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { NuxtLink } from "#components";
import { useApi } from "~/lib/auth.js";
import { useAuth } from "~/lib/auth.js";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import { t as useTheme_t } from "~/lib/useTheme.js";
import ChartBox from "~/components/ChartBox.vue";
import ListEmpty from "~/components/ListEmpty.vue";
import skeleton from "primevue/skeleton";
var x = {
class: `home-card`,
},
S = {
class: `home-card-head`,
},
C = {
class: `home-mini-stats`,
},
w = {
class: `home-mini-stat`,
},
T = {
class: `home-mini-value`,
},
E = {
class: `home-mini-stat`,
},
D = {
class: `home-mini-value`,
},
O = {
class: `home-mini-stat`,
},
k = {
class: `home-mini-value`,
},
A = {
class: `chart-wrap`,
},
j = {
key: 0,
},
M = 6,
N = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `HomeConsumeTrend`,
setup(u) {
let g = useApi(),
N = useAuth(),
P = useTheme_t(),
F = ref([]),
I = ref(!0),
L = ref(``);
// 月份键包含年份,跨年时不会把不同年份的同名月份合并。
function R(e) {
let t = new Date();
return Array.from(
{
length: e,
},
(n, r) => {
let i = new Date(
t.getFullYear(),
t.getMonth() - (e - 1 - r),
1,
);
return {
key: `${i.getFullYear()}-${i.getMonth() + 1}`,
label: `${i.getMonth() + 1}月`,
};
},
);
}
// 按秒级 create_time 归入本地月份;没有记录的月份保持为零,图表只反映此页返回的记录。
onMounted(async () => {
try {
let e = await g.get(`/transaction`, {
page: 1,
limit: 200,
}),
t = R(M),
n = new Map(t.map((e) => [e.key, 0]));
for (let t of e.list ?? []) {
let e = new Date((t.create_time || 0) * 1e3),
r = `${e.getFullYear()}-${e.getMonth() + 1}`;
n.has(r) && n.set(r, (n.get(r) ?? 0) + Number(t.amount || 0));
}
F.value = t.map((e) => ({
label: e.label,
amount: Math.round((n.get(e.key) ?? 0) * 100) / 100,
}));
} catch (e) {
L.value = e instanceof Error ? e.message : `消费记录加载失败`;
} finally {
I.value = !1;
}
});
// 图表选项随月份数据与主题更新,ChartBox 负责图表实例的生命周期。
let z = computed(() => (P.isDark.value ? `#618dff` : `#0052d9`)),
B = computed(() => ({
grid: {
left: 4,
right: 8,
top: 16,
bottom: 0,
outerBoundsMode: `same`,
outerBoundsContain: `axisLabel`,
},
tooltip: {
trigger: `axis`,
valueFormatter: (e) => `¥${Number(e ?? 0).toFixed(2)}`,
},
xAxis: {
type: `category`,
boundaryGap: !1,
data: F.value.map((e) => e.label),
},
yAxis: {
type: `value`,
axisLabel: {
formatter: `¥{value}`,
},
},
series: [
{
type: `line`,
smooth: !0,
symbol: `circle`,
symbolSize: 6,
data: F.value.map((e) => e.amount),
itemStyle: {
color: z.value,
},
lineStyle: {
color: z.value,
width: 2,
},
areaStyle: {
color: z.value,
opacity: 0.1,
},
},
],
}));
// 顶部账户汇总与趋势请求分开显示,趋势失败不把账户累计消费改成零。
return (t, r) => {
let a = NuxtLink,
u = skeleton,
m = ListEmpty,
h = ChartBox;
return (
openBlock(),
createElementBlock(`div`, x, [
createElementVNode(`div`, S, [
(r[1] ||= createElementVNode(
`div`,
{
class: `home-card-title`,
},
[
createElementVNode(`i`, {
class: `pi pi-chart-line`,
}),
createTextVNode(`消费趋势`),
],
-1,
)),
createVNode(
a,
{
to: `/finance`,
class: `home-card-more`,
},
{
default: withCtx(() => [
...(r[0] ||= [createTextVNode(`消费记录 ›`, -1)]),
]),
_: 1,
},
),
]),
createElementVNode(`div`, C, [
createElementVNode(`div`, w, [
(r[2] ||= createElementVNode(
`span`,
{
class: `home-mini-label`,
},
`本月消费`,
-1,
)),
createElementVNode(
`span`,
T,
`¥` +
toDisplayString(
unref(N).overview?.this_month_consume ?? `--`,
),
1,
),
]),
createElementVNode(`div`, E, [
(r[3] ||= createElementVNode(
`span`,
{
class: `home-mini-label`,
},
`累计消费`,
-1,
)),
createElementVNode(
`span`,
D,
`¥` + toDisplayString(unref(N).overview?.consume ?? `--`),
1,
),
]),
createElementVNode(`div`, O, [
(r[4] ||= createElementVNode(
`span`,
{
class: `home-mini-label`,
},
`未付订单`,
-1,
)),
createElementVNode(
`span`,
k,
toDisplayString(unref(N).overview?.unpaid_order ?? `--`),
1,
),
]),
]),
createElementVNode(`div`, A, [
unref(I)
? (openBlock(),
createElementBlock(`div`, j, [
createVNode(u, {
height: `150px`,
}),
]))
: unref(L)
? (openBlock(),
createBlock(
m,
{
key: 1,
icon: `pi pi-exclamation-circle`,
title: `消费趋势加载失败`,
description: unref(L),
},
null,
8,
[`description`],
))
: (openBlock(),
createBlock(
h,
{
key: 2,
option: unref(B),
height: 150,
},
null,
8,
[`option`],
)),
]),
])
);
};
},
}),
[[`__scopeId`, `data-v-90c11ad2`]],
),
{
__name: `HomeConsumeTrend`,
},
);
export {};
export default N;
</script>