Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
V
vue-quasar-admin-dev
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
吴超
vue-quasar-admin-dev
Commits
1ef65f87
Commit
1ef65f87
authored
Dec 25, 2025
by
周海峰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
no message
parent
169a1987
显示空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
498 行增加
和
123 行删除
+498
-123
src/components/organization-ant.vue
+498
-104
src/pages/permission/roleuser.vue
+0
-19
没有找到文件。
src/components/organization-ant.vue
View file @
1ef65f87
<
template
>
<
template
>
<div
style=
"padding:1vh;"
>
<div
style=
"padding:1vh;"
>
<div
v-show=
"getTreeData.length > 0"
>
<div
v-show=
"getTreeData.length > 0"
>
<div
class=
"search"
>
<div
class=
"search-container"
>
<q-input
v-model=
"searchText"
dense
outlined
@
input=
"onChange"
clearable
label=
"搜索(支持两字以上的名字搜索)"
/>
<div
class=
"search-wrapper"
>
<q-input
v-model=
"searchText"
clearable
class=
"search-input"
label=
"搜索(支持两字以上的名字搜索)"
placeholder=
"输入搜索并选择"
@
input=
"onSearchInput"
@
focus=
"showSearchMenu = true"
@
blur=
"hideSearchMenu"
>
<template
v-slot:prepend
>
<q-icon
name=
"search"
class=
"search-icon"
/>
</
template
>
<
template
v-slot:append
>
<q-btn
flat
dense
round
icon=
"search"
class=
"search-btn"
@
click=
"manualSearch"
/>
</
template
>
</q-input>
<!-- 搜索菜单 -->
<div
v-show=
"showSearchMenu"
class=
"search-menu"
>
<div
class=
"search-results"
v-if=
"searchOptions.length > 0"
>
<div
v-for=
"option in searchOptions"
:key=
"option.key"
class=
"search-result-item"
@
click=
"selectSearchOption(option)"
>
<div
class=
"search-result-avatar"
>
<q-icon
:name=
"option.type === 'department' ? 'business' : 'person'"
:color=
"option.type === 'department' ? 'primary' : 'positive'"
size=
"sm"
/>
</div>
<div
class=
"search-result-content"
>
<div
class=
"search-result-label"
>
{{ option.label }}
</div>
<div
class=
"search-result-caption"
>
{{ option.type === 'department' ? '部门' : '人员' }}
<span
v-if=
"option.key < 1000000 && option.key"
class=
"search-result-id"
>
ID: {{ option.key }}
</span>
</div>
</div>
<div
class=
"search-result-side"
>
<q-icon
name=
"chevron_right"
size=
"sm"
color=
"grey-5"
/>
</div>
</div>
</div>
<!-- 无搜索结果 -->
<div
v-else-if=
"searchText && searchText.length > 0"
class=
"no-results"
>
<div
class=
"no-result-item"
>
<div
class=
"no-result-avatar"
>
<q-icon
name=
"info"
color=
"grey-5"
size=
"sm"
/>
</div>
<div
class=
"no-result-content"
>
<div
class=
"no-results-text"
>
没有找到匹配的人员或部门
</div>
<div
class=
"no-results-hint"
>
请尝试其他关键词
</div>
</div>
</div>
</div>
</div>
</div>
<div
style=
"padding-top: 5vh"
>
</div>
</div>
<div
style=
"padding-top: 6vh"
>
<Tree
<Tree
v-if=
"getTreeData.length > 0"
v-if=
"getTreeData.length > 0"
ref=
"tree"
ref=
"tree"
v-model=
"selectedKeys"
checkable
:checkedKeys=
"checkedKeys"
@
expand=
"onExpand"
@
expand=
"onExpand"
:expandedKeys=
"expandedKeys"
:expandedKeys=
"expandedKeys"
:autoExpandParent=
"autoExpandParent"
:autoExpandParent=
"autoExpandParent"
:treeData=
"getTreeData"
:treeData=
"getTreeData"
:defaultExpandedKeys=
"defaultExpandedKeys"
:defaultExpandedKeys=
"defaultExpandedKeys"
@
select=
"onSelect"
@
check=
"onCheck"
@
check=
"onCheck"
@
select=
"onSelect"
>
>
<
template
slot=
"title"
slot-scope=
"node"
>
<
template
slot=
"title"
slot-scope=
"node"
>
<span
style=
"color: rgb(33, 186, 69);"
v-if=
"
getselectKeysStr
.indexOf(node.key)>-1"
>
√
</span>
<span
style=
"color: rgb(33, 186, 69);"
v-if=
"
checkedKeys
.indexOf(node.key)>-1"
>
√
</span>
<span
v-if=
"node.title.indexOf(searchValue) > -1"
>
<span
v-if=
"node.title.indexOf(searchValue) > -1"
>
{{
node
.
title
.
substr
(
0
,
node
.
title
.
indexOf
(
searchValue
))
}}
{{
node
.
title
.
substr
(
0
,
node
.
title
.
indexOf
(
searchValue
))
}}
<span
style=
"color: #f50"
>
{{
searchValue
}}
</span>
<span
style=
"color: #f50"
>
{{
searchValue
}}
</span>
...
@@ -96,18 +176,17 @@
...
@@ -96,18 +176,17 @@
expandedKeys
:
[
1000001
],
expandedKeys
:
[
1000001
],
defaultExpandedKeys
:
[
1000001
],
defaultExpandedKeys
:
[
1000001
],
autoExpandParent
:
true
,
autoExpandParent
:
true
,
//
v-model
//
复选模式下的选中key(包含部门和人员)
checkedKeys
:
[],
checkedKeys
:
[],
// 选择的key
selectedKeys
:
[],
selectedParent
:
[],
// 准备提交的选中的部门
// 准备提交的选中的部门
checkedDepartment
:
[],
checkedDepartment
:
[],
// 准备提交的选中的人类对象
// 准备提交的选中的人类对象
checkedPeople
:
[],
checkedPeople
:
[],
checkNodes
:
[],
// 节点缓存,用于快速查找
// 选中部门下的所有人
nodeCache
:
null
,
checkedPeopleWithDepartment
:
[]
// 搜索相关
searchOptions
:
[],
showSearchMenu
:
false
};
};
},
},
props
:
{
props
:
{
...
@@ -127,8 +206,7 @@
...
@@ -127,8 +206,7 @@
return
this
.
treeData
;
return
this
.
treeData
;
},
},
getselectKeysStr
(){
getselectKeysStr
(){
// alert(this.selectedKeys.map(item=>item).join(","))
return
this
.
checkedKeys
.
map
(
item
=>
item
).
join
(
","
)
return
this
.
selectedKeys
.
map
(
item
=>
item
).
join
(
","
)
}
}
},
},
created
()
{
created
()
{
...
@@ -143,6 +221,10 @@
...
@@ -143,6 +221,10 @@
let
resdata
=
Res
.
data
.
data
;
let
resdata
=
Res
.
data
.
data
;
this
.
treeData
.
push
(
resdata
)
this
.
treeData
.
push
(
resdata
)
generateList
(
this
.
treeData
);
generateList
(
this
.
treeData
);
// 构建节点缓存
this
.
nodeCache
=
new
Map
();
this
.
buildNodeCache
(
this
.
treeData
);
},
},
onExpand
(
expandedKeys
)
{
onExpand
(
expandedKeys
)
{
// console.log('onExpand', expandedKeys)
// console.log('onExpand', expandedKeys)
...
@@ -151,87 +233,194 @@
...
@@ -151,87 +233,194 @@
this
.
expandedKeys
=
expandedKeys
this
.
expandedKeys
=
expandedKeys
this
.
autoExpandParent
=
false
this
.
autoExpandParent
=
false
},
},
onCheck
(
checkedKeys
)
{
onCheck
(
checkedKeys
,
e
)
{
// console.log('onCheck', checkedKeys)
console
.
log
(
'onCheck'
,
checkedKeys
,
e
);
// this.checkedKeys = checkedKeys
let
finalCheckedKeys
=
[...
checkedKeys
];
// 当勾选父节点时,自动勾选所有叶子节点
if
(
e
.
checked
&&
e
.
node
.
children
&&
e
.
node
.
children
.
length
>
0
)
{
const
leafKeys
=
this
.
getAllLeafKeys
(
e
.
node
.
children
);
finalCheckedKeys
=
[...
new
Set
([...
finalCheckedKeys
,
...
leafKeys
])];
}
// 当取消勾选父节点时,取消勾选所有叶子节点
if
(
!
e
.
checked
&&
e
.
node
.
children
&&
e
.
node
.
children
.
length
>
0
)
{
const
leafKeys
=
this
.
getAllLeafKeys
(
e
.
node
.
children
);
finalCheckedKeys
=
finalCheckedKeys
.
filter
(
key
=>
!
leafKeys
.
includes
(
key
));
}
// 只在最终结果不同时才更新,避免不必要的触发
if
(
JSON
.
stringify
(
finalCheckedKeys
)
!==
JSON
.
stringify
(
this
.
checkedKeys
))
{
this
.
checkedKeys
=
finalCheckedKeys
;
// 更新选中的人员列表
this
.
updateSelectedStaff
();
}
},
},
onSelect
(
selectedKeys
,
info
)
{
onSelect
(
selectedKeys
,
info
)
{
if
(
selectedKeys
.
length
==
0
||
selectedKeys
[
0
]
>
1000000
){
return
}
// 在复选模式下,onSelect 可以用来处理一些辅助功能,比如展开/折叠
let
index
=
this
.
selectedKeys
.
indexOf
(
selectedKeys
[
0
])
// console.log('onSelect', selectedKeys, info);
if
(
index
==
-
1
&&
selectedKeys
[
0
]
<
1000000
){
},
this
.
selectedKeys
.
push
(
selectedKeys
[
0
]);
// 搜索输入处理
onSearchInput
(
value
)
{
this
.
searchValue
=
value
||
''
;
if
(
value
&&
value
.
length
>
0
)
{
// 过滤搜索选项
this
.
searchOptions
=
dataList
.
filter
(
item
=>
item
.
title
==
value
||
item
.
no
==
value
)
.
map
(
item
=>
({
key
:
item
.
key
,
label
:
item
.
title
,
displayLabel
:
`
${
item
.
title
}${
item
.
no
?
' ('
+
item
.
no
+
')'
:
''
}${
item
.
key
>=
1000000
?
' [部门]'
:
' [人员]'
}
`
,
type
:
item
.
key
>=
1000000
?
'department'
:
'person'
}))
.
slice
(
0
,
10
);
// 限制最多显示10个结果
this
.
showSearchMenu
=
true
;
}
else
{
this
.
searchOptions
=
[];
this
.
showSearchMenu
=
false
;
}
}
// console.log(this.selectedKeys)
// 调用原有的搜索高亮逻辑
// this.onChange(value);
},
},
onChange
(
e
)
{
if
(
!
e
)
{
// 手动搜索
manualSearch
()
{
if
(
this
.
searchText
&&
this
.
searchText
.
length
>
0
)
{
this
.
onSearchInput
(
this
.
searchText
);
}
},
// 隐藏搜索菜单
hideSearchMenu
()
{
// 延迟隐藏,以便点击选项时能正常触发
setTimeout
(()
=>
{
this
.
showSearchMenu
=
false
;
},
500
);
},
// 选择搜索选项
selectSearchOption
(
option
)
{
console
.
log
(
option
,
'selectSearchOption======='
)
// 勾选选中的节点
if
(
!
this
.
checkedKeys
.
includes
(
option
.
key
))
{
this
.
checkedKeys
=
[...
this
.
checkedKeys
,
option
.
key
];
this
.
updateSelectedStaff
();
}
// 展开到选中节点的路径
const
parentKeys
=
this
.
getParentKeys
(
option
.
key
,
this
.
treeData
);
this
.
expandedKeys
=
[...
new
Set
([...
this
.
expandedKeys
,
...
parentKeys
])];
this
.
autoExpandParent
=
false
;
// 清空搜索状态
this
.
searchText
=
''
;
this
.
searchOptions
=
[];
this
.
showSearchMenu
=
false
;
},
// 获取节点到根节点的路径
getParentKeys
(
key
,
treeData
,
parents
=
[])
{
for
(
let
node
of
treeData
)
{
if
(
node
.
key
===
key
)
{
return
parents
;
}
if
(
node
.
children
)
{
const
found
=
this
.
getParentKeys
(
key
,
node
.
children
,
[...
parents
,
node
.
key
]);
if
(
found
.
length
>
parents
.
length
)
{
return
found
;
}
}
}
return
parents
;
},
// 原有的搜索方法,现在主要用于高亮显示
onChange
(
value
)
{
if
(
!
value
)
{
this
.
searchValue
=
''
;
return
;
return
;
}
}
const
value
=
e
;
this
.
searchValue
=
value
;
// const value = e.target.value.toString();
console
.
log
(
'正在搜索...'
+
value
);
// 展开包含搜索结果的节点
console
.
log
(
'查找中'
.
value
)
const
expandedKeys
=
dataList
.
map
((
item
)
=>
{
const
expandedKeys
=
dataList
.
map
((
item
)
=>
{
// console.log("item",item)
if
(
item
.
title
.
indexOf
(
value
)
>
-
1
)
{
if
(
item
.
title
.
indexOf
(
value
)
>
-
1
)
{
return
getParentKey
(
item
.
key
,
this
.
getTreeData
)
return
getParentKey
(
item
.
key
,
this
.
getTreeData
)
}
}
return
null
return
null
}).
filter
((
item
,
i
,
self
)
=>
item
&&
self
.
indexOf
(
item
)
===
i
)
}).
filter
((
item
,
i
,
self
)
=>
item
&&
self
.
indexOf
(
item
)
===
i
)
Object
.
assign
(
this
,
{
if
(
expandedKeys
.
length
>
0
)
{
expandedKeys
,
this
.
expandedKeys
=
[...
new
Set
([...
this
.
expandedKeys
,
...
expandedKeys
])];
searchValue
:
value
,
this
.
autoExpandParent
=
true
;
autoExpandParent
:
true
,
})
},
readyToDeepin
()
{
this
.
checkedDepartment
=
[];
this
.
checkedPeople
=
[];
this
.
checkedPeopleWithDepartment
=
[]
},
// 一些递归方法
deepinTreeData
(
tree
)
{
tree
.
forEach
(
node
=>
{
// 判断是否选中当前节点
if
(
this
.
selectedKeys
.
indexOf
(
node
.
key
)
>
-
1
)
{
// 判断是否是部门,是部门
if
(
node
.
key
>
1000000
)
{
this
.
checkedDepartment
.
push
(
node
);
}
else
{
// 是人
this
.
checkedPeople
.
push
(
node
);
}
}
},
// 获取节点下的所有叶子节点key
getAllLeafKeys
(
nodes
)
{
let
leafKeys
=
[];
nodes
.
forEach
(
node
=>
{
if
(
node
.
children
&&
node
.
children
.
length
>
0
)
{
// 如果有子节点,递归获取
leafKeys
=
leafKeys
.
concat
(
this
.
getAllLeafKeys
(
node
.
children
));
}
else
{
}
else
{
// 未选中当前节点
// 如果是叶子节点(人员),添加到结果中
if
(
node
.
children
)
{
if
(
node
.
key
<
1000000
)
{
// 小于1000000的是人员
// 执行递归
leafKeys
.
push
(
node
.
key
);
this
.
deepinTreeData
(
node
.
children
);
}
}
}
}
});
});
return
leafKeys
;
},
},
// 递归部门所有人
deepinChildren
(
tree
)
{
// 更新选中的人员列表
tree
.
forEach
(
node
=>
{
updateSelectedStaff
()
{
// 判断是否是人
this
.
checkedPeople
=
[];
if
(
node
.
key
>
1000000
)
{
this
.
checkedDepartment
=
[];
// 是部门
if
(
node
.
children
)
{
// 使用 Map 缓存节点查找结果,避免重复遍历
this
.
deepinChildren
(
node
.
children
);
if
(
!
this
.
nodeCache
)
{
this
.
nodeCache
=
new
Map
();
this
.
buildNodeCache
(
this
.
treeData
);
}
// 遍历所有选中的key,区分人员和部门
this
.
checkedKeys
.
forEach
(
key
=>
{
const
node
=
this
.
nodeCache
.
get
(
key
);
if
(
node
)
{
if
(
key
<
1000000
)
{
// 人员
this
.
checkedPeople
.
push
(
node
);
}
else
{
// 部门
this
.
checkedDepartment
.
push
(
node
);
}
}
}
else
{
// 是人
this
.
checkedPeopleWithDepartment
.
push
(
node
);
}
}
});
});
// 向父组件发送选中的人员列表
this
.
$emit
(
'staffNode'
,
this
.
checkedPeople
);
},
},
// 构建节点缓存,避免每次查找都遍历树
buildNodeCache
(
nodes
)
{
nodes
.
forEach
(
node
=>
{
this
.
nodeCache
.
set
(
node
.
key
,
node
);
if
(
node
.
children
&&
node
.
children
.
length
>
0
)
{
this
.
buildNodeCache
(
node
.
children
);
}
});
},
orderStaffNode
(){
orderStaffNode
(){
//对选择的人根据选择顺序排序
//对选择的人根据选择顺序排序
let
staffNode
=
[]
let
staffNode
=
[]
for
(
var
i
=
0
;
i
<
this
.
select
edKeys
.
length
;
i
++
){
for
(
var
i
=
0
;
i
<
this
.
check
edKeys
.
length
;
i
++
){
let
key
=
this
.
select
edKeys
[
i
]
let
key
=
this
.
check
edKeys
[
i
]
if
(
key
<
1000000
){
//小于百万的为人员。大于为机构
if
(
key
<
1000000
){
//小于百万的为人员。大于为机构
let
node
=
this
.
checkedPeople
.
filter
(
item
=>
item
.
key
==
key
)[
0
]
let
node
=
this
.
checkedPeople
.
filter
(
item
=>
item
.
key
==
key
)[
0
]
if
(
node
){
if
(
node
){
...
@@ -243,37 +432,32 @@
...
@@ -243,37 +432,32 @@
}
}
},
},
watch
:
{
watch
:
{
selectedKeys
(
val
)
{
checkedKeys
:
{
// 深度遍历组织机构树
handler
(
val
)
{
this
.
readyToDeepin
();
//清空check的部门和人员
// 当 checkedKeys 改变时,同步更新 value,但避免循环
this
.
deepinTreeData
(
this
.
treeData
);
const
filteredKeys
=
val
.
filter
(
key
=>
key
<
1000000
);
// 只传递人员key给父组件
// 执行递归后,向父组件附件筛选出的数据
this
.
$emit
(
'staffNode'
,
this
.
checkedPeople
);
// this.$emit('departmentNode', this.checkedDepartment);
// console.log("你到底提交了吗", this)
// 只有当过滤后的key与当前value不同时才emit,避免循环
if
(
JSON
.
stringify
(
filteredKeys
)
!==
JSON
.
stringify
(
this
.
value
||
[]))
{
// this.deepinChildren(this.checkedDepartment);
this
.
$emit
(
'input'
,
filteredKeys
);
// this.$emit('checkedPeopleWithDepartment', this.checkedPeopleWithDepartment);
}
// this.value = this.checkedKeys;
},
// console.log("你到底提交了吗?????")
deep
:
true
// this.$emit('input', val);
},
},
// checkedKeys(val)
{
value
:
{
// this.readyToDeepin();//清空check的部门和人员
handler
(
newValue
)
{
// this.deepinTreeData(this.treeData);//先把选择的节点,分为人员checkedPeople和部门checkedDepartment
// 只有当树已经加载完成且新值与当前checkedKeys中的人员key不同时才更新,避免循环
// this.deepinChildren(this.checkedDepartment);//遍历部门,获取部门下的人checkedPeopleWithDepartment
if
(
this
.
treeData
.
length
>
0
)
{
// this.$emit('checkStaffNode', this.checkedPeople.concat(this.checkedPeopleWithDepartment)
);
const
currentStaffKeys
=
this
.
checkedKeys
.
filter
(
key
=>
key
<
1000000
);
if
(
JSON
.
stringify
(
newValue
||
[])
!==
JSON
.
stringify
(
currentStaffKeys
))
{
//单纯的提交选择的key给父组件
this
.
checkedKeys
=
newValue
||
[];
// let keys = val.filter(item=>item
<
1000000
)
if
(
this
.
checkedKeys
.
length
>
0
)
{
// this.$emit('checkStaffKey', keys
);
this
.
updateSelectedStaff
(
);
// },
}
value
(
newValue
)
{
}
// console.log('this.value', newValue);
}
this
.
selectedKeys
=
newValue
},
// this.checkedKeys = newVal
ue
immediate
:
tr
ue
}
}
},
},
}
}
...
@@ -282,12 +466,222 @@
...
@@ -282,12 +466,222 @@
</
script
>
</
script
>
<
style
scoped
>
<
style
scoped
>
.search
{
.search-container
{
border
:
1px
solid
rgb
(
208
,
208
,
220
);
position
:
fixed
;
position
:
fixed
;
width
:
16vw
;
width
:
17vw
;
background-color
:
#fff
;
z-index
:
9999
;
z-index
:
9999
;
padding-left
:
1vh
;
padding
:
1vh
;
padding-top
:
1vh
;
}
.search-wrapper
{
position
:
relative
;
}
.search-input
{
border-radius
:
4px
!important
;
background
:
linear-gradient
(
135deg
,
#f8f9fa
0%
,
#ffffff
100%
);
/* box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); */
transition
:
all
0.3s
cubic-bezier
(
0.4
,
0
,
0.2
,
1
);
}
.search-input
:hover
{
box-shadow
:
0
6px
20px
rgba
(
0
,
0
,
0
,
0.12
);
transform
:
translateY
(
-1px
);
}
.search-input
:focus-within
{
box-shadow
:
0
8px
25px
rgba
(
33
,
150
,
243
,
0.15
);
transform
:
translateY
(
-2px
);
}
.search-input
>>>
.q-field__control
{
border-radius
:
12px
;
padding
:
8px
16px
;
}
.search-input
>>>
.q-field__label
{
font-weight
:
500
;
color
:
#666
;
font-size
:
12px
;
}
.search-input
>>>
.q-field__native
{
font-size
:
5px
;
font-weight
:
200
;
}
.search-icon
{
color
:
#999
;
transition
:
color
0.3s
ease
;
}
.search-input
:hover
.search-icon
{
color
:
#1976d2
;
}
.search-btn
{
margin-right
:
4px
;
transition
:
all
0.3s
ease
;
}
.search-btn
:hover
{
background-color
:
rgba
(
25
,
118
,
210
,
0.1
);
transform
:
scale
(
1.05
);
}
.search-menu
{
border-radius
:
12px
;
box-shadow
:
0
8px
32px
rgba
(
0
,
0
,
0
,
0.12
);
border
:
1px
solid
rgba
(
255
,
255
,
255
,
0.2
);
backdrop-filter
:
blur
(
8px
);
background
:
rgba
(
255
,
255
,
255
,
0.95
);
min-width
:
16vw
;
max-width
:
16vw
;
max-height
:
300px
;
overflow-y
:
auto
;
position
:
absolute
;
top
:
100%
;
left
:
0
;
right
:
0
;
z-index
:
1000
;
margin-top
:
8px
;
}
.search-results
{
padding
:
8px
0
;
}
.search-result-item
{
display
:
flex
;
align-items
:
center
;
padding
:
12px
16px
;
border-radius
:
8px
;
margin
:
2px
8px
;
cursor
:
pointer
;
transition
:
all
0.2s
ease
;
border
:
1px
solid
transparent
;
}
.search-result-item
:hover
{
background-color
:
rgba
(
25
,
118
,
210
,
0.08
);
transform
:
translateX
(
2px
);
border-color
:
rgba
(
25
,
118
,
210
,
0.1
);
}
.search-result-avatar
{
flex-shrink
:
0
;
width
:
40px
;
height
:
40px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
border-radius
:
50%
;
background-color
:
rgba
(
0
,
0
,
0
,
0.04
);
margin-right
:
12px
;
}
.search-result-content
{
flex
:
1
;
min-width
:
0
;
}
.search-result-side
{
flex-shrink
:
0
;
margin-left
:
8px
;
opacity
:
0.6
;
}
.search-result-label
{
font-weight
:
500
;
color
:
#333
;
font-size
:
14px
;
}
.search-result-caption
{
font-size
:
12px
;
color
:
#666
;
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
}
.search-result-id
{
background-color
:
rgba
(
102
,
102
,
102
,
0.1
);
padding
:
2px
6px
;
border-radius
:
4px
;
font-size
:
11px
;
font-weight
:
500
;
}
.no-results
{
padding
:
16px
;
text-align
:
center
;
}
.no-result-item
{
display
:
flex
;
align-items
:
center
;
padding
:
12px
16px
;
justify-content
:
center
;
}
.no-result-avatar
{
flex-shrink
:
0
;
width
:
40px
;
height
:
40px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
border-radius
:
50%
;
background-color
:
rgba
(
0
,
0
,
0
,
0.04
);
margin-right
:
12px
;
}
.no-result-content
{
flex
:
1
;
text-align
:
left
;
}
.no-results-text
{
color
:
#666
;
font-weight
:
500
;
font-size
:
14px
;
}
.no-results-hint
{
color
:
#999
;
font-size
:
12px
;
margin-top
:
4px
;
}
/* 滚动条美化 */
.search-menu
::-webkit-scrollbar
{
width
:
6px
;
}
.search-menu
::-webkit-scrollbar-track
{
background
:
rgba
(
0
,
0
,
0
,
0.05
);
border-radius
:
3px
;
}
.search-menu
::-webkit-scrollbar-thumb
{
background
:
rgba
(
0
,
0
,
0
,
0.2
);
border-radius
:
3px
;
}
.search-menu
::-webkit-scrollbar-thumb:hover
{
background
:
rgba
(
0
,
0
,
0
,
0.3
);
}
/* 响应式设计 */
@media
(
max-width
:
768px
)
{
.search-container
{
width
:
90vw
;
}
.search-menu
{
min-width
:
90vw
;
max-width
:
90vw
;
}
}
}
</
style
>
</
style
>
src/pages/permission/roleuser.vue
View file @
1ef65f87
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
<div
style=
"padding:10px"
>
<div
style=
"padding:10px"
>
<q-card
inline
class=
"fit shadow-6"
>
<q-card
inline
class=
"fit shadow-6"
>
<div>
<div>
<!--
<a-button
type=
"primary"
>
hello world
</a-button>
-->
</div>
</div>
<q-card-main
style=
"height:80%"
>
<q-card-main
style=
"height:80%"
>
<q-table
ref=
"table"
color=
"primary"
:data=
"serverData"
:columns=
"columns"
separator=
"cell"
selection=
"none"
row-key=
"id"
:rows-per-page-options=
"[5,10,20,30,40,50,60,200,500]"
:pagination
.
sync=
"serverPagination"
<q-table
ref=
"table"
color=
"primary"
:data=
"serverData"
:columns=
"columns"
separator=
"cell"
selection=
"none"
row-key=
"id"
:rows-per-page-options=
"[5,10,20,30,40,50,60,200,500]"
:pagination
.
sync=
"serverPagination"
...
@@ -36,24 +35,6 @@
...
@@ -36,24 +35,6 @@
<q-btn
round
color=
"red"
@
click=
"modifyRoleUser"
>
{{$t('Save')}}
</q-btn>
<q-btn
round
color=
"red"
@
click=
"modifyRoleUser"
>
{{$t('Save')}}
</q-btn>
<q-btn
round
@
click=
"closeEditModal"
>
{{$t('Cancel')}}
</q-btn>
<q-btn
round
@
click=
"closeEditModal"
>
{{$t('Cancel')}}
</q-btn>
</q-toolbar>
</q-toolbar>
<!-- <div style="padding:20px">
<q-table ref="usertable" color="primary" :data="roleUser.serverData" :columns="roleUser.columns" separator="cell" row-key="id" :pagination.sync="roleUser.serverPagination"
@request="roleUserRequest" :loading="roleUser.loading" :rows-per-page-label="$t('Rows per page')" :no-data-label="$t('No data')">
<template slot="top-left" slot-scope="props">
<q-input v-model="roleUser.filter.account" type="text" :prefix="$t('Account') + ':'" />
<q-input v-model="roleUser.filter.username" type="text" :prefix="$t('Name') + ':'" />
<q-btn push dense color="primary" icon="search" @click="searchRoleUser">{{$t('Search')}}</q-btn>
</template>
<template slot="top-right" slot-scope="props">
<q-btn flat round dense :icon="props.inFullscreen ? 'fullscreen_exit' : 'fullscreen'" @click="props.toggleFullscreen" />
</template>
<q-td slot="body-cell-id" slot-scope="props" :props="props" style="width:100px">
<q-btn v-if="props.row.isAdd==2" glossy color="secondary" label='新增' @click="modifyRoleUser(props.value,1)"></q-btn>
<q-btn v-if="props.row.isAdd==1" glossy color="secondary" label='删除' @click="modifyRoleUser(props.value,0)"></q-btn>
</q-td>
</q-table>
</div>-->
<!-- 选择个人 -->
<!-- 选择个人 -->
<div
class=
" row q-mb-lg q-ml-lg q-mr-lg"
>
<div
class=
" row q-mb-lg q-ml-lg q-mr-lg"
>
<div
class=
"col-2 q-ml-lg"
style=
"height:80vh;overflow:auto;"
>
<div
class=
"col-2 q-ml-lg"
style=
"height:80vh;overflow:auto;"
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论