chore(projects): merge main to example

This commit is contained in:
Soybean 2024-05-20 01:24:46 +08:00
commit 10b231918a
19 changed files with 1110 additions and 784 deletions

View File

@ -1,6 +1,38 @@
# Changelog
## [v1.1.1](https://github.com/soybeanjs/soybean-admin/compare/v1.1.0...v1.1.1) (2024-05-20)
###    🚀 Features
- **hooks**: add setOptions for useEcharts &nbsp;-&nbsp; by @honghuangdc [<samp>(e4d53)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e4d53aa)
### &nbsp;&nbsp;&nbsp;🐞 Bug Fixes
- **projects**:
- fix useRouter. fixed #436 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/436 [<samp>(0774a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0774a51)
- add error handle when get routes in dynamic route mode. fixed 440 &nbsp;-&nbsp; by @honghuangdc [<samp>(57b4a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/57b4a9d)
- **styles**:
- fix useTable type &nbsp;-&nbsp; by @honghuangdc [<samp>(07124)</samp>](https://github.com/soybeanjs/soybean-admin/commit/071241f)
### &nbsp;&nbsp;&nbsp;📖 Documentation
- **projects**:
- update CHANGELOG &nbsp;-&nbsp; by @honghuangdc [<samp>(19783)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1978397)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(fa56e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fa56e9c)
- update README.md &nbsp;-&nbsp; by @honghuangdc [<samp>(419ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/419ea42)
### &nbsp;&nbsp;&nbsp;🏡 Chore
- **projects**:
- update deps & fix TS error &nbsp;-&nbsp; by @honghuangdc [<samp>(4ea9c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4ea9c85)
- update eslint-config & fix code &nbsp;-&nbsp; by @honghuangdc [<samp>(68ea9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/68ea974)
- update @elegant-router/vue & add error handle for resolve route. fixed #442 &nbsp;-&nbsp; by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/442 [<samp>(24ff8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/24ff852)
### &nbsp;&nbsp;&nbsp;❤️ Contributors
[![honghuangdc](https://github.com/honghuangdc.png?size=48)](https://github.com/honghuangdc)&nbsp;&nbsp;
## [v1.1.0](https://github.com/honghuangdc/soybean-admin/compare/v1.0.9...v1.1.0) (2024-05-07)
### &nbsp;&nbsp;&nbsp;🚀 Features

View File

@ -113,6 +113,9 @@ pnpm build
- [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).
- [MalusAdmin](https://github.com/pridejoy/MalusAdmin): A backend management framework developed based on Vue3/TypeScript/NaiveUI and NET7 & Sqlsugar. It is implemented in the most original and simplest way, with a fresh and elegant front-end, a clear and elegant backend structure, and powerful functions.
- [PanisAdmin](https://github.com/paynezhuang/panis-admin): Adopting SpringBoot 3, SaToken, MySQL and other frameworks to develop and modify [soybean-admin](https://github.com/soybeanjs/soybean-admin) for the second time, adapting dynamic menu/button-level authorization. Retaining the original flavor, fresh and elegant, high-value back-end management system scaffold.
- [snail-job](https://github.com/aizuda/snail-job): A distributed task retry and task scheduling platform with "high performance, high value and high activity".
- [SuperApi](https://github.com/TmmTop/SuperApi): Quickly turn your idea into an online stable product! Entity-less library and table building, add, delete, change and check entity-less library table, support 15 kinds of condition query, as well as paging, list, unlimited tree list and other functions of the API deployment! With interface documentation, Auth authorisation, interface flow restriction, access to the client's real IP, advanced server caching components, dynamic APIs and other features, we look forward to your experience!
- [FastSoyAdmin](https://github.com/sleep1223/fast-soy-admin): A modern Management Platform based on FastAPI+Vue3+Naive UI.
## How to Contribute

View File

@ -112,6 +112,9 @@ pnpm build
- [pea](https://github.com/haitang1894/pea) : 采用SpringBoot3.2 + JDK21、MyBatis-Plus、SpringSecurity安全框架等适配 [soybean-admin](https://gitee.com/honghuangdc/soybean-admin) 开发的简单权限系统。
- [MalusAdmin](https://github.com/pridejoy/MalusAdmin): 基于 Vue3/TypeScript/NaiveUI 和 NET7 & Sqlsugar 开发的后台管理框架。采用最原生最简洁的方式来实现, 前端清新优雅高颜值,后端 结构清晰,优雅易懂,功能强大。
- [PanisAdmin](https://github.com/paynezhuang/panis-admin): 采用SpringBoot3、SaToken、MySQL等框架开发二次修改 [soybean-admin](https://github.com/soybeanjs/soybean-admin),适配动态菜单/按钮级别的鉴权,保留原汁原味、清新优雅、高颜值的后台管理系统脚手架。
- [snail-job](https://github.com/aizuda/snail-job): 一款兼具 “高性能、高颜值、高活跃” 的分布式任务重试和分布式任务调度平台。
- [SuperApi](https://github.com/TmmTop/SuperApi): 快速将你的 idea 变成线上稳定运行的产品! 无实体建库建表,对无实体库表进行增删改查,支持 15 种条件查询,以及分页,列表,无限级树形列表 等功能的 API 部署! 拥有接口文档Auth 授权,接口限流,获取客户端真实 IP先进的服务器缓存组件动态 API 等功能,期待您的体验!
- [FastSoyAdmin](https://github.com/sleep1223/fast-soy-admin): 基于 FastAPI+Vue3+Naive UI 的现代化轻量管理平台.
## 如何贡献

View File

@ -1,7 +1,7 @@
{
"name": "soybean-admin",
"type": "module",
"version": "1.1.0",
"version": "1.1.1",
"description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。",
"author": {
"name": "Soybean",
@ -67,8 +67,8 @@
"print-js": "1.6.0",
"swiper": "11.1.1",
"vditor": "3.10.4",
"vue": "3.4.26",
"vue-draggable-plus": "0.4.0",
"vue": "3.4.27",
"vue-draggable-plus": "0.4.1",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
"wangeditor": "4.7.15",
@ -76,38 +76,38 @@
},
"devDependencies": {
"@amap/amap-jsapi-types": "0.0.8",
"@elegant-router/vue": "0.3.6",
"@iconify/json": "2.2.207",
"@elegant-router/vue": "0.3.7",
"@iconify/json": "2.2.211",
"@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.4",
"@soybeanjs/eslint-config": "1.3.5",
"@types/bmapgl": "0.0.5",
"@types/lodash-es": "4.17.12",
"@types/node": "20.12.10",
"@types/node": "20.12.12",
"@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.59.4",
"@unocss/preset-icons": "0.59.4",
"@unocss/preset-uno": "0.59.4",
"@unocss/transformer-directives": "0.59.4",
"@unocss/transformer-variant-group": "0.59.4",
"@unocss/vite": "0.59.4",
"@unocss/eslint-config": "0.60.2",
"@unocss/preset-icons": "0.60.2",
"@unocss/preset-uno": "0.60.2",
"@unocss/transformer-directives": "0.60.2",
"@unocss/transformer-variant-group": "0.60.2",
"@unocss/vite": "0.60.2",
"@vitejs/plugin-vue": "5.0.4",
"@vitejs/plugin-vue-jsx": "3.1.0",
"eslint": "9.2.0",
"eslint-plugin-vue": "9.25.0",
"eslint": "9.3.0",
"eslint-plugin-vue": "9.26.0",
"lint-staged": "15.2.2",
"sass": "1.76.0",
"sass": "1.77.2",
"simple-git-hooks": "2.11.1",
"tsx": "4.9.3",
"tsx": "4.10.5",
"typescript": "5.4.5",
"unplugin-icons": "0.19.0",
"unplugin-vue-components": "0.27.0",
"vite": "5.2.11",
"vite-plugin-progress": "0.0.7",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "7.1.3",
"vite-plugin-vue-devtools": "7.2.0",
"vue-eslint-parser": "9.4.2",
"vue-tsc": "2.0.16"
"vue-tsc": "2.0.19"
},
"simple-git-hooks": {
"commit-msg": "pnpm sa git-commit-verify",

View File

@ -1,6 +1,6 @@
{
"name": "@sa/axios",
"version": "1.1.0",
"version": "1.1.1",
"exports": {
".": "./src/index.ts"
},
@ -12,7 +12,7 @@
"dependencies": {
"@sa/utils": "workspace:*",
"axios": "1.6.8",
"axios-retry": "4.1.0",
"axios-retry": "4.2.0",
"qs": "6.12.1"
},
"devDependencies": {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "@sa/scripts",
"version": "1.1.0",
"version": "1.1.1",
"bin": {
"sa": "./bin.ts"
},
@ -19,9 +19,9 @@
"cac": "6.7.14",
"consola": "3.2.3",
"enquirer": "2.4.1",
"execa": "8.0.1",
"execa": "9.1.0",
"kolorist": "1.8.0",
"npm-check-updates": "16.14.20",
"rimraf": "5.0.5"
"rimraf": "5.0.7"
}
}

View File

@ -3,5 +3,5 @@ import type { Options } from 'execa';
export async function execCommand(cmd: string, args: string[], options?: Options) {
const { execa } = await import('execa');
const res = await execa(cmd, args, options);
return res?.stdout?.trim() || '';
return (res?.stdout as string)?.trim() || '';
}

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -73,10 +73,8 @@ function getActivePathIndex() {
}
/** key enter */
function handleEnter(e: Event | undefined) {
function handleEnter() {
if (resultOptions.value?.length === 0 || activePath.value === '') return;
e?.preventDefault();
handleClose();
router.push(activePath.value);
}
@ -114,7 +112,7 @@ registerShortcut();
<div class="mt-20px">
<NEmpty v-if="resultOptions.length === 0" :description="$t('common.noData')" />
<SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter="handleEnter" />
<SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter.prevent="handleEnter" />
</div>
<template #footer>
<SearchFooter v-if="!isMobile" />

View File

@ -42,7 +42,13 @@ function transformElegantRouteToVueRoute(
}
function getLayoutName(component: string) {
return component.replace(LAYOUT_PREFIX, '');
const layout = component.replace(LAYOUT_PREFIX, '');
if(!layouts[layout]) {
throw new Error(`Layout component "${layout}" not found`);
}
return layout;
}
function isView(component: string) {
@ -50,7 +56,13 @@ function transformElegantRouteToVueRoute(
}
function getViewName(component: string) {
return component.replace(VIEW_PREFIX, '');
const view = component.replace(VIEW_PREFIX, '');
if(!views[view]) {
throw new Error(`View component "${view}" not found`);
}
return view;
}
function isFirstLevelRoute(item: ElegantConstRoute) {
@ -81,40 +93,46 @@ function transformElegantRouteToVueRoute(
const vueRoute = { name, path, ...rest } as RouteRecordRaw;
if (component) {
if (isSingleLevelRoute(route)) {
const { layout, view } = getSingleLevelRouteComponent(component);
try {
if (component) {
if (isSingleLevelRoute(route)) {
const { layout, view } = getSingleLevelRouteComponent(component);
const singleLevelRoute: RouteRecordRaw = {
path,
component: layouts[layout],
children: [
{
name,
path: '',
component: views[view],
...rest
} as RouteRecordRaw
]
};
const singleLevelRoute: RouteRecordRaw = {
path,
component: layouts[layout],
children: [
{
name,
path: '',
component: views[view],
...rest
} as RouteRecordRaw
]
};
return [singleLevelRoute];
}
if (isLayout(component)) {
const layoutName = getLayoutName(component);
vueRoute.component = layouts[layoutName];
}
if (isView(component)) {
const viewName = getViewName(component);
vueRoute.component = views[viewName];
}
return [singleLevelRoute];
}
if (isLayout(component)) {
const layoutName = getLayoutName(component);
vueRoute.component = layouts[layoutName];
}
if (isView(component)) {
const viewName = getViewName(component);
vueRoute.component = views[viewName];
}
} catch (error: any) {
console.error(`Error transforming route "${route.name}": ${error.toString()}`);
return [];
}
// add redirect to child
if (children?.length && !vueRoute.redirect) {
vueRoute.redirect = {

View File

@ -179,15 +179,18 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
async function initConstantRoute() {
if (isInitConstantRoute.value) return;
if (authRouteMode.value === 'static') {
const staticRoute = createStaticRoutes();
const staticRoute = createStaticRoutes();
if (authRouteMode.value === 'static') {
addConstantRoutes(staticRoute.constantRoutes);
} else {
const { data, error } = await fetchGetConstantRoutes();
if (!error) {
addConstantRoutes(data);
} else {
// if fetch constant routes failed, use static constant routes
addConstantRoutes(staticRoute.constantRoutes);
}
}
@ -240,6 +243,9 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
handleUpdateRootRouteRedirect(home);
setIsInitAuthRoute(true);
} else {
// if fetch user routes failed, reset store
authStore.resetStore();
}
}

View File

@ -1,8 +1,8 @@
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';
import { defineStore } from 'pinia';
import { useEventListener } from '@vueuse/core';
import type { RouteKey } from '@elegant-router/types';
import { router } from '@/router';
import { SetupStoreId } from '@/enum';
import { useRouterPush } from '@/hooks/common/router';
import { localStg } from '@/utils/storage';
@ -23,7 +23,6 @@ import {
} from './shared';
export const useTabStore = defineStore(SetupStoreId.Tab, () => {
const router = useRouter();
const routeStore = useRouteStore();
const themeStore = useThemeStore();
const { routerPush } = useRouterPush(false);

View File

@ -359,13 +359,13 @@ watch(
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.keepAlive')" path="keepAlive">
<NRadioGroup v-model:value="model.keepAlive">
<NRadio value :label="$t('common.yesOrNo.yes')" />
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.constant')" path="constant">
<NRadioGroup v-model:value="model.constant">
<NRadio value :label="$t('common.yesOrNo.yes')" />
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
</NFormItemGi>
@ -394,7 +394,7 @@ watch(
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.multiTab')" path="multiTab">
<NRadioGroup v-model:value="model.multiTab">
<NRadio value :label="$t('common.yesOrNo.yes')" />
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
</NFormItemGi>