动态控制主题样式

merge-requests/1/head
dydwang 5 years ago
parent f95ee72676
commit dd02f47d82

2
.gitignore vendored

@ -1,7 +1,7 @@
.DS_Store .DS_Store
node_modules node_modules
/logistics_web_package
/dist /dist
# local env files # local env files
.env.local .env.local
.env.*.local .env.*.local

@ -0,0 +1,25 @@
// 动态更新antd主题颜色
const path = require('path');
const { generateTheme } = require('antd-theme-generator');
const options = {
antDir: path.join(__dirname, './node_modules/ant-design-vue'), //依赖位置
// stylesDir: path.join(__dirname, './src/style'), //处理style下所有less
varFile: path.join(__dirname, './src/style/antd-variables.less'), //antd全局变量
themeVariables: [
'@primary-color',
'@secondary-color',
'@text-color',
'@text-color-secondary',
'@heading-color',
'@layout-body-background',
'@btn-primary-bg',
'@layout-header-background'
], // 指定所有我们自定义的需要切换的样式变量。
outputFilePath: path.join(__dirname, './public/antd_color.less'), // 输出样式
}
generateTheme(options).then(() => {
console.log('Theme generated successfully');
}).catch(error => {
console.log('Error', error);
});

@ -3,13 +3,13 @@ module.exports = {
'@vue/cli-plugin-babel/preset' '@vue/cli-plugin-babel/preset'
], ],
plugins: [ plugins: [
[ // [
"import", // "import",
{ // {
libraryName: "ant-design-vue", // libraryName: "ant-design-vue",
libraryDirectory: "es", // libraryDirectory: "lib",
style: "css" // style: true
} // }
] // ]
] ]
} }

@ -0,0 +1,26 @@
server {
listen 9007;
server_name localhost;
client_max_body_size 90m;
location /api {
proxy_pass http://localhost:8099/api;
}
location /{
root D:\hzleaper_auto_install\logistics_web_package;
index index.html index.html;
}
location /api/node {
proxy_pass http://127.0.0.1:8117;
rewrite "^/api/node/(.*)$" /$1 break;
}
location /api/pic {
alias d:\data\media\\;
}
location /api/mp4 {
alias d:\\data\mp4\\;
}
}

1467
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -3,22 +3,26 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "node antdTheme.js && vue-cli-service serve",
"build": "vue-cli-service build", "build": "node antdTheme.js && vue-cli-service build",
"lint": "eslint --fix --ext .js,.vue src", "lint": "eslint --fix --ext .js,.vue src",
"start": "npm run serve" "start": "node antdTheme.js && npm run serve"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^1.6.3", "ant-design-vue": "^1.6.3",
"antd-theme-generator": "^1.2.8",
"axios": "^0.19.2", "axios": "^0.19.2",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"element-ui": "^2.15.6",
"path-to-regexp": "^6.2.0", "path-to-regexp": "^6.2.0",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"v-viewer": "^1.5.1", "v-viewer": "^1.5.1",
"video.js": "^7.10.2", "video.js": "^7.10.2",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-json-editor": "^1.4.3",
"vue-router": "^3.2.0", "vue-router": "^3.2.0",
"vuex": "^3.4.0" "vuex": "^3.4.0",
"vuex-multi-tab-state": "^1.0.16"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^4.4.0", "@vue/cli-plugin-babel": "^4.4.0",
@ -30,6 +34,8 @@
"eslint": "^6.7.2", "eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2", "eslint-plugin-import": "^2.20.2",
"eslint-plugin-vue": "^6.2.2", "eslint-plugin-vue": "^6.2.2",
"less": "^2.7.3",
"less-loader": "^6.2.0",
"node-sass": "^4.14.1", "node-sass": "^4.14.1",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"vue-happy-scroll": "^2.1.1", "vue-happy-scroll": "^2.1.1",

File diff suppressed because it is too large Load Diff

@ -15,7 +15,8 @@
continue.</strong> continue.</strong>
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
<!-- built files will be auto injected --> <!-- 动态更新antd主题-->
<link rel="stylesheet/less" type="text/css" href="/antd_color.less" />
</body> </body>
</html> </html>

@ -10,6 +10,7 @@
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN' import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import moment from 'moment' import moment from 'moment'
import 'moment/locale/zh-cn' import 'moment/locale/zh-cn'
import { mapActions } from 'vuex';
moment.locale('zh-cn') moment.locale('zh-cn')
export default { export default {
name: 'App', name: 'App',
@ -25,6 +26,7 @@ export default {
} }
}, },
methods: { methods: {
...mapActions(['getStyles']),
reload(){ reload(){
this.isRouterAlive = false this.isRouterAlive = false
this.$nextTick( function () { this.$nextTick( function () {
@ -33,6 +35,8 @@ export default {
} }
}, },
mounted() { mounted() {
//
this.getStyles();
window.onmessage = e => { window.onmessage = e => {
if (!e.data.id) return; if (!e.data.id) return;
sessionStorage.setItem("postMessage", e.data.id); sessionStorage.setItem("postMessage", e.data.id);

@ -167,5 +167,10 @@ export default {
name: '库存模板下载', name: '库存模板下载',
method: 'GET' method: 'GET'
}, },
scanAndCheck: {
url: '/ScanAndCheck',
name: '盘点操作里参数',
method: 'GET'
}
} }

@ -0,0 +1,12 @@
export default {
updateStylesAPI: {
url: '/node/styles/update',
name: '更新标题菜单样式',
method: 'POST'
},
getStylesAPI: {
url: '/node/default_css.json',
name: '获取标题菜单样式',
method: 'GET'
}
}

@ -1,18 +1,26 @@
<template> <template>
<a-layout-sider :class="['aside', collapsed ? 'merge' :'']" v-model="collapsed" theme="dark" :trigger="null" collapsible> <a-layout-sider :class="['aside', collapsed ? 'merge' :'']" v-model="collapsed" theme="dark" :trigger="null" collapsible>
<div class="logo"> <div class="logo" :style="styles.title.style">
<!-- <img src="@/assets/logo1.png" alt />--> <!-- <img src="@/assets/logo1.png" alt />-->
<span class="logo-title">垛机视觉系统</span> <span class="logo-title">{{ styles.title.text }}</span>
</div> </div>
<a-menu :selectedKeys="selectedKeys" <a-menu :selectedKeys="selectedKeys"
:openKeys.sync="openKeys" :openKeys.sync="openKeys"
@click="clickMenu" @click="clickMenu"
mode="inline" mode="inline"
theme="dark" theme="dark"
:inline-collapsed="aside_collapsed"> :inline-collapsed="aside_collapsed"
:style="styles.menu.default"
>
<template v-for="item in routes"> <template v-for="item in routes">
<!-- 如果没有子路由 --> <!-- 如果没有子路由 -->
<a-menu-item :key="item.name" v-if="!item.meta.unfold"> <a-menu-item
:key="item.name"
v-if="!item.meta.unfold"
:style="(selectedKeys[0] === item.name || item.name === mouseItemKey) ? styles.menu.select : styles.menu.default"
@mouseenter="menuItemHover"
@mouseleave="menuItemOut"
>
<a-icon :type="item.meta.icon" /> <a-icon :type="item.meta.icon" />
<span>{{ item.meta.name }}</span> <span>{{ item.meta.name }}</span>
</a-menu-item> </a-menu-item>
@ -29,7 +37,7 @@ export default {
name: "AsideMenu", name: "AsideMenu",
computed: { computed: {
...mapState(["aside_collapsed", "userInfo"]), ...mapState(["aside_collapsed", "userInfo"]),
...mapGetters(['getAside_collapsed']) ...mapGetters(['getAside_collapsed', 'styles'])
}, },
watch: { watch: {
$route() { $route() {
@ -39,14 +47,15 @@ export default {
getAside_collapsed: function (newValue) { getAside_collapsed: function (newValue) {
console.log(newValue) console.log(newValue)
this.collapsed = newValue this.collapsed = newValue
} },
}, },
data() { data() {
return { return {
collapsed:this.$store.state.aside_collapsed, collapsed:this.$store.state.aside_collapsed,
selectedKeys: [], selectedKeys: [],
openKeys: [], openKeys: [],
routes: [] routes: [],
mouseItemKey: "", // item
}; };
}, },
methods: { methods: {
@ -110,6 +119,13 @@ export default {
: (this.openKeys = [""]); : (this.openKeys = [""]);
this.$forceUpdate(); this.$forceUpdate();
},
// item hover
menuItemHover(e) {
this.mouseItemKey = e.key;
},
menuItemOut() {
this.mouseItemKey = '';
} }
}, },
mounted() { mounted() {
@ -140,7 +156,7 @@ export default {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: #ffffff; color: #ffffff;
background:#022342; // background:#022342;
/*text-align: center;*/ /*text-align: center;*/
img{ img{
width: 24px; width: 24px;

@ -2,10 +2,10 @@
<a-breadcrumb class="breadcrumb"> <a-breadcrumb class="breadcrumb">
<a-breadcrumb-item v-for="(item, index) in breadList" :key="item.name"> <a-breadcrumb-item v-for="(item, index) in breadList" :key="item.name">
<router-link <router-link
v-if="item.name != name && index != 1" v-if="item.name !== name && index !== 1"
:to="{ path: item.path === '' ? '/' : item.path }" :to="{ path: item.path === '' ? '/' : item.path }"
>{{ item.meta.name }}</router-link> >{{ item.meta.name }}</router-link>
<span v-else>{{ item.meta.name }}</span> <span v-else-if="breadList.length > 2">{{ item.meta.name }}</span>
</a-breadcrumb-item> </a-breadcrumb-item>
</a-breadcrumb> </a-breadcrumb>
</template> </template>

@ -3,6 +3,7 @@ import App from './App.vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
import './plugins/antd' import './plugins/antd'
import './plugins/element'
import './components/index' import './components/index'
import './layouts/index' import './layouts/index'
import utils from './utils/index' import utils from './utils/index'
@ -38,3 +39,6 @@ new Vue({
store, store,
render: h => h(App) render: h => h(App)
}).$mount('#app') }).$mount('#app')
const vuex = require('vuex');
console.log(vuex);

@ -1,4 +1,6 @@
import Vue from "vue"; import Vue from "vue";
import 'ant-design-vue/dist/antd.less';
// import "@/style/antd-variables.less";
import { import {
Layout, Layout,
ConfigProvider, ConfigProvider,
@ -29,10 +31,14 @@ import {
Upload, Upload,
Radio, Radio,
Badge, Badge,
Carousel Carousel,
Collapse,
Spin
} from "ant-design-vue"; } from "ant-design-vue";
Vue.use(Spin);
Vue.use(Layout); Vue.use(Layout);
Vue.use(ConfigProvider); Vue.use(ConfigProvider);
Vue.use(Collapse);
Vue.use(Input); Vue.use(Input);
Vue.use(InputNumber); Vue.use(InputNumber);
Vue.use(Tabs); Vue.use(Tabs);
@ -44,7 +50,12 @@ Vue.use(Button);
Vue.use(Breadcrumb); Vue.use(Breadcrumb);
Vue.use(Icon); Vue.use(Icon);
Vue.use(Tree); Vue.use(Tree);
Vue.use(result); try {
Vue.use(result);
}catch (e){
console.log(e);
}
Vue.use(Modal); Vue.use(Modal);
Vue.use(Popover); Vue.use(Popover);
Vue.use(Row); Vue.use(Row);
@ -60,6 +71,7 @@ Vue.use(Upload)
Vue.use(Radio) Vue.use(Radio)
Vue.use(Badge) Vue.use(Badge)
Vue.use(Carousel) Vue.use(Carousel)
Vue.prototype.$form = Form;
Vue.prototype.$message = message; Vue.prototype.$message = message;
Vue.prototype.$info = Modal.info; Vue.prototype.$info = Modal.info;
Vue.prototype.$success = Modal.success; Vue.prototype.$success = Modal.success;

@ -31,3 +31,4 @@ apiAll.keys().map((key) => {
return trans(moduleApis[name]); return trans(moduleApis[name]);
}); });
export default moduleApis; export default moduleApis;
console.log(moduleApis);

@ -0,0 +1,10 @@
import Vue from "vue";
import {
ColorPicker, // 颜色选择器
Form,
FormItem
} from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ColorPicker);
Vue.use(Form);
Vue.use(FormItem);

@ -0,0 +1,6 @@
import less from 'less'
export default {
...less,
async: false, // 是否同步
env: 'production', // 环境
};

@ -0,0 +1,18 @@
import less from './less';
// 更换antd主题色
export const changeTheme = (color) => {
console.log(less, color);
less
.modifyVars({
'@primary-color': color,
'@link-color': color,
'@btn-primary-bg': color
})
.then(() => {
console.log('antd主题颜色成功')
})
.catch(error => {
console.error('antd主题颜色失败')
console.error(error)
})
}

@ -172,6 +172,12 @@ const routes = [{
name: 'guide', name: 'guide',
component: () => import('../views/guide.vue') component: () => import('../views/guide.vue')
}, },
{
path: '/updateStyles',
name: '修改样式',
component: () => import('../views/updateStyles/index')
},
{ {
path: '*', path: '*',
name: '404', name: '404',

@ -1,7 +1,8 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import styles from './modules/styles'
Vue.use(Vuex) import createMultiTabState from 'vuex-multi-tab-state'; // 多个tab 共享vuex
Vue.use(Vuex);
export default new Vuex.Store({ export default new Vuex.Store({
state: { state: {
@ -9,6 +10,7 @@ export default new Vuex.Store({
userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}') userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}')
}, },
getters:{ getters:{
styles: (state) => state.styles.data,
getAside_collapsed(state){ getAside_collapsed(state){
return state.aside_collapsed return state.aside_collapsed
}, },
@ -25,5 +27,10 @@ export default new Vuex.Store({
}, },
}, },
actions: {}, actions: {},
modules: {} modules: {
styles
},
plugins: [
createMultiTabState()
]
}) })

@ -0,0 +1,62 @@
import Vue from "vue";
const vue = new Vue();
import api from '@/plugins/axios/index'
const { httpNodeApi } = api;
import axios from "axios";
import {changeTheme} from '@/plugins/themePicker'
const store = {
state: {
data:{
"theme":{
"primary-color":"rgba(184, 68, 13, 1)"
},
"title":{
"text":"ROBO垛机视觉系统",
"style":{
"color":"rgba(255, 255, 255, 1)",
"background-color":"rgba(163, 60, 12, 1)",
"font-size":"24px"
}
},
"menu":{
"default":{
"color":"rgba(230, 224, 224, 1)",
"background-color":"rgba(163, 60, 12, 1)"
},
"select":{
"color":"rgba(255, 255, 255, 1)",
"background-color":"rgba(184, 68, 13, 1)"
}
}
}
},
mutations:{
UPDATE_STYLES(state, data) {
// for(let key in data) {
// // state[key] = data[key];
// vue.$set(state, key, data[key])
// }
state.data = data;
// 改变主题颜色
changeTheme(data.theme['primary-color']);
// setItem(data);
}
},
actions: {
// 更新样式
async updateStyles({commit}, data) {
console.log(Vue.prototype.$api);
commit('UPDATE_STYLES', data);
await httpNodeApi.updateStylesAPI({data})
},
// 获取样式
async getStyles({commit}){
console.log('获取样式');
const data = await axios.get('/api/node/default_css.json');
commit('UPDATE_STYLES', data.data);
}
}
}
// 初始加载时默认更新一次主题
changeTheme(store.state.data.theme['primary-color']);
export default store;

@ -0,0 +1,24 @@
// @import "ant-design-vue/lib/style/themes/default.less";
@primary-color: #1890ff; // 全局主色
@link-color: #1890ff; // 链接色
@success-color: #52c41a; // 成功色
@warning-color: #faad14; // 警告色
@error-color: #f5222d; // 错误色
@font-size-base: 14px; // 主字号
@heading-color: rgba(0, 0, 0, 0.85); // 标题色
@text-color: rgba(0, 0, 0, 0.65); // 主文本色
@text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
@disabled-color: rgba(0, 0, 0, 0.25); // 失效色
@border-radius-base: 4px; // 组件/浮层圆角
@border-color-base: #d9d9d9; // 边框色
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // 浮层阴影
//:export {
// primary-color: @primary-color;
//}
:root {
--PC: @primary-color;
}
.primary-color{
color:@primary-color
}

@ -137,18 +137,32 @@
<div class="carousel-page-content"> <div class="carousel-page-content">
<div class="img-box"> <div class="img-box">
<div <div
style="display: flex;align-items: center;justify-content: center;width:600px;height:400px;background:#eaeaea"> style="display: flex;align-items: center;justify-content: center;width:500px;height:400px;background:#eaeaea">
暂无图片 暂无图片
</div> </div>
<p>操作前照片</p> <p>操作前照片</p>
</div> </div>
<div class="img-box"> <div class="img-box">
<div <div
style="display: flex;align-items: center;justify-content: center;width:600px;height:400px;background:#eaeaea"> style="display: flex;align-items: center;justify-content: center;width:500px;height:400px;background:#eaeaea">
暂无图片 暂无图片
</div> </div>
<p>操作后照片</p> <p>操作后照片</p>
</div> </div>
<div class="img-box">
<a-spin tip="加载中..." :spinning="!Object.keys(scanAndCheck).length">
<ul>
<li v-for="item in params" :key="item.label">
<span class="img-box-title">
{{ item.label }}:
</span>
<span class="img-box-value">
{{ scanAndCheck[item.key] }}
</span>
</li>
</ul>
</a-spin>
</div>
</div> </div>
<div class="carousel-page-footer"> <div class="carousel-page-footer">
<div class="info-box"> <div class="info-box">
@ -171,9 +185,6 @@
>核对正确 >核对正确
</a-button> </a-button>
</div> </div>
</div>
</div>
<div class="bottom-btn" <div class="bottom-btn"
v-if="listrow == row && listcolumn == column"> v-if="listrow == row && listcolumn == column">
<a-button class="btn" @click="defaultPrev(listrow,listcolumn)"></a-button> <a-button class="btn" @click="defaultPrev(listrow,listcolumn)"></a-button>
@ -184,6 +195,8 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
<Model <Model
:visible.sync="visible" :visible.sync="visible"
@ -201,6 +214,7 @@ export default {
data() { data() {
return { return {
listData: [], listData: [],
scanAndCheck: {},
checkObj: {}, checkObj: {},
streetDetail: {}, streetDetail: {},
checkList: {}, checkList: {},
@ -216,7 +230,25 @@ export default {
count: 0, count: 0,
modelData: {}, modelData: {},
index: 0, index: 0,
imgUrl: '' imgUrl: '',
params:[
{
label:'系统条码号',
key: 'SystemCode'
},
{
label:'扫描条码号',
key: 'ScanCode'
},
{
label:'系统数量',
key: 'SystemNumber'
},
{
label:'检测数量',
key: 'CheckNumber'
}
]
} }
}, },
created() { created() {
@ -242,7 +274,8 @@ export default {
} }
}, },
mounted() { mounted() {
this.getStreetList() this.getStreetList();
this.getScanAndCheck();
if (JSON.stringify(this.checkObj) !== '{}') { if (JSON.stringify(this.checkObj) !== '{}') {
if (this.checkObj.shelveId == this.streetDetail.leftShelveId) { if (this.checkObj.shelveId == this.streetDetail.leftShelveId) {
this.selectType = 'left' this.selectType = 'left'
@ -256,6 +289,26 @@ export default {
Model Model
}, },
methods: { methods: {
getScanAndCheck() {
// this.scanAndCheck = {
// SystemCode: 'D1H0000147',
// ScanCode: 'D1H0000147',
// SystemNumber: 10,
// CheckNumber: 10
// }
this.$api.httpApi.scanAndCheck({
name: 'getData'
}).then(res=>{
// 2
if(res.status === '0') {
setTimeout(()=>{
this.getScanAndCheck();
}, 2000);
}else{
this.scanAndCheck = res.data[0];
}
})
},
// //
getStreetList() { getStreetList() {
this.$api.httpApi.getStreetList({ this.$api.httpApi.getStreetList({
@ -498,7 +551,7 @@ export default {
.checkOperation { .checkOperation {
.carousel-page { .carousel-page {
width: 90%; width: 100%;
/*border: solid 1px blue;*/ /*border: solid 1px blue;*/
&-title { &-title {
color: #009FE3; color: #009FE3;
@ -528,10 +581,36 @@ export default {
p { p {
height: 25px; height: 25px;
} }
ul {
width: 320px;
height: 100%;
margin-bottom: 0;
padding-inline-start: 0;
li {
background-color: #ffaf11;
margin: 10px 0;
padding: 5px;
font-size: 16px;
font-weight: 600;
color: #494e52;
.img-box-title {
width: 90px;
display: inline-block;
}
.img-box-value {
display: inline-block;
width: calc(100% - 90px);
overflow: hidden;
position: relative;
top: 5px;
}
}
}
} }
} }
&-footer { &-footer {
width: calc(100% - 380px);
.info-box { .info-box {
color: #000000; color: #000000;
display: flex; display: flex;
@ -568,7 +647,7 @@ export default {
} }
.bottom-btn { .bottom-btn {
width: 900px; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

@ -73,7 +73,11 @@ export default {
destroyed(){ destroyed(){
if (this.$refs.vlc) { if (this.$refs.vlc) {
for (var i = 0; i < this.$refs.vlc.length; i++) { for (var i = 0; i < this.$refs.vlc.length; i++) {
try{
this.$refs.vlc[i].playlist.stop(); this.$refs.vlc[i].playlist.stop();
}catch (e) {
console.log(e);
}
} }
} }
}, },
@ -83,7 +87,11 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
if (this.$refs.vlc) { if (this.$refs.vlc) {
for (var i = 0; i < this.$refs.vlc.length; i++) { for (var i = 0; i < this.$refs.vlc.length; i++) {
try{
this.$refs.vlc[i].playlist.stop(); this.$refs.vlc[i].playlist.stop();
}catch (e) {
console.log(e);
}
} }
next(true) next(true)
} else { } else {

@ -0,0 +1,60 @@
<template>
<el-color-picker
show-alpha
size="medium"
:value="color"
:predefine="predefineColors"
@change="val => $emit('change', val)"
>
</el-color-picker>
</template>
<script>
export default {
name: "SelectColor",
components: {},
props: {
color: {
type: String
}
},
computed: {},
watch: {},
model: {
prop: 'color',
event: 'change'
},
data() {
return {
predefineColors: [
'#ff4500',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'rgba(255, 69, 0, 0.68)',
'rgb(255, 120, 0)',
'hsv(51, 100, 98)',
'hsva(120, 40, 94, 0.5)',
'hsl(181, 100%, 37%)',
'hsla(209, 100%, 56%, 0.73)',
'#c7158577'
]
}
},
mounted() {
},
created() {
},
destroyed() {
},
methods: {}
}
</script>
<style scoped lang="scss">
.SelectColor {
}
</style>

@ -0,0 +1,46 @@
<template>
<div class="StylesMenu">
<p>默认</p>
<el-form-item label="字体颜色">
<select-color v-model="form.default.color"></select-color>
</el-form-item>
<el-form-item label="背景颜色">
<select-color v-model="form.default['background-color']"></select-color>
</el-form-item>
<p>选中后</p>
<el-form-item label="字体颜色">
<select-color v-model="form.select.color"></select-color>
</el-form-item>
<el-form-item label="背景颜色">
<select-color v-model="form.select['background-color']"></select-color>
</el-form-item>
</div>
</template>
<script>
import SelectColor from "./SelectColor";
export default {
name: "StylesMenu",
components: {SelectColor},
props: {
form:{}
},
computed: {},
watch: {},
data() {
return {}
},
mounted() {
},
created() {
},
destroyed() {
},
methods: {}
}
</script>
<style scoped lang="scss">
.StylesMenu {
}
</style>

@ -0,0 +1,37 @@
<template>
<div class="StylesTheme">
<el-form-item label="主题颜色">
<select-color v-model="form['primary-color']"></select-color>
</el-form-item>
</div>
</template>
<script>
import SelectColor from "./SelectColor";
export default {
name: "StylesTheme",
components: {
SelectColor
},
props: {
form:{}
},
computed: {},
watch: {},
data() {
return {}
},
mounted() {
},
created() {
},
destroyed() {
},
methods: {}
}
</script>
<style scoped lang="scss">
.StylesTheme {
}
</style>

@ -0,0 +1,67 @@
<template>
<div class="styles-title">
<el-form-item label="标题文字" prop="title.text" :rules="{ required: true, message: '请输入标题', trigger: ['blur', 'change'] }">
<a-input v-model="form.text" />
</el-form-item>
<el-form-item label="字体颜色">
<select-color v-model="form.style.color"></select-color>
</el-form-item>
<el-form-item label="背景颜色">
<select-color v-model="form.style['background-color']"></select-color>
</el-form-item>
<!-- <a-form-item label="style">-->
<!--&lt;!&ndash; json编辑器&ndash;&gt;-->
<!-- <vue-json-editor-->
<!-- v-model="form.style"-->
<!-- :mode="'code'"-->
<!-- lang="zh"-->
<!-- @json-change="onJsonChange"-->
<!-- @has-error="onError">-->
<!-- </vue-json-editor>-->
<!-- </a-form-item>-->
</div>
</template>
<script>
import SelectColor from "./SelectColor";
// import vueJsonEditor from 'vue-json-editor'
export default {
name: "StylesTitle",
components: {
SelectColor
// vueJsonEditor
},
props: {
form: {}
},
computed: {},
watch: {},
data() {
return {
}
},
mounted() {
},
created() {
},
destroyed() {
},
methods: {
onJsonChange(data) {
if(typeof data === "object") {
this.form.style = data;
}
},
onError(err) {
// console.log(err);
}
}
}
</script>
<style scoped lang="scss">
.styles-title /deep/{
}
</style>

@ -0,0 +1,96 @@
<template>
<div class="index">
<el-form :model="formData" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<a-collapse v-model="activeKey">
<a-collapse-panel key="0" header="主题">
<styles-theme :form.sync="formData.theme"></styles-theme>
</a-collapse-panel>
<a-collapse-panel key="1" header="标题">
<styles-title :form.sync="formData.title"></styles-title>
</a-collapse-panel>
<a-collapse-panel key="2" header="菜单">
<styles-menu :form.sync="formData.menu"></styles-menu>
</a-collapse-panel>
</a-collapse>
<el-form-item>
<span style="float: right">
<a-button type="primary" @click="handleSubmit()" style="margin-right: 10px">
保存
</a-button>
<a-button type="info" @click="init()">
重置
</a-button>
</span>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import StylesTitle from "./StylesTitle";
import StylesMenu from "./StylesMenu";
import StylesTheme from "./StylesTheme";
export default {
name: "index",
components: {StylesTheme, StylesMenu, StylesTitle},
props: {},
computed: {
...mapGetters(['styles']),
watchStyles() {
return JSON.stringify(this.styles);
}
},
watch: {
watchStyles() {
this.init()
}
},
data() {
return {
activeKey: ['0', '1', '2'],
formData: {},
}
},
mounted() {
},
created() {
console.log(this.styles);
this.init();
},
destroyed() {
},
methods: {
...mapActions(['updateStyles']),
init() {
console.log('init');
this.formData = JSON.parse(JSON.stringify(this.styles));
},
//
handleSubmit() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
this.updateStyles(this.formData);
} else {
console.log('error submit!!');
return false;
}
});
}
}
}
</script>
<style scoped lang="scss">
.index /deep/{
width: 70%;
margin: auto;
.ant-form-item {
margin-bottom: 10px;
}
.jsoneditor-menu {
display: none;
}
}
</style>

@ -1,16 +1,38 @@
module.exports = { module.exports = {
css: { css: {
// 启用 CSS modules
requireModuleExtension: true,
// 是否使用css分离插件
extract: false,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: { loaderOptions: {
sass: { sass: {
prependData: `@import "~@/assets/scss/style.scss";` prependData: `@import "~@/assets/scss/style.scss";`
} },
less: {
lessOptions: {
// If you are using less-loader@5 please spread the lessOptions to options directly
// 动态设置and主题颜色
// modifyVars: {},
javascriptEnabled: true,
},
},
} }
}, },
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true, productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
devServer: { devServer: {
proxy: { proxy: {
'/api/node': {
target: 'http://127.0.0.1:8117',
logLevel:'debug', //控制台终端打印代理前的真实地址
pathRewrite:{
'/api/node':''
}
},
'/api': { '/api': {
target: 'http://192.168.66.27:8099', target: 'http://192.168.0.108:8099',
logLevel:'debug', //控制台终端打印代理前的真实地址 logLevel:'debug', //控制台终端打印代理前的真实地址
}, },
}, },

Loading…
Cancel
Save