mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
fix: user language
This commit is contained in:
parent
12feaac958
commit
f926de4f91
|
|
@ -301,7 +301,7 @@ const getMcpTools: (
|
|||
* 上传文件
|
||||
* @param 参数 file:file
|
||||
*/
|
||||
const uploadFile: (
|
||||
const postUploadFile: (
|
||||
file: any,
|
||||
sourceId: string,
|
||||
resourceType:
|
||||
|
|
@ -313,12 +313,13 @@ const uploadFile: (
|
|||
| 'TEMPORARY_30_MINUTE'
|
||||
| 'TEMPORARY_120_MINUTE'
|
||||
| 'TEMPORARY_1_DAY',
|
||||
) => Promise<Result<any>> = (file, sourceId, resourceType) => {
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (file, sourceId, resourceType, loading) => {
|
||||
const fd = new FormData()
|
||||
fd.append('file', file)
|
||||
fd.append('source_id', sourceId)
|
||||
fd.append('source_type', resourceType)
|
||||
return post(`/oss/file`, fd)
|
||||
return post(`/oss/file`, fd, undefined, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
@ -346,5 +347,5 @@ export default {
|
|||
postTextToSpeech,
|
||||
speechToText,
|
||||
getMcpTools,
|
||||
uploadFile,
|
||||
postUploadFile,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ const modifyChat: (chat_id: string, data: any, loading?: Ref<boolean>) => Promis
|
|||
* @param resourceType 资源类型
|
||||
* @returns
|
||||
*/
|
||||
const uploadFile: (
|
||||
const postUploadFile: (
|
||||
file: any,
|
||||
sourceId: string,
|
||||
resourceType:
|
||||
|
|
@ -309,12 +309,13 @@ const uploadFile: (
|
|||
| 'TEMPORARY_30_MINUTE'
|
||||
| 'TEMPORARY_120_MINUTE'
|
||||
| 'TEMPORARY_1_DAY',
|
||||
) => Promise<Result<any>> = (file, sourceId, sourceType) => {
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (file, sourceId, sourceType, loading) => {
|
||||
const fd = new FormData()
|
||||
fd.append('file', file)
|
||||
fd.append('source_id', sourceId)
|
||||
fd.append('source_type', sourceType)
|
||||
return post(`/oss/file`, fd)
|
||||
return post(`/oss/file`, fd, undefined, loading)
|
||||
}
|
||||
export default {
|
||||
open,
|
||||
|
|
@ -344,5 +345,5 @@ export default {
|
|||
speechToText,
|
||||
deleteChat,
|
||||
modifyChat,
|
||||
uploadFile,
|
||||
postUploadFile,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue'
|
||||
import KnowledgeSourceComponent from '@/components/ai-chat/component/knowledge-source-component/index.vue'
|
||||
import MdRenderer from '@/components/markdown/MdRenderer.vue'
|
||||
import OperationButton from '@/components/ai-chat/component/operation-button/index.vue'
|
||||
import { type chatType } from '@/api/type/application'
|
||||
import { computed } from 'vue'
|
||||
import bus from '@/bus'
|
||||
import useStore from '@/stores'
|
||||
const props = defineProps<{
|
||||
|
|
@ -100,7 +100,7 @@ const emit = defineEmits([
|
|||
])
|
||||
|
||||
const showAvatar = computed(() => {
|
||||
return (user.isEE() || user.isPE())? props.application.show_avatar : true
|
||||
return user.isEE() || user.isPE() ? props.application.show_avatar : true
|
||||
})
|
||||
const showUserAvatar = computed(() => {
|
||||
return user.isEE() || user.isPE() ? props.application.show_user_avatar : true
|
||||
|
|
@ -165,5 +165,11 @@ const stopChat = (chat: chatType) => {
|
|||
const startChat = (chat: chatType) => {
|
||||
props.chatManagement.write(chat.id)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
bus.on('chat:stop', () => {
|
||||
stopChat(props.chatRecord)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@
|
|||
</el-button>
|
||||
<!-- 使用 custom-class 自定义样式 -->
|
||||
<transition name="el-fade-in-linear">
|
||||
<el-card class="custom-speech-card" :class="isTouching ? '' : 'active'" v-if="dialogVisible">
|
||||
<el-card
|
||||
class="custom-speech-card white-bg"
|
||||
:class="isTouching ? '' : 'active'"
|
||||
v-if="dialogVisible"
|
||||
>
|
||||
<p>
|
||||
<el-text type="info" v-if="isTouching"
|
||||
>00:{{ props.time < 10 ? `0${props.time}` : props.time }}</el-text
|
||||
|
|
@ -43,16 +47,16 @@ import { ref, watch } from 'vue'
|
|||
const props = defineProps({
|
||||
time: {
|
||||
type: Number,
|
||||
default: 0
|
||||
default: 0,
|
||||
},
|
||||
start: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(['TouchStart', 'TouchEnd'])
|
||||
// 移动端语音
|
||||
|
|
@ -77,7 +81,7 @@ watch(
|
|||
dialogVisible.value = false
|
||||
isTouching.value = false
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => props.start,
|
||||
|
|
@ -90,7 +94,7 @@ watch(
|
|||
dialogVisible.value = false
|
||||
isTouching.value = false
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
function onTouchStart(event: any) {
|
||||
|
|
@ -127,7 +131,6 @@ function onTouchEnd() {
|
|||
left: 50%; /* 水平居中 */
|
||||
transform: translateX(-50%);
|
||||
width: 92%;
|
||||
background: #ffffff;
|
||||
border: 1px solid #ffffff;
|
||||
box-shadow: 0px 6px 24px 0px rgba(31, 35, 41, 0.08);
|
||||
z-index: 999;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
<template>
|
||||
<div class="ai-chat__operate p-16">
|
||||
<div class="text-center mb-8" v-if="loading">
|
||||
<el-button class="border-primary video-stop-button" @click="stopChat">
|
||||
<app-icon iconName="app-video-stop" class="mr-8"></app-icon>
|
||||
{{ $t('chat.operation.stopChat') }}</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="operate-textarea">
|
||||
<el-scrollbar max-height="136">
|
||||
<div
|
||||
class="p-8-12"
|
||||
v-loading="localLoading"
|
||||
v-loading="uploadLoading"
|
||||
v-if="
|
||||
uploadDocumentList.length ||
|
||||
uploadImageList.length ||
|
||||
|
|
@ -143,6 +149,7 @@
|
|||
</el-icon>
|
||||
</div>
|
||||
<el-image
|
||||
v-if="item.url"
|
||||
:src="item.url"
|
||||
alt=""
|
||||
fit="cover"
|
||||
|
|
@ -299,7 +306,6 @@ import bus from '@/bus'
|
|||
import 'recorder-core/src/engine/mp3'
|
||||
import 'recorder-core/src/engine/mp3-engine'
|
||||
import { MsgWarning } from '@/utils/message'
|
||||
import { debounce } from 'lodash'
|
||||
import chatAPI from '@/api/chat/chat'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
|
@ -347,6 +353,8 @@ const localLoading = computed({
|
|||
},
|
||||
})
|
||||
|
||||
const uploadLoading = ref(false)
|
||||
|
||||
const inputPlaceholder = computed(() => {
|
||||
return recorderStatus.value === 'START'
|
||||
? `${t('chat.inputPlaceholder.speaking')}...`
|
||||
|
|
@ -430,8 +438,13 @@ const uploadFile = async (file: any, fileList: any) => {
|
|||
}
|
||||
const api =
|
||||
props.type === 'debug-ai-chat'
|
||||
? applicationApi.uploadFile(file.raw, 'TEMPORARY_120_MINUTE', 'TEMPORARY_120_MINUTE')
|
||||
: chatAPI.uploadFile(file.raw, chatId_context.value, 'CHAT')
|
||||
? applicationApi.postUploadFile(
|
||||
file.raw,
|
||||
'TEMPORARY_120_MINUTE',
|
||||
'TEMPORARY_120_MINUTE',
|
||||
uploadLoading,
|
||||
)
|
||||
: chatAPI.postUploadFile(file.raw, chatId_context.value, 'CHAT', uploadLoading)
|
||||
api.then((ok) => {
|
||||
file.url = ok.data
|
||||
const split_path = ok.data.split('/')
|
||||
|
|
@ -639,7 +652,7 @@ class RecorderManage {
|
|||
}
|
||||
const getSpeechToTextAPI = () => {
|
||||
if (props.type === 'ai-chat') {
|
||||
return (application_id?: string, data?: any, loading?: Ref<boolean>) => {
|
||||
return (data?: any, loading?: Ref<boolean>) => {
|
||||
return chatAPI.speechToText(data, loading)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -802,6 +815,10 @@ function mouseenter(row: any) {
|
|||
function mouseleave() {
|
||||
showDelete.value = ''
|
||||
}
|
||||
|
||||
function stopChat() {
|
||||
bus.emit('chat:stop')
|
||||
}
|
||||
onMounted(() => {
|
||||
bus.on('chat-input', (message: string) => {
|
||||
inputValue.value = message
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@
|
|||
link
|
||||
>{{ $t('chat.operation.continue') }}
|
||||
</el-button>
|
||||
<el-button type="primary" v-else-if="!chatRecord.write_ed" @click="stopChat(chatRecord)" link
|
||||
<!-- <el-button type="primary" v-else-if="!chatRecord.write_ed" @click="stopChat(chatRecord)" link
|
||||
>{{ $t('chat.operation.stopChat') }}
|
||||
</el-button>
|
||||
</el-button> -->
|
||||
</div>
|
||||
|
||||
<ChatOperationButton
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@
|
|||
:executionIsRightPanel="props.executionIsRightPanel"
|
||||
@open-execution-detail="emit('openExecutionDetail', chatList[index])"
|
||||
@openParagraph="emit('openParagraph', chatList[index])"
|
||||
@openParagraphDocument="(val: any)=>emit('openParagraphDocument', chatList[index], val)"
|
||||
@openParagraphDocument="
|
||||
(val: any) => emit('openParagraphDocument', chatList[index], val)
|
||||
"
|
||||
></AnswerContent>
|
||||
</template>
|
||||
<TransitionContent
|
||||
|
|
@ -77,9 +79,6 @@
|
|||
v-model:show-user-input="showUserInput"
|
||||
v-if="type !== 'log'"
|
||||
>
|
||||
<template #operateBefore>
|
||||
<slot name="operateBefore"> </slot>
|
||||
</template>
|
||||
<template #userInput>
|
||||
<el-button
|
||||
v-if="isUserInput || isAPIInput"
|
||||
|
|
@ -105,7 +104,6 @@ import chatLogApi from '@/api/application/chat-log'
|
|||
import { ChatManagement, type chatType } from '@/api/type/application'
|
||||
import { randomId } from '@/utils/common'
|
||||
import useStore from '@/stores'
|
||||
import { isWorkFlow } from '@/utils/application'
|
||||
import { debounce } from 'lodash'
|
||||
import AnswerContent from '@/components/ai-chat/component/answer-content/index.vue'
|
||||
import QuestionContent from '@/components/ai-chat/component/question-content/index.vue'
|
||||
|
|
@ -139,7 +137,13 @@ const props = withDefaults(
|
|||
type: 'ai-chat',
|
||||
},
|
||||
)
|
||||
const emit = defineEmits(['refresh', 'scroll', 'openExecutionDetail', 'openParagraph','openParagraphDocument'])
|
||||
const emit = defineEmits([
|
||||
'refresh',
|
||||
'scroll',
|
||||
'openExecutionDetail',
|
||||
'openParagraph',
|
||||
'openParagraphDocument',
|
||||
])
|
||||
const { application, common } = useStore()
|
||||
const isMobile = computed(() => {
|
||||
return common.isMobile() || mode === 'embed' || mode === 'mobile'
|
||||
|
|
@ -246,14 +250,18 @@ function sendMessage(val: string, other_params_data?: any, chat?: chatType): Pro
|
|||
return userFormRef.value
|
||||
?.validate()
|
||||
.then((ok) => {
|
||||
let userFormData = JSON.parse(localStorage.getItem(`${accessToken}userForm`) || '{}')
|
||||
let userFormData = accessToken
|
||||
? JSON.parse(localStorage.getItem(`${accessToken}userForm`) || '{}')
|
||||
: {}
|
||||
const newData = Object.keys(form_data.value).reduce((result: any, key: string) => {
|
||||
result[key] = Object.prototype.hasOwnProperty.call(userFormData, key)
|
||||
? userFormData[key]
|
||||
: form_data.value[key]
|
||||
return result
|
||||
}, {})
|
||||
localStorage.setItem(`${accessToken}userForm`, JSON.stringify(newData))
|
||||
if (accessToken) {
|
||||
localStorage.setItem(`${accessToken}userForm`, JSON.stringify(newData))
|
||||
}
|
||||
|
||||
showUserInput.value = false
|
||||
|
||||
|
|
@ -300,11 +308,11 @@ const openChatId: () => Promise<string> = () => {
|
|||
return res.data
|
||||
})
|
||||
.catch((res) => {
|
||||
if (res.response.status === 403) {
|
||||
return application.asyncAppAuthentication(accessToken).then(() => {
|
||||
return openChatId()
|
||||
})
|
||||
}
|
||||
// if (res.response.status === 403) {
|
||||
// return application.asyncAppAuthentication(accessToken).then(() => {
|
||||
// return openChatId()
|
||||
// })
|
||||
// }
|
||||
return Promise.reject(res)
|
||||
})
|
||||
}
|
||||
|
|
@ -512,16 +520,7 @@ function chatMessage(chat?: any, problem?: string, re_chat?: boolean, other_para
|
|||
// 对话
|
||||
getChatMessageAPI()(chartOpenId.value, obj)
|
||||
.then((response) => {
|
||||
if (response.status === 401) {
|
||||
application
|
||||
.asyncAppAuthentication(accessToken)
|
||||
.then(() => {
|
||||
chatMessage(chat, problem)
|
||||
})
|
||||
.catch(() => {
|
||||
errorWrite(chat)
|
||||
})
|
||||
} else if (response.status === 460) {
|
||||
if (response.status === 460) {
|
||||
return Promise.reject(t('chat.tip.errorIdentifyMessage'))
|
||||
} else if (response.status === 461) {
|
||||
return Promise.reject(t('chat.tip.errorLimitMessage'))
|
||||
|
|
@ -661,6 +660,13 @@ defineExpose({
|
|||
width: calc(100% - 50px);
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.video-stop-button {
|
||||
box-shadow: 0px 6px 24px 0px rgba(31, 35, 41, 0.08);
|
||||
&:hover {
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 768px) {
|
||||
.firstUserInput {
|
||||
.user-form-container {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
:is="
|
||||
Object.keys(iconMap).includes(iconName)
|
||||
? iconMap[iconName].iconReader()
|
||||
: iconMap['404'].iconReader()
|
||||
: iconMap['app-404'].iconReader()
|
||||
"
|
||||
class="el-icon app-icon"
|
||||
>
|
||||
|
|
@ -22,7 +22,7 @@ const props = withDefaults(
|
|||
iconName?: string
|
||||
}>(),
|
||||
{
|
||||
iconName: '404',
|
||||
iconName: 'app-404',
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ export default {
|
|||
])
|
||||
},
|
||||
},
|
||||
'app-play-outlined': {
|
||||
'app-debug-outlined': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
|
|
|
|||
|
|
@ -230,6 +230,39 @@ export const iconMap: any = {
|
|||
])
|
||||
},
|
||||
},
|
||||
'app-404': {
|
||||
iconReader: () => {
|
||||
return h('i', [
|
||||
h(
|
||||
'svg',
|
||||
{
|
||||
viewBox: '0 0 1024 1024',
|
||||
version: '1.1',
|
||||
style: 'height:14px;width:14px',
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
},
|
||||
[
|
||||
h('path', {
|
||||
d: 'M260.266667 789.333333c-21.333333 0-38.4-17.066667-38.4-38.4v-59.733333H38.4c-12.8 0-29.866667-8.533333-34.133333-21.333333-4.266667-17.066667-4.266667-29.866667 4.266666-42.666667l221.866667-294.4c8.533333-12.8 25.6-17.066667 42.666667-12.8 17.066667 4.266667 25.6 21.333333 25.6 38.4v256h34.133333c21.333333 0 38.4 17.066667 38.4 38.4s-17.066667 38.4-38.4 38.4H298.666667v59.733333c0 21.333333-17.066667 38.4-38.4 38.4z m-145.066667-179.2h106.666667V469.333333l-106.666667 140.8zM913.066667 742.4c-21.333333 0-38.4-17.066667-38.4-38.4v-59.733333h-183.466667c-12.8 0-29.866667-8.533333-34.133333-21.333334-8.533333-12.8-4.266667-29.866667 4.266666-38.4l221.866667-294.4c8.533333-12.8 25.6-17.066667 42.666667-12.8 17.066667 4.266667 25.6 21.333333 25.6 38.4v256h34.133333c21.333333 0 38.4 17.066667 38.4 38.4s-17.066667 38.4-38.4 38.4h-34.133333v59.733334c0 17.066667-17.066667 34.133333-38.4 34.133333zM768 567.466667h106.666667V426.666667L768 567.466667zM533.333333 597.333333c-46.933333 0-85.333333-25.6-119.466666-68.266666-29.866667-38.4-42.666667-93.866667-42.666667-145.066667 0-55.466667 17.066667-106.666667 42.666667-145.066667 29.866667-42.666667 72.533333-68.266667 119.466666-68.266666 46.933333 0 85.333333 25.6 119.466667 68.266666 29.866667 38.4 42.666667 93.866667 42.666667 145.066667 0 55.466667-17.066667 106.666667-42.666667 145.066667-34.133333 46.933333-76.8 68.266667-119.466667 68.266666z m0-362.666666c-55.466667 0-98.133333 68.266667-98.133333 149.333333s46.933333 149.333333 98.133333 149.333333c55.466667 0 98.133333-68.266667 98.133334-149.333333s-46.933333-149.333333-98.133334-149.333333z',
|
||||
fill: '#978CFF',
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M354.133333 691.2a162.133333 21.333333 0 1 0 324.266667 0 162.133333 21.333333 0 1 0-324.266667 0Z',
|
||||
fill: '#E3E5FC',
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M8.533333 832a162.133333 21.333333 0 1 0 324.266667 0 162.133333 21.333333 0 1 0-324.266667 0Z',
|
||||
fill: '#E3E5FC',
|
||||
}),
|
||||
h('path', {
|
||||
d: 'M661.333333 797.866667a162.133333 21.333333 0 1 0 324.266667 0 162.133333 21.333333 0 1 0-324.266667 0Z',
|
||||
fill: '#E3E5FC',
|
||||
}),
|
||||
],
|
||||
),
|
||||
])
|
||||
},
|
||||
},
|
||||
// 动态加载的图标
|
||||
...dynamicIcons,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<el-dropdown placement="bottom-start" class="workspace-dropdown" popper-class="workspace-dropdown-popper">
|
||||
<el-button text style="font-size: 14px" class="workspace-dropdown__button">
|
||||
<AppIcon iconName="app-workspace" style="font-size: 18px"></AppIcon>
|
||||
<span class="ellipsis" style="max-width: 155px">
|
||||
<span class="ellipsis" style="max-width: 155px" :title="currentWorkspace?.name">
|
||||
{{ currentWorkspace?.name }}
|
||||
</span>
|
||||
<el-icon class="el-icon--right">
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
:class="`${item.id === currentWorkspace?.id ? 'active' : ''} flex-between`" @click="changeWorkspace(item)">
|
||||
<div class="flex align-center">
|
||||
<AppIcon class="mr-8" iconName="app-workspace" style="font-size: 16px"></AppIcon>
|
||||
<span class="ellipsis">
|
||||
<span class="ellipsis" :title="item.name">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ export default {
|
|||
label: '文本转语音',
|
||||
text: '将文本通过语音合成模型转换为音频',
|
||||
tts_model: {
|
||||
label: '语音识别模型',
|
||||
label: '语音合成模型',
|
||||
},
|
||||
content: {
|
||||
label: '选择文本内容',
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
import { useLocalStorage } from '@vueuse/core';
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { i18n, langCode, localeConfigKey } from '@/locales/index';
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { i18n, langCode, localeConfigKey } from '@/locales/index'
|
||||
|
||||
export function useLocale() {
|
||||
const { locale } = useI18n({ useScope: 'global' });
|
||||
function changeLocale(lang: string) {
|
||||
// 如果切换的语言不在对应语言文件里则默认为简体中文
|
||||
if (!langCode.includes(lang)) {
|
||||
lang = 'en-US';
|
||||
}
|
||||
|
||||
locale.value = lang;
|
||||
useLocalStorage(localeConfigKey, 'en-US').value = lang;
|
||||
const { locale } = useI18n({ useScope: 'global' })
|
||||
function changeLocale(lang: string) {
|
||||
// 如果切换的语言不在对应语言文件里则默认为简体中文
|
||||
if (!langCode.includes(lang)) {
|
||||
lang = 'en-US'
|
||||
}
|
||||
|
||||
const getComponentsLocale = computed(() => {
|
||||
const localeMessage = i18n.global.getLocaleMessage(locale.value) as Record<string, any>;
|
||||
return localeMessage.componentsLocale;
|
||||
});
|
||||
locale.value = lang
|
||||
useLocalStorage(localeConfigKey, 'en-US').value = lang
|
||||
}
|
||||
|
||||
return {
|
||||
changeLocale,
|
||||
getComponentsLocale,
|
||||
locale,
|
||||
};
|
||||
const getComponentsLocale = computed(() => {
|
||||
const localeMessage = i18n.global.getLocaleMessage(locale.value) as Record<string, any>
|
||||
return localeMessage.componentsLocale
|
||||
})
|
||||
|
||||
return {
|
||||
changeLocale,
|
||||
getComponentsLocale,
|
||||
locale,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ instance.interceptors.request.use(
|
|||
}
|
||||
const { chatUser } = useStore()
|
||||
const token = chatUser.getToken()
|
||||
// const language = chatUser.getLanguage()
|
||||
// config.headers['Accept-Language'] = `${language}`
|
||||
const language = chatUser.getLanguage()
|
||||
config.headers['Accept-Language'] = `${language}`
|
||||
if (token) {
|
||||
config.headers['AUTHORIZATION'] = `Bearer ${token}`
|
||||
}
|
||||
|
|
@ -177,12 +177,12 @@ export const postStream: (url: string, data?: unknown) => Promise<Result<any> |
|
|||
) => {
|
||||
const { chatUser } = useStore()
|
||||
const token = chatUser.getToken()
|
||||
// const language = user.getLanguage()
|
||||
const language = chatUser.getLanguage()
|
||||
const headers: HeadersInit = { 'Content-Type': 'application/json' }
|
||||
if (token) {
|
||||
headers['AUTHORIZATION'] = `Bearer ${token}`
|
||||
}
|
||||
// headers['Accept-Language'] = `${language}`
|
||||
headers['Accept-Language'] = `${language}`
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
body: data ? JSON.stringify(data) : undefined,
|
||||
|
|
|
|||
|
|
@ -47,27 +47,6 @@ const useApplicationStore = defineStore('application', {
|
|||
})
|
||||
},
|
||||
|
||||
async asyncAppAuthentication(
|
||||
token: string,
|
||||
loading?: Ref<boolean>,
|
||||
authentication_value?: any,
|
||||
) {
|
||||
return new Promise((resolve, reject) => {
|
||||
applicationApi
|
||||
.postAppAuthentication(token, loading, authentication_value)
|
||||
.then((res: any) => {
|
||||
localStorage.setItem(`${token}-accessToken`, res.data)
|
||||
sessionStorage.setItem(`${token}-accessToken`, res.data)
|
||||
resolve(res)
|
||||
})
|
||||
.catch((error: any) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
async refreshAccessToken(token: string) {
|
||||
this.asyncAppAuthentication(token)
|
||||
},
|
||||
// 修改应用
|
||||
async asyncPutApplication(id: string, data: any, loading?: Ref<boolean>) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@ import ChatAPI from '@/api/chat/chat'
|
|||
import type { ChatProfile, ChatUserProfile } from '@/api/type/chat'
|
||||
import type { LoginRequest } from '@/api/type/user'
|
||||
import type { Ref } from 'vue'
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { localeConfigKey } from '@/locales/index'
|
||||
import useUserStore from './user'
|
||||
import { getBrowserLang } from '@/locales/index'
|
||||
|
||||
interface ChatUser {
|
||||
// 用户id
|
||||
id: string
|
||||
|
|
@ -24,6 +23,9 @@ const useChatUserStore = defineStore('chat-user', {
|
|||
accessToken: undefined,
|
||||
}),
|
||||
actions: {
|
||||
getLanguage() {
|
||||
return localStorage.getItem(`${this.accessToken}-locale`) || getBrowserLang()
|
||||
},
|
||||
setAccessToken(accessToken: string) {
|
||||
this.accessToken = accessToken
|
||||
},
|
||||
|
|
@ -41,9 +43,8 @@ const useChatUserStore = defineStore('chat-user', {
|
|||
applicationProfile() {
|
||||
return ChatAPI.applicationProfile().then((ok) => {
|
||||
this.application = ok.data
|
||||
const user = useUserStore()
|
||||
useLocalStorage<string>(localeConfigKey, 'en-US').value =
|
||||
ok?.data?.language || user.getLanguage()
|
||||
localStorage.setItem(`${this.accessToken}-locale`, ok.data?.language || this.getLanguage())
|
||||
|
||||
if (this.application.custom_theme) {
|
||||
this.application['custom_theme']['theme_color'] =
|
||||
ok.data?.custom_theme?.theme_color || '#3370FF'
|
||||
|
|
|
|||
|
|
@ -1,32 +1,19 @@
|
|||
import {defineStore} from 'pinia'
|
||||
import {type Ref} from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { type Ref } from 'vue'
|
||||
import LoginApi from '@/api/user/login'
|
||||
import type {LoginRequest} from '@/api/type/login'
|
||||
import type { LoginRequest } from '@/api/type/login'
|
||||
import useUserStore from './user'
|
||||
|
||||
const useLoginStore = defineStore('login', {
|
||||
state: () => ({
|
||||
token: '',
|
||||
userAccessToken: '',
|
||||
}),
|
||||
actions: {
|
||||
getToken(): string | null {
|
||||
if (this.token) {
|
||||
return this.token
|
||||
}
|
||||
const user = useUserStore()
|
||||
return user.userType === 1 ? localStorage.getItem('token') : this.getAccessToken()
|
||||
},
|
||||
getAccessToken() {
|
||||
const token = sessionStorage.getItem(`${this.userAccessToken}-accessToken`)
|
||||
if (token) {
|
||||
return token
|
||||
}
|
||||
const local_token = localStorage.getItem(`${token}-accessToken`)
|
||||
if (local_token) {
|
||||
return local_token
|
||||
}
|
||||
return localStorage.getItem(`accessToken`)
|
||||
return localStorage.getItem('token')
|
||||
},
|
||||
|
||||
async asyncLogin(data: LoginRequest, loading?: Ref<boolean>) {
|
||||
|
|
@ -99,7 +86,6 @@ const useLoginStore = defineStore('login', {
|
|||
return ok.data
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import { defaultPlatformSetting } from '@/utils/theme'
|
|||
import useLoginStore from './login'
|
||||
|
||||
export interface userStateTypes {
|
||||
userType: number // 1 系统操作者 2 对话用户
|
||||
userInfo: User | null
|
||||
version?: string
|
||||
license_is_valid: boolean
|
||||
|
|
@ -22,7 +21,6 @@ export interface userStateTypes {
|
|||
|
||||
const useUserStore = defineStore('user', {
|
||||
state: (): userStateTypes => ({
|
||||
userType: 1, // 1 系统操作者 2 对话用户
|
||||
userInfo: null,
|
||||
version: '',
|
||||
license_is_valid: false,
|
||||
|
|
@ -32,11 +30,8 @@ const useUserStore = defineStore('user', {
|
|||
}),
|
||||
actions: {
|
||||
getLanguage() {
|
||||
return this.userType === 1
|
||||
? localStorage.getItem('MaxKB-locale') || getBrowserLang()
|
||||
: sessionStorage.getItem('language') || getBrowserLang()
|
||||
return localStorage.getItem('MaxKB-locale') || getBrowserLang()
|
||||
},
|
||||
|
||||
setWorkspaceId(workspace_id: string) {
|
||||
this.workspace_id = workspace_id
|
||||
localStorage.setItem('workspace_id', workspace_id)
|
||||
|
|
|
|||
|
|
@ -433,7 +433,6 @@ h5 {
|
|||
.layout-bg {
|
||||
background: var(--app-layout-bg-color);
|
||||
}
|
||||
|
||||
.white-bg {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-show="show" class="workflow-dropdown-menu border border-r-6">
|
||||
<div v-show="show" class="workflow-dropdown-menu border border-r-6 white-bg">
|
||||
<el-tabs v-model="activeName" class="workflow-dropdown-tabs">
|
||||
<div style="display: flex; width: 100%; justify-content: center" class="mb-12">
|
||||
<el-input
|
||||
|
|
@ -321,7 +321,6 @@ onMounted(() => {
|
|||
z-index: 99;
|
||||
width: 400px;
|
||||
box-shadow: 0px 4px 8px 0px var(--app-text-color-light-1);
|
||||
background: #ffffff;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.title {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="workflow-publish-history border-l">
|
||||
<div class="workflow-publish-history border-l white-bg">
|
||||
<h4 class="border-b p-16-24">{{ $t('views.applicationWorkflow.setting.releaseHistory') }}</h4>
|
||||
<div class="list-height pt-0">
|
||||
<el-scrollbar>
|
||||
|
|
@ -137,7 +137,6 @@ onMounted(() => {
|
|||
position: absolute;
|
||||
right: 0;
|
||||
top: 57px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 57px);
|
||||
z-index: 9;
|
||||
.list-height {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="application-workflow" v-loading="loading">
|
||||
<div class="header border-b flex-between p-12-24">
|
||||
<div class="header border-b flex-between p-12-24 white-bg">
|
||||
<div class="flex align-center">
|
||||
<back-button @click="back"></back-button>
|
||||
<h4>{{ detail?.name }}</h4>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
{{ $t('views.applicationWorkflow.setting.addComponent') }}
|
||||
</el-button>
|
||||
<el-button @click="clickShowDebug" :disabled="showDebug">
|
||||
<AppIcon iconName="app-play-outlined" class="mr-4"></AppIcon>
|
||||
<AppIcon iconName="app-debug-outlined" class="mr-4"></AppIcon>
|
||||
{{ $t('views.applicationWorkflow.setting.debug') }}</el-button
|
||||
>
|
||||
<el-button @click="saveApplication(true)">
|
||||
|
|
@ -142,7 +142,7 @@ import Workflow from '@/workflow/index.vue'
|
|||
import DropdownMenu from '@/views/application-workflow/component/DropdownMenu.vue'
|
||||
import PublishHistory from '@/views/application-workflow/component/PublishHistory.vue'
|
||||
import ApplicationAPI from '@/api/application/application'
|
||||
import { isAppIcon,resetUrl } from '@/utils/common'
|
||||
import { isAppIcon, resetUrl } from '@/utils/common'
|
||||
import { MsgSuccess, MsgError, MsgConfirm } from '@/utils/message'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
import { mapToUrlParams } from '@/utils/application'
|
||||
|
|
@ -575,9 +575,6 @@ onBeforeUnmount(() => {
|
|||
.application-workflow {
|
||||
background: var(--app-layout-bg-color);
|
||||
height: 100%;
|
||||
.header {
|
||||
background: #ffffff;
|
||||
}
|
||||
.workflow-main {
|
||||
height: calc(100vh - 62px);
|
||||
box-sizing: border-box;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@
|
|||
/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref, computed, onBeforeMount } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import useStore from '@/stores'
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { locale } = useI18n({ useScope: 'global' })
|
||||
const route = useRoute()
|
||||
const { chatUser, common } = useStore()
|
||||
|
||||
|
|
@ -23,7 +24,6 @@ const {
|
|||
} = route as any
|
||||
|
||||
const currentTemplate = computed(() => {
|
||||
console.log(common.isMobile())
|
||||
let modeName = ''
|
||||
if (!mode || mode === 'pc') {
|
||||
modeName = common.isMobile() ? 'mobile' : 'pc'
|
||||
|
|
@ -34,6 +34,8 @@ const currentTemplate = computed(() => {
|
|||
return components[name].default
|
||||
})
|
||||
|
||||
|
||||
const applicationAvailable = ref<boolean>(true)
|
||||
onBeforeMount(() => {
|
||||
locale.value = chatUser.getLanguage()
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form ref="FormRef" :model="form" @submit.prevent="validator">
|
||||
<el-form-item prop="value" :rules="rules">
|
||||
<el-input show-password v-model="form.value" />
|
||||
</el-form-item>
|
||||
<el-button class="w-full mt-8" type="primary" @click="validator" :loading="loading">
|
||||
{{ $t('common.confirm') }}</el-button
|
||||
>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import useStore from '@/stores'
|
||||
import { t } from '@/locales'
|
||||
const route = useRoute()
|
||||
const FormRef = ref()
|
||||
const {
|
||||
params: { accessToken },
|
||||
} = route as any
|
||||
const { application } = useStore()
|
||||
const loading = ref<boolean>(false)
|
||||
const auth = () => {
|
||||
return application.asyncAppAuthentication(accessToken, loading, form.value).then(() => {})
|
||||
}
|
||||
const validator_auth = (rule: any, value: string, callback: any) => {
|
||||
if (value === '') {
|
||||
callback(new Error(t('chat.passwordValidator.errorMessage1')))
|
||||
} else {
|
||||
auth().catch(() => {
|
||||
callback(new Error(t('chat.passwordValidator.errorMessage2')))
|
||||
})
|
||||
}
|
||||
}
|
||||
const validator = () => {
|
||||
FormRef.value.validate()
|
||||
}
|
||||
|
||||
const rules = reactive({
|
||||
value: [{ required: true, validator: validator_auth, trigger: 'manual' }],
|
||||
})
|
||||
|
||||
const form = ref({
|
||||
type: 'password',
|
||||
value: '',
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -16,13 +16,13 @@
|
|||
@click="changeLang(lang.value)"
|
||||
class="flex-between"
|
||||
>
|
||||
<span :class="lang.value === user.getLanguage() ? 'primary' : ''">{{
|
||||
<span :class="lang.value === chatUser.getLanguage() ? 'primary' : ''">{{
|
||||
lang.label
|
||||
}}</span>
|
||||
|
||||
<el-icon
|
||||
:class="lang.value === user.getLanguage() ? 'primary' : ''"
|
||||
v-if="lang.value === user.getLanguage()"
|
||||
:class="lang.value === chatUser.getLanguage() ? 'primary' : ''"
|
||||
v-if="lang.value === chatUser.getLanguage()"
|
||||
>
|
||||
<Check />
|
||||
</el-icon>
|
||||
|
|
@ -51,7 +51,7 @@ defineProps({
|
|||
default: true,
|
||||
},
|
||||
})
|
||||
const { user, theme } = useStore()
|
||||
const { chatUser, theme } = useStore()
|
||||
|
||||
const changeLang = (lang: string) => {
|
||||
useLocalStorage(localeConfigKey, getBrowserLang()).value = lang
|
||||
|
|
@ -59,7 +59,7 @@ const changeLang = (lang: string) => {
|
|||
}
|
||||
|
||||
const currentLanguage = computed(() => {
|
||||
return langList.value?.filter((v: any) => v.value === user.getLanguage())?.[0]?.label
|
||||
return langList.value?.filter((v: any) => v.value === chatUser.getLanguage())?.[0]?.label
|
||||
})
|
||||
|
||||
const fileURL = computed(() => {
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ import PasswordAuth from '@/views/chat/auth/component/password.vue'
|
|||
import { isAppIcon } from '@/utils/common'
|
||||
|
||||
const router = useRouter()
|
||||
const { login, user, theme, chatUser } = useStore()
|
||||
const { theme, chatUser } = useStore()
|
||||
const { locale } = useI18n({ useScope: 'global' })
|
||||
const loading = ref<boolean>(false)
|
||||
const route = useRoute()
|
||||
|
|
@ -226,6 +226,7 @@ function makeCode() {
|
|||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
locale.value = chatUser.getLanguage()
|
||||
makeCode()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="login-preview mr-16">
|
||||
<div class="login-preview mr-16 white-bg">
|
||||
<div class="header">
|
||||
<div class="tag flex-between">
|
||||
<div class="flex align-center">
|
||||
|
|
@ -78,7 +78,6 @@ const fileURL = computed(() => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.login-preview {
|
||||
background: #ffffff;
|
||||
border-radius: 4px;
|
||||
transform-origin: center;
|
||||
.login-container {
|
||||
|
|
|
|||
Loading…
Reference in New Issue