Feat: userStatusBlock

This commit is contained in:
alongw 2023-09-16 19:01:39 +08:00
parent b0ae78f5f9
commit bfe1730fba
5 changed files with 176 additions and 39 deletions

View File

@ -29,6 +29,7 @@ import LinkCard from "@/widgets/others/LinkCard.vue";
import QuickStartFlow from "@/widgets/setupApp/QuickStartFlow.vue";
import IframeCard from "@/widgets/others/IframeCard.vue";
import ClockCard from "@/widgets/others/ClockCard.vue";
import UserStatusBlock from "@/widgets/UserStatusBlock.vue";
import { NEW_CARD_TYPE } from "../types/index";
@ -60,7 +61,8 @@ export const LAYOUT_CARD_TYPES: { [key: string]: any } = {
IframeCard,
TextCard,
LinkCard,
ClockCard
ClockCard,
UserStatusBlock
};
export interface NewCardItem extends LayoutCard {

View File

@ -307,6 +307,51 @@ export const ORIGIN_LAYOUT_CONFIG: PageLayoutConfig[] = [
}
]
},
{
page: "/consumer",
items: [
{
id: getRandomId(),
type: "UserStatusBlock",
title: t("实例总计"),
meta: {
type: "instance_all"
},
width: 3,
height: LayoutCardHeight.SMALL
},
{
id: getRandomId(),
type: "UserStatusBlock",
title: t("正在运行"),
meta: {
type: "instance_running"
},
width: 3,
height: LayoutCardHeight.SMALL
},
{
id: getRandomId(),
type: "UserStatusBlock",
title: t("未运行"),
meta: {
type: "instance_stop"
},
width: 3,
height: LayoutCardHeight.SMALL
},
{
id: getRandomId(),
type: "UserStatusBlock",
title: t("维护中"),
meta: {
type: "instance_error"
},
width: 3,
height: LayoutCardHeight.SMALL
}
]
},
{
page: "/404",

View File

@ -1,8 +1,4 @@
import {
createRouter,
createWebHashHistory,
type RouteRecordRaw,
} from "vue-router";
import { createRouter, createWebHashHistory, type RouteRecordRaw } from "vue-router";
import LayoutContainer from "@/views/LayoutContainer.vue";
import { $t as t } from "@/lang/i18n";
import LoginVue from "@/views/Login.vue";
@ -31,15 +27,15 @@ let originRouterConfig = [
name: t("TXT_CODE_16d71239"),
component: LayoutContainer,
meta: {
mainMenu: true,
},
mainMenu: true
}
},
{
path: "/instances",
name: t("TXT_CODE_e21473bc"),
component: LayoutContainer,
meta: {
mainMenu: true,
mainMenu: true
},
children: [
{
@ -52,82 +48,90 @@ let originRouterConfig = [
path: "/instances/terminal/files",
name: t("TXT_CODE_ae533703"),
component: LayoutContainer,
meta: {},
meta: {}
},
{
path: "/instances/terminal/serverConfig",
name: t("TXT_CODE_d07742fe"),
component: LayoutContainer,
meta: {},
},
],
},
],
meta: {}
}
]
}
]
},
{
path: "/users",
name: t("TXT_CODE_1deaa2dd"),
component: LayoutContainer,
meta: {
mainMenu: true,
mainMenu: true
},
children: [
{
path: "/users/config",
name: t("TXT_CODE_236f70aa"),
component: LayoutContainer,
meta: {},
},
],
meta: {}
}
]
},
{
path: "/node",
name: t("TXT_CODE_e076d90b"),
component: LayoutContainer,
meta: {
mainMenu: true,
},
mainMenu: true
}
},
{
path: "/settings",
name: t("TXT_CODE_b5c7b82d"),
component: LayoutContainer,
meta: {
mainMenu: true,
},
mainMenu: true
}
},
{
path: "/user",
name: t("TXT_CODE_8c3164c9"),
component: LayoutContainer,
meta: {
mainMenu: false,
},
mainMenu: false
}
},
{
path: "/404",
name: "404",
component: LayoutContainer,
meta: {
mainMenu: false,
},
mainMenu: false
}
},
{
path: "/login",
name: "login",
component: LoginVue,
meta: {
mainMenu: false,
},
mainMenu: false
}
},
{
path: "/quickstart",
name: t("TXT_CODE_2799a1dd"),
component: LayoutContainer,
meta: {
mainMenu: false,
},
mainMenu: false
}
},
{
path: "/consumer",
name: t("用户主页"),
component: LayoutContainer,
meta: {
mainMenu: false
}
}
];
function routersConfigOptimize(
@ -147,7 +151,7 @@ function routersConfigOptimize(
const router = createRouter({
history: createWebHashHistory(),
routes: routersConfigOptimize(originRouterConfig) as RouteRecordRaw[],
routes: routersConfigOptimize(originRouterConfig) as RouteRecordRaw[]
});
export { router, originRouterConfig };

View File

@ -217,7 +217,10 @@ onMounted(async () => {
{{ t("TXT_CODE_1987587b") }}
</a-typography-text>
</a-typography-paragraph>
<a-input v-model:value="newUserDialog.data.username" :placeholder="t('TXT_CODE_4ea93630')" />
<a-input
v-model:value="newUserDialog.data.username"
:placeholder="t('TXT_CODE_4ea93630')"
/>
</div>
<div class="mb-20">
@ -227,7 +230,10 @@ onMounted(async () => {
{{ t("TXT_CODE_1f2062c7") }}
</a-typography-text>
</a-typography-paragraph>
<a-input v-model:value="newUserDialog.data.password" :placeholder="t('TXT_CODE_4ea93630')" />
<a-input
v-model:value="newUserDialog.data.password"
:placeholder="t('TXT_CODE_4ea93630')"
/>
</div>
<div class="mb-20">
@ -252,11 +258,7 @@ onMounted(async () => {
<a-typography-title :level="5">{{ t("TXT_CODE_ef0ce2e") }}</a-typography-title>
<a-typography-paragraph>
<a-typography-text type="secondary">
{{
t(
"TXT_CODE_9e9d3767"
)
}}
{{ t("TXT_CODE_9e9d3767") }}
<br />
<a href="https://docs.mcsmanager.com/" target="_blank">
{{ t("TXT_CODE_b01f8383") }}

View File

@ -0,0 +1,84 @@
<script setup lang="ts">
import { useLayoutCardTools } from "@/hooks/useCardTools";
import { t } from "@/lang/i18n";
import type { LayoutCard } from "@/types";
import { computed, onMounted, ref } from "vue";
import { userInfoApi } from "@/services/apis/index";
const props = defineProps<{
card: LayoutCard;
}>();
const { execute } = userInfoApi();
const state = ref();
const getInstanceList = async () => {
const res = await execute({
params: {
advanced: true
}
});
state.value = res.value?.instances;
};
const { getMetaValue } = useLayoutCardTools(props.card);
const type = getMetaValue<string>("type");
const computedStatusList = computed(() => {
if (!state.value) return [];
return [
{
type: "instance_all",
title: t("管理员所分配给您的所有实例总数"),
value: state.value.length
},
{
type: "instance_running",
title: t("实例正在运行中的数量"),
value: state.value.filter((e: any) => e.status == 3).length
},
{
type: "instance_stop",
title: t("实例未处于运行中的数量"),
value: state.value.filter((e: any) => e.status == 0).length
},
{
type: "instance_error",
title: t("暂时不可使用的实例数"),
value: state.value.filter((e: any) => e.status == -1 || e.status == 1 || e.status == 2).length
}
];
});
const realStatus = computed(() => computedStatusList.value.find((v) => v.type === type));
onMounted(() => {
getInstanceList();
});
</script>
<template>
<CardPanel class="StatusBlock" style="height: 100%">
<template #title>{{ card.title }}</template>
<template #body>
<a-typography-text class="color-info">
{{ realStatus?.title }}
</a-typography-text>
<div class="value">{{ realStatus?.value }}</div>
</template>
</CardPanel>
</template>
<style lang="scss" scoped>
.StatusBlock {
.value {
font-weight: 800;
font-size: var(--font-h1);
margin-top: 4px;
}
}
</style>