mirror of
https://github.com/MCSManager/MCSManager.git
synced 2025-01-30 15:19:32 +08:00
Feat: support open page
This commit is contained in:
parent
98f6b93225
commit
cadc0637a1
@ -53,20 +53,6 @@ import { closeAppLoading } from "./tools/dom";
|
||||
|
||||
onMounted(async () => {
|
||||
closeAppLoading();
|
||||
|
||||
if (["", "/"].includes(router.currentRoute.value.path.trim())) {
|
||||
if (state.userInfo?.token && !isAdmin.value) {
|
||||
router.push({
|
||||
path: "/customer"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!state.userInfo?.token) {
|
||||
return router.push({
|
||||
path: "/login"
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -53,11 +53,17 @@ const menus = computed(() => {
|
||||
return router
|
||||
.getRoutes()
|
||||
.filter((v) => {
|
||||
return v.meta.mainMenu && isLogged.value;
|
||||
})
|
||||
.filter((v) => {
|
||||
if (v.meta.onlyDisplayEditMode) return containerState.isDesignMode;
|
||||
return true;
|
||||
if (containerState.isDesignMode) {
|
||||
return v.meta.onlyDisplayEditMode || v.meta.mainMenu;
|
||||
}
|
||||
if (isAdmin.value) {
|
||||
return v.meta.mainMenu === true && v.meta.onlyDisplayEditMode !== true;
|
||||
}
|
||||
return (
|
||||
v.meta.mainMenu === true &&
|
||||
isLogged.value &&
|
||||
Number(appState.userInfo?.permission) >= Number(v.meta.permission)
|
||||
);
|
||||
})
|
||||
.map((r) => {
|
||||
return {
|
||||
@ -68,20 +74,6 @@ const menus = computed(() => {
|
||||
});
|
||||
});
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
console.log("Router:", from, "->", to);
|
||||
if (to.name == null) {
|
||||
router.push({
|
||||
path: "/404",
|
||||
query: {
|
||||
redirect: to.fullPath
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
const arr = [
|
||||
{
|
||||
@ -207,9 +199,9 @@ const appMenus = computed(() => {
|
||||
icon: BuildOutlined,
|
||||
click: () => {
|
||||
changeDesignMode(true);
|
||||
|
||||
notification.info({
|
||||
placement: "top",
|
||||
notification.warning({
|
||||
placement: "bottom",
|
||||
type: "warning",
|
||||
message: t("TXT_CODE_7b1adf35"),
|
||||
description: t("TXT_CODE_6b6f1d3")
|
||||
});
|
||||
|
@ -37,6 +37,7 @@ import InstanceShortcut from "@/widgets/instance/Shortcut.vue";
|
||||
import NodeItem from "@/widgets/node/NodeItem.vue";
|
||||
import TitleCard from "@/widgets/TitleCard.vue";
|
||||
import LoginCard from "@/widgets/LoginCard.vue";
|
||||
import DefaultCard from "@/widgets/DefaultCard.vue";
|
||||
|
||||
import { NEW_CARD_TYPE } from "../types/index";
|
||||
import { ROLE } from "./router";
|
||||
@ -77,7 +78,8 @@ export const LAYOUT_CARD_TYPES: { [key: string]: any } = {
|
||||
ImageManager,
|
||||
NewImage,
|
||||
Schedule,
|
||||
InstanceShortcut
|
||||
InstanceShortcut,
|
||||
DefaultCard
|
||||
};
|
||||
|
||||
export interface NewCardItem extends LayoutCard {
|
||||
|
@ -43,6 +43,25 @@ let originRouterConfig: RouterConfig[] = [
|
||||
mainMenu: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/quickstart",
|
||||
name: t("TXT_CODE_2799a1dd"),
|
||||
component: LayoutContainer,
|
||||
meta: {
|
||||
permission: ROLE.ADMIN,
|
||||
mainMenu: false
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/quickstart/minecraft",
|
||||
name: t("TXT_CODE_8d8b1d6a"),
|
||||
component: LayoutContainer,
|
||||
meta: {
|
||||
permission: ROLE.ADMIN
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
name: t("TXT_CODE_16d71239"),
|
||||
@ -178,7 +197,7 @@ let originRouterConfig: RouterConfig[] = [
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "404",
|
||||
name: t("页面不存在"),
|
||||
component: LayoutContainer,
|
||||
meta: {
|
||||
permission: ROLE.GUEST,
|
||||
@ -197,33 +216,22 @@ let originRouterConfig: RouterConfig[] = [
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
name: "登录页面",
|
||||
name: t("登录页"),
|
||||
component: LoginPage,
|
||||
meta: {
|
||||
permission: ROLE.GUEST,
|
||||
mainMenu: true,
|
||||
onlyDisplayEditMode: true
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/quickstart",
|
||||
name: t("TXT_CODE_2799a1dd"),
|
||||
path: "/_open_page",
|
||||
name: t("开放页"),
|
||||
component: LayoutContainer,
|
||||
meta: {
|
||||
permission: ROLE.ADMIN,
|
||||
mainMenu: false
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/quickstart/minecraft",
|
||||
name: t("TXT_CODE_8d8b1d6a"),
|
||||
component: LayoutContainer,
|
||||
meta: {
|
||||
permission: ROLE.ADMIN
|
||||
}
|
||||
}
|
||||
]
|
||||
permission: ROLE.ADMIN, // open page without permission
|
||||
mainMenu: true,
|
||||
onlyDisplayEditMode: true
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@ -254,8 +262,34 @@ const router = createRouter({
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const { state } = useAppStateStore();
|
||||
const permission = state.userInfo?.permission ?? 0;
|
||||
if (Number(to.meta.permission ?? 0) <= permission) {
|
||||
const userPermission = state.userInfo?.permission ?? 0;
|
||||
const toPagePermission = Number(to.meta.permission ?? 0);
|
||||
const fromRoutePath = router.currentRoute.value.path.trim();
|
||||
const toRoutePath = to.path.trim();
|
||||
console.info(
|
||||
"Router Changed:",
|
||||
from,
|
||||
"--->",
|
||||
to,
|
||||
"MyPermission:",
|
||||
userPermission,
|
||||
"toPagePermission:",
|
||||
toPagePermission
|
||||
);
|
||||
|
||||
if (toRoutePath.includes("_open_page") || toRoutePath === "/login") {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!state.userInfo?.token) return next("/login");
|
||||
|
||||
if (["", "/"].includes(fromRoutePath) && toRoutePath !== "/customer") {
|
||||
if (userPermission === ROLE.USER) {
|
||||
return next("/customer");
|
||||
}
|
||||
}
|
||||
|
||||
if (to.name && toPagePermission <= userPermission) {
|
||||
next();
|
||||
} else {
|
||||
next("/404");
|
||||
|
@ -3,11 +3,9 @@ import { ref } from "vue";
|
||||
export function useMouseEnter() {
|
||||
const targetId = ref<string>();
|
||||
const handleMouseEnter = (id: string) => {
|
||||
console.log("进入:", id);
|
||||
targetId.value = id;
|
||||
};
|
||||
const handleMouseLeave = (id: string) => {
|
||||
console.log("出去:", id);
|
||||
if (targetId.value === id) targetId.value = undefined;
|
||||
};
|
||||
|
||||
|
@ -58,6 +58,16 @@ export const loginUser = useDefineApi<
|
||||
method: "POST"
|
||||
});
|
||||
|
||||
export const loginPageInfo = useDefineApi<
|
||||
any,
|
||||
{
|
||||
loginInfo: string;
|
||||
}
|
||||
>({
|
||||
url: "/api/auth/login_info",
|
||||
method: "GET"
|
||||
});
|
||||
|
||||
export const logoutUser = useDefineApi<any, any>({
|
||||
url: "/api/auth/logout",
|
||||
method: "GET"
|
||||
|
59
frontend/src/widgets/DefaultCard.vue
Normal file
59
frontend/src/widgets/DefaultCard.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<script setup lang="ts">
|
||||
import { t } from "@/lang/i18n";
|
||||
import { useAppStateStore } from "@/stores/useAppStateStore";
|
||||
import type { LayoutCard } from "@/types";
|
||||
|
||||
defineProps<{
|
||||
card: LayoutCard;
|
||||
}>();
|
||||
const { state, isAdmin } = useAppStateStore();
|
||||
const myAddr = `${window.location.href}`;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardPanel class="CardWrapper h-100 w-100" style="height: 100%">
|
||||
<template #title>{{ card.title }}</template>
|
||||
<template #body>
|
||||
<div class="h-100 w-100">
|
||||
<a-empty
|
||||
:image-style="{
|
||||
height: '140px'
|
||||
}"
|
||||
>
|
||||
<template #description>
|
||||
<div v-if="isAdmin" class="admin-text">
|
||||
<a-typography-paragraph>
|
||||
<p>
|
||||
{{ t("1. 此页面所有人均可以访问,您也可以放置任何权限的卡片。") }}
|
||||
</p>
|
||||
<p>
|
||||
{{ t("2. 访问者没有登录或者权限不足,依然会无法加载卡片。") }}
|
||||
</p>
|
||||
<p>
|
||||
{{ t("3. 设计完成后,您可以使用已登录的状态直接访问。") }}
|
||||
</p>
|
||||
|
||||
<pre>{{ myAddr }}</pre>
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-typography-paragraph>
|
||||
<p>
|
||||
{{ t("此页面无内容。") }}
|
||||
</p>
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
</template>
|
||||
</a-empty>
|
||||
</div>
|
||||
</template>
|
||||
</CardPanel>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.admin-text {
|
||||
text-align: left;
|
||||
max-width: 420px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
</style>
|
@ -7,14 +7,20 @@ import {
|
||||
LockOutlined,
|
||||
UserOutlined
|
||||
} from "@ant-design/icons-vue";
|
||||
import { reactive, ref } from "vue";
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { router } from "@/config/router";
|
||||
import { loginUser } from "@/services/apis";
|
||||
import { loginPageInfo, loginUser } from "@/services/apis";
|
||||
import { sleep } from "@/tools/common";
|
||||
import { message } from "ant-design-vue";
|
||||
import { useAppStateStore } from "@/stores/useAppStateStore";
|
||||
import type { LayoutCard } from "@/types";
|
||||
import { markdownToHTML } from "@/tools/safe";
|
||||
|
||||
const { state: pageInfoResult, execute } = loginPageInfo();
|
||||
|
||||
onMounted(async () => {
|
||||
await execute();
|
||||
});
|
||||
const props = defineProps<{
|
||||
card: LayoutCard;
|
||||
}>();
|
||||
@ -110,6 +116,11 @@ const loginSuccess = () => {
|
||||
|
||||
<div class="mt-24 flex-between align-center">
|
||||
<div class="mcsmanager-link">
|
||||
<div
|
||||
v-if="pageInfoResult?.loginInfo"
|
||||
class="global-markdown-html"
|
||||
v-html="markdownToHTML(pageInfoResult?.loginInfo || '')"
|
||||
></div>
|
||||
Powered by
|
||||
<a href="https://mcsmanager.com" target="_blank" rel="noopener noreferrer">
|
||||
MCSManager
|
||||
@ -141,6 +152,17 @@ const loginSuccess = () => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.mcsmanager-link {
|
||||
.global-markdown-html {
|
||||
text-align: left !important;
|
||||
p {
|
||||
margin: 0px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.loginDone {
|
||||
.login-page-container {
|
||||
|
@ -546,6 +546,19 @@ function getDefaultFrontendLayoutConfig(): IPageLayoutConfig[] {
|
||||
disableDelete: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
page: "/_open_page",
|
||||
items: [
|
||||
{
|
||||
id: getRandomId(),
|
||||
meta: {},
|
||||
type: "DefaultCard",
|
||||
title: t("关于本页面"),
|
||||
width: 6,
|
||||
height: LayoutCardHeight.SMALL
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user