fix: 用户管理样式优化

This commit is contained in:
dataeaseShu 2022-07-26 18:03:31 +08:00
parent 052bf58292
commit 249ed7f257
6 changed files with 281 additions and 126 deletions

View File

@ -59,7 +59,7 @@ export default {
paginationEvent: {}, paginationEvent: {},
paginationDefalut: { paginationDefalut: {
currentPage: 1, currentPage: 1,
pageSizes: [10, 20, 30, 40], pageSizes: [10, 20, 50, 100],
pageSize: 10, pageSize: 10,
layout: "total, prev, pager, next, sizes, jumper", layout: "total, prev, pager, next, sizes, jumper",
total: 0, total: 0,

View File

@ -75,24 +75,17 @@ const closePress = {
} }
} }
// const btnPress = { const btnPress = {
// inserted: function (el) { update: function (el, binding) {
// el.onmousedown = function () { el.onmousedown = function (e) {
// el.style.background = '#EFF0F1'; e.currentTarget.style.setProperty('background', binding.value || '#EFF0F1', 'important');
// } }
// el.onmouseenter = function () { el.onmouseup = function (e) {
// el.style.background = '#F5F6F7 !important'; e.currentTarget.style.background = 'none';
// } }
// el.onmouseleave = function () { },
// el.style.background = 'none'; }
// }
// el.onmouseup = function () {
// el.style.background = 'none';
// }
// }
// }
// #EFF0F1
export default { export default {
install(Vue) { install(Vue) {
@ -102,7 +95,7 @@ export default {
Vue.directive('right-to-left-drag', right2LeftDrag) Vue.directive('right-to-left-drag', right2LeftDrag)
Vue.directive('bottom-to-top-drag', bottom2TopDrag) Vue.directive('bottom-to-top-drag', bottom2TopDrag)
Vue.directive('closePress', closePress) Vue.directive('closePress', closePress)
// Vue.directive('btnPress', btnPress) Vue.directive('btnPress', btnPress)
} }
} }

View File

@ -853,3 +853,21 @@ div:focus {
.view-select-option { .view-select-option {
display: none !important; display: none !important;
} }
.el-checkbox__input.is-checked + .el-checkbox__label {
color: #1F2329 !important;
}
.el-dialog__title {
font-weight: 500;
}
.el-tabs__nav-wrap::after {
height: 1px !important;
background-color: rgba(31, 35, 41, 0.15) !important;
}
.el-tabs__item:not(.is-active) {
font-weight: 400 !important;
}

View File

@ -391,9 +391,4 @@ export default {
float: right; float: right;
margin-right: 45px; margin-right: 45px;
} }
::v-deep .el-tabs__nav-wrap::after,
::v-deep .el-tabs__active-bar {
height: 1px !important;
}
</style> </style>

View File

@ -11,6 +11,7 @@
<span>状态</span> <span>状态</span>
<div class="filter-item"> <div class="filter-item">
<span <span
class="item"
@click="statusChange(ele.id)" @click="statusChange(ele.id)"
:class="[activeStatus.includes(ele.id) ? 'active' : '']" :class="[activeStatus.includes(ele.id) ? 'active' : '']"
:key="ele.id" :key="ele.id"
@ -22,6 +23,7 @@
<span>组织</span> <span>组织</span>
<div class="filter-item"> <div class="filter-item">
<span <span
class="item"
@click="activeDeptChange(ele.id)" @click="activeDeptChange(ele.id)"
:class="[activeDept.includes(ele.id) ? 'active' : '']" :class="[activeDept.includes(ele.id) ? 'active' : '']"
:key="ele.id" :key="ele.id"
@ -65,7 +67,7 @@
/> />
</el-select> </el-select>
</el-popover> </el-popover>
<span slot="reference">+ 更多</span> <span class="more" slot="reference">+ 更多</span>
</el-popover> </el-popover>
</div> </div>
</div> </div>
@ -74,6 +76,7 @@
<div class="filter-item"> <div class="filter-item">
<span <span
@click="activeRoleChange(ele.id)" @click="activeRoleChange(ele.id)"
class="item"
:class="[activeRole.includes(ele.id) ? 'active' : '']" :class="[activeRole.includes(ele.id) ? 'active' : '']"
:key="ele.id" :key="ele.id"
v-for="ele in rolesValueCopy" v-for="ele in rolesValueCopy"
@ -101,8 +104,7 @@
:value="item" :value="item"
/> />
</el-select> </el-select>
<span class="more" slot="reference">+ 更多</span>
<span slot="reference">+ 更多</span>
</el-popover> </el-popover>
</div> </div>
</div> </div>
@ -128,6 +130,7 @@ export default {
roleCahe: [], roleCahe: [],
deptCahe: [], deptCahe: [],
roles: [], roles: [],
filterTextMap: [],
status: [{ status: [{
id: 1, id: 1,
label: '启用' label: '启用'
@ -165,6 +168,17 @@ export default {
this.initRoles(); this.initRoles();
}, },
methods: { methods: {
clearFilter() {
Array(3).fill(1).forEach((_, index) => {
this.clearOneFilter(index)
})
this.$emit('search', [], [])
},
clearOneFilter(index) {
(this.filterTextMap[index] || []).forEach(ele => {
this[ele] = []
})
},
// //
treeByDeptId() { treeByDeptId() {
treeByDeptId(0).then((res) => { treeByDeptId(0).then((res) => {
@ -259,16 +273,20 @@ export default {
this.$emit('search', this.formatCondition(), this.formatText()) this.$emit('search', this.formatCondition(), this.formatText())
}, },
formatText() { formatText() {
this.filterTextMap = [];
const params = []; const params = [];
if (this.activeStatus.length) { if (this.activeStatus.length) {
let str = `状态:${this.activeStatus.reduce((pre,next) => (this.status.find(ele => ele.id === next) || {}).label + '、' + pre, '')}`; let str = `状态:${this.activeStatus.reduce((pre,next) => (this.status.find(ele => ele.id === next) || {}).label + '、' + pre, '')}`;
params.push(str.slice(0, str.length - 1 )) params.push(str.slice(0, str.length - 1 ))
this.filterTextMap.push(['activeStatus'])
} }
if (this.activeDept.length) { if (this.activeDept.length) {
params.push(`组织:${this.selectDeptsCahe.reduce((pre,next) => pre.label + '、' + next.label)}`) params.push(`组织:${this.selectDeptsCahe.map(ele => ele.label).join('、')}`)
this.filterTextMap.push(['activeDept', 'selectDepts', 'selectDeptsCahe', 'deptCahe'])
} }
if (this.activeRole.length) { if (this.activeRole.length) {
params.push(`角色:${this.rolesValueCopy.reduce((pre,next) => pre.label + '、' + next.labele)}`) params.push(`角色:${this.rolesValueCopy.map(ele => ele.name).join('、')}`)
this.filterTextMap.push(['rolesValue', 'activeRole', 'roleCahe'])
} }
return params; return params;
}, },
@ -290,10 +308,8 @@ export default {
this.userDrawer = true; this.userDrawer = true;
}, },
reset() { reset() {
this.activeStatus = []; this.userDrawer = false;
this.activeRole = []; this.clearFilter()
this.activeDept = [];
this.search()
}, },
}, },
}; };
@ -349,8 +365,10 @@ export default {
font-size: 14px; font-size: 14px;
} }
.filter-item { .filter-item {
span { .item,
.more {
font-family: PingFang SC; font-family: PingFang SC;
white-space: nowrap;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
@ -360,20 +378,16 @@ export default {
background: #f5f6f7; background: #f5f6f7;
border-radius: 2px; border-radius: 2px;
cursor: pointer; cursor: pointer;
span {
margin-right: 0;
padding: 0;
span {
margin-right: 0;
padding: 0;
}
}
} }
.active { .active,
.more:hover{
background: rgba(51, 112, 255, 0.1); background: rgba(51, 112, 255, 0.1);
color: #0c296e; color: #0c296e;
} }
.more {
white-space: nowrap;
}
} }
} }
.btn { .btn {

View File

@ -26,15 +26,16 @@
</el-input> </el-input>
<el-button <el-button
class="normal btn" class="normal btn"
v-btnPress="filterColor"
:class="[filterTexts.length ? 'active-btn filter-not-null' : 'filter-zero']"
icon="iconfont icon-icon-filter" icon="iconfont icon-icon-filter"
@click="filterShow" @click="filterShow"
>筛选<template v-if="filterTexts.length"> >筛选<template v-if="filterTexts.length">
({{ filterTexts.length }}) ({{ filterTexts.length }})
</template> </template>
</el-button </el-button>
>
<el-dropdown trigger="click" :hide-on-click="false"> <el-dropdown trigger="click" :hide-on-click="false">
<el-button class="normal btn" icon="el-icon-setting" <el-button v-btnPress class="normal btn filter-zero" icon="el-icon-setting"
>列表项</el-button >列表项</el-button
> >
<el-dropdown-menu class="list-colums-slect" slot="dropdown"> <el-dropdown-menu class="list-colums-slect" slot="dropdown">
@ -49,9 +50,12 @@
v-model="checkedColumnNames" v-model="checkedColumnNames"
@change="handleCheckedColumnNamesChange" @change="handleCheckedColumnNamesChange"
> >
<el-checkbox v-for="column in columnNames" :label="column.props" :key="column.props">{{ <el-checkbox
$t(column.label) v-for="column in columnNames"
}}</el-checkbox> :label="column.props"
:key="column.props"
>{{ $t(column.label) }}</el-checkbox
>
</el-checkbox-group> </el-checkbox-group>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
@ -61,14 +65,25 @@
<span class="sum">{{ paginationConfig.total }}</span> <span class="sum">{{ paginationConfig.total }}</span>
<span class="title">个结果</span> <span class="title">个结果</span>
<el-divider direction="vertical"></el-divider> <el-divider direction="vertical"></el-divider>
<p class="text" v-for="ele in filterTexts" :key="ele">{{ ele }} <i class="el-icon-close"></i></p> <i @click="scrollPre" v-if="showScroll" class="el-icon-arrow-left arrow-filter"></i>
<div class="filter-texts-container">
<p class="text" v-for="(ele, index) in filterTexts" :key="ele">
{{ ele }} <i @click="clearOneFilter(index)" class="el-icon-close"></i>
</p>
</div>
<i @click="scrollNext" v-if="showScroll" class="el-icon-arrow-right arrow-filter"></i>
<el-button <el-button
type="text" type="text"
class="clear-btn"
icon="el-icon-delete" icon="el-icon-delete"
@click="clearFilter" @click="clearFilter"
>{{ $t("user.create") }}</el-button> >清空条件</el-button
>
</div> </div>
<div class="table-container" :class="[filterTexts.length ? 'table-container-filter' : '']"> <div
class="table-container"
:class="[filterTexts.length ? 'table-container-filter' : '']"
>
<grid-table <grid-table
v-if="canLoadDom" v-if="canLoadDom"
v-loading="$store.getters.loadingMap[$store.getters.currentPath]" v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
@ -117,7 +132,7 @@
:label="$t('commons.organization')" :label="$t('commons.organization')"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<div>{{ scope.row.dept && scope.row.dept.deptName || "-" }}</div> <div>{{ (scope.row.dept && scope.row.dept.deptName) || "-" }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -160,12 +175,17 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column slot="__operation" label="操作" fixed="right" width="168"> <el-table-column
slot="__operation"
label="操作"
fixed="right"
width="168"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
v-permission="['user:edit']" v-permission="['user:edit']"
@click="edit(scope.row)" @click="edit(scope.row)"
class="text-btn" class="text-btn mr2"
type="text" type="text"
>{{ $t("commons.edit") }}</el-button >{{ $t("commons.edit") }}</el-button
> >
@ -196,16 +216,18 @@
<!-- <el-button class="btn normal">{{ <!-- <el-button class="btn normal">{{
$t("fu.search_bar.cancel") $t("fu.search_bar.cancel")
}}</el-button> --> }}</el-button> -->
<el-button @click="resetPwd(scope.row.userId)" type="primary" class="btn">{{ <el-button
$t("fu.search_bar.ok") @click="resetPwd(scope.row.userId)"
}}</el-button> type="primary"
class="btn"
>{{ $t("fu.search_bar.ok") }}</el-button
>
</div> </div>
<el-button <el-button
slot="reference" slot="reference"
v-permission="['user:editPwd']" v-permission="['user:editPwd']"
class="text-btn mar16" class="text-btn mar16"
@click="editPassword(scope.row)"
type="text" type="text"
>{{ $t("member.edit_password") }}</el-button >{{ $t("member.edit_password") }}</el-button
> >
@ -229,37 +251,43 @@
</template> </template>
<script> <script>
import userEditer from './userEditer.vue' import userEditer from "./userEditer.vue";
const columnOptions = [{ const columnOptions = [
label: 'ID', {
props: 'username' label: "ID",
},{ props: "username",
label: 'commons.nick_name', },
props: 'nickName' {
},{ label: "commons.nick_name",
label: 'user.source', props: "nickName",
props: 'from' },
},{ {
label: 'commons.email', label: "user.source",
props: 'email' props: "from",
},{ },
label: 'commons.organization', {
props: 'dept' label: "commons.email",
},{ props: "email",
label: 'commons.role', },
props: 'roles' {
},{ label: "commons.organization",
label: 'commons.status', props: "dept",
props: 'status' },
},{ {
label: 'commons.create_time', label: "commons.role",
props: 'createTime' props: "roles",
},]; },
{
label: "commons.status",
props: "status",
},
{
label: "commons.create_time",
props: "createTime",
},
];
import DeLayoutContent from "@/components/business/DeLayoutContent"; import DeLayoutContent from "@/components/business/DeLayoutContent";
import { import { addOrder, formatOrders } from "@/utils/index";
addOrder,
formatOrders,
} from "@/utils/index";
import { pluginLoaded, defaultPwd } from "@/api/user"; import { pluginLoaded, defaultPwd } from "@/api/user";
/* import { ldapStatus, pluginLoaded } from '@/api/user' */ /* import { ldapStatus, pluginLoaded } from '@/api/user' */
import { import {
@ -277,7 +305,7 @@ export default {
data() { data() {
return { return {
checkAll: true, checkAll: true,
checkedColumnNames: columnOptions.map(ele => ele.props), checkedColumnNames: columnOptions.map((ele) => ele.props),
columnNames: columnOptions, columnNames: columnOptions,
isIndeterminate: false, isIndeterminate: false,
paginationConfig: { paginationConfig: {
@ -320,15 +348,27 @@ export default {
isPluginLoaded: false, isPluginLoaded: false,
defaultPWD: "DataEase123..", defaultPWD: "DataEase123..",
canLoadDom: false, canLoadDom: false,
showScroll: false,
}; };
}, },
computed: { computed: {
...mapGetters(["user"]), ...mapGetters(["user"]),
filterColor() {
return this.filterTexts.length ? 'rgba(51, 112, 255, 0.15)' : '#EFF0F1'
}
},
watch: {
filterTexts: {
handler() {
this.getScrollStatus();
},
deep: true,
},
}, },
mounted() { mounted() {
this.allRoles(); this.allRoles();
this.search(); this.search();
document.addEventListener('keypress', this.entryKey) document.addEventListener("keypress", this.entryKey);
}, },
beforeCreate() { beforeCreate() {
pluginLoaded() pluginLoaded()
@ -349,20 +389,39 @@ export default {
}); });
}, },
destroyed() { destroyed() {
document.removeEventListener('keypress', this.entryKey) document.removeEventListener("keypress", this.entryKey);
}, },
methods: { methods: {
scrollPre() {
const dom = document.querySelector('.filter-texts-container');
dom.scrollLeft -= 10
if (dom.scrollLeft <= 0) {
dom.scrollLeft = 0
}
},
scrollNext() {
const dom = document.querySelector('.filter-texts-container');
dom.scrollLeft += 10
const width = dom.scrollWidth - dom.offsetWidth
if (dom.scrollLeft > width) {
dom.scrollLeft = width
}
},
clearFilter() { clearFilter() {
this.$refs.filterUser.clearFilter();
},
clearOneFilter(index) {
this.$refs.filterUser.clearOneFilter(index);
this.$refs.filterUser.search();
}, },
entryKey(event) { entryKey(event) {
const keyCode = event.keyCode const keyCode = event.keyCode;
if (keyCode === 13) { if (keyCode === 13) {
this.$refs.search.blur() this.$refs.search.blur();
} }
}, },
filterRoles(row, column, cellValue) { filterRoles(row, column, cellValue) {
const roleNames = cellValue.map(ele => ele.roleName); const roleNames = cellValue.map((ele) => ele.roleName);
return roleNames.length ? roleNames.join() : "-"; return roleNames.length ? roleNames.join() : "-";
}, },
initSearch() { initSearch() {
@ -372,7 +431,9 @@ export default {
this.$refs.filterUser.init(); this.$refs.filterUser.init();
}, },
handleCheckAllChange(val) { handleCheckAllChange(val) {
this.checkedColumnNames = val ? columnOptions.map(ele => ele.props) : []; this.checkedColumnNames = val
? columnOptions.map((ele) => ele.props)
: [];
this.isIndeterminate = false; this.isIndeterminate = false;
}, },
handleCheckedColumnNamesChange(value) { handleCheckedColumnNamesChange(value) {
@ -382,11 +443,13 @@ export default {
checkedCount > 0 && checkedCount < this.columnNames.length; checkedCount > 0 && checkedCount < this.columnNames.length;
}, },
resetPwd(userId) { resetPwd(userId) {
editPassword({ userId, newPassword: this.defaultPWD }).then((res) => { editPassword({ userId, newPassword: this.defaultPWD })
.then((res) => {
this.$success(this.$t("commons.modify_success")); this.$success(this.$t("commons.modify_success"));
this.initSearch(); this.initSearch();
}).finally(() => { })
this.$refs['initPwd' + userId].doClose(); .finally(() => {
this.$refs["initPwd" + userId].doClose();
}); });
}, },
sortChange({ column, prop, order }) { sortChange({ column, prop, order }) {
@ -420,7 +483,13 @@ export default {
filterDraw(condition, filterTexts = []) { filterDraw(condition, filterTexts = []) {
this.cacheCondition = condition; this.cacheCondition = condition;
this.filterTexts = filterTexts; this.filterTexts = filterTexts;
this.initSearch() this.initSearch();
},
getScrollStatus() {
this.$nextTick(() => {
const dom = document.querySelector(".filter-texts-container");
this.showScroll = dom && dom.scrollWidth > dom.offsetWidth;
});
}, },
search() { search() {
const param = { const param = {
@ -430,9 +499,9 @@ export default {
if (this.nikeName) { if (this.nikeName) {
param.conditions.push({ param.conditions.push({
field: `concat(nick_name, ',' , email)`, field: `concat(nick_name, ',' , email)`,
operator: 'like', operator: "like",
value: this.nikeName value: this.nikeName,
}) });
} }
const { currentPage, pageSize } = this.paginationConfig; const { currentPage, pageSize } = this.paginationConfig;
userLists(currentPage, pageSize, param).then((response) => { userLists(currentPage, pageSize, param).then((response) => {
@ -469,7 +538,9 @@ export default {
openMessageSuccess() { openMessageSuccess() {
const h = this.$createElement; const h = this.$createElement;
this.$message({ this.$message({
message: h("p", null, [h("span", null, this.$t("commons.delete_success"))]), message: h("p", null, [
h("span", null, this.$t("commons.delete_success")),
]),
iconClass: "el-icon-success", iconClass: "el-icon-success",
customClass: "de-message-success de-message", customClass: "de-message-success de-message",
}); });
@ -523,6 +594,10 @@ export default {
.mar16 { .mar16 {
margin: 0 -2px 0 4px; margin: 0 -2px 0 4px;
} }
.mr2 {
margin-left: -3px;
}
} }
.table-container-filter { .table-container-filter {
@ -532,11 +607,11 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 17px 0; margin: 17px 0;
font-family: 'PingFang SC'; font-family: "PingFang SC";
font-weight: 400; font-weight: 400;
.sum { .sum {
color: #1F2329;; color: #1f2329;
} }
.title { .title {
@ -550,9 +625,9 @@ export default {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
padding: 1px 22px 1px 6px; padding: 1px 22px 1px 6px;
display: flex; display: inline-block;
align-items: center; align-items: center;
color: #0C296E; color: #0c296e;
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
background: rgba(51, 112, 255, 0.1); background: rgba(51, 112, 255, 0.1);
@ -568,6 +643,45 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.clear-btn {
color: #646a73;
}
.clear-btn:hover {
color: #3370ff;
}
.filter-texts-container::-webkit-scrollbar { display: none; }
.arrow-filter {
font-size: 16px;
width: 24px;
height: 24px;
cursor: pointer;
color: #646A73;
display: flex;
justify-content: center;
align-items: center;
}
.arrow-filter:hover {
background: rgba(31, 35, 41, 0.1);
border-radius: 4px;
}
.el-icon-arrow-right.arrow-filter {
margin-left: 5px;
}
.el-icon-arrow-left.arrow-filter {
margin-right: 5px;
}
.filter-texts-container {
flex: 1;
overflow-x: auto;
white-space: nowrap;
height: 24px;
}
} }
.top-operate { .top-operate {
margin-bottom: 16px; margin-bottom: 16px;
@ -585,7 +699,6 @@ export default {
border: none; border: none;
box-sizing: border-box; box-sizing: border-box;
::v-deep span { ::v-deep span {
margin-left: 5px; margin-left: 5px;
} }
@ -597,6 +710,24 @@ export default {
margin-left: 12px; margin-left: 12px;
} }
.filter-not-null:focus {
background: rgba(51, 112, 255, 0.1);
}
.filter-not-null:hover {
background: rgba(51, 112, 255, 0.1) !important;
}
.filter-zero:focus {
background: #F5F6F7;
}
.filter-zero:hover {
background: #F5F6F7 !important;
}
.right-user { .right-user {
text-align: right; text-align: right;
display: flex; display: flex;
@ -614,6 +745,11 @@ export default {
border-color: #bbbfc4; border-color: #bbbfc4;
} }
} }
.active-btn {
border-color: #3370ff;
color: #3370ff;
}
} }
</style> </style>
<style lang="scss"> <style lang="scss">
@ -706,7 +842,7 @@ export default {
min-width: 20px !important; min-width: 20px !important;
padding: 16px 20px !important; padding: 16px 20px !important;
flex-direction: row; flex-direction: row;
box-shadow: 0px 4px 8px 0px #1F23291A; box-shadow: 0px 4px 8px 0px #1f23291a;
span { span {
font-family: PingFang SC; font-family: PingFang SC;
font-size: 14px; font-size: 14px;
@ -800,7 +936,6 @@ export default {
border: none; border: none;
color: #ffffff; color: #ffffff;
} }
} }
.de-confirm-fail { .de-confirm-fail {