Browse Source

Merge branch 'ds' into ds_hxl

ds_hxl
no99 1 week ago
parent
commit
da5b6d00f0
  1. 4
      .env.production
  2. 11
      src/api/AIxiaocaishen.js
  3. 55
      src/store/audio.js
  4. 5
      src/store/chat.js
  5. 75
      src/views/AIchat.vue
  6. 130
      src/views/AiEmotion.vue
  7. 20
      src/views/Selectmodel.vue
  8. 43
      src/views/components/emoEnergyConverter.vue
  9. 78
      src/views/components/emotionalBottomRadar.vue
  10. 1
      src/views/components/marketTemperature.vue
  11. 96
      src/views/homePage.vue

4
.env.production

@ -9,8 +9,8 @@ VITE_PUBLIC_PATH = /aixiaocaishen
VITE_USE_MOCK = true
#新数据接口
VITE_APP_API_BASE_URL = https://api.homilychart.com/link
# VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
# VITE_APP_API_BASE_URL = https://api.homilychart.com/link
VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
VITE_APP_IMG_API_BASE_URL = "https://api.homilychart.com/hljw/api/aws/upload"
#MJ API

11
src/api/AIxiaocaishen.js

@ -99,12 +99,13 @@ export const getAnnouncementAPI = function () {
// 获取用户次数接口
export const getUserCountAPI = function (params) {
return request({
url: `${APIurl}/api/ai_god/userUsageInfo`,
// 'http://39.101.133.168:8828/link/api/aiEmotion/client/getRemainNum',
url: `${APIurl}/api/aiEmotion/client/getRemainNum`,
method: "POST",
data: new URLSearchParams(params),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
data: params,
// headers: {
// "Content-Type": "application/x-www-form-urlencoded",
// },
});
};
// 推荐问题/每日复盘/小财神简介点击事件接口

55
src/store/audio.js

@ -9,7 +9,10 @@ export const useAudioStore = defineStore('audio', {
lastVoiceState: null,
ttsUrl:'',
isNewInstance: false, // 新增是否是新实例的标志
nowSound:''
nowSound:'',
currentAudioUrl: '', // 当前音频URL
isPaused: false, // 是否处于暂停状态
duration: 0 // 音频总时长
}),
actions: {
// 设置音频实例
@ -19,19 +22,67 @@ export const useAudioStore = defineStore('audio', {
// 播放控制
play() {
if (this.soundInstance) {
if (this.isPaused && this.playbackPosition > 0) {
// 从暂停位置继续播放
this.soundInstance.seek(this.playbackPosition)
}
this.soundInstance.play()
this.isPlaying = true
this.isPaused = false
}
},
// 暂停控制
pause() {
if (this.soundInstance) {
if (this.soundInstance && this.isPlaying) {
// 保存当前播放位置
this.playbackPosition = this.soundInstance.seek() || 0
this.soundInstance.pause()
this.isPlaying = false
this.isPaused = true
}
},
// 停止播放
stop() {
if (this.soundInstance) {
this.soundInstance.stop()
this.isPlaying = false
this.isPaused = false
this.playbackPosition = 0
}
},
// 切换播放/暂停
togglePlayPause() {
if (this.isPlaying) {
this.pause()
} else {
this.play()
}
},
// 设置当前音频URL
setCurrentAudioUrl(url) {
if (this.currentAudioUrl !== url) {
// 如果是新的音频,重置播放状态
this.stop()
this.currentAudioUrl = url
this.playbackPosition = 0
this.isPaused = false
}
},
// 语音开关控制
toggleVoice() {
this.isVoiceEnabled = !this.isVoiceEnabled
if (!this.isVoiceEnabled) {
// 关闭语音时停止当前播放
this.stop()
}
},
// 重置音频状态
resetAudioState() {
this.stop()
this.currentAudioUrl = ''
this.ttsUrl = ''
this.soundInstance = null
this.nowSound = ''
}
}
})

5
src/store/chat.js

@ -11,9 +11,10 @@ export const useChatStore = defineStore('chat', {
actions: {
async getUserCount() {
const result = await getUserCountAPI({
token: localStorage.getItem('localToken')
token: localStorage.getItem('localToken'),
source: '1'
})
this.UserCount = result.data.hasCount
this.UserCount = result.data
},
setLoading(status) {
this.isLoading = status

75
src/views/AIchat.vue

@ -146,6 +146,69 @@ const pauseAudio = () => {
}
};
//
const playAudioSequence = (audioUrls) => {
if (!audioUrls || audioUrls.length === 0) {
console.warn("音频URL列表为空,跳过播放");
return;
}
let currentIndex = 0;
const playNext = () => {
if (currentIndex >= audioUrls.length) {
console.log("所有音频播放完成");
return;
}
const currentUrl = audioUrls[currentIndex];
console.log(`正在播放第${currentIndex + 1}个音频:`, currentUrl);
//
if (audioStore.nowSound) {
audioStore.nowSound.stop();
}
const sound = new Howl({
src: [currentUrl],
html5: true,
format: ["mp3", "acc"],
rate: 1.2,
onplay: () => {
audioStore.isPlaying = true;
console.log(`开始播放音频 ${currentIndex + 1}`);
},
onend: () => {
audioStore.isPlaying = false;
console.log(`音频 ${currentIndex + 1} 播放完成`);
currentIndex++;
//
setTimeout(() => {
playNext();
}, 500); // 500ms
},
onstop: () => {
audioStore.isPlaying = false;
},
onloaderror: (id, err) => {
console.error(`音频 ${currentIndex + 1} 加载失败:`, err);
currentIndex++;
//
setTimeout(() => {
playNext();
}, 100);
}
});
audioStore.nowSound = sound;
audioStore.setAudioInstance(sound);
sound.play();
};
//
playNext();
};
//
const chatMsg = computed(() => chatStore.messages);
const props = defineProps({
@ -494,6 +557,18 @@ watch(
const result23 = await dbqbSecondThreeAPI(params2);
const result24 = await dbqbSecondFourAPI(params2);
// URL
const audioUrls = [];
if (result21.data.url) audioUrls.push(result21.data.url.trim());
if (result22.data.url) audioUrls.push(result22.data.url.trim());
if (result23.data.url) audioUrls.push(result23.data.url.trim());
if (result24.data.url) audioUrls.push(result24.data.url.trim());
//
if (audioUrls.length > 0 && audioStore.isVoiceEnabled) {
playAudioSequence(audioUrls);
}
const katexRegex = /\$\$(.*?)\$\$/g;
//
chatStore.messages.pop();

130
src/views/AiEmotion.vue

@ -183,11 +183,43 @@ import blueBorderImg from '@/assets/img/AiEmotion/blueBorder.png' //导入蓝色
import { ElMessage } from 'element-plus';
import { useEmotionStore } from '@/store/emotion'; // Pinia store
import { useAudioStore } from '@/store/audio.js'; // store
import { useChatStore } from '@/store/chat.js'; // store
import { Howl, Howler } from 'howler'; //
import { reactive } from 'vue';
import { marked } from 'marked'; // marked
// 使Pinia store
const emotionStore = useEmotionStore();
const audioStore = useAudioStore();
const chatStore = useChatStore();
// refuse
function processRefuseMessage(refuseData) {
if (!refuseData) return '未知错误';
// refuseMarkdown
try {
// marked
marked.setOptions({
breaks: true, // <br>
gfm: true, // GitHub Flavored Markdown
sanitize: false, // HTML
smartLists: true, //
smartypants: true, //
xhtml: false, // 使 XHTML
});
// MarkdownHTML
const htmlContent = marked(refuseData);
// HTMLElMessage
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlContent;
return tempDiv.textContent || tempDiv.innerText || refuseData;
} catch (error) {
console.error('处理refuse消息时出错:', error);
return refuseData;
}
}
//
const marketTemperatureRef = ref(null); //
@ -357,7 +389,7 @@ watch(currentStock, (newStock) => {
nextTick(() => {
renderCharts(newStock.apiData);
console.log('0000000000000000000000000',newStock.apiData)
console.log('0000000000000000000000000', newStock.apiData)
//
setTimeout(() => {
if (scenarioApplicationRef.value && parsedConclusion.value) {
@ -663,8 +695,11 @@ function playAudio(url) {
console.log('开始创建音频实例...');
try {
// URL
audioStore.setCurrentAudioUrl(url);
//
if (audioStore.nowSound) {
if (audioStore.nowSound && audioStore.nowSound.playing()) {
audioStore.nowSound.stop();
}
@ -675,19 +710,35 @@ function playAudio(url) {
format: ['mp3', 'wav'],
onplay: () => {
isAudioPlaying.value = true;
audioStore.isPlaying = true;
console.log('开始播放场景应用语音');
},
onend: () => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
console.log('场景应用语音播放结束');
},
onstop: () => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
console.log('场景应用语音播放停止');
},
onpause: () => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
console.log('场景应用语音播放暂停');
},
onerror: (error) => {
isAudioPlaying.value = false;
audioStore.isPlaying = false;
console.error('音频播放错误:', error);
},
onload: () => {
//
audioStore.duration = newSound.duration();
console.log('音频加载完成,时长:', audioStore.duration);
}
});
@ -726,14 +777,18 @@ async function handleSendMessage(input) {
console.log("发送内容:", input);
//
if (!input || !input.trim()) {
ElMessage.warning("输入内容不能为空");
return;
}
//
isRotating.value = true;
//
isLoading.value = true;
if (input.trim()) {
const userMessage = reactive({ sender: 'user', text: input });
messages.value.push(userMessage);
//
isLoading.value = true;
isPageLoaded.value = false;
//
isRotating.value = true;
try {
//
@ -750,20 +805,21 @@ async function handleSendMessage(input) {
aibullPrivilegeState: "1",
aigoldBullPrivilegeS: "1",
airadarPrivilegeStat: "1",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
marketList: "hk,cn,can,usa,my,sg,vi,in,gb",
},
};
const result = await getReplyAPI(params);
const response = await result.json(); // JSON
console.log("工作流接口返回数据:", response);
// data
const parsedData = JSON.parse(response.data); // JSON
console.log("解析后的数据:", parsedData);
if (parsedData && parsedData.market && parsedData.code) {
console.log("工作流接口返回股票信息:", parsedData);
isPageLoaded.value = false;
//
const conclusionParams = {
content: input.trim(),
@ -776,12 +832,6 @@ async function handleSendMessage(input) {
code: parsedData.code,
market: parsedData.market,
};
console.log('======================================')
//
// console.log('');
// startAutoScroll();
// fetchData
const [conclusionResult, fetchDataResult] = await Promise.all([
getConclusionAPI(conclusionParams),
@ -797,22 +847,21 @@ async function handleSendMessage(input) {
conclusionData.value = conclusionResponse.data;
// store
emotionStore.updateActiveStockConclusion(conclusionResponse.data);
console.log("结论数据已存储到响应式变量和store中:", conclusionData.value);
}
console.log('------------------------------------')
} else {
ElMessage.error('工作流接口未返回非股票信息');
// refuse
ElMessage.error(processRefuseMessage(parsedData.refuse));
return; //
}
} catch (error) {
ElMessage.error('请求工作流接口失败,请检查网络连接');
return; //
} finally {
//
isRotating.value = false;
//
if (isRotating.value) {
isRotating.value = false;
}
}
} else {
ElMessage.error('消息发送失败,请检查网络连接');
}
}
@ -857,17 +906,13 @@ async function fetchData(code, market, stockName, queryText) {
conclusionData: conclusionData.value, //
timestamp: new Date().toISOString()
};
// store
emotionStore.addStock(stockData);
console.log('股票数据已添加到store');
} else {
ElMessage.error('获取接口数据失败');
ElMessage.error('请求失败,请检查网络连接');
}
} catch (error) {
ElMessage.error('获取接口数据失败。。。');
ElMessage.error('请求失败,请检查网络连接');
}
}
@ -1115,7 +1160,15 @@ function triggerAutoScroll() {
}
//
onMounted(() => {
onMounted(async () => {
//
try {
await chatStore.getUserCount();
console.log('情绪大模型页面:用户次数获取成功');
} catch (error) {
console.error('情绪大模型页面:获取用户次数失败', error);
}
startImageRotation();
// DOM
@ -1141,6 +1194,9 @@ onUnmounted(() => {
}
});
//
const emit = defineEmits(['updateMessage', 'sendMessage', 'ensureAIchat']);
// 使
defineExpose({
handleSendMessage,
@ -1517,21 +1573,21 @@ defineExpose({
color: white;
font-size: 20px;
font-weight: bold;
margin-left: 44%;
margin-left: 45%;
}
.title3 {
color: white;
font-size: 20px;
font-weight: bold;
margin-left: 43%;
margin-left: 44.6%;
}
.title4 {
color: white;
font-size: 20px;
font-weight: bold;
margin-left: 41.5%;
margin-left: 44%;
}
.class09 {
@ -1580,7 +1636,7 @@ defineExpose({
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 66rem;
min-height: 69rem;
/* 设置最小高度,确保图片显示 */
margin: 0 auto;
}
@ -1596,7 +1652,7 @@ defineExpose({
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 86rem;
min-height: 90rem;
/* 设置最小高度,确保图片显示 */
margin: 0 auto;
}

20
src/views/Selectmodel.vue

@ -32,21 +32,31 @@
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { setHeight } from '@/utils/setHeight'
import { useDataStore } from "@/store/dataList.js";
const { getQueryVariable, setActiveTabIndex } = useDataStore();
const router = useRouter()
const pageRef = ref(null)
onMounted(() => {
setHeight(pageRef.value)
// onMounted(() => {
// setHeight(pageRef.value)
// })
onMounted(async () => {
const isPhone =
/phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
navigator.userAgent
);
!isPhone &&
localStorage.setItem(
"localToken",
decodeURIComponent(String(getQueryVariable("token")))
);
})
const goToDBQBmodel = () => {
router.push('/DBQBmodel')
window.location.href = '/DBQBmodel'
}
const goToEmotionsmodel = () => {
router.push('/Emotionsmodel')
window.location.href = '/Emotionsmodel'
}
</script>

43
src/views/components/emoEnergyConverter.vue

@ -244,12 +244,7 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
show: true,
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#fff',
width: 1,
type: 'solid'
},
type: 'line',
lineStyle: {
color: '#fff',
width: 1,
@ -280,10 +275,10 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
let color = param.color
if (param.seriesType === 'candlestick') {
let openPrice = value[0] //
let closePrice = value[1] //
let lowPrice = value[2] //
let highPrice = value[3] //
let openPrice = value[1] //
let closePrice = value[2] //
let lowPrice = value[3] //
let highPrice = value[4] //
//
if (typeof openPrice !== 'number' || typeof closePrice !== 'number' ||
@ -293,10 +288,10 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
let priceChange = closePrice - openPrice
let changePercent = ((priceChange / openPrice) * 100).toFixed(2)
let changeColor = priceChange >= 0 ? '#ef232a' : '#14b143'
let changeColor = priceChange >= 0 ? '#14b143' : '#ef232a'
result += `<div style="margin-bottom: 6px;">`
result += `<div style="color: #fff; font-weight: bold;">${param.seriesName}</div>`
// result += `<div style="color: #fff; font-weight: bold;">${param.seriesName}</div>`
result += `<div style="color: #fff;">开盘: ${openPrice.toFixed(2)}</div>`
result += `<div style="color: #fff;">收盘: ${closePrice.toFixed(2)}</div>`
result += `<div style="color: #fff;">最低: ${lowPrice.toFixed(2)}</div>`
@ -317,7 +312,7 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
{
type: 'slider',
xAxisIndex: 0,
start: 40,
start: 0,
end: 100,
show: true,
bottom: 10,
@ -335,7 +330,7 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
{
type: 'inside',
xAxisIndex: 0,
start: 70,
start: 0,
end: 100,
zoomOnMouseWheel: true,
moveOnMouseMove: true,
@ -349,9 +344,21 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
rotate: 45, // 45
color: "white"
},
axisLine: {
// show: false,
lineStyle: {
color: 'white', // x线
}
},
},
yAxis: {
scale: true,
axisLine: {
// show: false,
lineStyle: {
color: 'white', // x线
}
},
splitLine: {
show: false,
},
@ -391,10 +398,10 @@ function initQXNLZHEcharts(kline, qxnlzhqData) {
itemStyle: {
normal: {
// 线 >
color: 'transparent', // 线
color0: '#008080', // 线
borderColor: '#ff0783', // 线
borderColor0: '#008080', // 线绿
color: '#14b143', // < 绿
color0: '#ef232a', // >
borderColor: '#14b143', // 线绿
borderColor0: '#ef232a', // 线
}
},
//

78
src/views/components/emotionalBottomRadar.vue

@ -19,8 +19,28 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
// -x
let dateArray = barAndLineData.map(subArray => subArray[0])
// k线
let kLineDataArray = KlineData.map(subArray => subArray.slice(1, 5))
// k线['2025/04/24', 250.5, 259.51, 249.2, 259.54, 274.899, 0.685, 258.354]
// 1=, 2=, 3=, 4=
// ECharts candlestick[, , , ]
let kLineDataArray = KlineData.map(subArray => [
subArray[1], //
subArray[2], //
subArray[3], //
subArray[4] //
])
// K线y
let allKlineValues = []
kLineDataArray.forEach(item => {
if (Array.isArray(item) && item.length >= 4) {
// K线[, , , ]
allKlineValues.push(item[0], item[1], item[2], item[3])
}
})
// 10
let minValue = Math.min(...allKlineValues.filter(val => typeof val === 'number' && !isNaN(val)))
let yAxisMin = Math.floor(minValue / 10) * 10
// 线
let redLineDataArray = barAndLineData.map(subArray => subArray[1])
//
@ -157,24 +177,34 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
if (param.seriesType === 'candlestick') {
// ECharts candlestickvalue[, , , ]
// param.value
let dataIndex = param.dataIndex
let candlestickData = kLineDataArray[dataIndex]
let candlestickData = param.value
//
if (!Array.isArray(candlestickData) || candlestickData.length < 4) {
return ''
}
let openPrice = candlestickData[1] //
let closePrice = candlestickData[2] //
let lowPrice = candlestickData[3] //
let highPrice = candlestickData[4] //
//
if (typeof openPrice !== 'number' || typeof closePrice !== 'number' ||
typeof lowPrice !== 'number' || typeof highPrice !== 'number') {
return ''
}
let openPrice = candlestickData[0] //
let closePrice = candlestickData[1] //
let lowPrice = candlestickData[2] //
let highPrice = candlestickData[3] //
let priceChange = closePrice - openPrice
let changePercent = ((priceChange / openPrice) * 100).toFixed(2)
let changeColor = priceChange >= 0 ? '#14b143' : '#ef232a' // 绿
let changeColor = priceChange >= 0 ? '#14b143' : '#ef232a' // 绿
result += `<div style="margin-bottom: 6px;">`
result += `<div style="color: #fff; font-weight: bold;">${param.seriesName}</div>`
result += `<div style="color: #fff;">开盘: ${openPrice.toFixed(2)}</div>`
result += `<div style="color: #fff;">收盘: ${closePrice.toFixed(2)}</div>`
result += `<div style="color: #fff;">最低: ${lowPrice.toFixed(2)}</div>`
result += `<div style="color: #fff;">最高: ${highPrice.toFixed(2)}</div>`
result += `<div style="color: #fff;">开盘: ${openPrice.toFixed(1)}</div>`
result += `<div style="color: #fff;">收盘: ${closePrice.toFixed(1)}</div>`
result += `<div style="color: #fff;">最低: ${lowPrice.toFixed(1)}</div>`
result += `<div style="color: #fff;">最高: ${highPrice.toFixed(1)}</div>`
result += `<div style="color: ${changeColor};">涨跌: ${priceChange >= 0 ? '+' : ''}${priceChange.toFixed(2)} (${changePercent}%)</div>`
result += `</div>`
} else if (param.seriesName === '红线') {
@ -183,7 +213,6 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
result += `<div style="color: ${color}; margin-bottom: 4px;">${param.seriesName}: ${value}</div>`
}
})
return result
}
},
@ -251,7 +280,7 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
axisPointer: {
link: {
xAxisIndex: 'all'
}
},
}
},
{
@ -319,6 +348,7 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
type: 'value',
gridIndex: 0,
splitNumber: 4,
min: yAxisMin, // y10
axisLine: {
lineStyle: {
color: 'white' // y
@ -331,9 +361,6 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
width: 50, //
color: 'white',
formatter: function (value, index) {
if (index === 0) {
return '0'
}
return value.toFixed(2)
}
},
@ -344,7 +371,6 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
type: 'dotted' // 线 dotted线 solid:线
}
},
// min: 4,
scale: true, // 0k线
},
{
@ -424,7 +450,7 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
{
type: 'slider',
xAxisIndex: [0, 1, 2],
start: 70,
start: 0,
end: 100,
show: true,
bottom: 10,
@ -449,7 +475,7 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
{
type: 'inside',
xAxisIndex: [0, 1, 2],
start: 70,
start: 0,
end: 100,
zoomOnMouseWheel: true,
moveOnMouseMove: true,
@ -464,13 +490,13 @@ function initEmotionalBottomRadar(KlineData, barAndLineData) {
xAxisIndex: 0,
yAxisIndex: 0,
itemStyle: {
color: '#14b143', // (绿)
color0: '#ef232a', // ()
color: '#14b143', // > 绿
color0: '#ef232a', // <
borderColor: '#14b143',
borderColor0: '#ef232a',
normal: {
color: '#14b143', // (绿)
color0: '#ef232a', // ()
color: '#14b143', // > 绿
color0: '#ef232a', // <
borderColor: '#14b143',
borderColor0: '#ef232a',
opacity: function (params) {

1
src/views/components/marketTemperature.vue

@ -337,6 +337,7 @@ function initChart(raw, klineDataRawValue, WDRLValue) {
data: klineData,
itemStyle: {
normal: {
color: '#00FF00', // 线
color0: '#FF0000', // 线绿
borderColor: '#00FF00', // 线

96
src/views/homePage.vue

@ -46,7 +46,19 @@ const chatStore = useChatStore();
const audioStore = useAudioStore();
const isVoice = computed(() => audioStore.isVoiceEnabled);
const toggleVoice = () => {
audioStore.toggleVoice();
if (!audioStore.isVoiceEnabled) {
//
audioStore.toggleVoice();
} else {
// /
if (audioStore.currentAudioUrl || audioStore.ttsUrl) {
// /
audioStore.togglePlayPause();
} else {
//
audioStore.toggleVoice();
}
}
};
// sessionStorage 使 'aifindCow'tab
const activeTab = ref(sessionStorage.getItem("activeTabAI") || "AIchat");
@ -143,6 +155,13 @@ const sendMessage = async () => {
ElMessage.error("请先登录");
return;
}
//
if (!message.value || !message.value.trim()) {
ElMessage.warning("输入内容不能为空");
return;
}
isScrolling.value = false;
// AiEmotion
@ -157,7 +176,6 @@ const sendMessage = async () => {
ensureAIchat();
console.log(chatStore.isLoading, "isLoading.value1111");
if (!message.value) return;
if (chatStore.isLoading) return;
chatStore.setLoading(true);
console.log(chatStore.isLoading, "isLoading.value2222");
@ -485,15 +503,15 @@ document.addEventListener(
);
onMounted(async () => {
const isPhone =
/phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
navigator.userAgent
);
!isPhone &&
localStorage.setItem(
"localToken",
decodeURIComponent(String(getQueryVariable("token")))
);
// const isPhone =
// /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
// navigator.userAgent
// );
// !isPhone &&
// localStorage.setItem(
// "localToken",
// decodeURIComponent(String(getQueryVariable("token")))
// );
setHeight(document.getElementById("testId")); //
//
await chatStore.getUserCount();
@ -585,43 +603,20 @@ onMounted(async () => {
alt="夺宝奇兵大模型"
/>
<!-- AI情绪大模型按钮 -->
<img
:src="
activeTab === 'AiEmotion' ? emotionButton01 : emotionButton02
"
@click="setActiveTab('AiEmotion', 1)"
class="action-btn model-btn"
alt="AI情绪大模型"
/>
<img
v-if="isVoice"
:src="voice"
@click="toggleVoice"
class="action-btn"
/>
<img
v-else
:src="voiceNoActive"
@click="toggleVoice"
class="action-btn"
/>
<img :src="activeTab === 'AiEmotion' ? emotionButton01 : emotionButton02
" @click="setActiveTab('AiEmotion', 1)" class="action-btn model-btn" alt="AI情绪大模型" />
<img v-if="audioStore.isVoiceEnabled && !audioStore.isPlaying" :src="voice" @click="toggleVoice" class="action-btn" />
<img v-else-if="audioStore.isVoiceEnabled && audioStore.isPlaying" :src="voice" @click="toggleVoice" class="action-btn" style="opacity: 0.7; animation: pulse 1.5s infinite;" />
<img v-else :src="voiceNoActive" @click="toggleVoice" class="action-btn" />
</div>
</div>
<!-- 第二行输入框 -->
<div class="footer-second-line">
<img :src="msgBtn" class="msg-icon" />
<el-input
type="textarea"
v-model="message"
@focus="onFocus"
@blur="onBlur"
:autosize="{ minRows: 1, maxRows: 4 }"
placeholder="给AI小财神发消息..."
class="msg-input"
@keydown.enter.exact.prevent="isLoading ? null : sendMessage()"
resize="none"
>
<el-input type="textarea" v-model="message" @focus="onFocus" @blur="onBlur"
:autosize="{ minRows: 1, maxRows: 4 }" placeholder="请输入股票名称或股票代码..." class="msg-input"
@keydown.enter.exact.prevent="isLoading ? null : sendMessage()" resize="none">
</el-input>
<img
v-if="!chatStore.isLoading"
@ -681,8 +676,8 @@ onMounted(async () => {
<!-- 中间内容部分 -->
<div class="ruleContent">
<p>试运行期间AI小财神可以检索全市场数据</p>
<p>每个市场20支股票股票详情参见公告页面</p>
<p>弘历会员每人每日拥有10次检索机会</p>
<p>每个市场20支股票股票详情参见公告页面</p>
<!-- <p>弘历会员每人每日拥有10次检索机会</p> -->
</div>
<!-- <template #footer> -->
<!-- 添加一个div来包裹按钮并设置样式使其居中 -->
@ -1006,6 +1001,19 @@ body {
/* margin-right: 5px; */
}
/* 音频播放动画 */
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.footer-second-line {
position: relative;
display: flex;

Loading…
Cancel
Save