Compare commits

...

7 Commits

18 changed files with 483 additions and 2159 deletions

View File

@@ -1,6 +1,24 @@
# Changelog # Changelog
## [v1.3.4](https://github.com/honghuangdc/soybean-admin/compare/v1.3.3...v1.3.4) (2024-08-01)
###    🚨 Breaking Changes
- **projects**: don't reset active menu of vertical-mix layout when it is mixSiderFixed &nbsp;-&nbsp; by @honghuangdc [<samp>(939c5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/939c512)
### &nbsp;&nbsp;&nbsp;🛠 Optimizations
- **projects**: optimize code &nbsp;-&nbsp; by @honghuangdc [<samp>(cb1d4)</samp>](https://github.com/honghuangdc/soybean-admin/commit/cb1d445)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **projects**: update deps & fix vue-router type &nbsp;-&nbsp; by @honghuangdc [<samp>(96837)</samp>](https://github.com/honghuangdc/soybean-admin/commit/968370b)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.3.3](https://github.com/honghuangdc/soybean-admin/compare/v1.3.2...v1.3.3) (2024-07-30) ## [v1.3.3](https://github.com/honghuangdc/soybean-admin/compare/v1.3.2...v1.3.3) (2024-07-30)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes ### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes

View File

@@ -111,6 +111,7 @@ pnpm build
## Ecosystem ## Ecosystem
- [react-soybean-admin](https://github.com/mufeng889/react-soybean-admin): SoybeanAdmin based version of React.
- [electron-mock-admin](https://github.com/lixin59/electron-mock-api): A Mock Api management system that helps front-end developers quickly implement interface mocks. - [electron-mock-admin](https://github.com/lixin59/electron-mock-api): A Mock Api management system that helps front-end developers quickly implement interface mocks.
- [T-Shell](https://github.com/TheBlindM/T-Shell): A terminal emulator and SSH client with configurable command prompts. - [T-Shell](https://github.com/TheBlindM/T-Shell): A terminal emulator and SSH client with configurable command prompts.
- [pea](https://github.com/haitang1894/pea) : Adopting SpringBoot3.2 + JDK21, MyBatis-Plus, SpringSecurity security framework, etc., suitable for the simple permission system developed by [soybean-admin](https://gitee.com/honghuangdc/soybean-admin). - [pea](https://github.com/haitang1894/pea) : Adopting SpringBoot3.2 + JDK21, MyBatis-Plus, SpringSecurity security framework, etc., suitable for the simple permission system developed by [soybean-admin](https://gitee.com/honghuangdc/soybean-admin).

View File

@@ -109,6 +109,7 @@ pnpm build
## 周边生态 ## 周边生态
- [react-soybean-admin](https://github.com/mufeng889/react-soybean-admin): 基于SoybeanAdmin的React版本.
- [electron-mock-admin](https://github.com/lixin59/electron-mock-api): 一个 Mock Api 管理系统,帮助前端开发伙伴快速实现接口的 mock。 - [electron-mock-admin](https://github.com/lixin59/electron-mock-api): 一个 Mock Api 管理系统,帮助前端开发伙伴快速实现接口的 mock。
- [T-Shell](https://github.com/TheBlindM/T-Shell): 是一个可配置命令提示的终端模拟器和 SSH 客户端。 - [T-Shell](https://github.com/TheBlindM/T-Shell): 是一个可配置命令提示的终端模拟器和 SSH 客户端。
- [pea](https://github.com/haitang1894/pea) : 采用SpringBoot3.2 + JDK21、MyBatis-Plus、SpringSecurity安全框架等适配 [soybean-admin](https://gitee.com/honghuangdc/soybean-admin) 开发的简单权限系统。 - [pea](https://github.com/haitang1894/pea) : 采用SpringBoot3.2 + JDK21、MyBatis-Plus、SpringSecurity安全框架等适配 [soybean-admin](https://gitee.com/honghuangdc/soybean-admin) 开发的简单权限系统。

View File

@@ -1,7 +1,7 @@
{ {
"name": "soybean-admin", "name": "soybean-admin",
"type": "module", "type": "module",
"version": "1.3.3", "version": "1.3.4",
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。", "description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
"author": { "author": {
"name": "Soybean", "name": "Soybean",
@@ -62,25 +62,25 @@
"nprogress": "0.2.0", "nprogress": "0.2.0",
"pinia": "2.2.0", "pinia": "2.2.0",
"tailwind-merge": "2.4.0", "tailwind-merge": "2.4.0",
"vue": "3.4.34", "vue": "3.4.35",
"vue-draggable-plus": "0.5.2", "vue-draggable-plus": "0.5.2",
"vue-i18n": "9.13.1", "vue-i18n": "9.13.1",
"vue-router": "4.4.0" "vue-router": "4.4.1"
}, },
"devDependencies": { "devDependencies": {
"@elegant-router/vue": "0.3.7", "@elegant-router/vue": "0.3.8",
"@iconify/json": "2.2.232", "@iconify/json": "2.2.232",
"@sa/scripts": "workspace:*", "@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*", "@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.7", "@soybeanjs/eslint-config": "1.4.0",
"@types/node": "22.0.0", "@types/node": "22.0.1",
"@types/nprogress": "0.2.3", "@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.61.7", "@unocss/eslint-config": "0.61.9",
"@unocss/preset-icons": "0.61.7", "@unocss/preset-icons": "0.61.9",
"@unocss/preset-uno": "0.61.7", "@unocss/preset-uno": "0.61.9",
"@unocss/transformer-directives": "0.61.7", "@unocss/transformer-directives": "0.61.9",
"@unocss/transformer-variant-group": "0.61.7", "@unocss/transformer-variant-group": "0.61.9",
"@unocss/vite": "0.61.7", "@unocss/vite": "0.61.9",
"@vitejs/plugin-vue": "5.1.1", "@vitejs/plugin-vue": "5.1.1",
"@vitejs/plugin-vue-jsx": "4.0.0", "@vitejs/plugin-vue-jsx": "4.0.0",
"eslint": "9.8.0", "eslint": "9.8.0",
@@ -88,7 +88,7 @@
"lint-staged": "15.2.7", "lint-staged": "15.2.7",
"sass": "1.77.8", "sass": "1.77.8",
"simple-git-hooks": "2.11.1", "simple-git-hooks": "2.11.1",
"tsx": "4.16.2", "tsx": "4.16.3",
"typescript": "5.5.4", "typescript": "5.5.4",
"unplugin-icons": "0.19.1", "unplugin-icons": "0.19.1",
"unplugin-vue-components": "0.27.3", "unplugin-vue-components": "0.27.3",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/axios", "name": "@sa/axios",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/color", "name": "@sa/color",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/hooks", "name": "@sa/hooks",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/materials", "name": "@sa/materials",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/fetch", "name": "@sa/fetch",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/scripts", "name": "@sa/scripts",
"version": "1.3.3", "version": "1.3.4",
"bin": { "bin": {
"sa": "./bin.ts" "sa": "./bin.ts"
}, },
@@ -21,7 +21,7 @@
"enquirer": "2.4.1", "enquirer": "2.4.1",
"execa": "9.3.0", "execa": "9.3.0",
"kolorist": "1.8.0", "kolorist": "1.8.0",
"npm-check-updates": "16.14.20", "npm-check-updates": "17.0.0",
"rimraf": "6.0.1" "rimraf": "6.0.1"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/uno-preset", "name": "@sa/uno-preset",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@sa/utils", "name": "@sa/utils",
"version": "1.3.3", "version": "1.3.4",
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },

2514
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watchEffect } from 'vue';
import { useAuth } from '@/hooks/business/auth';
import { $t } from '@/locales'; import { $t } from '@/locales';
defineOptions({ defineOptions({
@@ -9,9 +11,21 @@ interface Props {
itemAlign?: NaiveUI.Align; itemAlign?: NaiveUI.Align;
disabledDelete?: boolean; disabledDelete?: boolean;
loading?: boolean; loading?: boolean;
showAdd?: boolean;
addCode?: string; // Button Add Permission Code
showDelete?: boolean;
deleteCode?: string; // Button Delete Permission Code
} }
defineProps<Props>(); const props = withDefaults(defineProps<Props>(), {
itemAlign: 'center',
disabledDelete: false,
loading: false,
showAdd: true,
addCode: '',
showDelete: true,
deleteCode: ''
});
interface Emits { interface Emits {
(e: 'add'): void; (e: 'add'): void;
@@ -19,6 +33,17 @@ interface Emits {
(e: 'refresh'): void; (e: 'refresh'): void;
} }
const { hasAuth } = useAuth();
const showAddButton = ref(false);
const showDeleteButton = ref(false);
// Monitor changes in permission codes and update the display status of buttons
watchEffect(() => {
showAddButton.value = props.showAdd && (!props.addCode || hasAuth(props.addCode));
showDeleteButton.value = props.showDelete && (!props.deleteCode || hasAuth(props.deleteCode));
});
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const columns = defineModel<NaiveUI.TableColumnCheck[]>('columns', { const columns = defineModel<NaiveUI.TableColumnCheck[]>('columns', {
@@ -42,13 +67,13 @@ function refresh() {
<NSpace :align="itemAlign" wrap justify="end" class="lt-sm:w-200px"> <NSpace :align="itemAlign" wrap justify="end" class="lt-sm:w-200px">
<slot name="prefix"></slot> <slot name="prefix"></slot>
<slot name="default"> <slot name="default">
<NButton size="small" ghost type="primary" @click="add"> <NButton v-if="showAddButton" size="small" ghost type="primary" @click="add">
<template #icon> <template #icon>
<icon-ic-round-plus class="text-icon" /> <icon-ic-round-plus class="text-icon" />
</template> </template>
{{ $t('common.add') }} {{ $t('common.add') }}
</NButton> </NButton>
<NPopconfirm @positive-click="batchDelete"> <NPopconfirm v-if="showDeleteButton" @positive-click="batchDelete">
<template #trigger> <template #trigger>
<NButton size="small" ghost type="error" :disabled="disabledDelete"> <NButton size="small" ghost type="error" :disabled="disabledDelete">
<template #icon> <template #icon>

View File

@@ -56,9 +56,7 @@ function handleSelectMixMenu(menu: App.Global.Menu) {
:theme-color="themeStore.themeColor" :theme-color="themeStore.themeColor"
@select="handleSelectMixMenu" @select="handleSelectMixMenu"
@toggle-sider-collapse="appStore.toggleSiderCollapse" @toggle-sider-collapse="appStore.toggleSiderCollapse"
> />
<slot></slot>
</FirstLevelMenu>
</Teleport> </Teleport>
</template> </template>

View File

@@ -49,8 +49,11 @@ function handleSelectMixMenu(menu: App.Global.Menu) {
} }
function handleResetActiveMenu() { function handleResetActiveMenu() {
getActiveFirstLevelMenuKey();
setDrawerVisible(false); setDrawerVisible(false);
if (!appStore.mixSiderFixed) {
getActiveFirstLevelMenuKey();
}
} }
const selectedKey = computed(() => { const selectedKey = computed(() => {

View File

@@ -97,10 +97,13 @@ function transformElegantRouteToVueRoute(
if (component) { if (component) {
if (isSingleLevelRoute(route)) { if (isSingleLevelRoute(route)) {
const { layout, view } = getSingleLevelRouteComponent(component); const { layout, view } = getSingleLevelRouteComponent(component);
const singleLevelRoute: RouteRecordRaw = { const singleLevelRoute: RouteRecordRaw = {
path, path,
component: layouts[layout], component: layouts[layout],
meta: {
title: route.meta?.title || ''
},
children: [ children: [
{ {
name, name,
@@ -110,36 +113,35 @@ function transformElegantRouteToVueRoute(
} as RouteRecordRaw } as RouteRecordRaw
] ]
}; };
return [singleLevelRoute]; return [singleLevelRoute];
} }
if (isLayout(component)) { if (isLayout(component)) {
const layoutName = getLayoutName(component); const layoutName = getLayoutName(component);
vueRoute.component = layouts[layoutName]; vueRoute.component = layouts[layoutName];
} }
if (isView(component)) { if (isView(component)) {
const viewName = getViewName(component); const viewName = getViewName(component);
vueRoute.component = views[viewName]; vueRoute.component = views[viewName];
} }
} }
} catch (error: any) { } catch (error: any) {
console.error(`Error transforming route "${route.name}": ${error.toString()}`); console.error(`Error transforming route "${route.name}": ${error.toString()}`);
return []; return [];
} }
// add redirect to child // add redirect to child
if (children?.length && !vueRoute.redirect) { if (children?.length && !vueRoute.redirect) {
vueRoute.redirect = { vueRoute.redirect = {
name: children[0].name name: children[0].name
}; };
} }
if (children?.length) { if (children?.length) {
const childRoutes = children.flatMap(child => transformElegantRouteToVueRoute(child, layouts, views)); const childRoutes = children.flatMap(child => transformElegantRouteToVueRoute(child, layouts, views));

View File

@@ -37,7 +37,7 @@ declare module "@elegant-router/types" {
/** /**
* custom route key * custom route key
*/ */
export type CustomRouteKey = Extract< export type CustomRouteKey = Extract<
RouteKey, RouteKey,
| "root" | "root"
@@ -46,7 +46,7 @@ declare module "@elegant-router/types" {
/** /**
* the generated route key * the generated route key
*/ */
export type GeneratedRouteKey = Exclude<RouteKey, CustomRouteKey>; export type GeneratedRouteKey = Exclude<RouteKey, CustomRouteKey>;
/** /**