版本更新
Some checks are pending
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Lint (ubuntu-latest) (push) Waiting to run
CI / Lint (windows-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / CI OK (push) Blocked by required conditions
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Deploy Website on push / Deploy Push Playground Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Docs Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Antd Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Element Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Naive Ftp (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
Some checks are pending
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Lint (ubuntu-latest) (push) Waiting to run
CI / Lint (windows-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / CI OK (push) Blocked by required conditions
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Deploy Website on push / Deploy Push Playground Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Docs Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Antd Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Element Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Naive Ftp (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
This commit is contained in:
parent
8b00dd8622
commit
e345451a58
@ -26,6 +26,20 @@ export interface ServerData {
|
||||
Reload?:boolean;
|
||||
}
|
||||
|
||||
export interface NodeData{
|
||||
NodeId?: number;
|
||||
NodeName: string;
|
||||
NodeIp: string;
|
||||
NodeInternalIp: string;
|
||||
NodeHardware: string;
|
||||
NodeArea: string;
|
||||
NodeOperator: string;
|
||||
NodeStatus?: number;
|
||||
NodeUser?: string;
|
||||
NodePassword?: string;
|
||||
NodeTz?: string;
|
||||
}
|
||||
|
||||
export interface serverParam {
|
||||
AppId: number;
|
||||
Type?: number;
|
||||
@ -35,6 +49,14 @@ export async function getAppListApi(){
|
||||
return requestClient.post<AppData[]>('/server/list');
|
||||
}
|
||||
|
||||
export async function getNodeListApi(){
|
||||
return requestClient.post<NodeData[]>('/server/nodeList');
|
||||
}
|
||||
|
||||
export async function addNode(n :NodeData){
|
||||
return requestClient.post('/server/addNode', n);
|
||||
}
|
||||
|
||||
export async function getServerListApi(P: serverParam){
|
||||
return requestClient.post<ServerData[]>('/server/serverList', P, {timeout: 120000});
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '../../../../../packages/@core/ui-kit/shadcn-ui';
|
||||
import dayjs from 'dayjs';
|
||||
interface Props {
|
||||
title: string;
|
||||
dataList: dataType[];
|
||||
|
||||
@ -47,6 +47,19 @@
|
||||
"piggy_bank_income": "猪猪银行收益",
|
||||
"card_pack_open": "开启卡包",
|
||||
"get_new_card": "获得新卡牌",
|
||||
"gift_free":"商店免费奖励",
|
||||
"item_change":"物品变更",
|
||||
"daily_task": "日常任务",
|
||||
"weekly_task": "每周任务",
|
||||
"level_up": "升级",
|
||||
"property_level_up": "属性升级",
|
||||
"time_limited_slot": "限时事件",
|
||||
"buy_energy_diamond": "购买体力",
|
||||
"time_limited_event_action": "限时事件操作",
|
||||
"petname_set": "设置宠物名称",
|
||||
"emoji_income": "获得表情包",
|
||||
"avatarIcon_income": "获得头像框",
|
||||
"gm": "GM操作",
|
||||
"nickname_set": "设置昵称"
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operation/level/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:area-chart',
|
||||
icon: 'lucide:chart-no-axes-column-increasing',
|
||||
title: $t('page.operation.level'),
|
||||
},
|
||||
},
|
||||
@ -30,7 +30,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operation/mail/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:area-chart',
|
||||
icon: 'lucide:mail',
|
||||
title: $t('page.operation.mail'),
|
||||
},
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
component: BasicLayout,
|
||||
meta: {
|
||||
icon: 'lucide:file-clock',
|
||||
icon: 'lucide:laugh',
|
||||
order: 1000,
|
||||
title: $t('page.userlog.title'),
|
||||
},
|
||||
@ -20,7 +20,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/userlog/userlist/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:area-chart',
|
||||
icon: 'lucide:list',
|
||||
title: $t('page.userlog.userlist'),
|
||||
},
|
||||
},
|
||||
@ -30,7 +30,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/userlog/assetlog/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:area-chart',
|
||||
icon: 'solar:stars-bold',
|
||||
title: $t('page.userlog.assetlog'),
|
||||
},
|
||||
},
|
||||
@ -40,7 +40,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/userlog/eventlog/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:area-chart',
|
||||
icon: 'lucide:apple',
|
||||
title: $t('page.userlog.eventlog'),
|
||||
},
|
||||
},
|
||||
@ -50,7 +50,7 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/userlog/orderlog/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:area-chart',
|
||||
icon: 'solar:chat-round-money-bold',
|
||||
title: $t('page.userlog.orderlog'),
|
||||
},
|
||||
},
|
||||
|
||||
@ -5,11 +5,8 @@ import { useVbenModal } from '@vben/common-ui';
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
|
||||
|
||||
const date = dayjs();
|
||||
const [Form, FormApi] = useVbenForm({
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
// 所有表单项共用,可单独在表单内覆盖s
|
||||
commonConfig: {
|
||||
// 所有表单项
|
||||
componentProps: {
|
||||
@ -29,9 +26,9 @@ const [Form, FormApi] = useVbenForm({
|
||||
placeholder: '1',
|
||||
},
|
||||
formItemClass:'col-span-2',
|
||||
fieldName: 'AppId',
|
||||
fieldName: 'NodeId',
|
||||
rules: "required|integer",
|
||||
label: 'AppId',
|
||||
label: 'NodeId',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
@ -164,6 +161,5 @@ defineExpose({
|
||||
<template>
|
||||
<Modal title="添加服务器" :width="800">
|
||||
<Form />
|
||||
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Button, Card, Space, notification } from 'ant-design-vue';
|
||||
import { Button, Card, Space } from 'ant-design-vue';
|
||||
import AppList from './appList.vue';
|
||||
import { getAppListApi, updateAppApi } from '#/api/core/server';
|
||||
import { getAppListApi } from '#/api/core/server';
|
||||
import type { AppData } from '#/api/core/server';
|
||||
import { useVbenModal } from '@vben/common-ui'
|
||||
import { ref,onMounted } from 'vue';
|
||||
@ -29,7 +29,6 @@ onMounted(async() => {
|
||||
//console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
async function addApp() {
|
||||
addServerApi.open()
|
||||
}
|
||||
@ -46,7 +45,6 @@ async function addApp() {
|
||||
</Card>
|
||||
<div class="p-5">
|
||||
<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">
|
||||
<h2 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>AppId</span>
|
||||
|
||||
@ -1,13 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { addServer } from '#/api/core/server';
|
||||
import { addNode, type NodeData } 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: {
|
||||
@ -25,82 +20,89 @@ const [Form, FormApi] = useVbenForm({
|
||||
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:',
|
||||
fieldName: 'NodeName',
|
||||
label: '节点名称',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: 'node1',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'ServerName',
|
||||
label: 'ServerName:',
|
||||
fieldName: 'NodeIp',
|
||||
label: '外网Ip',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'DatePicker',
|
||||
fieldName: 'datePicker',
|
||||
defaultValue: date,
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
},
|
||||
wrapperClass: 'grid-span-1',
|
||||
label: '开服日期',
|
||||
},
|
||||
{
|
||||
component: 'TimePicker',
|
||||
fieldName: 'timePicker',
|
||||
defaultValue: date,
|
||||
componentProps: {
|
||||
format: 'HH:mm:ss',
|
||||
},
|
||||
wrapperClass: 'grid-span-2 grid-start-2',
|
||||
label: '开服时间',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
defaultValue: 1,
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
filterOption: true,
|
||||
options: [
|
||||
{
|
||||
label: 'Start',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'Stop',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: 'Maintain',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
placeholder: '请选择',
|
||||
showSearch: true,
|
||||
typeof: 'number',
|
||||
},
|
||||
fieldName: 'Status',
|
||||
label: 'Status',
|
||||
rules: "required",
|
||||
fieldName: 'NodeInternalIp',
|
||||
label: '内网Ip',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeHardware',
|
||||
label: '硬件信息',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeArea',
|
||||
label: '区域',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeOperator',
|
||||
label: '运营商',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: '/usr/local/app',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeUser',
|
||||
label: '用户名',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'InputPassword',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodePassword',
|
||||
label: '密码',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
|
||||
],
|
||||
@ -111,30 +113,22 @@ const [Form, FormApi] = useVbenForm({
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
confirmText: '提交',
|
||||
onOpenChange:() => {
|
||||
const modalData = modalApi.getData();
|
||||
FormApi.updateSchema([
|
||||
{
|
||||
component: 'Input',
|
||||
disabled: true,
|
||||
defaultValue: modalData.AppId,
|
||||
componentProps: {
|
||||
placeholder: modalData.AppId,
|
||||
},
|
||||
formItemClass:'col-span-2',
|
||||
fieldName: 'AppId',
|
||||
label: 'AppId:',
|
||||
},
|
||||
])
|
||||
|
||||
},
|
||||
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);
|
||||
const values: Record<string, any> = await FormApi.getValues();
|
||||
const node:NodeData = {
|
||||
NodeName: values.NodeName,
|
||||
NodeIp: values.NodeIp,
|
||||
NodeInternalIp: values.NodeInternalIp,
|
||||
NodeHardware: values.NodeHardware,
|
||||
NodeArea: values.NodeArea,
|
||||
NodeOperator: values.NodeOperator,
|
||||
NodeUser: values.NodeUser,
|
||||
NodePassword: values.NodePassword,
|
||||
};
|
||||
await addNode(node);
|
||||
modalApi.close();
|
||||
},
|
||||
});
|
||||
@ -148,7 +142,6 @@ defineExpose({
|
||||
|
||||
<template>
|
||||
<Modal title="添加服务器" :width="800">
|
||||
<Form />
|
||||
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@ -1,149 +1,58 @@
|
||||
<script lang="ts" setup>
|
||||
import { Button, Tag, notification, Modal } from 'ant-design-vue';
|
||||
import type { ServerData } from '#/api/core/server';
|
||||
import {restartServer, getServerListApi, reloadServer} from '#/api/core/server';
|
||||
import type { NodeData } from '#/api/core/server';
|
||||
import AddServerModal from './addServer.vue'
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
|
||||
defineOptions({
|
||||
name: 'AppList',
|
||||
})
|
||||
interface Props {
|
||||
items: ServerData[];
|
||||
items: NodeData[];
|
||||
title: string;
|
||||
}
|
||||
withDefaults(defineProps<Props>(),{
|
||||
items: () => [],
|
||||
})
|
||||
|
||||
|
||||
function getColor(status: number) {
|
||||
switch (status){
|
||||
case 0:
|
||||
return 'red';
|
||||
case 1:
|
||||
return 'green';
|
||||
default:
|
||||
return 'blue';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function restart(Server: ServerData) {
|
||||
try{
|
||||
Server.Loading = true;
|
||||
const AppId = Server.AppId;
|
||||
await restartServer(AppId, Server.ServerId, Server.ServerName);
|
||||
notification.success({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '重启成功',
|
||||
type: 'success',
|
||||
});
|
||||
Server.Loading = false;
|
||||
const serverResponse = await getServerListApi({AppId:Server.AppId});
|
||||
const foundServer = serverResponse.find((item) => item.ServerId == Server.ServerId);
|
||||
Server.StartTime = foundServer ? foundServer.StartTime : undefined;
|
||||
//console.log('更新成功');
|
||||
}catch(e){
|
||||
notification.error({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '更新失败',
|
||||
type: 'error',
|
||||
});
|
||||
Server.Loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function reload(Server: ServerData) {
|
||||
try{
|
||||
Server.Reload = true;
|
||||
const AppId = Server.AppId;
|
||||
await reloadServer(AppId, Server.ServerId, Server.ServerName);
|
||||
notification.success({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '重载成功',
|
||||
type: 'success',
|
||||
});
|
||||
Server.Reload = false;
|
||||
const serverResponse = await getServerListApi({AppId:Server.AppId});
|
||||
const foundServer = serverResponse.find((item) => item.ServerId == Server.ServerId);
|
||||
Server.StartTime = foundServer ? foundServer.StartTime : undefined;
|
||||
//console.log('更新成功');
|
||||
}catch(e){
|
||||
notification.error({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '更新失败',
|
||||
type: 'error',
|
||||
});
|
||||
Server.Loading = false;
|
||||
}
|
||||
}
|
||||
function confirmUpdate(Server: ServerData) {
|
||||
Modal.confirm({
|
||||
title: '确认更新',
|
||||
content: `你确定要更新 ${Server.ServerName} 吗?`,
|
||||
onOk() {
|
||||
restart(Server);
|
||||
},
|
||||
onCancel() {
|
||||
//console.log('取消更新');
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<!-- <------------------- Add your code here ------------------->
|
||||
<template>
|
||||
<AddServerModal></AddServerModal>
|
||||
<div v-for="item in items" :key="item.ServerId">
|
||||
<div v-for="item in items" :key="item.NodeId">
|
||||
<div class="card-box p-4 py-6 md:mt-4">
|
||||
<div class="flex justify-between h-2 border-foreground/10">
|
||||
|
||||
<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>
|
||||
<span>{{ item.NodeName }}</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">
|
||||
<span>{{ item.ServerName }}</span>
|
||||
<span>{{ item.NodeIp }}</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">
|
||||
<Tag :color="getColor(item.Status || 0)">
|
||||
{{ item.Status == 0 ? 'Inactive' : item.Status == 1 ? 'Active' : 'Unknown' }}
|
||||
</Tag>
|
||||
<span>{{ item.NodeHardware }}</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>{{ dayjs((item.StartTime ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||
<span>{{ item.NodeArea }}</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>{{ item.PlayerNum }}</span>
|
||||
<span>{{ item.NodeOperator }}</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>{{ dayjs((item.OpenServerTime ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') }}</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">
|
||||
<Button @click=confirmUpdate(item) type="primary" :loading="item.Loading">Restart</Button>
|
||||
</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">
|
||||
<Button @click=reload(item) type="primary" :loading="item.Reload">Reload</Button>
|
||||
<span>{{ item.NodeTz }}</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@ -1,226 +1,83 @@
|
||||
<script lang="ts" setup>
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Button, Card, Space, notification } from 'ant-design-vue';
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { Button, Card, Space } from 'ant-design-vue';
|
||||
import AppList from './appList.vue';
|
||||
import { getServerListApi, getAppListApi, updateAppApi } from '#/api/core/server';
|
||||
import type { AppData, ServerData } from '#/api/core/server';
|
||||
import { getNodeListApi } from '#/api/core/server';
|
||||
import type { NodeData } from '#/api/core/server';
|
||||
import { useVbenModal } from '@vben/common-ui'
|
||||
import { ref,onMounted } from 'vue';
|
||||
import addServerModal from './addServer.vue';
|
||||
import dayjs from 'dayjs';
|
||||
const [BaseForm, BaseFormApi] = useVbenForm({
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
commonConfig: {
|
||||
// 所有表单项
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
},
|
||||
|
||||
// 使用 tailwindcss grid布局
|
||||
// 提交函数
|
||||
// 垂直布局,label和input在不同行,值为vertical
|
||||
layout: 'horizontal',
|
||||
// 水平布局,label和input在同一行
|
||||
schema: [
|
||||
{
|
||||
component: 'Select',
|
||||
defaultValue: 1,
|
||||
componentProps: {
|
||||
onChange: async (value: number) => {
|
||||
const serverResponse = await getServerListApi({AppId:value});
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
const app = appList.value.find((item) => item.AppId === value);
|
||||
if (!app) return;
|
||||
const updateTime = dayjs((app.Update ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss')
|
||||
BaseFormApi.setFieldValue("update", updateTime)
|
||||
},
|
||||
filterOption: true,
|
||||
options: [
|
||||
|
||||
],
|
||||
placeholder: '请选择',
|
||||
showSearch: true,
|
||||
},
|
||||
fieldName: 'fieldOptions',
|
||||
label: 'APP:',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
disabled: true,
|
||||
defaultValue: "",
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
fieldName: 'update',
|
||||
label: '更新时间:',
|
||||
}
|
||||
],
|
||||
// handleSubmit: async (values: Record<string, any>) => {
|
||||
// console.log(values);
|
||||
// },
|
||||
showDefaultActions: false,
|
||||
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||
wrapperClass: 'grid-cols-2 ',
|
||||
});
|
||||
|
||||
const [addServerM, addServerApi] = useVbenModal({
|
||||
connectedComponent: addServerModal,
|
||||
onClosed: async () => {
|
||||
const Value = await BaseFormApi.getValues();
|
||||
const serverResponse = await getServerListApi(Value.fieldOptions);
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
addServerApi.close();
|
||||
},
|
||||
});
|
||||
|
||||
const serverList = [
|
||||
{
|
||||
AppId: 1,
|
||||
AppName: '测试版本',
|
||||
WsHost: '1.226.16.67',
|
||||
Status: 'Online',
|
||||
},
|
||||
{
|
||||
AppId: 1,
|
||||
AppName: '测试版本',
|
||||
WsHost: '1.226.16.67',
|
||||
Status: 'Online',
|
||||
},
|
||||
{
|
||||
AppId: 1,
|
||||
AppName: '测试版本',
|
||||
WsHost: '1.226.16.67',
|
||||
Status: 'Online',
|
||||
},
|
||||
];
|
||||
const appList = ref<AppData[]>([]);
|
||||
const ServerList = ref<ServerData[]>([]);
|
||||
const reload = ref(false);
|
||||
|
||||
const nodeList = ref<NodeData[]>([]);
|
||||
onMounted(async() => {
|
||||
try{
|
||||
const response = await getAppListApi();
|
||||
appList.value = Array.isArray(response) ? response : [];
|
||||
const app = appList.value[0];
|
||||
const response = await getNodeListApi();
|
||||
nodeList.value = Array.isArray(response) ? response : [];
|
||||
const app = nodeList.value[0];
|
||||
if (!app) return;
|
||||
const updateTime = dayjs((app.Update ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss')
|
||||
BaseFormApi.setFieldValue("update", updateTime)
|
||||
BaseFormApi.updateSchema([
|
||||
{
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: appList.value.map((item) => ({
|
||||
label: item.AppName,
|
||||
value: item.AppId,
|
||||
})),
|
||||
},
|
||||
fieldName: 'fieldOptions',
|
||||
},
|
||||
]);
|
||||
const serverResponse = await getServerListApi({AppId:app.AppId});
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
}catch(e){
|
||||
appList.value = serverList;
|
||||
nodeList.value = [];
|
||||
//console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
async function addServer() {
|
||||
const Value = await BaseFormApi.getValues();
|
||||
addServerApi.setData({AppId: Value.fieldOptions});
|
||||
addServerApi.open();
|
||||
async function addNode() {
|
||||
addServerApi.open()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async function update() {
|
||||
reload.value = true;
|
||||
const Value = await BaseFormApi.getValues();
|
||||
try{
|
||||
await updateAppApi(Value.fieldOptions);
|
||||
reload.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){
|
||||
reload.value = false;
|
||||
notification.error({
|
||||
duration:10,
|
||||
message:"服务器更新失败"
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Page>
|
||||
<addServerM class="w-[50%]" @hidden="update"/>
|
||||
<Card class="mb-5" title="服务器操作">
|
||||
<BaseForm />
|
||||
<addServerM class="w-[50%]"/>
|
||||
<Card class="mb-5" title="节点操作">
|
||||
<Space>
|
||||
<Button @click="addServer">新增</Button>
|
||||
<Button type="primary" @click="update" :loading="reload"> 更新 </Button>
|
||||
<Button @click="addNode">新增</Button>
|
||||
<Button> 删除 </Button>
|
||||
<Button danger> 更新配置 </Button>
|
||||
</Space>
|
||||
</Card>
|
||||
<div class="p-5">
|
||||
<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">
|
||||
<h2 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>ServerId</span>
|
||||
<span>名称</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">
|
||||
<span>ServerName</span>
|
||||
<span>Ip</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>Status</span>
|
||||
<span>硬件</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>StartTime</span>
|
||||
<span>地区</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>PlayerNum</span>
|
||||
<span>运营商</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>OpenServerTime</span>
|
||||
<span>时区</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>Handle</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>Config</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <template>
|
||||
<AppList :items="ServerList" title="服务器列表"/>
|
||||
</template> -->
|
||||
<AppList :items="ServerList" title="服务器列表"/>
|
||||
|
||||
</div>
|
||||
<AppList :items="nodeList" title="服务器列表"/>
|
||||
</div>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
@ -1,13 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { addServer } from '#/api/core/server';
|
||||
import { addNode, type NodeData } 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: {
|
||||
@ -25,82 +20,89 @@ const [Form, FormApi] = useVbenForm({
|
||||
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:',
|
||||
fieldName: 'NodeName',
|
||||
label: '节点名称',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: 'node1',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'ServerName',
|
||||
label: 'ServerName:',
|
||||
fieldName: 'NodeIp',
|
||||
label: '外网Ip',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'DatePicker',
|
||||
fieldName: 'datePicker',
|
||||
defaultValue: date,
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
},
|
||||
wrapperClass: 'grid-span-1',
|
||||
label: '开服日期',
|
||||
},
|
||||
{
|
||||
component: 'TimePicker',
|
||||
fieldName: 'timePicker',
|
||||
defaultValue: date,
|
||||
componentProps: {
|
||||
format: 'HH:mm:ss',
|
||||
},
|
||||
wrapperClass: 'grid-span-2 grid-start-2',
|
||||
label: '开服时间',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
defaultValue: 1,
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
filterOption: true,
|
||||
options: [
|
||||
{
|
||||
label: 'Start',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'Stop',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: 'Maintain',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
placeholder: '请选择',
|
||||
showSearch: true,
|
||||
typeof: 'number',
|
||||
},
|
||||
fieldName: 'Status',
|
||||
label: 'Status',
|
||||
rules: "required",
|
||||
fieldName: 'NodeInternalIp',
|
||||
label: '内网Ip',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeHardware',
|
||||
label: '硬件信息',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeArea',
|
||||
label: '区域',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeOperator',
|
||||
label: '运营商',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: '/usr/local/app',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodeUser',
|
||||
label: '用户名',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'InputPassword',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
typeof: 'number',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'NodePassword',
|
||||
label: '密码',
|
||||
formItemClass:'col-span-2',
|
||||
},
|
||||
|
||||
],
|
||||
@ -111,30 +113,22 @@ const [Form, FormApi] = useVbenForm({
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
confirmText: '提交',
|
||||
onOpenChange:() => {
|
||||
const modalData = modalApi.getData();
|
||||
FormApi.updateSchema([
|
||||
{
|
||||
component: 'Input',
|
||||
disabled: true,
|
||||
defaultValue: modalData.AppId,
|
||||
componentProps: {
|
||||
placeholder: modalData.AppId,
|
||||
},
|
||||
formItemClass:'col-span-2',
|
||||
fieldName: 'AppId',
|
||||
label: 'AppId:',
|
||||
},
|
||||
])
|
||||
|
||||
},
|
||||
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);
|
||||
const values: Record<string, any> = await FormApi.getValues();
|
||||
const node:NodeData = {
|
||||
NodeName: values.NodeName,
|
||||
NodeIp: values.NodeIp,
|
||||
NodeInternalIp: values.NodeInternalIp,
|
||||
NodeHardware: values.NodeHardware,
|
||||
NodeArea: values.NodeArea,
|
||||
NodeOperator: values.NodeOperator,
|
||||
NodeUser: values.NodeUser,
|
||||
NodePassword: values.NodePassword,
|
||||
};
|
||||
await addNode(node);
|
||||
modalApi.close();
|
||||
},
|
||||
});
|
||||
@ -148,7 +142,6 @@ defineExpose({
|
||||
|
||||
<template>
|
||||
<Modal title="添加服务器" :width="800">
|
||||
<Form />
|
||||
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@ -1,149 +1,58 @@
|
||||
<script lang="ts" setup>
|
||||
import { Button, Tag, notification, Modal } from 'ant-design-vue';
|
||||
import type { ServerData } from '#/api/core/server';
|
||||
import {restartServer, getServerListApi, reloadServer} from '#/api/core/server';
|
||||
import type { NodeData } from '#/api/core/server';
|
||||
import AddServerModal from './addServer.vue'
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
|
||||
defineOptions({
|
||||
name: 'AppList',
|
||||
})
|
||||
interface Props {
|
||||
items: ServerData[];
|
||||
items: NodeData[];
|
||||
title: string;
|
||||
}
|
||||
withDefaults(defineProps<Props>(),{
|
||||
items: () => [],
|
||||
})
|
||||
|
||||
|
||||
function getColor(status: number) {
|
||||
switch (status){
|
||||
case 0:
|
||||
return 'red';
|
||||
case 1:
|
||||
return 'green';
|
||||
default:
|
||||
return 'blue';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function restart(Server: ServerData) {
|
||||
try{
|
||||
Server.Loading = true;
|
||||
const AppId = Server.AppId;
|
||||
await restartServer(AppId, Server.ServerId, Server.ServerName);
|
||||
notification.success({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '重启成功',
|
||||
type: 'success',
|
||||
});
|
||||
Server.Loading = false;
|
||||
const serverResponse = await getServerListApi({AppId:Server.AppId});
|
||||
const foundServer = serverResponse.find((item) => item.ServerId == Server.ServerId);
|
||||
Server.StartTime = foundServer ? foundServer.StartTime : undefined;
|
||||
//console.log('更新成功');
|
||||
}catch(e){
|
||||
notification.error({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '更新失败',
|
||||
type: 'error',
|
||||
});
|
||||
Server.Loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function reload(Server: ServerData) {
|
||||
try{
|
||||
Server.Reload = true;
|
||||
const AppId = Server.AppId;
|
||||
await reloadServer(AppId, Server.ServerId, Server.ServerName);
|
||||
notification.success({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '重载成功',
|
||||
type: 'success',
|
||||
});
|
||||
Server.Reload = false;
|
||||
const serverResponse = await getServerListApi({AppId:Server.AppId});
|
||||
const foundServer = serverResponse.find((item) => item.ServerId == Server.ServerId);
|
||||
Server.StartTime = foundServer ? foundServer.StartTime : undefined;
|
||||
//console.log('更新成功');
|
||||
}catch(e){
|
||||
notification.error({
|
||||
duration: 10,
|
||||
message: Server.ServerName + '更新失败',
|
||||
type: 'error',
|
||||
});
|
||||
Server.Loading = false;
|
||||
}
|
||||
}
|
||||
function confirmUpdate(Server: ServerData) {
|
||||
Modal.confirm({
|
||||
title: '确认更新',
|
||||
content: `你确定要更新 ${Server.ServerName} 吗?`,
|
||||
onOk() {
|
||||
restart(Server);
|
||||
},
|
||||
onCancel() {
|
||||
//console.log('取消更新');
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<!-- <------------------- Add your code here ------------------->
|
||||
<template>
|
||||
<AddServerModal></AddServerModal>
|
||||
<div v-for="item in items" :key="item.ServerId">
|
||||
<div v-for="item in items" :key="item.NodeId">
|
||||
<div class="card-box p-4 py-6 md:mt-4">
|
||||
<div class="flex justify-between h-2 border-foreground/10">
|
||||
|
||||
<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>
|
||||
<span>{{ item.NodeName }}</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">
|
||||
<span>{{ item.ServerName }}</span>
|
||||
<span>{{ item.NodeIp }}</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">
|
||||
<Tag :color="getColor(item.Status || 0)">
|
||||
{{ item.Status == 0 ? 'Inactive' : item.Status == 1 ? 'Active' : 'Unknown' }}
|
||||
</Tag>
|
||||
<span>{{ item.NodeHardware }}</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>{{ dayjs((item.StartTime ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||
<span>{{ item.NodeArea }}</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>{{ item.PlayerNum }}</span>
|
||||
<span>{{ item.NodeOperator }}</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>{{ dayjs((item.OpenServerTime ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss') }}</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">
|
||||
<Button @click=confirmUpdate(item) type="primary" :loading="item.Loading">Restart</Button>
|
||||
</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">
|
||||
<Button @click=reload(item) type="primary" :loading="item.Reload">Reload</Button>
|
||||
<span>{{ item.NodeTz }}</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@ -1,226 +1,83 @@
|
||||
<script lang="ts" setup>
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Button, Card, Space, notification } from 'ant-design-vue';
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { Button, Card, Space } from 'ant-design-vue';
|
||||
import AppList from './appList.vue';
|
||||
import { getServerListApi, getAppListApi, updateAppApi } from '#/api/core/server';
|
||||
import type { AppData, ServerData } from '#/api/core/server';
|
||||
import { getNodeListApi } from '#/api/core/server';
|
||||
import type { NodeData } from '#/api/core/server';
|
||||
import { useVbenModal } from '@vben/common-ui'
|
||||
import { ref,onMounted } from 'vue';
|
||||
import addServerModal from './addServer.vue';
|
||||
import dayjs from 'dayjs';
|
||||
const [BaseForm, BaseFormApi] = useVbenForm({
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
commonConfig: {
|
||||
// 所有表单项
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
},
|
||||
|
||||
// 使用 tailwindcss grid布局
|
||||
// 提交函数
|
||||
// 垂直布局,label和input在不同行,值为vertical
|
||||
layout: 'horizontal',
|
||||
// 水平布局,label和input在同一行
|
||||
schema: [
|
||||
{
|
||||
component: 'Select',
|
||||
defaultValue: 1,
|
||||
componentProps: {
|
||||
onChange: async (value: number) => {
|
||||
const serverResponse = await getServerListApi({AppId:value});
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
const app = appList.value.find((item) => item.AppId === value);
|
||||
if (!app) return;
|
||||
const updateTime = dayjs((app.Update ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss')
|
||||
BaseFormApi.setFieldValue("update", updateTime)
|
||||
},
|
||||
filterOption: true,
|
||||
options: [
|
||||
|
||||
],
|
||||
placeholder: '请选择',
|
||||
showSearch: true,
|
||||
},
|
||||
fieldName: 'fieldOptions',
|
||||
label: 'APP:',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
disabled: true,
|
||||
defaultValue: "",
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm:ss',
|
||||
},
|
||||
fieldName: 'update',
|
||||
label: '更新时间:',
|
||||
}
|
||||
],
|
||||
// handleSubmit: async (values: Record<string, any>) => {
|
||||
// console.log(values);
|
||||
// },
|
||||
showDefaultActions: false,
|
||||
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||
wrapperClass: 'grid-cols-2 ',
|
||||
});
|
||||
|
||||
const [addServerM, addServerApi] = useVbenModal({
|
||||
connectedComponent: addServerModal,
|
||||
onClosed: async () => {
|
||||
const Value = await BaseFormApi.getValues();
|
||||
const serverResponse = await getServerListApi(Value.fieldOptions);
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
addServerApi.close();
|
||||
},
|
||||
});
|
||||
|
||||
const serverList = [
|
||||
{
|
||||
AppId: 1,
|
||||
AppName: '测试版本',
|
||||
WsHost: '1.226.16.67',
|
||||
Status: 'Online',
|
||||
},
|
||||
{
|
||||
AppId: 1,
|
||||
AppName: '测试版本',
|
||||
WsHost: '1.226.16.67',
|
||||
Status: 'Online',
|
||||
},
|
||||
{
|
||||
AppId: 1,
|
||||
AppName: '测试版本',
|
||||
WsHost: '1.226.16.67',
|
||||
Status: 'Online',
|
||||
},
|
||||
];
|
||||
const appList = ref<AppData[]>([]);
|
||||
const ServerList = ref<ServerData[]>([]);
|
||||
const reload = ref(false);
|
||||
|
||||
const nodeList = ref<NodeData[]>([]);
|
||||
onMounted(async() => {
|
||||
try{
|
||||
const response = await getAppListApi();
|
||||
appList.value = Array.isArray(response) ? response : [];
|
||||
const app = appList.value[0];
|
||||
const response = await getNodeListApi();
|
||||
nodeList.value = Array.isArray(response) ? response : [];
|
||||
const app = nodeList.value[0];
|
||||
if (!app) return;
|
||||
const updateTime = dayjs((app.Update ?? 0) * 1000).format('YYYY-MM-DD HH:mm:ss')
|
||||
BaseFormApi.setFieldValue("update", updateTime)
|
||||
BaseFormApi.updateSchema([
|
||||
{
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: appList.value.map((item) => ({
|
||||
label: item.AppName,
|
||||
value: item.AppId,
|
||||
})),
|
||||
},
|
||||
fieldName: 'fieldOptions',
|
||||
},
|
||||
]);
|
||||
const serverResponse = await getServerListApi({AppId:app.AppId});
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
}catch(e){
|
||||
appList.value = serverList;
|
||||
nodeList.value = [];
|
||||
//console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
async function addServer() {
|
||||
const Value = await BaseFormApi.getValues();
|
||||
addServerApi.setData({AppId: Value.fieldOptions});
|
||||
addServerApi.open();
|
||||
async function addNode() {
|
||||
addServerApi.open()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async function update() {
|
||||
reload.value = true;
|
||||
const Value = await BaseFormApi.getValues();
|
||||
try{
|
||||
await updateAppApi(Value.fieldOptions);
|
||||
reload.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){
|
||||
reload.value = false;
|
||||
notification.error({
|
||||
duration:10,
|
||||
message:"服务器更新失败"
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Page>
|
||||
<addServerM class="w-[50%]" @hidden="update"/>
|
||||
<Card class="mb-5" title="服务器操作">
|
||||
<BaseForm />
|
||||
<addServerM class="w-[50%]"/>
|
||||
<Card class="mb-5" title="节点操作">
|
||||
<Space>
|
||||
<Button @click="addServer">新增</Button>
|
||||
<Button type="primary" @click="update" :loading="reload"> 更新 </Button>
|
||||
<Button @click="addNode">新增</Button>
|
||||
<Button> 删除 </Button>
|
||||
<Button danger> 更新配置 </Button>
|
||||
</Space>
|
||||
</Card>
|
||||
<div class="p-5">
|
||||
<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">
|
||||
<h2 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>ServerId</span>
|
||||
<span>名称</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">
|
||||
<span>ServerName</span>
|
||||
<span>Ip</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>Status</span>
|
||||
<span>硬件</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>StartTime</span>
|
||||
<span>地区</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>PlayerNum</span>
|
||||
<span>运营商</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>OpenServerTime</span>
|
||||
<span>时区</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>Handle</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>Config</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <template>
|
||||
<AppList :items="ServerList" title="服务器列表"/>
|
||||
</template> -->
|
||||
<AppList :items="ServerList" title="服务器列表"/>
|
||||
|
||||
</div>
|
||||
<AppList :items="nodeList" title="服务器列表"/>
|
||||
</div>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
@ -193,7 +193,7 @@ watch(
|
||||
<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> ${{ info.Charge.toFixed(2) }}</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>
|
||||
|
||||
@ -33,7 +33,7 @@ defineEmits(['click']);
|
||||
<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">
|
||||
<span>总充值金额:</span>
|
||||
<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 ">
|
||||
@ -46,7 +46,7 @@ defineEmits(['click']);
|
||||
|
||||
<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="">场景:</span>
|
||||
<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 ">
|
||||
@ -59,7 +59,7 @@ defineEmits(['click']);
|
||||
|
||||
<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="">最后登录:</span>
|
||||
<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 ">
|
||||
@ -72,7 +72,7 @@ defineEmits(['click']);
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<span>累计在线:</span>
|
||||
<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 ">
|
||||
@ -85,7 +85,7 @@ defineEmits(['click']);
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<span>今日累计在线:</span>
|
||||
<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 ">
|
||||
@ -98,7 +98,7 @@ defineEmits(['click']);
|
||||
|
||||
<div class="flex w-full">
|
||||
<div class="text-foreground/80 mt-3 flex h-4 md:w-1/2 p-1 leading-2">
|
||||
<span>Bonus:</span>
|
||||
<span class="font-bold">Bonus:</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 ">
|
||||
@ -115,7 +115,7 @@ defineEmits(['click']);
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.Value {
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -71,3 +71,6 @@
|
||||
cursor: pointer;
|
||||
color: hsl(var(--ring));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user