版本更新
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
abab4f3637
commit
86037f0933
@ -77,6 +77,10 @@ export async function updateAppApi(AppId: number){
|
|||||||
return requestClient.post('/server/updateApp', {AppId: AppId}, {timeout: 120000});
|
return requestClient.post('/server/updateApp', {AppId: AppId}, {timeout: 120000});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateAppReviewApi(AppId: number){
|
||||||
|
return requestClient.post('/server/updateAppReview', {AppId: AppId}, {timeout: 120000});
|
||||||
|
}
|
||||||
|
|
||||||
export async function releaseApp(appId: number, appName: string){
|
export async function releaseApp(appId: number, appName: string){
|
||||||
return requestClient.post(`/server/release`, {AppId: appId, AppName: appName}, {timeout: 120000});
|
return requestClient.post(`/server/release`, {AppId: appId, AppName: appName}, {timeout: 120000});
|
||||||
}
|
}
|
||||||
@ -89,8 +93,8 @@ export async function reloadServer(appId: number, serverId: number, serverName:
|
|||||||
return requestClient.post(`/server/reload`, {AppId: appId, ServerId: serverId, ServerName: serverName}, {timeout: 120000});
|
return requestClient.post(`/server/reload`, {AppId: appId, ServerId: serverId, ServerName: serverName}, {timeout: 120000});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addServer(AppId:number, ServerId:number, ServerName: string, Status: number, OpenServerTime: number){
|
export async function addServer(AppId:number, ServerId:number, ServerName: string, Status: number, OpenServerTime: number, Host?: string, Port?: number, WsPort?: number, Version?: string, Ecs?: number, WorkDir?: string){
|
||||||
return requestClient.post(`/server/addServer`, {AppId:AppId, ServerId: ServerId, ServerName: ServerName, Status: Status, OpenServerTime: OpenServerTime});
|
return requestClient.post(`/server/addServer`, {AppId:AppId, ServerId: ServerId, ServerName: ServerName, Status: Status, OpenServerTime: OpenServerTime, Host: Host, Port: Port, WsPort: WsPort, ClientVersion: Version, Ecs: Ecs, WorkDir: WorkDir});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editServer(editParam: editServerParam){
|
export async function editServer(editParam: editServerParam){
|
||||||
|
|||||||
@ -57,6 +57,81 @@ const [Form, FormApi] = useVbenForm({
|
|||||||
label: 'ServerName:',
|
label: 'ServerName:',
|
||||||
formItemClass:'col-span-2',
|
formItemClass:'col-span-2',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'google.bywaystudios.com',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'Host',
|
||||||
|
label: 'Host',
|
||||||
|
formItemClass:'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '3601',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'Port',
|
||||||
|
label: 'Port',
|
||||||
|
formItemClass:'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '3701',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'WsPort',
|
||||||
|
label: 'WsPort',
|
||||||
|
formItemClass:'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '1.0.50',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'ClientVersion',
|
||||||
|
label: 'ClientVersion',
|
||||||
|
formItemClass:'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '/usr/local/game',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'WorkDir',
|
||||||
|
label: 'WorkDir',
|
||||||
|
formItemClass:'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'ECS-tencent',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'ECS-aliyun-us-silicon',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'Ecs',
|
||||||
|
label: 'Ecs',
|
||||||
|
formItemClass:'col-span-2',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
fieldName: 'datePicker',
|
fieldName: 'datePicker',
|
||||||
@ -134,7 +209,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
const dateTime = dayjs(`${date} ${time}`).valueOf()/1000;
|
const dateTime = dayjs(`${date} ${time}`).valueOf()/1000;
|
||||||
const modalData = modalApi.getData();
|
const modalData = modalApi.getData();
|
||||||
const ServerId = parseInt(values.ServerId, 10);
|
const ServerId = parseInt(values.ServerId, 10);
|
||||||
await addServer(modalData.AppId, ServerId, values.ServerName, values.Status, dateTime);
|
await addServer(modalData.AppId, ServerId, values.ServerName, values.Status, dateTime, values.Host, parseInt(values.Port,10), parseInt(values.WsPort,10), values.ClientVersion, values.Ecs, values.WorkDir);
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -30,6 +30,10 @@ function getColor(status: number) {
|
|||||||
return 'red';
|
return 'red';
|
||||||
case 1:
|
case 1:
|
||||||
return 'green';
|
return 'green';
|
||||||
|
case 2:
|
||||||
|
return 'gray';
|
||||||
|
case 3:
|
||||||
|
return 'orange';
|
||||||
default:
|
default:
|
||||||
return 'blue';
|
return 'blue';
|
||||||
}
|
}
|
||||||
@ -114,6 +118,21 @@ function confirmUpdate(Server: ServerData) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStatusName(status: number) {
|
||||||
|
switch (status){
|
||||||
|
case 0:
|
||||||
|
return 'Inactive';
|
||||||
|
case 1:
|
||||||
|
return 'Running';
|
||||||
|
case 2:
|
||||||
|
return 'Stopped';
|
||||||
|
case 3:
|
||||||
|
return 'Maintenance';
|
||||||
|
default:
|
||||||
|
return 'Unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@ -138,7 +157,7 @@ function confirmUpdate(Server: ServerData) {
|
|||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<Tag :color="getColor(item.Status || 0)">
|
<Tag :color="getColor(item.Status || 0)">
|
||||||
{{ item.Status == 0 ? 'Inactive' : item.Status == 1 ? 'Running' : 'Unknown' }}
|
{{ getStatusName(item.Status || 0) }}
|
||||||
</Tag>
|
</Tag>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
import { Button, Card, Space, notification } from 'ant-design-vue';
|
import { Button, Card, Space, notification, Modal } from 'ant-design-vue';
|
||||||
import { useVbenForm } from '#/adapter/form';
|
import { useVbenForm } from '#/adapter/form';
|
||||||
import AppList from './appList.vue';
|
import AppList from './appList.vue';
|
||||||
import { getServerListApi, getAppListApi, updateAppApi } from '#/api/core/server';
|
import { getServerListApi, getAppListApi, updateAppApi,updateAppReviewApi } from '#/api/core/server';
|
||||||
import type { AppData, ServerData } from '#/api/core/server';
|
import type { AppData, ServerData } from '#/api/core/server';
|
||||||
import { useVbenModal } from '@vben/common-ui'
|
import { useVbenModal } from '@vben/common-ui'
|
||||||
import { ref,onMounted } from 'vue';
|
import { ref,onMounted } from 'vue';
|
||||||
@ -69,7 +69,7 @@ const [addServerM, addServerApi] = useVbenModal({
|
|||||||
connectedComponent: addServerModal,
|
connectedComponent: addServerModal,
|
||||||
onClosed: async () => {
|
onClosed: async () => {
|
||||||
const Value = await BaseFormApi.getValues();
|
const Value = await BaseFormApi.getValues();
|
||||||
const serverResponse = await getServerListApi(Value.fieldOptions);
|
const serverResponse = await getServerListApi({AppId:Value.fieldOptions});
|
||||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||||
addServerApi.close();
|
addServerApi.close();
|
||||||
},
|
},
|
||||||
@ -99,6 +99,7 @@ const serverList = [
|
|||||||
const appList = ref<AppData[]>([]);
|
const appList = ref<AppData[]>([]);
|
||||||
const ServerList = ref<ServerData[]>([]);
|
const ServerList = ref<ServerData[]>([]);
|
||||||
const reload = ref(false);
|
const reload = ref(false);
|
||||||
|
const reloadReview = ref(false);
|
||||||
onMounted(async() => {
|
onMounted(async() => {
|
||||||
try{
|
try{
|
||||||
const response = await getAppListApi();
|
const response = await getAppListApi();
|
||||||
@ -137,7 +138,31 @@ async function addServer() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function confirmUpdate() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认更新',
|
||||||
|
content: `你确定要更新吗?`,
|
||||||
|
onOk() {
|
||||||
|
update();
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
//console.log('取消更新');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmUpdateReview() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认更新',
|
||||||
|
content: `你确定要更新吗?`,
|
||||||
|
onOk() {
|
||||||
|
updateReview();
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
//console.log('取消更新');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function update() {
|
async function update() {
|
||||||
reload.value = true;
|
reload.value = true;
|
||||||
@ -163,6 +188,31 @@ async function update() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateReview() {
|
||||||
|
reloadReview.value = true;
|
||||||
|
const Value = await BaseFormApi.getValues();
|
||||||
|
try{
|
||||||
|
await updateAppReviewApi(Value.fieldOptions);
|
||||||
|
reloadReview.value = false;
|
||||||
|
notification.info({
|
||||||
|
duration:10,
|
||||||
|
message:"服务器更新成功"
|
||||||
|
})
|
||||||
|
const response = await getAppListApi();
|
||||||
|
appList.value = Array.isArray(response) ? response : [];
|
||||||
|
const app = appList.value.find((item) => item.AppId === Value.fieldOptions);
|
||||||
|
if (!app) return;
|
||||||
|
const updateTime = dayjs((app.Update ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
BaseFormApi.setFieldValue("update", updateTime)
|
||||||
|
}catch(e){
|
||||||
|
reloadReview.value = false;
|
||||||
|
notification.error({
|
||||||
|
duration:10,
|
||||||
|
message:"服务器更新失败"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
@ -172,7 +222,8 @@ async function update() {
|
|||||||
<BaseForm />
|
<BaseForm />
|
||||||
<Space>
|
<Space>
|
||||||
<Button type="primary" @click="addServer">新增</Button>
|
<Button type="primary" @click="addServer">新增</Button>
|
||||||
<Button type="primary" @click="update" :loading="reload"> 更新 </Button>
|
<Button type="primary" @click="confirmUpdate" :loading="reload"> 更新正式环境 </Button>
|
||||||
|
<Button type="primary" @click="confirmUpdateReview" :loading="reloadReview"> 更新review环境 </Button>
|
||||||
<Button type="primary"> 更新配置 </Button>
|
<Button type="primary"> 更新配置 </Button>
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import type { VxeGridProps, VxeGridListeners } from '#/adapter/vxe-table';
|
import type { VxeGridProps, VxeGridListeners } from '#/adapter/vxe-table';
|
||||||
import { Button, notification,Image } from 'ant-design-vue';
|
import { Button, notification,Image } from 'ant-design-vue';
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
import { getLanguageList, exportLanguageFile, saveLanguageList, deleteLanguageItem } from '#/api/core/statistics';
|
import { getLanguageList, saveLanguageList, deleteLanguageItem } from '#/api/core/statistics';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import addLanguage from './addLanguage.vue';
|
import addLanguage from './addLanguage.vue';
|
||||||
import type { VbenFormProps } from '#/adapter/form';
|
import type { VbenFormProps } from '#/adapter/form';
|
||||||
@ -97,15 +97,12 @@ const formOptions: VbenFormProps = {
|
|||||||
},
|
},
|
||||||
wrapperClass: 'grid-cols-1 md:grid-cols-5',
|
wrapperClass: 'grid-cols-1 md:grid-cols-5',
|
||||||
// 是否在字段值改变时提交表单
|
// 是否在字段值改变时提交表单
|
||||||
submitOnChange: true,
|
submitOnChange: false,
|
||||||
// 按下回车时是否提交表单
|
// 按下回车时是否提交表单
|
||||||
submitOnEnter: false,
|
submitOnEnter: false,
|
||||||
}
|
}
|
||||||
const gridOptions: VxeGridProps<languageType> = {
|
const gridOptions: VxeGridProps<languageType> = {
|
||||||
border: true,
|
border: true,
|
||||||
cellConfig:{
|
|
||||||
height:60,
|
|
||||||
},
|
|
||||||
columns: [
|
columns: [
|
||||||
{ title: 'Id', field: 'Id', width: 100 },
|
{ title: 'Id', field: 'Id', width: 100 },
|
||||||
{ editRender: { name: 'input' }, field: 'key', title: 'key', filters: [{ data: "" }], filterRender: { name: "input" }, visible: keyVisible },
|
{ editRender: { name: 'input' }, field: 'key', title: 'key', filters: [{ data: "" }], filterRender: { name: "input" }, visible: keyVisible },
|
||||||
@ -317,7 +314,7 @@ const gridOptions: VxeGridProps<languageType> = {
|
|||||||
pageSizes: [40, 80, 100, 200, 500, 1000],
|
pageSizes: [40, 80, 100, 200, 500, 1000],
|
||||||
},
|
},
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
showOverflow: true,
|
showOverflow: false,
|
||||||
};
|
};
|
||||||
const gridEvents: VxeGridListeners<languageType> = {
|
const gridEvents: VxeGridListeners<languageType> = {
|
||||||
editClosed: ({ row, column }) => {
|
editClosed: ({ row, column }) => {
|
||||||
@ -374,23 +371,6 @@ function saveAll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function exportLang() {
|
|
||||||
exportLanguageFile().then((response) => {
|
|
||||||
const code = response.code || 0;
|
|
||||||
const msg = response.msg || '';
|
|
||||||
if (code !== 0) {
|
|
||||||
notification.error({
|
|
||||||
duration: 10,
|
|
||||||
message: msg,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
notification.success({
|
|
||||||
duration: 10,
|
|
||||||
message: $t('page.language.exportSuccess'),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function deleteRow(row: languageType) {
|
function deleteRow(row: languageType) {
|
||||||
deleteLanguageItem({ key: row.key }).then((response) => {
|
deleteLanguageItem({ key: row.key }).then((response) => {
|
||||||
const code = response.code || 0;
|
const code = response.code || 0;
|
||||||
|
|||||||
@ -115,7 +115,7 @@ const gridOptions: VxeGridProps<MailData> = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
showOverflow: false,
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
isHover: true,
|
isHover: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
import { Button, Card, Space, notification, Tag } from 'ant-design-vue';
|
import { Button, Card, Space, notification, Tag } from 'ant-design-vue';
|
||||||
import { useVbenDrawer, VbenButton } from '@vben/common-ui';
|
import { useVbenDrawer, VbenButton } from '@vben/common-ui';
|
||||||
import ExtraDrawer from './drawer.vue';
|
import ExtraDrawer from './drawer.vue';
|
||||||
const [Drawer, drawerApi] = useVbenDrawer({
|
const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
@ -8,7 +8,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
function startScript(id:number) {
|
function startScript(id: number) {
|
||||||
notification.success({
|
notification.success({
|
||||||
message: '脚本已启动',
|
message: '脚本已启动',
|
||||||
description: '文案自动化脚本已成功启动,正在运行中。',
|
description: '文案自动化脚本已成功启动,正在运行中。',
|
||||||
@ -35,16 +35,12 @@ function startScript(id:number) {
|
|||||||
<span>Script Name</span>
|
<span>Script Name</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
<div class="flex flex-col justify-center md:mt-0 lg:w-3/12">
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<span>TAGS</span>
|
<span>TAGS</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
|
||||||
<span>Last Running</span>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<span>Start</span>
|
<span>Start</span>
|
||||||
@ -60,16 +56,12 @@ function startScript(id:number) {
|
|||||||
<span>文案自动化脚本</span>
|
<span>文案自动化脚本</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
<div class="flex flex-col justify-center md:mt-0 lg:w-3/12">
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<Tag>xlsx</Tag>
|
<Tag>xlsx</Tag><Tag>文案</Tag><Tag>策划</Tag>
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
|
||||||
<span>2026-01-01 12:00:00</span>
|
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<Button type="primary" @click="startScript(1)">Start</Button>
|
<Button type="primary" @click="startScript(1)">Start</Button>
|
||||||
@ -79,5 +71,5 @@ function startScript(id:number) {
|
|||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
250
apps/web-antd/src/views/userlog/userlist/asset-table.vue
Normal file
250
apps/web-antd/src/views/userlog/userlist/asset-table.vue
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
import type { VxeGridListeners } from '#/adapter/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;
|
||||||
|
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);
|
||||||
|
return ItemData.find((item) => item.Id === cellValue)?.Name || cellValue;
|
||||||
|
}
|
||||||
|
const d = ref({
|
||||||
|
sum: 0,
|
||||||
|
psum: 0,
|
||||||
|
nsum: 0,
|
||||||
|
});
|
||||||
|
const startDate = dayjs().startOf('day');
|
||||||
|
const endDate = dayjs().endOf('day');
|
||||||
|
const itemIdOptions = ref([
|
||||||
|
{ label: '能量', value: 100001 },
|
||||||
|
{ label: '宠物币', value: 100002 },
|
||||||
|
{ label: '钻石', value: 100003 },
|
||||||
|
]);
|
||||||
|
const formOptions: VbenFormProps = {
|
||||||
|
// 所有表单项共用,可单独在表单内覆盖
|
||||||
|
commonConfig: {
|
||||||
|
// 所有表单项
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
// 默认展开
|
||||||
|
collapsed: false,
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
disabled: true,
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'Uid',
|
||||||
|
},
|
||||||
|
defaultValue: state.uid,
|
||||||
|
fieldName: 'Uid',
|
||||||
|
label: 'Uid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'DatePicker',
|
||||||
|
defaultValue: startDate,
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
fieldName: 'StartTime',
|
||||||
|
label: '开始时间',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
component: 'DatePicker',
|
||||||
|
defaultValue: endDate,
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
fieldName: 'EndTime',
|
||||||
|
label: '结束时间',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: itemIdOptions,
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
fieldName: 'ItemId',
|
||||||
|
label: '道具id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '增加', value: 'gain' },
|
||||||
|
{ label: '减少', value: 'consume' },
|
||||||
|
],
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
fieldName: 'Event',
|
||||||
|
label: '变化类型',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 控制表单是否显示折叠按钮
|
||||||
|
showCollapseButton: true,
|
||||||
|
submitButtonOptions: {
|
||||||
|
content: '查询',
|
||||||
|
},
|
||||||
|
// 是否在字段值改变时提交表单
|
||||||
|
submitOnChange: false,
|
||||||
|
// 按下回车时是否提交表单
|
||||||
|
submitOnEnter: false,
|
||||||
|
}
|
||||||
|
const gridEvents: VxeGridListeners<RowType> = {
|
||||||
|
cellDblclick: async ({ row }) => {
|
||||||
|
console.log(row);
|
||||||
|
modalApi.setData({
|
||||||
|
StartTime: row.timestamp,
|
||||||
|
EndTime: row.timestamp,
|
||||||
|
});
|
||||||
|
modalApi.open();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const gridOptions: VxeGridProps<RowType> = {
|
||||||
|
columns: [
|
||||||
|
{ field: 'Uid', title: 'Uid', align: 'center' },
|
||||||
|
{ field: 'change_type', title: '变化类型', formatter: ({ cellValue }) => formatType(cellValue), align: 'center' },
|
||||||
|
{ field: 'change_num', title: '变化数值', align: 'center' },
|
||||||
|
{ field: 'change_after', title: '变化后数值', align: 'center' },
|
||||||
|
{ field: 'item_id', title: '道具名称', formatter: ({ cellValue }) => formatItemName(cellValue), align: 'center' },
|
||||||
|
{ field: 'item_id', title: '道具id', align: 'center' },
|
||||||
|
{ field: 'timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue * 1000).toLocaleString(), align: 'center' },
|
||||||
|
],
|
||||||
|
stripe: true,
|
||||||
|
round: true,
|
||||||
|
height: 'auto',
|
||||||
|
exportConfig: {
|
||||||
|
filename: '用户资产日志',
|
||||||
|
type: 'csv',
|
||||||
|
mode: 'current',
|
||||||
|
download: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
custom: true,
|
||||||
|
export: true,
|
||||||
|
refresh: true,
|
||||||
|
zoom: true,
|
||||||
|
},
|
||||||
|
pagerConfig: {},
|
||||||
|
proxyConfig: {
|
||||||
|
response: {
|
||||||
|
total: "total",
|
||||||
|
result: "data"
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }, formValues) => {
|
||||||
|
let uid = parseInt(formValues.Uid, 10);
|
||||||
|
if (uid == 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
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.unix(),
|
||||||
|
EndTime: formValues.EndTime.unix(),
|
||||||
|
ItemId: ItemId,
|
||||||
|
CurrentPage: page.currentPage,
|
||||||
|
PageSize: page.pageSize,
|
||||||
|
});
|
||||||
|
// 动态收集 item_id 与 item_name 生成下拉
|
||||||
|
if (Array.isArray(r.data)) {
|
||||||
|
itemIdOptions.value = [
|
||||||
|
{ label: '能量', value: 100001 },
|
||||||
|
{ label: '宠物币', value: 100002 },
|
||||||
|
{ label: '钻石', value: 100003 },
|
||||||
|
];
|
||||||
|
const exist = new Set(itemIdOptions.value.map(o => String(o.value)));
|
||||||
|
for (const row of r.data as any[]) {
|
||||||
|
const idRaw = (row as any).item_id;
|
||||||
|
const nameRaw = String(formatItemName(idRaw));
|
||||||
|
if (idRaw !== undefined && idRaw !== null) {
|
||||||
|
const idStr = String(idRaw);
|
||||||
|
if (!exist.has(idStr)) {
|
||||||
|
exist.add(idStr);
|
||||||
|
itemIdOptions.value.push({
|
||||||
|
label: nameRaw,
|
||||||
|
value: parseInt(idStr, 10) || idRaw,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.value.sum = r.sum;
|
||||||
|
d.value.psum = r.psum;
|
||||||
|
d.value.nsum = r.nsum;
|
||||||
|
return r
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rowConfig: {
|
||||||
|
isHover: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Page auto-content-height class="h-[800px]">
|
||||||
|
<Grid>
|
||||||
|
<template #empty>
|
||||||
|
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;">
|
||||||
|
<img src="https://n.sinaimg.cn/sinacn17/w120h120/20180314/89fc-fyscsmv5911424.gif" alt="no-data"
|
||||||
|
style="max-width:200px;display:block;">
|
||||||
|
<p style="margin:8px 0 0;">没有更多数据了!</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<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>
|
||||||
|
<Modal class="w-[1200px]"> </Modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
173
apps/web-antd/src/views/userlog/userlist/event-table.vue
Normal file
173
apps/web-antd/src/views/userlog/userlist/event-table.vue
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import { getUserlogEventApi } from '#/api/core/log';
|
||||||
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
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, 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 {
|
||||||
|
Uid: string;
|
||||||
|
Event: string;
|
||||||
|
Param: string;
|
||||||
|
Timestamp: string;
|
||||||
|
}
|
||||||
|
const formOptions: VbenFormProps = {
|
||||||
|
// 默认展开
|
||||||
|
collapsed: false,
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
disabled: true,
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'Uid',
|
||||||
|
},
|
||||||
|
defaultValue: state.uid,
|
||||||
|
fieldName: 'Uid',
|
||||||
|
label: 'Uid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'Event',
|
||||||
|
},
|
||||||
|
defaultValue: state.Event,
|
||||||
|
fieldName: 'Event',
|
||||||
|
label: '事件类型',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'DatePicker',
|
||||||
|
defaultValue: startDate,
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
fieldName: 'StartTime',
|
||||||
|
label: '开始时间',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'DatePicker',
|
||||||
|
defaultValue: endDate,
|
||||||
|
componentProps: {
|
||||||
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
},
|
||||||
|
fieldName: 'EndTime',
|
||||||
|
label: '结束时间',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// 控制表单是否显示折叠按钮
|
||||||
|
showCollapseButton: true,
|
||||||
|
submitButtonOptions: {
|
||||||
|
content: '查询',
|
||||||
|
},
|
||||||
|
// 是否在字段值改变时提交表单
|
||||||
|
submitOnChange: false,
|
||||||
|
// 按下回车时是否提交表单
|
||||||
|
submitOnEnter: false,
|
||||||
|
wrapperClass: 'grid-cols-1 md:grid-cols-5',
|
||||||
|
}
|
||||||
|
const gridEvents: VxeGridListeners<RowType> = {
|
||||||
|
cellDblclick: 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: '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: '800px',
|
||||||
|
pagerConfig: {},
|
||||||
|
proxyConfig: {
|
||||||
|
response: {
|
||||||
|
total: "total",
|
||||||
|
result: "data"
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }, formValues) => {
|
||||||
|
let Uid = parseInt(formValues.Uid, 10);
|
||||||
|
if (Uid == 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
state.uid = Uid;
|
||||||
|
state.Event = formValues.Event;
|
||||||
|
let startTimeUnix = 0;
|
||||||
|
let endTimeUnix = 0;
|
||||||
|
// formValues.StartTime/EndTime 可能是 string(当 DatePicker 设置了 valueFormat 时)
|
||||||
|
// 也可能是 dayjs 对象(未设置 valueFormat 时)
|
||||||
|
if (formValues.StartTime) {
|
||||||
|
if (typeof formValues.StartTime === 'string') {
|
||||||
|
startTimeUnix = dayjs(formValues.StartTime).unix();
|
||||||
|
} else if (dayjs.isDayjs(formValues.StartTime)) {
|
||||||
|
startTimeUnix = formValues.StartTime.unix();
|
||||||
|
} else if (typeof (formValues.StartTime as any).unix === 'function') {
|
||||||
|
startTimeUnix = (formValues.StartTime as any).unix();
|
||||||
|
} else {
|
||||||
|
startTimeUnix = dayjs(formValues.StartTime).unix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (formValues.EndTime) {
|
||||||
|
if (typeof formValues.EndTime === 'string') {
|
||||||
|
endTimeUnix = dayjs(formValues.EndTime).unix();
|
||||||
|
} else if (dayjs.isDayjs(formValues.EndTime)) {
|
||||||
|
endTimeUnix = formValues.EndTime.unix();
|
||||||
|
} else if (typeof (formValues.EndTime as any).unix === 'function') {
|
||||||
|
endTimeUnix = (formValues.EndTime as any).unix();
|
||||||
|
} else {
|
||||||
|
endTimeUnix = dayjs(formValues.EndTime).unix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 使用计算好的 unix 时间调用接口
|
||||||
|
return await getUserlogEventApi({
|
||||||
|
Id: Uid,
|
||||||
|
Event: formValues.Event,
|
||||||
|
StartTime: startTimeUnix,
|
||||||
|
EndTime: endTimeUnix,
|
||||||
|
CurrentPage: page.currentPage,
|
||||||
|
PageSize: page.pageSize,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rowConfig: {
|
||||||
|
isHover: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Page class="h-[800px]">
|
||||||
|
<Grid />
|
||||||
|
</Page>
|
||||||
|
<Modal class="w-[800px]"> </Modal>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
150
apps/web-antd/src/views/userlog/userlist/order-table.vue
Normal file
150
apps/web-antd/src/views/userlog/userlist/order-table.vue
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { VbenFormProps } from '#/adapter/form';
|
||||||
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
import type { AppData } from '#/api/core/server';
|
||||||
|
|
||||||
|
import { inject, onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
import { getUserlogOrderApi } from '#/api/core/log';
|
||||||
|
import { getAppListApi } from '#/api/core/server';
|
||||||
|
import { globalState } from '#/store/globalState';
|
||||||
|
import { rechargeData } from '#/store/recharge';
|
||||||
|
|
||||||
|
const state = inject('globalState', globalState);
|
||||||
|
|
||||||
|
interface RowType {
|
||||||
|
Uid: string;
|
||||||
|
Event: string;
|
||||||
|
Param: string;
|
||||||
|
timestamp: string;
|
||||||
|
}
|
||||||
|
const appList = ref<AppData[]>([]);
|
||||||
|
|
||||||
|
const formOptions: VbenFormProps = {
|
||||||
|
// 默认展开
|
||||||
|
collapsed: false,
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
disabled: true,
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'Uid',
|
||||||
|
},
|
||||||
|
defaultValue: state.uid,
|
||||||
|
fieldName: 'Uid',
|
||||||
|
label: 'Uid',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 控制表单是否显示折叠按钮
|
||||||
|
showCollapseButton: false,
|
||||||
|
submitButtonOptions: {
|
||||||
|
show:false,
|
||||||
|
},
|
||||||
|
resetButtonOptions: {
|
||||||
|
show:false,
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
const gridOptions: VxeGridProps<RowType> = {
|
||||||
|
columns: [
|
||||||
|
{ field: 'Uid', title: 'id' },
|
||||||
|
{ field: 'OrderId', title: '订单号' },
|
||||||
|
{ field: 'PayChannelOrderId', title: '3th订单号' },
|
||||||
|
{ field: 'Price', title: '金额' },
|
||||||
|
{
|
||||||
|
field: 'ProductId',
|
||||||
|
title: 'chargeId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return rechargeData[cellValue] || cellValue;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'CreateTimeStr', title: '创建时间' },
|
||||||
|
{ field: 'PayTimeStr', title: '支付时间' },
|
||||||
|
{
|
||||||
|
field: 'PayType',
|
||||||
|
title: '支付类型',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
if (cellValue === 0) return '谷歌';
|
||||||
|
if (cellValue === 1) return '微信';
|
||||||
|
if (cellValue === 2) return '支付宝';
|
||||||
|
if (cellValue === 3) return '苹果内购';
|
||||||
|
return cellValue;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'Param', title: '参数' },
|
||||||
|
],
|
||||||
|
exportConfig: {
|
||||||
|
filename: '用户订单日志',
|
||||||
|
type: 'csv',
|
||||||
|
mode: 'current',
|
||||||
|
download: true,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
custom: true,
|
||||||
|
export: true,
|
||||||
|
refresh: true,
|
||||||
|
zoom: true,
|
||||||
|
},
|
||||||
|
stripe: true,
|
||||||
|
height: 'auto',
|
||||||
|
pagerConfig: {},
|
||||||
|
proxyConfig: {
|
||||||
|
response: {
|
||||||
|
total: 'total',
|
||||||
|
result: 'data',
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }, formValues) => {
|
||||||
|
const Uid = Number.parseInt(formValues.Uid, 10);
|
||||||
|
state.uid = Uid;
|
||||||
|
state.Event = formValues.Event;
|
||||||
|
return await getUserlogOrderApi({
|
||||||
|
Id: Uid,
|
||||||
|
Event: formValues.Event,
|
||||||
|
CurrentPage: page.currentPage,
|
||||||
|
PageSize: page.pageSize,
|
||||||
|
AppId: 1,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
rowConfig: {
|
||||||
|
isHover: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const [Grid, GridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
const response = await getAppListApi();
|
||||||
|
appList.value = Array.isArray(response) ? response : [];
|
||||||
|
const app = appList.value[0];
|
||||||
|
if (!app) return;
|
||||||
|
GridApi.formApi.updateSchema([
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: appList.value.map((item) => ({
|
||||||
|
label: item.AppName,
|
||||||
|
value: item.AppId,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
fieldName: 'AppId',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
} catch {
|
||||||
|
appList.value = [];
|
||||||
|
// console.log(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Page auto-content-height class="h-[800px]">
|
||||||
|
<Grid />
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
@ -4,7 +4,7 @@ import MergeData from '#/store/MergeData.json';
|
|||||||
import { orderTypeData, orderDiffData } from '#/store/order';
|
import { orderTypeData, orderDiffData } from '#/store/order';
|
||||||
import { faceTypeData } from '#/store/face';
|
import { faceTypeData } from '#/store/face';
|
||||||
import { useVbenModal, useVbenForm, WorkbenchTrends } from '@vben/common-ui';
|
import { useVbenModal, useVbenForm, WorkbenchTrends } from '@vben/common-ui';
|
||||||
import { message, Card } from 'ant-design-vue';
|
import { message, Card, Tabs } from 'ant-design-vue';
|
||||||
import { getUserlogInfoApi } from '#/api/core/log';
|
import { getUserlogInfoApi } from '#/api/core/log';
|
||||||
import { userGmApi, userBanApi } from '#/api/core/user';
|
import { userGmApi, userBanApi } from '#/api/core/user';
|
||||||
import { calendar } from '#/component/index';
|
import { calendar } from '#/component/index';
|
||||||
@ -18,7 +18,9 @@ import dayjs from 'dayjs';
|
|||||||
import { WorkbenchDetail } from '@vben/common-ui';
|
import { WorkbenchDetail } from '@vben/common-ui';
|
||||||
import UserHeader from './user-header.vue';
|
import UserHeader from './user-header.vue';
|
||||||
import { AccessControl } from '@vben/access';
|
import { AccessControl } from '@vben/access';
|
||||||
|
import eventTable from './event-table.vue';
|
||||||
|
import assetTable from './asset-table.vue';
|
||||||
|
import orderTable from './order-table.vue';
|
||||||
|
|
||||||
|
|
||||||
// 这是一个示例数据,实际项目中需要根据实际情况进行调整
|
// 这是一个示例数据,实际项目中需要根据实际情况进行调整
|
||||||
@ -252,6 +254,7 @@ let trendItems: WorkbenchTrendItem[] = [
|
|||||||
|
|
||||||
];
|
];
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
fullscreen: true,
|
||||||
onCancel() {
|
onCancel() {
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
@ -464,57 +467,62 @@ watch(
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal title="玩家详情">
|
<Modal title="玩家详情" class="h-[100%]">
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<UserHeader :avatar="info.Face" :ban="info.Ban">
|
<Tabs>
|
||||||
<template #nick_name> nick_name: {{ info.Name || 'N/A' }} </template>
|
<Tabs.TabPane key="1" tab="玩家信息">
|
||||||
<template #user_name> user_name: {{ info.Mac }} </template>
|
<UserHeader :avatar="info.Face" :ban="info.Ban">
|
||||||
<template #uid> uid: {{ info.Uid }} </template>
|
<template #nick_name> nick_name: {{ info.Name || 'N/A' }} </template>
|
||||||
<template #level>{{ info.Level }}</template>
|
<template #user_name> user_name: {{ info.Mac }} </template>
|
||||||
<template #star>{{ info.Star }}</template>
|
<template #uid> uid: {{ info.Uid }} </template>
|
||||||
<template #energy>{{ info.Energy }} </template>
|
<template #level>{{ info.Level }}</template>
|
||||||
<template #diamond>{{ info.Diamond }}</template>
|
<template #star>{{ info.Star }}</template>
|
||||||
</UserHeader>
|
<template #energy>{{ info.Energy }} </template>
|
||||||
<AccessControl :codes="['super', 'admin']" type="role">
|
<template #diamond>{{ info.Diamond }}</template>
|
||||||
<div class="mt-5 flex">
|
</UserHeader>
|
||||||
<Card class="card-box flex flex-col p-5 w-[50%]">
|
<AccessControl :codes="['super', 'admin']" type="role">
|
||||||
<BaseForm />
|
<div class="mt-5 flex">
|
||||||
</Card>
|
<Card class="card-box flex flex-col p-5 w-[50%]">
|
||||||
<Card class="card-box flex flex-col p-5 w-[45%] ml-5">
|
<BaseForm />
|
||||||
<BanForm />
|
</Card>
|
||||||
</Card>
|
<Card class="card-box flex flex-col p-5 w-[45%] ml-5">
|
||||||
</div>
|
<BanForm />
|
||||||
</AccessControl>
|
</Card>
|
||||||
<div class="mt-5 flex flex-col lg:flex-row">
|
</div>
|
||||||
<div class="mr-4 w-full lg:w-3/5">
|
</AccessControl>
|
||||||
<orderComponent :items="info.Order" title="订单" />
|
<div class="mt-5 flex flex-col lg:flex-row">
|
||||||
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
<div class="mr-4 w-full lg:w-3/5">
|
||||||
</div>
|
<orderComponent :items="info.Order" title="订单" />
|
||||||
<div class="w-full lg:w-2/5">
|
<WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
|
||||||
<WorkbenchDetail :items="projectItems" class="mt-5 lg:mt-0" title="玩家详情">
|
</div>
|
||||||
<template #areaid> {{ info.AreaId }}</template>
|
<div class="w-full lg:w-2/5">
|
||||||
<template #charge> <b>$</b>{{ chargeDisplay }}</template>
|
<WorkbenchDetail :items="projectItems" class="mt-5 lg:mt-0" title="玩家详情">
|
||||||
<template #RegisterTime> {{ info.RegisterTime }}</template>
|
<template #areaid> {{ info.AreaId }}</template>
|
||||||
<template #logintime> {{ info.LoginTime }}</template>
|
<template #charge> <b>$</b>{{ chargeDisplay }}</template>
|
||||||
<template #Cumulative>{{ info.Cumulative }}</template>
|
<template #RegisterTime> {{ info.RegisterTime }}</template>
|
||||||
<template #AreaId>{{ info.AreaId }}</template>
|
<template #logintime> {{ info.LoginTime }}</template>
|
||||||
<template #Code>{{ info.Code || 0 }}</template>
|
<template #Cumulative>{{ info.Cumulative }}</template>
|
||||||
<template #TodayCumulative>{{ info.TodayCumulative }}</template>
|
<template #AreaId>{{ info.AreaId }}</template>
|
||||||
</WorkbenchDetail>
|
<template #Code>{{ info.Code || 0 }}</template>
|
||||||
<chessComponent :items="info.Chess" title="棋盘" class="mt-6" />
|
<template #TodayCumulative>{{ info.TodayCumulative }}</template>
|
||||||
<calendar v-if="info.Heatmap.length > 0" style="margin-top: 15px" :dataList="info.Heatmap" title="热力图"
|
</WorkbenchDetail>
|
||||||
:key="`heatmap-${info.Uid}`" />
|
<chessComponent :items="info.Chess" title="棋盘" class="mt-6" />
|
||||||
<div v-else style="
|
<!-- <WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" /> -->
|
||||||
margin-top: 15px;
|
</div>
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
color: #999;
|
|
||||||
">
|
|
||||||
暂无热力图数据
|
|
||||||
</div>
|
</div>
|
||||||
<!-- <WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" /> -->
|
|
||||||
</div>
|
</Tabs.TabPane>
|
||||||
</div>
|
<Tabs.TabPane key="2" tab="操作日志">
|
||||||
|
<eventTable :uid="info.Uid" :serverId="data?.Node" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
<Tabs.TabPane key="3" tab="资产日志">
|
||||||
|
<assetTable :uid="info.Uid" :serverId="data?.Node" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
<Tabs.TabPane key="4" tab="订单日志">
|
||||||
|
<orderTable :uid="info.Uid" :serverId="data?.Node" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -12,6 +12,8 @@ import { onMounted, ref, inject } from 'vue';
|
|||||||
import { globalState } from '#/store/globalState';
|
import { globalState } from '#/store/globalState';
|
||||||
import { getServerListApi, getAppListApi } from '#/api/core/server';
|
import { getServerListApi, getAppListApi } from '#/api/core/server';
|
||||||
import type { AppData, ServerData } from '#/api/core/server';
|
import type { AppData, ServerData } from '#/api/core/server';
|
||||||
|
import { $t } from '#/locales'
|
||||||
|
|
||||||
const state = inject('globalState', globalState);
|
const state = inject('globalState', globalState);
|
||||||
const appList = ref<AppData[]>([]);
|
const appList = ref<AppData[]>([]);
|
||||||
const ServerList = ref<ServerData[]>([]);
|
const ServerList = ref<ServerData[]>([]);
|
||||||
@ -142,7 +144,7 @@ const gridEvents: VxeGridListeners<RowType> = {
|
|||||||
|
|
||||||
const gridOptions: VxeGridProps<RowType> = {
|
const gridOptions: VxeGridProps<RowType> = {
|
||||||
columns: [
|
columns: [
|
||||||
{ field: 'Uid', title: 'id' },
|
{ field: 'Uid', title: 'id' , sortable: true, sortBy: 'Uid'},
|
||||||
{ field: 'UserName', title: '登录名' },
|
{ field: 'UserName', title: '登录名' },
|
||||||
{ field: 'Level', title: '等级', formatter: ({ cellValue }) => `${cellValue} 级`, sortable: true, sortBy: 'Level' },
|
{ field: 'Level', title: '等级', formatter: ({ cellValue }) => `${cellValue} 级`, sortable: true, sortBy: 'Level' },
|
||||||
{ field: 'Node', title: '节点', },
|
{ field: 'Node', title: '节点', },
|
||||||
@ -150,8 +152,8 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
{ field: 'Diamond', title: '钻石', formatter: ({ cellValue }) => `${cellValue} 💎`, sortable: true, sortBy: 'Diamond' },
|
{ field: 'Diamond', title: '钻石', formatter: ({ cellValue }) => `${cellValue} 💎`, sortable: true, sortBy: 'Diamond' },
|
||||||
{ field: 'Star', title: '星星', formatter: ({ cellValue }) => `${cellValue} ⭐`, sortable: true, sortBy: 'Star' },
|
{ field: 'Star', title: '星星', formatter: ({ cellValue }) => `${cellValue} ⭐`, sortable: true, sortBy: 'Star' },
|
||||||
{ field: 'Energy', title: '能量', formatter: ({ cellValue }) => `${cellValue} ⚡`, sortable: true, sortBy: 'Energy' },
|
{ field: 'Energy', title: '能量', formatter: ({ cellValue }) => `${cellValue} ⚡`, sortable: true, sortBy: 'Energy' },
|
||||||
{ field: 'LoginTime', sortable: true, title: '登录时间', formatter: ({ cellValue }) => dayjs(cellValue * 1000).format('YYYY-MM-DD HH:mm:ss') },
|
{ field: 'LoginTime', sortable: true, title: '登录时间', formatter: ({ cellValue }) => dayjs(cellValue * 1000).format('YYYY-MM-DD HH:mm:ss'),sortBy: 'LoginTime' },
|
||||||
{ field: 'Online', title: '在线状态', slots: { default: 'online' } },
|
{ field: 'Online', title: '在线状态', slots: { default: 'online' } , sortable: true, sortBy: 'Online' },
|
||||||
],
|
],
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
pagerConfig: {},
|
pagerConfig: {},
|
||||||
@ -200,7 +202,7 @@ onMounted(async () => {
|
|||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
options: appList.value.map((item) => ({
|
options: appList.value.map((item) => ({
|
||||||
label: item.AppName,
|
label: $t('page.server.' + item.AppName),
|
||||||
value: item.AppId,
|
value: item.AppId,
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
@ -233,13 +235,13 @@ function getTagColor(online: string): string {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height class="h-[800px]">
|
<Page auto-content-height class="h-[1200px]">
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #online="{ row }">
|
<template #online="{ row }">
|
||||||
<Tag :color="getTagColor(row.Online)">{{ row.Online }}</Tag>
|
<Tag :color="getTagColor(row.Online)">{{ row.Online }}</Tag>
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
<userModal class="w-[98%]" />
|
<userModal class="w-[100%]" />
|
||||||
</Page>
|
</Page>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user