Compare commits

...
12 Commits
32 changed files with 2424 additions and 2359 deletions
+1 -1
View File
@@ -6,4 +6,4 @@ VITE_APP_API_BASEURL = /
VITE_APP_DEBUG_TOOL =
# 是否开启代理
VITE_OPEN_PROXY = true
VITE_OPEN_PROXY = false
-1
View File
@@ -1,7 +1,6 @@
{
"extends": [
"stylelint-stylistic/config",
"stylelint-config-standard",
"stylelint-config-standard-scss",
"stylelint-config-standard-vue/scss"
],
+40 -41
View File
@@ -1,5 +1,5 @@
{
"version": "3.2.0",
"version": "3.2.3",
"scripts": {
"dev": "vite",
"build:test": "vue-tsc --noEmit && vite build --mode test",
@@ -18,69 +18,68 @@
"release": "bumpp"
},
"dependencies": {
"@vueuse/core": "^10.2.0",
"@vueuse/integrations": "^10.2.0",
"axios": "^1.4.0",
"dayjs": "^1.11.8",
"element-plus": "^2.3.7",
"eruda": "^3.0.0",
"hotkeys-js": "^3.10.2",
"@vueuse/core": "^10.5.0",
"@vueuse/integrations": "^10.5.0",
"axios": "^1.5.1",
"dayjs": "^1.11.10",
"element-plus": "^2.3.14",
"eruda": "^3.0.1",
"hotkeys-js": "^3.12.0",
"lodash-es": "^4.17.21",
"mitt": "^3.0.0",
"mitt": "^3.0.1",
"mockjs": "^1.1.0",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.1",
"pinia": "^2.1.4",
"pinia": "^2.1.6",
"qs": "^6.11.2",
"vconsole": "^3.15.1",
"vue": "^3.3.4",
"vue-router": "^4.2.2"
"vue-router": "^4.2.5"
},
"devDependencies": {
"@antfu/eslint-config": "^0.39.5",
"@iconify-json/ep": "^1.1.11",
"@antfu/eslint-config": "^0.41.0",
"@iconify-json/ep": "^1.1.12",
"@iconify/vue": "^4.1.1",
"@types/nprogress": "^0.2.0",
"@types/nprogress": "^0.2.1",
"@types/path-browserify": "^1.0.0",
"@types/qs": "^6.9.7",
"@vitejs/plugin-legacy": "^4.0.5",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"autoprefixer": "^10.4.14",
"bumpp": "^9.1.1",
"cz-git": "^1.6.1",
"eslint": "^8.43.0",
"esno": "^0.16.3",
"@types/qs": "^6.9.8",
"@vitejs/plugin-legacy": "^4.1.1",
"@vitejs/plugin-vue": "^4.4.0",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"autoprefixer": "^10.4.16",
"bumpp": "^9.2.0",
"cz-git": "^1.7.1",
"eslint": "^8.51.0",
"esno": "^0.17.0",
"fs-extra": "^11.1.1",
"http-server": "^14.1.1",
"lint-staged": "^13.2.2",
"lint-staged": "^14.0.1",
"npm-run-all": "^4.1.5",
"plop": "^3.1.2",
"plop": "^4.0.0",
"postcss-html": "^1.5.0",
"sass": "^1.63.6",
"simple-git-hooks": "^2.8.1",
"stylelint": "^15.8.0",
"stylelint-config-standard": "^33.0.0",
"stylelint-config-standard-scss": "^9.0.0",
"sass": "^1.69.1",
"simple-git-hooks": "^2.9.0",
"stylelint": "^15.10.3",
"stylelint-config-standard-scss": "^11.0.0",
"stylelint-config-standard-vue": "^1.0.0",
"stylelint-scss": "^5.0.1",
"stylelint-stylistic": "^0.4.2",
"stylelint-scss": "^5.2.1",
"stylelint-stylistic": "^0.4.3",
"svgo": "^3.0.2",
"terser": "^5.18.1",
"typescript": "^5.0.4",
"unplugin-auto-import": "^0.16.4",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.3.9",
"vite-plugin-banner": "^0.7.0",
"terser": "^5.21.0",
"typescript": "^5.2.2",
"unplugin-auto-import": "^0.16.6",
"unplugin-vue-components": "^0.25.2",
"vite": "^4.4.11",
"vite-plugin-banner": "^0.7.1",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-mock": "^2.9.8",
"vite-plugin-pages": "^0.31.0",
"vite-plugin-spritesmith": "^0.1.1",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-inspector": "^3.4.2",
"vite-plugin-vue-meta-layouts": "^0.2.2",
"vue-tsc": "^1.6.5"
"vite-plugin-vue-inspector": "^4.0.0",
"vite-plugin-vue-meta-layouts": "^0.3.1",
"vue-tsc": "^1.8.18"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged",
+1 -1
View File
@@ -3,6 +3,6 @@ const fs = require('node:fs')
module.exports = function (plop) {
plop.setWelcomeMessage('请选择需要创建的模式:')
fs.readdirSync('./plop-templates').forEach((item) => {
plop.setGenerator(item, require(`./plop-templates/${item}/prompt`))
fs.lstatSync(`./plop-templates/${item}`).isDirectory() && plop.setGenerator(item, require(`./plop-templates/${item}/prompt`))
})
}
+2282 -2214
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -1,4 +1,5 @@
import path from 'node:path'
import process from 'node:process'
import fs from 'fs-extra'
import { icons } from '@iconify-json/ep'
+4 -4
View File
@@ -1,12 +1,12 @@
<script setup lang="ts">
const props = defineProps<{
value: string | string[]
}>()
defineOptions({
name: 'Auth',
})
const props = defineProps<{
value: string | string[]
}>()
function check() {
return useAuth().auth(props.value)
}
+4 -4
View File
@@ -1,12 +1,12 @@
<script setup lang="ts">
const props = defineProps<{
value: string[]
}>()
defineOptions({
name: 'AuthAll',
})
const props = defineProps<{
value: string[]
}>()
function check() {
return useAuth().authAll(props.value)
}
+4 -4
View File
@@ -2,6 +2,10 @@
import type { UploadProps, UploadUserFile } from 'element-plus'
import { ElMessage } from 'element-plus'
defineOptions({
name: 'FileUpload',
})
const props = withDefaults(
defineProps<{
action: UploadProps['action']
@@ -32,10 +36,6 @@ const emits = defineEmits<{
]
}>()
defineOptions({
name: 'FileUpload',
})
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
const fileName = file.name.split('.')
const fileExt = fileName.at(-1) ?? ''
+2 -2
View File
@@ -1,10 +1,10 @@
<script setup lang="ts">
const isBottom = ref(false)
defineOptions({
name: 'FixedActionBar',
})
const isBottom = ref(false)
onMounted(() => {
onScroll()
window.addEventListener('scroll', onScroll)
+4 -4
View File
@@ -1,4 +1,8 @@
<script setup lang="ts">
defineOptions({
name: 'ImagePreview',
})
const props = withDefaults(
defineProps<{
src: string
@@ -11,10 +15,6 @@ const props = withDefaults(
},
)
defineOptions({
name: 'ImagePreview',
})
const realWidth = computed(() => {
return typeof props.width === 'string' ? props.width : `${props.width}px`
})
+4 -4
View File
@@ -2,6 +2,10 @@
import type { UploadProps } from 'element-plus'
import { ElMessage } from 'element-plus'
defineOptions({
name: 'ImageUpload',
})
const props = withDefaults(
defineProps<{
action: UploadProps['action']
@@ -37,10 +41,6 @@ const emits = defineEmits<{
]
}>()
defineOptions({
name: 'ImageUpload',
})
const uploadData = ref({
imageViewerVisible: false,
progress: {
+4 -4
View File
@@ -2,6 +2,10 @@
import type { UploadProps } from 'element-plus'
import { ElMessage } from 'element-plus'
defineOptions({
name: 'ImagesUpload',
})
const props = withDefaults(
defineProps<{
action: UploadProps['action']
@@ -39,10 +43,6 @@ const emits = defineEmits<{
]
}>()
defineOptions({
name: 'ImagesUpload',
})
const uploadData = ref({
dialogImageIndex: 0,
imageViewerVisible: false,
+2 -3
View File
@@ -6,7 +6,7 @@ defineOptions({
const router = useRouter()
const data = ref({
inter: NaN,
inter: Number.NaN,
countdown: 5,
})
@@ -54,8 +54,7 @@ function goBack() {
@include position-center(xy);
.icon {
width: 400px;
height: 400px;
font-size: 400px;
}
.content {
+4 -4
View File
@@ -1,4 +1,8 @@
<script setup lang="ts">
defineOptions({
name: 'PageHeader',
})
withDefaults(
defineProps<{
title: string
@@ -9,10 +13,6 @@ withDefaults(
},
)
defineOptions({
name: 'PageHeader',
})
const slots = useSlots()
</script>
+4 -4
View File
@@ -1,4 +1,8 @@
<script setup lang="ts">
defineOptions({
name: 'PageMain',
})
const props = withDefaults(
defineProps<{
title?: string
@@ -12,10 +16,6 @@ const props = withDefaults(
},
)
defineOptions({
name: 'PageMain',
})
const titleSlot = !!useSlots().title
const collaspeData = ref(props.collaspe)
+4 -4
View File
@@ -2,6 +2,10 @@
// 行政区划数据来源于 https://github.com/modood/Administrative-divisions-of-China
import pcasRaw from './pcas-code.json'
defineOptions({
name: 'PcasCascader',
})
const props = withDefaults(
defineProps<{
modelValue: string[] | {
@@ -28,10 +32,6 @@ const emits = defineEmits<{
]
}>()
defineOptions({
name: 'PcasCascader',
})
interface pcasItem {
code: string
name: string
+4 -4
View File
@@ -1,4 +1,8 @@
<script setup lang="ts">
defineOptions({
name: 'SearchBar',
})
const props = withDefaults(
defineProps<{
fold?: boolean
@@ -21,10 +25,6 @@ const emits = defineEmits<{
]
}>()
defineOptions({
name: 'SearchBar',
})
const isFold = ref(props.fold)
watch(() => props.fold, (value) => {
+4 -4
View File
@@ -1,6 +1,10 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
defineOptions({
name: 'SvgIcon',
})
const props = defineProps<{
name: string
flip?: 'horizontal' | 'vertical' | 'both'
@@ -9,10 +13,6 @@ const props = defineProps<{
size?: string | number
}>()
defineOptions({
name: 'SvgIcon',
})
const style = computed(() => {
const transform = []
if (props.flip) {
+4 -4
View File
@@ -1,4 +1,8 @@
<script setup lang="ts">
defineOptions({
name: 'Trend',
})
const props = withDefaults(
defineProps<{
value: string
@@ -15,10 +19,6 @@ const props = withDefaults(
},
)
defineOptions({
name: 'Trend',
})
const isUp = computed(() => {
let isUp = props.type === 'up'
if (props.reverse) {
+4 -4
View File
@@ -2,6 +2,10 @@
import imgLogo from '@/assets/images/logo.png'
import useSettingsStore from '@/store/modules/settings'
defineOptions({
name: 'Logo',
})
withDefaults(
defineProps<{
showLogo?: boolean
@@ -13,10 +17,6 @@ withDefaults(
},
)
defineOptions({
name: 'Logo',
})
const settingsStore = useSettingsStore()
const title = ref(import.meta.env.VITE_APP_TITLE)
+8 -8
View File
@@ -21,9 +21,9 @@ const menuStore = useMenuStore()
interface listTypes {
path: string
icon?: string
title?: string | Function
title?: string | (() => string)
link?: string
breadcrumb: (string | Function | undefined)[]
breadcrumb: any[]
}
const isShow = ref(false)
@@ -147,16 +147,16 @@ function hasChildren(item: RouteRecordRaw) {
}
return flag
}
function getSourceList(arr: RouteRecordRaw[], basePath?: string, icon?: string, breadcrumb?: (string | Function | undefined)[]) {
function getSourceList(arr: RouteRecordRaw[], basePath?: string, icon?: string, breadcrumb?: (string | (() => string))[]) {
arr.forEach((item) => {
if (item.meta?.sidebar !== false) {
const breadcrumbTemp = cloneDeep(breadcrumb) || []
if (item.children && hasChildren(item)) {
breadcrumbTemp.push(item.meta?.title)
item.meta?.title && breadcrumbTemp.push(item.meta?.title)
getSourceList(item.children, basePath ? [basePath, item.path].join('/') : item.path, item.meta?.icon ?? icon, breadcrumbTemp)
}
else {
breadcrumbTemp.push(item.meta?.title)
item.meta?.title && breadcrumbTemp.push(item.meta?.title)
sourceList.value.push({
path: basePath ? [basePath, item.path].join('/') : item.path,
icon: item.meta?.icon ?? icon,
@@ -168,15 +168,15 @@ function getSourceList(arr: RouteRecordRaw[], basePath?: string, icon?: string,
}
})
}
function getSourceListByMenus(arr: Menu.recordRaw[], icon?: string, breadcrumb?: (string | Function | undefined)[]) {
function getSourceListByMenus(arr: Menu.recordRaw[], icon?: string, breadcrumb?: (string | (() => string))[]) {
arr.forEach((item) => {
const breadcrumbTemp = cloneDeep(breadcrumb) || []
if (item.children && item.children.length > 0) {
breadcrumbTemp.push(item.meta?.title)
item.meta?.title && breadcrumbTemp.push(item.meta?.title)
getSourceListByMenus(item.children, item.meta?.icon ?? icon, breadcrumbTemp)
}
else {
breadcrumbTemp.push(item.meta?.title)
item.meta?.title && breadcrumbTemp.push(item.meta?.title)
sourceList.value.push({
icon: item.meta?.icon ?? icon,
title: item.meta?.title,
+4 -4
View File
@@ -3,6 +3,10 @@ import { resolveRoutePath } from '@/utils'
import useSettingsStore from '@/store/modules/settings'
import type { Menu } from '#/global'
defineOptions({
name: 'SidebarItem',
})
const props = withDefaults(
defineProps<{
item: Menu.recordRaw
@@ -13,10 +17,6 @@ const props = withDefaults(
},
)
defineOptions({
name: 'SidebarItem',
})
const settingsStore = useSettingsStore()
const hasChildren = computed(() => {
+1 -1
View File
@@ -80,7 +80,7 @@ router.beforeEach(async (to, from, next) => {
}
// 注册并记录路由数据
// 记录的数据会在登出时会使用到,不使用 router.removeRoute 是考虑配置的路由可能不一定有设置 name ,则通过调用 router.addRoute() 返回的回调进行删除
const removeRoutes: Function[] = []
const removeRoutes: (() => void)[] = []
routeStore.flatRoutes.forEach((route) => {
if (!/^(https?:|mailto:|tel:)/.test(route.path)) {
removeRoutes.push(router.addRoute(route as RouteRecordRaw))
+5 -2
View File
@@ -17,7 +17,7 @@ const useRouteStore = defineStore(
const isGenerate = ref(false)
const routesRaw = ref<Route.recordMainRaw[]>([])
const filesystemRoutesRaw = ref<RouteRecordRaw[]>([])
const currentRemoveRoutes = ref<Function[]>([])
const currentRemoveRoutes = ref<(() => void)[]>([])
// 将多层嵌套路由处理成两层,保留顶层和最子层路由,中间层级将被拍平
function flatAsyncRoutes<T extends RouteRecordRaw>(route: T): T {
@@ -187,6 +187,9 @@ const useRouteStore = defineStore(
if (route.component) {
route.component = views[`../../views/${route.component}`]
}
else {
delete route.component
}
}
if (route.children) {
route.children = formatBackRoutes(route.children, views)
@@ -216,7 +219,7 @@ const useRouteStore = defineStore(
isGenerate.value = true
}
// 记录 accessRoutes 路由,用于登出时删除路由
function setCurrentRemoveRoutes(routes: Function[]) {
function setCurrentRemoveRoutes(routes: (() => void)[]) {
currentRemoveRoutes.value = routes
}
// 清空动态路由
+1
View File
@@ -1,6 +1,7 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
+3 -3
View File
@@ -211,7 +211,7 @@ declare namespace Settings {
declare module 'vue-router' {
interface RouteMeta {
title?: string | Function
title?: string | (() => string)
i18n?: string
icon?: string
activeIcon?: string
@@ -229,7 +229,7 @@ declare module 'vue-router' {
declare namespace Route {
interface recordMainRaw {
meta?: {
title?: string | Function
title?: string | (() => string)
icon?: string
auth?: string | string[]
}
@@ -237,7 +237,7 @@ declare namespace Route {
}
interface breadcrumb {
path: string
title?: string | Function
title?: string | (() => string)
hide: boolean
}
}
+13 -20
View File
@@ -1,20 +1,13 @@
declare interface Window {
webkitDevicePixelRatio: any
mozDevicePixelRatio: any
}
declare module '*.vue' {
import { type DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
declare const __SYSTEM_INFO__: {
pkg: {
version: string
dependencies: Recordable<string>
devDependencies: Recordable<string>
}
lastBuildTime: string
}
declare interface Window {
webkitDevicePixelRatio: any
mozDevicePixelRatio: any
}
declare const __SYSTEM_INFO__: {
pkg: {
version: string
dependencies: Recordable<string>
devDependencies: Recordable<string>
}
lastBuildTime: string
}
+2 -3
View File
@@ -10,7 +10,7 @@ meta:
const router = useRouter()
const data = ref({
inter: NaN,
inter: Number.NaN,
countdown: 5,
})
@@ -58,8 +58,7 @@ function goBack() {
@include position-center(xy);
.icon {
width: 400px;
height: 400px;
font-size: 400px;
}
.content {
+1 -2
View File
@@ -6,7 +6,6 @@ meta:
</route>
<script setup lang="ts">
import type { UploadProps } from 'element-plus'
import { ElMessage } from 'element-plus'
defineOptions({
@@ -23,7 +22,7 @@ const form = ref({
wechat: '',
})
const handleSuccess: UploadProps['onSuccess'] = (res) => {
function handleSuccess(res: any) {
if (res.error === '') {
form.value.headimg = res.data.path
}
+4 -1
View File
@@ -1,5 +1,6 @@
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { defineConfig, loadEnv } from 'vite'
import dayjs from 'dayjs'
import pkg from './package.json'
@@ -11,7 +12,9 @@ export default ({ mode, command }) => {
// 全局 scss 资源
const scssResources = []
fs.readdirSync('src/assets/styles/resources').forEach((dirname) => {
if (fs.statSync(`src/assets/styles/resources/${dirname}`).isFile()) { scssResources.push(`@use "src/assets/styles/resources/${dirname}" as *;`) }
if (fs.statSync(`src/assets/styles/resources/${dirname}`).isFile()) {
scssResources.push(`@use "src/assets/styles/resources/${dirname}" as *;`)
}
})
// css 精灵图相关
fs.readdirSync('src/assets/sprites').forEach((dirname) => {
+1
View File
@@ -1,4 +1,5 @@
import path from 'node:path'
import process from 'node:process'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
export default function createSvgIcon(isBuild) {