feat: chat message ui (#3275)
This commit is contained in:
parent
6fc0558f63
commit
00e486c3fe
@ -315,7 +315,7 @@ class ChatSerializers(serializers.Serializer):
|
|||||||
|
|
||||||
|
|
||||||
class OpenChatSerializers(serializers.Serializer):
|
class OpenChatSerializers(serializers.Serializer):
|
||||||
workspace_id = serializers.CharField(required=True)
|
workspace_id = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_("Workspace ID"))
|
||||||
application_id = serializers.UUIDField(required=True)
|
application_id = serializers.UUIDField(required=True)
|
||||||
chat_user_id = serializers.CharField(required=True, label=_("Client id"))
|
chat_user_id = serializers.CharField(required=True, label=_("Client id"))
|
||||||
chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
|
chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
|
||||||
@ -325,7 +325,10 @@ class OpenChatSerializers(serializers.Serializer):
|
|||||||
super().is_valid(raise_exception=True)
|
super().is_valid(raise_exception=True)
|
||||||
workspace_id = self.data.get('workspace_id')
|
workspace_id = self.data.get('workspace_id')
|
||||||
application_id = self.data.get('application_id')
|
application_id = self.data.get('application_id')
|
||||||
if not QuerySet(Application).filter(id=application_id, workspace_id=workspace_id).exists():
|
query_set = QuerySet(Application).filter(id=application_id)
|
||||||
|
if workspace_id:
|
||||||
|
query_set = query_set.filter(workspace_id=workspace_id)
|
||||||
|
if not query_set.exists():
|
||||||
raise AppApiException(500, gettext('Application does not exist'))
|
raise AppApiException(500, gettext('Application does not exist'))
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
|
|||||||
@ -126,6 +126,8 @@ class ApplicationProfileSerializer(serializers.Serializer):
|
|||||||
'user_avatar': application_setting.user_avatar,
|
'user_avatar': application_setting.user_avatar,
|
||||||
'show_user_avatar': application_setting.show_user_avatar,
|
'show_user_avatar': application_setting.show_user_avatar,
|
||||||
'float_location': application_setting.float_location}
|
'float_location': application_setting.float_location}
|
||||||
|
base_node = [node for node in ((application.work_flow or {}).get('nodes', []) or []) if
|
||||||
|
node.get('id') == 'base-node']
|
||||||
return {**ApplicationSerializerModel(application).data,
|
return {**ApplicationSerializerModel(application).data,
|
||||||
'stt_model_id': application.stt_model_id,
|
'stt_model_id': application.stt_model_id,
|
||||||
'tts_model_id': application.tts_model_id,
|
'tts_model_id': application.tts_model_id,
|
||||||
@ -136,8 +138,7 @@ class ApplicationProfileSerializer(serializers.Serializer):
|
|||||||
'stt_autosend': application.stt_autosend,
|
'stt_autosend': application.stt_autosend,
|
||||||
'file_upload_enable': application.file_upload_enable,
|
'file_upload_enable': application.file_upload_enable,
|
||||||
'file_upload_setting': application.file_upload_setting,
|
'file_upload_setting': application.file_upload_setting,
|
||||||
'work_flow': {'nodes': [node for node in ((application.work_flow or {}).get('nodes', []) or []) if
|
'work_flow': {'nodes': base_node} if base_node else None,
|
||||||
node.get('id') == 'base-node']},
|
|
||||||
'show_source': application_access_token.show_source,
|
'show_source': application_access_token.show_source,
|
||||||
'language': application_access_token.language,
|
'language': application_access_token.language,
|
||||||
**application_setting_dict}
|
**application_setting_dict}
|
||||||
|
|||||||
@ -5,10 +5,10 @@ from . import views
|
|||||||
app_name = 'chat'
|
app_name = 'chat'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('chat/embed', views.ChatEmbedView.as_view()),
|
path('embed', views.ChatEmbedView.as_view()),
|
||||||
path('application/anonymous_authentication', views.AnonymousAuthentication.as_view()),
|
path('auth/anonymous', views.AnonymousAuthentication.as_view()),
|
||||||
path('auth/profile', views.AuthProfile.as_view()),
|
path('profile', views.AuthProfile.as_view()),
|
||||||
path('profile', views.ApplicationProfile.as_view()),
|
path('application/profile', views.ApplicationProfile.as_view()),
|
||||||
path('chat_message/<str:chat_id>', views.ChatView.as_view()),
|
path('chat_message/<str:chat_id>', views.ChatView.as_view()),
|
||||||
path('workspace/<str:workspace_id>/application/<str:application_id>/open', views.OpenView.as_view())
|
path('open', views.OpenView.as_view())
|
||||||
]
|
]
|
||||||
|
|||||||
@ -100,7 +100,8 @@ class ChatView(APIView):
|
|||||||
return ChatSerializers(data={'chat_id': chat_id,
|
return ChatSerializers(data={'chat_id': chat_id,
|
||||||
'chat_user_id': request.auth.chat_user_id,
|
'chat_user_id': request.auth.chat_user_id,
|
||||||
'chat_user_type': request.auth.chat_user_type,
|
'chat_user_type': request.auth.chat_user_type,
|
||||||
'application_id': request.auth.application_id}
|
'application_id': request.auth.application_id,
|
||||||
|
'debug': False}
|
||||||
).chat(request.data)
|
).chat(request.data)
|
||||||
|
|
||||||
|
|
||||||
@ -116,7 +117,8 @@ class OpenView(APIView):
|
|||||||
responses=None,
|
responses=None,
|
||||||
tags=[_('Chat')] # type: ignore
|
tags=[_('Chat')] # type: ignore
|
||||||
)
|
)
|
||||||
def get(self, request: Request, workspace_id: str, application_id: str):
|
def get(self, request: Request):
|
||||||
return result.success(OpenChatSerializers(
|
return result.success(OpenChatSerializers(
|
||||||
data={'workspace_id': workspace_id, 'application_id': application_id,
|
data={'application_id': request.auth.application_id,
|
||||||
'chat_user_id': request.auth.chat_user_id, 'chat_user_type': request.auth.chat_user_type}).open())
|
'chat_user_id': request.auth.chat_user_id, 'chat_user_type': request.auth.chat_user_type,
|
||||||
|
'debug': False}).open())
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
download,
|
download,
|
||||||
exportFile,
|
exportFile,
|
||||||
} from '@/request/chat/index'
|
} from '@/request/chat/index'
|
||||||
|
import { type ChatProfile } from '@/api/type/chat'
|
||||||
import { type Ref } from 'vue'
|
import { type Ref } from 'vue'
|
||||||
|
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
@ -27,11 +27,9 @@ Object.defineProperty(prefix, 'value', {
|
|||||||
* @param loading 加载器
|
* @param loading 加载器
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const open: (application_id: string, loading?: Ref<boolean>) => Promise<Result<string>> = (
|
const open: (loading?: Ref<boolean>) => Promise<Result<string>> = (loading) => {
|
||||||
application_id,
|
return get('/open', {}, loading)
|
||||||
loading,
|
|
||||||
) => {
|
|
||||||
return get(`${prefix.value}/${application_id}/open`, {}, loading)
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 对话
|
* 对话
|
||||||
@ -40,22 +38,38 @@ const open: (application_id: string, loading?: Ref<boolean>) => Promise<Result<s
|
|||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
const chat: (chat_id: string, data: any) => Promise<any> = (chat_id, data) => {
|
const chat: (chat_id: string, data: any) => Promise<any> = (chat_id, data) => {
|
||||||
return postStream(`/api/chat_message/${chat_id}`, data)
|
return postStream(`/chat/api/chat_message/${chat_id}`, data)
|
||||||
}
|
}
|
||||||
const chatProfile: (assessToken: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
const chatProfile: (assessToken: string, loading?: Ref<boolean>) => Promise<Result<ChatProfile>> = (
|
||||||
assessToken,
|
assessToken,
|
||||||
loading,
|
loading,
|
||||||
) => {
|
) => {
|
||||||
return get('/auth/profile', { access_token: assessToken }, loading)
|
return get('/profile', { access_token: assessToken }, loading)
|
||||||
}
|
}
|
||||||
const applicationProfile: (assessToken: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
/**
|
||||||
assessToken,
|
* 匿名认证
|
||||||
loading,
|
* @param assessToken
|
||||||
) => {
|
* @param loading
|
||||||
return get('/chat/api/profile')
|
* @returns
|
||||||
|
*/
|
||||||
|
const anonymousAuthentication: (
|
||||||
|
assessToken: string,
|
||||||
|
loading?: Ref<boolean>,
|
||||||
|
) => Promise<Result<any>> = (assessToken, loading) => {
|
||||||
|
return post('/auth/anonymous', { access_token: assessToken }, {}, loading)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取应用相关信息
|
||||||
|
* @param loading
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const applicationProfile: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) => {
|
||||||
|
return get('/application/profile', {}, loading)
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
open,
|
open,
|
||||||
chat,
|
chat,
|
||||||
chatProfile,
|
chatProfile,
|
||||||
|
anonymousAuthentication,
|
||||||
|
applicationProfile,
|
||||||
}
|
}
|
||||||
|
|||||||
15
ui/src/api/type/chat.ts
Normal file
15
ui/src/api/type/chat.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
interface ChatProfile {
|
||||||
|
// 是否开启认证
|
||||||
|
authentication: boolean
|
||||||
|
// icon
|
||||||
|
icon?: string
|
||||||
|
// 应用名称
|
||||||
|
application_name?: string
|
||||||
|
// 背景图
|
||||||
|
bg_icon?: string
|
||||||
|
// 认证类型
|
||||||
|
authentication_type?: 'password' | 'login'
|
||||||
|
// 登录类型
|
||||||
|
login_value?: Array<string>
|
||||||
|
}
|
||||||
|
export { type ChatProfile }
|
||||||
@ -85,9 +85,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, nextTick, computed, watch, reactive, onMounted, onBeforeUnmount } from 'vue'
|
import { type Ref, ref, nextTick, computed, watch, reactive, onMounted, onBeforeUnmount } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import applicationApi from '@/api/application/application'
|
import applicationApi from '@/api/application/application'
|
||||||
|
import chatAPI from '@/api/chat/chat'
|
||||||
import chatLogApi from '@/api/application/chat-log'
|
import chatLogApi from '@/api/application/chat-log'
|
||||||
import { ChatManagement, type chatType } from '@/api/type/application'
|
import { ChatManagement, type chatType } from '@/api/type/application'
|
||||||
import { randomId } from '@/utils/utils'
|
import { randomId } from '@/utils/utils'
|
||||||
@ -280,23 +281,35 @@ const handleDebounceClick = debounce((val, other_params_data?: any, chat?: chatT
|
|||||||
*/
|
*/
|
||||||
const openChatId: () => Promise<string> = () => {
|
const openChatId: () => Promise<string> = () => {
|
||||||
const obj = props.applicationDetails
|
const obj = props.applicationDetails
|
||||||
|
return getOpenChatAPI()(obj.id)
|
||||||
|
.then((res) => {
|
||||||
|
chartOpenId.value = res.data
|
||||||
|
return res.data
|
||||||
|
})
|
||||||
|
.catch((res) => {
|
||||||
|
if (res.response.status === 403) {
|
||||||
|
return application.asyncAppAuthentication(accessToken).then(() => {
|
||||||
|
return openChatId()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Promise.reject(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChatMessageAPI = () => {
|
||||||
if (props.type === 'debug-ai-chat') {
|
if (props.type === 'debug-ai-chat') {
|
||||||
return applicationApi
|
return applicationApi.chat
|
||||||
.open(obj.id)
|
|
||||||
.then((res) => {
|
|
||||||
chartOpenId.value = res.data
|
|
||||||
return res.data
|
|
||||||
})
|
|
||||||
.catch((res) => {
|
|
||||||
if (res.response.status === 403) {
|
|
||||||
return application.asyncAppAuthentication(accessToken).then(() => {
|
|
||||||
return openChatId()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return Promise.reject(res)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject('暂不支持')
|
return chatAPI.chat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getOpenChatAPI = () => {
|
||||||
|
if (props.type === 'debug-ai-chat') {
|
||||||
|
return applicationApi.open
|
||||||
|
} else {
|
||||||
|
return (a?: string, loading?: Ref<boolean>) => {
|
||||||
|
return chatAPI.open(loading)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -453,8 +466,7 @@ function chatMessage(chat?: any, problem?: string, re_chat?: boolean, other_para
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
// 对话
|
// 对话
|
||||||
applicationApi
|
getChatMessageAPI()(chartOpenId.value, obj)
|
||||||
.chat(chartOpenId.value, obj)
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
application
|
application
|
||||||
|
|||||||
@ -23,10 +23,10 @@ instance.interceptors.request.use(
|
|||||||
if (config.headers === undefined) {
|
if (config.headers === undefined) {
|
||||||
config.headers = new AxiosHeaders()
|
config.headers = new AxiosHeaders()
|
||||||
}
|
}
|
||||||
const { user, login } = useStore()
|
const { chatUser } = useStore()
|
||||||
const token = login.getToken()
|
const token = chatUser.getToken()
|
||||||
const language = user.getLanguage()
|
// const language = chatUser.getLanguage()
|
||||||
config.headers['Accept-Language'] = `${language}`
|
// config.headers['Accept-Language'] = `${language}`
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers['AUTHORIZATION'] = `Bearer ${token}`
|
config.headers['AUTHORIZATION'] = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
@ -203,14 +203,14 @@ export const postStream: (url: string, data?: unknown) => Promise<Result<any> |
|
|||||||
url,
|
url,
|
||||||
data,
|
data,
|
||||||
) => {
|
) => {
|
||||||
const { user, login } = useStore()
|
const { chatUser } = useStore()
|
||||||
const token = login.getToken()
|
const token = chatUser.getToken()
|
||||||
const language = user.getLanguage()
|
// const language = user.getLanguage()
|
||||||
const headers: HeadersInit = { 'Content-Type': 'application/json' }
|
const headers: HeadersInit = { 'Content-Type': 'application/json' }
|
||||||
if (token) {
|
if (token) {
|
||||||
headers['AUTHORIZATION'] = `Bearer ${token}`
|
headers['AUTHORIZATION'] = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
headers['Accept-Language'] = `${language}`
|
// headers['Accept-Language'] = `${language}`
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: data ? JSON.stringify(data) : undefined,
|
body: data ? JSON.stringify(data) : undefined,
|
||||||
|
|||||||
@ -20,26 +20,39 @@ const router = createRouter({
|
|||||||
router.beforeEach(
|
router.beforeEach(
|
||||||
async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
|
async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
if (to.name === '404') {
|
if (to.path === '/404') {
|
||||||
next()
|
next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { user, login } = useStore()
|
const { chatUser } = useStore()
|
||||||
|
const notAuthRouteNameList = ['UserLogin']
|
||||||
const notAuthRouteNameList = ['login', 'ForgotPassword', 'ResetPassword', 'Chat', 'UserLogin']
|
|
||||||
if (!notAuthRouteNameList.includes(to.name ? to.name.toString() : '')) {
|
if (!notAuthRouteNameList.includes(to.name ? to.name.toString() : '')) {
|
||||||
if (to.query && to.query.token) {
|
if (to.params && to.params.accessToken) {
|
||||||
localStorage.setItem('token', to.query.token.toString())
|
chatUser.setAccessToken(to.params.accessToken.toString())
|
||||||
}
|
} else {
|
||||||
const token = login.getToken()
|
|
||||||
if (!token) {
|
|
||||||
next({
|
next({
|
||||||
path: '/login',
|
path: '/404',
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!user.userInfo) {
|
const token = chatUser.getToken()
|
||||||
await user.profile()
|
const authentication = await chatUser.isAuthentication()
|
||||||
|
if (authentication) {
|
||||||
|
if (!token) {
|
||||||
|
next({
|
||||||
|
name: 'UserLogin',
|
||||||
|
params: {
|
||||||
|
accessToken: to.params.accessToken,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await chatUser.anonymousAuthentication()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chatUser.application) {
|
||||||
|
await chatUser.applicationProfile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 判断是否有菜单权限
|
// 判断是否有菜单权限
|
||||||
|
|||||||
@ -4,13 +4,19 @@ export const routes: Array<RouteRecordRaw> = [
|
|||||||
// 对话
|
// 对话
|
||||||
{
|
{
|
||||||
path: '/:accessToken',
|
path: '/:accessToken',
|
||||||
name: 'Chat',
|
name: 'chat',
|
||||||
component: () => import('@/views/chat/index.vue'),
|
component: () => import('@/views/chat/index.vue'),
|
||||||
},
|
},
|
||||||
// 对话用户登录
|
// 对话用户登录
|
||||||
{
|
{
|
||||||
path: '/user-login/:accessToken',
|
path: '/user-login/:accessToken',
|
||||||
name: 'UserLogin',
|
name: 'user_login',
|
||||||
component: () => import('@/views/chat/user-login/index.vue'),
|
component: () => import('@/views/chat/user-login/index.vue'),
|
||||||
},
|
},
|
||||||
|
// 对话用户登录
|
||||||
|
{
|
||||||
|
path: '/404',
|
||||||
|
name: '404',
|
||||||
|
component: () => import('@/views/404/index.vue'),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import useParagraphStore from './modules/paragraph'
|
|||||||
import useDocumentStore from './modules/document'
|
import useDocumentStore from './modules/document'
|
||||||
import useApplicationStore from './modules/application'
|
import useApplicationStore from './modules/application'
|
||||||
import useChatLogStore from './modules/chat-log'
|
import useChatLogStore from './modules/chat-log'
|
||||||
|
import useChatUserStore from './modules/chat-user'
|
||||||
const useStore = () => ({
|
const useStore = () => ({
|
||||||
common: useCommonStore(),
|
common: useCommonStore(),
|
||||||
login: useLoginStore(),
|
login: useLoginStore(),
|
||||||
@ -25,6 +26,7 @@ const useStore = () => ({
|
|||||||
document: useDocumentStore(),
|
document: useDocumentStore(),
|
||||||
application: useApplicationStore(),
|
application: useApplicationStore(),
|
||||||
chatLog: useChatLogStore(),
|
chatLog: useChatLogStore(),
|
||||||
|
chatUser: useChatUserStore(),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default useStore
|
export default useStore
|
||||||
|
|||||||
74
ui/src/stores/modules/chat-user.ts
Normal file
74
ui/src/stores/modules/chat-user.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import ChatAPI from '@/api/chat/chat'
|
||||||
|
import { type ChatProfile } from '@/api/type/chat'
|
||||||
|
|
||||||
|
interface ChatUser {
|
||||||
|
// 用户id
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
interface Application {}
|
||||||
|
interface Chat {
|
||||||
|
chat_profile?: ChatProfile
|
||||||
|
application?: Application
|
||||||
|
token?: string
|
||||||
|
accessToken?: string
|
||||||
|
}
|
||||||
|
const useChatUserStore = defineStore('chat-user', {
|
||||||
|
state: (): Chat => ({
|
||||||
|
chat_profile: undefined,
|
||||||
|
application: undefined,
|
||||||
|
accessToken: undefined,
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setAccessToken(accessToken: string) {
|
||||||
|
this.accessToken = accessToken
|
||||||
|
},
|
||||||
|
getChatProfile() {
|
||||||
|
return ChatAPI.chatProfile(this.accessToken as string).then((ok) => {
|
||||||
|
this.chat_profile = ok.data
|
||||||
|
return this.chat_profile
|
||||||
|
})
|
||||||
|
},
|
||||||
|
applicationProfile() {
|
||||||
|
return ChatAPI.applicationProfile().then((ok) => {
|
||||||
|
this.application = ok.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
isAuthentication() {
|
||||||
|
if (this.chat_profile) {
|
||||||
|
return Promise.resolve(this.chat_profile.authentication)
|
||||||
|
} else {
|
||||||
|
return this.getChatProfile().then((ok) => {
|
||||||
|
return ok.authentication
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getToken() {
|
||||||
|
if (this.token) {
|
||||||
|
return this.token
|
||||||
|
}
|
||||||
|
const token = sessionStorage.getItem(`${this.accessToken}-accessToken`)
|
||||||
|
if (token) {
|
||||||
|
this.token = token
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
const local_token = localStorage.getItem(`${this.accessToken}-accessToken`)
|
||||||
|
if (local_token) {
|
||||||
|
this.token = local_token
|
||||||
|
return local_token
|
||||||
|
}
|
||||||
|
return localStorage.getItem(`accessToken`)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
*匿名认证
|
||||||
|
*/
|
||||||
|
anonymousAuthentication() {
|
||||||
|
return ChatAPI.anonymousAuthentication(this.accessToken as string).then((ok) => {
|
||||||
|
this.token = ok.data
|
||||||
|
return this.token
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default useChatUserStore
|
||||||
51
ui/src/views/404/index.vue
Normal file
51
ui/src/views/404/index.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<el-row class="not-found-container">
|
||||||
|
<el-col class="img" :xs="0" :sm="0" :md="12" :lg="12" :xl="12"> </el-col>
|
||||||
|
<el-col class="message-container" :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
|
||||||
|
<div class="title">{{ $t('views.notFound.title') }}</div>
|
||||||
|
<div class="message">{{ $t('views.notFound.message') }}</div>
|
||||||
|
<!-- TODO 暂时不处理 -->
|
||||||
|
<!-- <div class="operate"><el-button type="primary" @click="router.push('/')">{{ $t('views.notFound.operate') }}</el-button></div> -->
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
const router = useRouter()
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.not-found-container {
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.img {
|
||||||
|
background-image: url('@/assets/404.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-container {
|
||||||
|
color: var(--app-text-color);
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 50px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 30px 0 20px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1000px) {
|
||||||
|
.not-found-container .message-container {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,35 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
v-if="chat_show && init_data_end"
|
|
||||||
:applicationAvailable="applicationAvailable"
|
:applicationAvailable="applicationAvailable"
|
||||||
:is="currentTemplate"
|
:is="currentTemplate"
|
||||||
:application_profile="application_profile"
|
:application_profile="chatUser.application"
|
||||||
:key="route.fullPath"
|
:key="route.fullPath"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
/>
|
/>
|
||||||
<Auth
|
|
||||||
v-else
|
|
||||||
:application_profile="application_profile"
|
|
||||||
:auth_type="application_profile.authentication_type"
|
|
||||||
v-model="is_auth"
|
|
||||||
:style="{
|
|
||||||
'--el-color-primary': application_profile?.custom_theme?.theme_color,
|
|
||||||
'--el-color-primary-light-9': hexToRgba(application_profile?.custom_theme?.theme_color, 0.1),
|
|
||||||
}"
|
|
||||||
></Auth>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onBeforeMount, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
import Auth from '@/views/chat/auth/index.vue'
|
|
||||||
import { hexToRgba } from '@/utils/theme'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { getBrowserLang } from '@/locales/index'
|
|
||||||
import ChatAPI from '@/api/chat/chat.ts'
|
|
||||||
const { locale } = useI18n({ useScope: 'global' })
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { application, user } = useStore()
|
const { chatUser } = useStore()
|
||||||
|
|
||||||
const components: any = import.meta.glob('@/views/chat/**/index.vue', {
|
const components: any = import.meta.glob('@/views/chat/**/index.vue', {
|
||||||
eager: true,
|
eager: true,
|
||||||
@ -39,71 +23,20 @@ const {
|
|||||||
query: { mode },
|
query: { mode },
|
||||||
params: { accessToken },
|
params: { accessToken },
|
||||||
} = route as any
|
} = route as any
|
||||||
const is_auth = ref<boolean>(false)
|
|
||||||
const currentTemplate = computed(() => {
|
const currentTemplate = computed(() => {
|
||||||
let modeName = ''
|
let modeName = ''
|
||||||
if (!mode || mode === 'pc') {
|
if (!mode || mode === 'pc') {
|
||||||
modeName = show_history.value || !user.isEnterprise() ? 'pc' : 'base'
|
modeName = 'pc'
|
||||||
} else {
|
} else {
|
||||||
modeName = mode
|
modeName = mode
|
||||||
}
|
}
|
||||||
const name = `/src/views/chat/${modeName}/index.vue`
|
const name = `/src/views/chat/${modeName}/index.vue`
|
||||||
return components[name].default
|
return components[name].default
|
||||||
})
|
})
|
||||||
/**
|
|
||||||
* 是否显示对话
|
|
||||||
*/
|
|
||||||
const chat_show = computed(() => {
|
|
||||||
if (init_data_end.value) {
|
|
||||||
if (!applicationAvailable.value) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (application_profile.value) {
|
|
||||||
if (application_profile.value.authentication && is_auth.value) {
|
|
||||||
return true
|
|
||||||
} else if (!application_profile.value.authentication) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
const show_history = ref(false)
|
|
||||||
|
|
||||||
const application_profile = ref<any>({})
|
|
||||||
/**
|
|
||||||
|
|
||||||
* 初始化结束
|
|
||||||
*/
|
|
||||||
const init_data_end = ref<boolean>(false)
|
|
||||||
|
|
||||||
const applicationAvailable = ref<boolean>(true)
|
const applicationAvailable = ref<boolean>(true)
|
||||||
function getAppProfile() {
|
|
||||||
return application.asyncGetAppProfile(loading).then((res: any) => {
|
|
||||||
locale.value = res.data?.language || getBrowserLang()
|
|
||||||
show_history.value = res.data?.show_history
|
|
||||||
application_profile.value = res.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function getAccessToken(token: string) {
|
|
||||||
return application.asyncAppAuthentication(token, loading).then(() => {
|
|
||||||
return getAppProfile()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const getChatProfile = () => {
|
|
||||||
return ChatAPI.chatProfile(accessToken).then((ok: any) => {
|
|
||||||
console.log(ok)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onBeforeMount(() => {
|
|
||||||
user.changeUserType(2, accessToken)
|
|
||||||
Promise.all([user.asyncGetProfile(), getChatProfile()])
|
|
||||||
.catch(() => {
|
|
||||||
applicationAvailable.value = false
|
|
||||||
})
|
|
||||||
.finally(() => (init_data_end.value = true))
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@ -13,6 +13,7 @@ const envDir = './env'
|
|||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
const ENV = loadEnv(mode, envDir)
|
const ENV = loadEnv(mode, envDir)
|
||||||
|
console.log(ENV)
|
||||||
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
|
const prefix = process.env.VITE_DYNAMIC_PREFIX || ENV.VITE_BASE_PATH
|
||||||
const proxyConf: Record<string, string | ProxyOptions> = {}
|
const proxyConf: Record<string, string | ProxyOptions> = {}
|
||||||
proxyConf['/api'] = {
|
proxyConf['/api'] = {
|
||||||
@ -25,10 +26,9 @@ export default defineConfig(({ mode }) => {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
||||||
}
|
}
|
||||||
proxyConf['/chat'] = {
|
proxyConf['/chat/api'] = {
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path: string) => path.replace(ENV.VITE_BASE_PATH, '/'),
|
|
||||||
}
|
}
|
||||||
proxyConf['/doc'] = {
|
proxyConf['/doc'] = {
|
||||||
target: 'http://127.0.0.1:8080',
|
target: 'http://127.0.0.1:8080',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user