1
1
<script setup lang='ts'>
2
+ import type { Ref } from ' vue'
2
3
import { nextTick , onMounted , reactive , ref } from ' vue'
3
- import { NCol , NDatePicker , NIcon , NNumberAnimation , NRow , NSpin , NStatistic } from ' naive-ui'
4
+ import { NCol , NDatePicker , NIcon , NNumberAnimation , NRow , NSelect , NSpin , NStatistic } from ' naive-ui'
4
5
import type { ChartData , ChartOptions } from ' chart.js'
5
6
import { BarElement , CategoryScale , Chart as ChartJS , Legend , LinearScale , Title , Tooltip } from ' chart.js'
6
7
import { Bar } from ' vue-chartjs'
7
8
import dayjs from ' dayjs'
9
+ import type { UserInfo } from ' ./model'
8
10
import { t } from ' @/locales'
9
- import { fetchUserStatistics } from ' @/api'
11
+ import { fetchGetUsers , fetchUserStatistics } from ' @/api'
10
12
import { SvgIcon } from ' @/components/common'
13
+ import { useUserStore } from ' @/store'
11
14
12
15
ChartJS .register (Title , Tooltip , Legend , BarElement , CategoryScale , LinearScale )
13
16
17
+ const userStore = useUserStore ()
18
+
14
19
const chartData: ChartData <' bar' > = reactive ({
15
20
labels: [],
16
21
datasets: [
@@ -38,6 +43,10 @@ const summary = ref({
38
43
completionTokens: 0 ,
39
44
totalTokens: 0 ,
40
45
})
46
+
47
+ const usersOptions: Ref <{ label: string ; filter: string ; value: string }[]> = ref ([])
48
+ const user: Ref <string | null > = ref (null )
49
+
41
50
const loading = ref (false )
42
51
const range: any = ref ([
43
52
dayjs ().subtract (30 , ' day' ).startOf (' day' ).valueOf (),
@@ -66,6 +75,7 @@ async function fetchStatistics() {
66
75
try {
67
76
loading .value = true
68
77
const { data } = await fetchUserStatistics (
78
+ user .value as string ,
69
79
dayjs (range .value [0 ]).startOf (' day' ).valueOf (),
70
80
dayjs (range .value [1 ]).endOf (' day' ).valueOf (),
71
81
)
@@ -91,8 +101,25 @@ async function fetchStatistics() {
91
101
}
92
102
}
93
103
104
+ async function fetchUsers() {
105
+ const result = await fetchGetUsers (1 , 10000 )
106
+ result .data .users .forEach ((user : UserInfo ) => {
107
+ usersOptions .value .push ({
108
+ label: ` ${user .email } ` ,
109
+ value: ` ${user ._id } ` ,
110
+ filter: ` ${user .email } ${user .remark } ` ,
111
+ })
112
+ })
113
+ }
114
+
115
+ function filter(pattern : string , option : object ): boolean {
116
+ const a = option as { label: string ; filter: string ; value: string }
117
+ return ! a .filter ? false : a .filter .includes (pattern )
118
+ }
119
+
94
120
onMounted (() => {
95
121
fetchStatistics ()
122
+ fetchUsers ()
96
123
})
97
124
</script >
98
125
@@ -101,7 +128,16 @@ onMounted(() => {
101
128
<div class =" p-4 space-y-5 min-h-[200px]" >
102
129
<div class =" space-y-6" >
103
130
<div class =" flex items-center space-x-4" >
104
- <span class =" flex-shrink-0 w-[100px]" >{{ $t('setting.statisticsPeriod') }}</span >
131
+ <NSelect
132
+ v-if =" userStore.userInfo.root"
133
+ v-model:value =" user"
134
+ style =" width : 250px "
135
+ filterable
136
+ :filter =" filter"
137
+ placeholder =" Email or remark"
138
+ :options =" usersOptions"
139
+ @update-value =" (value) => { user = value; fetchStatistics() }"
140
+ />
105
141
<div class =" flex-1" >
106
142
<NDatePicker
107
143
v-model:value =" range"
0 commit comments