merge(projects): Merge remote-tracking branch 'Soybean/v2.0' into v2.0

This commit is contained in:
xlsea
2025-10-27 14:21:37 +08:00
28 changed files with 1197 additions and 1160 deletions
+18 -18
View File
@@ -1,7 +1,7 @@
{
"name": "ruoyi-vue-plus",
"type": "module",
"version": "1.2.0",
"version": "2.0.0-beta.1",
"description": "结合了 RuoYi-Vue-Plus 的强大后端功能和 Soybean Admin 的现代化前端特性,为开发者提供了完整的企业管理解决方案。",
"author": {
"name": "xlsea",
@@ -68,7 +68,7 @@
"@sa/utils": "workspace:*",
"@types/streamsaver": "^2.0.5",
"@umoteam/editor": "^8.1.0",
"@vueuse/core": "13.9.0",
"@vueuse/core": "14.0.0",
"clipboard": "2.0.11",
"dayjs": "1.11.18",
"defu": "6.1.4",
@@ -86,43 +86,43 @@
"vue-advanced-cropper": "^2.8.9",
"vue-draggable-plus": "0.6.0",
"vue-i18n": "11.1.12",
"vue-router": "4.5.1",
"vue-router": "4.6.3",
"xlsx": "0.18.5"
},
"devDependencies": {
"@elegant-router/vue": "0.3.8",
"@iconify/json": "2.2.395",
"@iconify/json": "2.2.400",
"@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.7.1",
"@types/node": "24.7.2",
"@types/node": "24.9.1",
"@types/nprogress": "0.2.3",
"@unocss/eslint-config": "66.5.3",
"@unocss/preset-icons": "66.5.3",
"@unocss/preset-uno": "66.5.3",
"@unocss/transformer-directives": "66.5.3",
"@unocss/transformer-variant-group": "66.5.3",
"@unocss/vite": "66.5.3",
"@unocss/eslint-config": "66.5.4",
"@unocss/preset-icons": "66.5.4",
"@unocss/preset-uno": "66.5.4",
"@unocss/transformer-directives": "66.5.4",
"@unocss/transformer-variant-group": "66.5.4",
"@unocss/vite": "66.5.4",
"@vitejs/plugin-vue": "6.0.1",
"@vitejs/plugin-vue-jsx": "5.1.1",
"consola": "3.4.2",
"eslint": "9.37.0",
"eslint-plugin-vue": "10.5.0",
"eslint": "9.38.0",
"eslint-plugin-vue": "10.5.1",
"kolorist": "1.8.0",
"sass": "1.93.2",
"simple-git-hooks": "2.13.1",
"tsx": "4.20.6",
"typescript": "5.9.3",
"unplugin-icons": "22.4.2",
"unplugin-vue-components": "29.1.0",
"vite": "7.1.9",
"unplugin-icons": "22.5.0",
"unplugin-vue-components": "30.0.0",
"vite": "7.1.12",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-progress": "0.0.7",
"vite-plugin-static-copy": "^3.1.0",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "8.0.2",
"vite-plugin-vue-devtools": "8.0.3",
"vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.1"
"vue-tsc": "3.1.2"
},
"simple-git-hooks": {
"commit-msg": "pnpm sa git-commit-verify",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/alova",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts",
"./fetch": "./src/fetch.ts",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/axios",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts"
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/color",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts"
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/hooks",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts"
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/materials",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts"
},
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/scripts",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"bin": {
"sa": "./bin.ts"
},
@@ -15,13 +15,13 @@
"devDependencies": {
"@soybeanjs/changelog": "0.3.25",
"bumpp": "10.3.1",
"c12": "3.3.0",
"c12": "3.3.1",
"cac": "6.7.14",
"consola": "3.4.2",
"enquirer": "2.4.1",
"execa": "9.6.0",
"kolorist": "1.8.0",
"npm-check-updates": "19.0.0",
"npm-check-updates": "19.1.1",
"picomatch": "4.0.3",
"rimraf": "6.0.1"
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/uno-preset",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts"
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@sa/utils",
"version": "1.3.15",
"version": "2.0.0-beta.1",
"exports": {
".": "./src/index.ts"
},
+1070 -1120
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -26,6 +26,7 @@ const tabRef = ref<HTMLElement>();
const isPCFlag = isPC();
const TAB_DATA_ID = 'data-tab-id';
const MIDDLE_MOUSE_BUTTON = 1;
type TabNamedNodeMap = NamedNodeMap & {
[TAB_DATA_ID]: Attr;
@@ -84,6 +85,20 @@ function handleCloseTab(tab: App.Global.Tab) {
tabStore.removeTab(tab.id);
}
function handleMousedown(e: MouseEvent, tab: App.Global.Tab) {
const isMiddleClick = e.button === MIDDLE_MOUSE_BUTTON;
if (!isMiddleClick || !themeStore.tab.closeTabByMiddleClick) {
return;
}
if (tabStore.isTabRetain(tab.id)) {
return;
}
e.preventDefault();
handleCloseTab(tab);
}
async function refresh() {
appStore.reloadPage(500);
}
@@ -183,6 +198,7 @@ init();
:active-color="themeStore.themeColor"
:closable="!tabStore.isTabRetain(tab.id)"
@pointerdown="tabStore.switchRouteByTab(tab)"
@mousedown="handleMousedown($event, tab)"
@close="handleCloseTab(tab)"
@contextmenu="handleContextMenu($event, tab.id)"
>
@@ -1,6 +1,7 @@
<script setup lang="ts">
import ThemeSchema from './modules/theme-schema.vue';
import ThemeColor from './modules/theme-color.vue';
import ThemeRadius from './modules/theme-radius.vue';
defineOptions({
name: 'AppearanceSettings'
@@ -11,6 +12,7 @@ defineOptions({
<div class="flex-col-stretch gap-16px">
<ThemeSchema />
<ThemeColor />
<ThemeRadius />
</div>
</template>
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { useThemeStore } from '@/store/modules/theme';
import { $t } from '@/locales';
import SettingItem from '../../../components/setting-item.vue';
defineOptions({
name: 'ThemeRadius'
});
const themeStore = useThemeStore();
</script>
<template>
<NDivider>{{ $t('theme.appearance.themeRadius.title') }}</NDivider>
<TransitionGroup tag="div" name="setting-list" class="flex-col-stretch gap-12px">
<SettingItem key="1" :label="$t('theme.appearance.themeRadius.title')">
<NInputNumber v-model:value="themeStore.themeRadius" size="small" :step="1" :min="0" :max="16" class="w-120px" />
</SettingItem>
</TransitionGroup>
</template>
<style scoped></style>
@@ -35,6 +35,12 @@ const themeStore = useThemeStore();
class="w-120px"
/>
</SettingItem>
<SettingItem v-if="themeStore.tab.visible" key="5" :label="$t('theme.layout.tab.closeByMiddleClick')">
<template #suffix>
<IconTooltip :desc="$t('theme.layout.tab.closeByMiddleClickTip')" />
</template>
<NSwitch v-model:value="themeStore.tab.closeTabByMiddleClick" />
</SettingItem>
</TransitionGroup>
</template>
@@ -14,6 +14,7 @@ type ThemePreset = Pick<
| 'colourWeakness'
| 'recommendColor'
| 'themeColor'
| 'themeRadius'
| 'otherColor'
| 'isInfoFollowPrimary'
| 'layout'
+6 -1
View File
@@ -107,6 +107,9 @@ const local: App.I18n.Schema = {
error: 'Error',
followPrimary: 'Follow Primary'
},
themeRadius: {
title: 'Theme Radius'
},
recommendColor: 'Apply Recommended Color Algorithm',
recommendColorDesc: 'The recommended color algorithm refers to',
preset: {
@@ -162,7 +165,9 @@ const local: App.I18n.Schema = {
slider: 'Slider',
chrome: 'Chrome',
button: 'Button'
}
},
closeByMiddleClick: 'Close Tab by Middle Click',
closeByMiddleClickTip: 'Enable closing tabs by clicking with the middle mouse button'
},
header: {
title: 'Header Settings',
+6 -1
View File
@@ -107,6 +107,9 @@ const local: App.I18n.Schema = {
error: '错误色',
followPrimary: '跟随主色'
},
themeRadius: {
title: '主题圆角'
},
recommendColor: '应用推荐算法的颜色',
recommendColorDesc: '推荐颜色的算法参照',
preset: {
@@ -159,7 +162,9 @@ const local: App.I18n.Schema = {
slider: '滑块风格',
chrome: '谷歌风格',
button: '按钮风格'
}
},
closeByMiddleClick: '鼠标中键关闭标签页',
closeByMiddleClickTip: '启用后可以使用鼠标中键点击标签页进行关闭'
},
header: {
title: '头部设置',
+1 -1
View File
@@ -53,7 +53,7 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
});
/** Naive theme */
const naiveTheme = computed(() => getNaiveTheme(themeColors.value, settings.value.recommendColor));
const naiveTheme = computed(() => getNaiveTheme(themeColors.value, settings.value));
/**
* Settings json
+7 -6
View File
@@ -236,22 +236,23 @@ function getNaiveThemeColors(colors: App.Theme.ThemeColor, recommended = false)
/**
* Get naive theme
*
* @param colors Theme colors
* @param [recommended=false] Use recommended color. Default is `false`
* @param settings Theme settings object.
* @param settings.recommendColor Whether to use recommended color palette.
* @param settings.themeRadius Border radius to use in the theme (in px).
*/
export function getNaiveTheme(colors: App.Theme.ThemeColor, recommended = false) {
export function getNaiveTheme(colors: App.Theme.ThemeColor, settings: App.Theme.ThemeSetting) {
const { primary: colorLoading } = colors;
const theme: GlobalThemeOverrides = {
common: {
...getNaiveThemeColors(colors, recommended),
borderRadius: '6px'
...getNaiveThemeColors(colors, settings.recommendColor),
borderRadius: `${settings.themeRadius}px`
},
LoadingBar: {
colorLoading
},
Tag: {
borderRadius: '6px'
borderRadius: `${settings.themeRadius}px`
},
Button: {
textColorPrimary: '#ffffff'
+1
View File
@@ -7,6 +7,7 @@ body,
#app {
height: 100%;
font-family: inherit;
text-autospace: normal;
}
html {
+8 -1
View File
@@ -1,7 +1,14 @@
@mixin scrollbar($size: 7px, $color: rgba(0, 0, 0, 0.5)) {
@mixin scrollbar($size: 7px, $color: rgba(0, 0, 0, 0.5), $dark-color: rgba(255, 255, 255, 0.5)) {
scrollbar-width: thin;
scrollbar-color: $color transparent;
// Dark theme override
.dark & {
// guide safari use light color scrollbar
color-scheme: dark;
scrollbar-color: $dark-color transparent;
}
&::-webkit-scrollbar-thumb {
background-color: $color;
border-radius: $size;
+1
View File
@@ -14,6 +14,7 @@
"warning": "#d4bb9d",
"error": "#c49a9a"
},
"themeRadius": 6,
"isInfoFollowPrimary": true,
"layout": {
"mode": "vertical-mix",
+1
View File
@@ -14,6 +14,7 @@
"warning": "#faad14",
"error": "#f5222d"
},
"themeRadius": 6,
"isInfoFollowPrimary": true,
"layout": {
"mode": "vertical",
+1
View File
@@ -14,6 +14,7 @@
"warning": "#faad14",
"error": "#f5222d"
},
"themeRadius": 6,
"isInfoFollowPrimary": true,
"layout": {
"mode": "vertical",
+1
View File
@@ -14,6 +14,7 @@
"warning": "#faad14",
"error": "#f5222d"
},
"themeRadius": 6,
"isInfoFollowPrimary": true,
"layout": {
"mode": "vertical",
+3 -1
View File
@@ -5,6 +5,7 @@ export const themeSettings: App.Theme.ThemeSetting = {
colourWeakness: false,
recommendColor: false,
themeColor: '#0E42D2',
themeRadius: 6,
otherColor: {
info: '#0E42D2',
success: '#009A29',
@@ -37,7 +38,8 @@ export const themeSettings: App.Theme.ThemeSetting = {
visible: true,
cache: true,
height: 44,
mode: 'chrome'
mode: 'chrome',
closeTabByMiddleClick: false
},
fixedHeaderAndTab: true,
sider: {
+9
View File
@@ -16,6 +16,8 @@ declare namespace App {
recommendColor: boolean;
/** Theme color */
themeColor: string;
/** Theme radius */
themeRadius: number;
/** Other color */
otherColor: OtherColor;
/** Whether info color is followed by the primary color */
@@ -69,6 +71,8 @@ declare namespace App {
height: number;
/** Tab mode */
mode: UnionKey.ThemeTabMode;
/** Whether to close tab by middle click */
closeTabByMiddleClick: boolean;
};
/** Fixed header and tab */
fixedHeaderAndTab: boolean;
@@ -416,6 +420,9 @@ declare namespace App {
} & Record<Theme.ThemeColorKey, string>;
recommendColor: string;
recommendColorDesc: string;
themeRadius: {
title: string;
};
preset: {
title: string;
apply: string;
@@ -439,6 +446,8 @@ declare namespace App {
cacheTip: string;
height: string;
mode: { title: string } & Record<UnionKey.ThemeTabMode, string>;
closeByMiddleClick: string;
closeByMiddleClickTip: string;
};
header: {
title: string;
+7 -1
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { computed } from 'vue';
import { createReusableTemplate } from '@vueuse/core';
import { useThemeStore } from '@/store/modules/theme';
import { $t } from '@/locales';
defineOptions({
@@ -72,6 +73,8 @@ interface GradientBgProps {
const [DefineGradientBg, GradientBg] = createReusableTemplate<GradientBgProps>();
const themeStore = useThemeStore();
function getGradientColor(color: CardData['color']) {
return `linear-gradient(to bottom right, ${color.start}, ${color.end})`;
}
@@ -81,7 +84,10 @@ function getGradientColor(color: CardData['color']) {
<NCard :bordered="false" size="small" class="card-wrapper">
<!-- define component start: GradientBg -->
<DefineGradientBg v-slot="{ $slots, gradientColor }">
<div class="rd-8px px-16px pb-4px pt-8px text-white" :style="{ backgroundImage: gradientColor }">
<div
class="px-16px pb-4px pt-8px text-white"
:style="{ backgroundImage: gradientColor, borderRadius: themeStore.themeRadius + 'px' }"
>
<component :is="$slots.default" />
</div>
</DefineGradientBg>