This commit is contained in:
‘huanghaiixia’
2026-02-03 16:22:04 +08:00
12 changed files with 220 additions and 46 deletions

View File

@ -1,20 +0,0 @@
{
"0 debug pnpm:scope": {
"selected": 1
},
"1 error pnpm": {
"errno": 1,
"code": "ELIFECYCLE",
"pkgid": "vben-admin@2.8.0",
"stage": "dev",
"script": "vite",
"pkgname": "vben-admin",
"err": {
"name": "pnpm",
"message": "vben-admin@2.8.0 dev: `vite`\nExit status 1",
"code": "ELIFECYCLE",
"stack": "pnpm: vben-admin@2.8.0 dev: `vite`\nExit status 1\n at EventEmitter.<anonymous> (C:\\Users\\Zexy\\AppData\\Roaming\\npm\\node_modules\\pnpm\\dist\\pnpm.cjs:103336:20)\n at EventEmitter.emit (events.js:400:28)\n at ChildProcess.<anonymous> (C:\\Users\\Zexy\\AppData\\Roaming\\npm\\node_modules\\pnpm\\dist\\pnpm.cjs:91276:18)\n at ChildProcess.emit (events.js:400:28)\n at maybeClose (internal/child_process.js:1058:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:293:5)"
}
},
"2 warn pnpm:global": " Local package.json exists, but node_modules missing, did you mean to install?"
}

View File

@ -48,3 +48,30 @@ export enum MixSidebarTriggerEnum {
HOVER = 'hover',
CLICK = 'click',
}
export class MenuThemeInfo {
background: string;
color: string;
hover: string;
active: string;
constructor(background: string, hover: string, color: string, active: string) {
this.background = background;
this.hover = hover;
this.color = color;
this.active = active;
}
}
export const MenuThemeEnum = {
CLASSIC_BLUE : new MenuThemeInfo('#2563eb', '#1d4ed8','#ffffff','#fef3c7'),
MINT_GREEN: new MenuThemeInfo('#10b981', '#059669', '#ffffff', '#ecfeff'),
ELEGANT_GRAY : new MenuThemeInfo('#1f2937', '#374151', '#e5e7eb', '#ffffff'),
WARM_ORANGE:new MenuThemeInfo('#f97316', '#ea580c', '#ffffff', '#fffbeb'),
ELEGANT_PURPLE: new MenuThemeInfo('#8b5cf6', '#7c3aed', '#ffffff', '#f3e8ff'),
CALM_CYAN: new MenuThemeInfo('#0891b2', '#0e7490', '#ffffff', '#ccfbf1'),
SOFT_PINK: new MenuThemeInfo('#f472b6', '#ec4899', '#ffffff', '#fff1f7'),
VIBRANT_LIME : new MenuThemeInfo('#84cc16', '#65a30d', '#1f2937', '#ffffff'),
MINIMAL_WHITE : new MenuThemeInfo('#ffffff', '#f9fafb', '#4b5563', '#2563eb'),
DEEP_NAVY: new MenuThemeInfo('#0f172a', '#1e293b', '#cbd5e1', '#38bdf8'),
}

View File

@ -1,13 +1,13 @@
<template>
<AFooter :class="prefixCls" v-if="getShowLayoutFooter" ref="footerRef">
<div :class="`${prefixCls}__links`">
<!-- <div :class="`${prefixCls}__links`">
<a @click="openWindow(SITE_URL)">{{ t('官网地址') }}</a>
<GithubFilled @click="openWindow(GITHUB_URL)" :class="`${prefixCls}__github`" />
<a @click="openWindow(DOC_URL)">{{ t('文档地址') }}</a>
</div>
<div>Copyright &copy;2024 ITC-FRAMEWORK</div>
<div>Copyright &copy;2024 ITC-FRAMEWORK</div> -->
</AFooter>
</template>

View File

@ -5,7 +5,7 @@ import { TypePicker, ThemeColorPicker, SettingFooter, SwitchItem, SelectItem, In
// import { AppDarkModeToggle } from '/@/components/Application';
import { MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum';
import { MenuTypeEnum, TriggerEnum, MenuThemeEnum } from '/@/enums/menuEnum';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
@ -22,6 +22,8 @@ import { HEADER_PRESET_BG_COLOR_LIST, SIDE_BAR_BG_COLOR_LIST, APP_PRESET_COLOR_L
const { t } = useI18n();
const THEME_COLOR = Object.keys(MenuThemeEnum).map((item) => MenuThemeEnum[item].background);
export default defineComponent({
name: 'SettingDrawer',
setup(_, { attrs }) {
@ -93,7 +95,7 @@ export default defineComponent({
}
function renderSiderTheme() {
return <ThemeColorPicker colorList={SIDE_BAR_BG_COLOR_LIST} def={unref(getMenuBgColor)} event={HandlerEnum.MENU_THEME} />;
return <ThemeColorPicker colorList={THEME_COLOR} def={unref(getMenuBgColor)} event={HandlerEnum.MENU_THEME} />;
}
function renderMainTheme() {
@ -114,17 +116,17 @@ export default defineComponent({
return (
<>
<SwitchItem title={t('分割菜单')} event={HandlerEnum.MENU_SPLIT} def={unref(getSplit)} disabled={!unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX} />
{/* <SwitchItem title={t('分割菜单')} event={HandlerEnum.MENU_SPLIT} def={unref(getSplit)} disabled={!unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX} />
<SwitchItem title={t('固定展开菜单')} event={HandlerEnum.MENU_FIXED_MIX_SIDEBAR} def={unref(getMixSideFixed)} disabled={!unref(getIsMixSidebar)} />
<SwitchItem title={t('切换页面关闭菜单')} event={HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE} def={unref(getCloseMixSidebarOnChange)} disabled={!unref(getIsMixSidebar)} />
<SwitchItem title={t('切换页面关闭菜单')} event={HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE} def={unref(getCloseMixSidebarOnChange)} disabled={!unref(getIsMixSidebar)} /> */}
<SwitchItem title={t('折叠菜单')} event={HandlerEnum.MENU_COLLAPSED} def={unref(getCollapsed)} disabled={!unref(getShowMenuRef)} />
<SwitchItem title={t('侧边菜单拖拽')} event={HandlerEnum.MENU_HAS_DRAG} def={unref(getCanDrag)} disabled={!unref(getShowMenuRef)} />
<SwitchItem title={t('菜单搜索')} event={HandlerEnum.HEADER_SEARCH} def={unref(getShowSearch)} disabled={!unref(getShowHeader)} />
{/* <SwitchItem title={t('菜单搜索')} event={HandlerEnum.HEADER_SEARCH} def={unref(getShowSearch)} disabled={!unref(getShowHeader)} /> */}
<SwitchItem title={t('侧边菜单手风琴模式')} event={HandlerEnum.MENU_ACCORDION} def={unref(getAccordion)} disabled={!unref(getShowMenuRef)} />
<SwitchItem title={t('折叠菜单显示名称')} event={HandlerEnum.MENU_COLLAPSED_SHOW_TITLE} def={unref(getCollapsedShowTitle)} disabled={!unref(getShowMenuRef) || !unref(getCollapsed) || unref(getIsMixSidebar)} />
{/* <SwitchItem title={t('折叠菜单显示名称')} event={HandlerEnum.MENU_COLLAPSED_SHOW_TITLE} def={unref(getCollapsedShowTitle)} disabled={!unref(getShowMenuRef) || !unref(getCollapsed) || unref(getIsMixSidebar)} /> */}
<SwitchItem title={t('固定header')} event={HandlerEnum.HEADER_FIXED} def={unref(getHeaderFixed)} disabled={!unref(getShowHeader)} />
<SwitchItem title={t('固定Sidebar')} event={HandlerEnum.MENU_FIXED} def={unref(getMenuFixed)} disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)} />
@ -170,8 +172,8 @@ export default defineComponent({
<SwitchItem title={t('顶栏')} event={HandlerEnum.HEADER_SHOW} def={unref(getShowHeader)} />
<SwitchItem title="Logo" event={HandlerEnum.SHOW_LOGO} def={unref(getShowLogo)} disabled={unref(getIsMixSidebar)} />
<SwitchItem title={t('页脚')} event={HandlerEnum.SHOW_FOOTER} def={unref(getShowFooter)} />
<SwitchItem title={t('全屏内容')} event={HandlerEnum.FULL_CONTENT} def={unref(getFullContent)} />
{/* <SwitchItem title={t('页脚')} event={HandlerEnum.SHOW_FOOTER} def={unref(getShowFooter)} />
<SwitchItem title={t('全屏内容')} event={HandlerEnum.FULL_CONTENT} def={unref(getFullContent)} /> */}
<SwitchItem title={t('灰色模式')} event={HandlerEnum.GRAY_MODE} def={unref(getGrayMode)} />
@ -197,12 +199,12 @@ export default defineComponent({
<BasicDrawer {...attrs} title={t('项目配置')} width={330} class="setting-drawer">
{/* {unref(getShowDarkModeToggle) && <Divider>{() => t('layout.setting.darkMode')}</Divider>}
{unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" />} */}
<Divider>{() => t('导航栏模式')}</Divider>
{renderSidebar()}
{ /*<Divider>{() => t('导航栏模式')}</Divider>
{renderSidebar()} */}
<Divider>{() => t('系统主题')}</Divider>
{renderMainTheme()}
<Divider>{() => t('顶栏主题')}</Divider>
{renderHeaderTheme()}
{/* <Divider>{() => t('顶栏主题')}</Divider>
{renderHeaderTheme()} */}
<Divider>{() => t('菜单主题')}</Divider>
{renderSiderTheme()}
<Divider>{() => t('界面功能')}</Divider>

View File

@ -1,8 +1,8 @@
<template>
<div :class="prefixCls">
<template v-for="color in colorList || []" :key="color">
<template v-for="(color,$index) in colorList || []" :key="color">
<span
@click="handleClick(color)"
@click="handleClick(color,$index)"
:class="[
`${prefixCls}__item`,
{
@ -43,8 +43,9 @@
setup(props) {
const { prefixCls } = useDesign('setting-theme-picker');
function handleClick(color: string) {
props.event && baseHandler(props.event, color);
function handleClick(color: string,i:number) {
console.log(i);
props.event && baseHandler(props.event, color,i);
}
return {
prefixCls,

View File

@ -1,5 +1,5 @@
import { HandlerEnum } from './enum';
import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground';
import { updateHeaderBgColor, updateSidebarBgColor,updateMenuTheme} from '/@/logics/theme/updateBackground';
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
@ -8,10 +8,22 @@ import { ProjectConfig } from '/#/config';
import { changeTheme } from '/@/logics/theme';
import { updateDarkTheme } from '/@/logics/theme/dark';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { info } from 'console';
import { MenuThemeEnum,MenuThemeInfo } from '/@/enums/menuEnum';
export function baseHandler(event: HandlerEnum, value: any) {
const MENU_THEME:{[key:string]:MenuThemeInfo}= (()=>{
let keys = Object.keys(MenuThemeEnum);
let res = {};
for(let i = 0; i < keys.length; i++){
let item = MenuThemeEnum[keys[i]];
res[item.background] = item;
}
return res;
})();
export function baseHandler(event: HandlerEnum, value: any, index?: number) {
const appStore = useAppStore();
const config = handler(event, value);
const config = handler(event,value,index);
appStore.setProjectConfig(config);
if (event === HandlerEnum.CHANGE_THEME) {
updateHeaderBgColor();
@ -19,7 +31,7 @@ export function baseHandler(event: HandlerEnum, value: any) {
}
}
export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> {
export function handler(event: HandlerEnum, value: any, index?: number): DeepPartial<ProjectConfig> {
const appStore = useAppStore();
const { getThemeColor, getDarkMode } = useRootSetting();
@ -80,7 +92,12 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf
return { menuSetting: { collapsedShowTitle: value } };
case HandlerEnum.MENU_THEME:
updateSidebarBgColor(value);
let info = MENU_THEME[value];
// updateSidebarBgColor(value);
// updateSidebarBgColor(value);
// updateHeaderBgColor(value);
updateMenuTheme(info);
return { menuSetting: { bgColor: value } };
case HandlerEnum.MENU_SPLIT:

View File

@ -26,3 +26,22 @@
}
});
</script>
<style lang="less">
.ant-layout-header {
.ant-menu-item {
color: var(--menu-top-color);
background: var(--menu-top-bg-color);
&:hover {
background: var(--menu-top-hover-bg-color);
}
&.ant-menu-item-selected {
color: var(--menu-top-active-color);
background: var(--menu-top-active-bg-color);
}
}
}
</style>

View File

@ -1,7 +1,8 @@
import { colorIsDark, lighten, darken } from '/@/utils/color';
import { useAppStore } from '/@/store/modules/app';
import { ThemeEnum } from '/@/enums/appEnum';
import { ThemeEnum } from '/@/enums/appEnum';
import { setCssVar } from './util';
import { MenuThemeInfo } from '/@/enums/menuEnum';
const HEADER_BG_COLOR_VAR = '--header-bg-color';
const HEADER_BG_HOVER_COLOR_VAR = '--header-bg-hover-color';
@ -73,3 +74,37 @@ export function updateSidebarBgColor(color?: string) {
},
});
}
export function updateMenuTheme(info?: MenuThemeInfo) {
console.log("主题切换",info);
setCssVar(HEADER_BG_COLOR_VAR, info?.background);
setCssVar(HEADER_BG_HOVER_COLOR_VAR, info?.hover);
setCssVar(HEADER_MENU_ACTIVE_BG_COLOR_VAR, info?.hover);
setCssVar(SIDER_DARK_BG_COLOR, info?.background);
setCssVar(SIDER_DARK_DARKEN_BG_COLOR,info?.hover);
setCssVar(SIDER_LIGHTEN_BG_COLOR, lighten(info?.hover!, 5));
let color = info?.background;
const appStore = useAppStore();
const darkMode = appStore.getDarkMode === ThemeEnum.DARK;
if (!color) {
if (darkMode) {
color = '#151515';
} else {
color = appStore.getHeaderSetting.bgColor;
}
}
const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase());
const isDark = colorIsDark(color!);
appStore.setProjectConfig({
menuSetting: {
theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK,
},
headerSetting: {
theme: isDark || darkMode ? ThemeEnum.DARK : ThemeEnum.LIGHT,
},
});
}

View File

@ -14,6 +14,10 @@ import { setupStore } from '/@/store';
import { setupGlobDirectives } from '/@/directives';
import { setupI18n } from '/@/locales/setupI18n';
import { registerGlobComp } from '/@/components/registerGlobComp';
import TColor from '/@/utils/t-color';
let cols = new TColor("#4598FA").gradient("#85F7D8",5);
console.log(cols);
import axios from 'axios';
import VueGridLayout from 'vue-grid-layout';

View File

@ -8,7 +8,7 @@ export const darkMode = ThemeEnum.LIGHT;
export const APP_PRESET_COLOR_LIST: string[] = ['#1179FF', '#0960bd', '#0084f4', '#009688', '#536dfe', '#ff5c93', '#ee4f12', '#0096c7', '#9c27b0', '#ff9800'];
// header preset color
export const HEADER_PRESET_BG_COLOR_LIST: string[] = ['#07093E', '#ffffff', '#151515', '#009688', '#5172DC', '#018ffb', '#409eff', '#e74c3c', '#24292e', '#394664', '#001529', '#383f45'];
export const HEADER_PRESET_BG_COLOR_LIST: string[] = ['#85F7D8', '#ffffff', '#151515', '#009688', '#5172DC', '#018ffb', '#409eff', '#e74c3c', '#24292e', '#394664', '#001529', '#383f45'];
// sider preset color
export const SIDE_BAR_BG_COLOR_LIST: string[] = ['#002F7B', '#212121', '#273352', '#ffffff', '#191b24', '#191a23', '#304156', '#001628', '#28333E', '#344058', '#383f45'];
export const SIDE_BAR_BG_COLOR_LIST: string[] = ['#002F7B', '#212121', '#273352', '#ffffff', '#191b24'];

88
src/utils/t-color.js Normal file
View File

@ -0,0 +1,88 @@
const HexRegex = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
function TColor(color){
this.rgb = TColor.toRgb(color);
}
TColor.prototype = {
gradient:function(color,step){
var to = TColor.toRgb(color);
var sR = (to[0] - this.rgb[0]) / step;//总差值
var sG = (to[1] - this.rgb[1]) / step;
var sB = (to[2] - this.rgb[2]) / step;
var res = [];
for (var i = 0; i < step; i++) {
//计算每一步的hex值
var hex = TColor.rgbHex('rgb('+ parseInt((sR * i + this.rgb[0]))+ ',' +
parseInt((sG * i + this.rgb[1]))+ ',' + parseInt((sB * i + this.rgb[2])) + ')');
res.push(hex);
}
return res;
}
}
TColor.valueOf = function(color){
return new TColor(color);
}
TColor.rgbHex = function(rgb){
var _this = rgb;
if (/^(rgb|RGB)/.test(_this)) {
var aColor = _this.replace(/(?:(|)|rgb|RGB)*/g, "").split(",");
var strHex = "#";
for (var i = 0; i < aColor.length; i++) {
var hex = Number(aColor[i]).toString(16);
hex = hex < 10 ? 0 + '' + hex : hex;// 保证每个rgb的值为2位
if (hex === "0") {
hex += hex;
}
strHex += hex;
}
if (strHex.length !== 7) {
strHex = _this;
}
return strHex;
} else if (HexRegex.test(_this)) {
var aNum = _this.replace(/#/, "").split("");
if (aNum.length === 6) {
return _this;
} else if (aNum.length === 3) {
var numHex = "#";
for (var i = 0; i < aNum.length; i += 1) {
numHex += (aNum[i] + aNum[i]);
}
return numHex;
}
} else {
return _this;
}
}
TColor.toRgb= function(sColor){
var sColor = sColor.toLowerCase();
if (sColor && HexRegex.test(sColor)) {
if (sColor.length === 4) {
var sColorNew = "#";
for (var i = 1; i < 4; i += 1) {
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
}
sColor = sColorNew;
}
//处理六位的颜色值
var sColorChange = [];
for (var i = 1; i < 7; i += 2) {
sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
}
return sColorChange;
} else {
return sColor;
}
}
if(window!=undefined){
window.TColor = TColor;
}
export default TColor;

View File

@ -1,5 +1,6 @@
<template>
<div class="t-container">
<StarBackground3 />
<div :class="prefixCls" class="login-box relative w-full h-full" v-if="!isSingleLogin">
<div class="center-box">
<div class="login-left-title">