chore: dev proxy config, sprite animator refactor, cleanups
- add vite dev proxy for `/ingress` to forward requests to backend https://onefeel.brother7.cn - update .env.development to use relative proxy paths instead of full backend URLs - move SpriteAnimator component to correct directory, update all imports and global type declarations in components.d.ts - remove unused CSS styles and fix styling for ChatTopNavBar component, including switching to van-icon and hardcoding temporary site name - uncomment and enable the ChatMainList component in home page - clean up unused code, fix formatting, and set default client ID in src/utils/request.ts - comment out redundant uni API calls in ChatMainList to simplify code - update WebSocket URL handling to support relative paths in ChatMainList
This commit is contained in:
@@ -1,153 +1,14 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-screen relative overflow-hidden">
|
||||
<!-- 顶部自定义导航栏 -->
|
||||
<div class="header absolute top-0 left-0 w-full z-10" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<div class="absolute top-0 left-0 w-full z-10">
|
||||
<ChatTopNavBar ref="topNavBarRef" :mainPageDataModel="mainPageDataModel" @showDrawer="handleShowDrawer" />
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<img class="w-full block" :src="mainPageDataModel?.initPageImages?.backgroundImageUrl" mode="aspectFill"
|
||||
style="height: 252px;" />
|
||||
<div class="absolute bottom-0 left-0 right-0 flex-full">
|
||||
<div class="px-12 pt-12">
|
||||
<HomeWelcome :mainPageDataModel="mainPageDataModel" />
|
||||
</div>
|
||||
<div style="margin-bottom: -1px;">
|
||||
<AiTabSwitch v-model="tabIndex" :list="tabList" @change="handleChange" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="tabIndex === 0" class="main-scroll-area flex-full overflow-hidden min-height-0"
|
||||
@touchstart.capture="handleScrollAreaTouchStart" @touchstart="handleScrollAreaTouchStart"
|
||||
@touchmove="handleScrollAreaTouchMove">
|
||||
<Discovery @scroll-touch-start="handleScrollAreaTouchStart" @scroll-touch="handleScrollAreaTouchMove" />
|
||||
</div>
|
||||
|
||||
<!-- 消息列表(可滚动区域) -->
|
||||
<div v-show="tabIndex === 1" class="main main-scroll-area flex-full overflow-hidden min-height-0" scroll-y
|
||||
:scroll-top="scrollTop" :scroll-with-animation="true" @scroll="handleScroll" @scrolltolower="handleScrollToLower"
|
||||
@touchstart.capture="handleScrollAreaTouchStart" @touchstart="handleScrollAreaTouchStart"
|
||||
@touchmove="handleScrollAreaTouchMove">
|
||||
|
||||
<div class="area-msg-list-content" v-for="item in chatMsgList" :key="item.msgId" :id="item.msgId">
|
||||
<template v-if="item.msgType === MessageRole.AI">
|
||||
<ChatCardAI class="flex flex-justify-start" :key="`ai-${item.msgId}-${item.msg ? item.msg.length : 0}`" :text="item.componentName && isLongTextCard(item.componentName)
|
||||
? ''
|
||||
: item.msg || ''
|
||||
" :isLoading="item.isLoading">
|
||||
<template #content v-if="
|
||||
item.toolCall ||
|
||||
(item.componentName && isLongTextCard(item.componentName))
|
||||
">
|
||||
<!-- <AnswerComponent
|
||||
v-if="isLongTextCard(item.componentName)"
|
||||
:longTextData="item.longTextData"
|
||||
:finish="item.finish"
|
||||
/> -->
|
||||
|
||||
<LongTextGuideCardPreview v-if="item.componentName && isLongTextCard(item.componentName)"
|
||||
:componentName="item.componentName" />
|
||||
|
||||
<QuickBookingComponent v-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.quickBookingCard
|
||||
" />
|
||||
<DiscoveryCardComponent v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.discoveryCard
|
||||
" />
|
||||
<CreateServiceOrder v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.callServiceCard
|
||||
" :toolCall="item.toolCall" />
|
||||
<OpenMapComponent v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.mapCard
|
||||
" />
|
||||
<GeneratorPhotoComponent v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName ===
|
||||
CompName.aigcPhotoGeneratorCard
|
||||
" :toolCall="item.toolCall" />
|
||||
<!-- <ZModuleC01
|
||||
v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.aigcPhotoGeneratorCard
|
||||
"
|
||||
/> -->
|
||||
|
||||
<Feedback v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.feedbackCard
|
||||
" :toolCall="item.toolCall" />
|
||||
<DetailCardCompontent v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName ===
|
||||
CompName.pictureAndCommodityCard
|
||||
" :toolCall="item.toolCall" />
|
||||
<AddCarCrad v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName === CompName.enterLicensePlateCard
|
||||
" :toolCall="item.toolCall" />
|
||||
<SurveyQuestionnaire v-else-if="
|
||||
item.toolCall &&
|
||||
item.toolCall.componentName ===
|
||||
CompName.callSurveyQuestionnaire
|
||||
" :toolCall="item.toolCall" />
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<!-- 这个是底部 -->
|
||||
<AttachListComponent v-if="item.question" :question="item.question" />
|
||||
</template>
|
||||
</ChatCardAI>
|
||||
</template>
|
||||
|
||||
<template v-else-if="item.msgType === MessageRole.ME">
|
||||
<ChatCardMine class="flex flex-justify-end" :text="item.msg" />
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<ChatCardOther class="flex flex-justify-center" :text="item.msg">
|
||||
<ChatGuide v-if="chatMsgList.length < 2" />
|
||||
<ActivityListComponent v-if="
|
||||
mainPageDataModel.activityList &&
|
||||
mainPageDataModel.activityList.length > 0
|
||||
" :activityList="mainPageDataModel.activityList" />
|
||||
|
||||
<!-- 先不展示了,等后续有需求再加回来 false -->
|
||||
<RecommendPostsComponent v-if="
|
||||
false &&
|
||||
mainPageDataModel.recommendTheme &&
|
||||
mainPageDataModel.recommendTheme.length > 0
|
||||
" :recommendThemeList="mainPageDataModel.recommendTheme" />
|
||||
</ChatCardOther>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 输入框区域 -->
|
||||
<div class="pb-safe-area">
|
||||
<ChatQuickAccess />
|
||||
<ChatInputArea ref="inputAreaRef" v-model="inputMessage" :holdKeyboard="holdKeyboard"
|
||||
:is-session-active="isSessionActive" :stop-request="stopRequest" @send="sendMessageAction"
|
||||
@noHideKeyboard="handleNoHideKeyboard" @keyboardShow="handleKeyboardShow" @keyboardHide="handleKeyboardHide" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, nextTick, onUnmounted, ref } from "vue";
|
||||
import {
|
||||
SWITCH_TO_COMPANION_TAB,
|
||||
SWITCH_TO_DISCOVERY_TAB,
|
||||
SCROLL_TO_BOTTOM,
|
||||
SEND_MESSAGE_CONTENT_TEXT,
|
||||
SEND_MESSAGE_COMMAND_TYPE,
|
||||
NOTICE_EVENT_LOGOUT,
|
||||
NOTICE_EVENT_LOGIN_SUCCESS,
|
||||
} from "@/constants/constant";
|
||||
import { MessageRole, MessageType, CompName, Command } from "@/constants/ChatModel";
|
||||
|
||||
import HomeWelcome from "../HomeWelcome/index.vue";
|
||||
@@ -195,8 +56,7 @@ import { getAccessToken } from "@/constants/token";
|
||||
|
||||
const emit = defineEmits(["showDrawer"]);
|
||||
const appStore = useAppStore();
|
||||
/// 导航栏相关
|
||||
const statusBarHeight = ref(20);
|
||||
|
||||
/// 输入框组件引用
|
||||
const inputAreaRef = ref(null);
|
||||
const topNavBarRef = ref();
|
||||
@@ -278,7 +138,7 @@ const handleTouchEnd = () => {
|
||||
holdKeyboardTimer.value = setTimeout(() => {
|
||||
// 键盘弹出时点击界面则关闭键盘
|
||||
if (holdKeyboardFlag.value && isKeyboardShow.value) {
|
||||
uni.hideKeyboard();
|
||||
// uni.hideKeyboard();
|
||||
}
|
||||
holdKeyboardFlag.value = true;
|
||||
}, 100);
|
||||
@@ -319,13 +179,7 @@ const hideKeyboardByScroll = () => {
|
||||
inputAreaRef.value.blurInput();
|
||||
}
|
||||
|
||||
uni.hideKeyboard();
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
if (typeof plus !== "undefined" && plus.key && plus.key.hideSoftKeybord) {
|
||||
plus.key.hideSoftKeybord();
|
||||
}
|
||||
// #endif
|
||||
};
|
||||
|
||||
const hideKeyboardAfterSend = () => {
|
||||
@@ -338,8 +192,6 @@ const hideKeyboardAfterSend = () => {
|
||||
typeof inputAreaRef.value.blurInput === "function"
|
||||
) {
|
||||
inputAreaRef.value.blurInput();
|
||||
} else {
|
||||
uni.hideKeyboard();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -439,54 +291,48 @@ const sendMessageAction = (inputText) => {
|
||||
|
||||
/// 添加通知
|
||||
const addNoticeListener = () => {
|
||||
uni.$on(NOTICE_EVENT_LOGIN_SUCCESS, () => {
|
||||
if (!isWsConnected()) {
|
||||
initHandler();
|
||||
}
|
||||
});
|
||||
// uni.$on(NOTICE_EVENT_LOGIN_SUCCESS, () => {
|
||||
// if (!isWsConnected()) {
|
||||
// initHandler();
|
||||
// }
|
||||
// });
|
||||
|
||||
uni.$on(NOTICE_EVENT_LOGOUT, () => {
|
||||
resetConfig();
|
||||
});
|
||||
// uni.$on(NOTICE_EVENT_LOGOUT, () => {
|
||||
// resetConfig();
|
||||
// });
|
||||
|
||||
uni.$on(SCROLL_TO_BOTTOM, () => {
|
||||
setTimeout(() => {
|
||||
scrollToBottom(true);
|
||||
}, 200);
|
||||
});
|
||||
// uni.$on(SCROLL_TO_BOTTOM, () => {
|
||||
// setTimeout(() => {
|
||||
// scrollToBottom(true);
|
||||
// }, 200);
|
||||
// });
|
||||
|
||||
uni.$on(SEND_MESSAGE_CONTENT_TEXT, (value) => {
|
||||
console.log("SEND_MESSAGE_CONTENT_TEXT:", value);
|
||||
if (value && value.length > 0) {
|
||||
handleReplyText(value);
|
||||
}
|
||||
});
|
||||
// uni.$on(SEND_MESSAGE_CONTENT_TEXT, (value) => {
|
||||
// console.log("SEND_MESSAGE_CONTENT_TEXT:", value);
|
||||
// if (value && value.length > 0) {
|
||||
// handleReplyText(value);
|
||||
// }
|
||||
// });
|
||||
|
||||
uni.$on(SEND_MESSAGE_COMMAND_TYPE, (item) => {
|
||||
console.log("SEND_MESSAGE_COMMAND_TYPE:", item);
|
||||
if (item && item.type) {
|
||||
handleReplyInstruct(item);
|
||||
}
|
||||
});
|
||||
// uni.$on(SEND_MESSAGE_COMMAND_TYPE, (item) => {
|
||||
// console.log("SEND_MESSAGE_COMMAND_TYPE:", item);
|
||||
// if (item && item.type) {
|
||||
// handleReplyInstruct(item);
|
||||
// }
|
||||
// });
|
||||
|
||||
uni.$on(SWITCH_TO_COMPANION_TAB, () => {
|
||||
tabIndex.value = 1;
|
||||
});
|
||||
// uni.$on(SWITCH_TO_COMPANION_TAB, () => {
|
||||
// tabIndex.value = 1;
|
||||
// });
|
||||
|
||||
uni.$on(SWITCH_TO_DISCOVERY_TAB, () => {
|
||||
tabIndex.value = 0;
|
||||
});
|
||||
// uni.$on(SWITCH_TO_DISCOVERY_TAB, () => {
|
||||
// tabIndex.value = 0;
|
||||
// });
|
||||
};
|
||||
|
||||
/// =============生命周期函数↓================
|
||||
// TODO
|
||||
// onLoad(() => {
|
||||
// uni.getSystemInfo({
|
||||
// success: (res) => {
|
||||
// statusBarHeight.value = res.statusBarHeight || 20;
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
|
||||
|
||||
// onReady(() => {
|
||||
// // #ifdef APP-PLUS
|
||||
@@ -548,9 +394,10 @@ const loadConversationMsgList = async () => {
|
||||
// 获取首页数据
|
||||
|
||||
const getMainPageData = async () => {
|
||||
/// 从个渠道获取如二维,没有的时候就返回首页的数据
|
||||
// 从个渠道获取如二维,没有的时候就返回首页的数据
|
||||
const sceneId = appStore.sceneId || "";
|
||||
const res = await mainPageData({ sceneId });
|
||||
console.log("🚀 ~ getMainPageData ~ res:", res)
|
||||
|
||||
if (res.code === 0) {
|
||||
initData();
|
||||
@@ -582,7 +429,18 @@ const initWebSocket = async () => {
|
||||
|
||||
// 使用配置的WebSocket服务器地址
|
||||
const token = getAccessToken();
|
||||
const wsUrl = `${appStore.serverConfig.wssUrl}?access_token=${token}`;
|
||||
const rawWsUrl = appStore.serverConfig.wssUrl;
|
||||
const resolvedWsUrl =
|
||||
typeof rawWsUrl === "string" &&
|
||||
(rawWsUrl.startsWith("ws://") || rawWsUrl.startsWith("wss://"))
|
||||
? rawWsUrl
|
||||
: `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}${typeof rawWsUrl === "string"
|
||||
? rawWsUrl.startsWith("/")
|
||||
? rawWsUrl
|
||||
: `/${rawWsUrl}`
|
||||
: ""
|
||||
}`;
|
||||
const wsUrl = `${resolvedWsUrl}?access_token=${token}`;
|
||||
|
||||
// 初始化WebSocket管理器
|
||||
webSocketManager = new WebSocketManager({
|
||||
@@ -917,9 +775,9 @@ const sendMessage = async (message, isInstruct = false) => {
|
||||
if (!isWsConnected()) {
|
||||
console.log("WebSocket未连接,尝试重新连接...");
|
||||
// 显示加载提示
|
||||
uni.showLoading({
|
||||
title: "正在连接服务器...",
|
||||
});
|
||||
// uni.showLoading({
|
||||
// title: "正在连接服务器...",
|
||||
// });
|
||||
|
||||
// 尝试重新初始化WebSocket连接
|
||||
try {
|
||||
@@ -929,34 +787,34 @@ const sendMessage = async (message, isInstruct = false) => {
|
||||
|
||||
// 检查连接是否成功建立
|
||||
if (!isWsConnected()) {
|
||||
uni.hideLoading();
|
||||
// uni.hideLoading();
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: "连接服务器失败,请稍后重试",
|
||||
icon: "none",
|
||||
});
|
||||
// uni.showToast({
|
||||
// title: "连接服务器失败,请稍后重试",
|
||||
// icon: "none",
|
||||
// });
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
uni.hideLoading();
|
||||
// uni.hideLoading();
|
||||
} catch (error) {
|
||||
console.error("重新连接WebSocket失败:", error);
|
||||
uni.hideLoading();
|
||||
// uni.hideLoading();
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: "连接服务器失败,请稍后重试",
|
||||
icon: "none",
|
||||
});
|
||||
// uni.showToast({
|
||||
// title: "连接服务器失败,请稍后重试",
|
||||
// icon: "none",
|
||||
// });
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSessionActive.value) {
|
||||
uni.showToast({
|
||||
title: "请等待当前回复完成",
|
||||
icon: "none",
|
||||
});
|
||||
// uni.showToast({
|
||||
// title: "请等待当前回复完成",
|
||||
// icon: "none",
|
||||
// });
|
||||
return;
|
||||
}
|
||||
isSessionActive.value = true;
|
||||
@@ -1230,11 +1088,11 @@ const stopRequest = async () => {
|
||||
|
||||
// 组件销毁时清理资源
|
||||
onUnmounted(() => {
|
||||
uni.$off(NOTICE_EVENT_LOGIN_SUCCESS);
|
||||
uni.$off(SCROLL_TO_BOTTOM);
|
||||
uni.$off(SEND_MESSAGE_CONTENT_TEXT);
|
||||
uni.$off(SEND_MESSAGE_COMMAND_TYPE);
|
||||
uni.$off(NOTICE_EVENT_LOGOUT);
|
||||
// uni.$off(NOTICE_EVENT_LOGIN_SUCCESS);
|
||||
// uni.$off(SCROLL_TO_BOTTOM);
|
||||
// uni.$off(SEND_MESSAGE_CONTENT_TEXT);
|
||||
// uni.$off(SEND_MESSAGE_COMMAND_TYPE);
|
||||
// uni.$off(NOTICE_EVENT_LOGOUT);
|
||||
|
||||
resetConfig();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user