mirror of
https://github.com/zclzone/vue-naive-admin.git
synced 2026-01-22 23:50:22 +08:00
Compare commits
19 Commits
36ce5c34d0
...
2.x_vxe-ta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a977ec1f3a | ||
|
|
6d1b3a4159 | ||
|
|
6af6eb3c99 | ||
|
|
69e6e9a14a | ||
|
|
d066c999cc | ||
|
|
97fb638ac2 | ||
|
|
db800f60a9 | ||
|
|
304b74bb49 | ||
|
|
359f683955 | ||
|
|
d7a4034c69 | ||
|
|
520db7ec6e | ||
|
|
2264512a8b | ||
|
|
3359b0f2b5 | ||
|
|
615c3b63f7 | ||
|
|
51f2d5d22c | ||
|
|
02e614e903 | ||
|
|
fdb6ad5f1d | ||
|
|
723d141705 | ||
|
|
7b1b990d77 |
@@ -1,63 +0,0 @@
|
|||||||
{
|
|
||||||
"globals": {
|
|
||||||
"$loadingBar": true,
|
|
||||||
"$message": true,
|
|
||||||
"$dialog": true,
|
|
||||||
"$notification": true,
|
|
||||||
"$modal": true,
|
|
||||||
"defineOptions": true,
|
|
||||||
"EffectScope": true,
|
|
||||||
"computed": true,
|
|
||||||
"createApp": true,
|
|
||||||
"customRef": true,
|
|
||||||
"defineAsyncComponent": true,
|
|
||||||
"defineComponent": true,
|
|
||||||
"effectScope": true,
|
|
||||||
"getCurrentInstance": true,
|
|
||||||
"getCurrentScope": true,
|
|
||||||
"h": true,
|
|
||||||
"inject": true,
|
|
||||||
"isProxy": true,
|
|
||||||
"isReactive": true,
|
|
||||||
"isReadonly": true,
|
|
||||||
"isRef": true,
|
|
||||||
"markRaw": true,
|
|
||||||
"nextTick": true,
|
|
||||||
"onActivated": true,
|
|
||||||
"onBeforeMount": true,
|
|
||||||
"onBeforeUnmount": true,
|
|
||||||
"onBeforeUpdate": true,
|
|
||||||
"onDeactivated": true,
|
|
||||||
"onErrorCaptured": true,
|
|
||||||
"onMounted": true,
|
|
||||||
"onRenderTracked": true,
|
|
||||||
"onRenderTriggered": true,
|
|
||||||
"onScopeDispose": true,
|
|
||||||
"onServerPrefetch": true,
|
|
||||||
"onUnmounted": true,
|
|
||||||
"onUpdated": true,
|
|
||||||
"provide": true,
|
|
||||||
"reactive": true,
|
|
||||||
"readonly": true,
|
|
||||||
"ref": true,
|
|
||||||
"resolveComponent": true,
|
|
||||||
"shallowReactive": true,
|
|
||||||
"shallowReadonly": true,
|
|
||||||
"shallowRef": true,
|
|
||||||
"toRaw": true,
|
|
||||||
"toRef": true,
|
|
||||||
"toRefs": true,
|
|
||||||
"triggerRef": true,
|
|
||||||
"unref": true,
|
|
||||||
"useAttrs": true,
|
|
||||||
"useCssModule": true,
|
|
||||||
"useCssVars": true,
|
|
||||||
"useRoute": true,
|
|
||||||
"useRouter": true,
|
|
||||||
"useSlots": true,
|
|
||||||
"watch": true,
|
|
||||||
"watchEffect": true,
|
|
||||||
"watchPostEffect": true,
|
|
||||||
"watchSyncEffect": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
@@ -1,8 +1,4 @@
|
|||||||
{
|
{
|
||||||
// Enable the ESlint flat config support
|
|
||||||
// (remove this if your ESLint extension above v3.0.5)
|
|
||||||
"eslint.experimental.useFlatConfig": true,
|
|
||||||
|
|
||||||
"prettier.enable": false,
|
"prettier.enable": false,
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
|
|
||||||
@@ -24,5 +20,12 @@
|
|||||||
"json",
|
"json",
|
||||||
"jsonc"
|
"jsonc"
|
||||||
],
|
],
|
||||||
"common-intellisense.ui": ["naiveUi2"]
|
"common-intellisense.ui": [
|
||||||
|
"naiveUi2"
|
||||||
|
],
|
||||||
|
"workbench.colorCustomizations": {
|
||||||
|
"activityBar.background": "#233212",
|
||||||
|
"titleBar.activeBackground": "#314619",
|
||||||
|
"titleBar.activeForeground": "#F9FCF6"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ npx degit zclzone/vue-naive-admin
|
|||||||
- [naive-admin-go](https://github.com/ituserxxx/naive-admin-go): 一个 Go 后端服务,基于 gin、gorm、mysql、jwt和session,已对接 Vue Naive Admin 2.0。
|
- [naive-admin-go](https://github.com/ituserxxx/naive-admin-go): 一个 Go 后端服务,基于 gin、gorm、mysql、jwt和session,已对接 Vue Naive Admin 2.0。
|
||||||
- [isme-java](https://github.com/AllenDengMs/isme-java): 一个轻量且完成度高的Java后端服务,基于Springboot 3 + JDK21,层次结构严谨,注释齐全,避免过度封装,代码可读性度高,依赖最简化,上手成本低,已集成 账号管理、权限管理、API鉴权、消息国际化等功能。
|
- [isme-java](https://github.com/AllenDengMs/isme-java): 一个轻量且完成度高的Java后端服务,基于Springboot 3 + JDK21,层次结构严谨,注释齐全,避免过度封装,代码可读性度高,依赖最简化,上手成本低,已集成 账号管理、权限管理、API鉴权、消息国际化等功能。
|
||||||
|
|
||||||
## 入群交流
|
## 联系作者 or 进交流群
|
||||||
|
|
||||||
添加微信,拉你进群
|
[https://www.isme.top/contact.html](https://www.isme.top/contact.html)
|
||||||
|
|
||||||

|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { globSync } from 'glob'
|
import { globSync } from 'glob'
|
||||||
import dynamicIcons from '../src/assets/icons/dynamic-icons'
|
import dynamicIcons from '../src/assets/icons/dynamic-icons.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @usage 生成icons, 用于 unocss safelist,以支持页面动态渲染自定义图标
|
* @usage 生成icons, 用于 unocss safelist,以支持页面动态渲染自定义图标
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
export { pluginPagePathes } from './page-pathes'
|
|
||||||
export { pluginIcons } from './icons'
|
export { pluginIcons } from './icons'
|
||||||
|
export { pluginPagePathes } from './page-pathes'
|
||||||
|
|||||||
55
package.json
55
package.json
@@ -13,41 +13,46 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@arco-design/color": "^0.4.0",
|
"@arco-design/color": "^0.4.0",
|
||||||
"@vueuse/core": "^10.11.0",
|
"@vueuse/core": "^11.1.0",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.7",
|
||||||
"dayjs": "^1.11.12",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
|
"exceljs": "^4.4.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"naive-ui": "^2.39.0",
|
"naive-ui": "^2.40.1",
|
||||||
"pinia": "^2.2.0",
|
"pinia": "^2.2.4",
|
||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
"pinia-plugin-persistedstate": "^4.1.1",
|
||||||
"vue": "^3.4.35",
|
"vue": "^3.5.12",
|
||||||
"vue-echarts": "^6.7.3",
|
"vue-echarts": "^7.0.3",
|
||||||
"vue-router": "^4.4.0",
|
"vue-router": "^4.4.5",
|
||||||
|
"vxe-pc-ui": "4.2.5",
|
||||||
|
"vxe-table": "4.8.13",
|
||||||
|
"vxe-table-plugin-export-xlsx": "^4.0.4",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^2.24.0",
|
"@antfu/eslint-config": "^3.8.0",
|
||||||
"@iconify/json": "^2.2.232",
|
"@iconify/json": "^2.2.262",
|
||||||
"@unocss/eslint-config": "^0.61.8",
|
"@unocss/eslint-config": "^0.63.6",
|
||||||
"@unocss/eslint-plugin": "^0.61.8",
|
"@unocss/eslint-plugin": "^0.63.6",
|
||||||
"@unocss/preset-rem-to-px": "^0.61.8",
|
"@unocss/preset-rem-to-px": "^0.63.6",
|
||||||
"@vitejs/plugin-vue": "^5.1.1",
|
"@vitejs/plugin-vue": "^5.1.4",
|
||||||
"eslint": "^9.8.0",
|
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||||
|
"eslint": "^9.13.0",
|
||||||
"eslint-plugin-format": "^0.1.2",
|
"eslint-plugin-format": "^0.1.2",
|
||||||
"esno": "^4.7.0",
|
"esno": "^4.8.0",
|
||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.2.0",
|
||||||
"lint-staged": "^15.2.7",
|
"glob": "^11.0.0",
|
||||||
|
"lint-staged": "^15.2.10",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"sass": "^1.77.8",
|
|
||||||
"simple-git-hooks": "^2.11.1",
|
"simple-git-hooks": "^2.11.1",
|
||||||
"taze": "^0.16.3",
|
"taze": "^0.17.2",
|
||||||
"unocss": "^0.61.8",
|
"unocss": "^0.63.6",
|
||||||
"unplugin-auto-import": "^0.18.2",
|
"unplugin-auto-import": "^0.18.3",
|
||||||
"unplugin-vue-components": "^0.27.3",
|
"unplugin-vue-components": "^0.27.4",
|
||||||
"vite": "^5.3.5",
|
"vite": "^5.4.9",
|
||||||
"vite-plugin-router-warn": "^1.0.0",
|
"vite-plugin-router-warn": "^1.0.0",
|
||||||
"vite-plugin-vue-devtools": "^7.3.7"
|
"vite-plugin-vue-devtools": "^7.5.2"
|
||||||
},
|
},
|
||||||
"simple-git-hooks": {
|
"simple-git-hooks": {
|
||||||
"pre-commit": "pnpm lint-staged"
|
"pre-commit": "pnpm lint-staged"
|
||||||
|
|||||||
4406
pnpm-lock.yaml
generated
4406
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -16,9 +16,11 @@
|
|||||||
>
|
>
|
||||||
<router-view v-if="Layout" v-slot="{ Component, route: curRoute }">
|
<router-view v-if="Layout" v-slot="{ Component, route: curRoute }">
|
||||||
<component :is="Layout">
|
<component :is="Layout">
|
||||||
|
<transition name="fade-slide" mode="out-in" appear>
|
||||||
<KeepAlive :include="keepAliveNames">
|
<KeepAlive :include="keepAliveNames">
|
||||||
<component :is="Component" v-if="!tabStore.reloading" :key="curRoute.fullPath" />
|
<component :is="Component" v-if="!tabStore.reloading" :key="curRoute.fullPath" />
|
||||||
</KeepAlive>
|
</KeepAlive>
|
||||||
|
</transition>
|
||||||
</component>
|
</component>
|
||||||
|
|
||||||
<LayoutSetting v-if="layoutSettingVisible" class="fixed right-12 top-1/2 z-999" />
|
<LayoutSetting v-if="layoutSettingVisible" class="fixed right-12 top-1/2 z-999" />
|
||||||
@@ -27,10 +29,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { darkTheme, dateZhCN, zhCN } from 'naive-ui'
|
|
||||||
import { layoutSettingVisible } from './settings'
|
|
||||||
import { LayoutSetting } from '@/components'
|
import { LayoutSetting } from '@/components'
|
||||||
import { useAppStore, useTabStore } from '@/store'
|
import { useAppStore, useTabStore } from '@/store'
|
||||||
|
import { darkTheme, dateZhCN, zhCN } from 'naive-ui'
|
||||||
|
import { layoutSettingVisible } from './settings'
|
||||||
|
|
||||||
const layouts = new Map()
|
const layouts = new Map()
|
||||||
function getLayout(name) {
|
function getLayout(name) {
|
||||||
|
|||||||
@@ -8,13 +8,12 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="cus-scroll h-full flex-col flex-1 bg-#f5f6fb dark:bg-#121212">
|
<main class="cus-scroll h-full flex-col flex-1 bg-#f5f6fb dark:bg-#121212">
|
||||||
<transition name="fade-slide" mode="out-in" appear>
|
|
||||||
<main :class="{ 'flex-1': full }" class="m-12">
|
<main :class="{ 'flex-1': full }" class="m-12">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
</transition>
|
<slot name="footer">
|
||||||
<slot v-if="$slots.footer" name="footer" />
|
<TheFooter v-if="showFooter" class="mb-12 mt-auto" />
|
||||||
<TheFooter v-else-if="showFooter" class="mb-12 mt-auto" />
|
</slot>
|
||||||
<n-back-top :bottom="20" />
|
<n-back-top :bottom="20" />
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
--------------------------------->
|
--------------------------------->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-full flex-1 overflow-hidden bg-#f5f6fb dark:bg-#121212">
|
<main class="h-full flex-col flex-1 overflow-hidden bg-#f5f6fb dark:bg-#121212">
|
||||||
<div class="h-full flex-col">
|
|
||||||
<AppCard
|
<AppCard
|
||||||
v-if="showHeader"
|
v-if="showHeader"
|
||||||
class="sticky top-0 z-1 min-h-60 flex items-center justify-between px-24"
|
class="sticky top-0 z-1 min-h-60 flex items-center justify-between px-24"
|
||||||
@@ -17,8 +16,8 @@
|
|||||||
<slot v-if="$slots.header" name="header" />
|
<slot v-if="$slots.header" name="header" />
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<slot v-if="$slots['title-prefix']" name="title-prefix" />
|
<slot name="title-prefix">
|
||||||
<template v-else-if="back">
|
<template v-if="back">
|
||||||
<div
|
<div
|
||||||
class="mr-16 flex cursor-pointer items-center text-16 opacity-60 transition-all-300 hover:opacity-40"
|
class="mr-16 flex cursor-pointer items-center text-16 opacity-60 transition-all-300 hover:opacity-40"
|
||||||
@click="router.back()"
|
@click="router.back()"
|
||||||
@@ -27,6 +26,8 @@
|
|||||||
<span class="ml-4">返回</span>
|
<span class="ml-4">返回</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
</slot>
|
||||||
|
|
||||||
<div class="mr-12 h-16 w-4 rounded-l-2 bg-primary" />
|
<div class="mr-12 h-16 w-4 rounded-l-2 bg-primary" />
|
||||||
<h2 class="font-normal">
|
<h2 class="font-normal">
|
||||||
{{ title ?? route.meta?.title }}
|
{{ title ?? route.meta?.title }}
|
||||||
@@ -36,20 +37,16 @@
|
|||||||
<slot name="action" />
|
<slot name="action" />
|
||||||
</template>
|
</template>
|
||||||
</AppCard>
|
</AppCard>
|
||||||
<transition name="fade-slide" mode="out-in" appear>
|
|
||||||
<AppCard class="cus-scroll m-12 h-0 flex-1 rounded-8 p-24" bordered>
|
<AppCard class="cus-scroll m-12 h-0 flex-1 rounded-8 p-24" bordered>
|
||||||
<slot />
|
<slot />
|
||||||
</AppCard>
|
</AppCard>
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer class="bg-#f5f6fb dark:bg-#121212">
|
<slot name="footer">
|
||||||
<slot v-if="$slots.footer" name="footer" />
|
<AppCard v-if="showFooter" class="flex-shrink-0 py-12">
|
||||||
<AppCard v-else-if="showFooter" class="py-12">
|
|
||||||
<TheFooter />
|
<TheFooter />
|
||||||
</AppCard>
|
</AppCard>
|
||||||
</footer>
|
</slot>
|
||||||
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -94,8 +94,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { MeModal } from '@/components'
|
import { MeModal } from '@/components'
|
||||||
import { useAppStore } from '@/store'
|
|
||||||
import { useModal } from '@/composables'
|
import { useModal } from '@/composables'
|
||||||
|
import { useAppStore } from '@/store'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const [modalRef] = useModal()
|
const [modalRef] = useModal()
|
||||||
|
|||||||
240
src/components/common/MeVxeGrid.vue
Normal file
240
src/components/common/MeVxeGrid.vue
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:style="isComputedHeight ? `height: calc(100% - ${autoHeight}px);` : `height: ${autoHeight}px`"
|
||||||
|
>
|
||||||
|
<vxe-grid
|
||||||
|
ref="gridRef"
|
||||||
|
:columns="vxeColumns"
|
||||||
|
:loading="loading"
|
||||||
|
:data="data"
|
||||||
|
height="auto"
|
||||||
|
:stripe="true"
|
||||||
|
:border="true"
|
||||||
|
size="mini"
|
||||||
|
:auto-resize="true"
|
||||||
|
:pager-config="pagerConfig"
|
||||||
|
:export-config="exportConfig"
|
||||||
|
:toolbar-config="vxeToolbarConfig"
|
||||||
|
:proxy-config="proxyConfig"
|
||||||
|
v-on="gridEvent"
|
||||||
|
>
|
||||||
|
<template #loading>
|
||||||
|
<n-spin :show="loading" />
|
||||||
|
</template>
|
||||||
|
<template #total>
|
||||||
|
<span class="font-size-14 line-height-28px">共 {{ pagerConfig.total }} 条数据</span>
|
||||||
|
</template>
|
||||||
|
<template v-for="(c, k) in slots" :key="k" #[c.key]="{ row }">
|
||||||
|
<template v-if="Array.isArray(c.render(row))">
|
||||||
|
<component :is="r" v-for="(r, k1) in c.render(row)" :key="k1" :row="row" :col="c" />
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<component :is="c.render(row)" :row="row" :col="c" />
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</vxe-grid>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
defineOptions({ name: 'MeVxeGrid' })
|
||||||
|
const props = defineProps({
|
||||||
|
/**
|
||||||
|
* @remote 当isComputedHeight为true时为除table外的高度 false时为table高度
|
||||||
|
*/
|
||||||
|
autoHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 300,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @isPagination 是否为自动计算高度
|
||||||
|
*/
|
||||||
|
isComputedHeight: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @remote table的列
|
||||||
|
*/
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
|
pagination: {
|
||||||
|
type: [Boolean, Object],
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
exportConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({ }),
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 是否显示复选框
|
||||||
|
*/
|
||||||
|
showCheck: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
rowKey: {
|
||||||
|
type: String, // rowKey
|
||||||
|
default: 'id',
|
||||||
|
},
|
||||||
|
|
||||||
|
exportMethod: {
|
||||||
|
type: Function,
|
||||||
|
default: () => null,
|
||||||
|
},
|
||||||
|
remoteMethod: {
|
||||||
|
type: Function,
|
||||||
|
default: () => null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const emits = defineEmits(['update:checked-row-keys', 'pageChanged'])
|
||||||
|
const isFirst = shallowRef(true)
|
||||||
|
const gridRef = ref(null)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
(n) => {
|
||||||
|
isFirst.value = false
|
||||||
|
gridRef.value.reloadData(n)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const vxeToolbarConfig = computed(() => {
|
||||||
|
return {
|
||||||
|
size: 'mini',
|
||||||
|
className: 'c-toolbar',
|
||||||
|
perfect: true,
|
||||||
|
refresh: true,
|
||||||
|
export: true,
|
||||||
|
zoom: true,
|
||||||
|
custom: true,
|
||||||
|
...props.toolbarConfig,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const pagerConfig = computed(() => {
|
||||||
|
if (props.pagination === false) {
|
||||||
|
return {
|
||||||
|
enabled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
currentPage: props.pagination.pageNo,
|
||||||
|
pageSize: props.pagination.pageSize,
|
||||||
|
total: props.pagination.itemCount || 0,
|
||||||
|
background: true,
|
||||||
|
size: 'small',
|
||||||
|
layouts: [
|
||||||
|
'Home',
|
||||||
|
'PrevPage',
|
||||||
|
'JumpNumber',
|
||||||
|
'NextPage',
|
||||||
|
'End',
|
||||||
|
'Sizes',
|
||||||
|
'FullJump',
|
||||||
|
// 'Total',
|
||||||
|
],
|
||||||
|
slots: {
|
||||||
|
right: 'total',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* 将naive 转为vxe-table可用的列
|
||||||
|
*/
|
||||||
|
const vxeColumns = computed(() => {
|
||||||
|
if (props.showCheck) {
|
||||||
|
return [{
|
||||||
|
type: 'checkbox',
|
||||||
|
resizable: false,
|
||||||
|
width: 45,
|
||||||
|
align: 'center',
|
||||||
|
fixed: 'left',
|
||||||
|
}, ...props.columns.map((item) => {
|
||||||
|
item.field = item.key
|
||||||
|
if (item.render) {
|
||||||
|
item.slots = { default: item.key }
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})]
|
||||||
|
}
|
||||||
|
return props.columns.map((item) => {
|
||||||
|
item.field = item.key
|
||||||
|
if (item.render) {
|
||||||
|
item.slots = { default: item.key }
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将naive render函数转换为vxeTable的slots
|
||||||
|
*/
|
||||||
|
const slots = computed(() => {
|
||||||
|
return props.columns.filter(item => item.render)
|
||||||
|
})
|
||||||
|
|
||||||
|
const gridEvent = {
|
||||||
|
checkboxAll() {
|
||||||
|
const $grid = gridRef.value
|
||||||
|
if ($grid) {
|
||||||
|
emits(
|
||||||
|
'update:checked-row-keys',
|
||||||
|
$grid.getCheckboxRecords().map(item => item[props.rowKey]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
checkboxChange() {
|
||||||
|
const $grid = gridRef.value
|
||||||
|
if ($grid) {
|
||||||
|
emits(
|
||||||
|
'update:checked-row-keys',
|
||||||
|
$grid.getCheckboxRecords().map(item => item[props.rowKey]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pageChange(e) {
|
||||||
|
emits('pageChanged', e)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxyConfig = {
|
||||||
|
props: {
|
||||||
|
result: 'data.pageData',
|
||||||
|
total: 'data.total',
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }) => {
|
||||||
|
if (isFirst.value === true) {
|
||||||
|
return Promise.reject('')
|
||||||
|
}
|
||||||
|
props.remoteMethod(page.currentPage, page.pageSize)
|
||||||
|
},
|
||||||
|
queryAll: async () => {
|
||||||
|
const res = await props.exportMethod()
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
- Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
- Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
--------------------------------->
|
--------------------------------->
|
||||||
<template>
|
<template>
|
||||||
<div class="h-40 w-40 rounded-4 bg-primary p-1/100">
|
<div class="h-32 w-32 rounded-4 bg-primary">
|
||||||
<img src="@/assets/images/isme.png" alt="Logo">
|
<img src="@/assets/images/isme.png" alt="Logo">
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getPresetColors } from '@arco-design/color'
|
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
import { getPresetColors } from '@arco-design/color'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useDark, useToggle } from '@vueuse/core'
|
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
import { useDark, useToggle } from '@vueuse/core'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const isDark = useDark()
|
const isDark = useDark()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export { default as AppCard } from './AppCard.vue'
|
export { default as AppCard } from './AppCard.vue'
|
||||||
export { default as TheFooter } from './TheFooter.vue'
|
|
||||||
export { default as AppPage } from './AppPage.vue'
|
export { default as AppPage } from './AppPage.vue'
|
||||||
export { default as CommonPage } from './CommonPage.vue'
|
export { default as CommonPage } from './CommonPage.vue'
|
||||||
export { default as LayoutSetting } from './LayoutSetting.vue'
|
export { default as LayoutSetting } from './LayoutSetting.vue'
|
||||||
|
export { default as MeVxeGrid } from './MeVxeGrid.vue'
|
||||||
|
export { default as TheFooter } from './TheFooter.vue'
|
||||||
export { default as ToggleTheme } from './ToggleTheme.vue'
|
export { default as ToggleTheme } from './ToggleTheme.vue'
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
--------------------------------->
|
--------------------------------->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div :class="computedHeight === true ? 'h-100%' : ''">
|
||||||
|
<div id="search_main">
|
||||||
<AppCard v-if="$slots.default" bordered bg="#fafafc dark:black" class="mb-30 min-h-60 rounded-4">
|
<AppCard v-if="$slots.default" bordered bg="#fafafc dark:black" class="mb-30 min-h-60 rounded-4">
|
||||||
<form class="flex justify-between p-16" @submit.prevent="handleSearch()">
|
<form class="flex justify-between p-16" @submit.prevent="handleSearch()">
|
||||||
<n-scrollbar x-scrollable>
|
<n-scrollbar x-scrollable>
|
||||||
@@ -37,8 +39,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</AppCard>
|
</AppCard>
|
||||||
|
</div>
|
||||||
|
<MeVxeGrid
|
||||||
|
:remote="remote"
|
||||||
|
:loading="loading"
|
||||||
|
:scroll-x="scrollX"
|
||||||
|
:columns="columns"
|
||||||
|
:export-config="{ filename: exportName, modes: ['all', 'current'] }"
|
||||||
|
:toolbar-config="toolbarConfig"
|
||||||
|
:data="tableData"
|
||||||
|
:auto-height="computedHeight === true ? autoHeight : computedHeight"
|
||||||
|
:row-key="rowKey"
|
||||||
|
:is-computed-height="computedHeight === true"
|
||||||
|
:show-check="showCheck"
|
||||||
|
:pagination="isPagination ? pagination : false"
|
||||||
|
:remote-method="remoteMethod"
|
||||||
|
:export-method="exportMethod"
|
||||||
|
@update:checked-row-keys="onChecked"
|
||||||
|
@update:page="onPageChange"
|
||||||
|
/>
|
||||||
|
|
||||||
<NDataTable
|
<!-- <NDataTable
|
||||||
:remote="remote"
|
:remote="remote"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:scroll-x="scrollX"
|
:scroll-x="scrollX"
|
||||||
@@ -48,14 +69,39 @@
|
|||||||
:pagination="isPagination ? pagination : false"
|
:pagination="isPagination ? pagination : false"
|
||||||
@update:checked-row-keys="onChecked"
|
@update:checked-row-keys="onChecked"
|
||||||
@update:page="onPageChange"
|
@update:page="onPageChange"
|
||||||
/>
|
/> -->
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { NDataTable } from 'naive-ui'
|
|
||||||
import { utils, writeFile } from 'xlsx'
|
import { utils, writeFile } from 'xlsx'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
/**
|
||||||
|
* 是否自动计算高度,适用只有search和table
|
||||||
|
*/
|
||||||
|
computedHeight: {
|
||||||
|
type: [Boolean, Number],
|
||||||
|
default: () => true,
|
||||||
|
},
|
||||||
|
showCheck: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => false,
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
export: true,
|
||||||
|
zoom: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @remote 导出数据表格名称
|
||||||
|
*/
|
||||||
|
exportName: {
|
||||||
|
type: String,
|
||||||
|
default: '导出数据',
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @remote true: 后端分页 false: 前端分页
|
* @remote true: 后端分页 false: 前端分页
|
||||||
*/
|
*/
|
||||||
@@ -105,8 +151,18 @@ const props = defineProps({
|
|||||||
/** 是否支持展开 */
|
/** 是否支持展开 */
|
||||||
expand: Boolean,
|
expand: Boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:queryItems', 'onChecked', 'onDataChange'])
|
const emit = defineEmits(['update:queryItems', 'onChecked', 'onDataChange'])
|
||||||
|
|
||||||
|
const autoHeight = ref(0)
|
||||||
|
|
||||||
|
window.onresize = () => {
|
||||||
|
autoHeight.value = document.getElementById('search_main').clientHeight + 24
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
autoHeight.value = document.getElementById('search_main').clientHeight + 24
|
||||||
|
})
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const initQuery = { ...props.queryItems }
|
const initQuery = { ...props.queryItems }
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
@@ -125,6 +181,22 @@ function toggleExpand() {
|
|||||||
isExpanded.value = !isExpanded.value
|
isExpanded.value = !isExpanded.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function exportMethod() {
|
||||||
|
const { data } = await props.getData({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 2000,
|
||||||
|
...props.queryItems,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
function remoteMethod(page, pageSize) {
|
||||||
|
pagination.page = page
|
||||||
|
pagination.pageSize = pageSize
|
||||||
|
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
async function handleQuery() {
|
async function handleQuery() {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -143,6 +215,7 @@ async function handleQuery() {
|
|||||||
// 如果当前页数据为空,且总条数不为0,则返回上一页数据
|
// 如果当前页数据为空,且总条数不为0,则返回上一页数据
|
||||||
onPageChange(pagination.page - 1)
|
onPageChange(pagination.page - 1)
|
||||||
}
|
}
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@@ -156,7 +229,7 @@ async function handleQuery() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleSearch(keepCurrentPage = false) {
|
function handleSearch(keepCurrentPage = false) {
|
||||||
if (keepCurrentPage) {
|
if (keepCurrentPage || !props.remote) {
|
||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -180,9 +253,7 @@ function onPageChange(currentPage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function onChecked(rowKeys) {
|
function onChecked(rowKeys) {
|
||||||
if (props.columns.some(item => item.type === 'selection')) {
|
|
||||||
emit('onChecked', rowKeys)
|
emit('onChecked', rowKeys)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function handleExport(columns = props.columns, data = tableData.value) {
|
function handleExport(columns = props.columns, data = tableData.value) {
|
||||||
if (!data?.length)
|
if (!data?.length)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export { default as MeModal } from './modal/index.vue'
|
|
||||||
export { default as MeCrud } from './crud/index.vue'
|
export { default as MeCrud } from './crud/index.vue'
|
||||||
export { default as MeQueryItem } from './crud/QueryItem.vue'
|
export { default as MeQueryItem } from './crud/QueryItem.vue'
|
||||||
|
export { default as MeModal } from './modal/index.vue'
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
<!-- 底部按钮 -->
|
<!-- 底部按钮 -->
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<slot v-if="$slots.footer" name="footer" />
|
<slot name="footer">
|
||||||
<footer v-else-if="modalOptions.showFooter" class="flex justify-end">
|
<footer v-if="modalOptions.showFooter" class="flex justify-end">
|
||||||
<n-button v-if="modalOptions.showCancel" @click="handleCancel()">
|
<n-button v-if="modalOptions.showCancel" @click="handleCancel()">
|
||||||
{{ modalOptions.cancelText }}
|
{{ modalOptions.cancelText }}
|
||||||
</n-button>
|
</n-button>
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
{{ modalOptions.okText }}
|
{{ modalOptions.okText }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</footer>
|
</footer>
|
||||||
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
export * from './useAliveData'
|
||||||
export * from './useCrud'
|
export * from './useCrud'
|
||||||
export * from './useForm'
|
export * from './useForm'
|
||||||
export * from './useModal'
|
export * from './useModal'
|
||||||
export * from './useAliveData'
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function handleMenuSelect(key, item) {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style>
|
||||||
.side-menu:not(.n-menu--collapsed) {
|
.side-menu:not(.n-menu--collapsed) {
|
||||||
.n-menu-item-content {
|
.n-menu-item-content {
|
||||||
&::before {
|
&::before {
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useAuthStore, usePermissionStore, useUserStore } from '@/store'
|
|
||||||
import { RoleSelect } from '@/layouts/components'
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { RoleSelect } from '@/layouts/components'
|
||||||
|
import { useAuthStore, usePermissionStore, useUserStore } from '@/store'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
export { default as RoleSelect } from './RoleSelect.vue'
|
|
||||||
export { default as UserAvatar } from './UserAvatar.vue'
|
|
||||||
export { default as MenuCollapse } from './MenuCollapse.vue'
|
|
||||||
export { default as BreadCrumb } from './BreadCrumb.vue'
|
export { default as BreadCrumb } from './BreadCrumb.vue'
|
||||||
export { default as AppTab } from './tab/index.vue'
|
export { default as Fullscreen } from './Fullscreen.vue'
|
||||||
|
export { default as MenuCollapse } from './MenuCollapse.vue'
|
||||||
|
export { default as RoleSelect } from './RoleSelect.vue'
|
||||||
export { default as SideLogo } from './SideLogo.vue'
|
export { default as SideLogo } from './SideLogo.vue'
|
||||||
export { default as SideMenu } from './SideMenu.vue'
|
export { default as SideMenu } from './SideMenu.vue'
|
||||||
export { default as Fullscreen } from './Fullscreen.vue'
|
export { default as AppTab } from './tab/index.vue'
|
||||||
|
export { default as UserAvatar } from './UserAvatar.vue'
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import ContextMenu from './ContextMenu.vue'
|
|
||||||
import { useTabStore } from '@/store'
|
import { useTabStore } from '@/store'
|
||||||
|
import ContextMenu from './ContextMenu.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const tabStore = useTabStore()
|
const tabStore = useTabStore()
|
||||||
@@ -74,7 +74,7 @@ async function handleContextMenu(e, tagItem) {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped>
|
||||||
:deep(.n-tabs) {
|
:deep(.n-tabs) {
|
||||||
.n-tabs-tab {
|
.n-tabs-tab {
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import SideBar from './sidebar/index.vue'
|
|
||||||
import AppHeader from './header/index.vue'
|
|
||||||
import { useAppStore } from '@/store'
|
|
||||||
import { AppTab } from '@/layouts/components'
|
import { AppTab } from '@/layouts/components'
|
||||||
|
import { useAppStore } from '@/store'
|
||||||
|
import AppHeader from './header/index.vue'
|
||||||
|
import SideBar from './sidebar/index.vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import SideBar from './sidebar/index.vue'
|
|
||||||
import AppHeader from './header/index.vue'
|
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
import AppHeader from './header/index.vue'
|
||||||
|
import SideBar from './sidebar/index.vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import SideBar from './sidebar/index.vue'
|
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
import SideBar from './sidebar/index.vue'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
26
src/main.js
26
src/main.js
@@ -8,19 +8,35 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import '@/styles/reset.css'
|
import ExcelJS from 'exceljs'
|
||||||
import '@/styles/global.scss'
|
|
||||||
import 'uno.css'
|
|
||||||
|
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
|
||||||
|
import { setupDirectives } from './directives'
|
||||||
|
/**
|
||||||
|
* 引入vxe-table 和 vxe-pc-ui excel导出
|
||||||
|
*/
|
||||||
|
import VxeUI from 'vxe-pc-ui'
|
||||||
|
import VXETable from 'vxe-table'
|
||||||
|
import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx'
|
||||||
import { setupRouter } from './router'
|
import { setupRouter } from './router'
|
||||||
import { setupStore } from './store'
|
import { setupStore } from './store'
|
||||||
|
|
||||||
import { setupNaiveDiscreteApi } from './utils'
|
import { setupNaiveDiscreteApi } from './utils'
|
||||||
import { setupDirectives } from './directives'
|
import 'vxe-pc-ui/lib/style.css'
|
||||||
|
import 'vxe-table/lib/style.css'
|
||||||
|
import '@/styles/reset.css'
|
||||||
|
import '@/styles/global.css'
|
||||||
|
import 'uno.css'
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
|
VXETable.use(VXETablePluginExportXLSX, {
|
||||||
|
ExcelJS,
|
||||||
|
})
|
||||||
|
app.use(VxeUI).use(VXETable)
|
||||||
|
|
||||||
setupStore(app)
|
setupStore(app)
|
||||||
setupDirectives(app)
|
setupDirectives(app)
|
||||||
await setupRouter(app)
|
await setupRouter(app)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { useAuthStore, usePermissionStore, useUserStore } from '@/store'
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { useAuthStore, usePermissionStore, useUserStore } from '@/store'
|
||||||
import { getPermissions, getUserInfo } from '@/store/helper'
|
import { getPermissions, getUserInfo } from '@/store/helper'
|
||||||
|
|
||||||
const WHITE_LIST = ['/login', '/404']
|
const WHITE_LIST = ['/login', '/404']
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
||||||
import { setupRouterGuards } from './guards'
|
|
||||||
import { basicRoutes } from './basic-routes'
|
import { basicRoutes } from './basic-routes'
|
||||||
|
import { setupRouterGuards } from './guards'
|
||||||
|
|
||||||
export const router = createRouter({
|
export const router = createRouter({
|
||||||
history:
|
history:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { basePermissions } from '@/settings'
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { basePermissions } from '@/settings'
|
||||||
|
|
||||||
export async function getUserInfo() {
|
export async function getUserInfo() {
|
||||||
const res = await api.getUser()
|
const res = await api.getUser()
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { defineStore } from 'pinia'
|
|
||||||
import { useDark } from '@vueuse/core'
|
|
||||||
import { generate, getRgbStr } from '@arco-design/color'
|
|
||||||
import { defaultLayout, defaultPrimaryColor, naiveThemeOverrides } from '@/settings'
|
import { defaultLayout, defaultPrimaryColor, naiveThemeOverrides } from '@/settings'
|
||||||
|
import { generate, getRgbStr } from '@arco-design/color'
|
||||||
|
import { useDark } from '@vueuse/core'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { VxeUI } from 'vxe-pc-ui'
|
||||||
|
|
||||||
export const useAppStore = defineStore('app', {
|
export const useAppStore = defineStore('app', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -40,6 +41,18 @@ export const useAppStore = defineStore('app', {
|
|||||||
list: true,
|
list: true,
|
||||||
dark: isDark,
|
dark: isDark,
|
||||||
})
|
})
|
||||||
|
VxeUI.setTheme(isDark ? 'dark' : 'light')
|
||||||
|
if (isDark) {
|
||||||
|
document.body.style.setProperty('--vxe-ui-font-color', '#fff')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.body.style.setProperty('--vxe-ui-font-color', '#000')
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.style.setProperty('--vxe-ui-font-primary-color', color)
|
||||||
|
document.body.style.setProperty('--vxe-ui-font-primary-lighten-color', color)
|
||||||
|
document.body.style.setProperty('--vxe-ui-font-primary-darken-color', color)
|
||||||
|
|
||||||
document.body.style.setProperty('--primary-color', getRgbStr(colors[5]))
|
document.body.style.setProperty('--primary-color', getRgbStr(colors[5]))
|
||||||
this.naiveThemeOverrides.common = Object.assign(this.naiveThemeOverrides.common || {}, {
|
this.naiveThemeOverrides.common = Object.assign(this.naiveThemeOverrides.common || {}, {
|
||||||
primaryColor: colors[5],
|
primaryColor: colors[5],
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { defineStore } from 'pinia'
|
|
||||||
import { usePermissionStore, useRouterStore, useTabStore, useUserStore } from '@/store'
|
import { usePermissionStore, useRouterStore, useTabStore, useUserStore } from '@/store'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
export const useAuthStore = defineStore('auth', {
|
export const useAuthStore = defineStore('auth', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * from './app'
|
export * from './app'
|
||||||
export * from './auth'
|
export * from './auth'
|
||||||
export * from './permission'
|
export * from './permission'
|
||||||
|
export * from './router'
|
||||||
export * from './tab'
|
export * from './tab'
|
||||||
export * from './user'
|
export * from './user'
|
||||||
export * from './router'
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
import { isExternal } from '@/utils'
|
||||||
import { hyphenate } from '@vueuse/core'
|
import { hyphenate } from '@vueuse/core'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { isExternal } from '@/utils'
|
|
||||||
|
|
||||||
export const usePermissionStore = defineStore('permission', {
|
export const usePermissionStore = defineStore('permission', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ body {
|
|||||||
|
|
||||||
.fade-slide-enter-from {
|
.fade-slide-enter-from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(-30px);
|
transform: translateX(-2%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-slide-leave-to {
|
.fade-slide-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(30px);
|
transform: translateX(2%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自定义滚动条样式 */
|
/* 自定义滚动条样式 */
|
||||||
@@ -1,49 +1,388 @@
|
|||||||
/**********************************
|
/*
|
||||||
* @Author: Ronnie Zhang
|
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
||||||
* @LastEditor: Ronnie Zhang
|
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
||||||
* @LastEditTime: 2023/12/05 21:26:38
|
2. [UnoCSS]: allow to override the default border color with css var `--un-default-border-color`
|
||||||
* @Email: zclzone@outlook.com
|
*/
|
||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
|
||||||
**********************************/
|
|
||||||
|
|
||||||
html {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
*,
|
||||||
::before,
|
::before,
|
||||||
::after {
|
::after {
|
||||||
margin: 0;
|
box-sizing: border-box; /* 1 */
|
||||||
padding: 0;
|
border-width: 0; /* 2 */
|
||||||
box-sizing: inherit;
|
border-style: solid; /* 2 */
|
||||||
|
border-color: var(--un-default-border-color, #e5e7eb); /* 2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::before,
|
||||||
|
::after {
|
||||||
|
--un-content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Use a consistent sensible line-height in all browsers.
|
||||||
|
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||||
|
3. Use a more readable tab size.
|
||||||
|
4. Use the user's configured `sans` font-family by default.
|
||||||
|
5. Use the user's configured `sans` font-feature-settings by default.
|
||||||
|
6. Use the user's configured `sans` font-variation-settings by default.
|
||||||
|
7. Disable tap highlights on iOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html,
|
||||||
|
:host {
|
||||||
|
line-height: 1.5; /* 1 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
-moz-tab-size: 4; /* 3 */
|
||||||
|
tab-size: 4; /* 3 */
|
||||||
|
font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||||
|
'Noto Color Emoji'; /* 4 */
|
||||||
|
font-feature-settings: normal; /* 5 */
|
||||||
|
font-variation-settings: normal; /* 6 */
|
||||||
|
-webkit-tap-highlight-color: transparent; /* 7 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Remove the margin in all browsers.
|
||||||
|
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0; /* 1 */
|
||||||
|
line-height: inherit; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Add the correct height in Firefox.
|
||||||
|
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||||
|
3. Ensure horizontal rules are visible by default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: 0; /* 1 */
|
||||||
|
color: inherit; /* 2 */
|
||||||
|
border-top-width: 1px; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr:where([title]) {
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove the default font size and weight for headings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reset links to optimize for opt-in styling instead of opt-out.
|
||||||
|
*/
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
text-decoration: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover,
|
/*
|
||||||
a:link,
|
Add the correct font weight in Edge and Safari.
|
||||||
a:visited,
|
*/
|
||||||
a:active {
|
|
||||||
text-decoration: none;
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Use the user's configured `mono` font-family by default.
|
||||||
|
2. Use the user's configured `mono` font-feature-settings by default.
|
||||||
|
3. Use the user's configured `mono` font-variation-settings by default.
|
||||||
|
4. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp,
|
||||||
|
pre {
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; /* 1 */
|
||||||
|
font-feature-settings: normal; /* 2 */
|
||||||
|
font-variation-settings: normal; /* 3 */
|
||||||
|
font-size: 1em; /* 4 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add the correct font size in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||||
|
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||||
|
3. Remove gaps between table borders by default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
table {
|
||||||
|
text-indent: 0; /* 1 */
|
||||||
|
border-color: inherit; /* 2 */
|
||||||
|
border-collapse: collapse; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Change the font styles in all browsers.
|
||||||
|
2. Remove the margin in Firefox and Safari.
|
||||||
|
3. Remove default padding in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: inherit; /* 1 */
|
||||||
|
font-feature-settings: inherit; /* 1 */
|
||||||
|
font-variation-settings: inherit; /* 1 */
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
font-weight: inherit; /* 1 */
|
||||||
|
line-height: inherit; /* 1 */
|
||||||
|
color: inherit; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
padding: 0; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove the inheritance of text transform in Edge and Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
2. Remove default button styles.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type='button'],
|
||||||
|
[type='reset'],
|
||||||
|
[type='submit'] {
|
||||||
|
-webkit-appearance: button; /* 1 */
|
||||||
|
/* background-color: transparent; */
|
||||||
|
background-image: none; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use the modern Firefox focus style for all focusable elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:-moz-focusring {
|
||||||
|
outline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||||
|
*/
|
||||||
|
|
||||||
|
:-moz-ui-invalid {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add the correct vertical alignment in Chrome and Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Correct the cursor style of increment and decrement buttons in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::-webkit-inner-spin-button,
|
||||||
|
::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Correct the odd appearance in Chrome and Safari.
|
||||||
|
2. Correct the outline style in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type='search'] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
outline-offset: -2px; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove the inner padding in Chrome and Safari on macOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
2. Change font properties to `inherit` in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add the correct display in Chrome and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Removes the default spacing for appropriate elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
blockquote,
|
||||||
|
dl,
|
||||||
|
dd,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
hr,
|
||||||
|
figure,
|
||||||
|
p,
|
||||||
|
pre {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul {
|
ul,
|
||||||
|
menu {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
dialog {
|
||||||
textarea {
|
padding: 0;
|
||||||
outline: none;
|
|
||||||
border: none;
|
|
||||||
resize: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Prevent resizing textareas horizontally by default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||||
|
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input::placeholder,
|
||||||
|
textarea::placeholder {
|
||||||
|
opacity: 1; /* 1 */
|
||||||
|
color: #9ca3af; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the default cursor for buttons.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
[role='button'] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make sure disabled buttons don't get the pointer cursor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:disabled {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||||
|
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||||
|
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||||
|
*/
|
||||||
|
|
||||||
|
img,
|
||||||
|
svg,
|
||||||
|
video,
|
||||||
|
canvas,
|
||||||
|
audio,
|
||||||
|
iframe,
|
||||||
|
embed,
|
||||||
|
object {
|
||||||
|
display: block; /* 1 */
|
||||||
|
vertical-align: middle; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||||
|
*/
|
||||||
|
|
||||||
img,
|
img,
|
||||||
video {
|
video {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make elements with the HTML hidden attribute stay hidden by default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,29 +7,10 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { resolveResError } from './helpers'
|
|
||||||
import { useAuthStore } from '@/store'
|
import { useAuthStore } from '@/store'
|
||||||
|
import { resolveResError } from './helpers'
|
||||||
|
|
||||||
export function setupInterceptors(axiosInstance) {
|
export function setupInterceptors(axiosInstance) {
|
||||||
function reqResolve(config) {
|
|
||||||
// 处理不需要token的请求
|
|
||||||
if (config.needToken === false) {
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
const { accessToken } = useAuthStore()
|
|
||||||
if (accessToken) {
|
|
||||||
// token: Bearer + xxx
|
|
||||||
config.headers.Authorization = `Bearer ${accessToken}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
function reqReject(error) {
|
|
||||||
return Promise.reject(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
const SUCCESS_CODES = [0, 200]
|
const SUCCESS_CODES = [0, 200]
|
||||||
function resResolve(response) {
|
function resResolve(response) {
|
||||||
const { data, status, config, statusText, headers } = response
|
const { data, status, config, statusText, headers } = response
|
||||||
@@ -49,7 +30,30 @@ export function setupInterceptors(axiosInstance) {
|
|||||||
return Promise.resolve(data ?? response)
|
return Promise.resolve(data ?? response)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resReject(error) {
|
axiosInstance.interceptors.request.use(reqResolve, reqReject)
|
||||||
|
axiosInstance.interceptors.response.use(resResolve, resReject)
|
||||||
|
}
|
||||||
|
|
||||||
|
function reqResolve(config) {
|
||||||
|
// 处理不需要token的请求
|
||||||
|
if (config.needToken === false) {
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
const { accessToken } = useAuthStore()
|
||||||
|
if (accessToken) {
|
||||||
|
// token: Bearer + xxx
|
||||||
|
config.headers.Authorization = `Bearer ${accessToken}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
function reqReject(error) {
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function resReject(error) {
|
||||||
if (!error || !error.response) {
|
if (!error || !error.response) {
|
||||||
const code = error?.code
|
const code = error?.code
|
||||||
/** 根据code处理对应的操作,并返回处理后的message */
|
/** 根据code处理对应的操作,并返回处理后的message */
|
||||||
@@ -63,8 +67,4 @@ export function setupInterceptors(axiosInstance) {
|
|||||||
const needTip = config?.needTip !== false
|
const needTip = config?.needTip !== false
|
||||||
const message = resolveResError(code, data?.message ?? error.message, needTip)
|
const message = resolveResError(code, data?.message ?? error.message, needTip)
|
||||||
return Promise.reject({ code, message, error: error.response?.data || error.response })
|
return Promise.reject({ code, message, error: error.response?.data || error.response })
|
||||||
}
|
|
||||||
|
|
||||||
axiosInstance.interceptors.request.use(reqResolve, reqReject)
|
|
||||||
axiosInstance.interceptors.response.use(resResolve, resReject)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import * as NaiveUI from 'naive-ui'
|
|
||||||
import { isNullOrUndef } from '@/utils'
|
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
import { isNullOrUndef } from '@/utils'
|
||||||
|
import * as NaiveUI from 'naive-ui'
|
||||||
|
|
||||||
export function setupMessage(NMessage) {
|
export function setupMessage(NMessage) {
|
||||||
class Message {
|
class Message {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { MeModal } from '@/components'
|
import { MeModal } from '@/components'
|
||||||
import { sleep } from '@/utils'
|
|
||||||
import { useModal } from '@/composables'
|
import { useModal } from '@/composables'
|
||||||
|
import { sleep } from '@/utils'
|
||||||
|
|
||||||
const text = ref('')
|
const text = ref('')
|
||||||
const [$modal1, okLoading1] = useModal()
|
const [$modal1, okLoading1] = useModal()
|
||||||
|
|||||||
@@ -63,10 +63,9 @@ defineOptions({ name: 'ImgUpload' })
|
|||||||
const { copy, copied } = useClipboard()
|
const { copy, copied } = useClipboard()
|
||||||
|
|
||||||
const imgList = reactive([
|
const imgList = reactive([
|
||||||
{ url: 'https://cdn.isme.top/images/5c23d52f880511ebb6edd017c2d2eca2.jpg' },
|
{ url: 'https://img.isme.top/isme/67208863145ef.jpg' },
|
||||||
{ url: 'https://cdn.isme.top/images/5c23d52f880511ebb6edd017c2d2eca2.jpg' },
|
{ url: 'https://img.isme.top/isme/67208ab2a9de0.jpg' },
|
||||||
{ url: 'https://cdn.isme.top/images/5c23d52f880511ebb6edd017c2d2eca2.jpg' },
|
{ url: 'https://img.isme.top/isme/67208ab4c6596.jpg' },
|
||||||
{ url: 'https://cdn.isme.top/images/5c23d52f880511ebb6edd017c2d2eca2.jpg' },
|
|
||||||
])
|
])
|
||||||
|
|
||||||
watch(copied, (val) => {
|
watch(copied, (val) => {
|
||||||
|
|||||||
@@ -160,13 +160,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import * as echarts from 'echarts/core'
|
import { useUserStore } from '@/store'
|
||||||
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
|
|
||||||
import { BarChart, LineChart, PieChart } from 'echarts/charts'
|
import { BarChart, LineChart, PieChart } from 'echarts/charts'
|
||||||
|
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
|
||||||
|
import * as echarts from 'echarts/core'
|
||||||
import { UniversalTransition } from 'echarts/features'
|
import { UniversalTransition } from 'echarts/features'
|
||||||
import { CanvasRenderer } from 'echarts/renderers'
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
import VChart from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
import { useUserStore } from '@/store'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
|||||||
@@ -101,10 +101,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { useAuthStore } from '@/store'
|
||||||
|
import { lStorage, throttle } from '@/utils'
|
||||||
import { useStorage } from '@vueuse/core'
|
import { useStorage } from '@vueuse/core'
|
||||||
import api from './api'
|
import api from './api'
|
||||||
import { lStorage, throttle } from '@/utils'
|
|
||||||
import { useAuthStore } from '@/store'
|
|
||||||
|
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import axios from 'axios'
|
|
||||||
import { request } from '@/utils'
|
import { request } from '@/utils'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getMenuTree: () => request.get('/permission/menu/tree'),
|
getMenuTree: () => request.get('/permission/menu/tree'),
|
||||||
|
|||||||
@@ -38,8 +38,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { withModifiers } from 'vue'
|
|
||||||
import { NButton } from 'naive-ui'
|
import { NButton } from 'naive-ui'
|
||||||
|
import { withModifiers } from 'vue'
|
||||||
import api from '../api'
|
import api from '../api'
|
||||||
import ResAddOrEdit from './ResAddOrEdit.vue'
|
import ResAddOrEdit from './ResAddOrEdit.vue'
|
||||||
|
|
||||||
|
|||||||
@@ -159,12 +159,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import pagePathes from 'isme:page-pathes'
|
|
||||||
import icons from 'isme:icons'
|
|
||||||
import api from '../api'
|
|
||||||
import QuestionLabel from './QuestionLabel.vue'
|
|
||||||
import { MeModal } from '@/components'
|
import { MeModal } from '@/components'
|
||||||
import { useForm, useModal } from '@/composables'
|
import { useForm, useModal } from '@/composables'
|
||||||
|
import icons from 'isme:icons'
|
||||||
|
import pagePathes from 'isme:page-pathes'
|
||||||
|
import api from '../api'
|
||||||
|
import QuestionLabel from './QuestionLabel.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
menus: {
|
menus: {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
<n-spin size="small" :show="treeLoading">
|
<n-spin size="small" :show="treeLoading">
|
||||||
<MenuTree
|
<MenuTree
|
||||||
v-model:currentMenu="currentMenu"
|
v-model:current-menu="currentMenu"
|
||||||
class="w-320 shrink-0"
|
class="w-320 shrink-0"
|
||||||
:tree-data="treeData"
|
:tree-data="treeData"
|
||||||
@refresh="initData"
|
@refresh="initData"
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
:columns="btnsColumns"
|
:columns="btnsColumns"
|
||||||
:scroll-x="-1"
|
:scroll-x="-1"
|
||||||
:get-data="api.getButtons"
|
:get-data="api.getButtons"
|
||||||
|
:computed-height="300"
|
||||||
:query-items="{ parentId: currentMenu.id }"
|
:query-items="{ parentId: currentMenu.id }"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -92,11 +93,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { MeCrud } from '@/components'
|
||||||
import { NButton, NSwitch } from 'naive-ui'
|
import { NButton, NSwitch } from 'naive-ui'
|
||||||
|
import api from './api'
|
||||||
import MenuTree from './components/MenuTree.vue'
|
import MenuTree from './components/MenuTree.vue'
|
||||||
import ResAddOrEdit from './components/ResAddOrEdit.vue'
|
import ResAddOrEdit from './components/ResAddOrEdit.vue'
|
||||||
import api from './api'
|
|
||||||
import { MeCrud } from '@/components'
|
|
||||||
|
|
||||||
const treeData = ref([])
|
const treeData = ref([])
|
||||||
const treeLoading = ref(false)
|
const treeLoading = ref(false)
|
||||||
|
|||||||
@@ -95,10 +95,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { NButton, NSwitch } from 'naive-ui'
|
|
||||||
import api from './api'
|
|
||||||
import { MeCrud, MeModal, MeQueryItem } from '@/components'
|
import { MeCrud, MeModal, MeQueryItem } from '@/components'
|
||||||
import { useCrud } from '@/composables'
|
import { useCrud } from '@/composables'
|
||||||
|
import { NButton, NSwitch } from 'naive-ui'
|
||||||
|
import api from './api'
|
||||||
|
|
||||||
defineOptions({ name: 'RoleMgt' })
|
defineOptions({ name: 'RoleMgt' })
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
:scroll-x="1200"
|
:scroll-x="1200"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:get-data="api.getAllUsers"
|
:get-data="api.getAllUsers"
|
||||||
|
:show-check="true"
|
||||||
@on-checked="onChecked"
|
@on-checked="onChecked"
|
||||||
>
|
>
|
||||||
<MeQueryItem label="用户名" :label-width="50">
|
<MeQueryItem label="用户名" :label-width="50">
|
||||||
@@ -67,11 +68,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { MeCrud, MeQueryItem } from '@/components'
|
||||||
|
import { formatDateTime } from '@/utils'
|
||||||
import { NAvatar, NButton, NSwitch, NTag } from 'naive-ui'
|
import { NAvatar, NButton, NSwitch, NTag } from 'naive-ui'
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import api from './api'
|
import api from './api'
|
||||||
import { MeCrud, MeQueryItem } from '@/components'
|
|
||||||
import { formatDateTime } from '@/utils'
|
|
||||||
|
|
||||||
defineOptions({ name: 'RoleUser' })
|
defineOptions({ name: 'RoleUser' })
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -90,7 +91,7 @@ const genders = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ type: 'selection', fixed: 'left' },
|
// { type: 'selection', fixed: 'left' },
|
||||||
{
|
{
|
||||||
title: '头像',
|
title: '头像',
|
||||||
key: 'avatar',
|
key: 'avatar',
|
||||||
@@ -101,11 +102,10 @@ const columns = [
|
|||||||
src: avatar,
|
src: avatar,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{ title: '用户名', key: 'username', width: 150, ellipsis: { tooltip: true } },
|
{ title: '用户名', key: 'username', ellipsis: { tooltip: true } },
|
||||||
{
|
{
|
||||||
title: '角色',
|
title: '角色',
|
||||||
key: 'roles',
|
key: 'roles',
|
||||||
width: 200,
|
|
||||||
ellipsis: { tooltip: true },
|
ellipsis: { tooltip: true },
|
||||||
render: ({ roles }) => {
|
render: ({ roles }) => {
|
||||||
if (roles?.length) {
|
if (roles?.length) {
|
||||||
@@ -156,7 +156,7 @@ const columns = [
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'actions',
|
key: 'actions',
|
||||||
width: 100,
|
width: 120,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
hideInExcel: true,
|
hideInExcel: true,
|
||||||
|
|||||||
@@ -110,11 +110,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { NAvatar, NButton, NSwitch, NTag } from 'naive-ui'
|
|
||||||
import api from './api'
|
|
||||||
import { formatDateTime } from '@/utils'
|
|
||||||
import { MeCrud, MeModal, MeQueryItem } from '@/components'
|
import { MeCrud, MeModal, MeQueryItem } from '@/components'
|
||||||
import { useCrud } from '@/composables'
|
import { useCrud } from '@/composables'
|
||||||
|
import { formatDateTime } from '@/utils'
|
||||||
|
import { NAvatar, NButton, NSwitch, NTag } from 'naive-ui'
|
||||||
|
import api from './api'
|
||||||
|
|
||||||
defineOptions({ name: 'UserMgt' })
|
defineOptions({ name: 'UserMgt' })
|
||||||
|
|
||||||
@@ -162,11 +162,10 @@ const columns = [
|
|||||||
src: avatar,
|
src: avatar,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{ title: '用户名', key: 'username', width: 150, ellipsis: { tooltip: true } },
|
{ title: '用户名', key: 'username', ellipsis: { tooltip: true } },
|
||||||
{
|
{
|
||||||
title: '角色',
|
title: '角色',
|
||||||
key: 'roles',
|
key: 'roles',
|
||||||
width: 200,
|
|
||||||
ellipsis: { tooltip: true },
|
ellipsis: { tooltip: true },
|
||||||
render: ({ roles }) => {
|
render: ({ roles }) => {
|
||||||
if (roles?.length) {
|
if (roles?.length) {
|
||||||
|
|||||||
@@ -105,11 +105,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import api from './api'
|
|
||||||
import { MeModal } from '@/components'
|
import { MeModal } from '@/components'
|
||||||
import { useForm, useModal } from '@/composables'
|
import { useForm, useModal } from '@/composables'
|
||||||
import { useUserStore } from '@/store'
|
import { useUserStore } from '@/store'
|
||||||
import { getUserInfo } from '@/store/helper'
|
import { getUserInfo } from '@/store/helper'
|
||||||
|
import api from './api'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const required = {
|
const required = {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import { defineConfig, presetAttributify, presetIcons, presetUno } from 'unocss'
|
|
||||||
import presetRemToPx from '@unocss/preset-rem-to-px'
|
|
||||||
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
|
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
|
||||||
import { getIcons } from './build'
|
import presetRemToPx from '@unocss/preset-rem-to-px'
|
||||||
|
import { defineConfig, presetAttributify, presetIcons, presetUno } from 'unocss'
|
||||||
|
import { getIcons } from './build/index.js'
|
||||||
|
|
||||||
const icons = getIcons()
|
const icons = getIcons()
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
|||||||
@@ -7,14 +7,15 @@
|
|||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { defineConfig, loadEnv } from 'vite'
|
|
||||||
import Vue from '@vitejs/plugin-vue'
|
import Vue from '@vitejs/plugin-vue'
|
||||||
import VueDevTools from 'vite-plugin-vue-devtools'
|
import VueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
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 Components from 'unplugin-vue-components/vite'
|
|
||||||
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
|
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
|
||||||
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
import { defineConfig, loadEnv } from 'vite'
|
||||||
import removeNoMatch from 'vite-plugin-router-warn'
|
import removeNoMatch from 'vite-plugin-router-warn'
|
||||||
|
import VueDevTools from 'vite-plugin-vue-devtools'
|
||||||
import { pluginIcons, pluginPagePathes } from './build/plugin-isme'
|
import { pluginIcons, pluginPagePathes } from './build/plugin-isme'
|
||||||
|
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
@@ -25,6 +26,7 @@ export default defineConfig(({ mode }) => {
|
|||||||
base: VITE_PUBLIC_PATH || '/',
|
base: VITE_PUBLIC_PATH || '/',
|
||||||
plugins: [
|
plugins: [
|
||||||
Vue(),
|
Vue(),
|
||||||
|
VueJsx(),
|
||||||
VueDevTools(),
|
VueDevTools(),
|
||||||
Unocss(),
|
Unocss(),
|
||||||
AutoImport({
|
AutoImport({
|
||||||
|
|||||||
Reference in New Issue
Block a user