ssvfdn 3 месяцев назад
Родитель
Сommit
4b79dc2944

BIN
apps/web-antd/dist.zip


+ 17 - 0
apps/web-antd/src/api/data_statistics/rank_bet.ts

@@ -0,0 +1,17 @@
+import {requestClient} from "#/api/request";
+
+interface ApiResultListData {
+    data: Object;
+    status: number;
+    total: number;
+    list: Array<any>;
+}
+
+/**
+ * 获取转账记录列表
+ */
+export async function getRankBetList(data:any) {
+    const params = new URLSearchParams(data); // 创建一个新的URLSearchParams对象
+    const queryString = params.toString(); // 转换为查询字符串
+    return requestClient.get<ApiResultListData>('/rank_list/bet_amount?' + queryString);
+}

+ 17 - 0
apps/web-antd/src/api/data_statistics/rank_lose.ts

@@ -0,0 +1,17 @@
+import {requestClient} from "#/api/request";
+
+interface ApiResultListData {
+    data: Object;
+    status: number;
+    total: number;
+    list: Array<any>;
+}
+
+/**
+ * 获取转账记录列表
+ */
+export async function getRankLoseList(data:any) {
+    const params = new URLSearchParams(data); // 创建一个新的URLSearchParams对象
+    const queryString = params.toString(); // 转换为查询字符串
+    return requestClient.get<ApiResultListData>('/rank_list/lose_amount?' + queryString);
+}

+ 17 - 0
apps/web-antd/src/api/data_statistics/rank_win.ts

@@ -0,0 +1,17 @@
+import {requestClient} from "#/api/request";
+
+interface ApiResultListData {
+    data: Object;
+    status: number;
+    total: number;
+    list: Array<any>;
+}
+
+/**
+ * 获取转账记录列表
+ */
+export async function getRankWinList(data:any) {
+    const params = new URLSearchParams(data); // 创建一个新的URLSearchParams对象
+    const queryString = params.toString(); // 转换为查询字符串
+    return requestClient.get<ApiResultListData>('/rank_list/win_amount?' + queryString);
+}

+ 2 - 2
apps/web-antd/src/api/request.ts

@@ -116,13 +116,13 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
 export const requestClient = createRequestClient(apiURL, {
   responseReturn: 'data',
     withCredentials: true,
-    timeout:30 * 1000,
+    timeout: 60 * 1000,
 });
 // 获取body内容,拿全的内容如data,message, code, state {"state":1,"code":0,"data":[],"message":"更新游戏成功"}
 export const requestBodyClient = createRequestClient(apiURL, {
     responseReturn: 'body',
     withCredentials: true,
-    timeout:30 * 1000,
+    timeout: 60 * 1000,
 });
 
 export const baseRequestClient = new RequestClient({ baseURL: apiURL });

+ 16 - 1
apps/web-antd/src/locales/langs/zh-CN/data_statistics.json

@@ -6,6 +6,10 @@
     "game_title": "游戏每日数据",
     "history_title": "历史数据统计",
     "history_agent_title": "商户统计",
+    "rank_title": "排行榜",
+    "rank_win_title": "赢分榜",
+    "rank_lose_title": "输分榜",
+    "rank_bet_title": "注单额榜",
     "search": {
 
     },
@@ -31,5 +35,16 @@
         "platform_fee_desc": "对应品牌的总盈利值 * 该商户对应品牌的费用比例 = 平台收入",
         "buy_free_bet": "购买免费游戏次数",
         "buy_free_bet_desc": "玩家在游戏中购买免费游戏的次数"
-    }
+    },
+    "rank_win": {
+        "ranking": "排名",
+        "nickname": "平台昵称",
+        "total_win": "盈利值",
+        "bet_count": "注单数",
+        "balance": "当前余额",
+        "total_lose":"亏损值",
+        "total_bet":"注单额"
+    },
+    "day_ranking": "日榜",
+    "total_ranking": "总榜"
 }

+ 41 - 0
apps/web-antd/src/router/routes/modules/data_statistics.ts

@@ -74,6 +74,47 @@ const routes: RouteRecordRaw[] = [
                         component: () => import('#/views/data_statistics/history/agent/index.vue'),
                     },
                 ]
+            },
+            {
+                meta: {
+                    title: $t('data_statistics.rank_title'),
+                    icon:'solar:ranking-outline',
+                    keepAlive: true
+                },
+                name: 'Rank',
+                path: '/data-statistics/rank',
+                children: [
+                    {
+                        meta: {
+                            title: $t('data_statistics.rank_win_title'),
+                            // icon:'solar:file-text-outline',
+                            keepAlive: true
+                        },
+                        name: 'RankWin',
+                        path: '/data-statistics/rank/win',
+                        component: () => import('#/views/data_statistics/rank/win/index.vue'),
+                    },
+                    {
+                        meta: {
+                            title: $t('data_statistics.rank_lose_title'),
+                            // icon:'solar:file-text-outline',
+                            keepAlive: true
+                        },
+                        name: 'RankLose',
+                        path: '/data-statistics/rank/lose',
+                        component: () => import('#/views/data_statistics/rank/lose/index.vue'),
+                    },
+                    {
+                        meta: {
+                            title: $t('data_statistics.rank_bet_title'),
+                            // icon:'solar:file-text-outline',
+                            keepAlive: true
+                        },
+                        name: 'RankBet',
+                        path: '/data-statistics/rank/bet_amount',
+                        component: () => import('#/views/data_statistics/rank/bet/index.vue'),
+                    },
+                ]
             }
         ],
     },

+ 147 - 0
apps/web-antd/src/views/data_statistics/rank/bet/index.vue

@@ -0,0 +1,147 @@
+<script setup>
+import {Page} from "@vben/common-ui";
+import dayjs from "dayjs";
+import {$t} from "@vben/locales";
+import {useVbenVxeGrid} from "#/adapter/vxe-table.js";
+import {ref} from "vue";
+import {Avatar, Tag, RadioGroup, RadioButton} from "ant-design-vue";
+import {getRankBetList} from "#/api/data_statistics/rank_bet.js";
+
+const disabledDate = (current) => {
+	return current && current > dayjs().endOf('day');
+};
+
+
+
+const formOptions = {
+	// 默认展开
+	collapsed: false,
+	// 所有表单项共用,可单独在表单内覆盖
+	commonConfig: {
+		// 所有表单项
+		componentProps: {
+			class: 'w-full',
+		},
+	},
+	// 垂直布局,label和input在不同行,值为vertical
+	// 水平布局,label和input在同一行
+	layout: 'horizontal',
+	schema: [
+		{
+			label:$t("common.day_range_time"),
+			component: 'DatePicker',
+			defaultValue: dayjs(),
+			fieldName: 'range_time',
+			componentProps: {
+				disabledDate: disabledDate,
+			}
+		},
+	],
+	// 是否可展开
+	submitButtonOptions: {
+		content: '查询',
+	},
+	showCollapseButton: false,
+	wrapperClass: 'grid-cols-1 md:grid-cols-3',
+}
+
+// 列表
+const gridOptions = {
+	border: true,
+	stripe: true,
+	scrollbarConfig: {
+		x: {
+			visible: 'visible'
+		},
+		y: {
+			visible: 'auto'
+		}
+	},
+	columns: [
+		{ fixed: 'left', field: "ranking",  title: $t('data_statistics.rank_win.ranking'), type: 'seq', width: 80, slots: {'default':"ranking"}},
+		{ field: 'nickname', title: $t('data_statistics.rank_win.nickname')},
+		{ field: 'total_bet', title: $t('data_statistics.rank_win.total_bet'), slots:{'default':'total_bet'}},
+		{ field: 'rtp', title: "RTP", width: 100},
+		{ field: 'bet_count', title: $t('data_statistics.rank_win.bet_count')},
+		{ field: 'balance', title: $t('data_statistics.rank_win.balance')},
+	],
+	keepSource: true,
+	proxyConfig: {
+		ajax: {
+			query: async ({ page }) => {
+				let form = {
+					page: page.currentPage,
+					limit: page.pageSize,
+					compress: 0
+				};
+				const search = await gridApi.formApi.getValues();
+				for (let key in search) {
+					if(search[key]) {
+						form[key] = search[key];
+					}
+				}
+				if(search.range_time) {
+					if(form.range_time) {
+						delete form.range_time;
+					}
+					if(tabType.value == 1) {
+						form['date'] = search.range_time.format('YYYY-MM-DD');
+					}
+				}
+				const list = await getRankBetList(form);
+				list.list.forEach((item, index) => {
+					item['ranking'] = index + 1;
+				})
+				return {
+					total: list.total,
+					items: list.list
+				}
+			},
+		},
+	},
+	rowConfig: {
+		isHover: true,
+	},
+	toolbarConfig: {
+		custom: true,
+		export: true,
+		// import: true,
+		refresh: true,
+		zoom: true,
+	},
+};
+const [Grid, gridApi] = useVbenVxeGrid({
+	formOptions,
+	gridOptions,
+});
+
+let tabType = ref("1");
+const changeTabType = function () {
+	gridApi.reload();
+}
+
+</script>
+
+<template>
+	<Page>
+		<Grid>
+			<template #ranking="{ row }">
+				<h2 style="font-size:1rem;">No.{{row.ranking}}</h2>
+			</template>
+			<template #total_bet="{ row }">
+				<span style="color:green" v-if="row.total_bet >= 0">{{row.total_bet}}</span>
+				<span style="color:red" v-else>{{row.total_bet}}</span>
+			</template>
+			<template #toolbar-actions>
+				<RadioGroup v-model:value="tabType" button-style="solid" @change="changeTabType">
+					<RadioButton value="1">{{ $t('data_statistics.day_ranking') }}</RadioButton>
+					<RadioButton value="2">{{ $t('data_statistics.total_ranking') }}</RadioButton>
+				</RadioGroup>
+			</template>
+		</Grid>
+	</Page>
+</template>
+
+<style scoped>
+
+</style>

+ 147 - 0
apps/web-antd/src/views/data_statistics/rank/lose/index.vue

@@ -0,0 +1,147 @@
+<script setup>
+import {Page} from "@vben/common-ui";
+import dayjs from "dayjs";
+import {$t} from "@vben/locales";
+import {useVbenVxeGrid} from "#/adapter/vxe-table.js";
+import {ref} from "vue";
+import {Avatar, Tag, RadioGroup, RadioButton} from "ant-design-vue";
+import {getRankLoseList} from "#/api/data_statistics/rank_lose.js";
+
+const disabledDate = (current) => {
+	return current && current > dayjs().endOf('day');
+};
+
+
+
+const formOptions = {
+	// 默认展开
+	collapsed: false,
+	// 所有表单项共用,可单独在表单内覆盖
+	commonConfig: {
+		// 所有表单项
+		componentProps: {
+			class: 'w-full',
+		},
+	},
+	// 垂直布局,label和input在不同行,值为vertical
+	// 水平布局,label和input在同一行
+	layout: 'horizontal',
+	schema: [
+		{
+			label:$t("common.day_range_time"),
+			component: 'DatePicker',
+			defaultValue: dayjs(),
+			fieldName: 'range_time',
+			componentProps: {
+				disabledDate: disabledDate,
+			}
+		},
+	],
+	// 是否可展开
+	submitButtonOptions: {
+		content: '查询',
+	},
+	showCollapseButton: false,
+	wrapperClass: 'grid-cols-1 md:grid-cols-3',
+}
+
+// 列表
+const gridOptions = {
+	border: true,
+	stripe: true,
+	scrollbarConfig: {
+		x: {
+			visible: 'visible'
+		},
+		y: {
+			visible: 'auto'
+		}
+	},
+	columns: [
+		{ fixed: 'left', field: "ranking",  title: $t('data_statistics.rank_win.ranking'), type: 'seq', width: 80, slots: {'default':"ranking"}},
+		{ field: 'nickname', title: $t('data_statistics.rank_win.nickname')},
+		{ field: 'total_lose', title: $t('data_statistics.rank_win.total_lose'), slots:{'default':'total_lose'}},
+		{ field: 'rtp', title: "RTP", width: 100},
+		{ field: 'bet_count', title: $t('data_statistics.rank_win.bet_count')},
+		{ field: 'balance', title: $t('data_statistics.rank_win.balance')},
+	],
+	keepSource: true,
+	proxyConfig: {
+		ajax: {
+			query: async ({ page }) => {
+				let form = {
+					page: page.currentPage,
+					limit: page.pageSize,
+					compress: 0
+				};
+				const search = await gridApi.formApi.getValues();
+				for (let key in search) {
+					if(search[key]) {
+						form[key] = search[key];
+					}
+				}
+				if(search.range_time) {
+					if(form.range_time) {
+						delete form.range_time;
+					}
+					if(tabType.value == 1) {
+						form['date'] = search.range_time.format('YYYY-MM-DD');
+					}
+				}
+				const list = await getRankLoseList(form);
+				list.list.forEach((item, index) => {
+					item['ranking'] = index + 1;
+				})
+				return {
+					total: list.total,
+					items: list.list
+				}
+			},
+		},
+	},
+	rowConfig: {
+		isHover: true,
+	},
+	toolbarConfig: {
+		custom: true,
+		export: true,
+		// import: true,
+		refresh: true,
+		zoom: true,
+	},
+};
+const [Grid, gridApi] = useVbenVxeGrid({
+	formOptions,
+	gridOptions,
+});
+
+let tabType = ref("1");
+const changeTabType = function () {
+	gridApi.reload();
+}
+
+</script>
+
+<template>
+	<Page>
+		<Grid>
+			<template #ranking="{ row }">
+				<h2 style="font-size:1rem;">No.{{row.ranking}}</h2>
+			</template>
+			<template #total_lose="{ row }">
+				<span style="color:green" v-if="row.total_lose >= 0">{{row.total_lose}}</span>
+				<span style="color:red" v-else>{{row.total_lose}}</span>
+			</template>
+			<template #toolbar-actions>
+				<RadioGroup v-model:value="tabType" button-style="solid" @change="changeTabType">
+					<RadioButton value="1">{{ $t('data_statistics.day_ranking') }}</RadioButton>
+					<RadioButton value="2">{{ $t('data_statistics.total_ranking') }}</RadioButton>
+				</RadioGroup>
+			</template>
+		</Grid>
+	</Page>
+</template>
+
+<style scoped>
+
+</style>

+ 147 - 0
apps/web-antd/src/views/data_statistics/rank/win/index.vue

@@ -0,0 +1,147 @@
+<script setup>
+import {Page} from "@vben/common-ui";
+import dayjs from "dayjs";
+import {$t} from "@vben/locales";
+import {useVbenVxeGrid} from "#/adapter/vxe-table.js";
+import {ref} from "vue";
+import {Avatar, Tag, RadioGroup, RadioButton} from "ant-design-vue";
+import {getRankWinList} from "#/api/data_statistics/rank_win.js";
+
+const disabledDate = (current) => {
+	return current && current > dayjs().endOf('day');
+};
+
+
+
+const formOptions = {
+	// 默认展开
+	collapsed: false,
+	// 所有表单项共用,可单独在表单内覆盖
+	commonConfig: {
+		// 所有表单项
+		componentProps: {
+			class: 'w-full',
+		},
+	},
+	// 垂直布局,label和input在不同行,值为vertical
+	// 水平布局,label和input在同一行
+	layout: 'horizontal',
+	schema: [
+		{
+			label:$t("common.day_range_time"),
+			component: 'DatePicker',
+			defaultValue: dayjs(),
+			fieldName: 'range_time',
+			componentProps: {
+				disabledDate: disabledDate,
+			}
+		},
+	],
+	// 是否可展开
+	submitButtonOptions: {
+		content: '查询',
+	},
+	showCollapseButton: false,
+	wrapperClass: 'grid-cols-1 md:grid-cols-3',
+}
+
+// 列表
+const gridOptions = {
+	border: true,
+	stripe: true,
+	scrollbarConfig: {
+		x: {
+			visible: 'visible'
+		},
+		y: {
+			visible: 'auto'
+		}
+	},
+	columns: [
+		{ fixed: 'left', field: "ranking",  title: $t('data_statistics.rank_win.ranking'), type: 'seq', width: 80, slots: {'default':"ranking"}},
+		{ field: 'nickname', title: $t('data_statistics.rank_win.nickname')},
+		{ field: 'total_win', title: $t('data_statistics.rank_win.total_win'), slots:{'default':'total_win'}},
+		{ field: 'rtp', title: "RTP", width: 100},
+		{ field: 'bet_count', title: $t('data_statistics.rank_win.bet_count')},
+		{ field: 'balance', title: $t('data_statistics.rank_win.balance')},
+	],
+	keepSource: true,
+	proxyConfig: {
+		ajax: {
+			query: async ({ page }) => {
+				let form = {
+					page: page.currentPage,
+					limit: page.pageSize,
+					compress: 0
+				};
+				const search = await gridApi.formApi.getValues();
+				for (let key in search) {
+					if(search[key]) {
+						form[key] = search[key];
+					}
+				}
+				if(search.range_time) {
+					if(form.range_time) {
+						delete form.range_time;
+					}
+					if(tabType.value == 1) {
+						form['date'] = search.range_time.format('YYYY-MM-DD');
+					}
+				}
+				const list = await getRankWinList(form);
+				list.list.forEach((item, index) => {
+					item['ranking'] = index + 1;
+				})
+				return {
+					total: list.total,
+					items: list.list
+				}
+			},
+		},
+	},
+	rowConfig: {
+		isHover: true,
+	},
+	toolbarConfig: {
+		custom: true,
+		export: true,
+		// import: true,
+		refresh: true,
+		zoom: true,
+	},
+};
+const [Grid, gridApi] = useVbenVxeGrid({
+	formOptions,
+	gridOptions,
+});
+
+let tabType = ref("1");
+const changeTabType = function () {
+	gridApi.reload();
+}
+
+</script>
+
+<template>
+	<Page>
+		<Grid>
+			<template #ranking="{ row }">
+				<h2 style="font-size:1rem;">No.{{row.ranking}}</h2>
+			</template>
+			<template #total_win="{ row }">
+				<span style="color:green" v-if="row.total_win >= 0">{{row.total_win}}</span>
+				<span style="color:red" v-else>{{row.total_win}}</span>
+			</template>
+			<template #toolbar-actions>
+				<RadioGroup v-model:value="tabType" button-style="solid" @change="changeTabType">
+					<RadioButton value="1">{{ $t('data_statistics.day_ranking') }}</RadioButton>
+					<RadioButton value="2">{{ $t('data_statistics.total_ranking') }}</RadioButton>
+				</RadioGroup>
+			</template>
+		</Grid>
+	</Page>
+</template>
+
+<style scoped>
+
+</style>