Browse Source

0.4.0

新增样式,布局(主页和登录页)
master
许孟阳 7 months ago
parent
commit
a9d57f7a6e
  1. 52
      examples/App.vue
  2. 7
      examples/config/router.ts
  3. 3
      examples/store/index.ts
  4. 3
      examples/store/state.ts
  5. 2
      package.json
  6. 92
      packages/base/data/login-form.vue
  7. 3
      packages/base/data/search-row.vue
  8. 11
      packages/base/index.ts
  9. 6
      packages/base/item/input.vue
  10. 283
      packages/manage/common/head.vue
  11. 4
      packages/manage/common/index.ts
  12. 127
      packages/manage/common/login.vue
  13. 145
      packages/manage/common/login2.vue
  14. 26
      packages/manage/head/fullscreen.vue
  15. 119
      packages/manage/head/head.vue
  16. 9
      packages/manage/head/index.ts
  17. 29
      packages/manage/head/lang-change.vue
  18. 44
      packages/manage/head/menu-tree.vue
  19. 87
      packages/manage/head/personal.vue
  20. 32
      packages/manage/head/size-change.vue
  21. 63
      packages/manage/head/style-change.vue
  22. 6
      packages/manage/index.ts
  23. 39
      packages/manage/router/index.vue
  24. 6
      packages/manage/views/index.ts
  25. 58
      packages/manage/views/login.vue
  26. 2
      plugs/config/size/large.ts
  27. 3
      plugs/config/size/normal.ts
  28. 2
      plugs/config/size/small.ts
  29. 3
      plugs/config/styles/dark.ts
  30. 2
      plugs/config/styles/index.ts
  31. 3
      plugs/config/styles/light.ts
  32. 5
      plugs/config/styles/plain.ts
  33. 17
      plugs/config/styles/plainb.ts
  34. 5
      plugs/i18n/en.ts
  35. 4
      plugs/i18n/zh.ts
  36. 24
      plugs/store/index.ts

52
examples/App.vue

@ -1,5 +1,6 @@
<template> <template>
<Index :menus="menus" @updatePwd="pwd => console.log(pwd)" :checkUser="true" username="超级管理员" :closeAble="true"> <Index :menus="menus" @updatePwd="pwd => console.log(pwd)" :checkUser="true" username="超级管理员" :closeAble="true"
mode="horizontal">
</Index> </Index>
</template> </template>
@ -10,29 +11,29 @@ import { Index, Views } from "noob-mengyxu";
const store = useStore(); const store = useStore();
const { buff, dictionary, config, permission, role, user, status, log } = Views.menus; const { buff, dictionary, config, permission, role, user, status, log } = Views.menus;
// const menus = [ const menus = [
// { {
// i18n: "menu.home", path: "home", icon: "HomeFilled" i18n: "menu.home", path: "home", icon: "HomeFilled"
// }, },
// { {
// i18n: "menu.operator", path: "operator", icon: "Platform", children: [ i18n: "menu.operator", path: "operator", icon: "Platform", children: [
// buff, dictionary, config, permission, role, user, status, log buff, dictionary, config, permission, role, user, status, log
// ] ]
// }, },
// { {
// i18n: "menu.base", path: "base", icon: "House", children: [ i18n: "menu.base", path: "base", icon: "House", children: [
// { i18n: "menu.table", path: "table", icon: "List" }, { i18n: "menu.table", path: "table", icon: "List" },
// { i18n: "menu.form", path: "form", icon: "Postcard" }, { i18n: "menu.form", path: "form", icon: "Postcard" },
// ] ]
// }, },
// { {
// i18n: "menu.tool", path: "tool", icon: "Tools", children: [ i18n: "menu.tool", path: "tool", icon: "Tools", children: [
// { i18n: "menu.terminal", path: "terminal", icon: "Platform" }, { i18n: "menu.terminal", path: "terminal", icon: "Platform" },
// { i18n: "menu.color", path: "color", icon: "MagicStick" }, { i18n: "menu.color", path: "color", icon: "MagicStick" },
// ] ]
// } }
// ] ]
const menus = null; // const menus = null;
onMounted(() => { }); onMounted(() => { });
@ -41,5 +42,4 @@ onMounted(() => { });
<style lang="scss"> <style lang="scss">
// ::v-deep .no-padding .el-dialog__body { // ::v-deep .no-padding .el-dialog__body {
// background-color: black; // background-color: black;
// } // }</style>
</style>

7
examples/config/router.ts

@ -1,5 +1,5 @@
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'; import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import { Views } from 'noob-mengyxu'; import { Views, Common } from 'noob-mengyxu';
import Home from '../view/home.vue'; import Home from '../view/home.vue';
import Table from '../view/base/table.vue'; import Table from '../view/base/table.vue';
import Form from '../view/base/form.vue'; import Form from '../view/base/form.vue';
@ -16,6 +16,11 @@ const routes: Array<RouteRecordRaw> = [
name: 'home', name: 'home',
component: Home, component: Home,
}, },
{
path: '/login',
name: 'login',
component: Common.Login2,
},
{ {
path: '/table', path: '/table',
name: 'table', name: 'table',

3
examples/store/index.ts

@ -3,8 +3,11 @@ import state from './state';
import mutations from './mutations'; import mutations from './mutations';
import actions from './actions'; import actions from './actions';
const getters = new Store.Getters();
export default Store.createStore({ export default Store.createStore({
state, state,
getters,
mutations, mutations,
actions, actions,
}); });

3
examples/store/state.ts

@ -1,9 +1,10 @@
import { Store } from 'noob-mengyxu'; import { Store, Styles } from 'noob-mengyxu';
class State extends Store.State { class State extends Store.State {
test = [ test = [
{ key: 'a', value: 'A' }, { key: 'a', value: 'A' },
{ key: 'b', value: 'B' }, { key: 'b', value: 'B' },
{ key: 'c', value: 'C' }, { key: 'c', value: 'C' },
]; ];
style = Styles.plainb;
} }
export default new State(); export default new State();

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "noob-mengyxu", "name": "noob-mengyxu",
"version": "0.3.8", "version": "0.4.0",
"main": "index.ts", "main": "index.ts",
"module": "index.ts", "module": "index.ts",
"keywords": [ "keywords": [

92
packages/base/data/login-form.vue

@ -1,92 +0,0 @@
<template>
<el-form label-position="right" class="login-form" :model="param" ref="loginForm" :rules="rules">
<div class="logo-item" v-if="logo">
<el-image class="logo" :src="logo" fit="fit" />
</div>
<el-form-item>
<div class="lte-title"> {{ t('title') }} </div>
</el-form-item>
<el-form-item prop="userId">
<NoobInput v-model="param.userId" :placeholder="t('pwd.userId')" :full="true"></NoobInput>
</el-form-item>
<el-form-item prop="password">
<NoobInput v-model="param.password" type="password" :placeholder="t('pwd.pwd')" :full="true"></NoobInput>
</el-form-item>
<el-form-item>
<NoobButton @click="login">{{ t('pwd.login') }}</NoobButton>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { FormInstance } from "element-plus";
import { NoobInput, NoobButton, Element } from "noob-mengyxu";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state } = useStore();
const { SimpleRequired } = Element;
const emit = defineEmits(["login"]);
const param = ref<any>({});
const loginForm = ref<FormInstance>();
const rules = {
userId: [new SimpleRequired('pwd.userId')],
password: [new SimpleRequired('pwd.pwd')]
}
const props = defineProps({
logo: {
type: String,
default: null,
},
});
const login = () => {
if (!loginForm.value) return;
loginForm.value?.validate((valid, fields) => {
if (valid) {
emit("login", param.value);
loginForm.value?.clearValidate();
}
});
}
onMounted(() => { });
</script>
<style lang="scss" scoped>
//@import url(); css
.login-form {
width: v-bind('state.size.loginWidth');
height: v-bind('state.size.loginHeight');
}
.logo-item {
text-align: center;
align-items: center;
}
.logo {
width: 50px;
height: 50px;
img {
display: inline !important;
}
}
.lte-title {
font-size: 1.5em;
font-weight: bold;
text-align: center;
width: 100%;
color: rgb(49, 89, 143);
}
.el-button {
width: 100%;
}
</style>

3
packages/base/data/search-row.vue

@ -75,8 +75,10 @@ onMounted(() => { });
.search-row, .search-row,
.query, .query,
.title,
.left { .left {
height: v-bind('state.size.searchRowHeight'); height: v-bind('state.size.searchRowHeight');
line-height: v-bind('state.size.searchRowHeight');
} }
.title { .title {
@ -84,5 +86,6 @@ onMounted(() => { });
padding-right: 15px; padding-right: 15px;
font-size: v-bind('state.size.titleSize'); font-size: v-bind('state.size.titleSize');
min-width: 20px; min-width: 20px;
color: v-bind('state.style.subTitleColor')
} }
</style> </style>

11
packages/base/index.ts

@ -11,15 +11,6 @@ import SearchRow from './data/search-row.vue';
import ListTable from './data/list-table.vue'; import ListTable from './data/list-table.vue';
import Infomation from './data/infomation.vue'; import Infomation from './data/infomation.vue';
import ModifyForm from './data/modify-form.vue'; import ModifyForm from './data/modify-form.vue';
import LoginForm from './data/login-form.vue';
import Descriptions from './data/descriptions.vue'; import Descriptions from './data/descriptions.vue';
import TableAction from './data/table-action.vue'; import TableAction from './data/table-action.vue';
export { export { SearchRow, ListTable, Infomation, ModifyForm, Descriptions, TableAction };
SearchRow,
ListTable,
Infomation,
ModifyForm,
LoginForm,
Descriptions,
TableAction,
};

6
packages/base/item/input.vue

@ -1,5 +1,5 @@
<template> <template>
<el-input :size="state.size.size" :class="['form-item', full && 'full']" v-model="myValue" :type="type" <el-input :size="state.size.size" :class="['form-item', prop.class, full && 'full']" v-model="myValue" :type="type"
:placeholder="placeholder || t('rule.pleaseEnter')" :disabled="disabled" :clearable="clearable"> :placeholder="placeholder || t('rule.pleaseEnter')" :disabled="disabled" :clearable="clearable">
<template v-if="label" #prepend>{{ label }}</template> <template v-if="label" #prepend>{{ label }}</template>
</el-input> </el-input>
@ -22,6 +22,10 @@ const prop = defineProps({
type: String, type: String,
default: null default: null
}, },
class: {
type: String,
default: null
},
type: { type: {
type: String, type: String,
default: null default: null

283
packages/manage/common/head.vue

@ -1,283 +0,0 @@
<template>
<el-button v-if="closeAble" class="close-btn" :icon="isClose ? 'CaretRight' : 'CaretLeft'" circle
:size="state.size.size" @click="close"></el-button>
<div class="head">
<div class="title">
<el-image class="logo" v-if="logo" :src="logo" fit="fit" />
{{ title || t('title') }}
</div>
<div class="menu">
<el-dropdown class="icon" :size="state.size.size" :teleported="false">
<el-button :size="state.size.size" icon="Avatar" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="center" @click="router.push(center)">
{{ t('head.center') }}
</el-dropdown-item>
<el-dropdown-item @click="updatePass">{{ t('pwd.changePwd') }}</el-dropdown-item>
<el-dropdown-item @click="dispatch('logout'); emit('logout')">{{ t('head.logout')
}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-tooltip effect="dark" :content="t('head.fullScreen')" placement="bottom">
<el-icon @click="fullscreen" class="icon">
<FullScreen />
</el-icon>
</el-tooltip>
<el-tooltip effect="dark" :content="t('head.changeStyle')" placement="left">
<el-dropdown v-show="styleAble" class="icon" :size="state.size.size" trigger="click" :teleported="false">
<el-button :size="state.size.size" icon="Opportunity" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="changeStyle('plain')">
<el-tooltip effect="dark" :content="t('head.default')" placement="left">
<el-icon class="dropdown-icon">
<Sunset />
</el-icon>
</el-tooltip>
</el-dropdown-item>
<el-dropdown-item @click="changeStyle('light')">
<el-tooltip effect="dark" :content="t('head.light')" placement="left">
<el-icon class="dropdown-icon">
<Sunny />
</el-icon>
</el-tooltip>
</el-dropdown-item>
<el-dropdown-item @click="changeStyle('dark')">
<el-tooltip effect="dark" :content="t('head.dark')" placement="left">
<el-icon class="dropdown-icon">
<MoonNight />
</el-icon>
</el-tooltip>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
<el-tooltip effect="dark" :content="t('head.language')" placement="left">
<el-dropdown v-show="langAble" class="icon" :size="state.size.size" trigger="click" :teleported="false">
<el-button icon="Flag" :size="state.size.size" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="changeLang('zh')">{{ t('head.zh') }}</el-dropdown-item>
<el-dropdown-item @click="changeLang('en')">{{ t('head.en') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
<el-tooltip effect="dark" :content="t('head.size')" placement="left">
<el-dropdown v-show="sizeAble" class="icon" :size="state.size.size" trigger="click" :teleported="false">
<el-button icon="Switch" :size="state.size.size" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="changeSize('small')">{{ t('head.small') }}</el-dropdown-item>
<el-dropdown-item @click="changeSize('normal')">{{ t('head.normal') }}</el-dropdown-item>
<el-dropdown-item @click="changeSize('large')">{{ t('head.large') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
<span class="username" v-if="username">{{ username }}</span>
</div>
</div>
<el-dialog :title="t('pwd.changePwd')" v-model="flag.update" :size="state.size.size" :close-on-click-modal="false"
top="10vh" width="40%">
<ModifyForm :width="150" :param="password" @cancel="flag.update = false"
@confirm="emit('updatePwd', password); flag.update = false" :rules="rules" :items="items">
</ModifyForm>
</el-dialog>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { ModifyForm } from "noob-mengyxu";
import { Element, Styles, Size, NoobInput } from "noob-mengyxu";
import { useRouter } from "vue-router";
import { useI18n } from "vue3-i18n";
const { SimpleRequired, SimplePassword } = Element;
const { state, commit, dispatch } = useStore();
const router = useRouter();
const i18n = useI18n();
const { t } = useI18n();
const emit = defineEmits(["updatePwd", "logout"]);
const flag = reactive({
update: false
})
const password = ref({
new: '',
reNew: '',
old: ''
})
const props = defineProps({
title: {
type: String,
default: null,
},
username: {
type: String,
default: null,
},
styleAble: {
type: Boolean,
},
sizeAble: {
type: Boolean,
},
langAble: {
type: Boolean,
},
center: {
type: String,
default: null,
},
closeAble: {
type: Boolean,
default: false,
},
logo: {
type: String,
default: null,
},
});
const isClose = ref(false)
const close = () => {
isClose.value = !isClose.value;
if (isClose.value) {
state.size.asideWidth = '0px';
commit("initSize");
} else {
state.size.asideWidth = state.size.aside + 'px';
commit("initSize");
}
}
const rules = {
old: [new SimpleRequired('pwd.oldPwd')],
new: [new SimpleRequired('pwd.newPwd'), new SimplePassword()],
reNew: [{
required: true,
trigger: 'blur',
validator: (rule: any, value: any, callback: any) => {
if (value == null || value === '') {
callback(new Error(t('pwd.plsRePwd')));
} else if (value != password.value.new) {
callback(new Error(t('pwd.rePwdError')));
}
callback();
}
}]
}
const items = [
{ i18n: 'pwd.oldPwd', code: 'old', type: "password" },
{ i18n: 'pwd.newPwd', code: 'new', type: "password" },
{ i18n: 'pwd.rePwd', code: 'reNew', type: "password" },
]
const updatePass = () => {
password.value = {
new: '',
reNew: '',
old: ''
};
flag.update = true;
}
const fullscreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
const changeStyle = type => {
commit('updateState', ['style', Styles[type]]);
}
const changeLang = type => {
i18n.setLocale(type);
}
const changeSize = type => {
commit('updateState', ['size', Size[type]])
commit('initSize', window.innerHeight);
}
onMounted(() => { });
</script>
<style lang="scss" scoped>
.close-btn {
position: absolute;
z-index: 99;
top: v-bind('state.size.closeTop');
left: -5px;
color: red;
background: transparent;
}
.head {
background-color: v-bind('state.style.headBg');
height: v-bind('state.size.headHeight');
}
.logo {
float: left;
width: v-bind('state.size.headHeight');
height: v-bind('state.size.headHeight');
}
.title {
height: v-bind('state.size.headHeight');
// width: v-bind('state.size.asideWidth');
text-align: center;
float: left;
font-size: v-bind('state.size.titleSize');
line-height: v-bind('state.size.headHeight');
font-weight: bold;
color: v-bind('state.style.titleColor');
}
.menu {
float: right;
line-height: v-bind('state.size.headHeight');
width: v-bind('state.size.headMenuWidth');
padding-right: 10px;
align-items: center;
justify-content: center;
.icon {
float: right;
cursor: pointer;
height: v-bind('state.size.headHeight');
margin-right: 20px;
font-size: v-bind('state.size.headIconSize');
align-items: center;
color: v-bind('state.style.color');
}
.username {
float: right;
height: v-bind('state.size.headHeight');
margin-right: 20px;
font-size: v-bind('state.size.titleSize');
font-weight: bold;
color: v-bind('state.style.color');
}
}
.dropdown-icon {
font-size: 20px;
margin: 5px 3px;
}
</style>

4
packages/manage/common/index.ts

@ -0,0 +1,4 @@
import Login from './login.vue';
import Login2 from './login2.vue';
export default { Login, Login2 };

127
packages/manage/common/login.vue

@ -0,0 +1,127 @@
<template>
<div class="login">
<el-form label-position="right" class="login-form" :model="param" ref="loginForm" :rules="rules">
<div class="logo-item" v-if="logo">
<el-image class="logo" :src="logo" fit="fit" />
</div>
<el-form-item>
<div class="lte-title"> {{ t('title') }} </div >
</el-form-item>
<el-form-item prop="userId">
<NoobInput v-model="param.userId" :placeholder="t('pwd.userId')" :full="true"></NoobInput>
</el-form-item>
<el-form-item prop="password">
<NoobInput v-model="param.password" type="password" :placeholder="t('pwd.pwd')" :full="true">
</NoobInput>
</el-form-item>
<el-form-item>
<NoobButton @click="login">{{ t('pwd.login') }}</NoobButton>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { onBeforeMount, onMounted, ref } from "vue";
import { useRouter } from "vue-router";
import { FormInstance } from "element-plus";
import { Api, NoobInput, NoobButton, Element } from "noob-mengyxu";
import md5 from "js-md5";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const { SimpleRequired } = Element;
const emit = defineEmits(["login"]);
const param = ref<any>({});
const loginForm = ref<FormInstance>();
const rules = {
userId: [new SimpleRequired('pwd.userId')],
password: [new SimpleRequired('pwd.pwd')]
}
const props = defineProps({
logo: {
type: String,
default: null,
},
});
const router = useRouter();
onBeforeMount(() => {
state.size.headHeight = '0px';
state.size.asideWidth = '0px';
commit("initSize");
});
const loginConfirm = user => {
const param = JSON.parse(JSON.stringify(user));
param.password = md5(param.password);
Api.pub.login(param).then(rsp => {
if (rsp) {
state.size.headHeight = state.size.head + 'px';
state.size.asideWidth = state.size.aside + 'px';
commit("initSize");
dispatch("getMenus");
router.back();
}
})
};
const login = () => {
if (!loginForm.value) return;
loginForm.value?.validate((valid, fields) => {
if (valid) {
loginConfirm(param.value);
loginForm.value?.clearValidate();
}
});
}
onMounted(() => { });
</script>
<style lang="scss" scoped>
.login {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.login-form {
width: v-bind('state.size.loginWidth');
height: v-bind('state.size.loginHeight');
align-self: center;
}
.logo-item {
text-align: center;
align-items: center;
}
.logo {
width: 50px;
height: 50px;
img {
display: inline !important;
}
}
.lte-title {
font-size: 1.5em;
font-weight: bold;
text-align: center;
width: 100%;
color: rgb(49, 89, 143);
}
.el-button {
width: 100%;
}
</style>

145
packages/manage/common/login2.vue

@ -0,0 +1,145 @@
<template>
<div class="login">
<el-form label-position="right" class="login-form" :model="param" ref="loginForm" :rules="rules">
<div class="logo-item" v-if="logo">
<el-image class="logo" :src="logo" fit="fit" />
</div>
<div class="lte-title"> {{ t('title') }} </div>
<el-form-item vlass prop="userId">
<span class="login-label">{{ t('pwd.userId') }}:</span>
<NoobInput class="login-input " v-model="param.userId" :full="true" placeholder=" " />
</el-form-item>
<el-form-item prop="password">
<span class="login-label">{{ t('pwd.pwd') }}:</span>
<NoobInput class="login-input" v-model="param.password" type="password" :full="true" placeholder=" " />
</el-form-item>
<el-form-item>
<NoobButton class="login-btn" @click="login">{{ t('pwd.login') }}</NoobButton>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { onBeforeMount, onMounted, ref } from "vue";
import { useRouter } from "vue-router";
import { FormInstance } from "element-plus";
import { Api, NoobInput, NoobButton, Element } from "noob-mengyxu";
import md5 from "js-md5";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const { SimpleRequired } = Element;
const emit = defineEmits(["login"]);
const param = ref<any>({});
const loginForm = ref<FormInstance>();
const rules = {
userId: [new SimpleRequired('pwd.userId')],
password: [new SimpleRequired('pwd.pwd')]
}
const props = defineProps({
logo: {
type: String,
default: null,
},
});
const router = useRouter();
onBeforeMount(() => {
state.size.headHeight = '0px';
state.size.asideWidth = '0px';
commit("initSize");
});
const loginConfirm = user => {
const param = JSON.parse(JSON.stringify(user));
param.password = md5(param.password);
Api.pub.login(param).then(rsp => {
if (rsp) {
state.size.headHeight = state.size.head + 'px';
state.size.asideWidth = state.size.aside + 'px';
commit("initSize");
dispatch("getMenus");
router.back();
}
})
};
const login = () => {
if (!loginForm.value) return;
loginForm.value?.validate((valid, fields) => {
if (valid) {
loginConfirm(param.value);
loginForm.value?.clearValidate();
}
});
}
onMounted(() => { });
</script>
<style lang="scss" scoped>
.login {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.login-form {
width: 600px;
height: 600px;
align-self: center;
}
.logo-item {
text-align: center;
align-items: center;
}
.logo {
width: 50px;
height: 50px;
img {
display: inline !important;
}
}
.lte-title {
font-size: 2.5em;
height: 100px;
line-height: 100px;
font-weight: bold;
text-align: center;
width: 100%;
color: #424242;
}
.login-input {
::v-deep .el-input__inner {
font-size: 2rem;
line-height: 3.5rem;
height: 3.5rem;
padding: 1rem;
}
}
.el-button {
width: 100%;
}
.login-btn {
margin-top: 1.2rem;
font-size: 1.5rem;
line-height: 2rem;
height: 3rem;
}
</style>

26
packages/manage/head/fullscreen.vue

@ -0,0 +1,26 @@
<template>
<el-tooltip effect="dark" :content="t('head.fullScreen')" placement="bottom">
<el-icon @click="fullscreen" class="head-icon">
<FullScreen />
</el-icon>
</el-tooltip>
</template>
<script lang="ts" setup>
import { onMounted } from "vue";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const fullscreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
onMounted(() => { });
</script>
<style lang="scss" scoped></style>

119
packages/manage/head/head.vue

@ -0,0 +1,119 @@
<template>
<el-button v-if="closeAble" class="close-aside-btn" :icon="isClose ? 'CaretRight' : 'CaretLeft'" circle
:size="state.size.size" @click="close"></el-button>
<div class="head">
<div class="head-left">
<div class="title">
<el-image class="logo" v-if="logo" :src="logo" fit="fit" />
{{ title || t('title') }}
</div>
<slot name="left"></slot>
</div>
<div class="head-right">
<slot></slot>
<span class="username" v-if="username">{{ username }}</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const props = defineProps({
closeAble: {
type: Boolean,
default: false,
},
title: {
type: String,
default: null,
},
logo: {
type: String,
default: null,
},
username: {
type: String,
default: null,
},
})
const isClose = ref(false)
const close = () => {
isClose.value = !isClose.value;
if (isClose.value) {
state.size.asideWidth = '0px';
commit("initSize");
} else {
state.size.asideWidth = state.size.aside + 'px';
commit("initSize");
}
}
onMounted(() => { });
</script>
<style lang="scss">
//@import url(); css
.close-aside-btn {
position: absolute;
z-index: 99;
top: v-bind('state.size.closeTop');
left: -5px;
color: red;
background: transparent;
}
.title {
height: v-bind('state.size.headHeight');
// width: v-bind('state.size.asideWidth');
text-align: center;
float: left;
font-size: v-bind('state.size.titleSize');
line-height: v-bind('state.size.headHeight');
font-weight: bold;
color: v-bind('state.style.titleColor');
}
.head-left {
float: left;
line-height: v-bind('state.size.headHeight');
width: v-bind('state.size.headLeftWidth');
align-items: center;
justify-content: center;
}
.head-right {
float: right;
line-height: v-bind('state.size.headHeight');
width: v-bind('state.size.headRightWidth');
padding-right: 10px;
align-items: center;
justify-content: center;
.head-icon {
float: right;
cursor: pointer;
height: v-bind('state.size.headHeight');
margin-right: 20px;
font-size: v-bind('state.size.headIconSize');
align-items: center;
color: v-bind('state.style.color');
}
.username {
float: right;
height: v-bind('state.size.headHeight');
margin-right: 20px;
font-size: v-bind('state.size.titleSize');
font-weight: bold;
color: v-bind('state.style.color');
}
}
</style>

9
packages/manage/head/index.ts

@ -0,0 +1,9 @@
import Head from './head.vue';
import HeadPersonal from './personal.vue';
import Fullscreen from './fullscreen.vue';
import StyleChange from './style-change.vue';
import LangChange from './lang-change.vue';
import SizeChange from './size-change.vue';
import MenuTree from './menu-tree.vue';
export default { MenuTree, Head, HeadPersonal, Fullscreen, StyleChange, LangChange, SizeChange };

29
packages/manage/head/lang-change.vue

@ -0,0 +1,29 @@
<template>
<el-tooltip effect="dark" :content="t('head.language')" placement="left">
<el-dropdown class="head-icon" :size="state.size.size" trigger="click" :teleported="false">
<el-button icon="Flag" :size="state.size.size" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="changeLang('zh')">{{ t('head.zh') }}</el-dropdown-item>
<el-dropdown-item @click="changeLang('en')">{{ t('head.en') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
const { t, setLocale } = useI18n();
const { state, commit, dispatch } = useStore();
const changeLang = type => {
setLocale(type);
}
onMounted(() => { });
</script>
<style lang="scss" scoped></style>

44
packages/manage/common/menu-tree.vue → packages/manage/head/menu-tree.vue

@ -1,15 +1,19 @@
<template> <template>
<el-menu :default-active="active" router class="menu-tree" :text-color="state.style.menuColor" <el-menu :default-active="active" router :mode="mode" :class="mode" :text-color="state.style.menuColor"
:background-color="state.style.menuBg" :active-text-color="state.style.menuActiveColor" :size="state.size.size"> :background-color="mode == 'horizontal' ? state.style.headBg : state.style.menuBg"
:active-text-color="state.style.menuActiveColor" :size="state.size.size">
<template v-for="menu in data || state.menus"> <template v-for="menu in data || state.menus">
<template v-if="menu.children && menu.children.length > 0"> <template v-if="menu.children && menu.children.length > 0">
<el-sub-menu :index="getPath(menu)" :key="menu.path"> <el-sub-menu :index="getPath(menu)" :key="menu.path">
<template #title> <template #title>
<component class="icon" :is="menu.icon || state.style.menuDefaultIcon"></component> <component class="icon" :is="menu.icon || state.style.menuDefaultIcon">
</component>
<span>{{ menu.title || t(menu.i18n) }}</span> <span>{{ menu.title || t(menu.i18n) }}</span>
</template> </template>
<el-menu-item v-for="child in menu.children" :index="getPath(child)" :router="router"> <el-menu-item v-for="child in menu.children" :index="getPath(child)" :router="router">
<component class="icon" :is="child.icon || state.style.menuDefaultIcon"></component> <component class="icon" :width="getters.menuIconSize" :height="getters.menuIconSize"
:is="child.icon || state.style.menuDefaultIcon">
</component>
{{ child.title || t(child.i18n) }} {{ child.title || t(child.i18n) }}
</el-menu-item> </el-menu-item>
</el-sub-menu> </el-sub-menu>
@ -26,22 +30,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { useStore } from "vuex"; import { useStore } from "vuex";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { ref, onMounted } from "vue" import { ref, onMounted, reactive } from "vue"
import { useI18n } from "vue3-i18n"; import { useI18n } from "vue3-i18n";
const { t } = useI18n(); const { t } = useI18n();
const { state, commit } = useStore() const { state, getters } = useStore()
const props = defineProps({ const props = defineProps({
mode: {
type: String,
default: 'vertical'
},
data: { data: {
type: Array<any>(), type: Array<any>(),
default: null default: null
}, },
type: {
type: String,
default: 'def',
},
}); });
const style = reactive({ 'margin-right': '10px', width: getters.menuIconSize, height: getters.menuIconSize })
const router = useRouter(); const router = useRouter();
const getPath = (menu) => { const getPath = (menu) => {
const prefix = menu.path.startsWith("/") ? "" : "/"; const prefix = menu.path.startsWith("/") ? "" : "/";
@ -58,14 +63,20 @@ onMounted(() => {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.menu-tree { .horizontal {
padding-top: 1px;
height: v-bind('state.size.headHeight');
border: none;
// display: inline-flex;
}
.vertical {
padding-top: 1px; padding-top: 1px;
height: v-bind('state.size.mainHeight'); height: v-bind('state.size.mainHeight');
border: none; border: none;
} }
.icon { .icon {
// margin-left: -15px;
margin-right: 10px; margin-right: 10px;
width: v-bind('state.size.menuIconSize'); width: v-bind('state.size.menuIconSize');
height: v-bind('state.size.menuIconSize'); height: v-bind('state.size.menuIconSize');
@ -75,9 +86,14 @@ onMounted(() => {
background-color: v-bind('state.style.menuActiveBg'); background-color: v-bind('state.style.menuActiveBg');
} }
.el-sub-menu, .vertical .el-sub-menu,
.el-menu-item { .vertical .el-menu-item {
min-width: v-bind('state.size.asideWidth') !important; min-width: v-bind('state.size.asideWidth') !important;
font-size: v-bind('state.size.fontSize') !important; font-size: v-bind('state.size.fontSize') !important;
} }
.horizontal .el-sub-menu,
.horizontal .el-menu-item {
font-size: v-bind('state.size.fontSize') !important;
}
</style> </style>

87
packages/manage/head/personal.vue

@ -0,0 +1,87 @@
<template>
<el-dropdown class="head-icon" :size="state.size.size" :teleported="false">
<el-button :size="state.size.size" icon="Avatar" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="center" @click="router.push(center)">
{{ t('head.center') }}
</el-dropdown-item>
<el-dropdown-item @click="updatePass">{{ t('pwd.changePwd') }}</el-dropdown-item>
<el-dropdown-item @click="dispatch('logout'); emit('logout')">{{ t('head.logout')
}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-dialog :title="t('pwd.changePwd')" v-model="flag.update" :size="state.size.size" :close-on-click-modal="false"
top="10vh" width="40%">
<ModifyForm :width="150" :param="password" @cancel="flag.update = false"
@confirm="emit('updatePwd', password); flag.update = false" :rules="rules" :items="items">
</ModifyForm>
</el-dialog>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { Element, ModifyForm } from "noob-mengyxu";
import { useRouter } from "vue-router";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const { SimpleRequired, SimplePassword } = Element;
const router = useRouter();
const flag = reactive({
update: false
})
const password = ref({
new: '',
reNew: '',
old: ''
})
const emit = defineEmits(["updatePwd", "logout"]);
const props = defineProps({
center: {
type: String,
default: null,
},
})
const rules = {
old: [new SimpleRequired('pwd.oldPwd')],
new: [new SimpleRequired('pwd.newPwd'), new SimplePassword()],
reNew: [{
required: true,
trigger: 'blur',
validator: (rule: any, value: any, callback: any) => {
if (value == null || value === '') {
callback(new Error(t('pwd.plsRePwd')));
} else if (value != password.value.new) {
callback(new Error(t('pwd.rePwdError')));
}
callback();
}
}]
}
const items = [
{ i18n: 'pwd.oldPwd', code: 'old', type: "password" },
{ i18n: 'pwd.newPwd', code: 'new', type: "password" },
{ i18n: 'pwd.rePwd', code: 'reNew', type: "password" },
]
const updatePass = () => {
password.value = {
new: '',
reNew: '',
old: ''
};
flag.update = true;
}
onMounted(() => { });
</script>
<style lang="scss" scoped></style>

32
packages/manage/head/size-change.vue

@ -0,0 +1,32 @@
<template>
<el-tooltip effect="dark" :content="t('head.size')" placement="left">
<el-dropdown class="head-icon" :size="state.size.size" trigger="click" :teleported="false">
<el-button icon="Switch" :size="state.size.size" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="changeSize('small')">{{ t('head.small') }}</el-dropdown-item>
<el-dropdown-item @click="changeSize('normal')">{{ t('head.normal') }}</el-dropdown-item>
<el-dropdown-item @click="changeSize('large')">{{ t('head.large') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
import { Size } from "noob-mengyxu";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const changeSize = type => {
commit('updateState', ['size', Size[type]])
commit('initSize', [window.innerHeight, window.innerWidth]);
}
onMounted(() => { });
</script>
<style lang="scss" scoped></style>

63
packages/manage/head/style-change.vue

@ -0,0 +1,63 @@
<template>
<el-tooltip effect="dark" :content="t('head.changeStyle')" placement="left">
<el-dropdown class="head-icon" :size="state.size.size" trigger="click" :teleported="false">
<el-button :size="state.size.size" icon="Opportunity" circle></el-button>
<template #dropdown>
<el-dropdown-menu>
<!-- <el-dropdown-item v-for="item in Styles" @click="changeStyle(item.name)">
<el-tooltip effect="dark" :content="t(item.i18n)" placement="left">
<component class="icon" :is="item.icon"></component>
</el-tooltip>
</el-dropdown-item> -->
<el-dropdown-item @click="changeStyle('plainb')">
<el-tooltip effect="dark" :content="t('styles[3]')" placement="left">
<el-icon class="dropdown-icon">
<Sunset />
</el-icon>
</el-tooltip>
</el-dropdown-item>
<el-dropdown-item @click="changeStyle('plain')">
<el-tooltip effect="dark" :content="t('styles[0]')" placement="left">
<el-icon class="dropdown-icon">
<Sunset />
</el-icon>
</el-tooltip>
</el-dropdown-item>
<el-dropdown-item @click="changeStyle('light')">
<el-tooltip effect="dark" :content="t('styles[1]')" placement="left">
<el-icon class="dropdown-icon">
<Sunny />
</el-icon>
</el-tooltip>
</el-dropdown-item>
<el-dropdown-item @click="changeStyle('dark')">
<el-tooltip effect="dark" :content="t('styles[2]')" placement="left">
<el-icon class="dropdown-icon">
<MoonNight />
</el-icon>
</el-tooltip>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-tooltip>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { onMounted } from "vue";
import { Styles } from "noob-mengyxu";
import { useI18n } from "vue3-i18n";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const changeStyle = type => {
commit('updateState', ['style', Styles[type]]);
}
onMounted(() => { });
</script>
<style lang="scss" scoped></style>

6
packages/manage/index.ts

@ -1,5 +1,5 @@
import Index from './router/index.vue'; import Index from './router/index.vue';
import MenuTree from './common/menu-tree.vue'; import Common from './common';
import Head from './common/head.vue'; import NoobHead from './head';
import Views from './views'; import Views from './views';
export { Index, MenuTree, Head, Views }; export { Index, Common, NoobHead, Views };

39
packages/manage/router/index.vue

@ -2,12 +2,21 @@
<el-container :style="appMain" ref="main" v-show="!flag.loading"> <el-container :style="appMain" ref="main" v-show="!flag.loading">
<el-header v-show="state.size.headHeight != '0px'" class="app-head" :height="state.size.headHeight"> <el-header v-show="state.size.headHeight != '0px'" class="app-head" :height="state.size.headHeight">
<Head :title="title" @updatePwd="updatePwd" @logout="onLogout" :styleAble="styleAble" :sizeAble="sizeAble" <Head :title="title" :logo="logo" :username="username">
:langAble="langAble" :center="center" :username="username" :closeAble="closeAble" :logo="logo" /> <template #left>
<MenuTree v-show="mode == 'horizontal'" :data="menus" mode="horizontal" />
</template>
<HeadPersonal @updatePwd="updatePwd" @logout="onLogout" :center="center" />
<Fullscreen />
<StyleChange v-if="styleAble" />
<LangChange v-if="langAble" />
<SizeChange v-if="sizeAble" />
</Head>
</el-header> </el-header>
<el-container id="container"> <el-container id="container">
<el-aside v-show="state.size.asideWidth != '0px'" :width="state.size.asideWidth"> <el-aside v-show="mode == 'vertical' && state.size.asideWidth != '0px'" :width="state.size.asideWidth">
<MenuTree :data="menus" :type="type" /> <MenuTree :data="menus" mode="vertical" />
</el-aside> </el-aside>
<el-main class="app-main"> <el-main class="app-main">
<router-view /> <router-view />
@ -20,7 +29,8 @@
import { reactive, onMounted, ref, onBeforeUnmount } from "vue"; import { reactive, onMounted, ref, onBeforeUnmount } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { MenuTree, Head, Api } from "noob-mengyxu" import { NoobHead, Api } from "noob-mengyxu"
const { Head, MenuTree, HeadPersonal, Fullscreen, StyleChange, LangChange, SizeChange } = NoobHead;
import md5 from "js-md5"; import md5 from "js-md5";
const { state, commit, dispatch } = useStore(); const { state, commit, dispatch } = useStore();
@ -47,9 +57,9 @@ const props = defineProps({
type: Array<any>(), type: Array<any>(),
default: null default: null
}, },
type: { mode: {
type: String, type: String,
default: 'def', default: 'vertical',
}, },
styleAble: { styleAble: {
type: Boolean, type: Boolean,
@ -88,7 +98,7 @@ const props = defineProps({
const onResize = () => { const onResize = () => {
const height = window.innerHeight; const height = window.innerHeight;
appMain.height = height + 'px'; appMain.height = height + 'px';
commit('initSize', height); commit('initSize', [height, window.innerWidth]);
} }
const getUser = (first?) => { const getUser = (first?) => {
@ -172,6 +182,18 @@ body {
.app-head { .app-head {
padding: 0px !important; padding: 0px !important;
background-color: v-bind('state.style.headBg');
height: v-bind('state.size.headHeight');
}
.head-icon {
float: right;
cursor: pointer;
height: v-bind('state.size.headHeight');
margin-right: 20px;
font-size: v-bind('state.size.headIconSize');
align-items: center;
color: v-bind('state.style.color');
} }
.form-item { .form-item {
@ -216,4 +238,5 @@ body {
color: v-bind('state.style.selectionColor'); color: v-bind('state.style.selectionColor');
} }
} }
</style> </style>

6
packages/manage/views/index.ts

@ -1,4 +1,3 @@
import Login from './login.vue';
import Buffer from './buffer.vue'; import Buffer from './buffer.vue';
import Config from './config.vue'; import Config from './config.vue';
import Dictionary from './dictionary.vue'; import Dictionary from './dictionary.vue';
@ -8,11 +7,6 @@ import User from './user.vue';
import Status from './status.vue'; import Status from './status.vue';
import Log from './log.vue'; import Log from './log.vue';
const routes = [ const routes = [
{
path: '/login',
name: 'login',
component: Login,
},
{ {
path: '/buffer', path: '/buffer',
name: 'buffer', name: 'buffer',

58
packages/manage/views/login.vue

@ -1,58 +0,0 @@
<template>
<div class="login">
<LoginForm @login="login">
</LoginForm>
</div>
</template>
<script lang="ts" setup>
import { onBeforeMount } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import md5 from "js-md5";
import { Api, LoginForm } from "noob-mengyxu";
const { state, commit, dispatch } = useStore();
const router = useRouter();
onBeforeMount(() => {
state.size.headHeight = '0px';
state.size.asideWidth = '0px';
commit("initSize");
});
const login = user => {
const param = JSON.parse(JSON.stringify(user));
param.password = md5(param.password);
Api.pub.login(param).then(rsp => {
if (rsp) {
state.size.headHeight = state.size.head + 'px';
state.size.asideWidth = state.size.aside + 'px';
commit("initSize");
dispatch("getMenus");
router.back();
}
})
};
</script>
<style lang='scss' scoped>
//@import url(); css
.login {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.canvas {
position: fixed;
z-index: -1; // background-color: black;
}
.logo {
width: 300px;
height: 90px;
}
</style>

2
plugs/config/size/large.ts

@ -8,7 +8,7 @@ export default class Small extends Normal {
headIconSize = '24px'; //头部图标尺寸 headIconSize = '24px'; //头部图标尺寸
headHeight = '60px'; //头部高度 headHeight = '60px'; //头部高度
closeTop = '45px'; //展开收起菜单按钮 closeTop = '45px'; //展开收起菜单按钮
headMenuWidth = '450px'; //头部右侧菜单宽度 headRightWidth = '450px'; //头部右侧菜单宽度
asideWidth = '200px'; //左侧菜单宽度 asideWidth = '200px'; //左侧菜单宽度
mainPad = '8px'; mainPad = '8px';

3
plugs/config/size/normal.ts

@ -7,7 +7,8 @@ export default class Normal {
headIconSize = '20px'; //头部图标尺寸 headIconSize = '20px'; //头部图标尺寸
headHeight = '50px'; //头部高度 headHeight = '50px'; //头部高度
closeTop = '40px'; //展开收起菜单按钮 closeTop = '40px'; //展开收起菜单按钮
headMenuWidth = '400px'; //头部右侧菜单宽度 headRightWidth = '400px'; //头部右侧菜单宽度
headLeftWidth = ''; //头部左侧剩余宽度
asideWidth = '180px'; //左侧菜单宽度 asideWidth = '180px'; //左侧菜单宽度
mainHeight = ''; //通用页面组件高度 mainHeight = ''; //通用页面组件高度
mainPad = '5px'; //通用页面组件内边距 mainPad = '5px'; //通用页面组件内边距

2
plugs/config/size/small.ts

@ -8,7 +8,7 @@ export default class Small extends Normal {
headIconSize = '16px'; //头部图标尺寸 headIconSize = '16px'; //头部图标尺寸
headHeight = '45px'; //头部高度 headHeight = '45px'; //头部高度
closeTop = '35px'; //展开收起菜单按钮 closeTop = '35px'; //展开收起菜单按钮
headMenuWidth = '350px'; //头部右侧菜单宽度 headRightWidth = '350px'; //头部右侧菜单宽度
asideWidth = '160px'; //左侧菜单宽度 asideWidth = '160px'; //左侧菜单宽度
menuIconSize = '16px'; menuIconSize = '16px';

3
plugs/config/styles/dark.ts

@ -3,8 +3,11 @@ import { light, dark, grey } from './color';
export default class Dark extends Plain { export default class Dark extends Plain {
name = 'dark'; //总体样式名称 name = 'dark'; //总体样式名称
icon = 'MoonNight'; //图标样式
i18n = 'styles.2'; //样式提示i18n配置
bodyBg = dark[3]; //全局背景颜色 bodyBg = dark[3]; //全局背景颜色
titleColor = light[0]; //标题颜色 titleColor = light[0]; //标题颜色
subTitleColor = light[4];//二级标题颜色
color = grey[5]; //全局字体颜色 color = grey[5]; //全局字体颜色
selectionBg = '#0438a2'; //全局文字选中后背景 selectionBg = '#0438a2'; //全局文字选中后背景

2
plugs/config/styles/index.ts

@ -1,6 +1,8 @@
import Plain from './plain'; import Plain from './plain';
import Plainb from './plainb';
import Light from './light'; import Light from './light';
import Dark from './dark'; import Dark from './dark';
export const plain = new Plain(); export const plain = new Plain();
export const plainb = new Plainb();
export const light = new Light(); export const light = new Light();
export const dark = new Dark(); export const dark = new Dark();

3
plugs/config/styles/light.ts

@ -3,8 +3,11 @@ import { light, dark, grey } from './color';
export default class Light extends Plain { export default class Light extends Plain {
name = 'light'; //总体样式名称 name = 'light'; //总体样式名称
icon = 'Sunny'; //图标样式
i18n = 'styles.1'; //样式提示i18n配置
bodyBg = light[0]; //全局背景颜色 bodyBg = light[0]; //全局背景颜色
titleColor = dark[0]; //标题颜色 titleColor = dark[0]; //标题颜色
subTitleColor = dark[3];//二级标题颜色
headBg = light[0]; //头部背景颜色 headBg = light[0]; //头部背景颜色
menuBg = light[0]; //菜单背景颜色 menuBg = light[0]; //菜单背景颜色

5
plugs/config/styles/plain.ts

@ -1,10 +1,13 @@
import { light, dark } from './color'; import { light, dark, grey } from './color';
export default class Plain { export default class Plain {
name = 'plain'; //总体样式名称 name = 'plain'; //总体样式名称
icon = 'Sunset'; //图标样式
i18n = 'styles.0'; //样式提示i18n配置
// bodyBg = light[0]; //全局背景颜色 // bodyBg = light[0]; //全局背景颜色
bodyBg = light[7]; //全局背景颜色 bodyBg = light[7]; //全局背景颜色
titleColor = light[0]; //标题颜色 titleColor = light[0]; //标题颜色
subTitleColor = dark[9];//二级标题颜色
color = '#4e5969'; //全局字体颜色 color = '#4e5969'; //全局字体颜色
selectionBg = '#3367d1'; //全局文字选中后背景 selectionBg = '#3367d1'; //全局文字选中后背景
selectionColor = '#fff'; //全局文字选中后背景 selectionColor = '#fff'; //全局文字选中后背景

17
plugs/config/styles/plainb.ts

@ -0,0 +1,17 @@
import Plain from './plain';
import { light, dark, grey } from './color';
export default class Plainb extends Plain {
name = 'plainb'; //总体样式名称
i18n = 'styles.3'; //样式提示i18n配置
// bodyBg = light[0]; //全局背景颜色
bodyBg = light[0]; //全局背景颜色
titleColor = light[3]; //标题颜色
subTitleColor = '#424242'; //二级标题颜色
color = grey[0]; //全局字体颜色
selectionBg = '#9255f4'; //全局文字选中后背景
headBg = '#6200ee'; //头部背景颜色
menuBg = '#ebebeb'; //菜单背景颜色
}

5
plugs/i18n/en.ts

@ -36,14 +36,13 @@ export default class English {
required: 'The password contains at least uppercase and lowercase letters and numbers', required: 'The password contains at least uppercase and lowercase letters and numbers',
}; };
styles = ['Default', 'Lignt', 'Dark', 'DefaultB'];
head = { head = {
center: 'Personal center', center: 'Personal center',
logout: 'Logout', logout: 'Logout',
fullScreen: 'Toggle full screen', fullScreen: 'Toggle full screen',
changeStyle: 'Switch themes', changeStyle: 'Switch themes',
default: 'Default',
light: 'Lignt',
dark: 'Dark',
language: 'Language', language: 'Language',
zh: 'Chinese', zh: 'Chinese',
en: 'English', en: 'English',

4
plugs/i18n/zh.ts

@ -35,15 +35,13 @@ export default class Zh {
noSpace: '密码不能包含空格', noSpace: '密码不能包含空格',
required: '密码至少包含大小写字母和数字', required: '密码至少包含大小写字母和数字',
}; };
styles = ['默认', '明亮', '黑夜', '默认2'];
head = { head = {
center: '个人中心', center: '个人中心',
logout: '退出登录', logout: '退出登录',
fullScreen: '切换全屏', fullScreen: '切换全屏',
changeStyle: '切换主题', changeStyle: '切换主题',
default: '默认',
light: '明亮',
dark: '黑夜',
language: '语言', language: '语言',
zh: '中文', zh: '中文',
en: '英文', en: '英文',

24
plugs/store/index.ts

@ -61,29 +61,37 @@ export class Mutations {
updateState = (state, param) => { updateState = (state, param) => {
state[param[0]] = param[1]; state[param[0]] = param[1];
}; };
initSize = (state, height) => { initSize = (state, param) => {
const size = state.size; const size = state.size;
const head = parseInt(size.headHeight); const head = parseInt(size.headHeight);
const mainPad = parseInt(size.mainPad); const mainPad = parseInt(size.mainPad);
const searchRow = parseInt(size.searchRowHeight); const searchRow = parseInt(size.searchRowHeight);
const searchRowPad = parseInt(size.searchRowPad); const searchRowPad = parseInt(size.searchRowPad);
if (height) { const headRightWidth = parseInt(size.headRightWidth);
size.height = height; if (param) {
} else { size.height = param[0];
height = size.height; size.width = param[1];
} }
size.mainHeight = Math.floor(height - head) + 'px'; size.mainHeight = Math.floor(size.height - head) + 'px';
size.tableHeight = height - 2 * (mainPad + searchRowPad) - 3 - searchRow - head; size.tableHeight = size.height - 2 * (mainPad + searchRowPad) - 3 - searchRow - head;
size.pTableHeight = size.tableHeight - size.pageHeight; size.pTableHeight = size.tableHeight - size.pageHeight;
size.headLeftWidth = size.width - headRightWidth - 10 + 'px';
}; };
updateDict = (state, param) => { updateDict = (state, param) => {
state.dict[param[0]] = param[1]; state.dict[param[0]] = param[1];
}; };
} }
export class Getters {
menuIconSize = (state) => {
return state.size.menuIconSize;
};
}
export interface StoreOptions { export interface StoreOptions {
state?: State; state?: State;
getters?; getters?: Getters;
actions?; actions?;
mutations?: Mutations; mutations?: Mutations;
modules?; modules?;

Loading…
Cancel
Save