Pre Merge pull request !259 from jinglv/theme-color-reload-partially-invalid

pull/259/MERGE
jinglv 3 years ago committed by Gitee
commit 952fd63936
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F

@ -1,273 +1,269 @@
/** /**
* css * css
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
/** 基础通用 **/ /** 基础通用 **/
.pt5 { .pt5 {
padding-top: 5px; padding-top: 5px;
} }
.pr5 { .pr5 {
padding-right: 5px; padding-right: 5px;
} }
.pb5 { .pb5 {
padding-bottom: 5px; padding-bottom: 5px;
} }
.mt5 { .mt5 {
margin-top: 5px; margin-top: 5px;
} }
.mr5 { .mr5 {
margin-right: 5px; margin-right: 5px;
} }
.mb5 { .mb5 {
margin-bottom: 5px; margin-bottom: 5px;
} }
.mb8 { .mb8 {
margin-bottom: 8px; margin-bottom: 8px;
} }
.ml5 { .ml5 {
margin-left: 5px; margin-left: 5px;
} }
.mt10 { .mt10 {
margin-top: 10px; margin-top: 10px;
} }
.mr10 { .mr10 {
margin-right: 10px; margin-right: 10px;
} }
.mb10 { .mb10 {
margin-bottom: 10px; margin-bottom: 10px;
} }
.ml10 { .ml10 {
margin-left: 10px; margin-left: 10px;
} }
.mt20 { .mt20 {
margin-top: 20px; margin-top: 20px;
} }
.mr20 { .mr20 {
margin-right: 20px; margin-right: 20px;
} }
.mb20 { .mb20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.ml20 { .ml20 {
margin-left: 20px; margin-left: 20px;
} }
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
font-family: inherit; font-family: inherit;
font-weight: 500; font-weight: 500;
line-height: 1.1; line-height: 1.1;
color: inherit; color: inherit;
} }
.el-dialog:not(.is-fullscreen) { .el-dialog:not(.is-fullscreen) {
margin-top: 6vh !important; margin-top: 6vh !important;
} }
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body { .el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
max-height: 70vh; max-height: 70vh;
padding: 10px 20px 0; padding: 10px 20px 0;
} }
.el-table { .el-table {
.el-table__header-wrapper, .el-table__fixed-header-wrapper { .el-table__header-wrapper, .el-table__fixed-header-wrapper {
th { th {
word-break: break-word; word-break: break-word;
background-color: #f8f8f9; background-color: #f8f8f9;
color: #515a6e; color: #515a6e;
height: 40px; height: 40px;
font-size: 13px; font-size: 13px;
} }
} }
.el-table__body-wrapper { .el-table__body-wrapper {
.el-button [class*="el-icon-"] + span { .el-button [class*="el-icon-"] + span {
margin-left: 1px; margin-left: 1px;
} }
} }
} }
/** 表单布局 **/ /** 表单布局 **/
.form-header { .form-header {
font-size:15px; font-size:15px;
color:#6379bb; color:#6379bb;
border-bottom:1px solid #ddd; border-bottom:1px solid #ddd;
margin:8px 10px 25px 10px; margin:8px 10px 25px 10px;
padding-bottom:5px padding-bottom:5px
} }
/** 表格布局 **/ /** 表格布局 **/
.pagination-container { .pagination-container {
position: relative; position: relative;
height: 25px; height: 25px;
margin-bottom: 10px; margin-bottom: 10px;
margin-top: 15px; margin-top: 15px;
padding: 10px 20px !important; padding: 10px 20px !important;
} }
/* tree border */ /* tree border */
.tree-border { .tree-border {
margin-top: 5px; margin-top: 5px;
border: 1px solid #e5e6e7; border: 1px solid #e5e6e7;
background: #FFFFFF none; background: #FFFFFF none;
border-radius:4px; border-radius:4px;
} }
.pagination-container .el-pagination { .pagination-container .el-pagination {
right: 0; right: 0;
position: absolute; position: absolute;
} }
@media ( max-width : 768px) { @media ( max-width : 768px) {
.pagination-container .el-pagination > .el-pagination__jump { .pagination-container .el-pagination > .el-pagination__jump {
display: none !important; display: none !important;
} }
.pagination-container .el-pagination > .el-pagination__sizes { .pagination-container .el-pagination > .el-pagination__sizes {
display: none !important; display: none !important;
} }
} }
.el-table .fixed-width .el-button--mini { .el-table .fixed-width .el-button--mini {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
width: inherit; width: inherit;
} }
/** 表格更多操作下拉样式 */ /** 表格更多操作下拉样式 */
.el-table .el-dropdown-link { .el-button+.el-dropdown{margin-left: 10px;}
cursor: pointer;
color: #409EFF; .el-table .el-dropdown, .el-icon-arrow-down {
margin-left: 5px; font-size: 12px;
} }
.el-table .el-dropdown, .el-icon-arrow-down { .el-tree-node__content > .el-checkbox {
font-size: 12px; margin-right: 8px;
} }
.el-tree-node__content > .el-checkbox { .list-group-striped > .list-group-item {
margin-right: 8px; border-left: 0;
} border-right: 0;
border-radius: 0;
.list-group-striped > .list-group-item { padding-left: 0;
border-left: 0; padding-right: 0;
border-right: 0; }
border-radius: 0;
padding-left: 0; .list-group {
padding-right: 0; padding-left: 0px;
} list-style: none;
}
.list-group {
padding-left: 0px; .list-group-item {
list-style: none; border-bottom: 1px solid #e7eaec;
} border-top: 1px solid #e7eaec;
margin-bottom: -1px;
.list-group-item { padding: 11px 0px;
border-bottom: 1px solid #e7eaec; font-size: 13px;
border-top: 1px solid #e7eaec; }
margin-bottom: -1px;
padding: 11px 0px; .pull-right {
font-size: 13px; float: right !important;
} }
.pull-right { .el-card__header {
float: right !important; padding: 14px 15px 7px;
} min-height: 40px;
}
.el-card__header {
padding: 14px 15px 7px; .el-card__body {
min-height: 40px; padding: 15px 20px 20px 20px;
} }
.el-card__body { .card-box {
padding: 15px 20px 20px 20px; padding-right: 15px;
} padding-left: 15px;
margin-bottom: 10px;
.card-box { }
padding-right: 15px;
padding-left: 15px; /* button color */
margin-bottom: 10px; .el-button--cyan.is-active,
} .el-button--cyan:active {
background: #20B2AA;
/* button color */ border-color: #20B2AA;
.el-button--cyan.is-active, color: #FFFFFF;
.el-button--cyan:active { }
background: #20B2AA;
border-color: #20B2AA; .el-button--cyan:focus,
color: #FFFFFF; .el-button--cyan:hover {
} background: #48D1CC;
border-color: #48D1CC;
.el-button--cyan:focus, color: #FFFFFF;
.el-button--cyan:hover { }
background: #48D1CC;
border-color: #48D1CC; .el-button--cyan {
color: #FFFFFF; background-color: #20B2AA;
} border-color: #20B2AA;
color: #FFFFFF;
.el-button--cyan { }
background-color: #20B2AA;
border-color: #20B2AA; /* text color */
color: #FFFFFF; .text-navy {
} color: #1ab394;
}
/* text color */
.text-navy { .text-primary {
color: #1ab394; color: inherit;
} }
.text-primary { .text-success {
color: inherit; color: #1c84c6;
} }
.text-success { .text-info {
color: #1c84c6; color: #23c6c8;
} }
.text-info { .text-warning {
color: #23c6c8; color: #f8ac59;
} }
.text-warning { .text-danger {
color: #f8ac59; color: #ed5565;
} }
.text-danger { .text-muted {
color: #ed5565; color: #888888;
} }
.text-muted { /* image */
color: #888888; .img-circle {
} border-radius: 50%;
}
/* image */
.img-circle { .img-lg {
border-radius: 50%; width: 120px;
} height: 120px;
}
.img-lg {
width: 120px; .avatar-upload-preview {
height: 120px; position: absolute;
} top: 50%;
transform: translate(50%, -50%);
.avatar-upload-preview { width: 200px;
position: absolute; height: 200px;
top: 50%; border-radius: 50%;
transform: translate(50%, -50%); box-shadow: 0 0 4px #ccc;
width: 200px; overflow: hidden;
height: 200px; }
border-radius: 50%;
box-shadow: 0 0 4px #ccc; /* 拖拽列样式 */
overflow: hidden; .sortable-ghost{
} opacity: .8;
color: #fff!important;
/* 拖拽列样式 */ background: #42b983!important;
.sortable-ghost{ }
opacity: .8;
color: #fff!important; .top-right-btn {
background: #42b983!important; position: relative;
} float: right;
}
.top-right-btn {
position: relative;
float: right;
}

@ -1,173 +1,56 @@
<template> <template>
<el-color-picker <el-color-picker
v-model="theme" v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker" class="theme-picker"
popper-class="theme-picker-dropdown" popper-class="theme-picker-dropdown"
/> />
</template> </template>
<script> <script>
const version = require('element-ui/package.json').version // element-ui version from node_modules export default {
const ORIGINAL_THEME = '#409EFF' // default color data() {
return {
export default { theme: ''
data() { }
return { },
chalk: '', // content of theme-chalk css computed: {
theme: '' defaultTheme() {
} return this.$store.state.settings.theme
}, }
computed: { },
defaultTheme() { watch: {
return this.$store.state.settings.theme defaultTheme: {
} handler: function(val, oldVal) {
}, this.theme = val
watch: { },
defaultTheme: { immediate: true
handler: function(val, oldVal) { },
this.theme = val theme(val) {
}, this.setTheme(val)
immediate: true }
}, },
async theme(val) { methods: {
await this.setTheme(val) setTheme(val){
} this.$emit('change', val)
}, },
created() { }
if(this.defaultTheme !== ORIGINAL_THEME) { }
this.setTheme(this.defaultTheme) </script>
}
}, <style>
.theme-message,
methods: { .theme-picker-dropdown {
async setTheme(val) { z-index: 99999 !important;
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME }
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', '')) .theme-picker .el-color-picker__trigger {
const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) height: 26px !important;
width: 26px !important;
const getHandler = (variable, id) => { padding: 2px;
return () => { }
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) .theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
let styleTag = document.getElementById(id) }
if (!styleTag) { </style>
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$emit('change', val)
},
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</script>
<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>

@ -1,42 +1,164 @@
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const state = {
title: '', import Vue from 'vue'
theme: storageSetting.theme || '#409EFF', storageSetting.theme&&setThemeColor(storageSetting.theme)
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings, const state = {
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, title: '',
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, theme: storageSetting.theme || '#409EFF',
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, sideTheme: storageSetting.sideTheme || sideTheme,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, showSettings: showSettings,
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
} tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
const mutations = { fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
CHANGE_SETTING: (state, { key, value }) => { sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
if (state.hasOwnProperty(key)) { dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
state[key] = value }
} const mutations = {
} CHANGE_SETTING: (state, { key, value }) => {
} if (state.hasOwnProperty(key)) {
state[key] = value
const actions = { if(key==='theme'){
// 修改布局设置 setThemeColor(value)
changeSetting({ commit }, data) { }
commit('CHANGE_SETTING', data) }
}, }
// 设置网页标题 }
setTitle({ commit }, title) {
state.title = title const actions = {
} // 修改布局设置
} changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
export default { },
namespaced: true, // 设置网页标题
state, setTitle({ commit }, title) {
mutations, state.title = title
actions }
} }
function setThemeColor(val,oldColor){
let chalk=''
let theme=''
const ORIGINAL_THEME = '#409EFF'
const version = require('element-ui/package.json').version
setTheme(val)
async function setTheme(val) {
const oldVal = chalk ? theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = getThemeCluster(val.replace('#', ''))
const originalCluster = getThemeCluster(oldVal.replace('#', ''))
const getHandler = (variable, id) => {
return () => {
const originalCluster = getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = updateStyle(Vue[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await getCSSString(url, 'chalk')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = updateStyle(innerText, originalCluster, themeCluster)
})
}
function updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
}
function getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
Vue[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
}
function getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save