简化,适用于快速搭建项目
This commit is contained in:
parent
7802b85ed2
commit
fc3679a5eb
Binary file not shown.
Before Width: | Height: | Size: 945 B |
Binary file not shown.
Before Width: | Height: | Size: 729 B |
Binary file not shown.
Before Width: | Height: | Size: 847 B |
Binary file not shown.
Before Width: | Height: | Size: 379 B |
Binary file not shown.
Before Width: | Height: | Size: 653 B |
Binary file not shown.
Before Width: | Height: | Size: 839 B |
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* @Author: Guanghao
|
||||
* @Date: 2022-01-05 18:48:51
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-05 18:53:10
|
||||
* @Description: 日志相关数据请求和处理逻辑
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description 查询操作日志列表
|
||||
* @returns {Array.<Log>} 日志对象数组
|
||||
*/
|
||||
|
||||
async function findByAction() {
|
||||
return [
|
||||
{
|
||||
user: '张三',
|
||||
time: '2021-12-31 18:40:11',
|
||||
module: '演示方案',
|
||||
position: '101主题',
|
||||
action: '编辑'
|
||||
},
|
||||
{
|
||||
user: '张三',
|
||||
time: '2021-12-31 18:40:11',
|
||||
module: '演示方案',
|
||||
position: '101主题',
|
||||
action: '编辑'
|
||||
},
|
||||
{
|
||||
user: '张三',
|
||||
time: '2021-12-31 18:40:11',
|
||||
module: '演示方案',
|
||||
position: '101主题',
|
||||
action: '编辑'
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 查询登录日志列表
|
||||
* @returns {Array.<Log>} 日志对象数组
|
||||
*/
|
||||
async function findByLogin() {
|
||||
return [
|
||||
{
|
||||
user: '张三',
|
||||
time: '2021-12-31 18:43:55',
|
||||
result: '成功',
|
||||
ip: '192.168.0.0.228'
|
||||
},
|
||||
{
|
||||
user: '张三',
|
||||
time: '2021-12-31 18:43:55',
|
||||
result: '成功',
|
||||
ip: '192.168.0.0.228'
|
||||
},
|
||||
{
|
||||
user: '张三',
|
||||
time: '2021-12-31 18:43:55',
|
||||
result: '成功',
|
||||
ip: '192.168.0.0.228'
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
findByAction,
|
||||
findByLogin
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-31 14:31:45
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 14:00:53
|
||||
* @Description: 请输入
|
||||
*/
|
||||
import MenuItem from "../../entity/Ui/Menu/MenuItem.js";
|
||||
|
||||
async function getBackMenuItems() {
|
||||
return [
|
||||
new MenuItem({
|
||||
title: '组织架构',
|
||||
iconClass: 'el-icon-s-operation',
|
||||
routerName: 'Org',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '角色管理',
|
||||
iconClass: 'el-icon-user',
|
||||
routerName: 'Role',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '分类管理',
|
||||
iconClass: 'el-icon-film',
|
||||
routerName: 'Classification',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '数据统计',
|
||||
iconClass: 'el-icon-s-data',
|
||||
routerName: 'Statistics',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '专题管理',
|
||||
iconClass: 'el-icon-edit-outline',
|
||||
routerName: 'Topic',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '平台设置',
|
||||
iconClass: 'el-icon-setting',
|
||||
routerName: 'PlatformSetting',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '授权管理',
|
||||
iconClass: 'el-icon-finished',
|
||||
routerName: 'Authorization',
|
||||
children: [
|
||||
new MenuItem({
|
||||
title: '合作伙伴授权管理',
|
||||
routerName: 'Authorization4Partner',
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '客户授权管理',
|
||||
routerName: 'Authorization4Customer',
|
||||
})
|
||||
]
|
||||
}),
|
||||
new MenuItem({
|
||||
title: '系统日志',
|
||||
iconClass: 'el-icon-notebook-2',
|
||||
routerName: 'Log',
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
export default {
|
||||
getBackMenuItems
|
||||
};
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2021-12-18 02:20:09
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-07 16:40:08
|
||||
* @LastEditTime: 2022-03-07 14:36:12
|
||||
* @Description: 请输入
|
||||
*/
|
||||
|
||||
|
@ -10,6 +10,13 @@ import MenuItem from "../entity/Ui/Menu/MenuItem.js";
|
|||
|
||||
async function getMainMenuItems() {
|
||||
return [
|
||||
|
||||
new MenuItem({
|
||||
id: 'ProductAndCases',
|
||||
title: '产品案例',
|
||||
|
||||
routerName: 'ProductAndCases',
|
||||
}),
|
||||
// 内部标签
|
||||
new MenuItem({
|
||||
id: 'ProductAndCases',
|
||||
|
@ -51,68 +58,16 @@ async function getMainMenuItems() {
|
|||
routerName: 'PersonalSpace',
|
||||
}),
|
||||
// popover
|
||||
new MenuItem({
|
||||
id: 'More',
|
||||
title: '更多',
|
||||
iconSrc: require("../assets/MenuIcons/Main/More1.png"),
|
||||
iconSrcInactive: require("../assets/MenuIcons/Main/More2.png"),
|
||||
// routerName: 'More',
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
async function getSecondaryMenuItems() {
|
||||
return [
|
||||
// 抽屉
|
||||
new MenuItem({
|
||||
id: 'QuickFavorites',
|
||||
title: '快捷收藏',
|
||||
iconSrc: require("../assets/MenuIcons/Secondary/QuickFavorites.png"),
|
||||
// routerName: 'QuickFavorites',
|
||||
drawerName: 'QuickFavorites'
|
||||
}),
|
||||
// 内部标签
|
||||
new MenuItem({
|
||||
id: 'QuickDemonstrations',
|
||||
title: '快捷演示方案',
|
||||
iconSrc: require("../assets/MenuIcons/Secondary/QuickDemonstrations.png"),
|
||||
routerName: 'QuickDemonstrations',
|
||||
}),
|
||||
// 抽屉
|
||||
new MenuItem({
|
||||
id: 'Clients',
|
||||
title: '客户列表',
|
||||
iconSrc: require("../assets/MenuIcons/Secondary/Clients.png"),
|
||||
// routerName: 'Clients',
|
||||
drawerName: 'Clients'
|
||||
}),
|
||||
// 抽屉
|
||||
new MenuItem({
|
||||
id: 'Partners',
|
||||
title: '合作伙伴',
|
||||
iconSrc: require("../assets/MenuIcons/Secondary/Partners.png"),
|
||||
// routerName: 'Partners',
|
||||
drawerName: 'Partners'
|
||||
}),
|
||||
// 抽屉
|
||||
new MenuItem({
|
||||
id: 'PersonalComputer',
|
||||
title: '我的电脑',
|
||||
iconSrc: require("../assets/MenuIcons/Secondary/PersonalComputer.png"),
|
||||
// routerName: 'PersonalComputer',
|
||||
drawerName: 'PersonalComputer'
|
||||
}),
|
||||
// 内部标签
|
||||
new MenuItem({
|
||||
id: 'CloudDesktop',
|
||||
title: '云桌面',
|
||||
iconSrc: require("../assets/MenuIcons/Secondary/CloudDesktop.png"),
|
||||
routerName: 'CloudDesktop',
|
||||
}),
|
||||
// new MenuItem({
|
||||
// id: 'More',
|
||||
// title: '更多',
|
||||
// iconSrc: require("../assets/MenuIcons/Main/More1.png"),
|
||||
// iconSrcInactive: require("../assets/MenuIcons/Main/More2.png"),
|
||||
// // routerName: 'More',
|
||||
// }),
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
getMainMenuItems,
|
||||
getSecondaryMenuItems
|
||||
getMainMenuItems
|
||||
};
|
|
@ -1,218 +0,0 @@
|
|||
<template>
|
||||
<div class="header-inner" :class="arrangeMode">
|
||||
<div class="header-menu"></div>
|
||||
|
||||
<div class="header-userinfo">
|
||||
<el-popover
|
||||
v-model="isUserInfoVisible"
|
||||
class="userinfo-popover"
|
||||
width="150"
|
||||
:placement="arrangeMode === 'horizontal' ? 'bottom' : 'right'"
|
||||
trigger="click"
|
||||
>
|
||||
<el-menu
|
||||
:default-active="headerActiveIndex"
|
||||
@select="handleUserMenuSelect"
|
||||
>
|
||||
<el-menu-item index="d">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
<span slot="title">系统数据</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="a">
|
||||
<i class="el-icon-user"></i>
|
||||
<span slot="title">个人设置</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="b" v-if="isAdmin">
|
||||
<i class="el-icon-setting"></i>
|
||||
<span slot="title">管理界面</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="c">
|
||||
<i class="el-icon-switch-button"></i>
|
||||
<span slot="title">退出</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-avatar
|
||||
class="main-avatar"
|
||||
slot="reference"
|
||||
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
|
||||
></el-avatar>
|
||||
</el-popover>
|
||||
</div>
|
||||
<!-- <el-dialog
|
||||
class="dial-sys-info"
|
||||
title="系统数据"
|
||||
:visible.sync="isSysDataDialVisible"
|
||||
width="50%"
|
||||
:before-close="onSysDataDialClose"
|
||||
>
|
||||
<SysInfo :token="currUserInfo.token" :cdmsSid="currUserInfo.cdmsSid" />
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="isSysDataDialVisible = false"
|
||||
>确 定</el-button
|
||||
>
|
||||
</span>
|
||||
</el-dialog> -->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import UserLoginApi from "../../api/Rbac/UserLogin.js";
|
||||
import LoginInfo from "../../storage/login-info.js";
|
||||
// import SysInfo from "./SysInfo.vue";
|
||||
// import Menu from "./Menu.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
// SysInfo
|
||||
},
|
||||
props: {
|
||||
// 排列模式,横向还是竖向
|
||||
arrangeMode: {
|
||||
type: String,
|
||||
default: "horizontal",
|
||||
validator: function (value) {
|
||||
return ["horizontal", "vertical"].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isAdmin: false, // 是否管理员,默认不是管理员,在mounted事件里判断
|
||||
isUserInfoVisible: false, // 控制用户信息popover的显示与否
|
||||
isSysDataDialVisible: false, // 系统数据弹窗是否显示
|
||||
currUserInfo: {}, // 当前系统登录数据
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
headerActiveIndex: function () {
|
||||
return this.$route.meta.headerActiveIndex; // 当前页面应选中的头部菜单项的index
|
||||
},
|
||||
// menuDefaultActive: function () {
|
||||
// let _routerName = this.$route.name;
|
||||
// return this.mainMenuItems.findIndex(
|
||||
// (item) => item.routerName === _routerName
|
||||
// );
|
||||
// },
|
||||
},
|
||||
mounted() {
|
||||
let userInfo = LoginInfo.getUserInfo();
|
||||
this.currUserInfo = userInfo ? userInfo : {};
|
||||
},
|
||||
methods: {
|
||||
// 处理导航菜单选择事件
|
||||
// handleHeaderMenuSelect(item, index) {
|
||||
// let routerName;
|
||||
// switch (index) {
|
||||
// case 1:
|
||||
// routerName = "Test";
|
||||
// break;
|
||||
// case 2:
|
||||
// routerName = "Test2";
|
||||
// break;
|
||||
// }
|
||||
// },
|
||||
|
||||
// 处理用户信息菜单选择事件
|
||||
async handleUserMenuSelect(key, keyPath) {
|
||||
keyPath;
|
||||
switch (key) {
|
||||
case "a": // 设置
|
||||
this.isUserInfoVisible = false;
|
||||
break;
|
||||
case "b": // 管理界面
|
||||
this.isUserInfoVisible = false;
|
||||
break;
|
||||
case "c": {
|
||||
try {
|
||||
await UserLoginApi.logout(); // 无论后台退出是否成功,前端都先行退出
|
||||
} catch (e) {
|
||||
console.log("后端退出登录失败");
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
LoginInfo.removeUser();
|
||||
|
||||
let currRouteName = this.$route.name;
|
||||
if (currRouteName)
|
||||
this.$safePush({
|
||||
name: "Login",
|
||||
query: {
|
||||
routeName: currRouteName,
|
||||
},
|
||||
});
|
||||
else this.$safePush({ name: "Login" });
|
||||
break;
|
||||
}
|
||||
case "d":
|
||||
// 系统数据
|
||||
this.isSysDataDialVisible = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// 系统数据弹窗的关闭事件回调
|
||||
onSysDataDialClose(done) {
|
||||
done();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables";
|
||||
.header-inner {
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
&.horizontal {
|
||||
flex-direction: row;
|
||||
.header-userinfo {
|
||||
flex-direction: row;
|
||||
margin-right: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
.header-userinfo {
|
||||
flex-direction: column;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-menu {
|
||||
}
|
||||
|
||||
.header-userinfo {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
.userinfo-popover {
|
||||
// 让头像垂直居中
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.main-avatar {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dial-sys-info {
|
||||
::v-deep .el-dialog {
|
||||
min-width: 530px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
border-right: none; // 取消垂直导航菜单默认的右边框
|
||||
&.el-menu--horizontal {
|
||||
border-bottom: none; // 取消水平导航菜单默认的下边框
|
||||
}
|
||||
> .el-menu-item {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,195 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-18 16:30:05
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-07 17:16:09
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<!--
|
||||
props: 看下面注释
|
||||
event:
|
||||
1.select index: 选中菜单项的index, item: 选中菜单项的MenuItem类型对象
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="menu" :class="arrangeMode">
|
||||
<div class="menu-item-area" v-for="(item, index) in menuItems" :key="index">
|
||||
<div
|
||||
class="menu-item"
|
||||
:class="[index === activeIndex ? 'active' : '']"
|
||||
@click="onItemClick(item, index)"
|
||||
>
|
||||
<el-tooltip
|
||||
v-if="displayMode === 'icon'"
|
||||
class="text-tip"
|
||||
effect="light"
|
||||
:content="item.title"
|
||||
:open-delay="750"
|
||||
:placement="arrangeMode === 'horizontal' ? 'bottom' : 'right'"
|
||||
>
|
||||
<i v-if="iconMode === 'elementUi'" :class="item.iconClass"></i>
|
||||
<img v-if="iconMode === 'img'" class="icon-img" :src="item.iconSrc" />
|
||||
</el-tooltip>
|
||||
|
||||
<i
|
||||
v-if="iconMode === 'elementUi'"
|
||||
class="icon-ele"
|
||||
:class="item.iconClass"
|
||||
></i>
|
||||
<img
|
||||
v-if="iconMode === 'img' && displayMode === 'both'"
|
||||
class="icon-img"
|
||||
:src="item.iconSrc"
|
||||
/>
|
||||
<span v-if="displayMode !== 'icon'">{{ item.title }}</span>
|
||||
</div>
|
||||
<div class="sub-items" v-if="item.children && item.children.length">
|
||||
<div
|
||||
class="sub-item"
|
||||
v-for="(item, index) in item.children"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 主菜单栏的信息数组
|
||||
menuItems: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
// 排列模式,横向还是竖向
|
||||
arrangeMode: {
|
||||
type: String,
|
||||
default: "horizontal",
|
||||
validator: function (value) {
|
||||
return ["horizontal", "vertical"].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
// 显示模式,只显示文字、只显示图标,还是都显示
|
||||
displayMode: {
|
||||
type: String,
|
||||
default: "both",
|
||||
validator: function (value) {
|
||||
return ["text", "icon", "both"].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
// 图标来源,elementUi自带的图标、png jpg等格式图片、svg图标(暂不支持)
|
||||
iconMode: {
|
||||
type: String,
|
||||
default: "elementUi",
|
||||
validator: function (value) {
|
||||
return ["elementUi", "img", "svg"].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
// 当前激活菜单的 index (支持.sync)
|
||||
defaultActive: { type: Number, default: 0 },
|
||||
},
|
||||
computed: {
|
||||
activeIndex: {
|
||||
get() {
|
||||
return this.activeIndex_;
|
||||
},
|
||||
set(val) {
|
||||
// this.$emit("update:defaultActive", val); // 暂时用不上
|
||||
this.activeIndex_ = val;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
defaultActive: function (val, oldVal) {
|
||||
this.activeIndex_ = val;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeIndex_: this.defaultActive,
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
onItemClick(item, index) {
|
||||
this.activeIndex = index;
|
||||
this.$emit("select", item, index);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables";
|
||||
.menu {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
&.horizontal {
|
||||
flex-direction: row;
|
||||
.menu-item-area {
|
||||
.menu-item {
|
||||
flex-direction: row;
|
||||
border-bottom: solid 2px transparent;
|
||||
.icon-img {
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
.menu-item-area {
|
||||
.menu-item {
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
// padding-left: 48px;
|
||||
// border-right: solid 2px transparent;
|
||||
.icon-img,
|
||||
.icon-ele {
|
||||
padding-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.menu-item-area {
|
||||
.menu-item {
|
||||
display: flex;
|
||||
// justify-content: flex-start;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
color: $font-color-dark;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
border-radius: 4px;
|
||||
transition: border-color 0.3s, background-color 0.3s, color 0.3s;
|
||||
|
||||
&.active {
|
||||
// border-bottom-color: $theme-main-color;
|
||||
// border-right-color: $theme-main-color;
|
||||
background-color: $theme-main-color;
|
||||
color: #fff;
|
||||
}
|
||||
.icon-img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
.sub-items {
|
||||
.sub-item {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
padding-left: 48px;
|
||||
margin: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,96 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2022-01-04 11:46:31
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 17:40:39
|
||||
* @Description: 请输入
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="menu">
|
||||
<el-menu
|
||||
v-if="menuItems && menuItems.length"
|
||||
:default-active="activeIndex"
|
||||
@select="handleSelect"
|
||||
@open="handleOpen"
|
||||
@close="handleClose"
|
||||
>
|
||||
<template v-for="(item, index) in menuItems">
|
||||
<el-submenu
|
||||
v-if="item.children && item.children.length"
|
||||
:index="item.routerName"
|
||||
:key="index"
|
||||
>
|
||||
<template slot="title">
|
||||
<i :class="item.iconClass"></i>
|
||||
<span>{{ item.title }}</span>
|
||||
</template>
|
||||
<template v-for="(subItem, index2) in item.children">
|
||||
<el-menu-item :index="subItem.routerName" :key="index2">
|
||||
{{ subItem.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-submenu>
|
||||
<el-menu-item v-else :index="item.routerName" :key="index">
|
||||
<i :class="item.iconClass"></i>
|
||||
<span slot="title">{{ item.title }}</span>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 主菜单栏的信息数组
|
||||
menuItems: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
// 当前激活菜单的 index (支持.sync)
|
||||
defaultActive: { type: String },
|
||||
},
|
||||
computed: {
|
||||
activeIndex: {
|
||||
get() {
|
||||
if (this.activeIndex_) return this.activeIndex_;
|
||||
else return this.menuItems[0].routerName;
|
||||
},
|
||||
set(val) {
|
||||
// this.$emit("update:defaultActive", val); // 暂时用不上
|
||||
this.activeIndex_ = val;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
defaultActive: function (val, oldVal) {
|
||||
this.activeIndex_ = val;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeIndex_: this.defaultActive,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleSelect(index, indexPath) {
|
||||
// console.log("index :>> ", index);
|
||||
// console.log("indexPath :>> ", indexPath);
|
||||
const routerName = index;
|
||||
this.$safePush({ name: routerName });
|
||||
},
|
||||
handleOpen(key, keyPath) {},
|
||||
handleClose(key, keyPath) {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-menu {
|
||||
border-right: none; // 取消垂直导航菜单默认的右边框
|
||||
&.el-menu--horizontal {
|
||||
border-bottom: none; // 取消水平导航菜单默认的下边框
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,113 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2022-01-05 17:30:05
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-07 16:57:02
|
||||
* @Description: 右边导航栏(副栏)
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="header-inner" :class="arrangeMode">
|
||||
<div class="header-menu">
|
||||
<Menu
|
||||
:menuItems="secondaryMenuItems"
|
||||
:arrangeMode="arrangeMode"
|
||||
:displayMode="'icon'"
|
||||
:defaultActive="menuDefaultActive"
|
||||
:hasActiveEffect="true"
|
||||
@select="handleHeaderMenuSelect"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import MenuBiz from "../../biz/Menu.js";
|
||||
import Menu from "./Menu.vue";
|
||||
import { HIDE_DRAWER_WHEN_PUSH } from "../../const.js";
|
||||
|
||||
export default {
|
||||
components: { Menu },
|
||||
props: {
|
||||
// 排列模式,横向还是竖向
|
||||
arrangeMode: {
|
||||
type: String,
|
||||
default: "horizontal",
|
||||
validator: function (value) {
|
||||
return ["horizontal", "vertical"].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
menuDefaultActive: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
secondaryMenuItems: [], // 主菜单栏的信息数组
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// menuDefaultActive: function () {
|
||||
// // let _routerName = this.$route.name;
|
||||
// // return this.secondaryMenuItems.findIndex(
|
||||
// // (item) => item.routerName === _routerName
|
||||
// // );
|
||||
// const _routerName = this.$route.name;
|
||||
// const item = this.secondaryMenuItems.find(
|
||||
// (item) => item.routerName === _routerName
|
||||
// );
|
||||
// return item ? item.id : "";
|
||||
// },
|
||||
},
|
||||
async beforeMount() {
|
||||
this.secondaryMenuItems = await MenuBiz.getSecondaryMenuItems();
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
// 处理导航菜单选择事件
|
||||
handleHeaderMenuSelect(item, index) {
|
||||
let routerName, drawerName;
|
||||
routerName = item.routerName;
|
||||
drawerName = item.drawerName;
|
||||
if (routerName) {
|
||||
// this.$safePush({ name: routerName });
|
||||
|
||||
let drawerName;
|
||||
if (!HIDE_DRAWER_WHEN_PUSH) {
|
||||
drawerName = this.$route.query.drawerName;
|
||||
}
|
||||
this.$safePush({
|
||||
name: "Main",
|
||||
params: { routerName },
|
||||
query: { drawerName },
|
||||
});
|
||||
} else if (drawerName) {
|
||||
this.$safePush({
|
||||
name: "Main",
|
||||
query: { drawerName },
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables";
|
||||
.header-inner {
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
&.horizontal {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.header-menu {
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2021-12-18 16:30:05
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-10 21:19:25
|
||||
* @LastEditTime: 2022-03-07 14:54:56
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<!--
|
||||
|
@ -23,35 +23,35 @@ event:
|
|||
:key="index"
|
||||
@click="onItemClick(item, index)"
|
||||
>
|
||||
<el-tooltip
|
||||
v-if="displayMode === 'icon'"
|
||||
class="text-tip"
|
||||
effect="light"
|
||||
:content="item.title"
|
||||
:open-delay="750"
|
||||
:placement="arrangeMode === 'horizontal' ? 'bottom' : 'right'"
|
||||
>
|
||||
<template v-if="item.iconSrc && item.iconSrcInactive">
|
||||
<el-tooltip
|
||||
v-if="displayMode === 'icon'"
|
||||
class="text-tip"
|
||||
effect="light"
|
||||
:content="item.title"
|
||||
:open-delay="750"
|
||||
:placement="arrangeMode === 'horizontal' ? 'bottom' : 'right'"
|
||||
>
|
||||
<img
|
||||
class="icon-img"
|
||||
:src="
|
||||
item.id !== activeId && item.iconSrcInactive
|
||||
? item.iconSrcInactive
|
||||
: item.iconSrc
|
||||
"
|
||||
/>
|
||||
</el-tooltip>
|
||||
|
||||
<img
|
||||
class="icon-img"
|
||||
v-if="displayMode === 'both'"
|
||||
class="icon-img before-title"
|
||||
:src="
|
||||
item.id !== activeId && item.iconSrcInactive
|
||||
? item.iconSrcInactive
|
||||
: item.iconSrc
|
||||
"
|
||||
alt="无图标"
|
||||
/>
|
||||
</el-tooltip>
|
||||
|
||||
<img
|
||||
v-if="displayMode === 'both'"
|
||||
class="icon-img before-title"
|
||||
:src="
|
||||
item.id !== activeId && item.iconSrcInactive
|
||||
? item.iconSrcInactive
|
||||
: item.iconSrc
|
||||
"
|
||||
alt="无图标"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<span class="title-text" v-if="displayMode !== 'icon'">{{
|
||||
item.title
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-08-31 15:26:21
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 17:22:09
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-form ref="form" :model="form" :rules="orgRules" label-width="100px">
|
||||
<el-form-item label="上级部门名称">
|
||||
<el-input :value="org.name" readonly></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="name">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="btns">
|
||||
<el-button @click="onCancel">{{ btnCancelName }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import OrganizationBiz from "../../../biz/Rbac/Organization.js";
|
||||
export default {
|
||||
props: {
|
||||
org: { type: Object, required: true }, // 当前的目标上级部门
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
// id: 0,
|
||||
name: "",
|
||||
},
|
||||
orgRules: {
|
||||
name: [{ required: true, message: "请填写部门名称", trigger: "none" }],
|
||||
},
|
||||
btnCancelName: "取消",
|
||||
};
|
||||
},
|
||||
updated() {},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$refs["form"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
this.$confirm(
|
||||
`确定把在部门 ${this.org.name} 下新增 ${this.form.name} 子部门?`,
|
||||
{
|
||||
title: "确认新增",
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
this.form.name = this.form.name.trim();
|
||||
try {
|
||||
let newOrg = await OrganizationBiz.add(
|
||||
this.org.id < 0 ? null : this.org.id,
|
||||
this.form.name
|
||||
);
|
||||
if (newOrg) {
|
||||
this.$message.success(
|
||||
`${this.org.name} 成功增加下级 ${this.form.name}`
|
||||
);
|
||||
this.btnCancelName = "退出";
|
||||
this.$emit("success", this.org, newOrg);
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.error(e.message);
|
||||
}
|
||||
})
|
||||
.catch((e) => {});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$emit("cancel");
|
||||
},
|
||||
|
||||
// 供外部调用,更新本组件的一些显示
|
||||
updateForm() {
|
||||
this.$refs["form"].clearValidate();
|
||||
this.btnCancelName = "取消";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-form-item.btns {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 0;
|
||||
::v-deep .el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,105 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-08-29 02:03:41
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 17:22:26
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-form ref="form" :model="form" label-width="90px">
|
||||
<el-form-item label="原部门名称">
|
||||
<el-input :value="org.name" readonly></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新部门名称">
|
||||
<el-input v-model="form.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="btns">
|
||||
<el-button @click="onCancel">{{ btnCancelName }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import OrganizationBiz from "../../../biz/Rbac/Organization.js";
|
||||
export default {
|
||||
props: {
|
||||
org: { type: Object, required: true }, // 当前编辑的部门
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
// id: 0,
|
||||
name: "",
|
||||
},
|
||||
btnCancelName: "取消",
|
||||
};
|
||||
},
|
||||
updated() {},
|
||||
watch: {
|
||||
org: {
|
||||
handler: function (newVal, oldVal) {
|
||||
// this.form.id = newVal.id;
|
||||
this.form.name = newVal.name;
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
if (this.form.name.trim() === this.org.name) {
|
||||
this.$message.warning("新旧部门名称相同");
|
||||
} else {
|
||||
this.$confirm(
|
||||
`确定把部门名称从 ${this.org.name} 修改为 ${this.form.name}?`,
|
||||
{
|
||||
title: "确认修改",
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
this.form.name = this.form.name.trim();
|
||||
try {
|
||||
let count = await OrganizationBiz.update(
|
||||
this.org.id < 0 ? null : this.org.id,
|
||||
this.form.name
|
||||
);
|
||||
if (count) {
|
||||
this.$message.success(
|
||||
`${this.org.name} 成功修改为 ${this.form.name}`
|
||||
);
|
||||
this.btnCancelName = "退出";
|
||||
this.org.name = this.form.name; // 更新一下组织架构树状节点
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.error(e.message);
|
||||
}
|
||||
})
|
||||
.catch((e) => {});
|
||||
}
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$emit("cancel");
|
||||
},
|
||||
|
||||
// 供外部调用,更新本组件的一些显示
|
||||
updateForm() {
|
||||
this.btnCancelName = "取消";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-form-item.btns {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 0;
|
||||
::v-deep .el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,161 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-08-29 02:03:27
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 17:23:42
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div class="container">
|
||||
<LightSplit :ratios="[1, 1]" :minHeight="300">
|
||||
<template v-slot:1>
|
||||
<div class="tree-container">
|
||||
<el-tree
|
||||
ref="org-tree"
|
||||
:data="treeData"
|
||||
:node-key="'id'"
|
||||
:props="treeProps"
|
||||
:show-checkbox="false"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="true"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
@node-click="onTreeNodeClick"
|
||||
@current-change="onOrgTreeCurrChange"
|
||||
></el-tree>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:2>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
:label-position="'top'"
|
||||
:rules="orgRules"
|
||||
>
|
||||
<el-form-item label="目标上级部门名称" prop="parentName">
|
||||
<el-input
|
||||
:value="form.parentName"
|
||||
placeholder="请在左侧选择"
|
||||
readonly
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="正在移动部门名称">
|
||||
<el-input :value="org.name" readonly></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="btns">
|
||||
<el-button @click="onCancel">{{ btnCancelName }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</LightSplit>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import OrganizationBiz from "../../../biz/Rbac/Organization.js";
|
||||
import LightSplit from "../../../components/_Common/LightSplit.vue";
|
||||
export default {
|
||||
components: { LightSplit },
|
||||
props: {
|
||||
treeData: { type: Array },
|
||||
org: { type: Object, required: true }, // 当前移动的部门
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
parentId: 0,
|
||||
parentName: "",
|
||||
targetParentData: null,
|
||||
},
|
||||
orgRules: {
|
||||
parentName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择目标上级部门",
|
||||
trigger: "none",
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultExpandedKeys: [null],
|
||||
treeProps: {
|
||||
label: "name",
|
||||
children: "Children",
|
||||
},
|
||||
btnCancelName: "取消",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$refs["form"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (this.org.id === this.form.parentId) {
|
||||
this.$message.warning(`部门不能移动到自身内`);
|
||||
} else {
|
||||
this.$confirm(
|
||||
`确定把在部门 ${this.org.name} 移动到 ${this.form.parentName} 部门下面?`,
|
||||
{
|
||||
title: "确认新增",
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
try {
|
||||
let org = OrganizationBiz.move(
|
||||
this.org.id < 0 ? null : this.org.id,
|
||||
this.form.parentId !== null && this.form.parentId < 1 // 由于需要维护树状控件,树状控件不支持节点对象的id为null,故根节点id都设置为-1
|
||||
? null
|
||||
: this.form.parentId
|
||||
);
|
||||
if (org) {
|
||||
this.$message.success(
|
||||
`${this.org.name} 移动到 ${this.form.parentName} 部门下`
|
||||
);
|
||||
this.btnCancelName = "退出";
|
||||
this.$emit("success", this.org, this.form.targetParentData);
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.error(e.message);
|
||||
}
|
||||
})
|
||||
.catch((e) => {});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$emit("cancel");
|
||||
},
|
||||
|
||||
onTreeNodeClick() {},
|
||||
// 当组织架构树被改变选中时
|
||||
onOrgTreeCurrChange(data, node) {
|
||||
this.form.parentId = data.id;
|
||||
this.form.parentName = data.name;
|
||||
this.form.targetParentData = data;
|
||||
// this.$refs["form"].clearValidate();
|
||||
},
|
||||
|
||||
// 供外部调用,更新本组件的一些显示
|
||||
updateForm() {
|
||||
this.$refs["form"].clearValidate();
|
||||
this.btnCancelName = "取消";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tree-container {
|
||||
height: 100%;
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.el-form-item.btns {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 0;
|
||||
::v-deep .el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,80 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2022-01-05 11:53:19
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-05 18:21:24
|
||||
* @Description: 角色新建框
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="角色名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色说明" prop="description">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="form.description"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="btns">
|
||||
<el-button @click="$emit('on-cancel')">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RoleBiz from "../../../biz/Rbac/Role.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 角色表单
|
||||
form: {
|
||||
name: "",
|
||||
description: "",
|
||||
},
|
||||
// 角色表单验证
|
||||
rules: {
|
||||
name: [{ required: true, message: "请先填写角色名称" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 点击-确定
|
||||
handleConfirmClick() {
|
||||
this.$refs["form"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { name, description } = this.form;
|
||||
|
||||
try {
|
||||
const res = await RoleBiz.add(name, description);
|
||||
console.log("roleAdd", res);
|
||||
|
||||
this.$message.success("新建角色成功");
|
||||
this.$emit("on-submit", res);
|
||||
} catch ({ message }) {
|
||||
this.$message.error(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-form-item.btns {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 0;
|
||||
::v-deep .el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,93 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2022-01-05 11:53:19
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-05 18:21:17
|
||||
* @Description: 角色编辑框
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="角色名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色说明" prop="description">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="form.description"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="btns">
|
||||
<el-button @click="$emit('on-cancel')">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirmClick">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from "../../_Common/Dialog.vue";
|
||||
|
||||
import RoleBiz from "../../../biz/Rbac/Role.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Dialog,
|
||||
},
|
||||
|
||||
props: {
|
||||
role: { type: Object, required: true }, // 要编辑的对象
|
||||
},
|
||||
|
||||
data() {
|
||||
const { id, name, description } = this.role;
|
||||
|
||||
return {
|
||||
// 角色表单
|
||||
form: {
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
},
|
||||
// 角色表单验证
|
||||
rules: {
|
||||
name: [{ required: true, message: "请先填写角色名称" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 点击-确定
|
||||
handleConfirmClick() {
|
||||
this.$refs["form"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const { id, name, description } = this.form;
|
||||
|
||||
try {
|
||||
const res = await RoleBiz.update(id, name, description);
|
||||
console.log("roleUpdate", res);
|
||||
|
||||
this.$message.success("编辑角色成功");
|
||||
this.$emit("on-submit", res);
|
||||
} catch ({ message }) {
|
||||
this.$message.error(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-form-item.btns {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 0;
|
||||
::v-deep .el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,121 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-08-17 14:23:18
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 17:26:55
|
||||
* @Description: 用户添加
|
||||
-->
|
||||
|
||||
<!-- 用户添加成功后,会触发user-add-success事件,参数为新用户 -->
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-dialog
|
||||
title="添加用户"
|
||||
:visible="isVisible"
|
||||
:before-close="beforeClose"
|
||||
width="30%"
|
||||
>
|
||||
<el-form
|
||||
:model="newUser"
|
||||
:rules="newUserRules"
|
||||
ref="newUserForm"
|
||||
label-width="70px"
|
||||
class="newUserForm"
|
||||
>
|
||||
<el-form-item label="部门名" prop="name">
|
||||
<el-input :value="org.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名" prop="name">
|
||||
<el-input v-model="newUser.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input
|
||||
v-model="newUser.password"
|
||||
autocomplete="new-password"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="onQuitClick">退 出</el-button>
|
||||
<el-button type="primary" @click="onConfirmClick">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// import SystemApi from "../../../api/Rbac/System.js";
|
||||
import UserBiz from "../../../biz/Rbac/User.js";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
org: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newUser: {
|
||||
name: "",
|
||||
password: "",
|
||||
},
|
||||
newUserRules: {
|
||||
name: [{ required: true, message: "请填写用户名", trigger: "none" }],
|
||||
password: [
|
||||
{ required: true, message: "请填写密码", trigger: "none" },
|
||||
{
|
||||
min: 5,
|
||||
max: 18,
|
||||
message: "长度在 5 到 18 个字符",
|
||||
trigger: "none",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onQuitClick() {
|
||||
this.$emit("update:isVisible", false);
|
||||
},
|
||||
|
||||
onConfirmClick() {
|
||||
this.$refs["newUserForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
UserBiz.add({
|
||||
name: this.newUser.name,
|
||||
password: this.newUser.password,
|
||||
orgId: this.org.id < 0 ? null : this.org.id,
|
||||
})
|
||||
.then((userId) => {
|
||||
this.$message({
|
||||
message: "添加用户成功",
|
||||
type: "success",
|
||||
});
|
||||
this.$emit("user-add-success", userId);
|
||||
console.log("userId :>> ", userId);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message({
|
||||
message: err.message,
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// “添加用户”对话框的❌被点击时
|
||||
beforeClose(done) {
|
||||
this.$emit("update:isVisible", false);
|
||||
done();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,381 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-06-19 00:51:47
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 17:41:04
|
||||
* @Description: 用户列表
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="user">
|
||||
<el-table :data="userInfo.rows" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" width="100"></el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="用户名"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Organization.name"
|
||||
label="部门"
|
||||
width="100"
|
||||
:formatter="departmentNameFormatter"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="softDelete"
|
||||
label="禁用"
|
||||
width="80"
|
||||
:formatter="booleanFormatter"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
label="创建时间"
|
||||
width="180"
|
||||
:formatter="timeFormatter"
|
||||
></el-table-column>
|
||||
<!-- <el-table-column
|
||||
prop="modifyTime"
|
||||
label="修改时间"
|
||||
width="180"
|
||||
:formatter="timeFormatter"
|
||||
></el-table-column> -->
|
||||
<el-table-column label="操作" width="100" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
class="btn-icon"
|
||||
icon="el-icon-edit"
|
||||
type="text"
|
||||
@click="onEditBtnClick(scope.$index, scope.row)"
|
||||
></el-button>
|
||||
|
||||
<el-button
|
||||
class="btn-icon"
|
||||
icon="el-icon-delete"
|
||||
type="text"
|
||||
@click="onDelBtnClick(scope.$index, scope.row)"
|
||||
></el-button>
|
||||
|
||||
<el-button
|
||||
class="btn-icon"
|
||||
icon="el-icon-rank"
|
||||
type="text"
|
||||
@click="onMoveBtnClick(scope.$index, scope.row)"
|
||||
></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
background
|
||||
layout="prev, pager, next"
|
||||
:total="userInfo.totalCount"
|
||||
:page-size="userInfo.pageSize"
|
||||
:current-page.sync="userInfo.pageNum"
|
||||
></el-pagination>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-if="editingUser"
|
||||
title="修改用户"
|
||||
:visible.sync="isDialEditUserVisible"
|
||||
width="30%"
|
||||
:before-close="onDialEditUserClose"
|
||||
>
|
||||
<el-form
|
||||
:model="editingUser"
|
||||
:rules="userRules"
|
||||
ref="edit-user-form"
|
||||
label-width="70px"
|
||||
class="edit-user-form"
|
||||
>
|
||||
<el-form-item label="用户名" prop="name">
|
||||
<el-input v-model="editingUser.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否禁用">
|
||||
<el-radio-group v-model="editingUser.softDelete">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="isDialEditUserVisible = false">退 出</el-button>
|
||||
<el-button type="primary" @click="onEditUserConfirmClick"
|
||||
>确 定</el-button
|
||||
>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="移动用户"
|
||||
width="50%"
|
||||
:visible.sync="isDialMoveUserVisible"
|
||||
:before-close="onDialMoveUserClose"
|
||||
@open="onDialMoveUserOpen"
|
||||
>
|
||||
<UserMove
|
||||
ref="user-move-form"
|
||||
:user="editingUser"
|
||||
:treeData="orgTreeData"
|
||||
@cancel="isDialMoveUserVisible = false"
|
||||
@success="onUserMoveSuccess"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import UserMove from "../../../components/Rbac/User/UserMove.vue";
|
||||
import UserBiz from "../../../biz/Rbac/User.js";
|
||||
import OrgAndUserBiz from "../../../biz/Rbac/OrgAndUser.js";
|
||||
import DateHelper from "../../../util/DateHelper.js";
|
||||
|
||||
export default {
|
||||
components: { UserMove },
|
||||
props: {
|
||||
orgId: { type: Number }, // orgId是-1的时候代表根节点
|
||||
orgTreeData: { type: Array }, // 组织架构树结构,主要用于移动用户
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDialEditUserVisible: false,
|
||||
userRules: {
|
||||
name: [{ required: true, message: "请填写用户名", trigger: "none" }],
|
||||
password: [{ required: true, message: "请填写密码", trigger: "none" }],
|
||||
},
|
||||
editingUser: null,
|
||||
editingUserPrototype: null,
|
||||
userInfo: {
|
||||
rows: [],
|
||||
totalCount: 0,
|
||||
pageSize: 10,
|
||||
pageNum: 1,
|
||||
},
|
||||
isDialMoveUserVisible: false, // 移动用户对话框是否显示
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 共几页
|
||||
pageCount: function () {
|
||||
return Math.ceil(this.userInfo.totalCount / this.userInfo.pageSize);
|
||||
},
|
||||
myOrgId: function () {
|
||||
return this.orgId < 0 ? null : this.orgId;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
"userInfo.pageNum": function (newVal, oldVal) {
|
||||
this.getCurrPageUsers();
|
||||
},
|
||||
orgId: function (newVal, oldVal) {
|
||||
this.getCurrPageUsers();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCurrPageUsers();
|
||||
// this.getAllRoles();
|
||||
},
|
||||
methods: {
|
||||
// 获取当前页面的用户信息列表
|
||||
async getCurrPageUsers() {
|
||||
// if (this.myOrgId === null) {
|
||||
// // 查询所有用户
|
||||
// UserBiz.findByPage(this.userInfo.pageSize, this.userInfo.pageNum).then(
|
||||
// (result) => {
|
||||
// this.userInfo.rows = result.rows;
|
||||
// this.userInfo.totalCount = result.count;
|
||||
// }
|
||||
// );
|
||||
// } else {
|
||||
// OrgAndUserBiz.findUsersByOrgIdAndByPage(
|
||||
// this.myOrgId,
|
||||
// this.userInfo.pageSize,
|
||||
// this.userInfo.pageNum
|
||||
// ).then((result) => {
|
||||
// this.userInfo.rows = result.rows;
|
||||
// this.userInfo.totalCount = result.count;
|
||||
// });
|
||||
// }
|
||||
|
||||
await OrgAndUserBiz.findUsersByOrgIdAndByPage(
|
||||
this.myOrgId,
|
||||
this.userInfo.pageSize,
|
||||
this.userInfo.pageNum
|
||||
).then((result) => {
|
||||
this.userInfo.rows = result.rows;
|
||||
this.userInfo.totalCount = result.count;
|
||||
});
|
||||
},
|
||||
|
||||
// table里每一row的“编辑”按钮被点击时
|
||||
onEditBtnClick(index, row) {
|
||||
this.editingUserPrototype = row;
|
||||
this.editingUser = JSON.parse(JSON.stringify(row));
|
||||
this.isDialEditUserVisible = true;
|
||||
},
|
||||
|
||||
// “修改用户”的对话框的确定按钮被点击时
|
||||
onEditUserConfirmClick() {
|
||||
this.$refs["edit-user-form"].validate((valid) => {
|
||||
if (valid) {
|
||||
let user = {};
|
||||
for (const key in this.editingUser) {
|
||||
if (Object.hasOwnProperty.call(this.editingUser, key)) {
|
||||
if (this.editingUser[key] !== this.editingUserPrototype[key]) {
|
||||
user[key] = this.editingUser[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (JSON.stringify(user) !== "{}") {
|
||||
user.id = this.editingUser.id;
|
||||
UserBiz.update(user)
|
||||
.then((count) => {
|
||||
if (count === 1) {
|
||||
this.$message({
|
||||
message: "用户修改成功",
|
||||
type: "success",
|
||||
});
|
||||
this.isDialEditUserVisible = false;
|
||||
this.getCurrPageUsers();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message({
|
||||
message: err.message,
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: "用户信息没有任何修改",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// “修改用户”的对话框的❌被点击时
|
||||
onDialEditUserClose(done) {
|
||||
done();
|
||||
},
|
||||
|
||||
// table里每一row的“删除”按钮被点击时
|
||||
onDelBtnClick(index, row) {
|
||||
this.$confirm("此操作将永久删除该用户, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
UserBiz.delById(row.id)
|
||||
.then((count) => {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "用户删除成功",
|
||||
});
|
||||
this.getCurrPageUsers();
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message({
|
||||
message: err.message,
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: "info",
|
||||
message: "已取消删除",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onMoveBtnClick(index, row) {
|
||||
this.editingUser = JSON.parse(JSON.stringify(row));
|
||||
// this.editingUser = row;
|
||||
this.isDialMoveUserVisible = true;
|
||||
},
|
||||
|
||||
// 去到表格的最后一页(外部调用)
|
||||
async goToLastPage() {
|
||||
let userCount = await UserBiz.countAll();
|
||||
this.userInfo.totalCount = userCount;
|
||||
|
||||
if (this.userInfo.pageNum === this.pageCount) {
|
||||
// 已在最后一页
|
||||
this.getCurrPageUsers();
|
||||
} else {
|
||||
// 未在最后一页
|
||||
this.userInfo.pageNum = this.pageCount;
|
||||
this.getCurrPageUsers();
|
||||
}
|
||||
},
|
||||
|
||||
// “移动用户”的对话框的❌被点击时
|
||||
onDialMoveUserClose(done) {
|
||||
done();
|
||||
},
|
||||
|
||||
// 当移动用户的对话框的open事件被触发时
|
||||
onDialMoveUserOpen() {
|
||||
let $refForm = this.$refs["user-move-form"];
|
||||
// 第一次打开dialog时,表单会不存在
|
||||
if ($refForm) {
|
||||
$refForm.updateForm();
|
||||
}
|
||||
},
|
||||
|
||||
// 当移动用户的对话框里移动用户成功时
|
||||
async onUserMoveSuccess(currNodeData, targetParentData) {
|
||||
// TODO: 非常神奇,马上获取本页用户,被移动的用户还在;但是如果隔1秒获取,则被移动的用户已不在本页;而后端明明是等(await)用户保存成功后才返回的
|
||||
setTimeout(() => {
|
||||
this.getCurrPageUsers();
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
departmentNameFormatter(row, column, cellValue, index) {
|
||||
return cellValue ? cellValue : "-";
|
||||
},
|
||||
|
||||
// 表格的布尔值格式器
|
||||
booleanFormatter(row, column, cellValue, index) {
|
||||
return cellValue ? "是" : "否";
|
||||
},
|
||||
|
||||
// 表格的时间格式器
|
||||
timeFormatter(row, column, cellValue, index) {
|
||||
let date = new Date(cellValue);
|
||||
let dateStr = DateHelper.format(date, "yyyy-MM-dd hh:mm");
|
||||
return dateStr;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.user {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
// padding: 10px;
|
||||
.el-table {
|
||||
.el-button {
|
||||
padding: 0px;
|
||||
&.btn-icon {
|
||||
color: #000;
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pagination {
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
.el-pagination {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-09-03 11:26:04
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 17:38:31
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div class="container">
|
||||
<LightSplit :ratios="[1, 1]" :minHeight="300">
|
||||
<template v-slot:1>
|
||||
<div class="tree-container">
|
||||
<el-tree
|
||||
ref="org-tree"
|
||||
:data="treeData"
|
||||
:node-key="'id'"
|
||||
:props="treeProps"
|
||||
:show-checkbox="false"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="true"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
@node-click="onTreeNodeClick"
|
||||
@current-change="onOrgTreeCurrChange"
|
||||
></el-tree>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:2>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
:label-position="'top'"
|
||||
:rules="orgRules"
|
||||
>
|
||||
<el-form-item label="目标部门名称" prop="parentName">
|
||||
<el-input
|
||||
:value="form.parentName"
|
||||
placeholder="请在左侧选择"
|
||||
readonly
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="移动用户名称">
|
||||
<el-input :value="user.name" readonly></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="btns">
|
||||
<el-button @click="onCancel">{{ btnCancelName }}</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</LightSplit>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// import OrganizationApi from "../../../api/Rbac/Organization.js";
|
||||
import OrgAndUserBiz from "../../../biz/Rbac/OrgAndUser.js";
|
||||
import LightSplit from "../../../components/_Common/LightSplit.vue";
|
||||
export default {
|
||||
components: { LightSplit },
|
||||
props: {
|
||||
treeData: { type: Array },
|
||||
user: { type: Object, required: true }, // 当前移动的用户对象
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
parentId: 0,
|
||||
parentName: "",
|
||||
targetParentData: null,
|
||||
},
|
||||
orgRules: {
|
||||
parentName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择目标上级部门",
|
||||
trigger: "none",
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultExpandedKeys: [null],
|
||||
treeProps: {
|
||||
label: "name",
|
||||
children: "Children",
|
||||
},
|
||||
btnCancelName: "取消",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$refs["form"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
this.$confirm(
|
||||
`确定把在用户 ${this.user.name} 移动到 ${this.form.parentName} 部门下面?`,
|
||||
{
|
||||
title: "确认移动",
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
try {
|
||||
let user = OrgAndUserBiz.relateUser(
|
||||
this.form.parentId < 0 ? null : this.form.parentId,
|
||||
this.user.id
|
||||
);
|
||||
if (user) {
|
||||
this.$message.success(
|
||||
`${this.user.name} 移动到 ${this.form.parentName} 部门下`
|
||||
);
|
||||
this.btnCancelName = "退出";
|
||||
this.$emit("success", user, this.form.targetParentData);
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.error(e.message);
|
||||
}
|
||||
})
|
||||
.catch((e) => {});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$emit("cancel");
|
||||
},
|
||||
|
||||
onTreeNodeClick() {},
|
||||
|
||||
// 当组织架构树被改变选中时
|
||||
onOrgTreeCurrChange(data, node) {
|
||||
this.form.parentId = data.id;
|
||||
this.form.parentName = data.name;
|
||||
this.form.targetParentData = data;
|
||||
// this.$refs["form"].clearValidate();
|
||||
},
|
||||
|
||||
// 供外部调用,更新本组件的一些显示
|
||||
updateForm() {
|
||||
this.$refs["form"].clearValidate();
|
||||
this.btnCancelName = "取消";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.tree-container {
|
||||
height: 100%;
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.el-form-item.btns {
|
||||
padding-top: 20px;
|
||||
margin-bottom: 0;
|
||||
::v-deep .el-form-item__content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,47 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2022-01-04 17:18:23
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-05 15:47:30
|
||||
* @Description: 弹框组件,
|
||||
直接使用方式:
|
||||
<Dialog title="" visible="">
|
||||
要写入的内容
|
||||
</Dialog>
|
||||
当页面不是直接使用时应采取以下方式(比如新建/编辑框):
|
||||
<Dialog v-bind="$attrs" v-on="$listeners" @on-confirm.native="">
|
||||
要写入的内容
|
||||
</Dialog>
|
||||
-->
|
||||
|
||||
<template>
|
||||
<el-dialog :title="title" :visible="visible" :width="width">
|
||||
<!-- 内容 -->
|
||||
<slot />
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="$emit('update:visible', false)">取 消</el-button>
|
||||
<el-button type="primary" @click="$emit('on-confirm')">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Dialog",
|
||||
|
||||
props: {
|
||||
visible: { type: Boolean, required: true }, // 是否显示弹框
|
||||
title: { type: String, required: true }, // 弹框标题
|
||||
width: { type: String, default: "30%" }, // 弹框宽度,格式:30%、30px
|
||||
},
|
||||
|
||||
created() {
|
||||
console.log(this.$props);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -1,386 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-20 09:54:19
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 13:59:12
|
||||
* @Description: 请输入
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="sliders-container" ref="sliders-container">
|
||||
<Draggable
|
||||
:class="[index === activeIndex ? 'active' : '']"
|
||||
class="slider"
|
||||
v-for="(item, index) in sliders"
|
||||
ref="sliders"
|
||||
:key="index"
|
||||
:id="index"
|
||||
:inertia="false"
|
||||
:moveDirection="'horizontal'"
|
||||
:isFrozen="isFrozen"
|
||||
:style="{ width: perSliderWidth + 'px' }"
|
||||
@drag-start="onDragStart"
|
||||
@drag-move="onDragMove"
|
||||
@drag-end="onDragEnd"
|
||||
@drag-enter="onDragEnter"
|
||||
@mousedown.native="onSliderMousedown($event, index)"
|
||||
>
|
||||
<slot
|
||||
v-bind:item="item"
|
||||
v-bind:index="index"
|
||||
v-bind:isActive="index === activeIndex"
|
||||
></slot>
|
||||
</Draggable>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Draggable from "./Drag/Draggable.vue";
|
||||
// import Velocity from "velocity-animate";
|
||||
export default {
|
||||
components: { Draggable },
|
||||
props: {
|
||||
// 滑块对象的数组
|
||||
sliders: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
// 当前激活菜单的 index (支持.sync)
|
||||
currentActive: { type: Number, default: 0 },
|
||||
// 滑块移动方向
|
||||
direction: {
|
||||
type: String,
|
||||
default: "horizontal",
|
||||
validator: function (value) {
|
||||
return ["horizontal", "vertical"].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
// 滑块滑动的时间
|
||||
millisecondOfMove: { type: Number, default: 250 },
|
||||
// 每个滑块的宽度(不传则不设定宽度)
|
||||
perSliderWidth: { type: Number },
|
||||
},
|
||||
computed: {
|
||||
// 当前被激活(选中)的标签index
|
||||
activeIndex: {
|
||||
get() {
|
||||
return this.currentActive;
|
||||
},
|
||||
set(val) {
|
||||
this.calcCurrSliderKeyPoints(val);
|
||||
this.activeSliderWidth = this.slidersInfo[val].width;
|
||||
this.$emit("update:currentActive", val);
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
slidersInfo: [], // {dom, width, midPoint}
|
||||
activeSliderStartPoint: 0, // slider 头部坐标
|
||||
activeSliderEndPoint: 0, // slider 尾部坐标
|
||||
activeSliderWidth: 0, // slider 的宽度
|
||||
indexOfSliderNeedToMoveCurrentlyAndActiveSliderShouldBe: 0,
|
||||
isFrozen: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.refreshSlidersInfo();
|
||||
});
|
||||
|
||||
// this.calcAllTabsMidPoints();
|
||||
|
||||
// https://stackoverflow.com/questions/11700927/horizontal-scrolling-with-mouse-wheel-in-a-div
|
||||
const slidersContainer = this.$refs["sliders-container"];
|
||||
slidersContainer.addEventListener(
|
||||
"mousewheel",
|
||||
(e) => {
|
||||
e = window.event || e;
|
||||
var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
|
||||
slidersContainer.scrollLeft -= delta * 80; // Multiplied by 80
|
||||
e.preventDefault();
|
||||
},
|
||||
false
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
DoFrozen() {
|
||||
this.isFrozen = true;
|
||||
},
|
||||
DisFrozen() {
|
||||
this.isFrozen = false;
|
||||
},
|
||||
|
||||
onDragStart(info) {},
|
||||
onDragMove(info) {
|
||||
// 移动后的 slider 头部的坐标
|
||||
const activeSliderStartPointCurr =
|
||||
this.activeSliderStartPoint + info.currentX;
|
||||
// 移动后的 slider 尾部的坐标
|
||||
const activeSliderEndPointCurr =
|
||||
this.activeSliderEndPoint + info.currentX;
|
||||
|
||||
const midPoints = this.slidersInfo.map((ti) => ti.midPoint);
|
||||
// 当前激活 slider 之前的 sliders 的中间点集合
|
||||
const midPointsBefore = midPoints.slice(0, this.activeIndex);
|
||||
// 当前激活 slider 之后的 sliders 的中间点集合
|
||||
const midPointsAfter = midPoints.slice(this.activeIndex + 1);
|
||||
|
||||
let index = this.activeIndex;
|
||||
// 查找需要移动的 slider 的index
|
||||
function findNeedToMoveIndex() {
|
||||
if (info.currentX > 0) {
|
||||
for (const k in midPointsAfter) {
|
||||
const point = midPointsAfter[k];
|
||||
if (point > activeSliderEndPointCurr) {
|
||||
index += Number(k);
|
||||
return;
|
||||
}
|
||||
}
|
||||
index = midPoints.length - 1; // 最后一个 slider
|
||||
} else {
|
||||
for (const k in midPointsBefore.reverse()) {
|
||||
const point = midPointsBefore[k];
|
||||
if (point < activeSliderStartPointCurr) {
|
||||
index -= Number(k);
|
||||
return;
|
||||
}
|
||||
}
|
||||
index = 0; // 第0个 slider
|
||||
}
|
||||
}
|
||||
|
||||
findNeedToMoveIndex();
|
||||
|
||||
this.indexOfSliderNeedToMoveCurrentlyAndActiveSliderShouldBe = index;
|
||||
|
||||
// console.log("当前需要移动的 slider index :>> ", index);
|
||||
|
||||
if (index !== this.activeIndex) {
|
||||
const refSlider = this.$refs["sliders"][index];
|
||||
let _index = index;
|
||||
if (index > this.activeIndex) {
|
||||
// 当需要移动的 slider 在当前激活 slider 的后面时
|
||||
refSlider.MoveTo({
|
||||
x: -this.activeSliderWidth,
|
||||
transitionDuration: this.millisecondOfMove,
|
||||
afterMoveTo: () => {},
|
||||
});
|
||||
// 当需要移动的 slider 的后面的 sliders 需要复原
|
||||
while (_index < midPoints.length - 1) {
|
||||
_index++;
|
||||
this.$refs["sliders"][_index].Rebound({
|
||||
transitionDuration: this.millisecondOfMove,
|
||||
afterRebound: () => {},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 当需要移动的 slider 在当前激活 slider 的前面时
|
||||
refSlider.MoveTo({
|
||||
x: this.activeSliderWidth,
|
||||
transitionDuration: this.millisecondOfMove,
|
||||
afterMoveTo: () => {},
|
||||
});
|
||||
// 当需要移动的 slider 的前面的 sliders 需要复原
|
||||
while (_index > 0) {
|
||||
_index--;
|
||||
this.$refs["sliders"][_index].Rebound({
|
||||
transitionDuration: this.millisecondOfMove,
|
||||
afterRebound: () => {},
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 当需要移动的 slider 就是当前激活的 slider 时
|
||||
let _index = 0;
|
||||
while (_index < midPoints.length - 1) {
|
||||
if (_index !== this.activeIndex) {
|
||||
this.$refs["sliders"][_index].Rebound({
|
||||
transitionDuration: this.millisecondOfMove,
|
||||
});
|
||||
}
|
||||
_index++;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onDragEnd(info) {
|
||||
const index =
|
||||
this.indexOfSliderNeedToMoveCurrentlyAndActiveSliderShouldBe;
|
||||
|
||||
const widths = this.slidersInfo.map((ti) => ti.width);
|
||||
let point = 0;
|
||||
if (index > this.activeIndex) {
|
||||
// 移动到原位置的右边
|
||||
for (let i = this.activeIndex + 1; i <= index; i++) {
|
||||
point += widths[i];
|
||||
}
|
||||
} else {
|
||||
// 移动到原位置的左边 或保持原位
|
||||
for (let i = index; i < this.activeIndex; i++) {
|
||||
point -= widths[i];
|
||||
}
|
||||
}
|
||||
|
||||
const currSlider = this.$refs["sliders"][this.activeIndex];
|
||||
|
||||
this.isFrozen = true;
|
||||
|
||||
currSlider.MoveTo({
|
||||
x: point,
|
||||
transitionDuration: this.millisecondOfMove,
|
||||
zIndex: 1000,
|
||||
|
||||
afterMoveTo: () => {
|
||||
this.dragAndDrop(
|
||||
this.sliders,
|
||||
this.activeIndex,
|
||||
this.indexOfSliderNeedToMoveCurrentlyAndActiveSliderShouldBe
|
||||
);
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs["sliders"].forEach((slider) => {
|
||||
slider.Clear();
|
||||
});
|
||||
|
||||
this.refreshSlidersInfo();
|
||||
// this.calcAllTabsMidPoints();
|
||||
|
||||
this.activeIndex =
|
||||
this.indexOfSliderNeedToMoveCurrentlyAndActiveSliderShouldBe;
|
||||
|
||||
this.isFrozen = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
onDragEnter(info) {},
|
||||
|
||||
onSliderMousedown(event, index) {
|
||||
switch (event.button) {
|
||||
case 0: // 左键
|
||||
if (!this.isFrozen) this.activeIndex = index;
|
||||
break;
|
||||
case 1: // 中轮
|
||||
break;
|
||||
case 2: // 右键
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// handleMoveEnd(Rebound) {
|
||||
// Rebound({});
|
||||
// },
|
||||
|
||||
// 更新所有 slider 的信息
|
||||
refreshSlidersInfo() {
|
||||
const slidersRef = this.$refs["sliders"];
|
||||
this.slidersInfo = [];
|
||||
// 找出 slider 的宽度
|
||||
for (const sliderRef of slidersRef) {
|
||||
const dom = sliderRef.$el;
|
||||
const width = dom.getBoundingClientRect().width;
|
||||
|
||||
const rectSlider = dom.getBoundingClientRect();
|
||||
const rectContainer =
|
||||
this.$refs["sliders-container"].getBoundingClientRect();
|
||||
const startPoint = rectSlider.left - rectContainer.left;
|
||||
const endPoint = rectSlider.right - rectContainer.left;
|
||||
const midPoint = startPoint + width / 2;
|
||||
|
||||
this.slidersInfo.push({
|
||||
dom,
|
||||
width,
|
||||
startPoint,
|
||||
endPoint,
|
||||
midPoint,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 计算当前激活的 slider 的头部和尾部相对坐标点
|
||||
calcCurrSliderKeyPoints(activeIndex) {
|
||||
// ----------下面是旧写法------------------------------------------
|
||||
// const widths = this.slidersInfo.map((ti) => ti.width);
|
||||
// const widthsLess = widths.slice(0, activeIndex);
|
||||
// const widthsMore = widths.slice(0, activeIndex + 1);
|
||||
|
||||
// let sumStartPoint = 0,
|
||||
// sumEndPoint = 0;
|
||||
// widthsLess.forEach((el) => (sumStartPoint += el));
|
||||
// widthsMore.forEach((el) => (sumEndPoint += el));
|
||||
|
||||
// this.activeSliderStartPoint = sumStartPoint;
|
||||
// this.activeSliderEndPoint = sumEndPoint;
|
||||
|
||||
// ----------下面是新写法------------------------------------------
|
||||
const doms = this.slidersInfo.map((ti) => ti.dom);
|
||||
const rectActive = doms[activeIndex].getBoundingClientRect();
|
||||
const rectContainer =
|
||||
this.$refs["sliders-container"].getBoundingClientRect();
|
||||
|
||||
const startPoint = rectActive.left - rectContainer.left;
|
||||
const endPoint = rectActive.right - rectContainer.left;
|
||||
|
||||
this.activeSliderStartPoint = startPoint;
|
||||
this.activeSliderEndPoint = endPoint;
|
||||
},
|
||||
|
||||
// 找出 slider 的中间点(弃用)
|
||||
calcAllTabsMidPoints() {
|
||||
for (const key in this.slidersInfo) {
|
||||
if (Object.hasOwnProperty.call(this.slidersInfo, key)) {
|
||||
const ti = this.slidersInfo[key];
|
||||
if (key - 1 >= 0) {
|
||||
ti.midPoint =
|
||||
this.slidersInfo[key - 1].midPoint +
|
||||
this.slidersInfo[key - 1].width / 2 +
|
||||
ti.width / 2;
|
||||
} else {
|
||||
ti.midPoint = ti.width / 2;
|
||||
}
|
||||
// ti.title = this.sliders[key].title;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
swap(arr, i1, i2) {
|
||||
arr[i1] = arr.splice(i2, 1, arr[i1])[0];
|
||||
return arr;
|
||||
},
|
||||
|
||||
dragAndDrop(arr, i1, i2) {
|
||||
let o = arr.splice(i1, 1)[0];
|
||||
arr.splice(i2, 0, o);
|
||||
return arr;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables.scss";
|
||||
.sliders-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
|
||||
scrollbar-width: none; /* For Firefox */
|
||||
-ms-overflow-style: none; /* For Internet Explorer and Edge */
|
||||
&::-webkit-scrollbar {
|
||||
/* For Chrome, Safari, and Opera */
|
||||
// width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
// flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,162 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2022-01-01 05:27:31
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 14:32:19
|
||||
* @Description: 请输入
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="tabs-container">
|
||||
<Sliders
|
||||
class="tabs-sliders"
|
||||
ref="tabs-sliders"
|
||||
:sliders="tabs"
|
||||
:currentActive.sync="currentActive"
|
||||
>
|
||||
<template v-slot="{ item, index, isActive }">
|
||||
<div
|
||||
class="tab"
|
||||
:class="{ active: isActive }"
|
||||
:style="{
|
||||
width: `${perTabWidth}px`,
|
||||
maxWidth: `${perTabMaxWidth}px`,
|
||||
padding: `0 ${perTabPadding}px`,
|
||||
}"
|
||||
@mouseenter="onTabMouseenter(item, index)"
|
||||
>
|
||||
<span
|
||||
class="title"
|
||||
:style="{
|
||||
width: `${titleWidth}px`,
|
||||
}"
|
||||
>
|
||||
{{ item.title }}
|
||||
</span>
|
||||
<span
|
||||
class="close"
|
||||
:style="{ width: `${tabCloseWidth}px` }"
|
||||
@click="onTabCloseClick(item, index)"
|
||||
@mousedown="onTabCloseMousedown(item, index)"
|
||||
@mouseup="onTabCloseMouseup(item, index)"
|
||||
@mouseenter="onTabCloseMouseenter(item, index)"
|
||||
@mouseleave="onTabCloseMouseleave(item, index)"
|
||||
><i class="el-icon-close icon"></i
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
</Sliders>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Sliders from "../Sliders.vue";
|
||||
export default {
|
||||
components: { Sliders },
|
||||
props: {
|
||||
// 标签数据对象的属性,数据对象的类型是@/entity/Ui/Tab/Tab.js
|
||||
tabs: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
// 当前激活菜单的 index (支持.sync)
|
||||
tabsCurrActiveIndex: { type: Number, default: 0 },
|
||||
},
|
||||
computed: {
|
||||
currentActive: {
|
||||
get() {
|
||||
return this.tabsCurrActiveIndex;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit("update:tabsCurrActiveIndex", val);
|
||||
},
|
||||
},
|
||||
titleWidth: function () {
|
||||
return (
|
||||
Math.min(this.perTabWidth, this.perTabMaxWidth) -
|
||||
this.tabCloseWidth -
|
||||
this.perTabPadding * 2
|
||||
);
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isTabCloseMousedown: false,
|
||||
tabCloseWidth: 18,
|
||||
perTabPadding: 8,
|
||||
perTabMaxWidth: 200,
|
||||
perTabWidth: this.perTabMaxWidth,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const rectSliders = this.$refs["tabs-sliders"].$el.getBoundingClientRect();
|
||||
this.perTabWidth = rectSliders.width / this.tabs.length;
|
||||
},
|
||||
methods: {
|
||||
onTabCloseClick(item, index) {},
|
||||
onTabMouseenter(item, index) {
|
||||
// if (!this.isTabCloseMousedown) {
|
||||
// this.$refs["tabs-sliders"].DisFrozen();
|
||||
// }
|
||||
},
|
||||
onTabCloseMousedown(item, index) {
|
||||
// this.$refs["tabs-sliders"].DoFrozen();
|
||||
// this.isTabCloseMousedown = true;
|
||||
},
|
||||
onTabCloseMouseup(item, index) {
|
||||
// this.$refs["tabs-sliders"].DisFrozen();
|
||||
// this.isTabCloseMousedown = false;
|
||||
},
|
||||
onTabCloseMouseenter(item, index) {
|
||||
// this.$refs["tabs-sliders"].DoFrozen();
|
||||
// console.log("onTabCloseMouseenter");
|
||||
},
|
||||
onTabCloseMouseleave(item, index) {
|
||||
// this.$refs["tabs-sliders"].DisFrozen();
|
||||
// if (!this.isTabCloseMousedown) {
|
||||
// this.$refs["tabs-sliders"].DisFrozen();
|
||||
// }
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables.scss";
|
||||
.tabs-container {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background-color: $theme-background-dark;
|
||||
.tabs-sliders {
|
||||
.tab {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: $theme-background-dark;
|
||||
cursor: default;
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
}
|
||||
.title {
|
||||
display: block;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
.close {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
padding-left: 4px;
|
||||
cursor: pointer;
|
||||
.icon {
|
||||
border-radius: 50%;
|
||||
padding: 1px;
|
||||
&:hover {
|
||||
background-color: #bbb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
17
src/const.js
17
src/const.js
|
@ -2,10 +2,10 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2020-09-10 09:49:13
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-11 10:47:12
|
||||
* @LastEditTime: 2022-03-07 15:17:54
|
||||
* @Description: 配置文件
|
||||
*/
|
||||
export const PROJECT_NAME = '销售';
|
||||
export const PROJECT_NAME = '示例';
|
||||
export const LOGIN_PAGE_TITLE = '前端示例 2';
|
||||
export const TOKEY_ATTR_NAME = 'X-Access-Token'; // TOKEN的属性名(即客户端传token到服务端,token的属性名)
|
||||
export const IS_LOGIN_NEEDED = true; // 系统是否需要登录后使用
|
||||
|
@ -13,11 +13,11 @@ export const IS_LOGIN_NEEDED = true; // 系统是否需要登录后使用
|
|||
let baseUrl; // 基础API地址
|
||||
switch (process.env.NODE_ENV) {
|
||||
case "production": // 发布到服务器 npm run build
|
||||
baseUrl = 'http://ty.y68.fun/sales-expo-saas'; // swagger http://ty.y68.fun/sales-expo-saas/#/
|
||||
break;
|
||||
case "preview": // 发布前预览 npm run preview
|
||||
{
|
||||
baseUrl = 'http://ty.y68.fun/sales-expo-saas'; // swagger http://ty.y68.fun/sales-expo-saas/#/
|
||||
break;
|
||||
}
|
||||
case "development": // 本机前端开发调试 npm run serve
|
||||
default:
|
||||
baseUrl = 'http://ty.y68.fun/sales-show-3'; // swagger http://ty.y68.fun/sales-expo-saas/#/
|
||||
|
@ -53,11 +53,4 @@ export const UPLOAD_TIMEOUT = 0; // 指定文件上传请求超时的毫秒数(0
|
|||
|
||||
export const DEFAULT_HOME_LAYOUT = ['top-bottom', 'left-right'][0]; // 网站前台是上下布局还是左右布局
|
||||
export const DEFAULT_BACK_LAYOUT = ['top-bottom', 'left-right'][0]; // 网站后台是上下布局还是左右布局
|
||||
export const HEADER_THICKNESS = 48; // 首页头部尺寸(单位:像素)
|
||||
export const HIDE_DRAWER_WHEN_PUSH = false; // 当跳转页面时,抽屉是否隐藏
|
||||
|
||||
// 弹框类型
|
||||
export const DIALOG_TYPE = {
|
||||
ADD: 'add', // 添加(新建)
|
||||
EDIT: 'edit', // 编辑(更新)
|
||||
}
|
||||
export const HEADER_THICKNESS = 48; // 首页头部尺寸(单位:像素)
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-23 01:22:12
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 22:02:35
|
||||
* @Description: 请输入
|
||||
*/
|
||||
|
||||
class Tab {
|
||||
/**
|
||||
* @description 标签栏的每个标签
|
||||
* @param {string} title 标题
|
||||
*/
|
||||
constructor({
|
||||
title
|
||||
}) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
|
||||
export default Tab;
|
46
src/main.js
46
src/main.js
|
@ -2,7 +2,7 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2020-09-10 09:12:00
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-01 05:26:15
|
||||
* @LastEditTime: 2022-03-07 15:03:20
|
||||
* @Description: 请输入
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
|
@ -13,7 +13,7 @@ import ElementUI from 'element-ui';
|
|||
import './scss/element-variables.scss';
|
||||
import "./svgicon/index.js";
|
||||
import Event from './util/Event';
|
||||
import AuthHelper from "./auth/AuthHelper.js";
|
||||
// import AuthHelper from "./auth/AuthHelper.js";
|
||||
import SafePush from './util/SafePush';
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
@ -24,31 +24,31 @@ Vue.use(ElementUI, {
|
|||
Vue.prototype.$safePush = SafePush;
|
||||
|
||||
// 注册一个全局自定义指令 `v-auth`,用于验证权限
|
||||
Vue.directive('auth', {
|
||||
bind: function (el, param) { },
|
||||
// 当被绑定的元素插入到 DOM 中时……
|
||||
inserted: function (el, param) {
|
||||
let pass = AuthHelper.checkAuth(param.value);
|
||||
if (!pass) {
|
||||
el.remove()
|
||||
}
|
||||
},
|
||||
update: function (el, param) { },
|
||||
componentUpdated: function (el, param) { },
|
||||
unbind: function (el, param) { }
|
||||
});
|
||||
// Vue.directive('auth', {
|
||||
// bind: function (el, param) { },
|
||||
// // 当被绑定的元素插入到 DOM 中时……
|
||||
// inserted: function (el, param) {
|
||||
// let pass = AuthHelper.checkAuth(param.value);
|
||||
// if (!pass) {
|
||||
// el.remove()
|
||||
// }
|
||||
// },
|
||||
// update: function (el, param) { },
|
||||
// componentUpdated: function (el, param) { },
|
||||
// unbind: function (el, param) { }
|
||||
// });
|
||||
|
||||
// 全局事件总线
|
||||
// 参考:https://zhuanlan.zhihu.com/p/72777951
|
||||
// 不到必要时,不建议使用,否则容易增加全局代码复杂度
|
||||
let EventBus = new Vue();
|
||||
Object.defineProperties(Vue.prototype, {
|
||||
$bus: {
|
||||
get: function () {
|
||||
return EventBus;
|
||||
}
|
||||
}
|
||||
});
|
||||
// let EventBus = new Vue();
|
||||
// Object.defineProperties(Vue.prototype, {
|
||||
// $bus: {
|
||||
// get: function () {
|
||||
// return EventBus;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2020-09-10 09:12:00
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-10 20:27:12
|
||||
* @LastEditTime: 2022-03-07 13:35:34
|
||||
* @Description: 静态路由
|
||||
*/
|
||||
import Vue from 'vue'
|
||||
|
@ -16,8 +16,6 @@ import {
|
|||
import LoginInfo from "../storage/login-info.js";
|
||||
import TestChildren from "./test.js";
|
||||
import MainChildren from "./main.js";
|
||||
import SecondaryChildren from "./secondary.js";
|
||||
import BackChildren from "./back.js";
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
|
@ -40,22 +38,8 @@ const routes = [{
|
|||
},
|
||||
children: [
|
||||
...MainChildren,
|
||||
...SecondaryChildren,
|
||||
...TestChildren
|
||||
]
|
||||
}, {
|
||||
path: '/back',
|
||||
name: 'Back',
|
||||
redirect: {
|
||||
name: 'Org'
|
||||
},
|
||||
component: () => import( /* webpackChunkName: "Back" */ '../views/Back.vue'),
|
||||
meta: {
|
||||
title: ''
|
||||
},
|
||||
children: [
|
||||
...BackChildren
|
||||
]
|
||||
}, {
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-29 17:34:21
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 13:59:15
|
||||
* @Description: 请输入
|
||||
*/
|
||||
|
||||
export default [{
|
||||
path: 'org',
|
||||
name: 'Org',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Org" */
|
||||
'../views/BackViews/Org.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '组织架构',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'role',
|
||||
name: 'Role',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Role" */
|
||||
'../views/BackViews/Role.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '角色管理',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'classification',
|
||||
name: 'Classification',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Classification" */
|
||||
'../views/BackViews/Classification.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '分类管理',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'statistics',
|
||||
name: 'Statistics',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Statistics" */
|
||||
'../views/BackViews/Statistics.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '数据统计',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'topic',
|
||||
name: 'Topic',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Topic" */
|
||||
'../views/BackViews/Topic.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '专题管理',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'platformsetting',
|
||||
name: 'PlatformSetting',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "PlatformSetting" */
|
||||
'../views/BackViews/PlatformSetting.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '平台设置',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'authorization-for-partner',
|
||||
name: 'Authorization4Partner',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Authorization4Partner" */
|
||||
'../views/BackViews/Authorization4Partner.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '合作伙伴授权管理',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'authorization-for-customer',
|
||||
name: 'Authorization4Customer',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Authorization4Customer" */
|
||||
'../views/BackViews/Authorization4Customer.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '客户授权管理',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}, {
|
||||
path: 'log',
|
||||
name: 'Log',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "Log" */
|
||||
'../views/BackViews/Log.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '系统日志',
|
||||
// headerActiveIndex: '1',
|
||||
// keepAlive: false
|
||||
}
|
||||
}]
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* @Author: Billy
|
||||
* @Date: 2022-01-06 18:23:05
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 18:28:19
|
||||
* @Description: 请输入
|
||||
*/
|
||||
|
||||
export default [{
|
||||
path: '/quick-demonstrations',
|
||||
name: 'QuickDemonstrations',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "QuickDemonstrations" */
|
||||
'../views/HomeSubViews/Secondary/QuickDemonstrations.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '快捷演示方案',
|
||||
// headerActiveIndex: '1',
|
||||
keepAlive: true
|
||||
}
|
||||
}, {
|
||||
path: '/cloud-desktop',
|
||||
name: 'CloudDesktop',
|
||||
component: () => import(
|
||||
/* webpackChunkName: "CloudDesktop" */
|
||||
'../views/HomeSubViews/Secondary/CloudDesktop.vue'
|
||||
),
|
||||
meta: {
|
||||
title: '云桌面',
|
||||
// headerActiveIndex: '1',
|
||||
keepAlive: true
|
||||
}
|
||||
}]
|
|
@ -1,61 +0,0 @@
|
|||
@import "../variables.scss";
|
||||
|
||||
// 自定义类
|
||||
// 水平两列结构(左列溢出可垂直滚动,右列溢出隐藏)
|
||||
.back-column-two {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
.column-left {
|
||||
width: calc(100% * 0.186);
|
||||
min-width: 300px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.column-right {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
border-left: 2px solid $theme-background-light;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
// 水平一列结构
|
||||
.back-column-one {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
// 标题区域变量
|
||||
$title-height: 36; // 标题区域高度(不包含外边距)
|
||||
$title-margin-bottom: 20; // 标题下外边距
|
||||
|
||||
// 标题区域样式
|
||||
.back-title {
|
||||
height: #{$title-height + px}; // 减掉外边距
|
||||
margin-bottom: #{$title-margin-bottom + px};
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 16px;
|
||||
color: #25262b;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
.el-pagination {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
// 清除默认样式
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
@import "./back.scss";
|
||||
|
||||
// 暗色背景输入框
|
||||
.bg-dark.el-input::v-deep {
|
||||
.el-input__icon {
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
height: 36px;
|
||||
background-color: #e5e7ed;
|
||||
}
|
||||
}
|
||||
|
||||
.back-title-el-tabs.el-tabs::v-deep {
|
||||
height: 100%;
|
||||
|
||||
.el-tabs__header {
|
||||
margin-bottom: #{$title-margin-bottom + px};
|
||||
}
|
||||
|
||||
.el-tabs__nav-wrap::after {
|
||||
background-color: $theme-background-light;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
height: #{$title-height + px};
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
// 取消当前tab默认样式,否则电脑切换应用后会显示
|
||||
&.is-active {
|
||||
box-shadow: none !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-29 17:24:10
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-07 17:16:12
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div class="back">
|
||||
<el-container>
|
||||
<el-header
|
||||
v-if="DEFAULT_BACK_LAYOUT === 'top-bottom'"
|
||||
:height="HEADER_THICKNESS + 'px'"
|
||||
>
|
||||
<Header :arrangeMode="'horizontal'" />
|
||||
</el-header>
|
||||
<el-aside
|
||||
v-else-if="DEFAULT_BACK_LAYOUT === 'left-right'"
|
||||
:width="HEADER_THICKNESS + 'px'"
|
||||
>
|
||||
<Header :arrangeMode="'vertical'" />
|
||||
</el-aside>
|
||||
<el-container>
|
||||
<el-aside width="200px">
|
||||
<!-- <Menu
|
||||
:menuItems="backMenuItems"
|
||||
:arrangeMode="'vertical'"
|
||||
:displayMode="'both'"
|
||||
:defaultActive="menuDefaultActive"
|
||||
@select="handleMenuSelect"
|
||||
/> -->
|
||||
<Menu2
|
||||
:menuItems="backMenuItems"
|
||||
:defaultActive="menuDefaultActive"
|
||||
/>
|
||||
</el-aside>
|
||||
<el-main>
|
||||
<div class="main">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
import MenuBiz from "../biz/Back/_Menu.js";
|
||||
import Header from "../components/Back/Header.vue";
|
||||
// import Menu from "../components/Back/Menu(backup).vue";
|
||||
import Menu2 from "../components/Back/Menu.vue";
|
||||
// import TreeHelper from "../util/TreeHelper.js";
|
||||
import { DEFAULT_BACK_LAYOUT, HEADER_THICKNESS } from "../const.js";
|
||||
|
||||
export default {
|
||||
name: "Back",
|
||||
components: {
|
||||
Header,
|
||||
// Menu,
|
||||
Menu2,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
DEFAULT_BACK_LAYOUT,
|
||||
HEADER_THICKNESS,
|
||||
backMenuItems: [], // 后台菜单栏的信息数组
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
menuDefaultActive: function () {
|
||||
const _routerName = this.$route.name;
|
||||
// let index = this.backMenuItems.findIndex(
|
||||
// (item) => item.routerName && item.routerName === _routerName
|
||||
// );
|
||||
return _routerName;
|
||||
},
|
||||
},
|
||||
async beforeMount() {
|
||||
this.backMenuItems = await MenuBiz.getBackMenuItems();
|
||||
},
|
||||
methods: {
|
||||
// 处理导航菜单选择事件
|
||||
handleMenuSelect(item, index) {
|
||||
let routerName;
|
||||
// switch (index) {
|
||||
// case 1:
|
||||
// routerName = "Test";
|
||||
// break;
|
||||
// case 2:
|
||||
// routerName = "Test2";
|
||||
// break;
|
||||
// }
|
||||
routerName = item.routerName;
|
||||
if (routerName) this.$safePush({ name: routerName });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.back {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables.scss";
|
||||
.el-container {
|
||||
height: 100%;
|
||||
// 上下布局时
|
||||
.el-header {
|
||||
// height: $header-thin + px !important;
|
||||
padding: 0;
|
||||
box-sizing: content-box;
|
||||
border-bottom: solid 1px #e6e6e6;
|
||||
}
|
||||
// 左右布局时
|
||||
.el-aside {
|
||||
// width: $header-thin + px !important;
|
||||
border-right: solid 1px #e6e6e6;
|
||||
}
|
||||
.el-container {
|
||||
.el-main {
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
background-color: $theme-background-light;
|
||||
.main {
|
||||
background-color: #fff;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,211 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-04 09:49:49
|
||||
* @Description: 后台管理-授权管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="authorization back-column-two">
|
||||
<!-- 左侧-列表 -->
|
||||
<div class="column-left">
|
||||
<div class="title back-title">
|
||||
{{ $route.meta.title }}
|
||||
<el-button class="authorization-new" icon="el-icon-circle-plus">
|
||||
新建身份
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-input
|
||||
v-model="inputauthorization"
|
||||
prefix-icon="el-icon-search"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
|
||||
<div class="authorization-list">
|
||||
<ul class="list-ul">
|
||||
<li
|
||||
class="list-li"
|
||||
v-for="authorization in authorizationList"
|
||||
:key="authorization"
|
||||
>
|
||||
{{ authorization }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧-内容 -->
|
||||
<div class="column-right">
|
||||
<ul class="auth-first-ul">
|
||||
<li v-for="firstAuth in authList" :key="firstAuth.text">
|
||||
<el-checkbox v-model="firstAuth.checked">
|
||||
{{ firstAuth.text }}
|
||||
</el-checkbox>
|
||||
<ul class="auth-second-ul">
|
||||
<li v-for="secondAuth in firstAuth.children" :key="secondAuth.text">
|
||||
<el-checkbox v-model="secondAuth.checked">
|
||||
{{ secondAuth.text }}
|
||||
</el-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Authorization",
|
||||
|
||||
data() {
|
||||
return {
|
||||
inputauthorization: "", // 角色搜索内容
|
||||
authorizationList: ["普通用户", "一级用户", "二级用户"],
|
||||
titleList: [
|
||||
{
|
||||
prop: "name",
|
||||
label: "伙伴名称",
|
||||
},
|
||||
{
|
||||
prop: "department",
|
||||
label: "部门",
|
||||
},
|
||||
{
|
||||
prop: "authorization",
|
||||
label: "角色",
|
||||
},
|
||||
{
|
||||
prop: "status",
|
||||
label: "账号状态",
|
||||
},
|
||||
],
|
||||
dataList: [
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "正常",
|
||||
},
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "正常",
|
||||
},
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "正常",
|
||||
},
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "异常",
|
||||
},
|
||||
],
|
||||
authList: [
|
||||
{
|
||||
text: "全部",
|
||||
checked: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
text: "产品",
|
||||
children: [
|
||||
{
|
||||
text: "查看",
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
text: "新建产品",
|
||||
checked: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 切换tab
|
||||
handleTabClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
|
||||
.authorization {
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid $theme-background-light;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.authorization-new {
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: #347eff;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.authorization-list {
|
||||
.list-ul {
|
||||
margin-top: 20px;
|
||||
|
||||
.list-li {
|
||||
height: 36px;
|
||||
padding-left: 20px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(52, 126, 255, 0.1);
|
||||
// opacity: 0.1;
|
||||
color: #347eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.auth-first-ul {
|
||||
& > li {
|
||||
margin-bottom: 20px;
|
||||
|
||||
& > .el-checkbox {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-second-ul {
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
margin-left: 20px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,211 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-04 15:36:55
|
||||
* @Description: 后台管理-授权管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="authorization back-column-two">
|
||||
<!-- 左侧-列表 -->
|
||||
<div class="column-left">
|
||||
<div class="title back-title">
|
||||
{{ $route.meta.title }}
|
||||
<el-button class="authorization-new" icon="el-icon-circle-plus">
|
||||
新建身份
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-input
|
||||
v-model="inputauthorization"
|
||||
prefix-icon="el-icon-search"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
|
||||
<div class="authorization-list">
|
||||
<ul class="list-ul">
|
||||
<li
|
||||
class="list-li"
|
||||
v-for="authorization in authorizationList"
|
||||
:key="authorization"
|
||||
>
|
||||
{{ authorization }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧-内容 -->
|
||||
<div class="column-right">
|
||||
<ul class="auth-first-ul">
|
||||
<li v-for="firstAuth in authList" :key="firstAuth.text">
|
||||
<el-checkbox v-model="firstAuth.checked">
|
||||
{{ firstAuth.text }}
|
||||
</el-checkbox>
|
||||
<ul class="auth-second-ul">
|
||||
<li v-for="secondAuth in firstAuth.children" :key="secondAuth.text">
|
||||
<el-checkbox v-model="secondAuth.checked">
|
||||
{{ secondAuth.text }}
|
||||
</el-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Authorization",
|
||||
|
||||
data() {
|
||||
return {
|
||||
inputauthorization: "", // 角色搜索内容
|
||||
authorizationList: ["普通用户", "一级用户", "二级用户"],
|
||||
titleList: [
|
||||
{
|
||||
prop: "name",
|
||||
label: "伙伴名称",
|
||||
},
|
||||
{
|
||||
prop: "department",
|
||||
label: "部门",
|
||||
},
|
||||
{
|
||||
prop: "authorization",
|
||||
label: "角色",
|
||||
},
|
||||
{
|
||||
prop: "status",
|
||||
label: "账号状态",
|
||||
},
|
||||
],
|
||||
dataList: [
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "正常",
|
||||
},
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "正常",
|
||||
},
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "正常",
|
||||
},
|
||||
{
|
||||
name: "李杰",
|
||||
department: "战略支持部",
|
||||
authorization: "系统管理员",
|
||||
status: "异常",
|
||||
},
|
||||
],
|
||||
authList: [
|
||||
{
|
||||
text: "全部",
|
||||
checked: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
text: "产品",
|
||||
children: [
|
||||
{
|
||||
text: "查看",
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
text: "新建产品",
|
||||
checked: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 切换tab
|
||||
handleTabClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
|
||||
.authorization {
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid $theme-background-light;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.authorization-new {
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: #347eff;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.authorization-list {
|
||||
.list-ul {
|
||||
margin-top: 20px;
|
||||
|
||||
.list-li {
|
||||
height: 36px;
|
||||
padding-left: 20px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(52, 126, 255, 0.1);
|
||||
// opacity: 0.1;
|
||||
color: #347eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.auth-first-ul {
|
||||
& > li {
|
||||
margin-bottom: 20px;
|
||||
|
||||
& > .el-checkbox {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-second-ul {
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
margin-left: 20px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,84 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-04 09:49:29
|
||||
* @Description: 后台管理-角色管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="classification back-column-one">
|
||||
<div class="back-title">{{ $route.meta.title }}</div>
|
||||
|
||||
<el-tabs value="product" type="card" @tab-click="handleClick">
|
||||
<el-tab-pane label="产品案例" name="product">
|
||||
<el-tabs value="role-remember" @tab-click="handleTabClick">
|
||||
<el-tab-pane label="软硬件产品" name="role-remember">
|
||||
<el-button type="primary" round>新建分类</el-button>
|
||||
<el-table :data="dataList" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="title in titleList"
|
||||
:key="title.prop"
|
||||
:prop="title.prop"
|
||||
:label="title.label"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="技术服务" name="role-remember2"></el-tab-pane>
|
||||
<el-tab-pane label="软件服务" name="role-remember3"></el-tab-pane>
|
||||
<el-tab-pane label="应用案例" name="role-remember4"></el-tab-pane>
|
||||
<el-tab-pane label="培训服务" name="role-remember5"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="解决方案" name="solution">解决方案</el-tab-pane>
|
||||
<el-tab-pane label="演示方案" name="demo">演示方案</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Classification",
|
||||
|
||||
data() {
|
||||
return {
|
||||
titleList: [
|
||||
{
|
||||
prop: "type",
|
||||
label: "分类名称",
|
||||
},
|
||||
{
|
||||
prop: "dest",
|
||||
label: "说明",
|
||||
},
|
||||
{
|
||||
prop: "num",
|
||||
label: "统计数量",
|
||||
},
|
||||
],
|
||||
dataList: [
|
||||
{
|
||||
type: "品牌",
|
||||
dest: "-",
|
||||
num: 26,
|
||||
},
|
||||
{
|
||||
type: "品牌",
|
||||
dest: "-",
|
||||
num: 26,
|
||||
},
|
||||
{
|
||||
type: "品牌",
|
||||
dest: "-",
|
||||
num: 26,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
</style>
|
|
@ -1,108 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-05 18:56:12
|
||||
* @Description: 后台管理-角色管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="log back-column-one">
|
||||
<div class="back-title">{{ $route.meta.title }}</div>
|
||||
<el-tabs value="role-remember">
|
||||
<el-tab-pane label="操作日志" name="role-remember">
|
||||
<el-table :data="actionList" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="title in actionTitleList"
|
||||
:key="title.prop"
|
||||
:prop="title.prop"
|
||||
:label="title.label"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="登录日志" name="role-remember2">
|
||||
<el-table :data="loginList" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="title in loginTitleList"
|
||||
:key="title.prop"
|
||||
:prop="title.prop"
|
||||
:label="title.label"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogBiz from "../../biz/Back/Log.js";
|
||||
|
||||
export default {
|
||||
name: "Log",
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 操作日志列表标题
|
||||
actionTitleList: [
|
||||
{
|
||||
prop: "user",
|
||||
label: "用户",
|
||||
},
|
||||
|
||||
{
|
||||
prop: "time",
|
||||
label: "时间",
|
||||
},
|
||||
{
|
||||
prop: "module",
|
||||
label: "模块",
|
||||
},
|
||||
{
|
||||
prop: "position",
|
||||
label: "所在位置",
|
||||
},
|
||||
{
|
||||
prop: "action",
|
||||
label: "行为",
|
||||
},
|
||||
],
|
||||
actionList: [], // 操作日志数据列表
|
||||
// 登录日志列表标题
|
||||
loginTitleList: [
|
||||
{
|
||||
prop: "user",
|
||||
label: "用户",
|
||||
},
|
||||
{
|
||||
prop: "time",
|
||||
label: "登录时间",
|
||||
},
|
||||
{
|
||||
prop: "result",
|
||||
label: "认证结果",
|
||||
},
|
||||
{
|
||||
prop: "ip",
|
||||
label: "IP地址",
|
||||
},
|
||||
],
|
||||
loginList: [], // 登录日志数据列表
|
||||
};
|
||||
},
|
||||
|
||||
async created() {
|
||||
const [actionList, loginList] = await Promise.all([
|
||||
LogBiz.findByAction(),
|
||||
LogBiz.findByLogin(),
|
||||
]);
|
||||
this.actionList = actionList;
|
||||
this.loginList = loginList;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
</style>
|
|
@ -1,390 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-29 17:34:35
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-04 21:51:32
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<PageSplit
|
||||
class="split-pane"
|
||||
:distribute="0.15"
|
||||
:lineThickness="6"
|
||||
:firstMinValue="200"
|
||||
:isVertical="true"
|
||||
@resizeLineStartMove="onResizeLineStartMove"
|
||||
@resizeLineMove="onResizeLineMove"
|
||||
@resizeLineEndMove="onResizeLineEndMove"
|
||||
>
|
||||
<template v-slot:first>
|
||||
<div class="container">
|
||||
<div class="title title-flex-both">
|
||||
<span class="title-inner">组织架构</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tree
|
||||
ref="org-tree"
|
||||
v-loading="vloadingOrgTree"
|
||||
:data="orgTreeData"
|
||||
:node-key="'id'"
|
||||
:props="treeProps"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="false"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:render-content="renderTreeNodeContent"
|
||||
@node-click="onTreeNodeClick"
|
||||
@current-change="onOrgTreeCurrChange"
|
||||
></el-tree>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:second>
|
||||
<div class="container">
|
||||
<div class="title title-flex-right">
|
||||
<el-button size="mini" type="primary" @click="onAddUserBtnClick"
|
||||
>新建用户</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="content">
|
||||
<UserList
|
||||
ref="user-list"
|
||||
:orgId="currSelectedOrg.id"
|
||||
:orgTreeData="orgTreeData"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="others">
|
||||
<UserAdd
|
||||
:org="currSelectedOrg"
|
||||
:isVisible.sync="isDialAddUserVisible"
|
||||
@user-add-success="onUserAddSuccess"
|
||||
/>
|
||||
|
||||
<el-dialog
|
||||
title="新建部门"
|
||||
width="30%"
|
||||
:visible.sync="isDialAddDeptVisible"
|
||||
:before-close="onDialAddDeptClose"
|
||||
@open="onDialAddDeptOpen"
|
||||
>
|
||||
<OrgAdd
|
||||
ref="org-add-form"
|
||||
:org="currEditingOrg"
|
||||
@cancel="isDialAddDeptVisible = false"
|
||||
@success="onOrgAddSuccess"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="编辑部门"
|
||||
width="30%"
|
||||
:visible.sync="isDialEditDeptVisible"
|
||||
:before-close="onDialEditDeptClose"
|
||||
@open="onDialEditDeptOpen"
|
||||
>
|
||||
<OrgEdit
|
||||
ref="org-edit-form"
|
||||
:org="currEditingOrg"
|
||||
@cancel="isDialEditDeptVisible = false"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="移动部门"
|
||||
width="50%"
|
||||
:visible.sync="isDialMoveDeptVisible"
|
||||
:before-close="onDialMoveDeptClose"
|
||||
@open="onDialMoveDeptOpen"
|
||||
>
|
||||
<OrgMove
|
||||
ref="org-move-form"
|
||||
:org="currEditingOrg"
|
||||
:treeData="orgTreeData"
|
||||
@cancel="isDialMoveDeptVisible = false"
|
||||
@success="onOrgMoveSuccess"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</PageSplit>
|
||||
</template>
|
||||
<script>
|
||||
import PageSplit from "vue-page-split";
|
||||
import UserList from "../../components/Rbac/User/UserList4Org.vue";
|
||||
import UserAdd from "../../components/Rbac/User/UserAdd.vue";
|
||||
import OrgAdd from "../../components/Rbac/Organization/OrgAdd.vue";
|
||||
import OrgEdit from "../../components/Rbac/Organization/OrgEdit.vue";
|
||||
import OrgMove from "../../components/Rbac/Organization/OrgMove.vue";
|
||||
import TreeNodeWith3Dots from "../../components/_Common/Tree/TreeNodeWith3Dots.vue";
|
||||
|
||||
import OrganizationBiz from "../../biz/Rbac/Organization.js";
|
||||
|
||||
// 空间树根节点
|
||||
const ORG_ROOT = {
|
||||
name: "COMPANY",
|
||||
id: -1,
|
||||
};
|
||||
|
||||
export default {
|
||||
components: { PageSplit, UserList, UserAdd, OrgEdit, OrgAdd, OrgMove },
|
||||
data() {
|
||||
return {
|
||||
treeProps: {
|
||||
label: "name",
|
||||
children: "Children",
|
||||
},
|
||||
orgTreeData: [], // 组织架构树数据
|
||||
vloadingOrgTree: false, // 组织架构树是否正在loading
|
||||
defaultExpandedKeys: [ORG_ROOT.id], // 组织架构树默认展开的节点id(默认展开根节点)
|
||||
isDialAddUserVisible: false, // 添加用户对话框是否显示
|
||||
|
||||
isDialEditDeptVisible: false, // 编辑部门对话框是否显示
|
||||
isDialAddDeptVisible: false, // 新建部门对话框是否显示
|
||||
isDialMoveDeptVisible: false, // 移动部门对话框是否显示
|
||||
|
||||
currSelectedOrg: ORG_ROOT, // 当前选中的部门id(什么都没选中,视为选中根节点)
|
||||
currEditingOrg: {
|
||||
id: ORG_ROOT.id, // 当前选中的部门id(什么都没选中,视为选中根节点)
|
||||
name: ORG_ROOT.name, // 当前选中的部门名称
|
||||
},
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
//加载组织架构树
|
||||
this.orgTreeData = await this.getAllNodesWithRoot();
|
||||
this.$nextTick(() => {
|
||||
// let rootNode = this.$refs["org-tree"].getNode(this.orgTreeData[0]);
|
||||
// console.log("rootNode :>> ", rootNode);
|
||||
this.$refs["org-tree"].setCurrentKey(ORG_ROOT.id);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
// “添加用户”按钮被点击时
|
||||
onAddUserBtnClick() {
|
||||
this.isDialAddUserVisible = true;
|
||||
},
|
||||
|
||||
// 当添加用户窗口添加用户成功时
|
||||
onUserAddSuccess(userId) {
|
||||
this.$refs["user-list"].goToLastPage();
|
||||
},
|
||||
|
||||
// “新建部门”的对话框的确定按钮被点击时
|
||||
onNewDeptConfirmClick() {
|
||||
this.$refs["new-org-form"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
let orgs = await OrganizationBiz.findByName(this.newOrg.name);
|
||||
let _org = orgs.find(
|
||||
(org) =>
|
||||
org.name === this.newOrg.name &&
|
||||
org.parentId === this.newOrg.parentNode.id
|
||||
);
|
||||
|
||||
if (_org) {
|
||||
this.$message({ type: "error", message: "不能有同名节点" });
|
||||
} else {
|
||||
let newOrg = await OrganizationBiz.add(
|
||||
this.newOrg.parentNode.id,
|
||||
this.newOrg.name
|
||||
);
|
||||
this.orgTreeData = await this.getAllNodesWithRoot();
|
||||
this.defaultExpandedKeys[0] = newOrg.id;
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message({ type: "error", message: e.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// “新建部门”的对话框的退出按钮被点击时
|
||||
onNewDeptQuitClick() {
|
||||
this.isDialNewDeptVisible = false;
|
||||
},
|
||||
|
||||
// “新建部门”的对话框的❌被点击时
|
||||
onDialAddDeptClose(done) {
|
||||
done();
|
||||
},
|
||||
|
||||
// “编辑部门”的对话框的❌被点击时
|
||||
onDialEditDeptClose(done) {
|
||||
done();
|
||||
},
|
||||
|
||||
// “移动部门”的对话框的❌被点击时
|
||||
onDialMoveDeptClose(done) {
|
||||
done();
|
||||
},
|
||||
|
||||
onTreeNodeClick() {},
|
||||
|
||||
// 当组织架构树被改变选中时
|
||||
onOrgTreeCurrChange(data, node) {
|
||||
this.currSelectedOrg = data;
|
||||
},
|
||||
|
||||
// 当添加子部门的对话框的open事件被触发时
|
||||
onDialAddDeptOpen() {
|
||||
let $refForm = this.$refs["org-add-form"];
|
||||
// 第一次打开dialog时,表单会不存在
|
||||
if ($refForm) {
|
||||
$refForm.updateForm();
|
||||
}
|
||||
},
|
||||
|
||||
// 当编辑部门的对话框的open事件被触发时
|
||||
onDialEditDeptOpen() {
|
||||
let $refForm = this.$refs["org-edit-form"];
|
||||
// 第一次打开dialog时,表单会不存在
|
||||
if ($refForm) {
|
||||
$refForm.updateForm();
|
||||
}
|
||||
},
|
||||
|
||||
// 当移动部门的对话框的open事件被触发时
|
||||
onDialMoveDeptOpen() {
|
||||
let $refForm = this.$refs["org-move-form"];
|
||||
// 第一次打开dialog时,表单会不存在
|
||||
if ($refForm) {
|
||||
$refForm.updateForm();
|
||||
}
|
||||
},
|
||||
|
||||
// 当添加子部门成功时
|
||||
async onOrgAddSuccess(currNodeData, newSubNodeData) {
|
||||
let treeNode = this.$refs["org-tree"].getNode(currNodeData); // 获取子部门的父部门树节点对象
|
||||
this.$refs["org-tree"].append(newSubNodeData, treeNode); // 在父部门树节点对象下加入子部门
|
||||
// this.$refs["org-tree"].append(newSubNodeData, currNodeData.id); // 在父部门树节点对象下加入子部门
|
||||
this.defaultExpandedKeys = [newSubNodeData.id]; // 展开父部门
|
||||
},
|
||||
|
||||
// 当移动部门的对话框里移动部门成功时
|
||||
onOrgMoveSuccess(currNodeData, targetParentData) {
|
||||
// console.log("currNodeData :>> ", currNodeData);
|
||||
// console.log("targetParentData :>> ", targetParentData);
|
||||
// let treeNode = this.$refs["org-tree"].getNode(currNodeData.id); // 获取子部门的树节点对象
|
||||
let parentTreeNode = this.$refs["org-tree"].getNode(targetParentData); // 获取子部门的目标父部门树节点对象
|
||||
let subTreeNode = this.$refs["org-tree"].getNode(currNodeData); // 获取子部门的树节点对象
|
||||
this.$refs["org-tree"].remove(subTreeNode);
|
||||
this.$refs["org-tree"].append(currNodeData, parentTreeNode);
|
||||
},
|
||||
|
||||
// 获取所有组织架构节点,并在最外层加上root节点
|
||||
async getAllNodesWithRoot() {
|
||||
this.vloadingOrgTree = true;
|
||||
let allTreeData = await OrganizationBiz.getAllNodes(null);
|
||||
this.vloadingOrgTree = false;
|
||||
let treeRoot = { ...ORG_ROOT };
|
||||
treeRoot.Children = allTreeData;
|
||||
return [treeRoot];
|
||||
},
|
||||
|
||||
// 渲染组织架构树节点内容的函数
|
||||
renderTreeNodeContent(h, { node, data, store }) {
|
||||
return (
|
||||
<TreeNodeWith3Dots
|
||||
data={data}
|
||||
btns={data.id ? ["edit", "add", "move", "delete"] : ["add"]}
|
||||
addBtnName={"新增子部门"}
|
||||
on-menu-select={(index, indexPath, data) => {
|
||||
switch (index) {
|
||||
case "add":
|
||||
this.isDialAddDeptVisible = true;
|
||||
this.currEditingOrg = data;
|
||||
break;
|
||||
case "edit":
|
||||
this.isDialEditDeptVisible = true;
|
||||
this.currEditingOrg = data; // 这样在OrgEdit中可以直接修改组织架构树的部门名
|
||||
// this.currEditingOrg.id = data.id;
|
||||
// this.currEditingOrg.name = data.name;
|
||||
break;
|
||||
case "move":
|
||||
this.currEditingOrg = data;
|
||||
this.isDialMoveDeptVisible = true;
|
||||
break;
|
||||
case "delete":
|
||||
this.currEditingOrg = data;
|
||||
this.$confirm(`确定删除部门 ${this.currEditingOrg.name}?`, {
|
||||
title: "确认删除",
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
let count = await OrganizationBiz.delById(
|
||||
this.currEditingOrg.id
|
||||
);
|
||||
if (count) {
|
||||
this.$message.success(
|
||||
`部门 ${this.currEditingOrg.name} 删除成功`
|
||||
);
|
||||
this.$refs["org-tree"].remove(this.currEditingOrg);
|
||||
} else {
|
||||
this.$message.success(
|
||||
`部门 ${this.currEditingOrg.name} 删除失败`
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.success(
|
||||
`部门 ${this.currEditingOrg.name} 删除失败,原因:${e.message}`
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
break;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
onResizeLineStartMove: function () {},
|
||||
onResizeLineMove: function (e) {},
|
||||
onResizeLineEndMove: function () {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/_variables.scss";
|
||||
|
||||
$line-height: 28px;
|
||||
.split-pane {
|
||||
// background-color: #fff;
|
||||
// border-radius: 8px;
|
||||
// border: solid 1px $theme-background-light;
|
||||
box-sizing: border-box;
|
||||
.pane {
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
.title {
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid $theme-background-dark;
|
||||
height: $line-height;
|
||||
&.title-flex-right {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
&.title-flex-both {
|
||||
// display: flex;
|
||||
// flex-direction: row;
|
||||
// justify-content: space-between;
|
||||
}
|
||||
.title-inner {
|
||||
line-height: $line-height;
|
||||
}
|
||||
.el-button.el-button--text {
|
||||
// padding: 0;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
padding-top: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,112 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-04 09:49:56
|
||||
* @Description: 后台管理-角色管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="platformSetting back-column-one">
|
||||
<div class="back-title">{{$route.meta.title}}</div>
|
||||
<el-button type="primary" round>新建模块</el-button>
|
||||
<el-table :data="dataList" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="title in titleList"
|
||||
:key="title.prop"
|
||||
:prop="title.prop"
|
||||
:label="title.label"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="操作">
|
||||
<template v-slot="scope">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="light"
|
||||
content="恢复"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
icon="el-icon-edit"
|
||||
type="text"
|
||||
@click="handleEditClick(scope.row)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="light"
|
||||
content="删除"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
icon="el-icon-delete"
|
||||
type="text"
|
||||
@click="handleDeleteClick(scope.row)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PlatformSetting",
|
||||
|
||||
data() {
|
||||
return {
|
||||
titleList: [
|
||||
{
|
||||
prop: 'type',
|
||||
label: '分类名称'
|
||||
},
|
||||
{
|
||||
prop: 'moduleType',
|
||||
label: '模块类型'
|
||||
},
|
||||
{
|
||||
prop: 'dest',
|
||||
label: '说明'
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态'
|
||||
},
|
||||
{
|
||||
prop: 'sort',
|
||||
label: '排序'
|
||||
},
|
||||
],
|
||||
dataList: [
|
||||
{
|
||||
type: '产品及演示方案',
|
||||
moduleType: '演示方案',
|
||||
dest: '-',
|
||||
status: '启用',
|
||||
sort: '',
|
||||
},
|
||||
{
|
||||
type: '产品及演示方案',
|
||||
moduleType: '演示方案',
|
||||
dest: '-',
|
||||
status: '启用',
|
||||
sort: '',
|
||||
},
|
||||
{
|
||||
type: '产品及演示方案',
|
||||
moduleType: '演示方案',
|
||||
dest: '-',
|
||||
status: '启用',
|
||||
sort: '',
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
</style>
|
|
@ -1,519 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-05 18:47:10
|
||||
* @Description: 后台管理-角色管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="role back-column-two">
|
||||
<!-- 左侧-角色列表 -->
|
||||
<div class="column-left">
|
||||
<div class="title back-title">
|
||||
{{ $route.meta.title }}
|
||||
<el-button
|
||||
class="role-new"
|
||||
icon="el-icon-circle-plus"
|
||||
@click="roleDialogAddVisible = true"
|
||||
>
|
||||
新建角色
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-input
|
||||
class="bg-dark"
|
||||
v-model="roleInput"
|
||||
prefix-icon="el-icon-search"
|
||||
placeholder="请输入"
|
||||
@change="handleRoleInput"
|
||||
/>
|
||||
|
||||
<div class="role-list">
|
||||
<ul class="list-ul">
|
||||
<li
|
||||
v-for="role in roleList"
|
||||
:key="role.id"
|
||||
class="list-li"
|
||||
:class="{ selected: role === selectedRole }"
|
||||
@click="handleRoleClick(role)"
|
||||
>
|
||||
<!-- {{ role.name }} -->
|
||||
<TreeNodeWith3Dots
|
||||
:data="role"
|
||||
:btns="['edit', 'delete']"
|
||||
@menu-select="handleRoleOperate"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
title="新建角色"
|
||||
width="30%"
|
||||
:visible.sync="roleDialogAddVisible"
|
||||
>
|
||||
<RoleAdd
|
||||
@on-cancel="roleDialogAddVisible = false"
|
||||
@on-submit="handleRoleAddSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="编辑角色"
|
||||
width="30%"
|
||||
:visible.sync="roleDialogEditVisible"
|
||||
>
|
||||
<RoleUpdate
|
||||
:role="selectedRole"
|
||||
@on-cancel="roleDialogEditVisible = false"
|
||||
@on-submit="handleRoleEditSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<!-- 右侧-角色内容 -->
|
||||
<div class="column-right">
|
||||
<el-tabs
|
||||
class="back-title-el-tabs"
|
||||
value="role-remember"
|
||||
@tab-click="handleTabClick"
|
||||
>
|
||||
<el-tab-pane label="角色成员(2)" name="role-remember">
|
||||
<div class="form-box">
|
||||
<el-button type="primary" round>关联用户</el-button>
|
||||
<el-input
|
||||
class="bg-dark"
|
||||
v-model="userInput"
|
||||
prefix-icon="el-icon-search"
|
||||
placeholder="请输入"
|
||||
@change="handleUserInput"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-box">
|
||||
<div>共132个伙伴</div>
|
||||
<div>
|
||||
<el-dropdown class="sort" @command="ff">
|
||||
<span class="el-dropdown-link">
|
||||
{{ sortType }}
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>创建时间正序</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-dropdown class="filter">
|
||||
<span class="el-dropdown-link">
|
||||
{{ filteType }}
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item>角色</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="userList" style="width: 100%">
|
||||
<el-table-column
|
||||
v-for="title in titleList"
|
||||
:key="title.prop"
|
||||
:prop="title.prop"
|
||||
:label="title.label"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="操作">
|
||||
<template v-slot="scope">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="light"
|
||||
content="编辑"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
icon="el-icon-edit"
|
||||
type="text"
|
||||
@click="handleEditClick(scope.row)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" />
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="light"
|
||||
content="删除"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
icon="el-icon-delete"
|
||||
type="text"
|
||||
@click="handleDeleteClick(scope.row)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="pagination">
|
||||
<el-pagination background layout="prev, pager, next" :total="1000">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="角色权限" name="role-auth">
|
||||
<ul class="auth-first-ul">
|
||||
<li v-for="firstAuth in authList" :key="firstAuth.text">
|
||||
<el-checkbox v-model="firstAuth.checked">
|
||||
{{ firstAuth.text }}
|
||||
</el-checkbox>
|
||||
<ul class="auth-second-ul">
|
||||
<li
|
||||
v-for="secondAuth in firstAuth.children"
|
||||
:key="secondAuth.text"
|
||||
>
|
||||
<el-checkbox v-model="secondAuth.checked">
|
||||
{{ secondAuth.text }}
|
||||
</el-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from "../../components/_Common/Dialog.vue";
|
||||
import RoleAdd from "../../components/Rbac/Role/RoleAdd.vue";
|
||||
import RoleUpdate from "../../components/Rbac/Role/RoleEdit.vue";
|
||||
import TreeNodeWith3Dots from "../../components/_Common/Tree/TreeNodeWith3Dots.vue";
|
||||
|
||||
import RoleBiz from "../../biz/Rbac/Role.js";
|
||||
import UserBiz from "../../biz/Rbac/User.js";
|
||||
|
||||
import { DIALOG_TYPE } from "../../const.js";
|
||||
|
||||
export default {
|
||||
name: "Role",
|
||||
|
||||
components: {
|
||||
RoleAdd,
|
||||
RoleUpdate,
|
||||
TreeNodeWith3Dots,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
roleDialogAddVisible: false, // 是否显示角色新建框
|
||||
roleDialogEditVisible: false, // 是否显示角色编辑框
|
||||
roleAction: DIALOG_TYPE.ADD, // 当前角色框类型(新建或编辑)
|
||||
roleInput: "", // 角色搜索内容
|
||||
userInput: "", // 用户搜索内容
|
||||
roleList: [], // 角色列表
|
||||
selectedRole: null, // 当前点击选中角色
|
||||
// 角色成员列表标题
|
||||
titleList: [
|
||||
{
|
||||
prop: "name",
|
||||
label: "伙伴名称",
|
||||
},
|
||||
{
|
||||
prop: "department",
|
||||
label: "部门",
|
||||
},
|
||||
{
|
||||
prop: "role",
|
||||
label: "角色",
|
||||
},
|
||||
{
|
||||
prop: "status",
|
||||
label: "账号状态",
|
||||
},
|
||||
],
|
||||
userList: [], // 角色成员列表数据
|
||||
//角色权限数据
|
||||
authList: [
|
||||
{
|
||||
text: "全部",
|
||||
checked: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
text: "产品",
|
||||
children: [
|
||||
{
|
||||
text: "查看",
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
text: "下架产品",
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
text: "编辑产品",
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
text: "分享产品",
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
text: "删除产品",
|
||||
checked: false,
|
||||
},
|
||||
{
|
||||
text: "收藏",
|
||||
checked: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "行业解决方案",
|
||||
children: [
|
||||
{
|
||||
text: "查看",
|
||||
checked: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "个人空间",
|
||||
children: [
|
||||
{
|
||||
text: "开启",
|
||||
checked: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "后台管理",
|
||||
children: [
|
||||
{
|
||||
text: "组织架构",
|
||||
checked: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
sortType: "排序", // 当前排序方式
|
||||
filteType: "筛选", // 当前筛选方式
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
// 当前角色框标题
|
||||
roleTitle() {
|
||||
switch (this.roleAction) {
|
||||
case DIALOG_TYPE.EDIT:
|
||||
return "编辑角色";
|
||||
case DIALOG_TYPE.ADD:
|
||||
default:
|
||||
return "新建角色";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
async selectedRole() {
|
||||
this.refreshUserList();
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 切换tab
|
||||
handleTabClick(tab, event) {
|
||||
console.log(tab, event);
|
||||
},
|
||||
|
||||
ff(a, b) {
|
||||
console.log(a, b);
|
||||
},
|
||||
|
||||
// 监听-角色搜索
|
||||
handleRoleInput() {
|
||||
console.log("searchRole >>> ");
|
||||
this.refreshRoleList();
|
||||
},
|
||||
|
||||
// 监听-用户搜索
|
||||
handleUserInput() {
|
||||
console.log("searchUser");
|
||||
this.refreshUserList();
|
||||
},
|
||||
|
||||
// 点击-左侧角色
|
||||
handleRoleClick(role) {
|
||||
this.selectedRole = role;
|
||||
},
|
||||
|
||||
// 监听-角色新建成功
|
||||
handleRoleAddSubmit(newRole) {
|
||||
console.log("newRole >>> ", newRole);
|
||||
this.roleDialogAddVisible = false;
|
||||
},
|
||||
|
||||
// 监听-角色编辑成功
|
||||
handleRoleEditSubmit() {
|
||||
this.roleDialogEditVisible = false;
|
||||
},
|
||||
|
||||
// 监听-角色操作(编辑、删除)
|
||||
handleRoleOperate(index, _, data) {
|
||||
switch (index) {
|
||||
case "edit":
|
||||
this.roleDialogEditVisible = true;
|
||||
break;
|
||||
case "delete":
|
||||
this.$confirm(`确定删除角色 ${data.name} ?`, { title: "确认删除" })
|
||||
.then(async () => {
|
||||
try {
|
||||
const count = await RoleBiz.delById(data.id);
|
||||
if (count) {
|
||||
this.$message.success("角色删除成功");
|
||||
} else {
|
||||
this.$message.error("角色删除失败");
|
||||
}
|
||||
} catch ({ message }) {
|
||||
this.$message.error(message);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
|
||||
// 点击-删除角色用户
|
||||
handleDeleteClick(user) {
|
||||
this.$confirm(`确定移除用户 ${user.name} ?`, { title: "确认移除" })
|
||||
.then(async () => {
|
||||
try {
|
||||
const count = await UserBiz.delById(user.id);
|
||||
if (count) {
|
||||
this.$message.success("用户移除成功");
|
||||
} else {
|
||||
this.$message.error("角色移除失败");
|
||||
}
|
||||
} catch ({ message }) {
|
||||
this.$message.error(message);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
// 刷新角色列表
|
||||
async refreshRoleList() {
|
||||
this.roleList = await RoleBiz.findByName(this.roleInput);
|
||||
|
||||
if (this.roleList) {
|
||||
this.selectedRole = this.roleList[0];
|
||||
}
|
||||
},
|
||||
|
||||
// 刷新用户列表
|
||||
async refreshUserList() {
|
||||
this.userList = await UserBiz.findByName(this.userInput);
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.refreshRoleList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/element-ui-reset.scss";
|
||||
|
||||
.role {
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: #{$title-height - 20 + px};
|
||||
border-bottom: 2px solid $theme-background-light;
|
||||
|
||||
.role-new {
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: #347eff;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.role-list {
|
||||
.list-ul {
|
||||
margin-top: 20px;
|
||||
|
||||
.list-li {
|
||||
height: 36px;
|
||||
padding-left: 20px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(52, 126, 255, 0.1);
|
||||
// opacity: 0.1;
|
||||
color: #347eff;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: rgba(52, 126, 255, 0.1);
|
||||
color: #347eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-box,
|
||||
.text-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.form-box {
|
||||
.el-input {
|
||||
width: 274px;
|
||||
}
|
||||
}
|
||||
|
||||
.text-box {
|
||||
margin: 20px 0;
|
||||
|
||||
.sort {
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filter {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-first-ul {
|
||||
& > li {
|
||||
margin-bottom: 30px;
|
||||
|
||||
& > .el-checkbox::v-deep {
|
||||
margin-bottom: 10px;
|
||||
font-weight: 700;
|
||||
|
||||
.el-checkbox__label {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-second-ul {
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
margin-left: 20px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,23 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-04 09:50:07
|
||||
* @Description: 后台管理-角色管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="statistics back-column-one">
|
||||
<div class="back-title">{{ $route.meta.title }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Statistics",
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
</style>
|
|
@ -1,23 +0,0 @@
|
|||
<!--
|
||||
* @Author: Guanghao
|
||||
* @Date: 2021-12-31 14:29:34
|
||||
* @LastEditors: Guanghao
|
||||
* @LastEditTime: 2022-01-04 09:50:10
|
||||
* @Description: 后台管理-角色管理页面
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="topic back-column-one">
|
||||
<div class="back-title">{{$route.meta.title}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Topic",
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/scss/Back/back.scss";
|
||||
</style>
|
|
@ -2,7 +2,7 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2020-09-10 09:12:00
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-10 21:10:42
|
||||
* @LastEditTime: 2022-03-07 14:32:23
|
||||
* @Description: 首页框架
|
||||
-->
|
||||
<template>
|
||||
|
@ -31,24 +31,18 @@
|
|||
<keep-alive v-if="$route.meta.keepAlive">
|
||||
<router-view></router-view>
|
||||
</keep-alive>
|
||||
|
||||
<!-- <el-aside class="right" :width="HEADER_THICKNESS + 'px'">
|
||||
<Header2 :arrangeMode="'vertical'" />
|
||||
</el-aside> -->
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Header from "../components/Home/Header.vue";
|
||||
import Header2 from "../components/Home/Header2.vue";
|
||||
import { DEFAULT_HOME_LAYOUT, HEADER_THICKNESS } from "../const.js";
|
||||
|
||||
export default {
|
||||
name: "Home",
|
||||
components: {
|
||||
Header,
|
||||
Header2,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -2,62 +2,18 @@
|
|||
* @Author: Billy
|
||||
* @Date: 2021-12-20 11:05:48
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 14:18:06
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2021-12-20 11:05:48
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2021-12-20 11:07:46
|
||||
* @LastEditTime: 2022-03-07 15:00:04
|
||||
* @Description: 请输入
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
aa
|
||||
<input type="text" />
|
||||
<!-- <TabViewer
|
||||
:tabs="tabs"
|
||||
:tabsCurrActiveIndex.sync="tabsCurrActiveIndex"
|
||||
></TabViewer> -->
|
||||
</div>
|
||||
<div class="container"></div>
|
||||
</template>
|
||||
<script>
|
||||
import TabViewer from "../../../components/_Common/Tab/TabViewer2.vue";
|
||||
import Tab from "../../../entity/Ui/Tab/Tab.js";
|
||||
export default {
|
||||
components: { TabViewer },
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
// 标签信息数组
|
||||
tabs: [
|
||||
new Tab({ title: "000000000a" }),
|
||||
new Tab({ title: "111111111b" }),
|
||||
new Tab({ title: "222222222c" }),
|
||||
new Tab({ title: "333333333d" }),
|
||||
new Tab({ title: "444444444e" }),
|
||||
new Tab({ title: "555555555f" }),
|
||||
new Tab({ title: "000000000000000000000000000000000000a" }),
|
||||
new Tab({ title: "111111111b" }),
|
||||
new Tab({ title: "222c" }),
|
||||
new Tab({ title: "333333333d" }),
|
||||
new Tab({ title: "444444444e" }),
|
||||
new Tab({ title: "555555555f" }),
|
||||
new Tab({ title: "000000000a" }),
|
||||
new Tab({ title: "111111111b" }),
|
||||
new Tab({ title: "222222222c" }),
|
||||
new Tab({ title: "333333333d" }),
|
||||
new Tab({ title: "444444444e" }),
|
||||
new Tab({ title: "555555555f" }),
|
||||
new Tab({ title: "000000000000000000000000000000000000a" }),
|
||||
new Tab({ title: "111111111b" }),
|
||||
new Tab({ title: "222c" }),
|
||||
new Tab({ title: "333333333d" }),
|
||||
new Tab({ title: "444444444e" }),
|
||||
new Tab({ title: "555555555f" }),
|
||||
],
|
||||
tabsCurrActiveIndex: 2,
|
||||
};
|
||||
return {};
|
||||
},
|
||||
mounted() {},
|
||||
};
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2022-01-06 15:22:46
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 15:22:46
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
|
@ -1,10 +0,0 @@
|
|||
<!--
|
||||
* @Author: Billy
|
||||
* @Date: 2022-01-06 15:22:46
|
||||
* @LastEditors: Billy
|
||||
* @LastEditTime: 2022-01-06 15:22:46
|
||||
* @Description: 请输入
|
||||
-->
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
Loading…
Reference in New Issue