WIP: 完成顶部导航,完成二级导航样式设置,完成主体部分样式设置,完成账户页面列表及搜索部分
BIN
public/images/top-nav/abnormal-alarm-active.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/top-nav/abnormal-alarm.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/top-nav/log-manage-active.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
public/images/top-nav/log-manage.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/top-nav/spectrum-analysis-active.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
public/images/top-nav/spectrum-analysis.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
public/images/top-nav/station-operation-active.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
public/images/top-nav/station-operation.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
public/images/top-nav/web-statistics-active.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
public/images/top-nav/web-statistics.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1022 B After Width: | Height: | Size: 1022 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/images/global/add.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/images/global/delete.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/global/edit.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/images/global/reset-pwd.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/images/global/search.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/global/select-down.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/header/avatar.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
BIN
src/assets/images/header/close.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/images/header/notice.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/images/header/split-line.png
Normal file
After Width: | Height: | Size: 992 B |
40
src/components/CustomSelect/index.vue
Normal file
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<a-select v-bind="$attrs" v-model="innerValue">
|
||||
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
|
||||
</a-select>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerValue: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value () {
|
||||
this.innerValue = this.value
|
||||
},
|
||||
innerValue () {
|
||||
this.$emit('input', this.innerValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.ant-select {
|
||||
.ant-select-arrow-icon {
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
&-open {
|
||||
.ant-select-arrow-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
89
src/components/SearchForm/index.vue
Normal file
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<div class="search-form">
|
||||
<a-row :gutter="20">
|
||||
<a-form-model ref="form" :model="formModel" v-bind="$attrs" @keyup.enter.native="onSearch">
|
||||
<a-col v-for="(item, index) in items" :key="index" :span="item.span || 6">
|
||||
<a-form-model-item :label="item.label" :prop="item.name" :labelCol="item.labelCol">
|
||||
<component :is="item.type" v-bind="item.props" v-model="formModel[item.name]" v-on="item.on"></component>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col>
|
||||
<a-button class="search-btn" type="primary" @click="onSearch">
|
||||
<img src="@/assets/images/global/search.png" alt="">
|
||||
search
|
||||
</a-button>
|
||||
<slot name="additional"></slot>
|
||||
</a-col>
|
||||
</a-form-model>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { cloneDeep } from 'lodash'
|
||||
export default {
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formModel: cloneDeep(this.value)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSearch() {
|
||||
this.$emit('search', this.formModel)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.formModel = val
|
||||
},
|
||||
formModel: {
|
||||
handler(val) {
|
||||
this.$emit('input', val)
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.search-form {
|
||||
height: 50px;
|
||||
padding: 10px;
|
||||
border-top: 1px solid rgba(12, 235, 201, .3);
|
||||
border-bottom: 1px solid rgba(12, 235, 201, .3);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
::v-deep .ant-form-item {
|
||||
display: flex;
|
||||
margin-bottom: 0;
|
||||
.ant-form-item-label,
|
||||
.ant-form-item-control {
|
||||
line-height: 32px;
|
||||
}
|
||||
.ant-form-item-label {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ant-form-item-control-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
img {
|
||||
width: 16px;
|
||||
height: 17px;
|
||||
margin-right: 9px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<global-layout @dynamicRouterShow="dynamicRouterShow">
|
||||
<div style="margin: 12px 12px 0;">
|
||||
<div>
|
||||
<!-- update-begin-author:taoyan date:20201221 for:此处删掉transition标签 不知道为什么加上后 页面路由切换的时候即1及菜单切到2及菜单的时候 两个菜单页面会同时出现300-500秒左右 -->
|
||||
<keep-alive v-if="multipage">
|
||||
<router-view v-if="reloadFlag"/>
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
<template>
|
||||
<div style="height: 100%; overflow: hidden;">
|
||||
<div class="custom-top-menu">
|
||||
<a-menu mode="horizontal" v-model="selectedKeys" @click="onMenuSelect">
|
||||
<a-menu-item v-for="menu in menus" :key="menu.name">
|
||||
<img class="menu-logo" :src="'/images/top-nav/' + menu.meta.icon + '.png'" alt="">
|
||||
<a-menu-item v-for="(menu, index) in menus" :key="menu.name" :class="{ 'is-last': index === menus.length - 1}">
|
||||
<img
|
||||
v-show="menu.name === selectedKeys[0]"
|
||||
class="menu-logo"
|
||||
:src="'/images/top-nav/' + menu.meta.icon + '-active.png'"
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
v-show="menu.name !== selectedKeys[0]"
|
||||
class="menu-logo"
|
||||
:src="'/images/top-nav/' + menu.meta.icon + '.png'"
|
||||
alt=""
|
||||
/>
|
||||
<span v-html="menu.meta.title.split(' ').join('<br>')"></span>
|
||||
<img v-if="index !== menus.length - 1" class="split-line" src="@/assets/images/header/split-line.png" alt="">
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
|
@ -23,7 +35,6 @@ export default {
|
|||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
const currTopMenu = this.findTopMenuByRouteName(this.menuItems, this.$route.name)
|
||||
this.selectedKeys = [currTopMenu.name]
|
||||
},
|
||||
|
@ -44,7 +55,7 @@ export default {
|
|||
* @param {Array} menus
|
||||
* @param {String} routeName
|
||||
*/
|
||||
findTopMenuByRouteName(menus, routeName) {
|
||||
findTopMenuByRouteName(menus, routeName) {
|
||||
for (const menu of menus) {
|
||||
if (menu.name === routeName) {
|
||||
return menu
|
||||
|
@ -72,25 +83,36 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ant-menu {
|
||||
background: transparent;
|
||||
height: 100% !important;
|
||||
font-size: 16px;
|
||||
&-item {
|
||||
color: #0CECCA !important;
|
||||
border-bottom: 0 !important;
|
||||
height: 100%;
|
||||
padding: 0 31px;
|
||||
border: 1px solid transparent;
|
||||
font-family: MicrogrammaD-MediExte;
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
line-height: normal;
|
||||
&-selected,
|
||||
&-active {
|
||||
background-color: rgba(9, 255, 212, .3) !important;
|
||||
color: #fff !important;
|
||||
border-color: rgba(5, 255, 184, 0.46);
|
||||
.custom-top-menu {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.ant-menu {
|
||||
background: transparent;
|
||||
height: 100% !important;
|
||||
color: #0cecca !important;
|
||||
font-size: 16px;
|
||||
&-item {
|
||||
color: #0cecca !important;
|
||||
border-bottom: 0 !important;
|
||||
height: 100%;
|
||||
padding: 0 30px;
|
||||
padding-right: 0;
|
||||
font-family: MicrogrammaD-MediExte;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
line-height: normal;
|
||||
&-selected,
|
||||
&-active {
|
||||
background-color: rgba(9, 255, 212, 0.3) !important;
|
||||
color: #fff !important;
|
||||
border-color: rgba(5, 255, 184, 0.46);
|
||||
}
|
||||
.split-line {
|
||||
margin-left: 30px;
|
||||
}
|
||||
&.is-last {
|
||||
padding-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,3 +121,38 @@ export default {
|
|||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.ant-menu-submenu-popup {
|
||||
.ant-menu {
|
||||
height: 73px;
|
||||
background-color: #0c3d43 !important;
|
||||
&-item {
|
||||
color: #0cecca !important;
|
||||
border-bottom: 0 !important;
|
||||
height: 100% !important;
|
||||
padding: 0 30px !important;
|
||||
padding-right: 0 !important;
|
||||
border: 1px solid transparent;
|
||||
font-family: MicrogrammaD-MediExte;
|
||||
font-size: 16px !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
line-height: normal !important;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0 !important;
|
||||
&-selected,
|
||||
&-active {
|
||||
background-color: rgba(9, 255, 212, 0.3) !important;
|
||||
color: #fff !important;
|
||||
border-color: rgba(5, 255, 184, 0.46);
|
||||
}
|
||||
.split-line {
|
||||
margin-left: 30px;
|
||||
}
|
||||
&.is-last {
|
||||
padding-right: 30px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -191,7 +191,7 @@
|
|||
/* update_end author:scott date:20190220 for: 缩小首页布局顶部的高度*/
|
||||
|
||||
.top-nav-header-index {
|
||||
background: url(~@/assets/header/bg.png) no-repeat;
|
||||
background: url(~@/assets/images/header/bg.png) no-repeat;
|
||||
background-size: 100% 120%;
|
||||
height: 100%;
|
||||
background-color: transparent !important;
|
||||
|
|
|
@ -13,14 +13,31 @@
|
|||
@toggle="toggle"
|
||||
@updateMenuTitle="handleUpdateMenuTitle"
|
||||
/>
|
||||
<div class="sub-menus" v-if="currentChildrenMenus && currentChildrenMenus.length">
|
||||
<s-menu :menu="currentChildrenMenus" mode="horizontal" theme="light"></s-menu>
|
||||
<div class="global-content">
|
||||
<div class="top-border">
|
||||
<img src="@/assets/images/content/top.png" alt="">
|
||||
</div>
|
||||
<div class="content-main">
|
||||
<div class="left-border">
|
||||
<img src="@/assets/images/content/left.png" alt="">
|
||||
</div>
|
||||
<!-- layout content -->
|
||||
<a-layout-content>
|
||||
<div class="sub-menus" v-if="currentChildrenMenus && currentChildrenMenus.length">
|
||||
<s-menu :menu="currentChildrenMenus" mode="horizontal" theme="light"></s-menu>
|
||||
</div>
|
||||
<div class="real-content" :class="currentChildrenMenus.length? 'has-submenu': ''">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
<div class="right-border">
|
||||
<img src="@/assets/images/content/left.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-border">
|
||||
<img src="@/assets/images/content/bottom.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- layout content -->
|
||||
<a-layout-content :style="{ height: '100%', paddingTop: fixedHeader ? '59px' : '0' }">
|
||||
<slot></slot>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
|
||||
<!-- update-start---- author:os_chengtgen -- date:20190830 -- for:issues/463 -编译主题颜色已生效,但还一直转圈,显示主题 正在编译 ---- -->
|
||||
|
@ -107,7 +124,7 @@
|
|||
findSubMenus(routeName) {
|
||||
for (const menu of this.menus) {
|
||||
if (menu.children) {
|
||||
const find = menu.children.find(child => child.name === routeName || child.children && child.children.find(item => item.child.name === routeName))
|
||||
const find = menu.children.find(child => child.name === routeName || child.children && child.children.find(item => item.name === routeName))
|
||||
if (find) {
|
||||
return menu.children
|
||||
}
|
||||
|
@ -294,18 +311,13 @@
|
|||
.header, .top-nav-header-index {
|
||||
|
||||
.user-wrapper {
|
||||
float: right;
|
||||
width: 140px;
|
||||
height: 100%;
|
||||
|
||||
margin-left: 30px;
|
||||
.action {
|
||||
cursor: pointer;
|
||||
padding: 0 14px;
|
||||
padding: 0 10px;
|
||||
display: inline-block;
|
||||
transition: all .3s;
|
||||
|
||||
height: 70%;
|
||||
line-height: 46px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
@ -651,10 +663,14 @@
|
|||
}
|
||||
|
||||
.sub-menus {
|
||||
margin-bottom: 16px;
|
||||
.ant-menu {
|
||||
font-size: 16px;
|
||||
background: transparent;
|
||||
background: rgba(12, 235, 201, .05);
|
||||
border-bottom: none;
|
||||
height: 40px;
|
||||
line-height: normal;
|
||||
padding-top: 5px;
|
||||
.ant-menu-item {
|
||||
background: rgba(58, 236, 240, .22) !important;
|
||||
border-bottom: none !important;
|
||||
|
@ -665,10 +681,18 @@
|
|||
position: relative;
|
||||
> a {
|
||||
color: #c9f6f6;
|
||||
font-weight: bold;
|
||||
font-family: BookmanOldStyle;
|
||||
}
|
||||
&-active,
|
||||
&-selected {
|
||||
> a {
|
||||
color: #2affdf;
|
||||
color: #2affdf !important;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-color: #0cecca !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,10 +716,64 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.global-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 73px);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.content-main {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.ant-layout-content {
|
||||
flex: 1;
|
||||
margin-top: 34px;
|
||||
margin-bottom: 34px;
|
||||
.real-content {
|
||||
height: 100%;
|
||||
overflow: hidden auto;
|
||||
}
|
||||
.has-submenu {
|
||||
height: calc(100% - 56px);
|
||||
}
|
||||
}
|
||||
}
|
||||
.top-border {
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 21px;
|
||||
}
|
||||
}
|
||||
.bottom-border {
|
||||
position: absolute;
|
||||
bottom: 6px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 21px;
|
||||
}
|
||||
}
|
||||
.left-border {
|
||||
width: 3px;
|
||||
height: 100%;
|
||||
margin-left: 12px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.right-border {
|
||||
width: 3px;
|
||||
height: 100%;
|
||||
margin-right: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ant-layout {
|
||||
background: #061314;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
|
@ -68,7 +68,7 @@
|
|||
</template>
|
||||
<span @click="fetchNotice" class="header-notice">
|
||||
<a-badge :count="msgTotal">
|
||||
<a-icon style="font-size: 16px; padding: 4px" type="bell" />
|
||||
<img src="@/assets/images/header/notice.png" alt="">
|
||||
</a-badge>
|
||||
</span>
|
||||
<show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<header-notice class="action"/>
|
||||
<a-dropdown>
|
||||
<span class="action action-full ant-dropdown-link user-dropdown-menu">
|
||||
人头icon
|
||||
<img src="@/assets/images/header/avatar.png" alt="">
|
||||
</span>
|
||||
<a-menu slot="overlay" class="user-dropdown-menu-wrapper">
|
||||
<a-menu-item key="0">
|
||||
|
@ -38,7 +38,7 @@
|
|||
</a-dropdown>
|
||||
<span class="action">
|
||||
<a class="logout_title" href="javascript:;" @click="handleLogout">
|
||||
<a-icon type="logout"/>
|
||||
<img src="@/assets/images/header/close.png" alt="">
|
||||
</a>
|
||||
</span>
|
||||
<user-password ref="userPassword"></user-password>
|
||||
|
|
|
@ -50,6 +50,9 @@ import '@/components/JVxeCells/install'
|
|||
import './style.less'
|
||||
//表单验证
|
||||
import { rules } from '@/utils/rules'
|
||||
|
||||
import CustomSelect from '@/components/CustomSelect'
|
||||
|
||||
Vue.prototype.rules = rules
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(Storage, config.storageOptions)
|
||||
|
@ -63,6 +66,7 @@ Vue.use(preview)
|
|||
Vue.use(vueBus);
|
||||
Vue.use(JeecgComponents);
|
||||
Vue.use(VueAreaLinkage);
|
||||
Vue.component('custom-select', CustomSelect)
|
||||
|
||||
SSO.init(() => {
|
||||
main()
|
||||
|
|
|
@ -22,7 +22,8 @@ export const JeecgListMixin = {
|
|||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
showTotal: (total, range) => {
|
||||
return range[0] + "-" + range[1] + " 共" + total + "条"
|
||||
const { current, pageSize } = this.ipagination
|
||||
return `共 ${total} 条记录 第${current} / ${Math.ceil(total / pageSize)} 页`
|
||||
},
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
|
|
180
src/style.less
|
@ -5,10 +5,20 @@
|
|||
src: url(~@/assets/fonts/MicrogrammaDMedExt.ttf);
|
||||
}
|
||||
|
||||
.ant-card {
|
||||
background-color: transparent;
|
||||
@font-face {
|
||||
font-family: BookmanOldStyle;
|
||||
src: url(~@/assets/fonts/BOOKOS.ttf);
|
||||
}
|
||||
|
||||
// 卡片样式
|
||||
.ant-card {
|
||||
background-color: #061214;
|
||||
.ant-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 表格样式
|
||||
.ant-table {
|
||||
color: #ade6ee;
|
||||
&-thead {
|
||||
|
@ -16,19 +26,43 @@
|
|||
th {
|
||||
background-color: #126b82 !important;
|
||||
color: #fff;
|
||||
padding: 6px 8px !important;
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-tbody {
|
||||
tr {
|
||||
background-color: #06282A;
|
||||
background-color: #06282a;
|
||||
&:nth-child(2n) {
|
||||
background-color: #08373A;
|
||||
background-color: #08373a;
|
||||
}
|
||||
td {
|
||||
padding: 10px 8px !important;
|
||||
border-bottom: none;
|
||||
}
|
||||
&:hover {
|
||||
td {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-placeholder {
|
||||
background-color: #061214;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
&-selected {
|
||||
background-color: 0d4e5c;
|
||||
}
|
||||
}
|
||||
.ant-table-pagination {
|
||||
float: none !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// 表单样式
|
||||
.ant-form {
|
||||
&-item {
|
||||
&-label {
|
||||
|
@ -39,24 +73,28 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@formInputBgColor: #03353f;
|
||||
@formInputBorderColor: #0b8c82;
|
||||
// 输入框样式
|
||||
.ant-input {
|
||||
background-color: @formInputBgColor;
|
||||
border-color: @formInputBorderColor;
|
||||
background-color: @formInputBgColor !important;
|
||||
border-color: @formInputBorderColor !important;
|
||||
border-radius: 0;
|
||||
color: #fff;
|
||||
&::placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
// 下拉框样式
|
||||
.ant-select {
|
||||
&-selection {
|
||||
background-color: @formInputBgColor;
|
||||
border-color: @formInputBorderColor;
|
||||
color: #fff !important;
|
||||
&-selection {
|
||||
background-color: @formInputBgColor !important;
|
||||
border-color: @formInputBorderColor !important;
|
||||
border-radius: 0;
|
||||
&__placeholder {
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,12 +103,126 @@
|
|||
&-menu {
|
||||
&-item {
|
||||
color: #fff;
|
||||
&:hover,
|
||||
background-color: #02282b;
|
||||
&:not(&-disabled):hover,
|
||||
&-selected,
|
||||
&-active {
|
||||
background-color: #0CECCA !important;
|
||||
background-color: #08363c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 树形下拉样式
|
||||
.ant-select-tree {
|
||||
color: #fff !important;
|
||||
.ant-select-tree-node-content-wrapper {
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮
|
||||
.ant-btn {
|
||||
border-radius: 0;
|
||||
font-family: Arial;
|
||||
span {
|
||||
text-shadow: 0px 1px 0px #000;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态
|
||||
.ant-empty {
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
&,
|
||||
&-item a {
|
||||
color: #ade6ee;
|
||||
}
|
||||
|
||||
&-item {
|
||||
width: 26px;
|
||||
height: 26px !important;
|
||||
line-height: 26px !important;
|
||||
border-radius: 50%;
|
||||
&-active {
|
||||
background-color: #00bded;
|
||||
a {
|
||||
color: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pagination-item-link {
|
||||
color: #00bded;
|
||||
}
|
||||
&-disabled {
|
||||
.ant-pagination-item-link {
|
||||
color: #9ca2a6;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-select {
|
||||
&-selection {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
background-color: transparent !important;
|
||||
color: #ade6ee;
|
||||
&-selected-value {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
.ant-select-arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.ant-select-selection__rendered::after {
|
||||
content: '';
|
||||
margin-left: 18px;
|
||||
border: 6px solid transparent;
|
||||
border-top-width: 8px;
|
||||
border-bottom-width: 8px;
|
||||
border-top-color: #00bded;
|
||||
visibility: visible;
|
||||
transform: translateY(8px);
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
transform-origin: 50% 25%;
|
||||
}
|
||||
&-open {
|
||||
.ant-select-selection__rendered::after {
|
||||
transform: translateY(6px) rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-options {
|
||||
&-quick-jumper {
|
||||
input {
|
||||
background-color: #011927;
|
||||
border: 1px solid #00cbfe;
|
||||
width: 70px !important;
|
||||
border-radius: 0;
|
||||
color: #ade6ee;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动条
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #011b1f;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #007f9a;
|
||||
}
|
||||
|
|
|
@ -1,129 +1,48 @@
|
|||
<template>
|
||||
<a-card :bordered="false">
|
||||
|
||||
<!-- 查询区域 -->
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
|
||||
<a-col :md="6" :sm="12">
|
||||
<a-form-item label="账号">
|
||||
<!--<a-input placeholder="请输入账号查询" v-model="queryParam.username"></a-input>-->
|
||||
<j-input placeholder="输入账号模糊查询" v-model="queryParam.username"></j-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item label="性别">
|
||||
<a-select v-model="queryParam.sex" placeholder="请选择性别">
|
||||
<a-select-option value="">请选择</a-select-option>
|
||||
<a-select-option value="1">男</a-select-option>
|
||||
<a-select-option value="2">女</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
|
||||
<template v-if="toggleSearchStatus">
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item label="真实名字">
|
||||
<a-input placeholder="请输入真实名字" v-model="queryParam.realname"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item label="手机号码">
|
||||
<a-input placeholder="请输入手机号码查询" v-model="queryParam.phone"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :md="6" :sm="8">
|
||||
<a-form-item label="用户状态">
|
||||
<a-select v-model="queryParam.status" placeholder="请选择">
|
||||
<a-select-option value="">请选择</a-select-option>
|
||||
<a-select-option value="1">正常</a-select-option>
|
||||
<a-select-option value="2">冻结</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
|
||||
<a-col :md="6" :sm="8">
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
|
||||
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
|
||||
</a>
|
||||
</span>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<div class="table-operator" style="border-top: 5px">
|
||||
<a-button @click="handleAdd" type="primary" icon="plus" >添加用户</a-button>
|
||||
<a-button type="primary" icon="download" @click="handleExportXls('用户信息')">导出</a-button>
|
||||
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
|
||||
<a-button type="primary" icon="import">导入</a-button>
|
||||
</a-upload>
|
||||
<j-third-app-button biz-type="user" :selected-row-keys="selectedRowKeys" syncToApp syncToLocal @sync-finally="onSyncFinally"/>
|
||||
<a-button type="primary" icon="hdd" @click="recycleBinVisible=true">回收站</a-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<a-menu slot="overlay" @click="handleMenuClick">
|
||||
<a-menu-item key="1">
|
||||
<a-icon type="delete" @click="batchDel"/>
|
||||
删除
|
||||
</a-menu-item>
|
||||
<a-menu-item key="2">
|
||||
<a-icon type="lock" @click="batchFrozen('2')"/>
|
||||
冻结
|
||||
</a-menu-item>
|
||||
<a-menu-item key="3">
|
||||
<a-icon type="unlock" @click="batchFrozen('1')"/>
|
||||
解冻
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
<a-button style="margin-left: 8px">
|
||||
批量操作
|
||||
<a-icon type="down"/>
|
||||
<search-form :items="formItems" v-model="queryParam" @search="searchQuery">
|
||||
<a-space style="float: right" class="btn-group" slot="additional">
|
||||
<a-button @click="handleAdd" type="primary">
|
||||
<img src="@/assets/images/global/add.png" alt="" />
|
||||
Add
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<j-super-query :fieldList="superQueryFieldList" @handleSuperQuery="handleSuperQuery"/>
|
||||
</div>
|
||||
<a-button @click="handleAdd" type="primary">
|
||||
<img src="@/assets/images/global/edit.png" alt="" />
|
||||
Edit
|
||||
</a-button>
|
||||
<a-button @click="handleAdd" type="primary">
|
||||
<img src="@/assets/images/global/delete.png" alt="" />
|
||||
Delete
|
||||
</a-button>
|
||||
<a-button @click="handleAdd" type="primary">
|
||||
<img src="@/assets/images/global/reset-pwd.png" alt="" />
|
||||
Reset pwd
|
||||
</a-button>
|
||||
</a-space>
|
||||
</search-form>
|
||||
|
||||
<!-- table区域-begin -->
|
||||
<div>
|
||||
<a-table
|
||||
ref="table"
|
||||
bordered
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:loading="loading"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
@change="handleTableChange">
|
||||
|
||||
<template slot="avatarslot" slot-scope="text, record, index">
|
||||
<div class="anty-img-wrap">
|
||||
<a-avatar shape="square" :src="getAvatarView(record.avatar)" icon="user"/>
|
||||
</div>
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<template slot="index" slot-scope="text, record, index">
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="handleEdit(record)" >编辑</a>
|
||||
<a @click="handleEdit(record)">编辑</a>
|
||||
|
||||
<a-divider type="vertical" />
|
||||
|
||||
<a-dropdown>
|
||||
<a class="ant-dropdown-link">
|
||||
更多 <a-icon type="down"/>
|
||||
</a>
|
||||
<a class="ant-dropdown-link"> 更多 <a-icon type="down" /> </a>
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item>
|
||||
<a href="javascript:;" @click="handleDetail(record)">详情</a>
|
||||
|
@ -139,249 +58,122 @@
|
|||
</a-popconfirm>
|
||||
</a-menu-item>
|
||||
|
||||
<a-menu-item v-if="record.status==1">
|
||||
<a-popconfirm title="确定冻结吗?" @confirm="() => handleFrozen(record.id,2,record.username)">
|
||||
<a-menu-item v-if="record.status == 1">
|
||||
<a-popconfirm title="确定冻结吗?" @confirm="() => handleFrozen(record.id, 2, record.username)">
|
||||
<a>冻结</a>
|
||||
</a-popconfirm>
|
||||
</a-menu-item>
|
||||
|
||||
<a-menu-item v-if="record.status==2">
|
||||
<a-popconfirm title="确定解冻吗?" @confirm="() => handleFrozen(record.id,1,record.username)">
|
||||
<a-menu-item v-if="record.status == 2">
|
||||
<a-popconfirm title="确定解冻吗?" @confirm="() => handleFrozen(record.id, 1, record.username)">
|
||||
<a>解冻</a>
|
||||
</a-popconfirm>
|
||||
</a-menu-item>
|
||||
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
</span>
|
||||
|
||||
|
||||
</a-table>
|
||||
</div>
|
||||
<!-- table区域-end -->
|
||||
|
||||
<user-modal ref="modalForm" @ok="modalFormOk"></user-modal>
|
||||
|
||||
<password-modal ref="passwordmodal" @ok="passwordModalOk"></password-modal>
|
||||
|
||||
<sys-user-agent-modal ref="sysUserAgentModal"></sys-user-agent-modal>
|
||||
|
||||
<!-- 用户回收站 -->
|
||||
<user-recycle-bin-modal :visible.sync="recycleBinVisible" @ok="modalFormOk"/>
|
||||
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserModal from './modules/UserModal'
|
||||
import PasswordModal from './modules/PasswordModal'
|
||||
import {putAction,getFileAccessHttpUrl} from '@/api/manage';
|
||||
import {frozenBatch} from '@/api/api'
|
||||
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
|
||||
import SysUserAgentModal from "./modules/SysUserAgentModal";
|
||||
import JInput from '@/components/jeecg/JInput'
|
||||
import UserRecycleBinModal from './modules/UserRecycleBinModal'
|
||||
import JSuperQuery from '@/components/jeecg/JSuperQuery'
|
||||
import JThirdAppButton from '@/components/jeecgbiz/thirdApp/JThirdAppButton'
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import SearchForm from '@/components/SearchForm'
|
||||
|
||||
export default {
|
||||
name: "UserList",
|
||||
mixins: [JeecgListMixin],
|
||||
components: {
|
||||
JThirdAppButton,
|
||||
SysUserAgentModal,
|
||||
UserModal,
|
||||
PasswordModal,
|
||||
JInput,
|
||||
UserRecycleBinModal,
|
||||
JSuperQuery
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
description: '这是用户管理页面',
|
||||
queryParam: {},
|
||||
recycleBinVisible: false,
|
||||
columns: [
|
||||
/*{
|
||||
title: '#',
|
||||
dataIndex: '',
|
||||
key:'rowIndex',
|
||||
width:60,
|
||||
align:"center",
|
||||
customRender:function (t,r,index) {
|
||||
return parseInt(index)+1;
|
||||
}
|
||||
},*/
|
||||
{
|
||||
title: '用户账号',
|
||||
align: "center",
|
||||
dataIndex: 'username',
|
||||
width: 120,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
align: "center",
|
||||
width: 100,
|
||||
dataIndex: 'realname',
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
align: "center",
|
||||
width: 120,
|
||||
dataIndex: 'avatar',
|
||||
scopedSlots: {customRender: "avatarslot"}
|
||||
},
|
||||
|
||||
{
|
||||
title: '性别',
|
||||
align: "center",
|
||||
width: 80,
|
||||
dataIndex: 'sex_dictText',
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
title: '生日',
|
||||
align: "center",
|
||||
width: 100,
|
||||
dataIndex: 'birthday'
|
||||
},
|
||||
{
|
||||
title: '手机号码',
|
||||
align: "center",
|
||||
width: 100,
|
||||
dataIndex: 'phone'
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
align: "center",
|
||||
width: 180,
|
||||
dataIndex: 'orgCodeTxt'
|
||||
},
|
||||
{
|
||||
title: '负责部门',
|
||||
align: "center",
|
||||
width: 180,
|
||||
dataIndex: 'departIds_dictText'
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
align: "center",
|
||||
width: 80,
|
||||
dataIndex: 'status_dictText'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
scopedSlots: {customRender: 'action'},
|
||||
align: "center",
|
||||
width: 170
|
||||
}
|
||||
|
||||
],
|
||||
superQueryFieldList: [
|
||||
{ type: 'input', value: 'username', text: '用户账号', },
|
||||
{ type: 'input', value: 'realname', text: '用户姓名', },
|
||||
{ type: 'select', value: 'sex', dbType: 'int', text: '性别', dictCode: 'sex' },
|
||||
],
|
||||
url: {
|
||||
syncUser: "/act/process/extActProcess/doSyncUser",
|
||||
list: "/sys/user/list",
|
||||
delete: "/sys/user/delete",
|
||||
deleteBatch: "/sys/user/deleteBatch",
|
||||
exportXlsUrl: "/sys/user/exportXls",
|
||||
importExcelUrl: "sys/user/importExcel",
|
||||
const formItems = [
|
||||
{
|
||||
type: 'a-input',
|
||||
label: 'User',
|
||||
name: 'username',
|
||||
span: 4
|
||||
},
|
||||
{
|
||||
type: 'a-input',
|
||||
label: 'Name',
|
||||
name: 'realname',
|
||||
span: 4
|
||||
},
|
||||
{
|
||||
type: 'custom-select',
|
||||
label: 'Role',
|
||||
name: 'role',
|
||||
span: 4,
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
label: 'test',
|
||||
value: '1'
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
importExcelUrl: function(){
|
||||
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAvatarView: function (avatar) {
|
||||
return getFileAccessHttpUrl(avatar)
|
||||
},
|
||||
|
||||
batchFrozen: function (status) {
|
||||
if (this.selectedRowKeys.length <= 0) {
|
||||
this.$message.warning('请选择一条记录!');
|
||||
return false;
|
||||
} else {
|
||||
let ids = "";
|
||||
let that = this;
|
||||
let isAdmin = false;
|
||||
that.selectionRows.forEach(function (row) {
|
||||
if (row.username == 'admin') {
|
||||
isAdmin = true;
|
||||
}
|
||||
});
|
||||
if (isAdmin) {
|
||||
that.$message.warning('管理员账号不允许此操作,请重新选择!');
|
||||
return;
|
||||
}
|
||||
that.selectedRowKeys.forEach(function (val) {
|
||||
ids += val + ",";
|
||||
});
|
||||
that.$confirm({
|
||||
title: "确认操作",
|
||||
content: "是否" + (status == 1 ? "解冻" : "冻结") + "选中账号?",
|
||||
onOk: function () {
|
||||
frozenBatch({ids: ids, status: status}).then((res) => {
|
||||
if (res.success) {
|
||||
that.$message.success(res.message);
|
||||
that.loadData();
|
||||
that.onClearSelected();
|
||||
} else {
|
||||
that.$message.warning(res.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
{
|
||||
label: 'test2',
|
||||
value: '2'
|
||||
}
|
||||
},
|
||||
handleMenuClick(e) {
|
||||
if (e.key == 1) {
|
||||
this.batchDel();
|
||||
} else if (e.key == 2) {
|
||||
this.batchFrozen(2);
|
||||
} else if (e.key == 3) {
|
||||
this.batchFrozen(1);
|
||||
}
|
||||
},
|
||||
handleFrozen: function (id, status, username) {
|
||||
let that = this;
|
||||
//TODO 后台校验管理员角色
|
||||
if ('admin' == username) {
|
||||
that.$message.warning('管理员账号不允许此操作!');
|
||||
return;
|
||||
}
|
||||
frozenBatch({ids: id, status: status}).then((res) => {
|
||||
if (res.success) {
|
||||
that.$message.success(res.message);
|
||||
that.loadData();
|
||||
} else {
|
||||
that.$message.warning(res.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleChangePassword(username) {
|
||||
this.$refs.passwordmodal.show(username);
|
||||
},
|
||||
passwordModalOk() {
|
||||
//TODO 密码修改完成 不需要刷新页面,可以把datasource中的数据更新一下
|
||||
},
|
||||
onSyncFinally({isToLocal}) {
|
||||
// 同步到本地时刷新下数据
|
||||
if (isToLocal) {
|
||||
this.loadData()
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'UserList',
|
||||
mixins: [JeecgListMixin],
|
||||
components: {
|
||||
SearchForm
|
||||
},
|
||||
data() {
|
||||
this.formItems = formItems
|
||||
return {
|
||||
queryParam: {},
|
||||
columns: [
|
||||
{
|
||||
title: 'NO',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'index'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'USER',
|
||||
align: 'center',
|
||||
dataIndex: 'username',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: 'NAME',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
dataIndex: 'realname'
|
||||
},
|
||||
{
|
||||
title: 'ROLE',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
dataIndex: 'roleCode'
|
||||
},
|
||||
{
|
||||
title: 'PHONE',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
dataIndex: 'phone'
|
||||
}
|
||||
],
|
||||
url: {
|
||||
list: '/sys/user/list',
|
||||
delete: '/sys/user/delete'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
@import '~@assets/less/common.less'
|
||||
</style>
|
||||
<style scoped lang="less">
|
||||
@import '~@assets/less/common.less';
|
||||
.btn-group {
|
||||
img {
|
||||
margin-right: 12px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|