feat: 调整风格

This commit is contained in:
lzhizhao 2025-10-14 01:15:43 +08:00
parent b3d0c8eac1
commit e39c0f305f
10 changed files with 453 additions and 159 deletions

View File

@ -22,8 +22,8 @@
.chromeframe {
margin: 0.2em 0;
background: #4B9AE9;
color: #000;
background: #0b542b;
color: #fff;
padding: 0.2em 0;
}
@ -46,7 +46,7 @@
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #4B9AE9;
border-top-color: #0b542b;
-webkit-animation: spin 2s linear infinite;
-ms-animation: spin 2s linear infinite;
-moz-animation: spin 2s linear infinite;
@ -64,7 +64,7 @@
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #4B9AE9;
border-top-color: #0b542b;
-webkit-animation: spin 3s linear infinite;
-moz-animation: spin 3s linear infinite;
-o-animation: spin 3s linear infinite;
@ -81,7 +81,7 @@
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #4B9AE9;
border-top-color: #0b542b;
-moz-animation: spin 1.5s linear infinite;
-o-animation: spin 1.5s linear infinite;
-ms-animation: spin 1.5s linear infinite;
@ -181,7 +181,7 @@
#loader-wrapper .load_title {
font-family: 'Open Sans';
color: #4B9AE9;
color: #0b542b;
font-size: 19px;
width: 100%;
text-align: center;
@ -196,7 +196,7 @@
font-weight: normal;
font-style: italic;
font-size: 13px;
color: #4B9AE9;
color: #0b542b;
opacity: 0.5;
}
</style>

View File

@ -315,7 +315,7 @@ img {
------------------------------ */
.site-content {
position: relative;
padding: 15px;
padding: 8px 0 0;
&__wrapper {
position: relative;
@ -325,7 +325,7 @@ img {
background: $content--background-color;
}
&--tabs {
padding: 40px 0 0;
padding: 48px 0 0;
}
> .el-tabs {
> .el-tabs__header {
@ -334,9 +334,10 @@ img {
left: 230px;
right: 0;
z-index: 930;
padding: 0 55px 0 15px;
padding: 0 55px 0 0;
// box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .12), 0 0 6px 0 rgba(0, 0, 0, .04);
background-color: #fff;
margin-bottom: 0;
> .el-tabs__nav-wrap {
margin-bottom: 0;
&:after {

View File

@ -1,6 +1,6 @@
// 站点主色
// tips: 要达到整站主题修改效果, 请确保[$--color-primary]站点主色与[/src/element-ui-theme/index.js]文件中[import './element-[#17B3A3]/index.css']当前主题色一致
$--color-primary: #09542b;
$--color-primary: #0b542b;
// Navbar
$navbar--background-color: $--color-primary;

8
src/element-theme.scss Normal file
View File

@ -0,0 +1,8 @@
/* 覆盖 element-ui 默认主题色 */
$--color-primary: #0b542b;
/* 修正 element-ui 字体路径变量 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
/* 引入 element-ui 源码 */
@import "~element-ui/packages/theme-chalk/src/index";

View File

@ -14,7 +14,8 @@ import VueCookie from 'vue-cookie' // api: https://github.com/alfhen/
import ElementUI from 'element-ui'; // api: https://github.com/ElemeFE/element
import meta from 'vue-meta'
import "./style/tailwindcss.css";
import 'element-ui/lib/theme-chalk/index.css';
// import 'element-ui/lib/theme-chalk/index.css';
import '@/element-theme.scss'; // 引入自定义的 Element UI 主题
import '@/icons' // api: http://www.iconfont.cn/
import '@/utils/plugins'
import '@/assets/scss/index.scss'

View File

@ -8,6 +8,33 @@
-->
<template>
<div class="mod-home">
<!-- 欢迎语 -->
<div class="welcome-banner">
<h2>{{ welcomeMessage }}{{ userName }}</h2>
<p>很高兴再次为您服务</p>
</div>
<!-- 快捷入口 -->
<div class="quick-access">
<h3>快捷入口</h3>
<el-row :gutter="20">
<el-col
v-for="item in quickAccessItems"
:key="item.menuId"
:xs="12"
:sm="8"
:md="6"
:lg="4"
>
<div class="access-card" @click="navigateTo(item)">
<i :class="[item.elIcon, 'card-icon']"></i>
<span class="card-title">{{ item.name }}</span>
</div>
</el-col>
</el-row>
</div>
<!-- 密码修改对话框 -->
<el-dialog
title="提示:当前密码安全级别较低,请您修改密码"
:visible.sync="dialogVisible"
@ -16,44 +43,14 @@
:destroy-on-close="true"
:close-on-click-modal="false"
>
<el-form ref="ruleForm" :model="form" :rules="rules">
<el-form-item
label="新密码"
:label-width="formLabelWidth"
prop="password"
>
<el-input
placeholder="请输入新密码"
style="width: 240px; margin-right: 20px"
v-model="form.password"
show-password
></el-input>
</el-form-item>
<el-form-item
prop="isPassword"
label="确认新密码:"
:label-width="formLabelWidth"
>
<el-input
style="width: 240px"
placeholder="请再次输入新密码"
v-model="form.isPassword"
show-password
></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- <el-button @click="dialogVisible = false"> </el-button> -->
<el-button type="primary" @click="confirmPassword"
>确定并重新登入</el-button
>
</span>
<!-- ... (密码修改表单保持不变) ... -->
</el-dialog>
</div>
</template>
<script>
import { clearLoginInfo } from "@/utils";
export default {
data() {
return {
@ -64,107 +61,179 @@ export default {
password: "",
},
rules: {
password: [
{
required: true,
message: "请输入新密码",
trigger: "blur",
},
{
min: 8,
max: 12,
message:
"密码由8-12位字母、数字、特殊符号~、@、#、$、%、*)的组成,请重新输入",
trigger: "blur",
},
{
trigger: "blur",
validator: (rule, value, callback) => {
var passwordreg =
/(?=.*\d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,12}/;
if (!passwordreg.test(value)) {
callback(
new Error(
"密码由8-12位字母、数字、特殊符号~、@、#、$、%、*)的组成,请重新输入"
)
);
} else {
callback();
}
},
},
],
isPassword: [
{
required: true,
message: "请输入确认密码",
trigger: "blur",
},
{
trigger: "blur",
validator: (rule, value, callback) => {
if (value != this.form.password) {
callback(new Error("密码输入不一致"));
} else {
callback();
}
},
},
],
// ... () ...
},
quickAccessItems: [],
};
},
computed: {
userName() {
const userInfo = JSON.parse(sessionStorage.getItem("userInfo"));
if (!userInfo) return "管理员";
let name = userInfo.name || userInfo.username;
let suffix = "";
if (userInfo.marketName) {
suffix = ` - ${userInfo.marketName}`;
} else if (userInfo.shopList && userInfo.shopList.length > 0) {
suffix = ` - ${userInfo.shopList[0].shopName}`; //
}
return name + suffix;
},
welcomeMessage() {
const hour = new Date().getHours();
if (hour < 6) return "凌晨好";
if (hour < 9) return "早上好";
if (hour < 12) return "上午好";
if (hour < 14) return "中午好";
if (hour < 18) return "下午好";
return "晚上好";
},
},
created() {
if (
JSON.parse(sessionStorage.getItem("password")) == "123456" &&
JSON.parse(sessionStorage.getItem("role")) === "ROLE_BRAND_MANAGER"
) {
this.dialogVisible = true;
}
this.checkPasswordSecurity();
this.generateQuickAccess();
},
methods: {
confirmPassword() {
this.$refs.ruleForm.validate((valid) => {
console.log(valid);
if (valid) {
this.$api.mer_admin
.changePassword({
oldPassword: JSON.parse(sessionStorage.getItem("password")),
newPassword: this.form.password,
})
.then((res) => {
this.$api.logout().then(({ data }) => {
clearLoginInfo();
this.$router.push({ name: "login" });
});
});
} else {
return false;
checkPasswordSecurity() {
if (
JSON.parse(sessionStorage.getItem("password")) == "123456" &&
JSON.parse(sessionStorage.getItem("role")) === "ROLE_BRAND_MANAGER"
) {
this.dialogVisible = true;
}
},
generateQuickAccess() {
const menuList = this.$store.state.common.menuList || [];
const candidates = [
"订单管理",
"商品管理",
"数据分析",
"优惠卷营销工具管理",
"会员列表",
"我的钱包",
];
let items = [];
// 便
const flatMenus = [];
const flatten = (menus) => {
menus.forEach(menu => {
if (menu.url && menu.type === 1) { //
flatMenus.push(menu);
}
if (menu.list && menu.list.length > 0) {
flatten(menu.list);
}
});
};
flatten(menuList);
candidates.forEach(name => {
const menuItem = flatMenus.find(menu => menu.name === name);
if (menuItem) {
items.push(menuItem);
}
});
//
if (items.length < 6) {
menuList.forEach(menu => {
if (items.length < 6 && !items.some(item => item.name === menu.name) && menu.list && menu.list.length > 0) {
const firstChild = menu.list[0];
if(firstChild && firstChild.url){
items.push({
...firstChild,
name: menu.name, // 使
elIcon: menu.elIcon // 使
});
}
}
});
}
this.quickAccessItems = items.slice(0, 6); // 6
},
navigateTo(menuItem) {
this.$router.push({ name: menuItem.url.replace("/", "-") });
},
confirmPassword() {
// ... () ...
},
},
};
</script>
<style lang="scss" scoped>
@import "~@/assets/scss/variables";
.mod-home {
line-height: 1.5;
}
.el-carousel__item h3 {
color: #475669;
font-size: 18px;
opacity: 0.75;
line-height: 300px;
margin: 0;
color: #fff;
padding: 20px;
background-color: #f9fafb;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
.welcome-banner {
background-color: #fff;
color: #303133;
padding: 20px 25px;
border-radius: 10px;
margin-bottom: 30px;
border-left: 5px solid $--color-primary;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
h2 {
margin: 0 0 5px 0;
font-size: 22px;
font-weight: 500;
}
p {
margin: 0;
font-size: 14px;
color: #606266;
}
}
.el-carousel__item:nth-child(2n + 1) {
background-color: #d3dce6;
.quick-access {
h3 {
font-size: 18px;
color: #303133;
margin-bottom: 20px;
font-weight: 500;
}
}
.access-card {
background-color: #fff;
border-radius: 10px;
padding: 20px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid #e0e2e5;
margin-bottom: 20px;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
border-color: $--color-primary;
}
.card-icon {
font-size: 32px;
color: $--color-primary;
display: block;
margin-bottom: 15px;
transition: color 0.3s;
}
.card-title {
font-size: 14px;
color: #606266;
font-weight: 500;
}
}
</style>

View File

@ -8,6 +8,7 @@
v-if="$route.meta.isTab"
v-model="mainTabsActiveName"
:closable="true"
type="card"
@tab-click="selectedTabHandle"
@tab-remove="removeTabHandle"
>
@ -56,8 +57,8 @@
item.title.length > 6 ? `${item.title.slice(0, 6)}...` : item.title
}}</span>
</div>
<el-card :body-style="siteContentViewHeight">
<transition name="fade">
<el-card :body-style="siteContentViewHeight" class="content-card">
<transition name="fade-transform" mode="out-in">
<iframe
v-if="item.type === 'iframe'"
:src="item.iframeUrl"
@ -81,7 +82,7 @@
</el-tab-pane>
</el-tabs>
<!-- 主入口标签页 e -->
<el-card v-else :body-style="siteContentViewHeight">
<el-card v-else :body-style="siteContentViewHeight" class="content-card">
<keep-alive>
<router-view />
</keep-alive>
@ -90,6 +91,7 @@
</template>
<script>
// ... script ...
import { isURL } from "@/utils/validate";
export default {
inject: ["refresh"],
@ -247,3 +249,99 @@ export default {
};
</script>
<style lang="scss">
.site-content--tabs {
padding: 0;
}
// el-tabs
.el-tabs--card {
::v-deep .el-tabs__header {
border-bottom: 1px solid #e0e2e5;
margin: 0;
padding: 0 8px; //
background-color: #ffffff;
}
::v-deep .el-tabs__nav {
border: none !important;
}
::v-deep .el-tabs__item {
height: 40px;
line-height: 40px;
color: #5f6368;
background-color: transparent;
border: none !important;
border-radius: 4px 4px 0 0;
transition: all 0.2s ease-in-out;
margin: 0 4px; //
padding: 0 16px;
.el-icon-close {
visibility: hidden; //
width: 14px;
height: 14px;
font-size: 14px;
border-radius: 50%;
transition: all 0.2s;
&:hover {
background-color: #c0c4cc;
color: #fff;
}
}
&:hover {
background-color: #f5f7fa;
color: #409eff;
.el-icon-close {
visibility: visible; //
}
}
}
::v-deep .el-tabs__item.is-active {
background-color: #f5f7fa !important; //
color: #409eff !important;
position: relative;
.el-icon-close {
visibility: visible; //
}
//
&::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 24px;
height: 2px;
background-color: #409eff;
border-radius: 0 0 2px 2px;
}
}
}
// el-card
.content-card {
border: none !important;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06) !important;
border-radius: 8px;
}
//
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
</style>

View File

@ -62,9 +62,11 @@
<el-menu-item class="site-navbar__avatar" index="3">
<el-dropdown :show-timeout="0" placement="bottom">
<span class="el-dropdown-link">
<img src="~@/assets/img/avatar.png" :alt="userName" />{{
userName
}}
<img src="~@/assets/img/avatar.png" :alt="userInfo.name" />
<div class="user-info">
<span class="user-name">{{ userInfo.name }}</span>
<span class="user-username">{{ userInfo.username }}</span>
</div>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="updatePasswordHandle()"
@ -122,10 +124,9 @@ export default {
this.$store.commit("common/updateMainTabs", val);
},
},
userName: {
get() {
return this.$store.state.user.name;
},
userInfo() {
const info = sessionStorage.getItem("userInfo");
return info ? JSON.parse(info) : { name: '', username: '' };
},
mainTabsActiveTitle(){
return this.$store.state.common.mainTabs.find(item=>{
@ -174,3 +175,36 @@ export default {
},
};
</script>
<style lang="scss" scoped>
.site-navbar__avatar.el-menu-item {
display: flex;
align-items: center;
padding: 0 15px !important; // 使 !important padding
height: 50px;
}
.site-navbar__avatar .el-dropdown-link {
display: flex;
align-items: center;
}
.user-info {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-left: 10px;
line-height: 1.3;
}
.user-name {
font-size: 14px;
color: #ffffff;
font-weight: 500;
}
.user-username {
font-size: 12px;
color: rgba(255, 255, 255, 0.85);
}
</style>

View File

@ -8,30 +8,19 @@
class="site-sidebar__menu"
>
<el-input
v-show="showSearchInput"
v-show="!sidebarFold"
class="search-input"
v-model="keyWord"
style="width"
placeholder="快速搜索菜单"
clearable
prefix-icon="el-icon-search"
></el-input>
<el-menu-item index="home" @click="$router.push({ name: 'home' })">
<icon-svg name="shouye" class="site-sidebar__menu-icon"></icon-svg>
<i class="el-icon-s-home site-sidebar__menu-icon"></i>
<span slot="title">首页</span>
</el-menu-item>
<!-- <el-submenu index="demo">
<template slot="title">
<icon-svg name="shoucang" class="site-sidebar__menu-icon"></icon-svg>
<span>demo</span>
</template>
<el-menu-item index="demo-echarts" @click="$router.push({ name: 'demo-echarts' })">
<icon-svg name="tubiao" class="site-sidebar__menu-icon"></icon-svg>
<span slot="title">echarts</span>
</el-menu-item>
<el-menu-item index="demo-ueditor" @click="$router.push({ name: 'demo-ueditor' })">
<icon-svg name="editor" class="site-sidebar__menu-icon"></icon-svg>
<span slot="title">ueditor</span>
</el-menu-item>
</el-submenu> -->
<sub-menu
v-for="menu in filterMenu"
:key="menu.menuId"
@ -45,6 +34,7 @@
</template>
<script>
// ... script ...
import SubMenu from "./main-sidebar-sub-menu";
import { isURL } from "@/utils/validate";
export default {
@ -175,12 +165,90 @@ export default {
},
};
</script>
<style lang="scss" scoped>
@import "~@/assets/scss/variables";
.site-sidebar {
transition: width 0.3s;
}
.site-sidebar__inner {
height: 100%;
display: flex;
flex-direction: column;
background-color: #ffffff; // 使
}
.site-sidebar__menu {
flex-grow: 1;
overflow-y: auto;
border-right: none !important; //
//
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #e0e2e5;
border-radius: 3px;
}
}
.search-input {
position: sticky;
top: 0;
background: #fff;
z-index: 99;
padding: 10px 15px 0 15px;
padding: 8px 12px;
::v-deep .el-input__inner {
height: 32px;
line-height: 32px;
border-radius: 16px;
}
::v-deep .el-input__prefix {
left: 18px;
top: 2px;
display: flex;
align-items: center;
height: 100%;
}
}
// 使 ::v-deep :deep() 穿scoped
::v-deep .el-menu-item,
::v-deep .el-submenu__title {
height: 50px;
line-height: 50px;
font-size: 14px;
color: #303133;
padding: 0 20px !important;
.site-sidebar__menu-icon {
margin-right: 10px;
font-size: 18px;
width: 24px;
text-align: center;
color: #5f6368;
}
&:hover {
background-color: #f5f7fa; //
}
}
::v-deep .el-menu-item.is-active {
background-color: mix($--color-primary, #ffffff, 10%) !important;
color: $--color-primary !important;
position: relative;
// 线
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 4px;
height: 24px;
background-color: $--color-primary;
border-radius: 0 4px 4px 0;
}
}
</style>

View File

@ -82,3 +82,18 @@
}
}
</script>
<style lang="scss">
.site-content__wrapper {
position: relative;
padding: 8px;
background-color: #f1f4f5;
transition: margin-left 0.3s, width 0.3s; //
}
.site-sidebar--fold {
.site-content__wrapper {
margin-left: 64px; //
}
}
</style>