update
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
29aeb8fa29
commit
1dc256452e
@ -14,3 +14,5 @@ VITE_DEVTOOLS=false
|
|||||||
|
|
||||||
# 是否注入全局loading
|
# 是否注入全局loading
|
||||||
VITE_INJECT_APP_LOADING=true
|
VITE_INJECT_APP_LOADING=true
|
||||||
|
|
||||||
|
VITE_PUBLIC_SRC_PATH=../../public
|
||||||
|
|||||||
3
apps/web-antd/.vscode/settings.json
vendored
3
apps/web-antd/.vscode/settings.json
vendored
@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"workbench.colorTheme": "GitHub Light Colorblind (Beta)"
|
"workbench.colorTheme":"One Dark Pro",
|
||||||
|
"editor.fontSize": 14
|
||||||
}
|
}
|
||||||
@ -13,9 +13,10 @@ export interface UserLogAssetParam {
|
|||||||
StartTime?: number;
|
StartTime?: number;
|
||||||
EndTime?: number;
|
EndTime?: number;
|
||||||
ItemId?: number;
|
ItemId?: number;
|
||||||
PageSize: number;
|
PageSize?: number;
|
||||||
CurrentPage: number;
|
CurrentPage?: number;
|
||||||
AppId?: number;
|
AppId?: number;
|
||||||
|
Node?: number;
|
||||||
}
|
}
|
||||||
export interface UserLogOrder {
|
export interface UserLogOrder {
|
||||||
Id: number;
|
Id: number;
|
||||||
|
|||||||
@ -24,6 +24,10 @@ export interface ServerData {
|
|||||||
PlayerNum?: number;
|
PlayerNum?: number;
|
||||||
Loading?:boolean;
|
Loading?:boolean;
|
||||||
Reload?:boolean;
|
Reload?:boolean;
|
||||||
|
CpuUsage?: number;
|
||||||
|
MemUsage?: number;
|
||||||
|
ClientVersion?: string;
|
||||||
|
Tags?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeData{
|
export interface NodeData{
|
||||||
|
|||||||
@ -15,6 +15,7 @@ export interface UserListParam {
|
|||||||
currentPage: number;
|
currentPage: number;
|
||||||
StartTime?: number;
|
StartTime?: number;
|
||||||
EndTime?: number;
|
EndTime?: number;
|
||||||
|
Nickname?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -52,6 +52,7 @@ export interface languageType {
|
|||||||
en_US: string;
|
en_US: string;
|
||||||
zh_CN: string;
|
zh_CN: string;
|
||||||
pt_BR: string;
|
pt_BR: string;
|
||||||
|
url?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
52
apps/web-antd/src/store/util.ts
Normal file
52
apps/web-antd/src/store/util.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import MergeData from "./MergeData.json";
|
||||||
|
|
||||||
|
export function getImageUrl(key: string): string {
|
||||||
|
if (!key) return "";
|
||||||
|
|
||||||
|
// 1. 判断 key 是否为 UI_MergeData_<number> 格式,取出数字;同时支持直接传入数字字符串或数字
|
||||||
|
let id: string | null = null;
|
||||||
|
const m = /^UI_MergeData_(\d+)$/.exec(key);
|
||||||
|
if (m) id = m[1] ?? "";
|
||||||
|
else if (/^\d+$/.test(key)) id = key;
|
||||||
|
else id = String(key);
|
||||||
|
|
||||||
|
// 2. 从 MergeData 中取出 id 对应的 Icon
|
||||||
|
const item = (MergeData as any)[id];
|
||||||
|
const icon = item && typeof item.Icon === 'string' ? item.Icon : '';
|
||||||
|
if (!icon) return '';
|
||||||
|
|
||||||
|
// 3. 在 Node 环境中遍历指定文件夹寻找包含 Icon 名称的文件并返回绝对路径
|
||||||
|
// 如果不在 Node 环境(例如浏览器),则回退返回 icon 字符串
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
const fs = require('fs');
|
||||||
|
// @ts-ignore
|
||||||
|
const path = require('path');
|
||||||
|
const SEARCH_DIR = 'D:\\Github\\AplusB_Pet_nation\\Assets\\GameMain\\UI\\UISprites\\MergeObj';
|
||||||
|
|
||||||
|
function findFile(dir: string): string | null {
|
||||||
|
let entries: string[] = [];
|
||||||
|
try { entries = fs.readdirSync(dir); } catch (e) { return null; }
|
||||||
|
for (const name of entries) {
|
||||||
|
const full = path.join(dir, name);
|
||||||
|
let stat;
|
||||||
|
try { stat = fs.statSync(full); } catch (e) { continue; }
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
const res = findFile(full);
|
||||||
|
if (res) return res;
|
||||||
|
} else {
|
||||||
|
if (name.indexOf(icon) !== -1) return path.resolve(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const found = findFile(SEARCH_DIR);
|
||||||
|
if (found) return found;
|
||||||
|
} catch (e) {
|
||||||
|
// 非 Node 环境或访问失败,忽略并回退
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回退:返回 icon 名称(供前端拼接资源路径使用)
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Button, Tag, notification, Modal } from 'ant-design-vue';
|
import { Button, Tag, notification, Modal, Progress } from 'ant-design-vue';
|
||||||
import type { ServerData } from '#/api/core/server';
|
import type { ServerData } from '#/api/core/server';
|
||||||
import {restartServer, getServerListApi, reloadServer} from '#/api/core/server';
|
import {restartServer, getServerListApi, reloadServer} from '#/api/core/server';
|
||||||
import AddServerModal from './addServer.vue'
|
import AddServerModal from './addServer.vue'
|
||||||
import dayjs from 'dayjs';
|
import EditServer from './editServer.vue';
|
||||||
|
import { useVbenModal } from '@vben/common-ui'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'AppList',
|
name: 'AppList',
|
||||||
@ -16,7 +16,13 @@ interface Props {
|
|||||||
withDefaults(defineProps<Props>(),{
|
withDefaults(defineProps<Props>(),{
|
||||||
items: () => [],
|
items: () => [],
|
||||||
})
|
})
|
||||||
|
const [editServerM, editServerApi] = useVbenModal({
|
||||||
|
connectedComponent: EditServer,
|
||||||
|
});
|
||||||
|
async function editServer(Server: ServerData) {
|
||||||
|
editServerApi.setData(Server);
|
||||||
|
editServerApi.open();
|
||||||
|
}
|
||||||
|
|
||||||
function getColor(status: number) {
|
function getColor(status: number) {
|
||||||
switch (status){
|
switch (status){
|
||||||
@ -29,6 +35,23 @@ function getColor(status: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCpuColor(usage: number) {
|
||||||
|
if (usage < 50) {
|
||||||
|
return 'green';
|
||||||
|
} else if (usage < 80) {
|
||||||
|
return 'orange';
|
||||||
|
} else {
|
||||||
|
return 'red';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatMemUsage(usage: number) {
|
||||||
|
if (usage < 1024) {
|
||||||
|
return usage + ' MB';
|
||||||
|
}
|
||||||
|
return (usage/1024).toFixed(2) + ' GB';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async function restart(Server: ServerData) {
|
async function restart(Server: ServerData) {
|
||||||
try{
|
try{
|
||||||
@ -96,31 +119,27 @@ function confirmUpdate(Server: ServerData) {
|
|||||||
|
|
||||||
<!-- <------------------- Add your code here ------------------->
|
<!-- <------------------- Add your code here ------------------->
|
||||||
<template>
|
<template>
|
||||||
|
<editServerM></editServerM>
|
||||||
<AddServerModal></AddServerModal>
|
<AddServerModal></AddServerModal>
|
||||||
<div v-for="item in items" :key="item.ServerId">
|
<div v-for="item in items" :key="item.ServerId">
|
||||||
<div class="card-box p-4 py-6 md:mt-4">
|
<div class="card-box p-4 py-6 md:mt-4">
|
||||||
<div class="flex justify-between h-2 border-foreground/10">
|
<div class="flex justify-between h-4 border-foreground/10">
|
||||||
|
<div @click="editServer(item)" 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">
|
|
||||||
<h2 class="text-md font-semibold md:text-ml text-center">
|
|
||||||
<span>{{ item.ServerId }}</span>
|
|
||||||
</h2>
|
|
||||||
</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">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<span>{{ item.ServerName }}</span>
|
<span>{{ item.ServerName }}</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">
|
||||||
<Tag :color="getColor(item.Status || 0)">
|
<Tag color="red">LOG</Tag>
|
||||||
{{ item.Status == 0 ? 'Inactive' : item.Status == 1 ? 'Active' : 'Unknown' }}
|
<Tag v-for="tag in item.Tags" :key="tag" color="blue">{{ tag }}</Tag>
|
||||||
</Tag>
|
|
||||||
</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">
|
||||||
<span>{{ dayjs((item.StartTime ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
<Tag :color="getColor(item.Status || 0)">
|
||||||
|
{{ item.Status == 0 ? 'Inactive' : item.Status == 1 ? 'Running' : 'Unknown' }}
|
||||||
|
</Tag>
|
||||||
</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">
|
||||||
@ -129,8 +148,21 @@ function confirmUpdate(Server: ServerData) {
|
|||||||
</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">
|
<Progress :percent="item.CpuUsage || 0" :stroke-color="getCpuColor(item.CpuUsage || 0)"/>
|
||||||
<span>{{ dayjs((item.OpenServerTime ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
</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>{{formatMemUsage(item.MemUsage||0)}}</span>
|
||||||
|
</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>32ms</span>
|
||||||
|
</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>1.0.0</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">
|
||||||
@ -138,11 +170,11 @@ function confirmUpdate(Server: ServerData) {
|
|||||||
<Button @click=confirmUpdate(item) type="primary" :loading="item.Loading">Restart</Button>
|
<Button @click=confirmUpdate(item) type="primary" :loading="item.Loading">Restart</Button>
|
||||||
</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 @click=reload(item) type="primary" :loading="item.Reload">Reload</Button>
|
<Button @click=reload(item) type="primary" :loading="item.Reload">Reload</Button>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
188
apps/web-antd/src/views/dashboard/serverList/editServer.vue
Normal file
188
apps/web-antd/src/views/dashboard/serverList/editServer.vue
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
import { addServer } from '#/api/core/server';
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const date = dayjs();
|
||||||
|
const [Form, FormApi] = useVbenForm({
|
||||||
|
// 所有表单项共用,可单独在表单内覆盖
|
||||||
|
commonConfig: {
|
||||||
|
// 所有表单项
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 使用 tailwindcss grid布局
|
||||||
|
// 提交函数
|
||||||
|
// 垂直布局,label和input在不同行,值为vertical
|
||||||
|
layout: 'horizontal',
|
||||||
|
// 水平布局,label和input在同一行
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
disabled: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '1',
|
||||||
|
},
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
fieldName: 'AppId',
|
||||||
|
label: 'AppId:',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
disabled: false,
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '2',
|
||||||
|
typeof: 'number',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'ServerId',
|
||||||
|
label: 'ServerId:',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'ServerName',
|
||||||
|
label: 'ServerName:',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'Tags',
|
||||||
|
label: 'Tags',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'version',
|
||||||
|
label: 'version',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'NumberPicker',
|
||||||
|
defaultValue: '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'max_online',
|
||||||
|
label: 'max_online',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
showDefaultActions: false,
|
||||||
|
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||||
|
wrapperClass: 'grid-cols-2',
|
||||||
|
});
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
confirmText: '提交',
|
||||||
|
onOpenChange: () => {
|
||||||
|
const modalData = modalApi.getData();
|
||||||
|
const tag = modalData.Tags ? modalData.Tags.join(',') : '';
|
||||||
|
FormApi.updateSchema([
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
disabled: true,
|
||||||
|
defaultValue: modalData.AppId ?? 0,
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '1',
|
||||||
|
},
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
fieldName: 'AppId',
|
||||||
|
label: 'AppId:',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
disabled: true,
|
||||||
|
defaultValue: modalData.ServerId ?? 0,
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '2',
|
||||||
|
typeof: 'number',
|
||||||
|
},
|
||||||
|
fieldName: 'ServerId',
|
||||||
|
label: 'ServerId:',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: modalData.ServerName ?? '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'ServerName',
|
||||||
|
label: 'ServerName:',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: tag ?? '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'Tags',
|
||||||
|
label: 'Tags',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
defaultValue: modalData.ClientVersion ?? '',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: 'node1',
|
||||||
|
},
|
||||||
|
rules: "required",
|
||||||
|
fieldName: 'version',
|
||||||
|
label: 'client-version',
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
},
|
||||||
|
onConfirm: async () => {
|
||||||
|
// 提交表单
|
||||||
|
const values = await FormApi.getValues();
|
||||||
|
const date = dayjs(values.datePicker).format('YYYY-MM-DD');
|
||||||
|
const time = dayjs(values.timePicker).format('HH:mm:ss');
|
||||||
|
const dateTime = dayjs(`${date} ${time}`).valueOf() / 1000;
|
||||||
|
const modalData = modalApi.getData();
|
||||||
|
const ServerId = parseInt(values.ServerId, 10);
|
||||||
|
await addServer(modalData.AppId, ServerId, values.ServerName, values.Status, dateTime);
|
||||||
|
modalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
defineOptions({
|
||||||
|
name: 'AddServerModal',
|
||||||
|
})
|
||||||
|
defineExpose({
|
||||||
|
FormApi
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal title="修改服务器信息" :width="800">
|
||||||
|
<Form />
|
||||||
|
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@ -74,6 +74,7 @@ const [addServerM, addServerApi] = useVbenModal({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const serverList = [
|
const serverList = [
|
||||||
{
|
{
|
||||||
AppId: 1,
|
AppId: 1,
|
||||||
@ -135,6 +136,8 @@ async function addServer() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function update() {
|
async function update() {
|
||||||
reload.value = true;
|
reload.value = true;
|
||||||
const Value = await BaseFormApi.getValues();
|
const Value = await BaseFormApi.getValues();
|
||||||
@ -163,64 +166,64 @@ async function update() {
|
|||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<addServerM class="w-[50%]" @hidden="update"/>
|
<addServerM class="w-[50%]" @hidden="update"/>
|
||||||
|
<editServerM class="w-[50%]" @hidden="update"/>
|
||||||
<Card class="mb-5" title="服务器操作">
|
<Card class="mb-5" title="服务器操作">
|
||||||
<BaseForm />
|
<BaseForm />
|
||||||
<Space>
|
<Space>
|
||||||
<Button @click="addServer">新增</Button>
|
<Button type="primary" @click="addServer">新增</Button>
|
||||||
<Button type="primary" @click="update" :loading="reload"> 更新 </Button>
|
<Button type="primary" @click="update" :loading="reload"> 更新 </Button>
|
||||||
<Button> 删除 </Button>
|
<Button type="primary"> 更新配置 </Button>
|
||||||
<Button danger> 更新配置 </Button>
|
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<div class="card-box p-4 py-6 flex justify-between h-12">
|
<div class="card-box p-4 py-6 flex justify-between h-12">
|
||||||
|
|
||||||
<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">
|
||||||
<h2 class="text-md font-semibold md:text-ml text-center">
|
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||||
<span>ServerId</span>
|
<span>SERVER INFO</span>
|
||||||
</h2>
|
</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">
|
||||||
<span>ServerName</span>
|
<span>TAGS</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">
|
||||||
<span>Status</span>
|
<span>STATUS</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">
|
||||||
<span>StartTime</span>
|
<span>PLAYERS</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">
|
||||||
<span>PlayerNum</span>
|
<span>CPU LOAD</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">
|
||||||
<span>OpenServerTime</span>
|
<span>MEMORY</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">
|
||||||
<span>Handle</span>
|
<span>LATENCY</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">
|
||||||
<span>Config</span>
|
<span>CLIENT VERSION</span>
|
||||||
|
</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>RESTART</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <template>
|
|
||||||
<AppList :items="ServerList" title="服务器列表"/>
|
|
||||||
</template> -->
|
|
||||||
<AppList :items="ServerList" title="服务器列表"/>
|
<AppList :items="ServerList" title="服务器列表"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeGridProps, VxeGridListeners } from '#/adapter/vxe-table';
|
import type { VxeGridProps, VxeGridListeners } from '#/adapter/vxe-table';
|
||||||
import { Button, notification } 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, exportLanguageFile, saveLanguageList, deleteLanguageItem } from '#/api/core/statistics';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
@ -106,6 +106,12 @@ const gridOptions: VxeGridProps<languageType> = {
|
|||||||
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 },
|
||||||
|
{
|
||||||
|
field: 'imageUrl',
|
||||||
|
slots: { default: 'image-url' },
|
||||||
|
title: 'Image',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
{ editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
|
{ editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
|
||||||
{
|
{
|
||||||
editRender: { name: 'input' },
|
editRender: { name: 'input' },
|
||||||
@ -238,10 +244,17 @@ const gridOptions: VxeGridProps<languageType> = {
|
|||||||
} else {
|
} else {
|
||||||
actionVisible = false;
|
actionVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let length = response.data ? response.data.length : 0;
|
let length = response.data ? response.data.length : 0;
|
||||||
GridApi.setGridOptions({
|
GridApi.setGridOptions({
|
||||||
columns: [
|
columns: [
|
||||||
{ 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 },
|
||||||
|
{
|
||||||
|
field: 'imageUrl',
|
||||||
|
slots: { default: 'image-url' },
|
||||||
|
title: 'Image',
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
{ editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
|
{ editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
|
||||||
{
|
{
|
||||||
editRender: { name: 'input' },
|
editRender: { name: 'input' },
|
||||||
@ -265,7 +278,7 @@ const gridOptions: VxeGridProps<languageType> = {
|
|||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
data: response.data || [],
|
data: newData,
|
||||||
total: response.total || 0,
|
total: response.total || 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -417,7 +430,10 @@ function deleteRow(row: languageType) {
|
|||||||
<Button type="primary" @click="saveAll" class="mr-2"> {{ $t('page.common.save') }} </Button>
|
<Button type="primary" @click="saveAll" class="mr-2"> {{ $t('page.common.save') }} </Button>
|
||||||
<Button type="primary" @click="exportLang"> {{ $t('page.common.gitCommit') }} </Button>
|
<Button type="primary" @click="exportLang"> {{ $t('page.common.gitCommit') }} </Button>
|
||||||
</template>
|
</template>
|
||||||
|
<template #image-url="{ row }">
|
||||||
|
<!-- <Image src="../../../../public/merge/Launcher_A_LV1.png" height="50" width="50" /> -->
|
||||||
|
<Image v-if="row.url" :src="row.url" height="50" width="50" />
|
||||||
|
</template>
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<AccessControl :codes="['super', 'admin']" type="role">
|
<AccessControl :codes="['super', 'admin']" type="role">
|
||||||
<Button type="primary" @click="deleteRow(row)">删除</Button>
|
<Button type="primary" @click="deleteRow(row)">删除</Button>
|
||||||
@ -426,5 +442,4 @@ function deleteRow(row: languageType) {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -142,7 +142,7 @@ const [BaseForm] = useVbenForm({
|
|||||||
const r = await userGmApi({
|
const r = await userGmApi({
|
||||||
Uid: cv.uid,
|
Uid: cv.uid,
|
||||||
AppId: cv.AppId,
|
AppId: cv.AppId,
|
||||||
ServerId: cv.ServerId,
|
ServerId: cv.Node,
|
||||||
Command: gm,
|
Command: gm,
|
||||||
});
|
});
|
||||||
message.success(r.Msg);
|
message.success(r.Msg);
|
||||||
@ -265,9 +265,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
try {
|
try {
|
||||||
const r = await getUserlogInfoApi({
|
const r = await getUserlogInfoApi({
|
||||||
Id: data.value.uid,
|
Id: data.value.uid,
|
||||||
Event: 'someEvent', // replace 'someEvent' with the actual event
|
Node: data.value.Node,
|
||||||
PageSize: 10, // replace 10 with the actual page size
|
|
||||||
CurrentPage: 1, // replace 1 with the actual current page
|
|
||||||
});
|
});
|
||||||
trendItems = [];
|
trendItems = [];
|
||||||
let id = 0;
|
let id = 0;
|
||||||
|
|||||||
@ -30,6 +30,8 @@ interface RowType {
|
|||||||
Energy: string;
|
Energy: string;
|
||||||
LoginTime: number;
|
LoginTime: number;
|
||||||
Online: string;
|
Online: string;
|
||||||
|
Node: number;
|
||||||
|
Nickname: string;
|
||||||
}
|
}
|
||||||
const startDate = dayjs().subtract(7, 'day').startOf('day');
|
const startDate = dayjs().subtract(7, 'day').startOf('day');
|
||||||
const endDate = dayjs().endOf('day');
|
const endDate = dayjs().endOf('day');
|
||||||
@ -69,18 +71,17 @@ const formOptions: VbenFormProps = {
|
|||||||
label: 'APP:',
|
label: 'APP:',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'Select',
|
component: 'Input',
|
||||||
defaultValue: 1,
|
|
||||||
componentProps: {
|
componentProps: {
|
||||||
filterOption: true,
|
filterOption: true,
|
||||||
options: [
|
options: [
|
||||||
|
|
||||||
],
|
],
|
||||||
placeholder: '请选择',
|
placeholder: '请输入',
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
},
|
},
|
||||||
fieldName: 'ServerId',
|
fieldName: 'Uid',
|
||||||
label: 'ServerId:',
|
label: 'Uid:',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
@ -89,11 +90,11 @@ const formOptions: VbenFormProps = {
|
|||||||
options: [
|
options: [
|
||||||
|
|
||||||
],
|
],
|
||||||
placeholder: '请选择',
|
placeholder: '请输入',
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
},
|
},
|
||||||
fieldName: 'Uid',
|
fieldName: 'Nickname',
|
||||||
label: 'Uid:',
|
label: '昵称:',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
@ -132,7 +133,7 @@ const formOptions: VbenFormProps = {
|
|||||||
const gridEvents: VxeGridListeners<RowType> = {
|
const gridEvents: VxeGridListeners<RowType> = {
|
||||||
cellClick: async ({ row }) => {
|
cellClick: async ({ row }) => {
|
||||||
const value = await GridApi.formApi.getValues();
|
const value = await GridApi.formApi.getValues();
|
||||||
userModalApi.setData({ uid: row.Uid, AppId: value.AppId, ServerId: value.ServerId });
|
userModalApi.setData({ uid: row.Uid, AppId: value.AppId, Node: row.Node });
|
||||||
userModalApi.open();
|
userModalApi.open();
|
||||||
state.uid = row.Uid;
|
state.uid = row.Uid;
|
||||||
},
|
},
|
||||||
@ -144,7 +145,8 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
{ field: 'Uid', title: 'id' },
|
{ field: 'Uid', title: 'id' },
|
||||||
{ 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: 'Exp', title: '经验', formatter: ({ cellValue }) => `${cellValue} XP`, sortable: true, sortBy: 'Exp' },
|
{ field: 'Node', title: '节点', },
|
||||||
|
{ field: 'Nickname', title: '昵称', },
|
||||||
{ 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' },
|
||||||
@ -170,9 +172,10 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
ajax: {
|
ajax: {
|
||||||
query: async ({ page }, formValues) => {
|
query: async ({ page }, formValues) => {
|
||||||
let Id = parseInt(formValues.AppId, 10);
|
let Id = parseInt(formValues.AppId, 10);
|
||||||
let ServerId = parseInt(formValues.ServerId, 10);
|
let ServerId = 1;
|
||||||
let Uid = parseInt(formValues.Uid, 10);
|
let Uid = parseInt(formValues.Uid, 10);
|
||||||
let r = await getUserListApi({ Id: Id, ServerId: ServerId, pageSize: page.pageSize, currentPage: page.currentPage, Uid: Uid, StartTime: formValues.StartTime ? Math.floor(new Date(formValues.StartTime).getTime() / 1000) : undefined, EndTime: formValues.EndTime ? Math.floor(new Date(formValues.EndTime).getTime() / 1000) : undefined });
|
let Nickname = formValues.Nickname ? String(formValues.Nickname) : '';
|
||||||
|
let r = await getUserListApi({ Id: Id, ServerId: ServerId, pageSize: page.pageSize, currentPage: page.currentPage, Uid: Uid, Nickname:Nickname, StartTime: formValues.StartTime ? Math.floor(new Date(formValues.StartTime).getTime() / 1000) : undefined, EndTime: formValues.EndTime ? Math.floor(new Date(formValues.EndTime).getTime() / 1000) : undefined });
|
||||||
return r;
|
return r;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user