mirror of
https://github.com/zclzone/vue-naive-admin.git
synced 2026-01-22 23:50:22 +08:00
Compare commits
23 Commits
2.x_vxe-ta
...
1934776063
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1934776063 | ||
|
|
c675a4d420 | ||
|
|
e29343586f | ||
|
|
6fea2a1b69 | ||
|
|
2513e475be | ||
|
|
dde25dd7ab | ||
|
|
1eb59b7cad | ||
|
|
27a50a99b4 | ||
|
|
cf0ba0a2bf | ||
|
|
70c2098d2e | ||
|
|
82748abcc3 | ||
|
|
e5fd1405da | ||
|
|
833321d31d | ||
|
|
53afc9b531 | ||
|
|
0733b81f82 | ||
|
|
26ce0bd551 | ||
|
|
1201e8e172 | ||
|
|
78d9bb99f2 | ||
|
|
9b510e8350 | ||
|
|
7ce6cf1f7c | ||
|
|
30ca69cf16 | ||
|
|
c34c3646aa | ||
|
|
6563797afc |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -19,6 +19,5 @@
|
|||||||
"markdown",
|
"markdown",
|
||||||
"json",
|
"json",
|
||||||
"jsonc"
|
"jsonc"
|
||||||
],
|
]
|
||||||
"common-intellisense.ui": ["naiveUi2"]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
<a href="./LICENSE"><img alt="MIT License" src="https://badgen.net/github/license/zclzone/vue-naive-admin"/></a>
|
<a href="./LICENSE"><img alt="MIT License" src="https://badgen.net/github/license/zclzone/vue-naive-admin"/></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<a href="https://hellogithub.com/repository/54f19ba1f9ae4238b3cbd111f3c428b0" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=54f19ba1f9ae4238b3cbd111f3c428b0&claim_uid=jXGayRdJZScqMNr" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
Vue Naive Admin 是一款极简风格的后台管理模板,包含前后端解决方案,前端使用 Vite + Vue3 + Pinia + Unocss,后端使用 Nestjs + TypeOrm + MySql,简单易用,赏心悦目,历经十几次重构和细节打磨,诚意满满!!
|
Vue Naive Admin 是一款极简风格的后台管理模板,包含前后端解决方案,前端使用 Vite + Vue3 + Pinia + Unocss,后端使用 Nestjs + TypeOrm + MySql,简单易用,赏心悦目,历经十几次重构和细节打磨,诚意满满!!
|
||||||
|
|||||||
57
package.json
57
package.json
@@ -13,42 +13,43 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@vueuse/core": "^11.1.0",
|
"@vueuse/core": "^13.1.0",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.8.4",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.6.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"naive-ui": "^2.40.1",
|
"naive-ui": "^2.41.0",
|
||||||
"pinia": "^2.2.4",
|
"pinia": "^3.0.2",
|
||||||
"pinia-plugin-persistedstate": "^4.1.1",
|
"pinia-plugin-persistedstate": "^4.2.0",
|
||||||
"vue": "^3.5.12",
|
"vue": "^3.5.13",
|
||||||
"vue-echarts": "^7.0.3",
|
"vue-echarts": "^7.0.3",
|
||||||
"vue-router": "^4.4.5",
|
"vue-router": "^4.5.0",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^3.8.0",
|
"@antfu/eslint-config": "^4.12.0",
|
||||||
"@iconify/json": "^2.2.262",
|
"@iconify/json": "^2.2.331",
|
||||||
"@unocss/eslint-config": "^0.63.6",
|
"@unocss/eslint-config": "^66.0.0",
|
||||||
"@unocss/eslint-plugin": "^0.63.6",
|
"@unocss/eslint-plugin": "^66.0.0",
|
||||||
"@unocss/preset-rem-to-px": "^0.63.6",
|
"@unocss/preset-rem-to-px": "^66.0.0",
|
||||||
"@vitejs/plugin-vue": "^5.1.4",
|
"@vitejs/plugin-vue": "^5.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
"@vitejs/plugin-vue-jsx": "^4.1.2",
|
||||||
"eslint": "^9.13.0",
|
"eslint": "^9.25.1",
|
||||||
"eslint-plugin-format": "^0.1.2",
|
"eslint-plugin-format": "^1.0.1",
|
||||||
"esno": "^4.8.0",
|
"esno": "^4.8.0",
|
||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.3.0",
|
||||||
"glob": "^11.0.0",
|
"glob": "^11.0.2",
|
||||||
"lint-staged": "^15.2.10",
|
"lint-staged": "^15.5.1",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.14.0",
|
||||||
"simple-git-hooks": "^2.11.1",
|
"simple-git-hooks": "^2.13.0",
|
||||||
"taze": "^0.17.2",
|
"taze": "^19.0.4",
|
||||||
"unocss": "^0.63.6",
|
"unocss": "^66.0.0",
|
||||||
"unplugin-auto-import": "^0.18.3",
|
"unplugin-auto-import": "^19.1.2",
|
||||||
"unplugin-vue-components": "^0.27.4",
|
"unplugin-vue-components": "^28.5.0",
|
||||||
"vite": "^5.4.9",
|
"vite": "^6.3.3",
|
||||||
"vite-plugin-router-warn": "^1.0.0",
|
"vite-plugin-router-warn": "^1.0.0",
|
||||||
"vite-plugin-vue-devtools": "^7.5.2"
|
"vite-plugin-vue-devtools": "^7.7.5",
|
||||||
|
"vue3-intro-step": "^1.0.5"
|
||||||
},
|
},
|
||||||
"simple-git-hooks": {
|
"simple-git-hooks": {
|
||||||
"pre-commit": "pnpm lint-staged"
|
"pre-commit": "pnpm lint-staged"
|
||||||
|
|||||||
5088
pnpm-lock.yaml
generated
5088
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<n-tooltip trigger="hover" placement="left">
|
<n-tooltip trigger="hover" placement="left">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div class="f-c-c rounded-4 bg-primary p-8" @click="modalRef.open()">
|
<div id="layout-setting" class="f-c-c rounded-4 bg-primary p-8" @click="modalRef.open()">
|
||||||
<i class="i-fe:settings cursor-pointer bg-white text-20" />
|
<i class="i-fe:settings cursor-pointer bg-white text-20" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-tooltip trigger="hover">
|
<div class="f-c-c">
|
||||||
<template #trigger>
|
<n-tooltip trigger="hover" placement="bottom">
|
||||||
<n-color-picker
|
<template #trigger>
|
||||||
class="mr-16 h-32 w-32"
|
<n-color-picker
|
||||||
:value="appStore.primaryColor"
|
id="theme-setting"
|
||||||
:swatches="primaryColors"
|
class="h-32 w-32"
|
||||||
:on-update:value="(v) => appStore.setPrimaryColor(v)"
|
:value="appStore.primaryColor"
|
||||||
:render-label="() => ''"
|
:swatches="primaryColors"
|
||||||
/>
|
:on-update:value="(v) => appStore.setPrimaryColor(v)"
|
||||||
</template>
|
:render-label="() => ''"
|
||||||
设置主题色
|
/>
|
||||||
</n-tooltip>
|
</template>
|
||||||
|
设置主题色
|
||||||
|
</n-tooltip>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<i
|
<i
|
||||||
|
id="toggleTheme"
|
||||||
class="mr-16 cursor-pointer"
|
class="mr-16 cursor-pointer"
|
||||||
:class="isDark ? 'i-fe:moon' : 'i-fe:sun'"
|
:class="isDark ? 'i-fe:moon' : 'i-fe:sun'"
|
||||||
@click="toggleDark"
|
@click="toggleDark"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { useForm, useModal } from '.'
|
import { useForm, useModal } from '.'
|
||||||
|
|
||||||
const ACTIONS = {
|
const ACTIONS = {
|
||||||
@@ -21,7 +22,7 @@ export function useCrud({ name, initForm = {}, doCreate, doDelete, doUpdate, ref
|
|||||||
|
|
||||||
/** 新增 */
|
/** 新增 */
|
||||||
function handleAdd(row = {}, title) {
|
function handleAdd(row = {}, title) {
|
||||||
handleOpen({ action: 'add', title, row: { ...initForm, ...row } })
|
handleOpen({ action: 'add', title, row: Object.assign({}, cloneDeep(initForm), cloneDeep(row)) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改 */
|
/** 修改 */
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
export function useForm(initFormData = {}) {
|
export function useForm(initFormData = {}) {
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
const formModel = ref({ ...initFormData })
|
const formModel = ref(cloneDeep(initFormData))
|
||||||
const rules = {
|
const rules = {
|
||||||
required: {
|
required: {
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { router } from '@/router'
|
import { router } from '@/router'
|
||||||
|
import { withDirectives } from 'vue'
|
||||||
|
|
||||||
const permission = {
|
const permission = {
|
||||||
mounted(el, binding) {
|
mounted(el, binding) {
|
||||||
@@ -21,3 +22,17 @@ const permission = {
|
|||||||
export function setupDirectives(app) {
|
export function setupDirectives(app) {
|
||||||
app.directive('permission', permission)
|
app.directive('permission', permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于h函数使用自定义权限指令
|
||||||
|
*
|
||||||
|
* @param {*} vnode 虚拟节点
|
||||||
|
* @param {*} code 权限码
|
||||||
|
* @returns 返回一个包含权限指令的vnode
|
||||||
|
*
|
||||||
|
* 使用示例:withPermission(h('button', {class: 'text-red-500'}, '删除'), 'user:delete')
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function withPermission(vnode, code) {
|
||||||
|
return withDirectives(vnode, [[permission, code]])
|
||||||
|
}
|
||||||
|
|||||||
120
src/layouts/components/BeginnerGuide.vue
Normal file
120
src/layouts/components/BeginnerGuide.vue
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<n-tooltip trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
|
<i
|
||||||
|
class="i-fe:beginner mr-16 cursor-pointer text-20"
|
||||||
|
@click="show = true"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
操作指引
|
||||||
|
</n-tooltip>
|
||||||
|
|
||||||
|
<Vue3IntroStep
|
||||||
|
ref="myIntroStep"
|
||||||
|
v-model:show="show"
|
||||||
|
:config="config"
|
||||||
|
>
|
||||||
|
<template #prev="{ tipItem, index }">
|
||||||
|
<NButton class="mr-12" type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="prev(tipItem, index)">
|
||||||
|
上一步
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
<template #next="{ tipItem }">
|
||||||
|
<NButton class="mr-12" type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="next(tipItem)">
|
||||||
|
下一步
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #skip>
|
||||||
|
<NButton type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="skip">
|
||||||
|
跳过
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #done>
|
||||||
|
<NButton type="primary" color="#fff" text-color="#fff" ghost round size="small" @click="done">
|
||||||
|
完成
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
</Vue3IntroStep>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import Vue3IntroStep from 'vue3-intro-step'
|
||||||
|
|
||||||
|
const myIntroStep = shallowRef(null)
|
||||||
|
const show = shallowRef(false)
|
||||||
|
const config = {
|
||||||
|
backgroundOpacity: 0.8,
|
||||||
|
titleStyle: {
|
||||||
|
textAlign: 'left',
|
||||||
|
fontSize: '18px',
|
||||||
|
},
|
||||||
|
contentStyle: {
|
||||||
|
textAlign: 'left',
|
||||||
|
fontSize: '14px',
|
||||||
|
},
|
||||||
|
tips: [
|
||||||
|
{
|
||||||
|
el: '#toggleTheme',
|
||||||
|
tipPosition: 'bottom',
|
||||||
|
title: '切换系统主题',
|
||||||
|
content: '一键开启护眼模式',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
el: '#fullscreen',
|
||||||
|
tipPosition: 'bottom',
|
||||||
|
title: '全屏/退出全屏',
|
||||||
|
content: '一键开启全屏',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
el: '#theme-setting',
|
||||||
|
tipPosition: 'bottom',
|
||||||
|
title: '设置主题色',
|
||||||
|
content: '调整为你喜欢的主题色',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
el: '#user-dropdown',
|
||||||
|
tipPosition: 'bottom',
|
||||||
|
title: '个人中心',
|
||||||
|
content: '查看个人资料和退出系统',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
el: '#menu-collapse',
|
||||||
|
tipPosition: 'bottom',
|
||||||
|
title: '展开/收起菜单',
|
||||||
|
content: '一键展开/收起菜单',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
el: '#top-tab',
|
||||||
|
tipPosition: 'bottom',
|
||||||
|
title: '标签栏',
|
||||||
|
content: '鼠标滚轮滑动可调整至最佳视野',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
el: '#layout-setting',
|
||||||
|
tipPosition: 'left',
|
||||||
|
title: '调整系统布局',
|
||||||
|
content: '将系统布局调整为你喜欢的样子',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
function skip() {
|
||||||
|
show.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function done() {
|
||||||
|
show.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
// tipItem当前的提示项信息
|
||||||
|
// 调用vue3-intro-step的next方法 手动触发下一步
|
||||||
|
myIntroStep.value.next()
|
||||||
|
}
|
||||||
|
function prev() {
|
||||||
|
// 调用vue3-intro-step的prev方法 手动触发上一步
|
||||||
|
myIntroStep.value.prev()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<i
|
<i
|
||||||
|
id="fullscreen"
|
||||||
class="mr-16 cursor-pointer"
|
class="mr-16 cursor-pointer"
|
||||||
:class="isFullscreen ? 'i-fe:minimize' : 'i-fe:maximize'"
|
:class="isFullscreen ? 'i-fe:minimize' : 'i-fe:maximize'"
|
||||||
@click="toggle"
|
@click="toggle"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
id="menu-collapse"
|
||||||
class="f-c-c cursor-pointer rounded-4 p-6 text-22 transition-all-300 auto-bg-hover"
|
class="f-c-c cursor-pointer rounded-4 p-6 text-22 transition-all-300 auto-bg-hover"
|
||||||
@click="appStore.switchCollapsed"
|
@click="appStore.switchCollapsed"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ function handleMenuSelect(key, item) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if(!item.path) return
|
||||||
router.push(item.path)
|
router.push(item.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-dropdown :options="options" @select="handleSelect">
|
<n-dropdown :options="options" @select="handleSelect">
|
||||||
<div class="flex cursor-pointer items-center">
|
<div id="user-dropdown" class="flex cursor-pointer items-center">
|
||||||
<n-avatar round :size="36" :src="userStore.avatar" />
|
<n-avatar round :size="36" :src="userStore.avatar" />
|
||||||
<div v-if="userStore.userInfo" class="ml-12 flex-col flex-shrink-0 items-center">
|
<div v-if="userStore.userInfo" class="ml-12 flex-col flex-shrink-0 items-center">
|
||||||
<span class="text-14">{{ userStore.nickName ?? userStore.username }}</span>
|
<span class="text-14">{{ userStore.nickName ?? userStore.username }}</span>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export { default as BeginnerGuide } from './BeginnerGuide.vue'
|
||||||
export { default as BreadCrumb } from './BreadCrumb.vue'
|
export { default as BreadCrumb } from './BreadCrumb.vue'
|
||||||
export { default as Fullscreen } from './Fullscreen.vue'
|
export { default as Fullscreen } from './Fullscreen.vue'
|
||||||
export { default as MenuCollapse } from './MenuCollapse.vue'
|
export { default as MenuCollapse } from './MenuCollapse.vue'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
--------------------------------->
|
--------------------------------->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div id="top-tab">
|
||||||
<n-tabs
|
<n-tabs
|
||||||
:value="tabStore.activeTab"
|
:value="tabStore.activeTab"
|
||||||
:closable="tabStore.tabs.length > 1"
|
:closable="tabStore.tabs.length > 1"
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
<BreadCrumb />
|
<BreadCrumb />
|
||||||
|
|
||||||
<div class="ml-auto flex flex-shrink-0 items-center px-12 text-18">
|
<div class="ml-auto flex flex-shrink-0 items-center px-12 text-18">
|
||||||
|
<BeginnerGuide />
|
||||||
|
|
||||||
<ToggleTheme />
|
<ToggleTheme />
|
||||||
|
|
||||||
<Fullscreen />
|
<Fullscreen />
|
||||||
@@ -35,7 +37,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ToggleTheme } from '@/components'
|
import { ToggleTheme } from '@/components'
|
||||||
import { BreadCrumb, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components'
|
import { BeginnerGuide, BreadCrumb, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components'
|
||||||
|
|
||||||
function handleLinkClick(link) {
|
function handleLinkClick(link) {
|
||||||
window.open(link)
|
window.open(link)
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
<span class="mx-6 opacity-20">|</span>
|
<span class="mx-6 opacity-20">|</span>
|
||||||
|
|
||||||
<div class="flex flex-shrink-0 items-center px-12 text-18">
|
<div class="flex flex-shrink-0 items-center px-12 text-18">
|
||||||
|
<BeginnerGuide />
|
||||||
|
|
||||||
<ToggleTheme />
|
<ToggleTheme />
|
||||||
|
|
||||||
<Fullscreen />
|
<Fullscreen />
|
||||||
@@ -37,7 +39,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ToggleTheme } from '@/components'
|
import { ToggleTheme } from '@/components'
|
||||||
import { AppTab, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components'
|
import { AppTab, BeginnerGuide, Fullscreen, MenuCollapse, UserAvatar } from '@/layouts/components'
|
||||||
|
|
||||||
function handleLinkClick(link) {
|
function handleLinkClick(link) {
|
||||||
window.open(link)
|
window.open(link)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
paths: ['collapsed', 'layout', 'primaryColor', 'naiveThemeOverrides'],
|
pick: ['collapsed', 'layout', 'primaryColor', 'naiveThemeOverrides'],
|
||||||
storage: sessionStorage,
|
storage: sessionStorage,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export const useTabStore = defineStore('tab', {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
persist: {
|
persist: {
|
||||||
paths: ['tabs'],
|
pick: ['tabs'],
|
||||||
storage: sessionStorage,
|
storage: sessionStorage,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ import { createStorage } from './storage'
|
|||||||
|
|
||||||
const prefixKey = 'vue-naive-admin_'
|
const prefixKey = 'vue-naive-admin_'
|
||||||
|
|
||||||
export const createLocalStorage = function (option = {}) {
|
export function createLocalStorage(option = {}) {
|
||||||
return createStorage({
|
return createStorage({
|
||||||
prefixKey: option.prefixKey || '',
|
prefixKey: option.prefixKey || '',
|
||||||
storage: localStorage,
|
storage: localStorage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createSessionStorage = function (option = {}) {
|
export function createSessionStorage(option = {}) {
|
||||||
return createStorage({
|
return createStorage({
|
||||||
prefixKey: option.prefixKey || '',
|
prefixKey: option.prefixKey || '',
|
||||||
storage: sessionStorage,
|
storage: sessionStorage,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { sleep } from '@/utils'
|
import { sleep } from '@/utils'
|
||||||
|
|
||||||
const handleDelete = function () {
|
function handleDelete() {
|
||||||
$dialog.confirm({
|
$dialog.confirm({
|
||||||
content: '确认删除?',
|
content: '确认删除?',
|
||||||
confirm() {
|
confirm() {
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
class="text-14 text-primary text-highlight hover:underline hover:opacity-80"
|
class="text-14 text-primary text-highlight hover:underline hover:opacity-80"
|
||||||
href="https://isme.top"
|
href="https://isme.top"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@click.prevent="message?.info('官网正在火速开发中...')"
|
|
||||||
>
|
>
|
||||||
isme.top
|
isme.top
|
||||||
</a>
|
</a>
|
||||||
@@ -284,6 +283,4 @@ const skillOption = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = $message
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -163,31 +163,31 @@ const columns = [
|
|||||||
render(row) {
|
render(row) {
|
||||||
return row.roles?.some(item => item.id === +route.params.roleId)
|
return row.roles?.some(item => item.id === +route.params.roleId)
|
||||||
? h(
|
? h(
|
||||||
NButton,
|
NButton,
|
||||||
{
|
{
|
||||||
size: 'small',
|
size: 'small',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
secondary: true,
|
secondary: true,
|
||||||
onClick: () => handleBatchRemove([row.id]),
|
onClick: () => handleBatchRemove([row.id]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
default: () => '取消授权',
|
default: () => '取消授权',
|
||||||
icon: () => h('i', { class: 'i-material-symbols:delete-outline text-14' }),
|
icon: () => h('i', { class: 'i-material-symbols:delete-outline text-14' }),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: h(
|
: h(
|
||||||
NButton,
|
NButton,
|
||||||
{
|
{
|
||||||
size: 'small',
|
size: 'small',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
secondary: true,
|
secondary: true,
|
||||||
onClick: () => handleBatchAdd([row.id]),
|
onClick: () => handleBatchAdd([row.id]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
default: () => '授权',
|
default: () => '授权',
|
||||||
icon: () => h('i', { class: 'i-line-md:confirm-circle text-14' }),
|
icon: () => h('i', { class: 'i-line-md:confirm-circle text-14' }),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
trigger: ['input', 'blur'],
|
trigger: ['input', 'blur'],
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<n-input v-model:value="modalForm.password" />
|
<n-input v-model:value="modalForm.password" type="password" show-password-on="mousedown" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item v-if="['add', 'setRole'].includes(modalAction)" label="角色" path="roleIds">
|
<n-form-item v-if="['add', 'setRole'].includes(modalAction)" label="角色" path="roleIds">
|
||||||
@@ -112,6 +112,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { MeCrud, MeModal, MeQueryItem } from '@/components'
|
import { MeCrud, MeModal, MeQueryItem } from '@/components'
|
||||||
import { useCrud } from '@/composables'
|
import { useCrud } from '@/composables'
|
||||||
|
import { withPermission } from '@/directives'
|
||||||
import { formatDateTime } from '@/utils'
|
import { formatDateTime } from '@/utils'
|
||||||
import { NAvatar, NButton, NSwitch, NTag } from 'naive-ui'
|
import { NAvatar, NButton, NSwitch, NTag } from 'naive-ui'
|
||||||
import api from './api'
|
import api from './api'
|
||||||
@@ -225,11 +226,23 @@ const columns = [
|
|||||||
hideInExcel: true,
|
hideInExcel: true,
|
||||||
render(row) {
|
render(row) {
|
||||||
return [
|
return [
|
||||||
|
withPermission(
|
||||||
|
h(NButton, {
|
||||||
|
size: 'small',
|
||||||
|
type: 'primary',
|
||||||
|
secondary: true,
|
||||||
|
}, {
|
||||||
|
default: () => '超管专属',
|
||||||
|
icon: () => h('i', { class: 'i-carbon:user-role text-14' }),
|
||||||
|
}),
|
||||||
|
'SuperAdmin',
|
||||||
|
),
|
||||||
h(
|
h(
|
||||||
NButton,
|
NButton,
|
||||||
{
|
{
|
||||||
size: 'small',
|
size: 'small',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
|
class: 'ml-12px',
|
||||||
secondary: true,
|
secondary: true,
|
||||||
onClick: () => handleOpenRolesSet(row),
|
onClick: () => handleOpenRolesSet(row),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -73,10 +73,10 @@
|
|||||||
require-mark-placement="left"
|
require-mark-placement="left"
|
||||||
>
|
>
|
||||||
<n-form-item label="原密码" path="oldPassword" :rule="required">
|
<n-form-item label="原密码" path="oldPassword" :rule="required">
|
||||||
<n-input v-model:value="pwdForm.oldPassword" type="password" placeholder="请输入原密码" />
|
<n-input v-model:value="pwdForm.oldPassword" type="password" placeholder="请输入原密码" show-password-on="mousedown" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="新密码" path="newPassword" :rule="required">
|
<n-form-item label="新密码" path="newPassword" :rule="required">
|
||||||
<n-input v-model:value="pwdForm.newPassword" type="password" placeholder="请输入新密码" />
|
<n-input v-model:value="pwdForm.newPassword" type="password" placeholder="请输入新密码" show-password-on="mousedown" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
</MeModal>
|
</MeModal>
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
|
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
|
||||||
import presetRemToPx from '@unocss/preset-rem-to-px'
|
import presetRemToPx from '@unocss/preset-rem-to-px'
|
||||||
import { defineConfig, presetAttributify, presetIcons, presetUno } from 'unocss'
|
import { defineConfig, presetAttributify, presetIcons, presetWind3 } from 'unocss'
|
||||||
import { getIcons } from './build/index.js'
|
import { getIcons } from './build/index.js'
|
||||||
|
|
||||||
const icons = getIcons()
|
const icons = getIcons()
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
presets: [
|
presets: [
|
||||||
presetUno(),
|
presetWind3(),
|
||||||
presetAttributify(),
|
presetAttributify(),
|
||||||
presetIcons({
|
presetIcons({
|
||||||
warn: true,
|
warn: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user