修改结构
This commit is contained in:
parent
8bf6270833
commit
9055685cea
@ -13,7 +13,6 @@
|
|||||||
"antfu.goto-alias",
|
"antfu.goto-alias",
|
||||||
"mikestead.dotenv",
|
"mikestead.dotenv",
|
||||||
"redhat.vscode-yaml",
|
"redhat.vscode-yaml",
|
||||||
"Lokalise.i18n-ally",
|
|
||||||
"Vue.volar",
|
"Vue.volar",
|
||||||
"steoates.autoimport",
|
"steoates.autoimport",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
|
4
.env
4
.env
@ -4,7 +4,7 @@
|
|||||||
VITE_API_BASE_URL = /api
|
VITE_API_BASE_URL = /api
|
||||||
|
|
||||||
# 标题
|
# 标题
|
||||||
VITE_APP_TITLE = tov
|
VITE_APP_TITLE = 后台
|
||||||
|
|
||||||
|
|
||||||
# markdown 渲染支持
|
# markdown 渲染支持
|
||||||
@ -12,7 +12,7 @@ VITE_APP_MARKDOWN = true
|
|||||||
|
|
||||||
|
|
||||||
# 开发时的开发面板
|
# 开发时的开发面板
|
||||||
VITE_APP_DEV_TOOLS = true
|
VITE_APP_DEV_TOOLS = false
|
||||||
|
|
||||||
|
|
||||||
# 生产时 mock 支持
|
# 生产时 mock 支持
|
||||||
|
1373
README_EN.md
1373
README_EN.md
File diff suppressed because it is too large
Load Diff
42
mock/test.ts
42
mock/test.ts
@ -1,42 +0,0 @@
|
|||||||
import { MockMethod } from 'vite-plugin-mock'
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
url: '/api/mock/get',
|
|
||||||
method: 'get',
|
|
||||||
response: () => {
|
|
||||||
return {
|
|
||||||
code: 0,
|
|
||||||
data: {
|
|
||||||
name: 'mock',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: '/api/mock/post',
|
|
||||||
method: 'post',
|
|
||||||
timeout: 2000,
|
|
||||||
response: {
|
|
||||||
code: 0,
|
|
||||||
data: {
|
|
||||||
name: 'mock',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: '/api/mock/text',
|
|
||||||
method: 'post',
|
|
||||||
rawResponse: async (req, res) => {
|
|
||||||
let reqbody = ''
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
req.on('data', (chunk) => {
|
|
||||||
reqbody += chunk
|
|
||||||
})
|
|
||||||
req.on('end', () => resolve(undefined))
|
|
||||||
})
|
|
||||||
res.setHeader('Content-Type', 'text/plain')
|
|
||||||
res.statusCode = 200
|
|
||||||
res.end(`hello, ${reqbody}`)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
] as MockMethod[]
|
|
30
package.json
30
package.json
@ -1,36 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "tov-template",
|
"name": "后台",
|
||||||
"version": "1.19.0",
|
"version": "1.19.0",
|
||||||
"description": "vite + vue3 + ts 开箱即用现代开发模板 | vite + vue3 + ts out-of-the-box modern development template",
|
"description": "后台",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"test": "vitest",
|
"build": "vite build"
|
||||||
"build": "vite build",
|
|
||||||
"prepare": "husky install",
|
|
||||||
"dev:host": "vite --host",
|
|
||||||
"dev:open": "vite --open",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"coverage": "vitest --coverage",
|
|
||||||
"preinstall": "npx only-allow pnpm",
|
|
||||||
"typecheck": "npx vue-tsc --noEmit",
|
|
||||||
"preview:host": "vite preview --host",
|
|
||||||
"preview:open": "vite preview --open",
|
|
||||||
"lint": "eslint --ext .ts,.js,.jsx,.vue .",
|
|
||||||
"release": "plop --plopfile scripts/release.cjs",
|
|
||||||
"auto:remove": "plop --plopfile scripts/remove.cjs",
|
|
||||||
"auto:create": "plop --plopfile scripts/create.cjs",
|
|
||||||
"build:debug": "cross-env NODE_ENV=debug vite build",
|
|
||||||
"safe:init": "plop --plopfile scripts/safe-init.cjs",
|
|
||||||
"deps:fresh": "plop --plopfile scripts/deps-fresh.cjs",
|
|
||||||
"lint:fix": "eslint --fix --ext .ts,.js,.jsx,.vue,.cjs ."
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.12.2"
|
"node": ">=20.12.2"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.15.8",
|
"packageManager": "pnpm@8.15.8",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^3.0.1",
|
|
||||||
"@types/ityped": "^1.0.3",
|
"@types/ityped": "^1.0.3",
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.12.7",
|
||||||
"@typescript-eslint/parser": "7.8.0",
|
"@typescript-eslint/parser": "7.8.0",
|
||||||
@ -60,7 +41,6 @@
|
|||||||
"lightningcss": "^1.24.1",
|
"lightningcss": "^1.24.1",
|
||||||
"lint-staged": "^15.2.2",
|
"lint-staged": "^15.2.2",
|
||||||
"local-pkg": "^0.5.0",
|
"local-pkg": "^0.5.0",
|
||||||
"markdown-it-prism": "^2.3.0",
|
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"perfect-debounce": "^1.0.0",
|
"perfect-debounce": "^1.0.0",
|
||||||
@ -84,16 +64,12 @@
|
|||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-env-types": "^0.1.4",
|
"vite-plugin-env-types": "^0.1.4",
|
||||||
"vite-plugin-legacy-swc": "^1.1.0",
|
"vite-plugin-legacy-swc": "^1.1.0",
|
||||||
"vite-plugin-mock": "2.9.8",
|
|
||||||
"vite-plugin-removelog": "^0.2.2",
|
|
||||||
"vite-plugin-use-modules": "^1.4.8",
|
"vite-plugin-use-modules": "^1.4.8",
|
||||||
"vite-plugin-vue-devtools": "^7.1.3",
|
"vite-plugin-vue-devtools": "^7.1.3",
|
||||||
"vite-plugin-vue-meta-layouts": "^0.4.3",
|
"vite-plugin-vue-meta-layouts": "^0.4.3",
|
||||||
"vitest": "^1.5.3",
|
"vitest": "^1.5.3",
|
||||||
"vue": "^3.4.26",
|
"vue": "^3.4.26",
|
||||||
"vue-dark-switch": "^1.0.6",
|
|
||||||
"vue-echarts": "^6.7.1",
|
"vue-echarts": "^6.7.1",
|
||||||
"vue-i18n": "^9.13.1",
|
|
||||||
"vue-request": "2.0.4",
|
"vue-request": "2.0.4",
|
||||||
"vue-router": "^4.3.2",
|
"vue-router": "^4.3.2",
|
||||||
"vue-toastification": "2.0.0-rc.5"
|
"vue-toastification": "2.0.0-rc.5"
|
||||||
|
860
pnpm-lock.yaml
generated
860
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
|||||||
import Prism from 'markdown-it-prism'
|
|
||||||
import UnoCss from 'unocss/vite'
|
import UnoCss from 'unocss/vite'
|
||||||
import AutoImport from 'unplugin-auto-import/vite'
|
import AutoImport from 'unplugin-auto-import/vite'
|
||||||
import {
|
import {
|
||||||
@ -28,13 +27,9 @@ import Router from 'unplugin-vue-router/vite'
|
|||||||
import { AutoGenerateImports, vue3Presets } from 'vite-auto-import-resolvers'
|
import { AutoGenerateImports, vue3Presets } from 'vite-auto-import-resolvers'
|
||||||
import Compression from 'vite-plugin-compression'
|
import Compression from 'vite-plugin-compression'
|
||||||
import EnvTypes from 'vite-plugin-env-types'
|
import EnvTypes from 'vite-plugin-env-types'
|
||||||
import { viteMockServe as Mock } from 'vite-plugin-mock'
|
|
||||||
import Removelog from 'vite-plugin-removelog'
|
|
||||||
import Modules from 'vite-plugin-use-modules'
|
import Modules from 'vite-plugin-use-modules'
|
||||||
import VueDevTools from 'vite-plugin-vue-devtools'
|
import VueDevTools from 'vite-plugin-vue-devtools'
|
||||||
import Layouts from 'vite-plugin-vue-meta-layouts'
|
import Layouts from 'vite-plugin-vue-meta-layouts'
|
||||||
|
|
||||||
import I18N from '@intlify/unplugin-vue-i18n/vite'
|
|
||||||
import Legacy from 'vite-plugin-legacy-swc'
|
import Legacy from 'vite-plugin-legacy-swc'
|
||||||
import Vue from '@vitejs/plugin-vue'
|
import Vue from '@vitejs/plugin-vue'
|
||||||
import Jsx from '@vitejs/plugin-vue-jsx'
|
import Jsx from '@vitejs/plugin-vue-jsx'
|
||||||
@ -121,13 +116,7 @@ export default function () {
|
|||||||
Layouts({
|
Layouts({
|
||||||
skipTopLevelRouteLayout: true,
|
skipTopLevelRouteLayout: true,
|
||||||
}),
|
}),
|
||||||
/**
|
|
||||||
* mock 服务
|
|
||||||
* https://github.com/vbenjs/vite-plugin-mock
|
|
||||||
*/
|
|
||||||
Mock({
|
|
||||||
prodEnabled: env.VITE_APP_MOCK_IN_PRODUCTION,
|
|
||||||
}),
|
|
||||||
/**
|
/**
|
||||||
* 组件自动按需引入
|
* 组件自动按需引入
|
||||||
* https://github.com/antfu/unplugin-vue-components
|
* https://github.com/antfu/unplugin-vue-components
|
||||||
@ -165,15 +154,7 @@ export default function () {
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
/**
|
|
||||||
* i18n 国际化支持
|
|
||||||
* https://www.npmjs.com/package/@intlify/unplugin-vue-i18n
|
|
||||||
*/
|
|
||||||
I18N({
|
|
||||||
runtimeOnly: false,
|
|
||||||
compositionOnly: true,
|
|
||||||
include: ['locales/**'],
|
|
||||||
}),
|
|
||||||
/**
|
/**
|
||||||
* jsx 和 tsx 支持
|
* jsx 和 tsx 支持
|
||||||
* https://www.npmjs.com/package/@vitejs/plugin-vue-jsx
|
* https://www.npmjs.com/package/@vitejs/plugin-vue-jsx
|
||||||
@ -213,28 +194,6 @@ export default function () {
|
|||||||
plugins.push(VueDevTools())
|
plugins.push(VueDevTools())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 生产环境下移除 console.log, console.warn, console.error
|
|
||||||
* https://github.com/dishait/vite-plugin-removelog
|
|
||||||
*/
|
|
||||||
if (process.env.NODE_ENV !== 'debug') {
|
|
||||||
plugins.push(Removelog())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* markdown 渲染插件
|
|
||||||
* https://github.com/mdit-vue/unplugin-vue-markdown
|
|
||||||
*/
|
|
||||||
if (env.VITE_APP_MARKDOWN) {
|
|
||||||
plugins.push(
|
|
||||||
Markdown({
|
|
||||||
wrapperClasses: safelist,
|
|
||||||
markdownItSetup(md) {
|
|
||||||
md.use(Prism)
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* api 自动按需引入
|
* api 自动按需引入
|
||||||
|
1
presets/types/vite.d.ts
vendored
1
presets/types/vite.d.ts
vendored
@ -3,7 +3,6 @@
|
|||||||
/// <reference types="unplugin-vue-router/client" />
|
/// <reference types="unplugin-vue-router/client" />
|
||||||
/// <reference types="vite-plugin-use-modules/client" />
|
/// <reference types="vite-plugin-use-modules/client" />
|
||||||
/// <reference types="vite-plugin-vue-meta-layouts/client" />
|
/// <reference types="vite-plugin-vue-meta-layouts/client" />
|
||||||
/// <reference types="@intlify/vite-plugin-vue-i18n/client" />
|
|
||||||
|
|
||||||
declare module "*.vue" {
|
declare module "*.vue" {
|
||||||
import type { DefineComponent } from "vue";
|
import type { DefineComponent } from "vue";
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import { useRequest } from 'vue-request'
|
|
||||||
|
|
||||||
export const testRequest = () => {
|
|
||||||
const { data, loading, error } = useRequest(() => http.post('/mock/post'))
|
|
||||||
return { data, loading, error }
|
|
||||||
}
|
|
@ -3,8 +3,7 @@
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export function login(data: any) {
|
export function login(data: any) {
|
||||||
|
return http.post("/api/login", data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,5 +11,15 @@ export function login(data: any) {
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
export function register(data: any) {
|
export function register(data: any) {
|
||||||
|
return http.post("/api/register", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
export function userInfo(userId: any) {
|
||||||
|
return http.get("/api/userInfo", {
|
||||||
|
params: { userId: userId }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { vOnClickOutside } from '@vueuse/components'
|
|
||||||
|
|
||||||
const visiable = ref(false)
|
|
||||||
function dropdownHandler() {
|
|
||||||
visiable.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const { availableLocales, locale } = useI18n()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="relative">
|
|
||||||
<div class="inline-flex items-center overflow-hidden rounded-md">
|
|
||||||
<button
|
|
||||||
class="h-full cursor-pointer border-0 bg-white p-2 text-gray-600 hover:bg-gray-200 hover:text-gray-700"
|
|
||||||
dark="bg-transparent hover:bg-gray-500"
|
|
||||||
:class="visiable ? 'bg-gray-200 bg-gray-500 dark:bg-gray-500' : ''"
|
|
||||||
@click.stop="visiable = !visiable"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="h-4 w-4"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="currentColor"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Transition name="fade" mode="out-in">
|
|
||||||
<div
|
|
||||||
v-if="visiable"
|
|
||||||
v-on-click-outside.bubble="dropdownHandler"
|
|
||||||
dark="bg-gray-500"
|
|
||||||
class="absolute end-0 z-10 mt-2 w-56 rounded-md bg-white shadow-lg divide-y divide-gray-100"
|
|
||||||
>
|
|
||||||
<div class="p-2">
|
|
||||||
<span
|
|
||||||
v-for="availableLocale of availableLocales"
|
|
||||||
:key="availableLocale"
|
|
||||||
:class="
|
|
||||||
locale === availableLocale
|
|
||||||
? 'bg-gray-100 text-gray-800 dark:bg-gray-400'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
class="block cursor-pointer rounded-lg px-4 py-2 text-sm text-gray-500 hover:text-gray-900"
|
|
||||||
dark="text-light-500 hover:text-light-900"
|
|
||||||
@click="locale = availableLocale"
|
|
||||||
>
|
|
||||||
{{ availableLocale }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,59 +1,8 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { getRoutes } from '@/plugins/router'
|
|
||||||
import { SwitchIcon } from 'vue-dark-switch'
|
|
||||||
|
|
||||||
const { te, t } = useI18n()
|
|
||||||
|
|
||||||
const routes = getRoutes()
|
|
||||||
.filter((r) => !r.path.includes('notFound'))
|
|
||||||
.map((r) => {
|
|
||||||
let { path, name } = r
|
|
||||||
if (path === safeResolve('/')) {
|
|
||||||
return { path, name: 'home' }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
name = path
|
|
||||||
}
|
|
||||||
|
|
||||||
return { path, name: name.toString().slice(1).replaceAll('/', ' · ') }
|
|
||||||
})
|
|
||||||
|
|
||||||
const $route = useRoute()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<nav
|
<nav
|
||||||
aria-label="Site Nav"
|
|
||||||
class="mx-auto h-80px max-w-3xl flex items-center justify-between p-4"
|
class="mx-auto h-80px max-w-3xl flex items-center justify-between p-4"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-center space-x-5">
|
|
||||||
<SwitchIcon unmount-persets />
|
|
||||||
<a href="https://pc.dishait.cn/" target="_blank">
|
|
||||||
<span
|
|
||||||
style="
|
|
||||||
color: white;
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 3px 0 0 3px;
|
|
||||||
padding: 4px 4px 4px 4px;
|
|
||||||
background: #00b894;
|
|
||||||
"
|
|
||||||
>帝莎编程</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style="
|
|
||||||
border-radius: 0 3px 3px 0;
|
|
||||||
padding: 5px 10px 5px 2px;
|
|
||||||
background: #00dc8220;
|
|
||||||
font-size: 13px;
|
|
||||||
color: rgba(37, 99, 235);
|
|
||||||
"
|
|
||||||
>
|
|
||||||
https://pc.dishait.cn/
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="flex items-center gap-2 text-sm font-medium">
|
<ul class="flex items-center gap-2 text-sm font-medium">
|
||||||
<li v-for="r of routes" :key="r.path" class="hidden !block">
|
<li v-for="r of routes" :key="r.path" class="hidden !block">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
@ -61,86 +10,23 @@ const $route = useRoute()
|
|||||||
:class="$route.path === r.path ? 'text-blue-700' : ''"
|
:class="$route.path === r.path ? 'text-blue-700' : ''"
|
||||||
:to="r.path"
|
:to="r.path"
|
||||||
>
|
>
|
||||||
{{ te(r.name) ? t(r.name) : r.name }}
|
{{ r.name }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
class="inline-flex items-center gap-2 rounded-lg px-3 py-2"
|
|
||||||
href="https://github.com/dishait/tov-template"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<mask id="lineMdGithubLoop0" width="24" height="24" x="0" y="0">
|
|
||||||
<g fill="#fff">
|
|
||||||
<ellipse cx="9.5" cy="9" rx="1.5" ry="1" />
|
|
||||||
<ellipse cx="14.5" cy="9" rx="1.5" ry="1" />
|
|
||||||
</g>
|
|
||||||
</mask>
|
|
||||||
<g
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-dasharray="30"
|
|
||||||
stroke-dashoffset="30"
|
|
||||||
d="M12 4C13.6683 4 14.6122 4.39991 15 4.5C15.5255 4.07463 16.9375 3 18.5 3C18.8438 4 18.7863 5.21921 18.5 6C19.25 7 19.5 8 19.5 9.5C19.5 11.6875 19.017 13.0822 18 14C16.983 14.9178 15.8887 15.3749 14.5 15.5C15.1506 16.038 15 17.3743 15 18C15 18.7256 15 21 15 21M12 4C10.3317 4 9.38784 4.39991 9 4.5C8.47455 4.07463 7.0625 3 5.5 3C5.15625 4 5.21371 5.21921 5.5 6C4.75 7 4.5 8 4.5 9.5C4.5 11.6875 4.98301 13.0822 6 14C7.01699 14.9178 8.1113 15.3749 9.5 15.5C8.84944 16.038 9 17.3743 9 18C9 18.7256 9 21 9 21"
|
|
||||||
>
|
|
||||||
<animate
|
|
||||||
fill="freeze"
|
|
||||||
attributeName="stroke-dashoffset"
|
|
||||||
dur="0.6s"
|
|
||||||
values="30;0"
|
|
||||||
/>
|
|
||||||
</path>
|
|
||||||
<path stroke-dasharray="10" stroke-dashoffset="10" d="M9 19">
|
|
||||||
<animate
|
|
||||||
fill="freeze"
|
|
||||||
attributeName="stroke-dashoffset"
|
|
||||||
begin="0.7s"
|
|
||||||
dur="0.2s"
|
|
||||||
values="10;0"
|
|
||||||
/>
|
|
||||||
<animate
|
|
||||||
attributeName="d"
|
|
||||||
dur="3s"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
values="M9 19c-1.406 0-2.844-.563-3.688-1.188C4.47 17.188 4.22 16.157 3 15.5;M9 19c-1.406 0-3-.5-4-.5-.532 0-1 0-2-.5;M9 19c-1.406 0-2.844-.563-3.688-1.188C4.47 17.188 4.22 16.157 3 15.5"
|
|
||||||
/>
|
|
||||||
</path>
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
width="8"
|
|
||||||
height="4"
|
|
||||||
x="8"
|
|
||||||
y="11"
|
|
||||||
fill="currentColor"
|
|
||||||
mask="url(#lineMdGithubLoop0)"
|
|
||||||
>
|
|
||||||
<animate
|
|
||||||
attributeName="y"
|
|
||||||
dur="10s"
|
|
||||||
keyTimes="0;0.45;0.46;0.54;0.55;1"
|
|
||||||
repeatCount="indefinite"
|
|
||||||
values="11;11;7;7;11;11"
|
|
||||||
/>
|
|
||||||
</rect>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="hidden !block">
|
|
||||||
<Dropdown />
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
"path": "/",
|
||||||
|
"name": "首页"
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
console.log(routes)
|
||||||
|
const $route = useRoute()
|
||||||
|
</script>
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
|
<!--基础折线图样式-->
|
||||||
|
<!--https://v-charts.js.org/#/line-->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-chart class="chart" :option="option" autoresize />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { use } from 'echarts/core'
|
import { use } from 'echarts/core'
|
||||||
import { isDark } from 'vue-dark-switch'
|
|
||||||
import { PieChart } from 'echarts/charts'
|
import { PieChart } from 'echarts/charts'
|
||||||
import { CanvasRenderer } from 'echarts/renderers'
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
import {
|
import {
|
||||||
@ -8,8 +14,7 @@ import {
|
|||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
LegendComponent,
|
LegendComponent,
|
||||||
} from 'echarts/components'
|
} from 'echarts/components'
|
||||||
import VChart, { THEME_KEY } from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
import type { EChartsOption } from 'echarts'
|
|
||||||
|
|
||||||
use([
|
use([
|
||||||
CanvasRenderer,
|
CanvasRenderer,
|
||||||
@ -18,15 +23,9 @@ use([
|
|||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
LegendComponent,
|
LegendComponent,
|
||||||
])
|
])
|
||||||
|
const option = ref<any>({
|
||||||
provide(
|
|
||||||
THEME_KEY,
|
|
||||||
computed(() => (isDark.value ? 'dark' : '')),
|
|
||||||
)
|
|
||||||
|
|
||||||
const option = ref<EChartsOption>({
|
|
||||||
title: {
|
title: {
|
||||||
text: 'Traffic Sources',
|
text: 'Traffic Sources111',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -62,14 +61,6 @@ const option = ref<EChartsOption>({
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<!-- @vue-ignore -->
|
|
||||||
<v-chart class="chart" :option="option" autoresize />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.chart {
|
.chart {
|
||||||
width: 100vw;
|
width: 100vw;
|
@ -1,12 +0,0 @@
|
|||||||
# About
|
|
||||||
|
|
||||||
> The page is markdown file
|
|
||||||
|
|
||||||
```js
|
|
||||||
console.log("hello");
|
|
||||||
```
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<!-- 支持嵌入组件 -->
|
|
||||||
<Counter />
|
|
@ -1,32 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<foundation-line></foundation-line>
|
||||||
<div class="grid grid-cols-3">
|
|
||||||
<a href="https://github.com/dishait/tov-template" target="_blank">
|
|
||||||
<img :src="safeResolve('/logo.png')" class="logo" alt="Vite logo" />
|
|
||||||
</a>
|
|
||||||
<a href="https://vitejs.dev" target="_blank">
|
|
||||||
<img :src="safeResolve('/vite.svg')" class="logo" alt="Vite logo" />
|
|
||||||
</a>
|
|
||||||
<a href="https://vuejs.org/" target="_blank">
|
|
||||||
<img :src="safeResolve('/vue.svg')" class="logo vue" alt="Vue logo" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<HelloWorld msg="Tov + Vite + Vue" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.logo {
|
|
||||||
width: 10em;
|
|
||||||
height: 10em;
|
|
||||||
padding: 1.5rem;
|
|
||||||
will-change: filter;
|
|
||||||
transition: filter 300ms;
|
|
||||||
}
|
|
||||||
.logo:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
|
||||||
}
|
|
||||||
.logo.vue:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #42b883aa);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import FoundationLine from '~/components/view/foundation-line.vue'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
import { defu } from 'defu'
|
|
||||||
import { createI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
const yamls = import.meta.glob('../../locales/*/**.y(a)?ml', {
|
|
||||||
eager: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const languages = Object.entries(yamls).map(([key, value]) => {
|
|
||||||
const yaml = key.endsWith('.yaml')
|
|
||||||
key = key.slice(14, yaml ? -5 : -4)
|
|
||||||
// 如果有子模块,则分割
|
|
||||||
if (key.includes('/')) {
|
|
||||||
key = key.split('/')[0]
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
return { [key]: value.default }
|
|
||||||
})
|
|
||||||
|
|
||||||
const messages = defu({}, ...languages)
|
|
||||||
|
|
||||||
// localStorage 中的 locale,第二个参数为默认值
|
|
||||||
// https://vueuse.org/core/useStorage/#usestorage
|
|
||||||
const storageLocale = useStorage('locale', '简体中文')
|
|
||||||
|
|
||||||
export const i18n = createI18n({
|
|
||||||
messages,
|
|
||||||
legacy: false,
|
|
||||||
globalInjection: true,
|
|
||||||
allowComposition: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 同步本地 localStorage 和 i18n
|
|
||||||
// https://vueuse.org/shared/syncRef/#syncref
|
|
||||||
syncRef(storageLocale, i18n.global.locale)
|
|
||||||
|
|
||||||
export default i18n
|
|
@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* 该模块主要给生产时的 mock 用,一般情况下你并不需要关注
|
* 该模块主要给生产时的 mock 用,一般情况下你并不需要关注
|
||||||
*/
|
*/
|
||||||
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
|
|
||||||
import { createFetchSever } from '../../presets/shared/mock'
|
import { createFetchSever } from '../../presets/shared/mock'
|
||||||
|
|
||||||
const shouldCreateServer =
|
const shouldCreateServer =
|
||||||
@ -18,6 +17,5 @@ if (shouldCreateServer) {
|
|||||||
mockModules.push(...v.default)
|
mockModules.push(...v.default)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
createProdMockServer(mockModules)
|
|
||||||
createFetchSever(mockModules)
|
createFetchSever(mockModules)
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
import { createGetRoutes, setupLayouts } from 'virtual:meta-layouts'
|
import { setupLayouts } from 'virtual:meta-layouts'
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { routes as fileRoutes } from 'vue-router/auto-routes'
|
import { routes as fileRoutes } from 'vue-router/auto-routes'
|
||||||
|
|
||||||
declare module 'vue-router' {
|
declare module 'vue-router' {}
|
||||||
// 在这里定义你的 meta 类型
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
interface RouteMeta {
|
|
||||||
title?: string
|
|
||||||
layout?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重定向 BASE_URL
|
// 重定向 BASE_URL
|
||||||
fileRoutes.flat(Infinity).forEach((route) => {
|
fileRoutes.flat(Infinity).forEach((route) => {
|
||||||
@ -21,6 +14,20 @@ export const router = createRouter({
|
|||||||
routes: setupLayouts(fileRoutes),
|
routes: setupLayouts(fileRoutes),
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getRoutes = createGetRoutes(router)
|
// 路由拦截
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 在这里编写拦截逻辑
|
||||||
|
// 例如,检查用户是否认证
|
||||||
|
const isLogin = userStore().isLogin
|
||||||
|
const authList=["/"]
|
||||||
|
if (authList.includes(to.fullPath) && !isLogin) {
|
||||||
|
toast.warning("未登录或者登录过期~")
|
||||||
|
// 如果用户未认证,则跳转到登录页面
|
||||||
|
next('/login');
|
||||||
|
} else {
|
||||||
|
// 如果用户已认证,或者不需要认证,则继续
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export default defineStore('counter', {
|
export default defineStore('userStore', {
|
||||||
state() {
|
state() {
|
||||||
return {
|
return {
|
||||||
count: 0,
|
isLogin: false,
|
||||||
|
token: "",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
inc() {
|
inc() {
|
||||||
this.count++
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
persist: true,
|
persist: true,
|
@ -1,4 +1,3 @@
|
|||||||
@import './md.css';
|
|
||||||
|
|
||||||
|
|
||||||
html.dark {
|
html.dark {
|
||||||
@ -52,4 +51,4 @@ html.dark ::-webkit-scrollbar-track {
|
|||||||
|
|
||||||
html.dark ::-webkit-scrollbar-thumb {
|
html.dark ::-webkit-scrollbar-thumb {
|
||||||
background-color: #343a40;
|
background-color: #343a40;
|
||||||
}
|
}
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
@import 'prism-theme-vars/base.css';
|
|
||||||
|
|
||||||
.prose {
|
|
||||||
--prism-font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica,
|
|
||||||
Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prose pre {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
html:not(.dark) {
|
|
||||||
--prism-foreground: #393a34;
|
|
||||||
--prism-background: #f8f8f8;
|
|
||||||
|
|
||||||
--prism-comment: #868e96;
|
|
||||||
--prism-namespace: #444444;
|
|
||||||
--prism-string: #bc8671;
|
|
||||||
--prism-punctuation: #80817d;
|
|
||||||
--prism-literal: #36acaa;
|
|
||||||
--prism-keyword: #d73a49;
|
|
||||||
--prism-function: #0c4c7d;
|
|
||||||
--prism-deleted: #9a050f;
|
|
||||||
--prism-class: #2b91af;
|
|
||||||
--prism-builtin: #800000;
|
|
||||||
--prism-property: #ce9178;
|
|
||||||
--prism-regex: #ad502b;
|
|
||||||
}
|
|
||||||
|
|
||||||
html.dark {
|
|
||||||
--prism-foreground: #d4d4d4;
|
|
||||||
--prism-background: #1e1e1e;
|
|
||||||
|
|
||||||
--prism-namespace: #aaaaaa;
|
|
||||||
--prism-comment: #868e96;
|
|
||||||
--prism-namespace: #444444;
|
|
||||||
--prism-string: #ce9178;
|
|
||||||
--prism-punctuation: #d4d4d4;
|
|
||||||
--prism-literal: #36acaa;
|
|
||||||
--prism-keyword: #0ca678;
|
|
||||||
--prism-function: #dcdcaa;
|
|
||||||
--prism-deleted: #9a050f;
|
|
||||||
--prism-class: #4ec9b0;
|
|
||||||
--prism-builtin: #d16969;
|
|
||||||
--prism-property: #ce9178;
|
|
||||||
--prism-regex: #ad502b;
|
|
||||||
}
|
|
||||||
ol {
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prose blockquote p:first-of-type::before {
|
|
||||||
content: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prose pre {
|
|
||||||
color: #495057;
|
|
||||||
background: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prose-sm p {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prose blockquote {
|
|
||||||
margin: 0;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
html.dark .prose blockquote {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
html.dark .prose pre {
|
|
||||||
color: #f8f9fa;
|
|
||||||
background: #2a2f33;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.comment {
|
|
||||||
font-style: normal;
|
|
||||||
font-size: 0.5rem;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
// Vitest Snapshot v1
|
|
||||||
|
|
||||||
exports[`suite name > snapshot 1`] = `
|
|
||||||
{
|
|
||||||
"foo": "bar",
|
|
||||||
}
|
|
||||||
`;
|
|
@ -1,16 +0,0 @@
|
|||||||
import { assert, describe, expect, it } from 'vitest'
|
|
||||||
|
|
||||||
describe('suite name', () => {
|
|
||||||
it('foo', () => {
|
|
||||||
expect(1 + 1).toEqual(2)
|
|
||||||
expect(true).to.be.true
|
|
||||||
})
|
|
||||||
|
|
||||||
it('bar', () => {
|
|
||||||
assert.equal(Math.sqrt(4), 2)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('snapshot', () => {
|
|
||||||
expect({ foo: 'bar' }).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
Loading…
Reference in New Issue
Block a user