版本更新
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
This commit is contained in:
parent
eaa008b67f
commit
e52eb2ca64
@ -1,11 +1,10 @@
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
export interface UserData {
|
||||
data: object[];
|
||||
total: number;
|
||||
sum : number;
|
||||
psum : number;
|
||||
nsum : number;
|
||||
sum: number;
|
||||
psum: number;
|
||||
nsum: number;
|
||||
}
|
||||
export interface UserLogAssetParam {
|
||||
Id: number;
|
||||
@ -17,61 +16,60 @@ export interface UserLogAssetParam {
|
||||
CurrentPage: number;
|
||||
AppId?: number;
|
||||
}
|
||||
export interface UserLogOrder{
|
||||
Id: number,
|
||||
Time: number,
|
||||
Type: number,
|
||||
Diff: number,
|
||||
ChessId: string,
|
||||
export interface UserLogOrder {
|
||||
Id: number;
|
||||
Time: number;
|
||||
Type: number;
|
||||
Diff: number;
|
||||
ChessId: string;
|
||||
}
|
||||
export interface heatType {
|
||||
date :string;
|
||||
value : number;
|
||||
date: string;
|
||||
value: number;
|
||||
}
|
||||
export interface UserLogInfo{
|
||||
AreaId : number,
|
||||
Charge:number,
|
||||
Level: number,
|
||||
Name: string,
|
||||
Star: number,
|
||||
Login: number,
|
||||
Energy: number,
|
||||
Diamond: number,
|
||||
Mac : string,
|
||||
Cumulative: number,
|
||||
TodayCumulative: number,
|
||||
Bonus?: number,
|
||||
Order:UserLogOrder[],
|
||||
Heatmap?: heatType[],
|
||||
export interface UserLogInfo {
|
||||
AreaId: number;
|
||||
Charge: number;
|
||||
Level: number;
|
||||
Name: string;
|
||||
Star: number;
|
||||
Login: number;
|
||||
Energy: number;
|
||||
Diamond: number;
|
||||
Mac: string;
|
||||
Cumulative: number;
|
||||
TodayCumulative: number;
|
||||
Bonus?: number;
|
||||
Code?: string;
|
||||
RegisterTime: number;
|
||||
Order: UserLogOrder[];
|
||||
Heatmap?: heatType[];
|
||||
}
|
||||
|
||||
|
||||
export interface UserOrder{
|
||||
Id: number,
|
||||
OrderId: number,
|
||||
Price: number,
|
||||
PayChannelOrderId: number,
|
||||
ProductId: number,
|
||||
CreateTime: number,
|
||||
PayTime: number,
|
||||
PayType: number,
|
||||
Param:string
|
||||
export interface UserOrder {
|
||||
Id: number;
|
||||
OrderId: number;
|
||||
Price: number;
|
||||
PayChannelOrderId: number;
|
||||
ProductId: number;
|
||||
CreateTime: number;
|
||||
PayTime: number;
|
||||
PayType: number;
|
||||
Param: string;
|
||||
}
|
||||
|
||||
|
||||
export async function getUserLogAssetApi(data : UserLogAssetParam) {
|
||||
export async function getUserLogAssetApi(data: UserLogAssetParam) {
|
||||
return requestClient.post<UserData>('/log/asset', data);
|
||||
}
|
||||
|
||||
export async function getUserlogEventApi(data : UserLogAssetParam) {
|
||||
export async function getUserlogEventApi(data: UserLogAssetParam) {
|
||||
return requestClient.post<UserData>('/log/event', data);
|
||||
}
|
||||
|
||||
export async function getUserlogInfoApi(data : UserLogAssetParam) {
|
||||
export async function getUserlogInfoApi(data: UserLogAssetParam) {
|
||||
return requestClient.post<UserLogInfo>('/log/user', data);
|
||||
}
|
||||
|
||||
export async function getUserlogOrderApi(data : UserLogAssetParam) {
|
||||
export async function getUserlogOrderApi(data: UserLogAssetParam) {
|
||||
return requestClient.post<UserOrder>('/log/order', data);
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ export interface dataType{
|
||||
|
||||
onMounted(() => {
|
||||
cal = new CalHeatMap();
|
||||
console.log(new Date(new Date().getFullYear(), 1, 1), new Date(new Date().getFullYear()+1, 0, 0));
|
||||
cal.paint({
|
||||
itemSelector: '#cal-heatmap',
|
||||
data: {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import eventTable from "./calendar/event-table.vue";
|
||||
import calendar from "./calendar/index.vue";
|
||||
import eventModal from "./modal/event.vue";
|
||||
import assetModal from "./modal/asset.vue";
|
||||
import type {dataType} from "./calendar/index.vue";
|
||||
export { eventTable, calendar };
|
||||
export { eventTable, calendar, eventModal, assetModal };
|
||||
export type { dataType };
|
||||
|
||||
100
apps/web-antd/src/component/modal/asset.vue
Normal file
100
apps/web-antd/src/component/modal/asset.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<script setup lang="ts">
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { getUserLogAssetApi } from '#/api/core/log';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { inject, ref } from 'vue';
|
||||
import { globalState } from '#/store/globalState';
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
const state = inject('globalState', globalState);
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
interface RowType {
|
||||
Uid: number;
|
||||
change_type: string;
|
||||
change_num: string;
|
||||
change_after: string;
|
||||
item_id: string;
|
||||
timestamp: string;
|
||||
}
|
||||
const formatType = (cellValue: string) => {
|
||||
switch (cellValue) {
|
||||
case "gain":
|
||||
return '增加';
|
||||
case "consume":
|
||||
return '减少';
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
}
|
||||
const formatItemName = (cellValue: number) => {
|
||||
// console.log(cellValue);
|
||||
switch (cellValue) {
|
||||
case 100001:
|
||||
return '能量';
|
||||
case 100002:
|
||||
return '宠物币';
|
||||
case 100003:
|
||||
return '钻石';
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
}
|
||||
const d = ref({
|
||||
sum : 0,
|
||||
psum : 0,
|
||||
nsum : 0,
|
||||
});
|
||||
|
||||
|
||||
const gridOptions: VxeGridProps<RowType> = {
|
||||
columns: [
|
||||
{ field: 'Uid', title: 'Uid' },
|
||||
{ field: 'change_type', title: '变化类型', formatter:({cellValue}) => formatType(cellValue)},
|
||||
{ field: 'change_num', title: '变化数值' },
|
||||
{ field: 'change_after', title: '变化后数值' },
|
||||
{ field: 'item_id', title: '道具id', formatter: ({ cellValue }) => formatItemName(cellValue) },
|
||||
{ field: 'timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue*1000).toLocaleString()},
|
||||
],
|
||||
height: '500px',
|
||||
keepSource: true,
|
||||
pagerConfig: {},
|
||||
proxyConfig: {
|
||||
response: {
|
||||
total: "total",
|
||||
result: "data"
|
||||
},
|
||||
ajax: {
|
||||
query: async () => {
|
||||
const r = await getUserLogAssetApi({
|
||||
Id: state.uid,
|
||||
Event :'',
|
||||
StartTime: modalApi.getData()?.StartTime || 0,
|
||||
EndTime: modalApi.getData()?.EndTime || 0,
|
||||
ItemId: 0,
|
||||
CurrentPage: 1,
|
||||
PageSize: 100,
|
||||
});
|
||||
d.value.sum = r.sum;
|
||||
d.value.psum = r.psum;
|
||||
d.value.nsum = r.nsum;
|
||||
return r
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
rowConfig: {
|
||||
isHover: true,
|
||||
},
|
||||
};
|
||||
|
||||
const [Grid] = useVbenVxeGrid({ gridOptions});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<Modal>
|
||||
<Grid />
|
||||
</Modal>
|
||||
|
||||
</template>
|
||||
66
apps/web-antd/src/component/modal/event.vue
Normal file
66
apps/web-antd/src/component/modal/event.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import { getUserlogEventApi } from '#/api/core/log';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
|
||||
import { inject } from 'vue';
|
||||
import { globalState } from '#/store/globalState';
|
||||
import { $t } from '#/locales';
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
import {useVbenModal } from '@vben/common-ui';
|
||||
const state = inject('globalState', globalState);
|
||||
|
||||
|
||||
interface RowType {
|
||||
Uid: string;
|
||||
Event: string;
|
||||
Param: string;
|
||||
Timestamp: string;
|
||||
}
|
||||
const [Modal, modalApi] = useVbenModal({});
|
||||
|
||||
const gridOptions: VxeGridProps<RowType> = {
|
||||
columns: [
|
||||
{ field: 'Uid', title: 'Uid' },
|
||||
{ field: 'Event', title: '事件类型', formatter: ({ cellValue }) => $t('page.log.event.' + `${cellValue}`) || cellValue },
|
||||
{ field: 'Label', title: 'Label'},
|
||||
{ field: 'Param', title: '参数' },
|
||||
{ field: 'Timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue*1000).toLocaleString()},
|
||||
],
|
||||
stripe: true,
|
||||
height: 'auto',
|
||||
pagerConfig: {
|
||||
enabled:true
|
||||
},
|
||||
proxyConfig: {
|
||||
response: {
|
||||
total: "total",
|
||||
result: "data"
|
||||
},
|
||||
ajax: {
|
||||
query: async () => {
|
||||
return await getUserlogEventApi({
|
||||
Id: state.uid,
|
||||
Event: '',
|
||||
StartTime: modalApi.getData()?.StartTime || "2025-03-17T16:00:00.000Z",
|
||||
EndTime: modalApi.getData()?.EndTime || "2025-03-17T16:00:00.000Z",
|
||||
CurrentPage: 1,
|
||||
PageSize: 100,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
rowConfig: {
|
||||
isHover: true,
|
||||
},
|
||||
};
|
||||
|
||||
const [Grid] = useVbenVxeGrid({gridOptions });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal>
|
||||
<Grid style="height: 500px;" />
|
||||
</Modal>
|
||||
</template>
|
||||
1
apps/web-antd/src/store/item.ts
Normal file
1
apps/web-antd/src/store/item.ts
Normal file
File diff suppressed because one or more lines are too long
@ -1,15 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import type { VxeGridListeners } from 'vxe-table';
|
||||
import { getUserLogAssetApi } from '#/api/core/log';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { inject, ref } from 'vue';
|
||||
import { globalState } from '#/store/globalState';
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
import { ItemData } from '#/store/item';
|
||||
import { eventModal } from '#/component';
|
||||
import dayjs from 'dayjs';
|
||||
const state = inject('globalState', globalState);
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
connectedComponent:eventModal,
|
||||
class:'width:1800px;',
|
||||
|
||||
});
|
||||
interface RowType {
|
||||
Uid: number;
|
||||
change_type: string;
|
||||
@ -30,16 +36,7 @@ const formatType = (cellValue: string) => {
|
||||
}
|
||||
const formatItemName = (cellValue: number) => {
|
||||
// console.log(cellValue);
|
||||
switch (cellValue) {
|
||||
case 100001:
|
||||
return '能量';
|
||||
case 100002:
|
||||
return '宠物币';
|
||||
case 100003:
|
||||
return '钻石';
|
||||
default:
|
||||
return cellValue;
|
||||
}
|
||||
return ItemData.find((item) => item.Id === cellValue)?.Name || cellValue;
|
||||
}
|
||||
const d = ref({
|
||||
sum : 0,
|
||||
@ -141,21 +138,31 @@ const formOptions: VbenFormProps = {
|
||||
// 按下回车时是否提交表单
|
||||
submitOnEnter: false,
|
||||
}
|
||||
const gridEvents: VxeGridListeners<RowType> = {
|
||||
cellClick: async ({ row }) => {
|
||||
console.log(row);
|
||||
modalApi.setData({
|
||||
StartTime: row.timestamp,
|
||||
EndTime: row.timestamp,
|
||||
});
|
||||
modalApi.open();
|
||||
},
|
||||
};
|
||||
const gridOptions: VxeGridProps<RowType> = {
|
||||
columns: [
|
||||
{ field: 'Uid', title: 'Uid' },
|
||||
{ field: 'change_type', title: '变化类型', formatter:({cellValue}) => formatType(cellValue)},
|
||||
{ field: 'change_num', title: '变化数值' },
|
||||
{ field: 'change_after', title: '变化后数值' },
|
||||
{ field: 'item_id', title: '道具id', formatter: ({ cellValue }) => formatItemName(cellValue) },
|
||||
{ field: 'timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue*1000).toLocaleString()},
|
||||
{ field: 'Uid', title: 'Uid' },
|
||||
{ field: 'change_type', title: '变化类型', formatter:({cellValue}) => formatType(cellValue)},
|
||||
{ field: 'change_num', title: '变化数值' },
|
||||
{ field: 'change_after', title: '变化后数值' },
|
||||
{ field: 'item_id', title: '道具名称', formatter: ({ cellValue }) => formatItemName(cellValue) },
|
||||
{ field: 'item_id', title: '道具id'},
|
||||
{ field: 'timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue*1000).toLocaleString()},
|
||||
],
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
toolbarConfig: {
|
||||
custom: true,
|
||||
export: true,
|
||||
// import: true,
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
},
|
||||
@ -174,11 +181,13 @@ const gridOptions: VxeGridProps<RowType> = {
|
||||
|
||||
state.uid = uid;
|
||||
const ItemId = parseInt(formValues.ItemId, 10);
|
||||
|
||||
console.log(formValues.StartTime.unix());
|
||||
const r = await getUserLogAssetApi({
|
||||
Id: uid,
|
||||
Event :formValues.Event,
|
||||
StartTime: formValues.StartTime,
|
||||
EndTime: formValues.EndTime,
|
||||
StartTime: formValues.StartTime.unix(),
|
||||
EndTime: formValues.EndTime.unix(),
|
||||
ItemId: ItemId,
|
||||
CurrentPage: page.currentPage,
|
||||
PageSize: page.pageSize,
|
||||
@ -196,18 +205,21 @@ const gridOptions: VxeGridProps<RowType> = {
|
||||
},
|
||||
};
|
||||
|
||||
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<Grid>
|
||||
<template #toolbar-tools>
|
||||
总数:<span style="margin-right: 10px;margin-left: 5px;"> {{ d.sum }} </span>
|
||||
正数和: <span style="margin-right: 10px;margin-left: 5px;color:green">{{ d.psum }} </span>
|
||||
负数和: <span style="color: red;margin-left: 5px;">{{ d.nsum }} </span>
|
||||
</template>
|
||||
<div>
|
||||
<Page auto-content-height>
|
||||
<Grid>
|
||||
<template #toolbar-tools>
|
||||
总数:<span style="margin-right: 10px;margin-left: 5px;"> {{ d.sum }} </span>
|
||||
正数和: <span style="margin-right: 10px;margin-left: 5px;color:green">{{ d.psum }} </span>
|
||||
负数和: <span style="color: red;margin-left: 5px;">{{ d.nsum }} </span>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</Page>
|
||||
<Modal class="w-[1200px]" "> </Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -2,16 +2,21 @@
|
||||
|
||||
import { getUserlogEventApi } from '#/api/core/log';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
|
||||
import { inject, ref } from 'vue';
|
||||
import { inject } from 'vue';
|
||||
import type { VxeGridListeners } from 'vxe-table';
|
||||
import { globalState } from '#/store/globalState';
|
||||
import { $t } from '#/locales';
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { assetModal } from '#/component';
|
||||
import dayjs from 'dayjs';
|
||||
const state = inject('globalState', globalState);
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
connectedComponent:assetModal,
|
||||
class:'width:1800px;',
|
||||
|
||||
});
|
||||
const startDate = dayjs().startOf('day');
|
||||
const endDate = dayjs().endOf('day');
|
||||
interface RowType {
|
||||
@ -92,9 +97,19 @@ const formOptions: VbenFormProps = {
|
||||
submitOnEnter: false,
|
||||
wrapperClass: 'grid-cols-1 md:grid-cols-5',
|
||||
}
|
||||
const gridEvents: VxeGridListeners<RowType> = {
|
||||
cellClick: async ({ row }) => {
|
||||
console.log(row);
|
||||
modalApi.setData({
|
||||
StartTime: row.Timestamp,
|
||||
EndTime: row.Timestamp,
|
||||
});
|
||||
modalApi.open();
|
||||
},
|
||||
};
|
||||
const gridOptions: VxeGridProps<RowType> = {
|
||||
columns: [
|
||||
{ field: 'Uid', title: 'id' },
|
||||
{ field: 'Uid', title: 'Uid' },
|
||||
{ field: 'Event', title: '事件类型', formatter: ({ cellValue }) => $t('page.log.event.' + `${cellValue}`) || cellValue },
|
||||
{ field: 'Label', title: 'Label'},
|
||||
{ field: 'Param', title: '参数' },
|
||||
@ -119,8 +134,8 @@ const gridOptions: VxeGridProps<RowType> = {
|
||||
return await getUserlogEventApi({
|
||||
Id: Uid,
|
||||
Event: formValues.Event,
|
||||
StartTime: formValues.StartTime,
|
||||
EndTime: formValues.EndTime,
|
||||
StartTime: formValues.StartTime.unix(),
|
||||
EndTime: formValues.EndTime.unix(),
|
||||
CurrentPage: page.currentPage,
|
||||
PageSize: page.pageSize,
|
||||
});
|
||||
@ -133,12 +148,16 @@ const gridOptions: VxeGridProps<RowType> = {
|
||||
},
|
||||
};
|
||||
|
||||
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<Grid />
|
||||
</Page>
|
||||
<div>
|
||||
<Page auto-content-height>
|
||||
<Grid />
|
||||
</Page>
|
||||
<Modal class="w-[1200px]"> </Modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
@ -4,25 +4,15 @@ import { useVbenModal, useVbenForm } from '@vben/common-ui';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getUserlogInfoApi } from '#/api/core/log';
|
||||
import { userGmApi } from '#/api/core/user';
|
||||
import {calendar} from '#/component/index'
|
||||
import type {dataType} from '#/component/index';
|
||||
import { calendar } from '#/component/index';
|
||||
import type { dataType } from '#/component/index';
|
||||
// 引入 cal-heatmap 样式
|
||||
import 'cal-heatmap/cal-heatmap.css';
|
||||
import type {
|
||||
WorkbenchProjectItem,
|
||||
|
||||
} from '@vben/common-ui';
|
||||
|
||||
|
||||
import type { WorkbenchProjectItem } from '@vben/common-ui';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
|
||||
WorkbenchProject,
|
||||
|
||||
WorkbenchDetail,
|
||||
} from '@vben/common-ui';
|
||||
import UserHeader from './user-header.vue';
|
||||
import { WorkbenchProject, WorkbenchDetail } from '@vben/common-ui';
|
||||
import UserHeader from './user-header.vue';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useUserStore } from '@vben/stores';
|
||||
|
||||
@ -50,21 +40,21 @@ const [BaseForm] = useVbenForm({
|
||||
schema: [
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: "",
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: '请输入gm命令',
|
||||
placeholder: '请输入gm命令',
|
||||
},
|
||||
label: 'Gm:',
|
||||
fieldName: 'gm',
|
||||
}
|
||||
},
|
||||
],
|
||||
handleSubmit: async (values) => {
|
||||
const cv = modalApi.getData<Record<string, any>>();
|
||||
const cv = modalApi.getData<Record<string, any>>();
|
||||
const r = await userGmApi({
|
||||
Uid: cv.uid,
|
||||
AppId: cv.AppId,
|
||||
ServerId: cv.ServerId,
|
||||
Command: values.gm,
|
||||
Uid: cv.uid,
|
||||
AppId: cv.AppId,
|
||||
ServerId: cv.ServerId,
|
||||
Command: values.gm,
|
||||
});
|
||||
message.success(r.Msg);
|
||||
},
|
||||
@ -75,85 +65,97 @@ const [BaseForm] = useVbenForm({
|
||||
|
||||
const data = ref();
|
||||
const info = ref<{
|
||||
Level: number;
|
||||
Star: number;
|
||||
Name: string;
|
||||
Charge: number;
|
||||
AreaId: number;
|
||||
LoginTime: string;
|
||||
Diamond: number;
|
||||
Energy: number;
|
||||
Mac: string;
|
||||
Uid: number;
|
||||
Cumulative:string;
|
||||
TodayCumulative:string;
|
||||
Bonus?: number;
|
||||
Order: WorkbenchProjectItem[];
|
||||
Heatmap: dataType[];
|
||||
Level: number;
|
||||
Star: number;
|
||||
Name: string;
|
||||
Charge: number;
|
||||
AreaId: number;
|
||||
LoginTime: string;
|
||||
Diamond: number;
|
||||
Energy: number;
|
||||
Mac: string;
|
||||
Uid: number;
|
||||
Cumulative: string;
|
||||
TodayCumulative: string;
|
||||
Bonus?: number;
|
||||
Code?: string;
|
||||
RegisterTime?: string;
|
||||
Order: WorkbenchProjectItem[];
|
||||
Heatmap: dataType[];
|
||||
}>({
|
||||
Level: 0,
|
||||
Star: 0,
|
||||
Name: '',
|
||||
Charge: 0,
|
||||
Uid: 0,
|
||||
AreaId: 0,
|
||||
LoginTime: '',
|
||||
Diamond: 0,
|
||||
Energy: 0,
|
||||
Mac: '',
|
||||
Cumulative:'0h',
|
||||
TodayCumulative:'0h',
|
||||
Order: [],
|
||||
Heatmap: [],
|
||||
})
|
||||
Level: 0,
|
||||
Star: 0,
|
||||
Name: '',
|
||||
Charge: 0,
|
||||
Uid: 0,
|
||||
AreaId: 0,
|
||||
LoginTime: '',
|
||||
Diamond: 0,
|
||||
Energy: 0,
|
||||
Mac: '',
|
||||
Cumulative: '0h',
|
||||
TodayCumulative: '0h',
|
||||
Order: [],
|
||||
Heatmap: [],
|
||||
});
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
onCancel() {
|
||||
modalApi.close();
|
||||
},
|
||||
onConfirm() {
|
||||
message.info('onConfirm');
|
||||
// modalApi.close();
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (isOpen) {
|
||||
data.value = modalApi.getData<Record<string, any>>();
|
||||
try {
|
||||
const r = await getUserlogInfoApi({
|
||||
Id: data.value.uid,
|
||||
Event: 'someEvent', // replace 'someEvent' with the actual event
|
||||
PageSize: 10, // replace 10 with the actual page size
|
||||
CurrentPage: 1, // replace 1 with the actual current page
|
||||
});
|
||||
info.value.Uid = data.value.uid;
|
||||
info.value.Level = r.Level
|
||||
info.value.Star = r.Star
|
||||
info.value.Name = r.Name
|
||||
info.value.Charge = r.Charge
|
||||
info.value.AreaId = r.AreaId
|
||||
info.value.LoginTime = dayjs(r.Login * 1000).format('YYYY-MM-DD HH:mm:ss'); // 转换时间戳
|
||||
info.value.Diamond = r.Diamond
|
||||
info.value.Energy = r.Energy
|
||||
info.value.Mac = r.Mac
|
||||
info.value.Cumulative = (r.Cumulative / 3600).toFixed(2) + 'h'
|
||||
info.value.TodayCumulative = (r.TodayCumulative / 3600).toFixed(2) + 'h'
|
||||
info.value.Order = []
|
||||
info.value.Heatmap = r.Heatmap || [];
|
||||
for (const i in r.Order) {
|
||||
info.value.Order.push({
|
||||
color: '#3fb27f',
|
||||
content: r.Order[i]?.ChessId || '',
|
||||
date: dayjs((r.Order[i]?.Time ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') || '',
|
||||
group: String(r.Order[i]?.Type) || '',
|
||||
icon: 'lets-icons:order',
|
||||
title: String(r.Order[i]?.Id) || '',
|
||||
url: '',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
//console.error('Error fetching user info:', error);
|
||||
}
|
||||
onCancel() {
|
||||
modalApi.close();
|
||||
},
|
||||
onConfirm() {
|
||||
message.info('onConfirm');
|
||||
// modalApi.close();
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (isOpen) {
|
||||
data.value = modalApi.getData<Record<string, any>>();
|
||||
try {
|
||||
const r = await getUserlogInfoApi({
|
||||
Id: data.value.uid,
|
||||
Event: 'someEvent', // replace 'someEvent' with the actual event
|
||||
PageSize: 10, // replace 10 with the actual page size
|
||||
CurrentPage: 1, // replace 1 with the actual current page
|
||||
});
|
||||
info.value.Uid = data.value.uid;
|
||||
info.value.Level = r.Level;
|
||||
info.value.Star = r.Star;
|
||||
info.value.Name = r.Name;
|
||||
info.value.Charge = r.Charge;
|
||||
info.value.AreaId = r.AreaId;
|
||||
info.value.LoginTime = dayjs(r.Login * 1000).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
); // 转换时间戳
|
||||
info.value.Diamond = r.Diamond;
|
||||
info.value.Energy = r.Energy;
|
||||
info.value.Mac = r.Mac;
|
||||
info.value.Cumulative = (r.Cumulative / 3600).toFixed(2) + 'h';
|
||||
info.value.TodayCumulative =
|
||||
(r.TodayCumulative / 3600).toFixed(2) + 'h';
|
||||
info.value.Order = [];
|
||||
info.value.Code = r.Code || '';
|
||||
info.value.RegisterTime = dayjs(r.RegisterTime * 1000).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
); // 转换注册时间戳
|
||||
info.value.Heatmap = r.Heatmap || [];
|
||||
for (const i in r.Order) {
|
||||
info.value.Order.push({
|
||||
color: '#3fb27f',
|
||||
content: r.Order[i]?.ChessId || '',
|
||||
date:
|
||||
dayjs((r.Order[i]?.Time ?? 0) * 1000).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
) || '',
|
||||
group: String(r.Order[i]?.Type) || '',
|
||||
icon: 'lets-icons:order',
|
||||
title: String(r.Order[i]?.Id) || '',
|
||||
url: '',
|
||||
});
|
||||
}
|
||||
},
|
||||
} catch (error) {
|
||||
//console.error('Error fetching user info:', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// 添加对热力图数据的监听
|
||||
@ -161,59 +163,70 @@ watch(
|
||||
() => info.value.Heatmap,
|
||||
(newHeatmap) => {
|
||||
if (newHeatmap && newHeatmap.length > 0) {
|
||||
console.log('Heatmap data loaded:', newHeatmap);
|
||||
// 可以在这里触发热力图重新渲染
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
{ deep: true },
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<Modal title="玩家详情">
|
||||
<div class="p-5">
|
||||
<UserHeader :avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar">
|
||||
<template #nick_name>
|
||||
nick_name: {{ info.Name || 'N/A' }}
|
||||
</template>
|
||||
<template #user_name> user_name: {{ info.Mac }} </template>
|
||||
<template #uid> uid: {{ info.Uid }} </template>
|
||||
<template #level>{{ info.Level }}</template>
|
||||
<template #star>{{ info.Star }}</template>
|
||||
<template #energy>{{ info.Energy }} </template>
|
||||
<template #diamond>{{ info.Diamond }}</template>
|
||||
</UserHeader>
|
||||
<div class="mt-5">
|
||||
<BaseForm />
|
||||
</div>
|
||||
<div class="mt-5 flex flex-col lg:flex-row">
|
||||
<div class="mr-4 w-full lg:w-3/5">
|
||||
<WorkbenchProject :items="info.Order" title="订单" />
|
||||
<!-- <WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" /> -->
|
||||
</div>
|
||||
<div class="w-full lg:w-2/5">
|
||||
<WorkbenchDetail :items="projectItems" class="mt-5 lg:mt-0" title="玩家详情">
|
||||
<template #areaid> {{ info.AreaId }}</template>
|
||||
<template #charge> <b>$</b>{{ info.Charge.toFixed(2) }}</template>
|
||||
<template #logintime> {{ info.LoginTime }}</template>
|
||||
<template #Cumulative>{{ info.Cumulative }}</template>
|
||||
<template #AreaId>{{ info.AreaId }}</template>
|
||||
<template #Bonus>{{ info.Bonus || 0 }}</template>
|
||||
<template #TodayCumulative>{{ info.TodayCumulative }}</template>
|
||||
</WorkbenchDetail>
|
||||
<calendar
|
||||
v-if="info.Heatmap.length > 0"
|
||||
style="margin-top:15px"
|
||||
:dataList="info.Heatmap"
|
||||
title="热力图"
|
||||
:key="`heatmap-${info.Uid}`"
|
||||
/>
|
||||
<div v-else style="margin-top:15px; padding: 20px; text-align: center; color: #999;">
|
||||
暂无热力图数据
|
||||
</div>
|
||||
<!-- <WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" /> -->
|
||||
</div>
|
||||
</div>
|
||||
<Modal title="玩家详情">
|
||||
<div class="p-5">
|
||||
<UserHeader
|
||||
:avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar"
|
||||
>
|
||||
<template #nick_name> nick_name: {{ info.Name || 'N/A' }} </template>
|
||||
<template #user_name> user_name: {{ info.Mac }} </template>
|
||||
<template #uid> uid: {{ info.Uid }} </template>
|
||||
<template #level>{{ info.Level }}</template>
|
||||
<template #star>{{ info.Star }}</template>
|
||||
<template #energy>{{ info.Energy }} </template>
|
||||
<template #diamond>{{ info.Diamond }}</template>
|
||||
</UserHeader>
|
||||
<div class="mt-5">
|
||||
<BaseForm />
|
||||
</div>
|
||||
<div class="mt-5 flex flex-col lg:flex-row">
|
||||
<div class="mr-4 w-full lg:w-3/5">
|
||||
<WorkbenchProject :items="info.Order" title="订单" />
|
||||
<!-- <WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" /> -->
|
||||
</div>
|
||||
</Modal>
|
||||
<div class="w-full lg:w-2/5">
|
||||
<WorkbenchDetail
|
||||
:items="projectItems"
|
||||
class="mt-5 lg:mt-0"
|
||||
title="玩家详情"
|
||||
>
|
||||
<template #areaid> {{ info.AreaId }}</template>
|
||||
<template #charge> <b>$</b>{{ info.Charge.toFixed(2) }}</template>
|
||||
<template #RegisterTime> {{ info.RegisterTime }}</template>
|
||||
<template #logintime> {{ info.LoginTime }}</template>
|
||||
<template #Cumulative>{{ info.Cumulative }}</template>
|
||||
<template #AreaId>{{ info.AreaId }}</template>
|
||||
<template #Code>{{ info.Code || 0 }}</template>
|
||||
<template #TodayCumulative>{{ info.TodayCumulative }}</template>
|
||||
</WorkbenchDetail>
|
||||
<calendar
|
||||
v-if="info.Heatmap.length > 0"
|
||||
style="margin-top: 15px"
|
||||
:dataList="info.Heatmap"
|
||||
title="热力图"
|
||||
:key="`heatmap-${info.Uid}`"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
style="
|
||||
margin-top: 15px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
"
|
||||
>
|
||||
暂无热力图数据
|
||||
</div>
|
||||
<!-- <WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" /> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { getUserListApi } from '#/api';
|
||||
// import { getPlayerInfoApi } from '#/api/core/player';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import dayjs from 'dayjs'; // 使用 dayjs 库来格式化时间戳
|
||||
import { Tag } from 'ant-design-vue';
|
||||
@ -9,10 +8,11 @@ import type { VbenFormProps } from '#/adapter/form';
|
||||
import { Page } from '@vben/common-ui';
|
||||
import type { VxeGridListeners } from 'vxe-table';
|
||||
import { useVbenModal } from '@vben/common-ui'
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, inject } from 'vue';
|
||||
import { globalState } from '#/store/globalState';
|
||||
import { getServerListApi, getAppListApi } from '#/api/core/server';
|
||||
import type { AppData, ServerData } from '#/api/core/server';
|
||||
|
||||
const state = inject('globalState', globalState);
|
||||
const appList = ref<AppData[]>([]);
|
||||
const ServerList = ref<ServerData[]>([]);
|
||||
import userModalDemo from './user.vue';
|
||||
@ -111,7 +111,7 @@ const gridEvents: VxeGridListeners<RowType> = {
|
||||
const value = await GridApi.formApi.getValues();
|
||||
userModalApi.setData({ uid: row.Uid, AppId: value.AppId, ServerId: value.ServerId });
|
||||
userModalApi.open();
|
||||
await navigator.clipboard.writeText(row.Uid.toString());
|
||||
state.uid = row.Uid;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { WorkbenchProjectItem } from '../typing';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@vben-core/shadcn-ui';
|
||||
|
||||
interface Props {
|
||||
items: WorkbenchProjectItem[];
|
||||
@ -29,14 +24,17 @@ defineEmits(['click']);
|
||||
<CardTitle class="text-lg">{{ title }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="flex flex-wrap p-0">
|
||||
|
||||
<div class="border-border w-full border-b border-r border-t p-5 transition-all hover:shadow-xl">
|
||||
<div
|
||||
class="border-border w-full border-b border-r border-t p-5 transition-all hover:shadow-xl"
|
||||
>
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<div class="text-foreground/80 leading-2 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">总充值金额:</span>
|
||||
</div>
|
||||
<div class="text-foreground/80 flex h-4 md:w-1/2 justify-start p-1 leading-2">
|
||||
<div class="Value ">
|
||||
<div
|
||||
class="text-foreground/80 leading-2 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.charge">
|
||||
<slot name="charge"></slot>
|
||||
</span>
|
||||
@ -45,11 +43,13 @@ defineEmits(['click']);
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2 ">
|
||||
<div class="text-foreground/80 leading-2 mt-3 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">场景:</span>
|
||||
</div>
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 justify-start p-1 leading-2">
|
||||
<div class="Value ">
|
||||
<div
|
||||
class="text-foreground/80 leading-2 mt-3 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.AreaId">
|
||||
<slot name="AreaId"></slot>
|
||||
</span>
|
||||
@ -58,11 +58,28 @@ defineEmits(['click']);
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2 ">
|
||||
<div class="text-foreground/80 leading-2 mt-3 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">注册时间:</span>
|
||||
</div>
|
||||
<div
|
||||
class="text-foreground/80 leading-2 mt-3 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.RegisterTime">
|
||||
<slot name="RegisterTime"></slot>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 leading-2 mt-3 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">最后登录:</span>
|
||||
</div>
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 justify-start p-1 leading-2">
|
||||
<div class="Value ">
|
||||
<div
|
||||
class="text-foreground/80 leading-2 mt-3 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.logintime">
|
||||
<slot name="logintime"></slot>
|
||||
</span>
|
||||
@ -71,11 +88,13 @@ defineEmits(['click']);
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<div class="text-foreground/80 leading-2 mt-3 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">累计在线:</span>
|
||||
</div>
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 justify-start p-1 leading-2">
|
||||
<div class="Value ">
|
||||
<div
|
||||
class="text-foreground/80 leading-2 mt-3 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.Cumulative">
|
||||
<slot name="Cumulative"></slot>
|
||||
</span>
|
||||
@ -84,11 +103,13 @@ defineEmits(['click']);
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<div class="text-foreground/80 leading-2 mt-3 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">今日累计在线:</span>
|
||||
</div>
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 justify-start p-1 leading-2">
|
||||
<div class="Value ">
|
||||
<div
|
||||
class="text-foreground/80 leading-2 mt-3 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.TodayCumulative">
|
||||
<slot name="TodayCumulative"></slot>
|
||||
</span>
|
||||
@ -97,13 +118,15 @@ defineEmits(['click']);
|
||||
</div>
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<span class="font-bold">Bonus:</span>
|
||||
<div class="text-foreground/80 leading-2 mt-3 flex h-4 p-1 md:w-1/2">
|
||||
<span class="font-bold">邀请码:</span>
|
||||
</div>
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 justify-start p-1 leading-2 text-shadow">
|
||||
<div class="Value ">
|
||||
<span v-if="$slots.Bonus">
|
||||
<slot name="Bonus"></slot>
|
||||
<div
|
||||
class="text-foreground/80 leading-2 text-shadow mt-3 flex h-4 justify-start p-1 md:w-1/2"
|
||||
>
|
||||
<div class="Value">
|
||||
<span v-if="$slots.Code">
|
||||
<slot name="Code"></slot>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -117,5 +140,4 @@ defineEmits(['click']);
|
||||
.Value {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user