feat(knowledge): 添加知识库创建者管理和时间信息显示
- 在多语言文件中添加更新时间、基本信息和未知状态的翻译 - 在知识库序列化器中添加用户ID和创建用户字段支持 - 在知识库设置页面添加创建者选择器和时间信息展示卡片 - 实现创建者信息的前后端数据同步和页面更新逻辑 - 添加用户列表获取功能以支持创建者选择 - 优化样式以适配新的创建者信息展示布局v3.2
parent
3013efb93c
commit
1c469f36b0
|
|
@ -80,6 +80,8 @@ class KnowledgeEditRequest(serializers.Serializer):
|
||||||
)
|
)
|
||||||
file_size_limit = serializers.IntegerField(required=False, label=_('file size limit'))
|
file_size_limit = serializers.IntegerField(required=False, label=_('file size limit'))
|
||||||
file_count_limit = serializers.IntegerField(required=False, label=_('file count limit'))
|
file_count_limit = serializers.IntegerField(required=False, label=_('file count limit'))
|
||||||
|
user_id = serializers.UUIDField(required=False, label=_('user id'))
|
||||||
|
create_user = serializers.UUIDField(required=False, label=_('create user'))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_knowledge_meta_valid_map():
|
def get_knowledge_meta_valid_map():
|
||||||
|
|
@ -381,6 +383,10 @@ class KnowledgeSerializer(serializers.Serializer):
|
||||||
knowledge.file_size_limit = instance.get('file_size_limit')
|
knowledge.file_size_limit = instance.get('file_size_limit')
|
||||||
if 'file_count_limit' in instance:
|
if 'file_count_limit' in instance:
|
||||||
knowledge.file_count_limit = instance.get('file_count_limit')
|
knowledge.file_count_limit = instance.get('file_count_limit')
|
||||||
|
if 'user_id' in instance:
|
||||||
|
knowledge.user_id = instance.get('user_id')
|
||||||
|
if 'create_user' in instance:
|
||||||
|
knowledge.create_user = instance.get('create_user')
|
||||||
if 'application_id_list' in instance and instance.get('application_id_list') is not None:
|
if 'application_id_list' in instance and instance.get('application_id_list') is not None:
|
||||||
application_id_list = instance.get('application_id_list')
|
application_id_list = instance.get('application_id_list')
|
||||||
# 当前用户可修改关联的知识库列表
|
# 当前用户可修改关联的知识库列表
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export default {
|
||||||
upgrade: 'Upgrade',
|
upgrade: 'Upgrade',
|
||||||
createDate: 'Create Date',
|
createDate: 'Create Date',
|
||||||
createTime: 'Create Time',
|
createTime: 'Create Time',
|
||||||
|
updateTime: 'Update Time',
|
||||||
operation: 'Action',
|
operation: 'Action',
|
||||||
character: 'characters',
|
character: 'characters',
|
||||||
export: 'Export',
|
export: 'Export',
|
||||||
|
|
@ -96,6 +97,8 @@ export default {
|
||||||
uploadImagePrompt: 'Please upload an image',
|
uploadImagePrompt: 'Please upload an image',
|
||||||
},
|
},
|
||||||
info: 'Base Information',
|
info: 'Base Information',
|
||||||
|
basicInfo: 'Basic Information',
|
||||||
|
unknown: 'Unknown',
|
||||||
otherSetting: 'Other Settings',
|
otherSetting: 'Other Settings',
|
||||||
username: 'username',
|
username: 'username',
|
||||||
importCreate: 'Import Create',
|
importCreate: 'Import Create',
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ export default {
|
||||||
upgrade: '升级',
|
upgrade: '升级',
|
||||||
createDate: '创建日期',
|
createDate: '创建日期',
|
||||||
createTime: '创建时间',
|
createTime: '创建时间',
|
||||||
|
updateTime: '更新时间',
|
||||||
operation: '操作',
|
operation: '操作',
|
||||||
character: '字符',
|
character: '字符',
|
||||||
export: '导出',
|
export: '导出',
|
||||||
|
|
@ -97,6 +98,8 @@ export default {
|
||||||
uploadImagePrompt: '请上传一张图片',
|
uploadImagePrompt: '请上传一张图片',
|
||||||
},
|
},
|
||||||
info: '基本信息',
|
info: '基本信息',
|
||||||
|
basicInfo: '基本信息',
|
||||||
|
unknown: '未知',
|
||||||
otherSetting: '其他设置',
|
otherSetting: '其他设置',
|
||||||
username: '用户名',
|
username: '用户名',
|
||||||
importCreate: '导入创建',
|
importCreate: '导入创建',
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export default {
|
||||||
upgrade: '升級',
|
upgrade: '升級',
|
||||||
createDate: '創建日期',
|
createDate: '創建日期',
|
||||||
createTime: '創建時間',
|
createTime: '創建時間',
|
||||||
|
updateTime: '更新時間',
|
||||||
operation: '操作',
|
operation: '操作',
|
||||||
character: '字符',
|
character: '字符',
|
||||||
export: '匯出',
|
export: '匯出',
|
||||||
|
|
@ -96,6 +97,8 @@ export default {
|
||||||
uploadImagePrompt: '請上傳一張圖片',
|
uploadImagePrompt: '請上傳一張圖片',
|
||||||
},
|
},
|
||||||
info: '使用者資訊',
|
info: '使用者資訊',
|
||||||
|
basicInfo: '基本資訊',
|
||||||
|
unknown: '未知',
|
||||||
otherSetting: '其他設定',
|
otherSetting: '其他設定',
|
||||||
username: '用戶名',
|
username: '用戶名',
|
||||||
importCreate: '導入創建',
|
importCreate: '導入創建',
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,22 @@
|
||||||
{{ $t('common.info') }}
|
{{ $t('common.info') }}
|
||||||
</h4>
|
</h4>
|
||||||
<BaseForm ref="BaseFormRef" :data="detail" :apiType="apiType"/>
|
<BaseForm ref="BaseFormRef" :data="detail" :apiType="apiType"/>
|
||||||
|
<el-card shadow="never" class="mb-16 w-full layout-bg">
|
||||||
|
<el-descriptions :column="3" border class="creator-info-descriptions">
|
||||||
|
<el-descriptions-item :label="$t('common.creator')" class="creator-info-item">
|
||||||
|
<el-select v-model="selectedCreator" placeholder="请选择创建者" v-if="!route.path.includes('share/') && permissionPrecise.edit(id)" class="creator-select">
|
||||||
|
<el-option v-for="user in user_options" :key="user.id" :label="user.nick_name" :value="user.id" />
|
||||||
|
</el-select>
|
||||||
|
<span v-else class="creator-text">{{ detail?.nick_name ? i18n_name(detail.nick_name) : detail?.create_user || $t('common.unknown') }}</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('common.createTime')" class="creator-info-item">
|
||||||
|
<span class="creator-text">{{ detail?.create_time ? new Date(detail.create_time).toLocaleString() : $t('common.unknown') }}</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('common.updateTime')" class="creator-info-item">
|
||||||
|
<span class="creator-text">{{ detail?.update_time ? new Date(detail.update_time).toLocaleString() : $t('common.unknown') }}</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<el-form
|
<el-form
|
||||||
ref="webFormRef"
|
ref="webFormRef"
|
||||||
|
|
@ -185,11 +201,14 @@ import {useRoute} from 'vue-router'
|
||||||
import BaseForm from '@/views/knowledge/component/BaseForm.vue'
|
import BaseForm from '@/views/knowledge/component/BaseForm.vue'
|
||||||
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
import {MsgSuccess, MsgConfirm} from '@/utils/message'
|
||||||
import {t} from '@/locales'
|
import {t} from '@/locales'
|
||||||
|
import {i18n_name} from '@/utils/common'
|
||||||
import permissionMap from '@/permission'
|
import permissionMap from '@/permission'
|
||||||
|
import useStore from '@/stores'
|
||||||
|
|
||||||
import {loadSharedApi} from '@/utils/dynamics-api/shared-api'
|
import {loadSharedApi} from '@/utils/dynamics-api/shared-api'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const { user } = useStore()
|
||||||
const {
|
const {
|
||||||
params: {id, folderId},
|
params: {id, folderId},
|
||||||
} = route as any
|
} = route as any
|
||||||
|
|
@ -217,6 +236,8 @@ const BaseFormRef = ref()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const detail = ref<any>({ })
|
const detail = ref<any>({ })
|
||||||
const cloneModelId = ref('')
|
const cloneModelId = ref('')
|
||||||
|
const user_options = ref<any[]>([])
|
||||||
|
const selectedCreator = ref('')
|
||||||
|
|
||||||
const form = ref<any>({
|
const form = ref<any>({
|
||||||
source_url: '',
|
source_url: '',
|
||||||
|
|
@ -269,11 +290,15 @@ async function submit() {
|
||||||
meta: form.value,
|
meta: form.value,
|
||||||
file_count_limit: form.value.file_count_limit,
|
file_count_limit: form.value.file_count_limit,
|
||||||
file_size_limit: form.value.file_size_limit,
|
file_size_limit: form.value.file_size_limit,
|
||||||
|
create_user: selectedCreator.value,
|
||||||
|
user_id: selectedCreator.value,
|
||||||
...BaseFormRef.value.form,
|
...BaseFormRef.value.form,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
file_count_limit: form.value.file_count_limit,
|
file_count_limit: form.value.file_count_limit,
|
||||||
file_size_limit: form.value.file_size_limit,
|
file_size_limit: form.value.file_size_limit,
|
||||||
|
create_user: selectedCreator.value,
|
||||||
|
user_id: selectedCreator.value,
|
||||||
...BaseFormRef.value.form,
|
...BaseFormRef.value.form,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,6 +315,13 @@ async function submit() {
|
||||||
.putReEmbeddingKnowledge(id)
|
.putReEmbeddingKnowledge(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
MsgSuccess(t('common.saveSuccess'))
|
MsgSuccess(t('common.saveSuccess'))
|
||||||
|
// 更新页面上显示的创建者信息
|
||||||
|
const selectedUser = user_options.value.find(user => user.id === selectedCreator.value)
|
||||||
|
if (selectedUser) {
|
||||||
|
detail.value.create_user = selectedUser.id
|
||||||
|
detail.value.user_id = selectedUser.id
|
||||||
|
detail.value.nick_name = selectedUser.nick_name
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -300,6 +332,13 @@ async function submit() {
|
||||||
.putReEmbeddingKnowledge(id)
|
.putReEmbeddingKnowledge(id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
MsgSuccess(t('common.saveSuccess'))
|
MsgSuccess(t('common.saveSuccess'))
|
||||||
|
// 更新页面上显示的创建者信息
|
||||||
|
const selectedUser = user_options.value.find(user => user.id === selectedCreator.value)
|
||||||
|
if (selectedUser) {
|
||||||
|
detail.value.create_user = selectedUser.id
|
||||||
|
detail.value.user_id = selectedUser.id
|
||||||
|
detail.value.nick_name = selectedUser.nick_name
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -312,12 +351,24 @@ async function submit() {
|
||||||
.putLarkKnowledge(id, obj, loading)
|
.putLarkKnowledge(id, obj, loading)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
MsgSuccess(t('common.saveSuccess'))
|
MsgSuccess(t('common.saveSuccess'))
|
||||||
|
// 更新页面上显示的创建者信息
|
||||||
|
const selectedUser = user_options.value.find(user => user.id === selectedCreator.value)
|
||||||
|
if (selectedUser) {
|
||||||
|
detail.value.create_user = selectedUser.id
|
||||||
|
detail.value.nick_name = selectedUser.nick_name
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
loadSharedApi({type: 'knowledge', systemType: apiType.value})
|
loadSharedApi({type: 'knowledge', systemType: apiType.value})
|
||||||
.putKnowledge(id, obj, loading)
|
.putKnowledge(id, obj, loading)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
MsgSuccess(t('common.saveSuccess'))
|
MsgSuccess(t('common.saveSuccess'))
|
||||||
|
// 更新页面上显示的创建者信息
|
||||||
|
const selectedUser = user_options.value.find(user => user.id === selectedCreator.value)
|
||||||
|
if (selectedUser) {
|
||||||
|
detail.value.create_user = selectedUser.id
|
||||||
|
detail.value.nick_name = selectedUser.nick_name
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -332,6 +383,8 @@ function getDetail() {
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
detail.value = res.data
|
detail.value = res.data
|
||||||
cloneModelId.value = res.data?.embedding_model_id
|
cloneModelId.value = res.data?.embedding_model_id
|
||||||
|
// 优先使用user_id,如果不存在则使用create_user
|
||||||
|
selectedCreator.value = res.data?.user_id || res.data?.create_user || ''
|
||||||
if (detail.value?.type === 0) {
|
if (detail.value?.type === 0) {
|
||||||
form.value.file_count_limit = res.data.file_count_limit
|
form.value.file_count_limit = res.data.file_count_limit
|
||||||
form.value.file_size_limit = res.data.file_size_limit
|
form.value.file_size_limit = res.data.file_size_limit
|
||||||
|
|
@ -339,11 +392,34 @@ function getDetail() {
|
||||||
if (detail.value?.type === 1 || detail.value?.type === 2) {
|
if (detail.value?.type === 1 || detail.value?.type === 2) {
|
||||||
form.value = res.data.meta
|
form.value = res.data.meta
|
||||||
}
|
}
|
||||||
|
// 如果有用户列表,尝试找到对应的用户信息来更新nick_name
|
||||||
|
if (user_options.value.length > 0 && selectedCreator.value) {
|
||||||
|
const selectedUser = user_options.value.find(user => user.id === selectedCreator.value)
|
||||||
|
if (selectedUser) {
|
||||||
|
detail.value.nick_name = selectedUser.nick_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserList() {
|
||||||
|
loadSharedApi({ type: 'workspace', isShared: isShared.value, systemType: apiType.value })
|
||||||
|
.getAllMemberList(user.getWorkspaceId(), loading)
|
||||||
|
.then((res: any) => {
|
||||||
|
user_options.value = res.data
|
||||||
|
// 如果已经有selectedCreator的值,尝试找到对应的用户信息来更新nick_name
|
||||||
|
if (selectedCreator.value) {
|
||||||
|
const selectedUser = user_options.value.find(user => user.id === selectedCreator.value)
|
||||||
|
if (selectedUser) {
|
||||||
|
detail.value.nick_name = selectedUser.nick_name
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getDetail()
|
getDetail()
|
||||||
|
getUserList()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -351,4 +427,35 @@ onMounted(() => {
|
||||||
width: 70%;
|
width: 70%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.creator-info-descriptions {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creator-info-item {
|
||||||
|
padding: 8px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creator-select {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creator-text {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 调整描述项标签的宽度,确保标签和内容对齐 */
|
||||||
|
:deep(.el-descriptions__label) {
|
||||||
|
padding-right: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 调整描述项内容的宽度,确保内容有足够的空间 */
|
||||||
|
:deep(.el-descriptions__content) {
|
||||||
|
padding-left: 8px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue