浏览代码

修改主题色

lex-xin 3 年之前
父节点
当前提交
6951e47d15

+ 3 - 0
src/App.vue

@@ -39,6 +39,9 @@ export default {
 [v-cloak] {
   display: none !important;
 }
+#app {
+  --color-primary: #14928a;
+}
 body {
   background-color: #eef4f9 !important;
 }

+ 8 - 8
src/components/ThemePicker/index.vue

@@ -37,13 +37,13 @@ export default {
       const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
       console.log(themeCluster, originalCluster)
 
-      const $message = this.$message({
-        message: '  Compiling the theme',
-        customClass: 'theme-message',
-        type: 'success',
-        duration: 0,
-        iconClass: 'el-icon-loading'
-      })
+      // const $message = this.$message({
+      //   message: 'Compiling the theme',
+      //   customClass: 'theme-message',
+      //   type: 'success',
+      //   duration: 0,
+      //   iconClass: 'el-icon-loading'
+      // })
 
       const getHandler = (variable, id) => {
         return () => {
@@ -82,7 +82,7 @@ export default {
 
       this.$emit('change', val)
 
-      $message.close()
+      // $message.close()
     }
   },
 

+ 12 - 12
src/main.js

@@ -58,22 +58,22 @@ class DonMessage {
   }
   error(options, single = true) {
       this[showMessage]('error', options, single)
+  }
+  [showMessage](type, options, single) {
+    // console.log(type, options, Message)
+    let params = {
+      message: options,
+      offset: 90
     }
-    [showMessage](type, options, single) {
-      // console.log(type, options, Message)
-      let params = {
-        message: options,
-        offset: 90
-      }
-      if (single) {
-        // 判断是否已存在Message
-        if (document.getElementsByClassName('el-message').length === 0) {
-          Message[type](params)
-        }
-      } else {
+    if (single) {
+      // 判断是否已存在Message
+      if (document.getElementsByClassName('el-message').length === 0) {
         Message[type](params)
       }
+    } else {
+      Message[type](params)
     }
+  }
 }
 
 // 修改默认属性

+ 127 - 0
src/utils/setTheme.js

@@ -0,0 +1,127 @@
+// 设置系统主题和主题色
+import { showFullScreenLoading, tryHideFullScreenLoading } from './request-loading'
+const version = require('element-ui/package.json').version // element-ui version from node_modules
+const ORIGINAL_THEME = '#409EFF' // default color
+
+let chalk = ''
+let theme = ''
+
+export const setTheme = async (val, isLoading) => { // 是否显示加载样式
+  const oldVal = ORIGINAL_THEME
+  if (typeof val !== 'string') return
+  const themeCluster = getThemeCluster(val.replace('#', ''))
+  const originalCluster = getThemeCluster(oldVal.replace('#', ''))
+
+  if(isLoading) {
+    showFullScreenLoading()
+  }
+
+  const getHandler = (variable, id) => {
+    return () => {
+      const originalCluster = getThemeCluster(ORIGINAL_THEME.replace('#', ''))
+      const newStyle = updateStyle(chalk, 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)
+  })
+
+  const element = document.getElementById('app')
+  element.style.setProperty('--color-primary', val)
+
+  if(isLoading) {
+    tryHideFullScreenLoading()
+  }
+}
+
+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) {
+        chalk = 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
+}

+ 1 - 6
src/views/adapayAccount/form.vue

@@ -7,11 +7,10 @@
     </h2>
     <div class="m-core"
          style="overflow: hidden">
-      <el-col :span="10">
+      <el-col :span="12" :lg="14" :md="20" :sm="20" :xs="24">
         <el-form :model="form"
                  :rules="rules"
                  ref="accountForm"
-                 
                  label-position="right"
                  label-width="180px">
           <el-form-item label="商户号"
@@ -390,14 +389,10 @@ export default {
   width: 100% !important;
 }
 .el-button--primary {
-  background: #14928a;
-  border-color: #14928a;
   color: #fff;
   &:hover,
   &:active,
   &:focus {
-    background: #14928a;
-    border-color: #14928a;
     color: #fff;
   }
 }

+ 87 - 3
src/views/organManager/components/organInfo.vue

@@ -40,7 +40,13 @@
           </el-form-item>
           <el-form-item label="主题色" v-if="tenantInfo == 'SETTING'" prop="themeColor" :rules="[{ required: true, message: '请选择主题色', trigger: 'change' }]">
             <div style="width: 300px !important">
-              <el-color-picker :disabled="isDisabled" v-model="form.themeColor"></el-color-picker>
+              <!-- <el-color-picker :disabled="isDisabled" v-model="form.themeColor"></el-color-picker> -->
+              <!-- <theme-picker  /> -->
+              <div class="themeColor">
+                <el-tooltip v-for="item in themeList" :key="item.color" effect="dark" :content="item.name" placement="top">
+                    <div class="themeColor-block" @click="onSelectTheme(item)" :style="item.style"><i class="el-icon-check" v-show="item.selected"></i></div>
+                </el-tooltip>
+              </div>
             </div>
           </el-form-item>
         </el-col>
@@ -102,8 +108,9 @@
           <el-input
             v-model.trim="form.name"
             :disabled="isDisabled"
-            :max="60"
-            placeholder="请输入机构简称"
+            :max="8"
+            :maxlength="8"
+            placeholder="请输入机构简称(最多8个字)"
           ></el-input>
         </el-form-item>
         <el-form-item label="机构联系人" prop="contacts"
@@ -171,13 +178,56 @@ import {
   areaQueryChild,
   getParentArea,
 } from "@/api/specialSetting";
+import ThemePicker from '@/components/ThemePicker'
 export default {
   props: ['type', 'data', 'tenantInfo'],
+  components: { ThemePicker },
   data () {
     return {
       headers: {
         Authorization: getToken(),
       },
+      themeList: [{
+        selected: true,
+        name: '大雅绿(默认)',
+        color: '#14928a',
+        style: 'background-color: #14928a'
+      }, {
+        selected: false,
+        name: '拂晓蓝',
+        color: '#1890ff',
+        style: 'background-color: #1890ff'
+      }, {
+        selected: false,
+        name: '薄暮',
+        color: '#f5222d',
+        style: 'background-color: #f5222d'
+      }, {
+        selected: false,
+        name: '火山',
+        color: '#fa541c',
+        style: 'background-color: #fa541c'
+      }, {
+        selected: false,
+        name: '日暮',
+        color: '#faad14',
+        style: 'background-color: #faad14'
+      }, {
+        selected: false,
+        name: '明青',
+        color: '#13c2c2',
+        style: 'background-color: #13c2c2'
+      }, {
+        selected: false,
+        name: '极客蓝',
+        color: '#2f54eb',
+        style: 'background-color: #2f54eb'
+      }, {
+        selected: false,
+        name: '酱紫',
+        color: '#722ed1',
+        style: 'background-color: #722ed1'
+      }],
       form: {
         tsignName: null,
         tsignCode: null,
@@ -207,6 +257,14 @@ export default {
       this.form = { ...this.data }
       this.payState = this.data.payState
     }
+    // 选中默认颜色
+    this.themeList.forEach(theme => {
+      if(theme.color == this.form.themeColor) {
+        theme.selected = true
+      } else {
+        theme.selected = false
+      }
+    })
     // 判断是否有城市编号
     if(this.form.areaId) {
       await getParentArea({ id: this.form.areaId }).then(async (res) => {
@@ -233,6 +291,13 @@ export default {
     }
   },
   methods: {
+    onSelectTheme(item) {
+      this.themeList.forEach(theme => {
+        theme.selected = false
+      })
+      item.selected = true
+      this.form.themeColor = item.color
+    },
     onSubmit() {
       let state = false
       this.$refs.form.validate(_ => {
@@ -350,4 +415,23 @@ export default {
   height: 72px;
   display: block;
 }
+.themeColor-block {
+  width: 20px;
+  height: 20px;
+  border-radius: 2px;
+  display: inline-block;
+  cursor: pointer;
+  vertical-align: middle;
+  overflow: hidden;
+  .el-icon-check {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 21px;
+    color: white;
+  }
+}
+.themeColor-block + .themeColor-block {
+  margin-left: 8px;
+}
 </style>

+ 8 - 5
src/views/tenantSetting/tenantInfo.vue

@@ -18,6 +18,7 @@
 <script>
 import { tenantInfoInfo, tenantInfoUpdate } from "../organManager/api";
 import organInfo from '../organManager/components/organInfo'
+import { setTheme } from '@/utils/setTheme'
 export default {
   components: { organInfo },
   data() {
@@ -40,26 +41,28 @@ export default {
         const res = await tenantInfoInfo({ id: tenantId })
         this.status = true
         const { config, productInfo, ...other } = res.data
-        const { theme, themeColor, ...con } = config
-        this.info = { ...other, theme, themeColor }
+        const { theme, themeColor, id, ...con } = config
+        this.info = { ...other, theme, themeColor, configId: id }
       } catch (e) {}
     },
     async onNext() {
       const organStatus = await this.$refs.organInfo.onSubmit()
       if(!organStatus) return
       const organData = await this.$refs.organInfo.getValues()
-      const { theme, themeColor, ...con } = organData
+      const { theme, themeColor, configId, ...con } = organData
         let config = {
           theme,
-          themeColor
+          themeColor,
+          id: configId
         }
       let params = {
-        ...organData,
+        ...con,
         config
       }
       try {
           const res = await tenantInfoUpdate(params)
           this.$message.success('修改更新成功')
+          setTheme(themeColor)
         } catch(e) {}
     }
   },