feat: add a new feature
This commit is contained in:
parent
2b80695c2d
commit
1ffc4237ca
18
.vscode/extensions.json
vendored
18
.vscode/extensions.json
vendored
@ -4,7 +4,23 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"Vue.volar", // Vue语言支持扩展
|
"afzalsayed96.icones",
|
||||||
|
"antfu.iconify",
|
||||||
|
"antfu.unocss",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"editorconfig.editorconfig",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"formulahendry.auto-close-tag",
|
||||||
|
"formulahendry.auto-complete-tag",
|
||||||
|
"formulahendry.auto-rename-tag",
|
||||||
|
"lokalise.i18n-ally",
|
||||||
|
"mhutchie.git-graph",
|
||||||
|
"mikestead.dotenv",
|
||||||
|
"naumovs.color-highlight",
|
||||||
|
"pkief.material-icon-theme",
|
||||||
|
"sdras.vue-vscode-snippets",
|
||||||
|
"whtouche.vscode-js-console-utils",
|
||||||
|
"zhuangtongfa.material-theme",
|
||||||
"Vue.vscode-typescript-vue-plugin", // 一个TS服务器插件,使TS服务器知道*.vue文件。
|
"Vue.vscode-typescript-vue-plugin", // 一个TS服务器插件,使TS服务器知道*.vue文件。
|
||||||
"esbenp.prettier-vscode", // 代码格式化
|
"esbenp.prettier-vscode", // 代码格式化
|
||||||
"dbaeumer.vscode-eslint" // 代码质量检查
|
"dbaeumer.vscode-eslint" // 代码质量检查
|
||||||
|
|||||||
242
.vscode/settings.json
vendored
242
.vscode/settings.json
vendored
@ -1,73 +1,185 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// vscode 编辑器和插件的配置 ////////////////////////////////////////////////
|
|
||||||
// 参考:https://blog.csdn.net/weixin_46238462/article/details/125867532 //
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
// "editor.codeActionsOnSave": true,
|
||||||
"editor.detectIndentation": false,
|
|
||||||
"editor.tabSize": 4,
|
|
||||||
"files.eol": "auto",
|
|
||||||
"eslint.enable": true,
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
|
||||||
// 官网参考:https://prettier.io/docs/en/options.html#tab-width //
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
"prettier.semi": true,
|
|
||||||
"prettier.tabWidth": 4,
|
|
||||||
"prettier.printWidth": 160,
|
|
||||||
"prettier.endOfLine": "auto",
|
|
||||||
"prettier.singleQuote": true,
|
|
||||||
"prettier.ignorePath": ".prettierignore",
|
|
||||||
// Enable the ESlint flat config support
|
|
||||||
// (remove this if your ESLint extension above v3.0.5)
|
|
||||||
"eslint.experimental.useFlatConfig": true,
|
|
||||||
|
|
||||||
// Disable the default formatter, use eslint instead
|
|
||||||
"prettier.enable": false,
|
|
||||||
"editor.formatOnSave": false,
|
|
||||||
|
|
||||||
// Auto fix
|
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": "explicit",
|
"source.fixAll.eslint": "explicit",
|
||||||
"source.organizeImports": "never"
|
"source.organizeImports": "never"
|
||||||
},
|
},
|
||||||
|
"eslint.experimental.useFlatConfig": true,
|
||||||
// Silent the stylistic rules in you IDE, but still auto fix them
|
"editor.formatOnSave": false,
|
||||||
"eslint.rules.customizations": [
|
"prettier.enable": false,
|
||||||
{ "rule": "style/*", "severity": "off" },
|
"unocss.root": ["./"],
|
||||||
{ "rule": "format/*", "severity": "off" },
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
{ "rule": "*-indent", "severity": "off" },
|
"vue.server.hybridMode": true,
|
||||||
{ "rule": "*-spacing", "severity": "off" },
|
"eslint.validate": ["html", "css", "scss", "json", "jsonc"],
|
||||||
{ "rule": "*-spaces", "severity": "off" },
|
"i18n-ally.displayLanguage": "zh-cn",
|
||||||
{ "rule": "*-order", "severity": "off" },
|
"i18n-ally.enabledParsers": ["ts"],
|
||||||
{ "rule": "*-dangle", "severity": "off" },
|
"i18n-ally.enabledFrameworks": ["vue"],
|
||||||
{ "rule": "*-newline", "severity": "off" },
|
"i18n-ally.editor.preferEditor": true,
|
||||||
{ "rule": "*quotes", "severity": "off" },
|
"i18n-ally.keystyle": "nested",
|
||||||
{ "rule": "*semi", "severity": "off" }
|
"i18n-ally.localesPaths": ["src/locales/langs"],
|
||||||
|
"editor.fontLigatures": true,
|
||||||
|
"editor.quickSuggestions": {
|
||||||
|
"strings": true
|
||||||
|
},
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"files.associations": {
|
||||||
|
"*.env.*": "dotenv",
|
||||||
|
"*.svg": "html"
|
||||||
|
},
|
||||||
|
// "files.refactoring.autoSave": false,
|
||||||
|
"files.eol": "\n",
|
||||||
|
"path-intellisense.mappings": {
|
||||||
|
"@": "${workspaceFolder}/src",
|
||||||
|
"~@": "${workspaceFolder}/src"
|
||||||
|
},
|
||||||
|
"terminal.integrated.fontSize": 14,
|
||||||
|
"terminal.integrated.fontWeight": 500,
|
||||||
|
"terminal.integrated.tabs.enabled": true,
|
||||||
|
// "workbench.iconTheme": "material-icon-theme",
|
||||||
|
"workbench.colorTheme": "Visual Studio Light",
|
||||||
|
"css.lint.unknownAtRules": "ignore",
|
||||||
|
"psi-header.config": {
|
||||||
|
"forceToTop": true,
|
||||||
|
"blankLinesAfter": 3,
|
||||||
|
"license": "Custom"
|
||||||
|
},
|
||||||
|
"psi-header.changes-tracking": {
|
||||||
|
"isActive": true,
|
||||||
|
"modAuthor": "Modified By: ",
|
||||||
|
"modDate": "Last Modified: ",
|
||||||
|
"modDateFormat": "date",
|
||||||
|
"include": [],
|
||||||
|
"exclude": ["markdown", "json"],
|
||||||
|
"excludeGlob": ["out/**", "src/**/*.xyz", "components/**/*.mk"],
|
||||||
|
"autoHeader": "manualSave"
|
||||||
|
},
|
||||||
|
"psi-header.license-text": ["May the force be with you."],
|
||||||
|
"psi-header.variables": [
|
||||||
|
["company", "self."]
|
||||||
|
// ["author", "你的名字 - 默认主机名"],
|
||||||
|
// ["authoremail", "xxxxx@gmail.com"],
|
||||||
|
// ["initials", "S.L"]
|
||||||
],
|
],
|
||||||
|
"psi-header.lang-config": [
|
||||||
// Enable eslint for all supported languages
|
{
|
||||||
"eslint.validate": [
|
"language": "html",
|
||||||
"javascript",
|
"begin": "<!--",
|
||||||
"javascriptreact",
|
"end": "-->",
|
||||||
"typescript",
|
"prefix": " "
|
||||||
"typescriptreact",
|
},
|
||||||
"vue",
|
{
|
||||||
"html",
|
"language": "vue",
|
||||||
"markdown",
|
"begin": "<!--",
|
||||||
"json",
|
"end": "-->",
|
||||||
"jsonc",
|
"prefix": " "
|
||||||
"yaml",
|
},
|
||||||
"toml",
|
{
|
||||||
"xml",
|
"language": "lua",
|
||||||
"gql",
|
"begin": "--[[",
|
||||||
"graphql",
|
"prefix": "--",
|
||||||
"astro",
|
"end": "--]]",
|
||||||
"css",
|
"blankLinesAfter": 0
|
||||||
"less",
|
},
|
||||||
"scss",
|
{
|
||||||
"pcss",
|
"language": "python",
|
||||||
"postcss"
|
"begin": "###",
|
||||||
|
"prefix": "# ",
|
||||||
|
"end": "###",
|
||||||
|
"blankLinesAfter": 0,
|
||||||
|
"beforeHeader": ["#!/usr/bin/env python", "# -*- coding:utf-8 -*-"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "javascript",
|
||||||
|
"begin": "/**",
|
||||||
|
"prefix": " * ",
|
||||||
|
"end": " */",
|
||||||
|
"blankLinesAfter": 0,
|
||||||
|
"forceToTop": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "typescript",
|
||||||
|
"mapTo": "javascript",
|
||||||
|
"begin": "/**",
|
||||||
|
"prefix": " * ",
|
||||||
|
"end": " */",
|
||||||
|
"blankLinesAfter": 0,
|
||||||
|
"forceToTop": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"psi-header.templates": [
|
||||||
|
{
|
||||||
|
"language": "javascript",
|
||||||
|
"template": [
|
||||||
|
"## File: <<filerelativepath>>",
|
||||||
|
"",
|
||||||
|
"Project: <<projectname>>",
|
||||||
|
"",
|
||||||
|
"Created Date: <<filecreated('YYYY-MM-DD HH:mm:SS')>>",
|
||||||
|
"",
|
||||||
|
"Author: <<author>>",
|
||||||
|
"",
|
||||||
|
"## Last Modified: <<filecreated('YYYY-MM-DD HH:mm:SS')>>",
|
||||||
|
"",
|
||||||
|
"Modified By: ",
|
||||||
|
"",
|
||||||
|
"## Copyright (c) <<year>> <<company>>",
|
||||||
|
"",
|
||||||
|
"Use To: "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "typescript",
|
||||||
|
"template": [
|
||||||
|
"## File: <<filerelativepath>>",
|
||||||
|
"",
|
||||||
|
"Project: <<projectname>>",
|
||||||
|
"",
|
||||||
|
"Created Date: <<filecreated('YYYY-MM-DD HH:mm:SS')>>",
|
||||||
|
"",
|
||||||
|
"Author: <<author>>",
|
||||||
|
"",
|
||||||
|
"## Last Modified: <<filecreated('YYYY-MM-DD HH:mm:SS')>>",
|
||||||
|
"",
|
||||||
|
"Modified By: ",
|
||||||
|
"",
|
||||||
|
"## Copyright (c) <<year>> <<company>>",
|
||||||
|
"",
|
||||||
|
"Use To: "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "html",
|
||||||
|
"begin": "<!--",
|
||||||
|
"end": "-->",
|
||||||
|
"template": [
|
||||||
|
"## File: <<filerelativepath>>",
|
||||||
|
"",
|
||||||
|
"Project: <<projectname>>",
|
||||||
|
"",
|
||||||
|
"Created Date: <<filecreated('YYYY-MM-DD HH:mm:SS')>>",
|
||||||
|
"",
|
||||||
|
"Author: <<author>>",
|
||||||
|
"",
|
||||||
|
"## Last Modified: <<filecreated('YYYY-MM-DD HH:mm:SS')>>",
|
||||||
|
"",
|
||||||
|
"Modified By: ",
|
||||||
|
"",
|
||||||
|
"## Copyright (c) <<year>> <<company>>",
|
||||||
|
"",
|
||||||
|
"Use To: "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "typescript",
|
||||||
|
"mapTo": "javascript"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "tsx",
|
||||||
|
"mapTo": "javascript"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "vue",
|
||||||
|
"mapTo": "html"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
13
README.md
13
README.md
@ -33,6 +33,19 @@
|
|||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
## appProvider 插件
|
||||||
|
|
||||||
|
- ./vite/plugins/appProvider.ts
|
||||||
|
- 本配置功能为扫描 @/pages/xx/index.vue 文件,通过覆盖一层 view 的方式注入 style 变量
|
||||||
|
- 相关文件 `./src/layout/AppProvider.vue`
|
||||||
|
|
||||||
|
## vite/plugins/build.unocss.config.ts - 构建 unocss 相关配置
|
||||||
|
|
||||||
|
- 本配置通过读取 ./src/theme/theme.ts 文件中相关配置构建 **theme 变量 , **theme 即 AppProvider.vue 文件的 style 变量
|
||||||
|
- 相关文件 `./src/theme/theme.ts`
|
||||||
|
`./src/stores/modules/system.ts`
|
||||||
|
`./src/mixins/theme.ts`
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
- **uni-app Vue3 Vite4 pinia2 TypeScript 基础框架**
|
- **uni-app Vue3 Vite4 pinia2 TypeScript 基础框架**
|
||||||
|
|||||||
@ -51,10 +51,14 @@
|
|||||||
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-4010920240607001",
|
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-4010920240607001",
|
||||||
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4010920240607001",
|
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4010920240607001",
|
||||||
"@multiavatar/multiavatar": "^1.0.7",
|
"@multiavatar/multiavatar": "^1.0.7",
|
||||||
|
"@unocss/transformer-directives": "^0.61.0",
|
||||||
"alova": "^2.21.3",
|
"alova": "^2.21.3",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
|
"unplugin-vue-components": "^0.27.0",
|
||||||
"vue": "^3.4.29"
|
"vue": "^3.4.29"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -68,6 +72,7 @@
|
|||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.14.2",
|
"@types/node": "^20.14.2",
|
||||||
|
"@types/normalize-path": "^3.0.0",
|
||||||
"@unocss/eslint-plugin": "^0.61.0",
|
"@unocss/eslint-plugin": "^0.61.0",
|
||||||
"@vitejs/plugin-vue": "^5.0.5",
|
"@vitejs/plugin-vue": "^5.0.5",
|
||||||
"@vue/runtime-core": "^3.4.29",
|
"@vue/runtime-core": "^3.4.29",
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onHide, onLaunch, onShow } from '@dcloudio/uni-app';
|
import { onHide, onLaunch, onShow } from '@dcloudio/uni-app';
|
||||||
import { useUserStore } from '@/stores/modules/user';
|
// import { useUserStore } from '@/stores/modules/user';
|
||||||
|
|
||||||
onLaunch(() => {
|
onLaunch(() => {
|
||||||
console.log('App Launch');
|
console.log('App Launch');
|
||||||
});
|
});
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
const userStore = useUserStore();
|
// const userStore = useUserStore();
|
||||||
userStore.initUserInfo();
|
// userStore.initUserInfo();
|
||||||
console.log('App Show');
|
console.log('App Show');
|
||||||
});
|
});
|
||||||
onHide(() => {
|
onHide(() => {
|
||||||
|
|||||||
@ -2,14 +2,14 @@
|
|||||||
"version": "1",
|
"version": "1",
|
||||||
"prompt": "template",
|
"prompt": "template",
|
||||||
"title": "服务协议和隐私政策",
|
"title": "服务协议和隐私政策",
|
||||||
"message": " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"\">《服务协议》</a>和<a href=\"\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
|
"message": "__请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款, 包括但不限于:为了更好的向你提供服务, 我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>__你可阅读<a href=\"\">《服务协议》</a>和<a href=\"\">《隐私政策》</a>了解详细信息。如果你同意, 请点击下面按钮开始接受我们的服务。",
|
||||||
"buttonAccept": "同意并接受",
|
"buttonAccept": "同意并接受",
|
||||||
"buttonRefuse": "暂不同意",
|
"buttonRefuse": "暂不同意",
|
||||||
// HX 3.4.13之后版本新增,system 使用系统webview 打开隐私协议链接,默认使用uni-app内置web组件
|
// HX 3.4.13之后版本新增, system 使用系统webview 打开隐私协议链接, 默认使用uni-app内置web组件
|
||||||
"hrefLoader": "default",
|
"hrefLoader": "default",
|
||||||
"second": {
|
"second": {
|
||||||
"title": "确认提示",
|
"title": "确认提示",
|
||||||
"message": " 进入应用前,你需先同意<a href=\"\">《服务协议》</a>和<a href=\"\">《隐私政策》</a>,否则将退出应用。",
|
"message": "__进入应用前, 你需先同意<a href=\"\">《服务协议》</a>和<a href=\"\">《隐私政策》</a>, 否则将退出应用。",
|
||||||
"buttonAccept": "同意并继续",
|
"buttonAccept": "同意并继续",
|
||||||
"buttonRefuse": "退出应用"
|
"buttonRefuse": "退出应用"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @description: 客户端 api 返回结果设置
|
||||||
|
*/
|
||||||
|
export enum ClientApiResultEnum {
|
||||||
|
CLIENT_SUCCESS = 1,
|
||||||
|
CLIENT_ERROR = 0,
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
* @description: 请求结果设置
|
* @description: 请求结果设置
|
||||||
*/
|
*/
|
||||||
export enum ResultEnum {
|
export enum ResultEnum {
|
||||||
SUCCESS = 10000,
|
SUCCESS = 200,
|
||||||
FAIL = 10001,
|
FAIL = 10001,
|
||||||
ERROR = 1,
|
ERROR = 1,
|
||||||
TIMEOUT = 401,
|
TIMEOUT = 401,
|
||||||
|
|||||||
@ -3,12 +3,16 @@ import App from './App.vue';
|
|||||||
import 'virtual:uno.css';
|
import 'virtual:uno.css';
|
||||||
import { setupRouter } from './router';
|
import { setupRouter } from './router';
|
||||||
import { setupStore } from './stores';
|
import { setupStore } from './stores';
|
||||||
|
import { themeMixin } from '@/mixins/theme';
|
||||||
|
|
||||||
export function createApp() {
|
export function createApp() {
|
||||||
const app = createSSRApp(App);
|
const app = createSSRApp(App);
|
||||||
|
|
||||||
setupStore(app);
|
setupStore(app);
|
||||||
|
|
||||||
|
//
|
||||||
|
app.mixin(themeMixin);
|
||||||
|
|
||||||
setupRouter(app);
|
setupRouter(app);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { useUserStore } from '@/stores/modules/user';
|
|||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const { loggedIn, userInfo } = storeToRefs(userStore);
|
const { loginOrNot, userInfo } = storeToRefs(userStore);
|
||||||
|
|
||||||
function handleJump(url: string) {
|
function handleJump(url: string) {
|
||||||
router.push(url);
|
router.push(url);
|
||||||
@ -17,8 +17,8 @@ function handleLoginOut() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="text-md pt-36">
|
<view class="text-md pt-36 bg-primary">
|
||||||
<view v-if="loggedIn" class="text-center">
|
<view v-if="loginOrNot" class="text-center">
|
||||||
<image class="h-56 w-56" :src="userInfo?.avatar" />
|
<image class="h-56 w-56" :src="userInfo?.avatar" />
|
||||||
<view class="mt-2">
|
<view class="mt-2">
|
||||||
{{ userInfo?.nickname }}
|
{{ userInfo?.nickname }}
|
||||||
@ -28,7 +28,7 @@ function handleLoginOut() {
|
|||||||
<BasicButton @click="handleJump('/pages/log/index?id=4345&title=log&word=关键词')">
|
<BasicButton @click="handleJump('/pages/log/index?id=4345&title=log&word=关键词')">
|
||||||
log
|
log
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
<BasicButton v-if="loggedIn" @click="handleLoginOut">
|
<BasicButton v-if="loginOrNot" @click="handleLoginOut">
|
||||||
登出
|
登出
|
||||||
</BasicButton>
|
</BasicButton>
|
||||||
<BasicButton v-else @click="handleJump('/pages/login/index')">
|
<BasicButton v-else @click="handleJump('/pages/login/index')">
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import type { Router } from 'uni-mini-router/lib/interfaces';
|
import type { Router } from 'uni-mini-router/lib/interfaces';
|
||||||
import { isLogin } from '@/utils/auth';
|
|
||||||
|
|
||||||
export function createRouterGuard(router: Router) {
|
export function createRouterGuard(router: Router) {
|
||||||
createBeforeEachGuard(router);
|
createBeforeEachGuard(router);
|
||||||
@ -9,7 +8,7 @@ export function createRouterGuard(router: Router) {
|
|||||||
function createBeforeEachGuard(router: Router) {
|
function createBeforeEachGuard(router: Router) {
|
||||||
router.beforeEach((to, _, next) => {
|
router.beforeEach((to, _, next) => {
|
||||||
console.log('beforeEach', to);
|
console.log('beforeEach', to);
|
||||||
const _isLogin = isLogin();
|
const _isLogin = true;
|
||||||
if (to && to?.meta?.ignoreAuth) {
|
if (to && to?.meta?.ignoreAuth) {
|
||||||
// 如果目标路由忽略验证直接跳转
|
// 如果目标路由忽略验证直接跳转
|
||||||
next();
|
next();
|
||||||
@ -31,7 +30,7 @@ function createAfterEachGuard(router: Router) {
|
|||||||
router.afterEach((to) => {
|
router.afterEach((to) => {
|
||||||
if (to && to?.meta?.ignoreAuth)
|
if (to && to?.meta?.ignoreAuth)
|
||||||
return;
|
return;
|
||||||
const _isLogin = isLogin();
|
const _isLogin = true;
|
||||||
if (!_isLogin && to && to.name !== 'Login') {
|
if (!_isLogin && to && to.name !== 'Login') {
|
||||||
// 如果没有登录且目标路由不是登录页面则跳转到登录页面
|
// 如果没有登录且目标路由不是登录页面则跳转到登录页面
|
||||||
router.push({ name: 'Login', params: { ...to.query } });
|
router.push({ name: 'Login', params: { ...to.query } });
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import type { App } from 'vue';
|
|
||||||
import { createPinia } from 'pinia';
|
import { createPinia } from 'pinia';
|
||||||
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||||
|
import type { App } from 'vue';
|
||||||
|
|
||||||
const store = createPinia();
|
const store = createPinia();
|
||||||
|
store.use(piniaPluginPersistedstate);
|
||||||
|
|
||||||
export function setupStore(app: App<Element>) {
|
export function setupStore(app: App<Element>) {
|
||||||
app.use(store);
|
app.use(store);
|
||||||
|
|||||||
@ -3,67 +3,75 @@ import { useRequest } from 'alova';
|
|||||||
import { getUserInfoApi } from '@/services/api/user';
|
import { getUserInfoApi } from '@/services/api/user';
|
||||||
import type { UserInfoModel } from '@/services/model/userModel';
|
import type { UserInfoModel } from '@/services/model/userModel';
|
||||||
import { login as loginApi } from '@/services/api/auth';
|
import { login as loginApi } from '@/services/api/auth';
|
||||||
import { getToken, isLogin, setToken } from '@/utils/auth';
|
|
||||||
import { removeCache } from '@/utils/cache';
|
|
||||||
import { TOKEN_KEY } from '@/enums/cacheEnum';
|
|
||||||
|
|
||||||
export const useUserStore = defineStore('UserStore', () => {
|
interface UserStore {
|
||||||
const token = ref<string | null>(null);
|
token: string | null
|
||||||
const userInfo = ref<UserInfoModel | null>(null);
|
userInfo: UserInfoModel | null
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化
|
export const useUserStore = defineStore({
|
||||||
function initUserInfo() {
|
id: 'UserStore',
|
||||||
if (isLogin()) {
|
state: (): UserStore => ({
|
||||||
token.value = getToken();
|
token: null,
|
||||||
getUserInfo();
|
userInfo: null,
|
||||||
}
|
}),
|
||||||
}
|
getters: {
|
||||||
|
loginOrNot: state => !!state.token,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
|
||||||
// 是否登录
|
// setToken
|
||||||
const loggedIn = computed(() => !!token.value);
|
setToken(token: string) {
|
||||||
|
this.token = token;
|
||||||
|
},
|
||||||
|
|
||||||
// 登录
|
// 登录
|
||||||
const { send: sendLogin } = useRequest(loginApi, { immediate: false });
|
async login(params: LoginParams) {
|
||||||
async function login(params: LoginParams) {
|
const { send: sendLogin } = useRequest(loginApi, { immediate: false });
|
||||||
try {
|
try {
|
||||||
const res = await sendLogin(params);
|
const res = await sendLogin(params);
|
||||||
token.value = res.token;
|
this.token = res.token;
|
||||||
setToken(res.token);
|
this.setToken(res.token);
|
||||||
await getUserInfo();
|
await this.getUserInfo();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
const { send: _getUserInfo } = useRequest(getUserInfoApi, { initialData: null, immediate: false });
|
async getUserInfo() {
|
||||||
async function getUserInfo() {
|
const { send: _getUserInfo } = useRequest(getUserInfoApi, { initialData: null, immediate: false });
|
||||||
try {
|
try {
|
||||||
userInfo.value = await _getUserInfo();
|
this.userInfo = await _getUserInfo();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
// 登出
|
// 初始化
|
||||||
// const { send: sendLogout } = useRequest(logoutApi, { immediate: false });
|
async initUserInfo() {
|
||||||
async function logout() {
|
//
|
||||||
try {
|
},
|
||||||
|
|
||||||
|
// 登出
|
||||||
|
async logout() {
|
||||||
|
// const { send: sendLogout } = useRequest(logoutApi, { immediate: false });
|
||||||
|
try {
|
||||||
// await sendLogout();
|
// await sendLogout();
|
||||||
removeCache(TOKEN_KEY);
|
this.userInfo = null;
|
||||||
userInfo.value = null;
|
this.token = null;
|
||||||
token.value = null;
|
} catch (err: any) {
|
||||||
} catch (err: any) {
|
throw err;
|
||||||
throw err;
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
storage: {
|
||||||
|
setItem: uni.setStorageSync,
|
||||||
|
getItem: uni.getStorageSync,
|
||||||
|
},
|
||||||
|
paths: ['token', 'userInfo'],
|
||||||
|
},
|
||||||
|
|
||||||
return {
|
|
||||||
userInfo,
|
|
||||||
loggedIn,
|
|
||||||
login,
|
|
||||||
logout,
|
|
||||||
getUserInfo,
|
|
||||||
initUserInfo,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,7 +6,10 @@ import { getBaseUrl, isUseMock } from '@/utils/env';
|
|||||||
import { mockAdapter } from '@/mock';
|
import { mockAdapter } from '@/mock';
|
||||||
import { ContentTypeEnum, ResultEnum } from '@/enums/httpEnum';
|
import { ContentTypeEnum, ResultEnum } from '@/enums/httpEnum';
|
||||||
import type { API } from '@/services/model/baseModel';
|
import type { API } from '@/services/model/baseModel';
|
||||||
import { getAuthorization } from '@/utils/auth';
|
|
||||||
|
function getAuthorization() {
|
||||||
|
return '1';
|
||||||
|
}
|
||||||
|
|
||||||
const BASE_URL = getBaseUrl();
|
const BASE_URL = getBaseUrl();
|
||||||
|
|
||||||
|
|||||||
@ -1,59 +1,67 @@
|
|||||||
{ // 指定要从编译中排除的文件列表
|
{ // 指定要从编译中排除的文件列表
|
||||||
"compilerOptions": { // 为所有发出的文件指定一个输出文件夹
|
"compilerOptions": {
|
||||||
"target": "ESNext", // 允许export=导出,由import from 导入
|
"target": "ESNext", // 编译出目标语言版本
|
||||||
"lib": ["ESNext", "DOM", "ScriptHost"], // 是否启用对装饰器的实验性支持,装饰器是一种语言特性,还没有完全被 JavaScript 规范批准
|
"jsx": "preserve",
|
||||||
"emitDecoratorMetadata": true, // 是否通过" . “(obj.key) 语法访问字段和"索引”( obj[“key”]), 以及在类型中声明属性的方式之间的一致性
|
"jsxImportSource": "vue",
|
||||||
|
"lib": ["ESNext", "DOM", "ScriptHost"], // TS需要引用的库
|
||||||
|
"emitDecoratorMetadata": true, // 为装饰器启用对发出类型元数据的实验性支持
|
||||||
/* 实验选项 */
|
/* 实验选项 */
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true, // 是否启用对装饰器的实验性支持,装饰器是一种语言特性,还没有完全被 JavaScript 规范批准
|
||||||
"baseUrl": "./", // 指定基目录以解析非相对模块名
|
"baseUrl": ".", // 指定基目录以解析非相对模块名
|
||||||
"rootDir": "./src", // 编译出目标语言版本
|
|
||||||
"module": "ESNext", // 生成代码的模板标准
|
"module": "ESNext", // 生成代码的模板标准
|
||||||
"moduleResolution": "node", // 删除注释
|
"moduleResolution": "node", // 指定TypeScript如何从给定的模块说明符查找文件
|
||||||
"paths": { "@/*": ["./src/*"] }, // 有错误时不进行编译
|
// 指定一组条目,它们将导入重新映射到其他查找位置
|
||||||
"resolveJsonModule": true, // TS需要引用的库
|
"paths": {
|
||||||
"types": ["@types/node"], // 在源文件中指定根文件夹
|
"~/*": ["./*"],
|
||||||
/* 严格检查选项 */
|
"@/*": ["./src/*"]
|
||||||
"strict": true, // 设置发出文件的换行符
|
},
|
||||||
|
"resolveJsonModule": true, // 是否解析 JSON 模块
|
||||||
|
"types": ["vite/client", "node"], // 指定要包含的类型包名,而不需要在源文件中引用
|
||||||
// "sourceMap": true, //为发出的JavaScript文件创建源映射文件。
|
// "sourceMap": true, //为发出的JavaScript文件创建源映射文件。
|
||||||
// "declaration": true, // 从项目中的TypeScript和JavaScript文件生成.d.ts文件
|
// "declaration": true, // 从项目中的TypeScript和JavaScript文件生成.d.ts文件
|
||||||
// "declarationMap": true, // 为d.ts文件创建源地图
|
// "declarationMap": true, // 为d.ts文件创建源地图
|
||||||
|
/* 严格检查选项 */
|
||||||
|
"strict": true, // 开启所有严格的类型检查
|
||||||
"strictBindCallApply": true, // 检查bind、call和apply方法的参数是否与原始函数匹配。
|
"strictBindCallApply": true, // 检查bind、call和apply方法的参数是否与原始函数匹配。
|
||||||
"strictFunctionTypes": true, // 不允许this有隐式的any类型
|
"strictFunctionTypes": true, // 在给函数赋值时,要确保参数和返回值是子类型兼容的。
|
||||||
"strictNullChecks": true, // 在给函数赋值时,要确保参数和返回值是子类型兼容的。
|
"strictNullChecks": true, // 在进行类型检查时,请考虑null和undefined。
|
||||||
"strictPropertyInitialization": true, // 开启所有严格的类型检查
|
"strictPropertyInitialization": true, // 类的实例属性必须初始化
|
||||||
"alwaysStrict": true, // 是否检查子类继承自基类时,其重载的函数命名与基类的函数不同步问题
|
"alwaysStrict": true, // 在代码中注入'use strict'
|
||||||
"noFallthroughCasesInSwitch": true, // 在代码中注入'use strict'
|
"noFallthroughCasesInSwitch": true, // 检查switch中是否含有case没有使用break跳出
|
||||||
"noImplicitAny": true, // 检查函数是否不含有隐式返回值
|
"noImplicitAny": false, // 不允许隐式的any类型
|
||||||
"noImplicitOverride": true, // 是否检查未使用的参数
|
"noImplicitOverride": true, // 是否检查子类继承自基类时,其重载的函数命名与基类的函数不同步问题
|
||||||
"noImplicitReturns": true, // 不允许隐式的any类型
|
"noImplicitReturns": true, // 检查函数是否不含有隐式返回值
|
||||||
"noImplicitThis": true, // 是否通过索引签名来描述对象上有未知键但已知值的对象
|
"noImplicitThis": true, // 不允许this有隐式的any类型
|
||||||
"noPropertyAccessFromIndexSignature": false, // 检查switch中是否含有case没有使用break跳出
|
"noPropertyAccessFromIndexSignature": false, // 是否通过" . “(obj.key) 语法访问字段和"索引”( obj[“key”]), 以及在类型中声明属性的方式之间的一致性
|
||||||
"noUncheckedIndexedAccess": true, // 类的实例属性必须初始化
|
"noUncheckedIndexedAccess": true, // 是否通过索引签名来描述对象上有未知键但已知值的对象
|
||||||
|
|
||||||
/* 额外检查 */
|
/* 额外检查 */
|
||||||
"noUnusedLocals": true, // 是否检查未使用的局部变量
|
"noUnusedLocals": true, // 是否检查未使用的局部变量
|
||||||
"noUnusedParameters": true, // 在输出中启用颜色和格式,使编译器错误更容易阅读
|
"noUnusedParameters": true, // 是否检查未使用的参数
|
||||||
"newLine": "crlf", // 是否查看 TS 在编译时花费的时间
|
"newLine": "crlf", // 设置发出文件的换行符
|
||||||
"noEmitOnError": true, // 在进行类型检查时,请考虑null和undefined。
|
"noEmitOnError": true, // 有错误时不进行编译
|
||||||
"outDir": "./dist", // 指定要包含的类型包名,而不需要在源文件中引用
|
"removeComments": true, // 删除注释
|
||||||
"removeComments": true, // 指定TypeScript如何从给定的模块说明符查找文件
|
// "incremental": true // 增量编译
|
||||||
"esModuleInterop": true, // 指定一组条目,它们将导入重新映射到其他查找位置
|
"allowSyntheticDefaultImports": true,
|
||||||
"pretty": true, // 为装饰器启用对发出类型元数据的实验性支持
|
"esModuleInterop": true, // 允许export=导出,由import from 导入
|
||||||
|
|
||||||
/* 高级选项 */
|
/* 高级选项 */
|
||||||
"forceConsistentCasingInFileNames": true, // 是否区分文件系统大小写规则
|
"forceConsistentCasingInFileNames": true, // 是否区分文件系统大小写规则
|
||||||
"extendedDiagnostics": false // 是否解析 JSON 模块
|
"isolatedModules": true,
|
||||||
// "incremental": true // 增量编译
|
// "rootDir": "./src", // 在源文件中指定根文件夹
|
||||||
|
// "outDir": "./dist", // 为所有发出的文件指定一个输出文件夹
|
||||||
|
// "extendedDiagnostics": true, //是否查看 TS 在编译时花费的时间
|
||||||
|
"pretty": true // 在输出中启用颜色和格式,使编译器错误更容易阅读
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts",
|
|
||||||
"src/**/*.d.ts",
|
"src/**/*.d.ts",
|
||||||
"src/**/*.tsx",
|
"src/**/*.tsx",
|
||||||
"src/**/*.vue",
|
"src/**/*.vue",
|
||||||
"vite.config.*",
|
"vite.config.*",
|
||||||
"typings/*.d.ts"
|
"typings/*.ts",
|
||||||
|
"typings/*.d.ts",
|
||||||
|
"./**/*.ts",
|
||||||
|
"./**/**/*.ts",
|
||||||
|
"./**/*.tsx",
|
||||||
|
"./**/*.vue"
|
||||||
], // 指定要包含在编译中的文件匹配列表
|
], // 指定要包含在编译中的文件匹配列表
|
||||||
"exclude": []
|
"exclude": ["node_modules", "dist"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import transformClass from 'unplugin-transform-class/vite';
|
|||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import ViteRestart from 'vite-plugin-restart';
|
import ViteRestart from 'vite-plugin-restart';
|
||||||
import AutoImport from 'unplugin-auto-import/vite';
|
import AutoImport from 'unplugin-auto-import/vite';
|
||||||
|
import { appProvider, buildThemeConfig, createComponents } from './vite/plugins/index';
|
||||||
|
|
||||||
export default defineConfig(async ({ mode }) => {
|
export default defineConfig(async ({ mode }) => {
|
||||||
const root = process.cwd();
|
const root = process.cwd();
|
||||||
@ -47,6 +48,9 @@ export default defineConfig(async ({ mode }) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
appProvider(),
|
||||||
|
buildThemeConfig(),
|
||||||
|
createComponents(),
|
||||||
// @ts-expect-error TODO uni() 会报错:uni is not a function,暂时使用此方式解决
|
// @ts-expect-error TODO uni() 会报错:uni is not a function,暂时使用此方式解决
|
||||||
uni?.default(),
|
uni?.default(),
|
||||||
AutoImport({
|
AutoImport({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user