feat: chat

This commit is contained in:
wangdan-fit2cloud 2025-06-13 21:56:01 +08:00
parent 5acf2f60e5
commit 16b1a79c0b
8 changed files with 190 additions and 222 deletions

2
ui/env/.env.chat vendored
View File

@ -1,5 +1,5 @@
VITE_APP_NAME=chat VITE_APP_NAME=chat
VITE_BASE_PATH=/chat/ VITE_BASE_PATH=/chat/
VITE_APP_PORT=3000 VITE_APP_PORT=3001
VITE_APP_TITLE = 'MaxKB' VITE_APP_TITLE = 'MaxKB'
VITE_ENTRY="entry/chat/index.html" VITE_ENTRY="entry/chat/index.html"

View File

@ -3,8 +3,14 @@ import type { RouteRecordRaw } from 'vue-router'
export const routes: Array<RouteRecordRaw> = [ export const routes: Array<RouteRecordRaw> = [
// 对话 // 对话
{ {
path: '/chat/:accessToken', path: '/:accessToken',
name: 'Chat', name: 'Chat',
component: () => import('@/views/chat/index.vue'), component: () => import('@/views/chat/index.vue'),
}, },
// 对话用户登录
{
path: '/user-login/:accessToken',
name: 'UserLogin',
component: () => import('@/views/chat/user-login/index.vue'),
},
] ]

View File

@ -62,15 +62,16 @@ const useApplicationStore = defineStore('application', {
async asyncGetAppProfile(loading?: Ref<boolean>) { async asyncGetAppProfile(loading?: Ref<boolean>) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// applicationApi console.log('xxxx')
// .getAppProfile(loading) applicationApi
// .then((res) => { .getAppProfile(loading)
// sessionStorage.setItem('language', res.data?.language || getBrowserLang()) .then((res) => {
// resolve(res) sessionStorage.setItem('language', res.data?.language || getBrowserLang())
// }) resolve(res)
// .catch((error) => { })
// reject(error) .catch((error) => {
// }) reject(error)
})
}) })
}, },
@ -80,16 +81,16 @@ const useApplicationStore = defineStore('application', {
authentication_value?: any, authentication_value?: any,
) { ) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// applicationApi applicationApi
// .postAppAuthentication(token, loading, authentication_value) .postAppAuthentication(token, loading, authentication_value)
// .then((res) => { .then((res) => {
// localStorage.setItem(`${token}-accessToken`, res.data) localStorage.setItem(`${token}-accessToken`, res.data)
// sessionStorage.setItem(`${token}-accessToken`, res.data) sessionStorage.setItem(`${token}-accessToken`, res.data)
// resolve(res) resolve(res)
// }) })
// .catch((error) => { .catch((error) => {
// reject(error) reject(error)
// }) })
}) })
}, },
async refreshAccessToken(token: string) { async refreshAccessToken(token: string) {

View File

@ -41,12 +41,10 @@
> >
<img :src="detail?.icon" alt="" /> <img :src="detail?.icon" alt="" />
</el-avatar> </el-avatar>
<el-avatar <LogoIcon
v-else-if="detail?.name" v-else
:name="detail?.name" height="28px"
pinyinColor style="width: 28px; height: 28px; display: block"
shape="square"
:size="32"
/> />
</div> </div>

View File

@ -92,13 +92,7 @@
> >
<img :src="detail?.icon" alt="" /> <img :src="detail?.icon" alt="" />
</el-avatar> </el-avatar>
<el-avatar <LogoIcon v-else height="28px" style="width: 28px; height: 28px; display: block" />
v-else-if="detail?.name"
:name="detail?.name"
pinyinColor
shape="square"
:size="32"
/>
</div> </div>
<h4> <h4>
@ -157,7 +151,7 @@ const isDefaultTheme = computed(() => {
return user.isDefaultTheme() return user.isDefaultTheme()
}) })
const { const {
params: { id } params: { id },
} = route as any } = route as any
let interval: any let interval: any
@ -182,7 +176,7 @@ function back() {
confirmButtonText: t('views.applicationWorkflow.setting.exitSave'), confirmButtonText: t('views.applicationWorkflow.setting.exitSave'),
cancelButtonText: t('views.applicationWorkflow.setting.exit'), cancelButtonText: t('views.applicationWorkflow.setting.exit'),
type: 'warning', type: 'warning',
distinguishCancelAndClose: true distinguishCancelAndClose: true,
}) })
.then(() => { .then(() => {
saveApplication(true, true) saveApplication(true, true)
@ -268,7 +262,7 @@ async function publicHandle() {
?.validate() ?.validate()
.then(async () => { .then(async () => {
const obj = { const obj = {
work_flow: getGraphData() work_flow: getGraphData(),
} }
await application.asyncPutApplication(id, obj, loading) await application.asyncPutApplication(id, obj, loading)
const workflow = new WorkFlowInstance(obj.work_flow) const workflow = new WorkFlowInstance(obj.work_flow)
@ -293,14 +287,14 @@ async function publicHandle() {
MsgError( MsgError(
res.node.properties?.stepName + res.node.properties?.stepName +
` ${t('views.applicationWorkflow.node').toLowerCase()} ` + ` ${t('views.applicationWorkflow.node').toLowerCase()} ` +
err_message.toLowerCase() err_message.toLowerCase(),
) )
} else { } else {
const keys = Object.keys(err_message) const keys = Object.keys(err_message)
MsgError( MsgError(
node.properties?.stepName + node.properties?.stepName +
` ${t('views.applicationWorkflow.node').toLowerCase()} ` + ` ${t('views.applicationWorkflow.node').toLowerCase()} ` +
err_message[keys[0]]?.[0]?.message.toLowerCase() err_message[keys[0]]?.[0]?.message.toLowerCase(),
) )
} }
}) })
@ -318,7 +312,7 @@ const clickShowDebug = () => {
...detail.value, ...detail.value,
type: 'WORK_FLOW', type: 'WORK_FLOW',
...workflow.get_base_node()?.properties.node_data, ...workflow.get_base_node()?.properties.node_data,
work_flow: getGraphData() work_flow: getGraphData(),
} }
showDebug.value = true showDebug.value = true
@ -331,14 +325,14 @@ const clickShowDebug = () => {
const err_message = res.errMessage const err_message = res.errMessage
if (typeof err_message == 'string') { if (typeof err_message == 'string') {
MsgError( MsgError(
res.node.properties?.stepName + ` ${t('views.applicationWorkflow.node')}` + err_message res.node.properties?.stepName + ` ${t('views.applicationWorkflow.node')}` + err_message,
) )
} else { } else {
const keys = Object.keys(err_message) const keys = Object.keys(err_message)
MsgError( MsgError(
node.properties?.stepName + node.properties?.stepName +
` ${t('views.applicationWorkflow.node')}` + ` ${t('views.applicationWorkflow.node')}` +
err_message[keys[0]]?.[0]?.message err_message[keys[0]]?.[0]?.message,
) )
} }
}) })
@ -376,7 +370,7 @@ function getDetail() {
function saveApplication(bool?: boolean, back?: boolean) { function saveApplication(bool?: boolean, back?: boolean) {
const obj = { const obj = {
work_flow: getGraphData() work_flow: getGraphData(),
} }
loading.value = back || false loading.value = back || false
application application

View File

@ -1,27 +1,4 @@
<template> <template>
<div class="chat-pc__header" :style="customStyle">
<div class="flex align-center">
<div class="mr-12 ml-24 flex">
<el-avatar
v-if="isAppIcon(application_profile?.icon)"
shape="square"
:size="32"
style="background: none"
>
<img :src="application_profile?.icon" alt="" />
</el-avatar>
<el-avatar
v-else-if="application_profile?.name"
:name="application_profile?.name"
pinyinColor
shape="square"
:size="32"
/>
</div>
<h4>{{ application_profile?.name }}</h4>
</div>
</div>
<component <component
:is="auth_components[`/src/views/chat/auth/component/${auth_type}.vue`].default" :is="auth_components[`/src/views/chat/auth/component/${auth_type}.vue`].default"
v-model="is_auth" v-model="is_auth"
@ -33,7 +10,7 @@ import { computed } from 'vue'
import { isAppIcon } from '@/utils/common' import { isAppIcon } from '@/utils/common'
const auth_components: any = import.meta.glob('@/views/chat/auth/component/*.vue', { const auth_components: any = import.meta.glob('@/views/chat/auth/component/*.vue', {
eager: true eager: true,
}) })
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
@ -42,8 +19,8 @@ const props = withDefaults(
defineProps<{ modelValue: boolean; application_profile: any; auth_type?: string; style?: any }>(), defineProps<{ modelValue: boolean; application_profile: any; auth_type?: string; style?: any }>(),
{ {
auth_type: 'password', auth_type: 'password',
style: {} style: {},
} },
) )
const is_auth = computed({ const is_auth = computed({
get: () => { get: () => {
@ -51,7 +28,7 @@ const is_auth = computed({
}, },
set: (v) => { set: (v) => {
emit('update:modelValue', v) emit('update:modelValue', v)
} },
}) })
const customStyle = computed(() => { const customStyle = computed(() => {
@ -59,7 +36,7 @@ const customStyle = computed(() => {
background: props.application_profile?.custom_theme?.theme_color, background: props.application_profile?.custom_theme?.theme_color,
color: props.application_profile?.custom_theme?.header_font_color, color: props.application_profile?.custom_theme?.header_font_color,
border: 'none', border: 'none',
...props.style ...props.style,
} }
}) })
</script> </script>

View File

@ -5,10 +5,13 @@
v-loading="loading" v-loading="loading"
:style="{ :style="{
'--el-color-primary': applicationDetail?.custom_theme?.theme_color, '--el-color-primary': applicationDetail?.custom_theme?.theme_color,
'--el-color-primary-light-9': hexToRgba(applicationDetail?.custom_theme?.theme_color, 0.1) '--el-color-primary-light-9': hexToRgba(applicationDetail?.custom_theme?.theme_color, 0.1),
}" }"
> >
<div class="chat-pc__header" :style="customStyle"> 11111111111
<div class="flex">
<div class="chat-pc__left border-r">
<div class="p-24 pb-0">
<div class="flex align-center"> <div class="flex align-center">
<div class="mr-12 ml-24 flex"> <div class="mr-12 ml-24 flex">
<el-avatar <el-avatar
@ -19,21 +22,10 @@
> >
<img :src="applicationDetail?.icon" alt="" /> <img :src="applicationDetail?.icon" alt="" />
</el-avatar> </el-avatar>
<el-avatar <LogoIcon v-else height="28px" style="width: 28px; height: 28px; display: block" />
v-else-if="applicationDetail?.name"
:name="applicationDetail?.name"
pinyinColor
shape="square"
:size="32"
/>
</div> </div>
<h4>{{ applicationDetail?.name }}</h4> <h4>{{ applicationDetail?.name }}</h4>
</div> </div>
</div>
<div>
<div class="flex">
<div class="chat-pc__left border-r">
<div class="p-24 pb-0">
<el-button class="add-button w-full primary" @click="newChat"> <el-button class="add-button w-full primary" @click="newChat">
<el-icon> <el-icon>
<Plus /> <Plus />
@ -50,8 +42,8 @@
'--el-color-primary': applicationDetail?.custom_theme?.theme_color, '--el-color-primary': applicationDetail?.custom_theme?.theme_color,
'--el-color-primary-light-9': hexToRgba( '--el-color-primary-light-9': hexToRgba(
applicationDetail?.custom_theme?.theme_color, applicationDetail?.custom_theme?.theme_color,
0.1 0.1,
) ),
}" }"
:data="chatLogData" :data="chatLogData"
class="mt-8" class="mt-8"
@ -155,7 +147,7 @@
<el-icon> <component :is="isCollapse ? 'Fold' : 'Expand'" /></el-icon> <el-icon> <component :is="isCollapse ? 'Fold' : 'Expand'" /></el-icon>
</el-button> </el-button>
</div> </div>
</div>
<EditTitleDialog ref="EditTitleDialogRef" @refresh="refreshFieldTitle" /> <EditTitleDialog ref="EditTitleDialogRef" @refresh="refreshFieldTitle" />
</div> </div>
</template> </template>
@ -181,7 +173,7 @@ const isCollapse = ref(false)
const customStyle = computed(() => { const customStyle = computed(() => {
return { return {
background: applicationDetail.value?.custom_theme?.theme_color, background: applicationDetail.value?.custom_theme?.theme_color,
color: applicationDetail.value?.custom_theme?.header_font_color color: applicationDetail.value?.custom_theme?.header_font_color,
} }
}) })
@ -189,13 +181,13 @@ const classObj = computed(() => {
return { return {
mobile: common.isMobile(), mobile: common.isMobile(),
hideLeft: !isCollapse.value, hideLeft: !isCollapse.value,
openLeft: isCollapse.value openLeft: isCollapse.value,
} }
}) })
const newObj = { const newObj = {
id: 'new', id: 'new',
abstract: t('chat.createChat') abstract: t('chat.createChat'),
} }
const props = defineProps<{ const props = defineProps<{
application_profile: any application_profile: any
@ -209,7 +201,7 @@ const applicationDetail = computed({
get: () => { get: () => {
return props.application_profile return props.application_profile
}, },
set: (v) => {} set: (v) => {},
}) })
const chatLogData = ref<any[]>([]) const chatLogData = ref<any[]>([])
@ -217,7 +209,7 @@ const chatLogData = ref<any[]>([])
const paginationConfig = ref({ const paginationConfig = ref({
current_page: 1, current_page: 1,
page_size: 20, page_size: 20,
total: 0 total: 0,
}) })
const currentRecordList = ref<any>([]) const currentRecordList = ref<any>([])
@ -286,7 +278,7 @@ function newChat() {
function getChatLog(id: string, refresh?: boolean) { function getChatLog(id: string, refresh?: boolean) {
const page = { const page = {
current_page: 1, current_page: 1,
page_size: 20 page_size: 20,
} }
chatLog.asyncGetChatLogClient(id, page, left_loading).then((res: any) => { chatLog.asyncGetChatLogClient(id, page, left_loading).then((res: any) => {
@ -313,7 +305,7 @@ function getChatRecord() {
currentChatId.value, currentChatId.value,
paginationConfig.value, paginationConfig.value,
loading, loading,
false false,
) )
.then((res: any) => { .then((res: any) => {
paginationConfig.value.total = res.data.total paginationConfig.value.total = res.data.total
@ -323,7 +315,7 @@ function getChatRecord() {
v['record_id'] = v.id v['record_id'] = v.id
}) })
currentRecordList.value = [...list, ...currentRecordList.value].sort((a, b) => currentRecordList.value = [...list, ...currentRecordList.value].sort((a, b) =>
a.create_time.localeCompare(b.create_time) a.create_time.localeCompare(b.create_time),
) )
if (paginationConfig.value.current_page === 1) { if (paginationConfig.value.current_page === 1) {
nextTick(() => { nextTick(() => {