Compare commits

..

2 Commits

Author SHA1 Message Date
caoqianming 2be9f382ed Merge branch 'main' into carbon 2025-10-30 08:17:27 +08:00
caoqianming e5d8fc7ac3 feat: route和store 2025-10-29 22:45:18 +08:00
6 changed files with 79 additions and 45 deletions

View File

@ -7,7 +7,7 @@
<title>双碳金融系统</title> <title>双碳金融系统</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app" style="height: 100vh;"></div>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
</body> </body>
</html> </html>

20
package-lock.json generated
View File

@ -15,7 +15,6 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^6.0.1", "@vitejs/plugin-vue": "^6.0.1",
"prettier": "^3.6.2",
"vite": "^7.1.7" "vite": "^7.1.7"
} }
}, },
@ -1166,6 +1165,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@ -1201,22 +1201,6 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/prettier": {
"version": "3.6.2",
"resolved": "https://registry.npmmirror.com/prettier/-/prettier-3.6.2.tgz",
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.52.5", "version": "4.52.5",
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.52.5.tgz", "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.52.5.tgz",
@ -1351,6 +1335,7 @@
"integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.5.0", "fdir": "^6.5.0",
@ -1425,6 +1410,7 @@
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.22.tgz", "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.22.tgz",
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.22", "@vue/compiler-dom": "3.5.22",
"@vue/compiler-sfc": "3.5.22", "@vue/compiler-sfc": "3.5.22",

View File

@ -1,39 +1,48 @@
<template> <template>
<div> <t-layout style="height:100%">
<t-layout style="height: 100vh;width: 100vw;"> <t-header>
<t-aside width="160px"> <t-head-menu theme="light">
<t-menu theme="light" default-value="item1" @change="handleMenuChange" v-model="activeMenu" width="160px"> <template #logo>
<template #logo> <img height="28" src="https://tdesign.gtimg.com/site/baseLogo-light.png" alt="logo" />
<img height="28" src="https://tdesign.gtimg.com/site/baseLogo-light.png" alt="logo" /> <!-- <span style="font-size: 18px; font-weight: 600;">XT_WEB_TD</span> -->
</template> </template>
<template #operations>
<t-button variant="outline" :icon="user">{{ userInfo.name }}
</t-button>
<t-button variant="text" shape="square" @click="handleQuit" style="margin-left: 2px;">
<template #icon><t-icon name="logout" style="color: #ff0000;"/></template>
</t-button>
</template>
</t-head-menu>
</t-header>
<t-layout>
<t-aside style="border-top: 1px solid #e5e5e5;" width="160px">
<t-menu theme="light" default-value="item1" @change="handleMenuChange"
v-model="activeMenu" width="160px">
<t-menu-item v-for="route in menuRoutes" :key="route.name" :value="route.name" <t-menu-item v-for="route in menuRoutes" :key="route.name" :value="route.name"
:disabled="route.meta?.disabled"> :disabled="route.meta?.disabled">
{{ route.name }} {{ route.name }}
<template #icon v-if="route.meta?.icon">
<t-icon :name="route.meta.icon" />
</template>
</t-menu-item> </t-menu-item>
<!-- <template #operations>
<t-button variant="text" shape="square" @click="changeCollapsed">
<template #icon><t-icon :name="iconName" /></template>
</t-button>
</template> -->
</t-menu> </t-menu>
</t-aside> </t-aside>
<t-layout> <t-content style="border-top: 1px solid #e5e5e5;">
<t-header> <router-view />
<t-head-menu theme="light"> </t-content>
<template #operations>
<t-button theme="warning" @click="handleQuit">退出</t-button>
</template>
</t-head-menu>
</t-header>
<t-content style="padding: 4px">
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</t-content>
</t-layout>
</t-layout> </t-layout>
</div> </t-layout>
</template> </template>
<script setup> <script setup>
import { ref, computed, watch } from 'vue'; import { ref, computed, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { authToken, userInfo } from '@/store/index.js'
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
@ -58,6 +67,8 @@ watch(() => route.name, (newName) => {
}, { immediate: true }) }, { immediate: true })
const handleQuit = () => { const handleQuit = () => {
window.location.replace('/login') authToken.access = null
authToken.refresh = null
router.replace('/login')
} }
</script> </script>

View File

@ -13,7 +13,7 @@
</t-input> </t-input>
</t-form-item> </t-form-item>
<t-form-item> <t-form-item>
<t-input type="password" v-model="password" size="large"> <t-input type="password" v-model="formData.password" size="large">
<template #prefix-icon> <template #prefix-icon>
<t-icon name="lock-on" /> <t-icon name="lock-on" />
</template> </template>
@ -30,6 +30,7 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { authToken } from '@/store/index.js'
const router = useRouter(); const router = useRouter();
const formData = ref({ const formData = ref({
username: "", username: "",
@ -39,8 +40,9 @@ const submitLoading = ref(false);
const handleLogin = () => { const handleLogin = () => {
submitLoading.value = true; submitLoading.value = true;
setTimeout(() => { setTimeout(() => {
authToken.access = "123456";
submitLoading.value = false; submitLoading.value = false;
router.push({ path: "/home" }); router.replace({ path: "/home" });
}, 300); }, 300);
} }
</script> </script>

View File

@ -1,4 +1,5 @@
import { createRouter, createWebHistory} from 'vue-router'; import { createRouter, createWebHistory} from 'vue-router';
import { authToken } from '@/store/index.js'
const routes = [ const routes = [
{ path: "/", redirect: "/login" }, { path: "/", redirect: "/login" },
{ {
@ -14,6 +15,7 @@ const routes = [
{ {
path: "", path: "",
name: "工作台", name: "工作台",
meta: { icon: "file"},
children: [ children: [
// { // {
// path: "home", // path: "home",
@ -52,4 +54,20 @@ const router = createRouter({
routes, routes,
}); });
router.beforeEach((to, from, next) => {
if (to.path === "/login") {
if (authToken.access) {
next("/home");
} else {
next();
}
} else {
if (authToken.access) {
next();
} else {
next("/login");
}
}
})
export default router; export default router;

17
src/store/index.js Normal file
View File

@ -0,0 +1,17 @@
import { reactive, watch } from "vue";
export const userInfo = reactive(JSON.parse(localStorage.getItem("userInfo")) || {
name: "张三",
username: "zhangsan"
});
watch(userInfo, (newVal) => {
localStorage.setItem("userInfo", JSON.stringify(newVal));
}, { deep: true, immediate: true})
export const authToken = reactive(JSON.parse(localStorage.getItem("authToken")) ||{
access: null,
refresh: null
})
watch(authToken, (newVal) => {
localStorage.setItem("authToken", JSON.stringify(newVal));
}, { deep: true, immediate: true})