liujie
4 天以前 2bd5b4f32d19abf1ef1cbbcba2b4686486ffcf0f
风格替换
1个文件已添加
19个文件已修改
541 ■■■■■ 已修改文件
hugray-admin/.env.development 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/.env.production 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/.env.staging 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/assets/icons/svg/size.svg 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/assets/images/login-left.png 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/assets/styles/index.scss 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/assets/styles/ruoyi.scss 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/assets/styles/sidebar.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/assets/styles/variables.module.scss 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/HeaderNotice/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/Navbar.vue 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/Settings/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/Sidebar/Logo.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/Sidebar/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/TopBar/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/components/TopNav/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/layout/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/settings.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/store/modules/settings.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/src/views/login.vue 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hugray-admin/.env.development
@@ -1,5 +1,5 @@
# 页面标题
VITE_APP_TITLE = 若依管理系统
VITE_APP_TITLE = Hugray
# 开发环境配置
VITE_APP_ENV = 'development'
hugray-admin/.env.production
@@ -1,5 +1,5 @@
# 页面标题
VITE_APP_TITLE = 若依管理系统
VITE_APP_TITLE = Hugray
# 生产环境配置
VITE_APP_ENV = 'production'
hugray-admin/.env.staging
@@ -1,5 +1,5 @@
# 页面标题
VITE_APP_TITLE = 若依管理系统
VITE_APP_TITLE = Hugray
# 生产环境配置
VITE_APP_ENV = 'staging'
hugray-admin/src/assets/icons/svg/size.svg
@@ -1 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path fill="#5a5e66" d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg>
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg>
hugray-admin/src/assets/images/login-left.png
hugray-admin/src/assets/styles/index.scss
@@ -120,9 +120,17 @@
  }
}
//main-container全局样式
//main-container全局样式(内容区浅灰底上的白色圆角卡片)
.app-container {
  padding: 20px;
  margin: 16px;
  background-color: #ffffff;
  border-radius: 6px;
}
// 暗色模式下卡片改用 EP 的浮层底色,否则白底 + 暗色文字规则会让内容不可读
html.dark .app-container {
  background-color: var(--el-bg-color-overlay);
}
.components-container {
hugray-admin/src/assets/styles/ruoyi.scss
@@ -86,8 +86,8 @@
  .el-table__header-wrapper, .el-table__fixed-header-wrapper {
    th {
      word-break: break-word;
      background-color: #f8f8f9 !important;
      color: #515a6e;
      background-color: #F2F3F5 !important;
      color: #303133;
      height: 40px !important;
      font-size: 13px;
    }
@@ -169,7 +169,7 @@
/** 表格更多操作下拉样式 */
.el-table .el-dropdown-link {
  cursor: pointer;
  color: #409EFF;
  color: #0F5291;
  margin-left: 10px;
}
@@ -492,3 +492,65 @@
.top-right-btn {
  margin-left: auto;
}
/* ===== 换肤:设计稿配色(深蓝 chrome + 绿色主色) ===== */
/* 以下浅色配色均为设计稿专用,限定 html:not(.dark):暗色模式沿用 EP 默认深色体系,
   避免出现浅灰填充/深蓝字落在深色面板上不可读 */
html:not(.dark) {
  /* 行内操作链接:设计稿为深蓝,不跟随主题色(主题色是绿色) */
  .el-table .el-button--primary.is-link {
    --el-button-text-color: #0F5291;
    --el-button-hover-text-color: #1667B3;
    --el-button-active-text-color: #0B4A85;
  }
  /* 表格单元格内的文字链接(与上面的操作链接同色系) */
  .el-table .link-type,
  .el-table .link-type:focus {
    color: #0F5291;
    &:hover {
      color: #1667B3;
    }
  }
  /* 分页当前页:设计稿为浅蓝底 + 深蓝字,而非 primary 实心块 */
  .el-pagination.is-background .el-pager li.is-active {
    background-color: #E8F4FF;
    color: #0F5291;
  }
  /* 默认按钮:设计稿为浅灰填充、无边框(走 EP 变量,保留 1px 边框宽度以免尺寸变化)。
     用 :not(带类型按钮) 而非 .el-button--default——后者只在全局 size=default 时存在,
     SizeSelect 切到"较大/稍小"会整站静默失效 */
  .el-button:not(.el-button--primary):not(.el-button--success):not(.el-button--warning):not(.el-button--danger):not(.el-button--info) {
    --el-button-bg-color: #F7F8FA;
    --el-button-border-color: transparent;
    --el-button-text-color: #4E5969;
    --el-button-hover-bg-color: #EEF0F2;
    --el-button-hover-border-color: transparent;
    --el-button-hover-text-color: #303133;
    --el-button-active-bg-color: #E5E8EC;
    --el-button-active-border-color: transparent;
    --el-button-disabled-bg-color: #F7F8FA;
    --el-button-disabled-border-color: transparent;
    --el-button-disabled-text-color: #A8ABB2;
  }
  /* 列表页查询表单:设计稿为浅灰填充、无边框输入框(弹窗内表单保持 EP 默认样式) */
  .app-container .el-form--inline {
    .el-input__wrapper,
    .el-select__wrapper {
      background-color: #F7F8FA;
      box-shadow: none;
      &.is-focus,
      &.is-focused {
        box-shadow: 0 0 0 1px var(--el-color-primary) inset;
      }
    }
  }
}
hugray-admin/src/assets/styles/sidebar.scss
@@ -7,6 +7,13 @@
    transition: margin-left .28s;
    margin-left: vars.$base-sidebar-width;
    position: relative;
    /* 内容区浅灰底,白色卡片(.app-container)浮于其上 */
    background-color: #F7F8FA;
  }
  /* 暗色模式沿用 EP 深色底,否则内容区留白会变成浅灰 */
  html.dark & .main-container {
    background-color: var(--el-bg-color);
  }
  .sidebarHide {
@@ -131,7 +138,7 @@
      }
      .el-sub-menu.is-active > .el-sub-menu__title {
        color: var(--current-color, #409eff) !important;
        color: var(--menu-active-text, #ffffff) !important;
      }
      .el-menu-item:not(.is-active),
hugray-admin/src/assets/styles/variables.module.scss
@@ -8,11 +8,11 @@
$yellow: #FEC171;
$panGreen: #30B08F;
// 默认主题变量
$menuText: #bfcbd9;
$menuActiveText: #409eff;
$menuBg: #1a1f2e;
$menuHover: #263445;
// 默认主题变量(品牌深蓝底 + 白字)
$menuText: rgba(255, 255, 255, 0.82);
$menuActiveText: #ffffff;
$menuBg: #0B3F6F;
$menuHover: rgba(255, 255, 255, 0.12);
// 浅色主题theme-light
$menuLightBg: #ffffff;
@@ -25,14 +25,14 @@
$sideBarWidth: 200px;
// 菜单暗色变量
$base-menu-color: rgba(255,255,255,.65);
$base-menu-color: rgba(255,255,255,.82);
$base-menu-color-active: #ffffff;
$base-menu-background: #1a1f2e;
$base-sub-menu-background: #141824;
$base-sub-menu-hover: rgba(255,255,255,.06);
$base-menu-background: #0B3F6F;
$base-sub-menu-background: #0A3660;
$base-sub-menu-hover: rgba(255,255,255,.10);
// 组件变量
$--color-primary: #409EFF;
$--color-primary: #80BF40;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
@@ -71,9 +71,11 @@
  --sidebar-bg: #{$menuBg};
  --sidebar-text: #{$menuText};
  --menu-hover: #{$menuHover};
  /* 深色侧栏选中项文字色(此前只在 html.dark 里定义,浅色下会回落到兜底色) */
  --menu-active-text: #{$menuActiveText};
  
  --navbar-bg: #ffffff;
  --navbar-text: #303133;
  --navbar-bg: #0B3F6F;
  --navbar-text: #ffffff;
  
  /* splitpanes default-theme 变量 */
  --splitpanes-default-bg: #ffffff;
hugray-admin/src/layout/components/HeaderNotice/index.vue
@@ -107,12 +107,16 @@
<style lang="scss" scoped>
.notice-trigger {
  position: relative;
  transform: translateX(-6px);
  .svg-icon { width: 1.2em; height: 1.2em; vertical-align: -0.2em; }
  display: flex;
  align-items: center;
  justify-content: center;
  /* 顶栏图标在 30px 圆形按钮内居中,行高需归零(否则继承 .right-menu 的 50px 使盒子溢出圆形) */
  line-height: 1;
  .svg-icon { width: 1.2em; height: 1.2em; }
  .notice-badge {
    position: absolute;
    top: 7px;
    right: -3px;
    top: -6px;
    right: -8px;
    background: #f56c6c;
    color: #fff;
    border-radius: 10px;
hugray-admin/src/layout/components/Navbar.vue
@@ -10,15 +10,7 @@
    <div class="right-menu">
      <template v-if="appStore.device !== 'mobile'">
        <header-search id="header-search" class="right-menu-item" />
        <el-tooltip content="源码地址" effect="dark" placement="bottom">
          <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
        </el-tooltip>
        <el-tooltip content="文档地址" effect="dark" placement="bottom">
          <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
        </el-tooltip>
        <header-search id="header-search" class="right-menu-item hover-effect" />
        <screenfull id="screenfull" class="right-menu-item hover-effect" />
@@ -40,8 +32,7 @@
      <el-dropdown @command="handleCommand" class="avatar-container right-menu-item hover-effect" trigger="hover">
        <div class="avatar-wrapper">
          <img :src="userStore.avatar" class="user-avatar" />
          <span class="user-nickname"> {{ userStore.nickName }} </span>
          <div class="avatar-initial">{{ avatarLetter }}</div>
        </div>
        <template #dropdown>
          <el-dropdown-menu>
@@ -74,8 +65,6 @@
import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect'
import HeaderSearch from '@/components/HeaderSearch'
import RuoYiGit from '@/components/RuoYi/Git'
import RuoYiDoc from '@/components/RuoYi/Doc'
import useAppStore from '@/store/modules/app'
import useUserStore from '@/store/modules/user'
import useLockStore from '@/store/modules/lock'
@@ -88,6 +77,9 @@
const userStore = useUserStore()
const lockStore = useLockStore()
const settingsStore = useSettingsStore()
// 顶栏头像为设计稿的绿色首字母圆,取昵称首字母(无昵称时兜底 A)
const avatarLetter = computed(() => (userStore.nickName || 'A').charAt(0).toUpperCase())
function toggleSideBar() {
  appStore.toggleSideBar()
@@ -190,6 +182,8 @@
  align-items: center;
  // padding: 0 8px;
  box-sizing: border-box;
  /* 品牌深蓝顶栏:hamburger 等用 fill="currentColor" 的图标继承白字 */
  color: #ffffff;
  .hamburger-container {
    line-height: 46px;
@@ -203,12 +197,24 @@
    margin-right: 8px;
    &:hover {
      background: rgba(0, 0, 0, 0.025);
      background: rgba(255, 255, 255, 0.12);
    }
  }
  .breadcrumb-container {
    flex-shrink: 0;
  }
  /* 面包屑在深蓝底上改白系(#breadcrumb-container 提权以盖过 Breadcrumb 组件内 .no-redirect 的灰字) */
  #breadcrumb-container {
    :deep(.el-breadcrumb__inner),
    :deep(.el-breadcrumb__separator) {
      color: rgba(255, 255, 255, 0.85);
    }
    :deep(.el-breadcrumb__inner.is-link:hover) {
      color: #ffffff;
    }
  }
  .topmenu-container {
@@ -236,27 +242,43 @@
      outline: none;
    }
    /* 设计稿顶栏右侧为一排白色描边的圆形图标按钮 */
    .right-menu-item {
      display: inline-block;
      padding: 0 8px;
      height: 100%;
      font-size: 18px;
      color: #5a5e66;
      vertical-align: text-bottom;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 30px;
      height: 30px;
      padding: 0;
      margin: 0 5px;
      font-size: 15px;
      color: #ffffff;
      border: 1px solid rgba(255, 255, 255, 0.35);
      border-radius: 50%;
      flex-shrink: 0;
      &.hover-effect {
        cursor: pointer;
        transition: background 0.3s;
        transition: background 0.3s, border-color 0.3s;
        &:hover {
          background: rgba(0, 0, 0, 0.025);
          background: rgba(255, 255, 255, 0.12);
          border-color: rgba(255, 255, 255, 0.6);
        }
      }
      /* 子组件自带的行高/内边距会在圆形按钮里偏心,归零让图标居中 */
      :deep(.size-icon--style) {
        line-height: 1;
        padding-right: 0;
      }
      :deep(.size-icon),
      :deep(.search-icon) {
        font-size: 15px;
      }
      &.theme-switch-wrapper {
        display: flex;
        align-items: center;
        svg {
          transition: transform 0.3s;
          
@@ -267,37 +289,29 @@
      }
    }
    .avatar-container {
      margin-right: 0px;
      padding-right: 0px;
    /* 头像容器不参与描边圆按钮:内层是设计稿的绿色首字母实心圆 */
    .avatar-container,
    .avatar-container.hover-effect:hover {
      border: none;
      background: transparent;
      .avatar-wrapper {
        margin-top: 10px;
        right: 8px;
        position: relative;
        display: flex;
        align-items: center;
        .user-avatar {
          cursor: pointer;
        .avatar-initial {
          display: flex;
          align-items: center;
          justify-content: center;
          width: 30px;
          height: 30px;
          margin-right: 8px;
          border-radius: 50%;
        }
        .user-nickname{
          position: relative;
          left: 0px;
          bottom: 10px;
          background-color: #80BF40;
          color: #ffffff;
          font-size: 14px;
          font-weight: bold;
        }
        i {
          font-weight: 600;
          cursor: pointer;
          position: absolute;
          right: -20px;
          top: 25px;
          font-size: 12px;
          user-select: none;
        }
      }
    }
hugray-admin/src/layout/components/Settings/index.vue
@@ -139,7 +139,7 @@
const sideTheme = ref(settingsStore.sideTheme)
const tagsViewPersist = ref(settingsStore.tagsViewPersist)
const storeSettings = computed(() => settingsStore)
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
const predefineColors = ref(["#80BF40", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
/** 是否需要dynamicTitle */
function dynamicTitleChange() {
@@ -203,14 +203,14 @@
    "sideTheme": storeSettings.value.sideTheme,
    "theme": storeSettings.value.theme
  }
  localStorage.setItem("layout-setting", JSON.stringify(layoutSetting))
  localStorage.setItem("layout-setting-v2", JSON.stringify(layoutSetting))
  setTimeout(proxy.$modal.closeLoading(), 1000)
}
function resetSetting() {
  proxy.$cache.local.remove('tags-view-visited')
  proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...")
  localStorage.removeItem("layout-setting")
  localStorage.removeItem("layout-setting-v2")
  setTimeout("window.location.reload()", 1000)
}
hugray-admin/src/layout/components/Sidebar/Logo.vue
@@ -35,7 +35,8 @@
    return 'var(--sidebar-bg)'
  }
  if (settingsStore.navType == 3) {
    return variables.menuLightBg
    // 顶部菜单模式下 Logo 位于品牌深蓝顶栏内,底色跟顶栏一致(原先取白色,在深蓝顶栏上会露出白块)
    return 'var(--navbar-bg)'
  }
  return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg
})
@@ -46,7 +47,7 @@
    return 'var(--sidebar-logo-text)'
  }
  if (settingsStore.navType == 3) {
    return variables.menuLightText
    return '#ffffff'
  }
  return sideTheme.value === 'theme-dark' ? '#fff' : variables.menuLightText
})
hugray-admin/src/layout/components/Sidebar/index.vue
@@ -8,7 +8,7 @@
        :background-color="getMenuBackground"
        :text-color="getMenuTextColor"
        :unique-opened="true"
        :active-text-color="theme"
        :active-text-color="getMenuActiveTextColor"
        :collapse-transition="false"
        mode="vertical"
        :class="sideTheme"
@@ -59,6 +59,16 @@
  return sideTheme.value === 'theme-dark' ? variables.menuText : variables.menuLightText
})
// 获取菜单选中项文字颜色
// 设计稿的深蓝侧栏中选中项为白字:主题色(绿)若渗进侧栏会与深蓝 chrome 冲突,
// 暗色模式与 theme-light 仍跟随主题色,保持原有行为
const getMenuActiveTextColor = computed(() => {
  if (!settingsStore.isDark && sideTheme.value === 'theme-dark') {
    return variables.menuActiveText
  }
  return theme.value
})
const activeMenu = computed(() => {
  const { meta, path } = route
  if (meta.activeMenu) {
hugray-admin/src/layout/components/TopBar/index.vue
@@ -67,7 +67,8 @@
  float: left;
  height: 50px !important;
  line-height: 50px !important;
  color: #303133 !important;
  /* 顶栏为品牌深蓝底,菜单文字用白系 */
  color: #ffffff !important;
  padding: 0 5px !important;
  margin: 0 10px !important;
}
@@ -80,7 +81,7 @@
.topbar-menu.el-menu--horizontal > .el-sub-menu .el-sub-menu__title {
  float: left;
  line-height: 50px !important;
  color: #303133 !important;
  color: #ffffff !important;
  margin: 0 15px -3px!important;
}
hugray-admin/src/layout/components/TopNav/index.vue
@@ -180,14 +180,15 @@
  float: left;
  height: 50px !important;
  line-height: 50px !important;
  color: #303133 !important;
  /* 顶栏为品牌深蓝底,菜单文字用白系 */
  color: #ffffff !important;
  padding: 0 5px !important;
  margin: 0 10px !important;
}
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title {
  border-bottom: 2px solid #{'var(--theme)'} !important;
  color: #303133;
  color: #ffffff;
}
/* sub-menu item */
@@ -195,14 +196,14 @@
  float: left;
  height: 50px !important;
  line-height: 50px !important;
  color: #303133 !important;
  color: #ffffff !important;
  padding: 0 5px !important;
  margin: 0 10px !important;
}
/* 背景色隐藏 */
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
  background-color: #ffffff;
  background-color: rgba(255, 255, 255, 0.12);
}
/* 图标右间距 */
hugray-admin/src/layout/index.vue
@@ -1,5 +1,6 @@
<template>
  <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme, '--current-color-light': theme + '1a', '--current-color-dark-bg': theme + '33' }">
  <!-- --current-color* 跟随主题色(页签栏选中项等);深色侧栏是固定的品牌深蓝,其选中/悬停覆盖层用固定白色,避免被主题色染成彩色块 -->
  <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme, '--current-color-light': theme + '1a', '--current-color-dark-bg': 'rgba(255, 255, 255, 0.12)' }">
    <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
    <sidebar v-if="!sidebar.hide" class="sidebar-container" />
    <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
hugray-admin/src/settings.js
@@ -62,6 +62,6 @@
  /**
   * 底部版权文本内容
   */
  footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
  footerContent: 'Copyright © 2018-2026 Hugray. All Rights Reserved.'
}
hugray-admin/src/store/modules/settings.js
@@ -8,14 +8,15 @@
const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
// v2:换肤后主题默认色由 #409EFF 改为 #80BF40,升级键名避免浏览器里的旧主题色覆盖新默认值
const storageSetting = JSON.parse(localStorage.getItem('layout-setting-v2')) || ''
const useSettingsStore = defineStore(
  'settings',
  {
    state: () => ({
      title: '',
      theme: storageSetting.theme || '#409EFF',
      theme: storageSetting.theme || '#80BF40',
      sideTheme: storageSetting.sideTheme || sideTheme,
      showSettings: showSettings,
      navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
hugray-admin/src/views/login.vue
@@ -1,65 +1,62 @@
<template>
  <div class="login">
    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
      <h3 class="title">{{ title }}</h3>
      <el-form-item prop="username">
    <!--  左侧品牌区:直接使用设计稿切图(含 Logo 与标语),图片底色 #0B3F6F 与面板底色一致,缩放后无缝  -->
    <div class="login-brand"></div>
    <!--  右侧表单区  -->
    <div class="login-panel">
      <el-form
        ref="loginRef"
        :model="loginForm"
        :rules="loginRules"
        label-position="top"
        hide-required-asterisk
        class="login-form"
      >
        <h3 class="title">登录</h3>
        <el-form-item label="账号" prop="username">
        <el-input
          v-model="loginForm.username"
          type="text"
          size="large"
          auto-complete="off"
          placeholder="账号"
        >
          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
        </el-input>
            placeholder="请输入"
            @keyup.enter="handleLogin"
          />
      </el-form-item>
      <el-form-item prop="password">
        <el-form-item label="密码" prop="password">
        <el-input
          v-model="loginForm.password"
          type="password"
          size="large"
          auto-complete="off"
          placeholder="密码"
            placeholder="请输入"
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
        </el-input>
          />
      </el-form-item>
      <el-form-item prop="code" v-if="captchaEnabled">
        <div class="login-options">
          <el-checkbox v-model="loginForm.rememberMe" class="remember">记住我</el-checkbox>
          <el-form-item prop="code" class="login-code" v-if="captchaEnabled">
        <el-input
          v-model="loginForm.code"
          size="large"
          auto-complete="off"
          placeholder="验证码"
          style="width: 63%"
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
        </el-input>
        <div class="login-code">
          <img :src="codeUrl" @click="getCode" class="login-code-img"/>
        </div>
            />
            <img :src="codeUrl" class="login-code-img" alt="验证码" @click="getCode" />
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
      <el-form-item style="width:100%;">
        <el-button
          :loading="loading"
          size="large"
          type="primary"
          style="width:100%;"
          @click.prevent="handleLogin"
        >
        </div>
        <div class="login-submit">
          <el-button :loading="loading" class="login-button" @click.prevent="handleLogin">
          <span v-if="!loading">登 录</span>
          <span v-else>登 录 中...</span>
        </el-button>
        <div style="float: right;" v-if="register">
        </div>
        <div class="login-register" v-if="register">
          <router-link class="link-type" :to="'/register'">立即注册</router-link>
        </div>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <div class="el-login-footer" v-if="footerVisible">
      <span>{{ footerContent }}</span>
      </div>
    </div>
  </div>
</template>
@@ -71,7 +68,7 @@
import useUserStore from '@/store/modules/user'
import defaultSettings from '@/settings'
const title = import.meta.env.VITE_APP_TITLE
const footerVisible = defaultSettings.footerVisible
const footerContent = defaultSettings.footerContent
const userStore = useUserStore()
const route = useRoute()
@@ -168,72 +165,166 @@
<style lang='scss' scoped>
.login {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-image: url("../assets/images/login-background.jpg");
  background-size: cover;
}
.title {
  margin: 0px auto 30px auto;
  text-align: center;
  color: #707070;
/* 左侧品牌区:设计稿切图按高度等比铺满,左右留白由同色底填充 */
.login-brand {
  flex: 0 0 61.5%;
  background-color: #0B3F6F;
  background-image: url("../assets/images/login-left.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}
/* 右侧表单区 */
.login-panel {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #80BF40;
}
.login-form {
  width: 360px;
  max-width: calc(100% - 32px);
  padding: 22px 52px 40px;
  background-color: #ffffff;
  border-radius: 6px;
  background: #ffffff;
  width: 400px;
  padding: 25px 25px 5px 25px;
  z-index: 1;
  .el-input {
    height: 40px;
    input {
      height: 40px;
    }
  }
  .input-icon {
    height: 39px;
    width: 14px;
    margin-left: 0px;
  }
}
.login-tip {
  font-size: 13px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.12);
  .title {
    margin: 0 0 18px;
  text-align: center;
  color: #bfbfbf;
    font-size: 16px;
    font-weight: 600;
    color: #0B3F6F;
}
  :deep(.el-form-item) {
    margin-bottom: 18px;
  }
  :deep(.el-form-item__label) {
    height: auto;
    padding: 0 0 8px;
    line-height: 1.2;
    font-size: 13px;
    color: #436596;
  }
  /* 输入框颜色与尺寸全部写死,避免暗色主题的 CSS 变量把白底黑字改掉 */
  :deep(.el-input__wrapper) {
    padding: 0 12px;
    border-radius: 4px;
    background-color: #ffffff;
    box-shadow: 0 0 0 1px #D2D2D2 inset;
    &:hover {
      box-shadow: 0 0 0 1px #C0C4CC inset;
    }
    &.is-focus {
      box-shadow: 0 0 0 1px #0B3F6F inset;
    }
  }
  :deep(.el-input__inner) {
    height: 36px;
    font-size: 13px;
    color: #333333;
    &::placeholder {
      color: #9DA6B3;
    }
  }
  .login-options {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
  }
  .remember {
    --el-checkbox-checked-bg-color: #1684FC;
    --el-checkbox-checked-input-border-color: #1684FC;
    --el-checkbox-checked-icon-color: #ffffff;
    --el-checkbox-input-border-color-hover: #1684FC;
    :deep(.el-checkbox__label) {
      font-size: 13px;
      color: #333333;
    }
  }
  /* 验证码输入框与图片同排,去掉表单项自身的下边距以与「记住我」垂直居中 */
.login-code {
  width: 33%;
  height: 40px;
  float: right;
  img {
    cursor: pointer;
    flex: 0 1 auto;
    min-width: 0;
    margin-bottom: 0;
    :deep(.el-form-item__content) {
      flex-wrap: nowrap;
      gap: 8px;
    }
    :deep(.el-input) {
      flex: 0 1 88px;
      width: 88px;
      min-width: 56px;
    }
  }
  .login-code-img {
    flex: 0 0 auto;
    height: 36px;
    border-radius: 4px;
    vertical-align: middle;
    cursor: pointer;
  }
  .login-submit {
    margin-top: 34px;
    text-align: center;
  }
  .login-button {
    width: 140px;
    height: 36px;
    font-size: 14px;
    letter-spacing: 1px;
    color: #ffffff;
    background-color: #0B3F6F;
    border-color: #0B3F6F;
    border-radius: 4px;
    &:hover,
    &:focus {
      color: #ffffff;
      background-color: #0A3660;
      border-color: #0A3660;
  }
}
}
.login-register {
  margin-top: 12px;
  text-align: center;
}
.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  height: 40px;
  line-height: 40px;
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}
.login-code-img {
  height: 40px;
  padding-left: 12px;
  color: rgba(11, 63, 111, 0.65);
}
html.dark .login {
  background-image: linear-gradient(rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.55)), url("../assets/images/login-background.jpg");
  .login-form {
    background: var(--el-bg-color-overlay) !important;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
/* 窄屏收起品牌区,保证表单可用 */
@media (max-width: 960px) {
  .login-brand {
    display: none;
  }
}
</style>