perf: Optimize

* fix: New conversation user, user group should be a mandatory field(#3833)

* fix: Filter empty files uploaded during application dialogue(#3836)

* fix: License not uploaded, knowledge base hits test interface style issue(#3852)

* perf: Optimize packaging

---------

Co-authored-by: wangdan-fit2cloud <dan.wang@fit2cloud.com>
This commit is contained in:
shaohuzhang1 2025-08-20 19:02:29 +08:00 committed by GitHub
parent c8ec7c5558
commit e715e244af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 62 additions and 15 deletions

View File

@ -44,6 +44,7 @@
"screenfull": "^6.0.2", "screenfull": "^6.0.2",
"sortablejs": "^1.15.6", "sortablejs": "^1.15.6",
"use-element-plus-theme": "^0.0.5", "use-element-plus-theme": "^0.0.5",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.2", "vite-plugin-html": "^3.2.2",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-clipboard3": "^2.0.0", "vue-clipboard3": "^2.0.0",

View File

@ -421,16 +421,29 @@ const uploadFile = async (file: any, fileList: any) => {
uploadAudioList.value.length + uploadAudioList.value.length +
uploadVideoList.value.length + uploadVideoList.value.length +
uploadOtherList.value.length uploadOtherList.value.length
if (file_limit_once >= maxFiles) { if (file_limit_once >= maxFiles) {
MsgWarning(t('chat.uploadFile.limitMessage1') + maxFiles + t('chat.uploadFile.limitMessage2')) MsgWarning(t('chat.uploadFile.limitMessage1') + maxFiles + t('chat.uploadFile.limitMessage2'))
fileList.splice(0, fileList.length, ...fileList.slice(0, maxFiles)) fileList.splice(0, fileList.length, ...fileList.slice(0, maxFiles))
return return
} }
console.log(fileList)
if (fileList.filter((f: any) => f.size == 0).length > 0) {
// MB
MsgWarning(t('chat.uploadFile.sizeLimit2') + fileLimit + 'MB')
//
fileList.splice(0, fileList.length, ...fileList.filter((f: any) => f.size > 0))
return
}
if (fileList.filter((f: any) => f.size > fileLimit * 1024 * 1024).length > 0) { if (fileList.filter((f: any) => f.size > fileLimit * 1024 * 1024).length > 0) {
// MB // MB
MsgWarning(t('chat.uploadFile.sizeLimit') + fileLimit + 'MB') MsgWarning(t('chat.uploadFile.sizeLimit') + fileLimit + 'MB')
// //
fileList.splice(0, fileList.length, ...fileList.filter((f: any) => f.size <= fileLimit * 1024 * 1024)) fileList.splice(
0,
fileList.length,
...fileList.filter((f: any) => f.size <= fileLimit * 1024 * 1024),
)
return return
} }
const inner = reactive(file) const inner = reactive(file)

View File

@ -66,6 +66,7 @@ export default {
limitMessage1: 'You can upload up to', limitMessage1: 'You can upload up to',
limitMessage2: 'files', limitMessage2: 'files',
sizeLimit: 'Each file must not exceed', sizeLimit: 'Each file must not exceed',
sizeLimit2: 'Empty files are not supported for upload',
imageMessage: 'Please process the image content', imageMessage: 'Please process the image content',
fileMessage: 'Please process the file content', fileMessage: 'Please process the file content',
errorMessage: 'Upload Failed', errorMessage: 'Upload Failed',

View File

@ -3,8 +3,10 @@ export default {
syncUsers: 'Sync Users', syncUsers: 'Sync Users',
syncUsersTip: 'Only sync newly added users', syncUsersTip: 'Only sync newly added users',
setUserGroups: 'Configure User Groups', setUserGroups: 'Configure User Groups',
knowledgeTitleTip: 'This configuration will only take effect after enabling chat user login authentication in the associated application', knowledgeTitleTip:
applicationTitleTip: 'This configuration requires login authentication to be enabled in the application', 'This configuration will only take effect after enabling chat user login authentication in the associated application',
applicationTitleTip:
'This configuration requires login authentication to be enabled in the application',
autoAuthorization: 'Auto Authorization', autoAuthorization: 'Auto Authorization',
authorization: 'Authorization', authorization: 'Authorization',
batchDeleteUser: 'Delete selected {count} users?', batchDeleteUser: 'Delete selected {count} users?',
@ -14,10 +16,12 @@ export default {
group: { group: {
title: 'User Groups', title: 'User Groups',
name: 'User Group Name', name: 'User Group Name',
requiredMessage: 'Please select user group',
usernameOrName: 'Username/Name', usernameOrName: 'Username/Name',
delete: { delete: {
confirmTitle: 'Confirm to delete user group:', confirmTitle: 'Confirm to delete user group:',
confirmMessage: 'All members in this group will be removed after deletion. Proceed with caution!', confirmMessage:
'All members in this group will be removed after deletion. Proceed with caution!',
}, },
batchDeleteMember: 'Remove selected {count} members?', batchDeleteMember: 'Remove selected {count} members?',
}, },
@ -25,5 +29,5 @@ export default {
title: 'Successfully synced {count} users', title: 'Successfully synced {count} users',
usernameExist: 'The following usernames already exist:', usernameExist: 'The following usernames already exist:',
nicknameExist: 'The following nicknames already exist:', nicknameExist: 'The following nicknames already exist:',
} },
} }

View File

@ -68,6 +68,7 @@ export default {
limitMessage1: '最多上传', limitMessage1: '最多上传',
limitMessage2: '个文件', limitMessage2: '个文件',
sizeLimit: '单个文件大小不能超过', sizeLimit: '单个文件大小不能超过',
sizeLimit2: '空文件不支持上传',
imageMessage: '请解析图片内容', imageMessage: '请解析图片内容',
fileMessage: '请解析文件内容', fileMessage: '请解析文件内容',
errorMessage: '上传失败', errorMessage: '上传失败',

View File

@ -13,6 +13,7 @@ export default {
replace: '替换', replace: '替换',
group: { group: {
title: '用户组', title: '用户组',
requiredMessage: '请选择用户组',
name: '用户组名称', name: '用户组名称',
usernameOrName: '用户名/姓名', usernameOrName: '用户名/姓名',
delete: { delete: {
@ -25,5 +26,5 @@ export default {
title: '成功同步 {count} 个用户', title: '成功同步 {count} 个用户',
usernameExist: '以下用户名已存在:', usernameExist: '以下用户名已存在:',
nicknameExist: '以下姓名已存在:', nicknameExist: '以下姓名已存在:',
} },
} }

View File

@ -64,6 +64,7 @@ export default {
limitMessage1: '最多上傳', limitMessage1: '最多上傳',
limitMessage2: '個文件', limitMessage2: '個文件',
sizeLimit: '單個文件大小不能超過', sizeLimit: '單個文件大小不能超過',
sizeLimit2: '空文件不支持上傳',
imageMessage: '請解析圖片內容', imageMessage: '請解析圖片內容',
fileMessage: '請解析文件內容', fileMessage: '請解析文件內容',
errorMessage: '上傳失敗', errorMessage: '上傳失敗',

View File

@ -13,6 +13,7 @@ export default {
replace: '替換', replace: '替換',
group: { group: {
title: '用戶組', title: '用戶組',
requiredMessage: '請選擇用戶組',
name: '用戶組名稱', name: '用戶組名稱',
usernameOrName: '用戶名/姓名', usernameOrName: '用戶名/姓名',
delete: { delete: {
@ -25,5 +26,5 @@ export default {
title: '成功同步 {count} 個用戶', title: '成功同步 {count} 個用戶',
usernameExist: '以下用戶名已存在:', usernameExist: '以下用戶名已存在:',
nicknameExist: '以下姓名已存在:', nicknameExist: '以下姓名已存在:',
} },
} }

View File

@ -287,3 +287,13 @@
.el-input { .el-input {
--el-input-text-color: var(--el-text-color-primary); --el-input-text-color: var(--el-text-color-primary);
} }
.el-input-group__prepend div.el-select .el-select__wrapper {
background: #ffffff;
&:hover {
background: #ffffff;
}
.el-select__placeholder {
color: var(--el-text-color-regular);
}
}

View File

@ -22,7 +22,7 @@
</div> </div>
</div> </div>
<el-scrollbar> <el-scrollbar>
<div class="hit-test-height"> <div :style="{ height: user.isExpire() ? 'calc(100vh - 340px)' : 'calc(100vh - 300px)' }">
<el-empty <el-empty
v-if="first" v-if="first"
:image="emptyImg" :image="emptyImg"
@ -231,6 +231,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { nextTick, ref, onMounted, computed } from 'vue' import { nextTick, ref, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import useStore from '@/stores'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import ParagraphDialog from '@/views/paragraph/component/ParagraphDialog.vue' import ParagraphDialog from '@/views/paragraph/component/ParagraphDialog.vue'
import { arraySort } from '@/utils/array' import { arraySort } from '@/utils/array'
@ -241,6 +242,7 @@ const route = useRoute()
const { const {
params: { id }, params: { id },
} = route as any } = route as any
const { user } = useStore()
const apiType = computed(() => { const apiType = computed(() => {
if (route.path.includes('shared')) { if (route.path.includes('shared')) {
return 'systemShare' return 'systemShare'
@ -408,10 +410,6 @@ onMounted(() => {})
position: absolute; position: absolute;
right: calc(var(--app-base-px) * 3); right: calc(var(--app-base-px) * 3);
} }
.hit-test-height {
height: calc(100vh - 300px);
}
.document-card { .document-card {
height: 210px; height: 210px;
border: 1px solid var(--app-layout-bg-color); border: 1px solid var(--app-layout-bg-color);

View File

@ -160,7 +160,7 @@
</div> </div>
</LayoutContainer> </LayoutContainer>
<div class="mul-operation border-t w-full" v-if="isBatch === true"> <div class="mul-operation border-t w-full flex align-center" v-if="isBatch === true">
<el-button :disabled="multipleSelection.length === 0" @click="openGenerateDialog()"> <el-button :disabled="multipleSelection.length === 0" @click="openGenerateDialog()">
{{ $t('views.document.generateQuestion.title') }} {{ $t('views.document.generateQuestion.title') }}
</el-button> </el-button>
@ -171,7 +171,7 @@
<el-button :disabled="multipleSelection.length === 0" @click="deleteMulParagraph"> <el-button :disabled="multipleSelection.length === 0" @click="deleteMulParagraph">
{{ $t('common.delete') }} {{ $t('common.delete') }}
</el-button> </el-button>
<span class="ml-8"> <span class="ml-24">
{{ $t('common.selected') }} {{ multipleSelection.length }} {{ $t('common.selected') }} {{ multipleSelection.length }}
{{ $t('views.document.items') }} {{ $t('views.document.items') }}
</span> </span>

View File

@ -51,7 +51,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch } from 'vue' import { ref, reactive, watch } from 'vue'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import chatUserApi from '@/api/system/chat-user'
import userManageApi from '@/api/system/user-manage' import userManageApi from '@/api/system/user-manage'
import { MsgSuccess } from '@/utils/message' import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales' import { t } from '@/locales'
@ -111,6 +110,14 @@ const rules = reactive({
trigger: 'blur', trigger: 'blur',
}, },
], ],
user_group_ids: [
{
type: 'array',
required: true,
message: t('views.chatUser.group.requiredMessage'),
trigger: 'change',
},
],
}) })
const visible = ref<boolean>(false) const visible = ref<boolean>(false)
const loading = ref(false) const loading = ref(false)

View File

@ -6,6 +6,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
import DefineOptions from 'unplugin-vue-define-options/vite' import DefineOptions from 'unplugin-vue-define-options/vite'
import path from 'path' import path from 'path'
import { createHtmlPlugin } from 'vite-plugin-html' import { createHtmlPlugin } from 'vite-plugin-html'
import viteCompression from 'vite-plugin-compression'
import fs from 'fs' import fs from 'fs'
// import vueDevTools from 'vite-plugin-vue-devtools' // import vueDevTools from 'vite-plugin-vue-devtools'
const envDir = './env' const envDir = './env'
@ -87,6 +88,14 @@ export default defineConfig((conf: any) => {
DefineOptions(), DefineOptions(),
createHtmlPlugin({ template: ENV.VITE_ENTRY }), createHtmlPlugin({ template: ENV.VITE_ENTRY }),
renameHtmlPlugin(`dist${ENV.VITE_BASE_PATH}`, ENV.VITE_ENTRY), renameHtmlPlugin(`dist${ENV.VITE_BASE_PATH}`, ENV.VITE_ENTRY),
viteCompression({
// gzip静态资源压缩配置
verbose: true, // 是否在控制台输出压缩结果
disable: false, // 是否禁用压缩
threshold: 10240, // 启用压缩的文件大小限制
algorithm: 'gzip', // 采用的压缩算法
ext: '.gz', // 生成的压缩包后缀
}),
], ],
server: { server: {
cors: true, cors: true,