commit
This commit is contained in:
parent
86e1a600a7
commit
4a090425c8
|
@ -2,9 +2,9 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="icon" type="image/svg+xml" href="/images/logo.png" />
|
||||
<!--<link rel="preload" as="image" href="/src/assets/images/hero-bg.jpg" fetchpriority="high">-->
|
||||
<link rel="preload" as="image" href="images/hero-bg.jpg" fetchpriority="high">
|
||||
<link rel="preload" as="image" href="images/logo.png" fetchpriority="high">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>优阅工作室</title>
|
||||
|
||||
|
|
|
@ -2,48 +2,58 @@
|
|||
<t-space v-if="isVisible1" align="center" @click="visibleModelessDrag = true" class="ai_style" >
|
||||
<img :src="aiImg" alt="勤怠登录页面" width="36px" height="36px">
|
||||
</t-space>
|
||||
<t-dialog
|
||||
v-model:visible="visibleModelessDrag"
|
||||
:footer="false"
|
||||
id ="abc"
|
||||
header="AI助手"
|
||||
mode="modeless"
|
||||
showOverlay="true"
|
||||
draggable
|
||||
:on-confirm="() => (visibleModelessDrag = false)"
|
||||
>
|
||||
<template #body>
|
||||
<t-chat
|
||||
layout="both"
|
||||
style="height: 600px;"
|
||||
:z-index="3000"
|
||||
:data="chatList"
|
||||
:clear-history="chatList.length > 0 && !isStreamLoad"
|
||||
:text-loading="loading"
|
||||
:is-stream-load="isStreamLoad"
|
||||
@on-action="operation"
|
||||
@clear="clearConfirm"
|
||||
>
|
||||
<!-- eslint-disable-next-line vue/no-unused-vars -->
|
||||
<template #actions="{ item, index }">
|
||||
<t-chat-action
|
||||
:content="item.content"
|
||||
:operation-btn="['good', 'bad', 'replay', 'copy']"
|
||||
@operation="handleOperation"
|
||||
/>
|
||||
</template>
|
||||
<template #footer>
|
||||
<t-chat-input v-model="inputValue" :stop-disabled="isStreamLoad" @send="inputEnter" @stop="onStop"> </t-chat-input>
|
||||
</template>
|
||||
</t-chat>
|
||||
</template>
|
||||
</t-dialog>
|
||||
<t-config-provider :global-config="globalConfig">
|
||||
<t-dialog
|
||||
v-model:visible="visibleModelessDrag"
|
||||
:footer="false"
|
||||
id ="abc"
|
||||
:header="t('ai.title')"
|
||||
mode="modeless"
|
||||
showOverlay="true"
|
||||
|
||||
draggable
|
||||
:on-confirm="() => (visibleModelessDrag = false)"
|
||||
>
|
||||
<template #body>
|
||||
<t-chat
|
||||
layout="both"
|
||||
style="height: 600px;"
|
||||
:z-index="3000"
|
||||
:data="chatList"
|
||||
:clear-history="chatList.length > 0 && !isStreamLoad"
|
||||
:text-loading="loading"
|
||||
:is-stream-load="isStreamLoad"
|
||||
@on-action="operation"
|
||||
@clear="clearConfirm"
|
||||
>
|
||||
<template #actions="{ item, index }">
|
||||
<t-chat-action
|
||||
:content="item.content"
|
||||
:operation-btn="['good', 'bad', 'replay', 'copy']"
|
||||
@operation="handleOperation"
|
||||
/>
|
||||
</template>
|
||||
<template #footer>
|
||||
<t-chat-input v-model="inputValue" :stop-disabled="isStreamLoad" @send="inputEnter" @stop="onStop"> </t-chat-input>
|
||||
</template>
|
||||
</t-chat>
|
||||
|
||||
|
||||
</template>
|
||||
</t-dialog>
|
||||
</t-config-provider>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted,inject, watch, computed} from 'vue'
|
||||
import aiImg from '@/assets/ai_img.png'
|
||||
const visibleModelessDrag = ref(false);
|
||||
import { useLanguageStore } from '../../store/language'
|
||||
import { MockSSEResponse } from './ChatAi';
|
||||
|
||||
import { globalConfig } from '../../locales/globalConfig'
|
||||
|
||||
|
||||
const visibleModelessDrag = ref(false);
|
||||
|
||||
const fetchCancel = ref(null);
|
||||
const loading = ref(false);
|
||||
const isStreamLoad = ref(false);
|
||||
|
@ -51,6 +61,9 @@ const chatRef = ref(null);
|
|||
const isShowToBottom = ref(false);
|
||||
const inputValue = ref('');
|
||||
|
||||
const store = useLanguageStore()
|
||||
|
||||
|
||||
|
||||
// 控制按钮显示/隐藏的状态
|
||||
const isVisible1 = ref(false)
|
||||
|
@ -63,25 +76,48 @@ const handleScroll1 = () => {
|
|||
|
||||
|
||||
};
|
||||
|
||||
// 注入翻译函数
|
||||
const t = inject<(key: string) => string>('t') || ((key) => key)
|
||||
|
||||
// 挂载时添加滚动监听
|
||||
onMounted(() => {
|
||||
|
||||
window.addEventListener('scroll', handleScroll1)
|
||||
})
|
||||
|
||||
|
||||
// 卸载时移除滚动监听
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
window.removeEventListener('scroll', handleScroll1)
|
||||
})
|
||||
|
||||
|
||||
// 计算属性,根据当前语言返回对应的文本
|
||||
const clearHistoryBtnText = computed(() => {
|
||||
return t('ai.clearHistory')
|
||||
})
|
||||
|
||||
// 获取指定格式的时间字符串
|
||||
const getFormattedDateTime = ():string => {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear().toString().slice(-2); // 取年份后两位
|
||||
const month = (now.getMonth() + 1).toString().padStart(2, '0'); // 月份从0开始,需要+1
|
||||
const day = now.getDate().toString().padStart(2, '0');
|
||||
const hours = now.getHours().toString().padStart(2, '0');
|
||||
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||
|
||||
return `[${year}-${month}-${day} ${hours}:${minutes}]`;
|
||||
};
|
||||
|
||||
|
||||
// 倒序渲染
|
||||
const chatList = ref([
|
||||
{
|
||||
avatar: 'https://tdesign.gtimg.com/site/chat-avatar.png',
|
||||
name: 'youyueAI',
|
||||
datetime: '今天16:38',
|
||||
content: '我是你的ai助手,有什么可以帮你的。',
|
||||
datetime: getFormattedDateTime(),
|
||||
content: t('ai.initContent'),
|
||||
role: 'assistant',
|
||||
}
|
||||
]);
|
||||
|
@ -105,6 +141,11 @@ const chatList = ref([
|
|||
// role: 'user',
|
||||
// },
|
||||
// ]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const handleOperation = function (type, options) {
|
||||
console.log('handleOperation', type, options);
|
||||
};
|
||||
|
@ -173,6 +214,25 @@ const fetchSSE = async (fetchFn, options) => {
|
|||
|
||||
};
|
||||
|
||||
// 监听语言变化,更新聊天内容
|
||||
watch(
|
||||
() => store.currentLanguage,
|
||||
(newLang: any, oldLang:any) => {
|
||||
// 当语言发生变化时,更新聊天列表中的内容
|
||||
if (chatList.value.length > 0 && chatList.value[chatList.value.length-1].role === 'assistant') {
|
||||
// 更新初始化消息的内容
|
||||
chatList.value[chatList.value.length-1].content = t('ai.initContent')
|
||||
}
|
||||
|
||||
// 如果有其他需要更新的聊天项,也可以在这里处理
|
||||
// 例如更新所有系统消息或其他固定内容
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const displayText = ref('');
|
||||
const fullText = ref('');
|
||||
const isLoading = ref(true);
|
||||
|
|
|
@ -13,8 +13,8 @@ const messages = {
|
|||
// 创建 i18n 实例
|
||||
const i18n = createI18n({
|
||||
legacy: false, // 使用 Composition API,必须设置为 false
|
||||
locale: 'zh', // 默认语言
|
||||
fallbackLocale: 'ja', // 回退语言
|
||||
locale: 'ja', // 默认语言
|
||||
fallbackLocale: 'zh', // 回退语言
|
||||
messages
|
||||
})
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import enUs from 'tdesign-vue-next/es/locale/en_US';
|
||||
export default {
|
||||
nav: {
|
||||
home: 'Home',
|
||||
|
@ -41,4 +42,10 @@ export default {
|
|||
timeline: {
|
||||
title: 'Company History',
|
||||
},
|
||||
ai:{
|
||||
title: 'AIチャット',
|
||||
initContent: 'こんにちは、何かお手伝いできることはありますか?',
|
||||
clearHistory: '履歴をクリア',
|
||||
},
|
||||
...enUs.chat
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
// 导入所需的语言包
|
||||
import zhConfig from 'tdesign-vue-next/es/locale/zh_CN';
|
||||
import enConfig from 'tdesign-vue-next/es/locale/en_US';
|
||||
import jaConfig from 'tdesign-vue-next/es/locale/ja_JP';
|
||||
import { merge } from 'lodash-es';
|
||||
// 全局特性配置,引入英文语言配置包 enConfig
|
||||
|
||||
import { ref, watch, computed } from 'vue';
|
||||
|
||||
|
||||
import { useLanguageStore } from '../store/language'
|
||||
|
||||
const store = useLanguageStore()
|
||||
|
||||
|
||||
|
||||
const currentLanguage = computed(() => store.currentLanguage)
|
||||
|
||||
// 定义支持的语言类型
|
||||
// export type Language = 'zh-CN' | 'en-US' | 'ja-JP';
|
||||
export type Language = 'zh' | 'en' | 'ja';
|
||||
|
||||
// 基础自定义配置
|
||||
const customConfig: GlobalConfigProvider = {
|
||||
calendar: {},
|
||||
table: {},
|
||||
pagination: {},
|
||||
chat:{},
|
||||
// 可以添加更多自定义配置
|
||||
};
|
||||
|
||||
// 语言包映射
|
||||
const localeMap = {
|
||||
'zh': zhConfig,
|
||||
'en': enConfig,
|
||||
'ja': jaConfig,
|
||||
};
|
||||
|
||||
// 响应式全局配置
|
||||
const globalConfig:GlobalConfigProvider = ref<GlobalConfigProvider>(
|
||||
merge({}, localeMap[currentLanguage.value], customConfig)
|
||||
);
|
||||
|
||||
// 当语言变化时更新全局配置
|
||||
watch(currentLanguage, (newLang) => {
|
||||
// 更新全局配置
|
||||
globalConfig.value = merge({}, localeMap[newLang], customConfig);
|
||||
console.log(globalConfig.value)
|
||||
});
|
||||
|
||||
|
||||
export {
|
||||
currentLanguage,
|
||||
globalConfig
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
// 导入所需的语言包
|
||||
import zhConfig from 'tdesign-vue-next/es/locale/zh_CN';
|
||||
import enConfig from 'tdesign-vue-next/es/locale/en_US';
|
||||
import jaConfig from 'tdesign-vue-next/es/locale/ja_JP';
|
||||
import { merge } from 'lodash-es';
|
||||
import { type GlobalConfigProvider } from 'tdesign-vue-next';
|
||||
import { ref, watch, computed } from 'vue';
|
||||
|
||||
|
||||
import { useLanguageStore } from '../store/language'
|
||||
|
||||
const store = useLanguageStore()
|
||||
|
||||
|
||||
|
||||
const currentLanguage = computed(() => store.currentLanguage)
|
||||
|
||||
// 定义支持的语言类型
|
||||
// export type Language = 'zh-CN' | 'en-US' | 'ja-JP';
|
||||
export type Language = 'zh' | 'en' | 'ja';
|
||||
|
||||
// 基础自定义配置
|
||||
const customConfig: GlobalConfigProvider = {
|
||||
calendar: {},
|
||||
table: {},
|
||||
pagination: {},
|
||||
chat:{},
|
||||
// 可以添加更多自定义配置
|
||||
};
|
||||
|
||||
// 语言包映射
|
||||
const localeMap = {
|
||||
'zh': zhConfig,
|
||||
'en': enConfig,
|
||||
'ja': jaConfig,
|
||||
};
|
||||
|
||||
// 响应式全局配置
|
||||
const globalConfig = ref<GlobalConfigProvider>(
|
||||
merge({}, localeMap[currentLanguage.value], customConfig)
|
||||
);
|
||||
|
||||
// 当语言变化时更新全局配置
|
||||
watch(currentLanguage, (newLang) => {
|
||||
// 更新全局配置
|
||||
globalConfig.value = merge({}, localeMap[newLang], customConfig);
|
||||
console.log(globalConfig.value)
|
||||
});
|
||||
|
||||
|
||||
export {
|
||||
currentLanguage,
|
||||
globalConfig
|
||||
};
|
|
@ -1,3 +1,5 @@
|
|||
import jaJP from 'tdesign-vue-next/es/locale/ja_JP';
|
||||
|
||||
export default {
|
||||
nav: {
|
||||
name:'優閲スタジオ',
|
||||
|
@ -117,6 +119,13 @@ export default {
|
|||
timeline: {
|
||||
title: 'タイムライン',
|
||||
},
|
||||
|
||||
ai:{
|
||||
title: 'AIチャット',
|
||||
initContent: 'こんにちは、何かお手伝いできることはありますか?',
|
||||
clearHistory: '履歴をクリア',
|
||||
},
|
||||
|
||||
chat: {
|
||||
...jaJP.chat
|
||||
}
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
import znCh from 'tdesign-vue-next/es/locale/zh_CN';
|
||||
|
||||
export default {
|
||||
nav: {
|
||||
name:'优阅工作室',
|
||||
|
@ -113,4 +116,13 @@ export default {
|
|||
timeline: {
|
||||
title: '项目经历',
|
||||
},
|
||||
ai:{
|
||||
title: 'AI助手',
|
||||
initContent: '我是你的ai助手,有什么可以帮你的。',
|
||||
clearHistory: "清空历史记录11",
|
||||
|
||||
},
|
||||
chat: {
|
||||
...znCh.chat
|
||||
}
|
||||
}
|
|
@ -3,8 +3,6 @@ import './style.css'
|
|||
import App from './App.vue'
|
||||
import router from './router/index.ts' // 确保路径正确
|
||||
|
||||
|
||||
|
||||
// 引入Pinia
|
||||
import { createPinia } from 'pinia'
|
||||
// 引入TDesign UI组件库
|
||||
|
@ -12,7 +10,6 @@ import TDesign from 'tdesign-vue-next'
|
|||
import TDesignChat from '@tdesign-vue-next/chat'; // 引入chat组件
|
||||
import 'tdesign-vue-next/es/style/index.css'
|
||||
|
||||
|
||||
const app = createApp(App)
|
||||
// 必须先 use(router),再挂载
|
||||
app.use(router)
|
||||
|
@ -20,10 +17,16 @@ app.use(router)
|
|||
// 使用Pinia
|
||||
app.use(createPinia())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 使用TDesign
|
||||
app.use(TDesign)
|
||||
app.use(TDesignChat)
|
||||
|
||||
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
// 临时打印路由列表,确认配置是否生效
|
||||
|
|
|
@ -2,7 +2,6 @@ import { defineStore } from 'pinia'
|
|||
import zh from '../locales/zh'
|
||||
import ja from '../locales/ja'
|
||||
|
||||
|
||||
// 获取浏览器语言
|
||||
function getBrowserLanguage() {
|
||||
// 获取浏览器主语言(如从 "zh-CN" 中提取 "zh-CN" 或从 "zh-TW" 中提取 "zh-TW")
|
||||
|
@ -11,7 +10,7 @@ function getBrowserLanguage() {
|
|||
return 'zh';
|
||||
}
|
||||
// 默认返回英语
|
||||
return 'en';
|
||||
return 'ja';
|
||||
}
|
||||
const lang = getBrowserLanguage()
|
||||
export const useLanguageStore = defineStore('language', {
|
||||
|
|
|
@ -3,5 +3,12 @@
|
|||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
],
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "Node",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"*": ["node_modules/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue