feat(knowledge): 添加知识库可见权限功能

- 新增可见权限选择组件 otherSelect
- 在知识库表单中集成可见权限选择
- 实现可见权限数据的获取和展示
- 优化 cascader 组件样式和交互
This commit is contained in:
陈昱达
2025-04-30 14:36:52 +08:00
parent 3bad79f9b8
commit ca030e4c57
5 changed files with 360 additions and 6 deletions

View File

@@ -12,7 +12,7 @@ export function docManageDataset(data) {
//单一知识库详情
export function getDatasetById(params) {
return request({
url: getUrl('/datasets/query'),
url: getUrl('/datasetsEx/query'),
method: 'get',
params: params
})

View File

@@ -14,6 +14,7 @@
}
.el-input--medium,
.el-cascader--medium,
.el-input--small,
.el-select--medium,
.el-range-editor--medium {
@@ -40,6 +41,74 @@
}
}
}
.el-cascader {
width: 100%;
& .el-input {
&.is-active,
&.is-focus {
border-color: $--color-primary;
&:hover {
border-color: $--color-primary;
}
& .el-input__inner {
border-color: $--color-primary;
&:focus {
border-color: $--color-primary;
}
&:hover {
border-color: $--color-primary;
}
&:active {
border-color: $--color-primary;
}
&:focus {
border-color: $--color-primary;
}
&:disabled {
border-color: rgba(0, 0, 0, 0.25);
}
}
}
& .el-input__inner {
&:focus {
border-color: $--color-primary;
}
&:hover {
border-color: $--color-primary;
}
&:active {
border-color: $--color-primary;
}
&:focus {
border-color: $--color-primary;
}
}
&.is-disabled {
border-color: transparent;
& .el-input__inner {
border-color: transparent !important;
&:focus {
border-color: transparent !important;
}
&:hover {
border-color: transparent !important;
}
&:active {
border-color: transparent !important;
}
}
}
}
}
.el-cascader-node {
&.in-active-path {
color: $--color-primary;
}
&.is-active {
color: $--color-primary;
}
}
.el-input,
.el-select,
.el-range-editor {
@@ -128,3 +197,56 @@
}
}
}
.ebiz-other-cascader {
width: 470px;
& .el-cascader-menu {
&:first-child {
position: relative;
&:after {
position: absolute;
bottom: 0;
content: '';
border-bottom: 1px solid $--color-primary;
opacity: 0.5;
transform: scaleY(0.5);
width: 100%;
}
}
}
& .el-cascader-panel {
display: unset;
& .el-scrollbar__wrap {
height: unset;
max-height: 300px;
& .el-cascader-menu__list {
max-height: 300px;
min-height: unset;
& .el-cascader-node {
&.is-active {
position: relative;
font-family: 'element-icons' !important;
&::after {
position: absolute;
content: '\e6da';
right: 20px;
}
}
}
//border-bottom: 1px solid $--color-primary;
& .el-checkbox {
display: none;
}
& .el-icon-arrow-right {
display: none;
}
}
}
}
}
.el-cascader__suggestion-item {
&.is-checked {
color: $--color-primary;
}
}

View File

@@ -63,6 +63,10 @@ const actions = {
// 验证返回的roles是否是一个非空数组
commit('SET_ROLES', roles)
}
sessionStorage.setItem(
'userInfo',
JSON.stringify(res.content.content)
)
commit('SET_NAME', res.content.content.userName)
resolve(res)
})

View File

@@ -25,6 +25,10 @@
<el-input type="textarea" v-model="model.description"></el-input>
</el-form-item>
<!-- 可见范围-->
<el-form-item label="可见权限:" prop="visibleRange">
<otherSelect :model="model"></otherSelect>
</el-form-item>
<el-form-item
label="分段模式:"
prop="segmentedMode"
@@ -32,6 +36,7 @@
>
{{ model.segmentedMode | filterSegmentedMode }}
</el-form-item>
<el-form-item label="分段模式:" prop="segmentedMode" v-else>
<el-radio-group v-model="model.segmentedMode">
<el-radio :label="0">通用分段模式</el-radio>
@@ -79,7 +84,7 @@
</template>
<script>
import 'nprogress/nprogress.css' // progress bar style
import otherSelect from '@/views/knowledge/detail/components/otherSelect/otherIndex.vue'
import {
datasetCreate,
datasetUpdate,
@@ -105,12 +110,14 @@ export default {
segmentedMode: 0,
id: null,
imageType: 'upload-img',
image: null
image: null,
visibleRange: 0
},
rules: {
name: [
{ required: true, message: '请输入知识库名称', trigger: 'blur' }
],
visibleRange: [{ required: true, message: '请选择可见权限' }],
image: [{ required: true, message: '请上传知识库图标' }],
segmentedMode: [{ required: true, message: '请选择分段模式' }]
}
@@ -168,7 +175,9 @@ export default {
// }
// }
},
components: {},
components: {
otherSelect
},
filters: {
filterSegmentedMode(val) {
switch (val) {
@@ -220,7 +229,7 @@ export default {
description: '',
name: '',
segmentedMode: 0,
visibleRange: 0,
visibleRange: '',
userIds: [],
image: null,
imageType: 'upload-img',
@@ -234,7 +243,7 @@ export default {
return false
}
this.model.visibleRange = 0
// this.model.visibleRange = 0/**/
;(!this.datasetId ? datasetCreate : datasetUpdate)(this.model).then(
res => {
if (res) {

View File

@@ -0,0 +1,219 @@
<template>
<div>
<el-cascader
popper-class="ebiz-other-cascader"
v-model="values"
size="medium"
ref="selectRef"
@change="handleChange"
@visible-change="visibleChange"
:options="options"
:teleported="false"
:show-all-levels="false"
:props="cascaderProps"
:filterable="values[0] !== 1 && values[0] !== 0"
:filter-method="filterMethod"
@remove-tag="removeTag"
>
<template #default="{ node, data }">
<div v-if="node.level === 1" @click="chooseItem(node, data)">
{{ data.realName }}
</div>
<div v-else @click="chooseItem(node, data)">
<div
class="flex align-items-c ellipsis"
:class="data.id === userInfo.id ? 'disabled' : ''"
>
{{ data.realName }}
</div>
</div>
</template>
</el-cascader>
</div>
</template>
<script>
import { getUserList } from '@/api/generatedApi/system'
export default {
name: 'otherIndex',
data() {
return {
values: [],
userInfo: {},
options: [
{
realName: '所有人可见',
id: 0
},
{
realName: '仅自己可见',
id: 1
},
{
realName: '部分人可见',
id: 2,
children: []
}
]
}
},
props: {
model: {
type: Object,
default: () => {
return {
visibleRange: 0,
userIds: []
}
}
}
},
computed: {
cascaderProps() {
return {
multiple: () => {
return false
},
label: 'realName',
value: 'id'
// checkStrictly: true
}
}
},
methods: {
removeTag(tag) {
// 不能删除自己
if (tag[1] === this.userInfo.id) {
this.values.push([2, this.userInfo.id])
}
},
filterMethod(path, queryString) {
return (
path.text.includes(queryString) &&
path.path[0] !== 0 &&
path.path[0] !== 1
)
},
getUsers() {
getUserList({
userCodeLike: '',
userNameLike: '',
status: 0,
realName: '',
realNameLike: '',
mobile: '',
mobileLike: '',
email: '',
emailLike: '',
sysUserRoleDTOs: [],
page: 1,
pageSize: 999999999
}).then(res => {
if (res) {
this.options[2].children = res.content.content
}
})
},
chooseItem(node, data) {
let userInfo = sessionStorage.getItem('userInfo')
userInfo = JSON.parse(userInfo)
if (data.id === userInfo.id) {
return false
}
if (node.level === 1) {
if (data.id === 0 || data.id === 1) {
this.cascaderProps.multiple = false
this.values = [data.id]
} else {
this.values = []
this.cascaderProps.multiple = true
if (this.values.length === 0) {
this.values.push([2, userInfo.id])
}
}
} else {
// 去重 如果包含就删除
if (this.values.some(item => item[1] === data.id)) {
this.values = this.values.filter(item => {
return item[1] !== data.id
})
} else {
let values = JSON.parse(JSON.stringify(this.values))
values.push([2, data.id])
this.values = values
}
}
},
visibleChange() {
this.$refs.selectRef.visible = true // 重新展开下拉面板
},
handleChange(value) {}
},
created() {
let userInfo = sessionStorage.getItem('userInfo')
if (userInfo) {
this.userInfo = JSON.parse(userInfo)
}
},
mounted() {
this.getUsers()
},
watch: {
model: {
handler(newVal) {
if (newVal.visibleRange === 0) {
this.values = [0]
this.cascaderProps.multiple = false
} else if (newVal.visibleRange === 1) {
this.values = [1]
this.cascaderProps.multiple = false
} else {
this.values = []
this.cascaderProps.multiple = true
if (newVal.userIds.length > 0) {
newVal.userIds.map(item => {
this.values.push([2, item])
})
}
}
}
},
values: {
handler(newVal) {
if (!this.cascaderProps.multiple) {
this.model.visibleRange = newVal[0]
if (newVal[0] === 0) {
this.model.userIds = []
} else {
this.model.userIds = []
// 只有自己能看
let userInfo = sessionStorage.getItem('userInfo')
if (userInfo) {
userInfo = JSON.parse(userInfo)
this.model.userIds = [userInfo.id]
}
}
} else {
this.model.visibleRange = 2
this.model.userIds = newVal.map(item => {
return item[1]
})
}
},
immediate: true
}
}
}
</script>
<style scoped lang="scss">
.disabled {
opacity: 0.5;
cursor: no-drop;
}
</style>