refactor: refactor

This commit is contained in:
张传龙 2022-08-27 14:09:32 +08:00
parent 230e3a72d9
commit 220a7800f7
36 changed files with 201 additions and 192 deletions

2
.env
View File

@ -1,3 +1,3 @@
VITE_APP_TITLE = 'Vue Naive Admin' VITE_TITLE = 'Vue Naive Admin'
VITE_PORT = 3100 VITE_PORT = 3100

View File

@ -2,13 +2,13 @@
VITE_PUBLIC_PATH = '/' VITE_PUBLIC_PATH = '/'
# 是否启用MOCK # 是否启用MOCK
VITE_APP_USE_MOCK = true VITE_USE_MOCK = true
# proxy # 是否启用MOCK
VITE_PROXY = [["/api","http://localhost:8080"],["/api-test","localhost:8080"]] VITE_USE_PROXY = false
# 代理类型(跟启动和构建环境无关) 'dev' | 'test' | 'prod'
VITE_PROXY_TYPE = 'dev'
# base api # base api
VITE_APP_BASE_API = '/api' VITE_BASE_API = '/api'
# test base api
VITE_APP_BASE_API_TEST = '/api-test'

View File

@ -1,16 +1,13 @@
# 自定义域名CNAME # 自定义域名CNAME
# VITE_APP_GLOB_CNAME = 'template.qszone.com' # VITE_CNAME = 'template.qszone.com'
# 资源公共路径,需要以 /开头和结尾 # 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH = '/vue-naive-admin/' VITE_PUBLIC_PATH = '/vue-naive-admin/'
VITE_APP_USE_HASH = true VITE_USE_HASH = true
# 是否启用MOCK # 是否启用MOCK
VITE_APP_USE_MOCK = true VITE_USE_MOCK = true
# base api # base api
VITE_APP_BASE_API = '/api' VITE_BASE_API = '/api'
# test base api
VITE_APP_BASE_API_TEST = '/api-test'

View File

@ -2,13 +2,10 @@
VITE_PUBLIC_PATH = '/' VITE_PUBLIC_PATH = '/'
# 是否启用MOCK # 是否启用MOCK
VITE_APP_USE_MOCK = true VITE_USE_MOCK = true
# base api # base api
VITE_APP_BASE_API = '/api' VITE_BASE_API = '/api'
# test base api
VITE_APP_BASE_API_TEST = '/api-test'
# 是否启用压缩 # 是否启用压缩
VITE_USE_COMPRESS = true VITE_USE_COMPRESS = true

View File

@ -1,10 +1,7 @@
VITE_PUBLIC_PATH = '/' VITE_PUBLIC_PATH = '/'
# 是否启用MOCK # 是否启用MOCK
VITE_APP_USE_MOCK = true VITE_USE_MOCK = true
# base api # base api
VITE_APP_BASE_API = '/api' VITE_BASE_API = '/api'
# test base api
VITE_APP_BASE_API_TEST = '/api-test'

View File

@ -1,12 +1,15 @@
{ {
"files.eol": "\n", "path-intellisense.mappings": {
"@/": "${workspaceRoot}/src",
"~/": "${workspaceRoot}"
},
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.printWidth": 120, "prettier.printWidth": 120,
"prettier.singleQuote": true, "prettier.singleQuote": true,
"prettier.semi": false, "prettier.semi": false,
"prettier.endOfLine": "lf", "prettier.endOfLine": "lf",
"files.eol": "\n",
"[javascript]": { "[javascript]": {
"editor.formatOnSave": false "editor.formatOnSave": false

13
build/config/define.js Normal file
View File

@ -0,0 +1,13 @@
import dayjs from 'dayjs'
/**
* * 此处定义的是全局常量启动或打包后将添加到window中
* https://vitejs.cn/config/#define
*/
// 项目构建时间
const _BUILD_TIME_ = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss'))
export const viteDefine = {
_BUILD_TIME_,
}

2
build/config/index.js Normal file
View File

@ -0,0 +1,2 @@
export * from './define'
export * from './proxy'

16
build/config/proxy.js Normal file
View File

@ -0,0 +1,16 @@
import { getProxyConfig } from '../../settings'
export function createViteProxy(isUseProxy = true, proxyType) {
if (!isUseProxy) return undefined
const proxyConfig = getProxyConfig(proxyType)
console.log(proxyConfig)
const proxy = {
[proxyConfig.prefix]: {
target: proxyConfig.target,
changeOrigin: true,
rewrite: (path) => path.replace(new RegExp(`^${proxyConfig.prefix}`), ''),
},
}
return proxy
}

View File

@ -1,13 +1,13 @@
import { createHtmlPlugin } from 'vite-plugin-html' import { createHtmlPlugin } from 'vite-plugin-html'
export function configHtmlPlugin(viteEnv, isBuild) { export function configHtmlPlugin(viteEnv, isBuild) {
const { VITE_APP_TITLE } = viteEnv const { VITE_TITLE } = viteEnv
const htmlPlugin = createHtmlPlugin({ const htmlPlugin = createHtmlPlugin({
minify: isBuild, minify: isBuild,
inject: { inject: {
data: { data: {
title: VITE_APP_TITLE, title: VITE_TITLE,
}, },
}, },
}) })

View File

@ -24,7 +24,7 @@ import unplugin from './unplugin'
export function createVitePlugins(viteEnv, isBuild) { export function createVitePlugins(viteEnv, isBuild) {
const plugins = [vue(), vueSetupExtend(), ...unplugin, configHtmlPlugin(viteEnv, isBuild), Unocss()] const plugins = [vue(), vueSetupExtend(), ...unplugin, configHtmlPlugin(viteEnv, isBuild), Unocss()]
if (viteEnv?.VITE_APP_USE_MOCK) { if (viteEnv?.VITE_USE_MOCK) {
plugins.push(configMockPlugin(isBuild)) plugins.push(configMockPlugin(isBuild))
} }

View File

@ -1,3 +1,4 @@
import { resolve } from 'path'
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite' import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
@ -12,9 +13,10 @@ import IconsResolver from 'unplugin-icons/resolver'
import Icons from 'unplugin-icons/vite' import Icons from 'unplugin-icons/vite'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import { getRootPath } from '../utils' import { getSrcPath } from '../utils'
const customIconPath = resolve(getSrcPath(), 'assets/svg')
const customIconPath = getRootPath('src', 'assets/svg')
export default [ export default [
AutoImport({ AutoImport({
imports: ['vue', 'vue-router'], imports: ['vue', 'vue-router'],

View File

@ -1,13 +1,14 @@
import { resolve } from 'path'
import chalk from 'chalk' import chalk from 'chalk'
import { writeFileSync } from 'fs-extra' import { writeFileSync } from 'fs-extra'
import { OUTPUT_DIR } from '../constant' import { OUTPUT_DIR } from '../constant'
import { getEnvConfig, getRootPath } from '../utils' import { getEnvConfig, getRootPath } from '../utils'
export function runBuildCNAME() { export function runBuildCNAME() {
const { VITE_APP_CNAME } = getEnvConfig() const { VITE_CNAME } = getEnvConfig()
if (!VITE_APP_CNAME) return if (!VITE_CNAME) return
try { try {
writeFileSync(getRootPath(`${OUTPUT_DIR}/CNAME`), VITE_APP_CNAME) writeFileSync(resolve(getRootPath(), `${OUTPUT_DIR}/CNAME`), VITE_CNAME)
} catch (error) { } catch (error) {
console.log(chalk.red('CNAME file failed to package:\n' + error)) console.log(chalk.red('CNAME file failed to package:\n' + error))
} }

View File

@ -2,53 +2,38 @@ import fs from 'fs'
import path from 'path' import path from 'path'
import dotenv from 'dotenv' import dotenv from 'dotenv'
const httpsReg = /^https:\/\// /**
* * 项目根路径
export function wrapperEnv(envOptions) { * @descrition 结尾不带/
if (!envOptions) return {} */
const ret = {} export function getRootPath() {
return path.resolve(process.cwd())
for (const key in envOptions) {
let val = envOptions[key]
if (['true', 'false'].includes(val)) {
val = val === 'true'
}
if (['VITE_PORT'].includes(key)) {
val = +val
}
if (key === 'VITE_PROXY' && val && typeof val === 'string') {
try {
val = JSON.parse(val.replace(/'/g, '"'))
} catch (error) {
val = ''
}
}
ret[key] = val
if (typeof val === 'string') {
process.env[key] = val
} else if (typeof val === 'object') {
process.env[key] = JSON.stringify(val)
}
}
return ret
} }
export function createProxy(list = []) { /**
const ret = {} * * 项目src路径
for (const [prefix, target] of list) { * @param srcName src目录名称(默认: "src")
const isHttps = httpsReg.test(target) * @descrition 结尾不带斜杠
*/
export function getSrcPath(srcName = 'src') {
return path.resolve(getRootPath(), srcName)
}
// https://github.com/http-party/node-http-proxy#options const httpsReg = /^https:\/\//
ret[prefix] = {
target: target, export function convertEnv(envOptions) {
changeOrigin: true, const result = {}
ws: true, if (!envOptions) return result
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
// https is require secure=false for (const envKey in envOptions) {
...(isHttps ? { secure: false } : {}), let envVal = envOptions[envKey]
} if (['true', 'false'].includes(envVal)) envVal = envVal === 'true'
if (['VITE_PORT'].includes(envKey)) envVal = +envVal
result[envKey] = envVal
} }
return ret return result
} }
/** /**
@ -65,7 +50,7 @@ function getConfFiles() {
return ['.env', '.env.local', '.env.production'] return ['.env', '.env.local', '.env.production']
} }
export function getEnvConfig(match = 'VITE_APP_GLOB_', confFiles = getConfFiles()) { export function getEnvConfig(match = 'VITE_', confFiles = getConfFiles()) {
let envConfig = {} let envConfig = {}
confFiles.forEach((item) => { confFiles.forEach((item) => {
try { try {
@ -85,7 +70,3 @@ export function getEnvConfig(match = 'VITE_APP_GLOB_', confFiles = getConfFiles(
}) })
return envConfig return envConfig
} }
export function getRootPath(...dir) {
return path.resolve(process.cwd(), ...dir)
}

View File

@ -2,6 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {
"~/*": ["./*"],
"@/*": ["src/*"] "@/*": ["src/*"]
}, },
"jsx": "preserve" "jsx": "preserve"

View File

@ -17,6 +17,7 @@
"@vueuse/core": "^8.4.2", "@vueuse/core": "^8.4.2",
"axios": "^0.21.4", "axios": "^0.21.4",
"dayjs": "^1.11.0", "dayjs": "^1.11.0",
"lodash-es": "^4.17.21",
"md-editor-v3": "^1.11.4", "md-editor-v3": "^1.11.4",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"pinia": "^2.0.13", "pinia": "^2.0.13",

3
pnpm-lock.yaml generated
View File

@ -23,6 +23,7 @@ specifiers:
fs-extra: ^10.0.1 fs-extra: ^10.0.1
husky: ^8.0.1 husky: ^8.0.1
lint-staged: ^13.0.3 lint-staged: ^13.0.3
lodash-es: ^4.17.21
md-editor-v3: ^1.11.4 md-editor-v3: ^1.11.4
mockjs: ^1.1.0 mockjs: ^1.1.0
naive-ui: ^2.32.1 naive-ui: ^2.32.1
@ -47,6 +48,7 @@ dependencies:
'@vueuse/core': 8.4.2_vue@3.2.31 '@vueuse/core': 8.4.2_vue@3.2.31
axios: 0.21.4 axios: 0.21.4
dayjs: 1.11.0 dayjs: 1.11.0
lodash-es: 4.17.21
md-editor-v3: 1.11.4 md-editor-v3: 1.11.4
mockjs: 1.1.0 mockjs: 1.1.0
pinia: 2.0.13_vue@3.2.31 pinia: 2.0.13_vue@3.2.31
@ -3284,7 +3286,6 @@ packages:
/lodash-es/4.17.21: /lodash-es/4.17.21:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
dev: true
/lodash.map/4.6.0: /lodash.map/4.6.0:
resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==}

View File

@ -13,7 +13,7 @@
.loading-svg { .loading-svg {
width: 128px; width: 128px;
height: 128px; height: 128px;
color: var(--primaryColor); color: var(--primary-color);
} }
.loading-spin__container { .loading-spin__container {
@ -45,7 +45,7 @@
position: absolute; position: absolute;
height: 16px; height: 16px;
width: 16px; width: 16px;
background-color: var(--primaryColor); background-color: var(--primary-color);
border-radius: 8px; border-radius: 8px;
-webkit-animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; -webkit-animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;

View File

@ -2,24 +2,24 @@
* 初始化加载效果的svg格式logo * 初始化加载效果的svg格式logo
* @param {string} id - 元素id * @param {string} id - 元素id
*/ */
function initSvgLogo(id) { function initSvgLogo(id) {
const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512" data-v-fba6e5d0=""><path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1c-16.3-51-21.5-84.3-63-84.3c-22.4 0-45.1 16.1-45.1 61.2c0 35.2 18 57.2 43.3 57.2c28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8c0-57.9 28.6-92 82.5-92c73.5 0 80.8 41.4 100.8 101.9c8.8 26.8 24.2 46.2 61.2 46.2c24.9 0 38.1-5.5 38.1-19.1c0-19.9-21.8-22-49.9-28.6c-30.4-7.3-42.5-23.1-42.5-48c0-40 32.3-52.4 65.2-52.4c37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4c-16.1 0-26 7.3-26 19.8c0 11 4.8 17.6 20.9 21.3c32.7 7.1 71.8 12 71.8 57.5c.1 36.7-30.7 50.6-76.1 50.6z" style="fill:currentColor"></path></svg>`; const svgStr = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512" data-v-fba6e5d0=""><path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1c-16.3-51-21.5-84.3-63-84.3c-22.4 0-45.1 16.1-45.1 61.2c0 35.2 18 57.2 43.3 57.2c28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8c0-57.9 28.6-92 82.5-92c73.5 0 80.8 41.4 100.8 101.9c8.8 26.8 24.2 46.2 61.2 46.2c24.9 0 38.1-5.5 38.1-19.1c0-19.9-21.8-22-49.9-28.6c-30.4-7.3-42.5-23.1-42.5-48c0-40 32.3-52.4 65.2-52.4c37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4c-16.1 0-26 7.3-26 19.8c0 11 4.8 17.6 20.9 21.3c32.7 7.1 71.8 12 71.8 57.5c.1 36.7-30.7 50.6-76.1 50.6z" style="fill:currentColor"></path></svg>`
const appEl = document.querySelector(id); const appEl = document.querySelector(id)
const div = document.createElement('div'); const div = document.createElement('div')
div.innerHTML = svgStr; div.innerHTML = svgStr
if (appEl) { if (appEl) {
appEl.appendChild(div); appEl.appendChild(div)
} }
} }
function addThemeColorCssVars() { function addThemeColorCssVars() {
const key = '__THEME_COLOR__' const key = '__THEME_COLOR__'
const defaultColor = '#316c72'; const defaultColor = '#316c72'
const themeColor = window.localStorage.getItem(key) || defaultColor; const themeColor = window.localStorage.getItem(key) || defaultColor
const cssVars = `--primaryColor: ${themeColor}`; const cssVars = `--primary-color: ${themeColor}`
document.documentElement.style.cssText = cssVars; document.documentElement.style.cssText = cssVars
} }
addThemeColorCssVars(); addThemeColorCssVars()
initSvgLogo('#loadingLogo'); initSvgLogo('#loadingLogo')

2
settings/index.js Normal file
View File

@ -0,0 +1,2 @@
export * from './theme.json'
export * from './proxy-config'

18
settings/proxy-config.js Normal file
View File

@ -0,0 +1,18 @@
const proxyConfigMappings = {
dev: {
prefix: '/api',
target: 'http://localhost:8080',
},
test: {
prefix: '/api',
target: 'http://localhost:8080',
},
prod: {
prefix: '/api',
target: 'http://localhost:8080',
},
}
export function getProxyConfig(envType = 'dev') {
return proxyConfigMappings[envType]
}

View File

@ -1,11 +1,11 @@
{ {
"header": {
"height": 60
},
"tags": { "tags": {
"visible": true, "visible": true,
"height": 50 "height": 50
}, },
"header": {
"height": 60
},
"naiveThemeOverrides": { "naiveThemeOverrides": {
"common": { "common": {
"primaryColor": "#316C72FF", "primaryColor": "#316C72FF",

View File

@ -1,5 +1,5 @@
<template> <template>
<n-config-provider wh-full :theme-overrides="themStore.naiveThemeOverrides"> <n-config-provider wh-full :theme-overrides="naiveThemeOverrides">
<n-loading-bar-provider> <n-loading-bar-provider>
<n-dialog-provider> <n-dialog-provider>
<n-notification-provider> <n-notification-provider>
@ -16,24 +16,18 @@
<script setup> <script setup>
import { defineComponent, h } from 'vue' import { defineComponent, h } from 'vue'
import { useLoadingBar, useDialog, useMessage, useNotification } from 'naive-ui' import { useLoadingBar, useDialog, useMessage, useNotification } from 'naive-ui'
import { useCssVar } from '@vueuse/core' import { useCssVar } from '@vueuse/core'
import { useThemeStore } from '@/store/modules/theme' import { kebabCase } from 'lodash-es'
import { setupMessage, setupDialog } from '@/utils/common/naiveTools' import { setupMessage, setupDialog } from '@/utils/common/naiveTools'
import { naiveThemeOverrides } from '~/settings'
const themStore = useThemeStore() function setupCssVar() {
watch( const common = naiveThemeOverrides.common
() => themStore.naiveThemeOverrides.common, for (const key in common) {
(vars) => { useCssVar(`--${kebabCase(key)}`, document.documentElement).value = common[key] || ''
for (const key in vars) { if (key === 'primaryColor') window.localStorage.setItem('__THEME_COLOR__', common[key] || '')
useCssVar(`--${key}`, document.documentElement).value = vars[key] }
if (key === 'primaryColor') { }
window.localStorage.setItem('__THEME_COLOR__', vars[key])
}
}
},
{ immediate: true }
)
// naivewindow, 便使 // naivewindow, 便使
function setupNaiveTools() { function setupNaiveTools() {
@ -46,6 +40,7 @@ function setupNaiveTools() {
const NaiveProviderContent = defineComponent({ const NaiveProviderContent = defineComponent({
setup() { setup() {
setupCssVar()
setupNaiveTools() setupNaiveTools()
}, },
render() { render() {

View File

@ -9,7 +9,7 @@
<script setup> <script setup>
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
const title = import.meta.env.VITE_APP_TITLE const title = import.meta.env.VITE_TITLE
const appStore = useAppStore() const appStore = useAppStore()
</script> </script>

View File

@ -1,9 +1,9 @@
<template> <template>
<ScrollX :class="`h-${useTheme.tags.height}`"> <ScrollX>
<n-tag <n-tag
v-for="tag in tagsStore.tags" v-for="tag in tagsStore.tags"
:key="tag.path" :key="tag.path"
class="px-15 mx-5 cursor-pointer hover:color-primary" class="px-15 mx-5 rounded-4 cursor-pointer hover:color-primary"
:type="tagsStore.activeTag === tag.path ? 'primary' : 'default'" :type="tagsStore.activeTag === tag.path ? 'primary' : 'default'"
:closable="tagsStore.tags.length > 1" :closable="tagsStore.tags.length > 1"
@click="handleTagClick(tag.path)" @click="handleTagClick(tag.path)"
@ -12,27 +12,24 @@
> >
{{ tag.title }} {{ tag.title }}
</n-tag> </n-tag>
<ContextMenu
v-if="contextMenuOption.show"
v-model:show="contextMenuOption.show"
:current-path="contextMenuOption.currentPath"
:x="contextMenuOption.x"
:y="contextMenuOption.y"
/>
</ScrollX> </ScrollX>
<ContextMenu
v-if="contextMenuOption.show"
v-model:show="contextMenuOption.show"
:current-path="contextMenuOption.currentPath"
:x="contextMenuOption.x"
:y="contextMenuOption.y"
/>
</template> </template>
<script setup name="Tags"> <script setup name="Tags">
import ContextMenu from './ContextMenu.vue' import ContextMenu from './ContextMenu.vue'
import { useTagsStore } from '@/store/modules/tags' import { useTagsStore } from '@/store/modules/tags'
import { useThemeStore } from '@/store/modules/theme'
import ScrollX from '@/components/common/ScrollX.vue' import ScrollX from '@/components/common/ScrollX.vue'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const tagsStore = useTagsStore() const tagsStore = useTagsStore()
const useTheme = useThemeStore()
const contextMenuOption = reactive({ const contextMenuOption = reactive({
show: false, show: false,
@ -76,17 +73,14 @@ async function handleContextMenu(e, tagItem) {
} }
</script> </script>
<style lang="scss"> <style>
.n-tag__close { .n-tag__close {
margin-left: 5px;
box-sizing: content-box; box-sizing: content-box;
border-radius: 50%;
font-size: 12px; font-size: 12px;
padding: 2px; padding: 2px;
border-radius: 50%; transform: scale(0.9);
transition: all 0.7s; transform: translateX(5px);
&:hover { transition: all 0.3s;
color: #fff;
background-color: var(--primaryColor);
}
} }
</style> </style>

View File

@ -11,16 +11,16 @@
<SideBar /> <SideBar />
</n-layout-sider> </n-layout-sider>
<n-layout> <n-layout>
<n-layout-header bg-white border-b bc-eee :style="`height: ${useTheme.header.height ?? 60}px`"> <n-layout-header bg-white border-b bc-eee :style="`height: ${header.height ?? 60}px`">
<AppHeader /> <AppHeader />
</n-layout-header> </n-layout-header>
<n-layout bg="#f5f6fb" :style="`height: calc(100% - ${useTheme.header.height ?? 60}px)`"> <n-layout bg="#f5f6fb" :style="`height: calc(100% - ${header.height ?? 60}px)`">
<AppTags v-if="useTheme.tags.visible" /> <AppTags v-if="tags.visible" :style="`height: ${tags.height ?? 50}px`" />
<AppMain <AppMain
class="cus-scroll border-t bc-eee" class="cus-scroll border-t bc-eee"
:style="{ :style="{
height: `calc(100% - ${useTheme.tags.visible ? useTheme.tags.height ?? 50 : 0}px)`, height: `calc(100% - ${tags.visible ? tags.height ?? 50 : 0}px)`,
overflow: 'auto', overflow: 'auto',
}" }"
/> />
@ -34,9 +34,8 @@ import AppHeader from './components/header/index.vue'
import SideBar from './components/sidebar/index.vue' import SideBar from './components/sidebar/index.vue'
import AppMain from './components/AppMain.vue' import AppMain from './components/AppMain.vue'
import AppTags from './components/tags/index.vue' import AppTags from './components/tags/index.vue'
import { useThemeStore } from '@/store/modules/theme'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
import { header, tags } from '~/settings'
const useTheme = useThemeStore()
const appStore = useAppStore() const appStore = useAppStore()
</script> </script>

View File

@ -1,5 +1,4 @@
import '@/styles/reset.css' import '@/styles/reset.css'
import '@/styles/variables.css'
import '@/styles/index.scss' import '@/styles/index.scss'
import 'uno.css' import 'uno.css'
import 'virtual:svg-icons-register' import 'virtual:svg-icons-register'

View File

@ -1,4 +1,4 @@
const baseTitle = import.meta.env.VITE_APP_TITLE const baseTitle = import.meta.env.VITE_TITLE
export function createPageTitleGuard(router) { export function createPageTitleGuard(router) {
router.afterEach((to) => { router.afterEach((to) => {

View File

@ -2,7 +2,7 @@ import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router
import { setupRouterGuard } from './guard' import { setupRouterGuard } from './guard'
import { basicRoutes } from './routes' import { basicRoutes } from './routes'
const isHash = import.meta.env.VITE_APP_USE_HASH === 'true' const isHash = import.meta.env.VITE_USE_HASH === 'true'
export const router = createRouter({ export const router = createRouter({
history: isHash ? createWebHashHistory('/') : createWebHistory('/'), history: isHash ? createWebHashHistory('/') : createWebHistory('/'),
routes: [], routes: [],

View File

@ -1 +0,0 @@
export { default as themeSettings } from './theme.json'

View File

@ -1,23 +0,0 @@
import { defineStore } from 'pinia'
import { themeSettings } from '@/settings'
export const useThemeStore = defineStore('theme', {
state() {
return {
tags: themeSettings.tag || { visible: true, height: 50 },
header: themeSettings.header || { height: 60 },
naiveThemeOverrides: themeSettings.naiveThemeOverrides || {
common: {
primaryColor: '#316C72FF',
primaryColorHover: '#316C72E3',
primaryColorPressed: '#2B4C59FF',
primaryColorSuppl: '#316C7263',
},
},
}
},
actions: {
setTabVisible(visible) {
this.tags.visible = visible
},
},
})

View File

@ -1,3 +0,0 @@
:root {
--primaryColor: #316c72;
}

View File

@ -3,7 +3,6 @@ import { repReject, repResolve, reqReject, reqResolve } from './interceptors'
export function createAxios(options = {}) { export function createAxios(options = {}) {
const defaultOptions = { const defaultOptions = {
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 12000, timeout: 12000,
} }
const service = axios.create({ const service = axios.create({
@ -15,10 +14,6 @@ export function createAxios(options = {}) {
return service return service
} }
export const defAxios = createAxios() export default createAxios({
baseURL: import.meta.env.VITE_BASE_API,
export default createAxios()
export const testAxios = createAxios({
baseURL: import.meta.env.VITE_APP_BASE_API_TEST,
}) })

View File

@ -50,7 +50,7 @@ import { useStorage } from '@vueuse/core'
import bgImg from '@/assets/images/login_bg.webp' import bgImg from '@/assets/images/login_bg.webp'
import api from './api' import api from './api'
const title = import.meta.env.VITE_APP_TITLE const title = import.meta.env.VITE_TITLE
const router = useRouter() const router = useRouter()
const { query } = useRoute() const { query } = useRoute()

View File

@ -20,7 +20,26 @@ export default defineConfig({
], ],
theme: { theme: {
colors: { colors: {
primary: 'var(--primaryColor)', primary: 'var(--primary-color)',
primary_hover: 'var(--primary-color-hover)',
primary_pressed: 'var(--primary-color-pressed)',
primary_active: 'var(--primary-color-active)',
info: 'var(--info-color)',
info_hover: 'var(--info-color-hover)',
info_pressed: 'var(--info-color-pressed)',
info_active: 'var(--info-color-active)',
success: 'var(--success-color)',
success_hover: 'var(--success-color-hover)',
success_pressed: 'var(--success-color-pressed)',
success_active: 'var(--success-color-active)',
warning: 'var(--warning-color)',
warning_hover: 'var(--warning-color-hover)',
warning_pressed: 'var(--warning-color-pressed)',
warning_active: 'var(--warning-color-active)',
error: 'var(--error-color)',
error_hover: 'var(--error-color-hover)',
error_pressed: 'var(--error-color-pressed)',
error_active: 'var(--error-color-active)',
}, },
}, },
}) })

View File

@ -1,31 +1,34 @@
import { defineConfig, loadEnv } from 'vite' import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import { wrapperEnv, createProxy } from './build/utils' import { convertEnv, getSrcPath, getRootPath } from './build/utils'
import { createViteProxy, viteDefine } from './build/config'
import { createVitePlugins } from './build/plugin' import { createVitePlugins } from './build/plugin'
import { OUTPUT_DIR } from './build/constant' import { OUTPUT_DIR } from './build/constant'
export default defineConfig(({ command, mode }) => { export default defineConfig(({ command, mode }) => {
const root = process.cwd() const srcPath = getSrcPath()
const rootPath = getRootPath()
const isBuild = command === 'build' const isBuild = command === 'build'
const env = loadEnv(mode, process.cwd()) const env = loadEnv(mode, process.cwd())
const viteEnv = wrapperEnv(env) const viteEnv = convertEnv(env)
const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv const { VITE_PORT, VITE_PUBLIC_PATH, VITE_USE_PROXY, VITE_PROXY_TYPE } = viteEnv
return { return {
root,
base: VITE_PUBLIC_PATH || '/', base: VITE_PUBLIC_PATH || '/',
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, 'src'), '~': rootPath,
'@': srcPath,
}, },
}, },
define: viteDefine,
plugins: createVitePlugins(viteEnv, isBuild), plugins: createVitePlugins(viteEnv, isBuild),
server: { server: {
host: '0.0.0.0', host: '0.0.0.0',
port: VITE_PORT, port: VITE_PORT,
proxy: createProxy(VITE_PROXY), open: false,
proxy: createViteProxy(VITE_USE_PROXY, VITE_PROXY_TYPE),
}, },
build: { build: {
target: 'es2015', target: 'es2015',