Compare commits

6 Commits

Author SHA1 Message Date
e6615da586 Merge branch 'fix-109' of https://git.nianxx.cn/zoujing/YGChatCS
# Conflicts:
#	src/pages/index/components/module/MoreService/index.vue
2025-10-16 20:40:30 +08:00
96fb41a9cf feat: 商品详情的卡片调整 2025-10-16 20:29:42 +08:00
d9287b47fa feat; 发送的消息类型的统一 2025-10-16 20:19:43 +08:00
1f590202a8 feat: 发送命令的组件与发送调整 2025-10-16 20:03:14 +08:00
24df46f2a3 Merge branch 'fix-109' of https://git.nianxx.cn/zoujing/YGChatCS
# Conflicts:
#	src/pages/index/components/chat/ChatQuickAccess/index.vue
2025-10-16 19:19:16 +08:00
b11b5888a7 feat: 样式调整 2025-10-16 18:57:48 +08:00
18 changed files with 135 additions and 157 deletions

View File

@@ -6,8 +6,8 @@ export const NOTICE_EVENT_LOGOUT = "NOTICE_EVENT_LOGOUT";
// 滚动到底部 // 滚动到底部
export const SCROLL_TO_BOTTOM = "SCROLL_TO_BOTTOM"; export const SCROLL_TO_BOTTOM = "SCROLL_TO_BOTTOM";
// 推荐帖子 // 发送消息文本类型
export const RECOMMEND_POSTS_TITLE = "RECOMMEND_POSTS_TITLE"; export const SEND_MESSAGE_CONTENT_TEXT = "SEND_MESSAGE_CONTENT_TEXT";
// 发送命令 // 发送消息命令类型
export const SEND_COMMAND_TEXT = "SEND_COMMAND_TEXT"; export const SEND_MESSAGE_COMMAND_TYPE = "SEND_MESSAGE_COMMAND_TYPE";

View File

@@ -14,6 +14,7 @@ export const MessageType = {
IMAGE: "IMAGE", IMAGE: "IMAGE",
}; };
/// 组件的名称
export const CompName = { export const CompName = {
// 快速预定卡片 // 快速预定卡片
quickBookingCard: "quickBookingCard", quickBookingCard: "quickBookingCard",
@@ -28,3 +29,21 @@ export const CompName = {
// 输入车牌卡片 // 输入车牌卡片
enterLicensePlateCard: "enterLicensePlateCard", enterLicensePlateCard: "enterLicensePlateCard",
}; };
/// 发送的指令类型
export const Command = {
// 快速预定
quickBooking: "Command.quickBooking",
// 探索发现
discovery: "Command.discovery",
// 呼叫服务
createWorkOrderCard: "Command.createWorkOrderCard",
// 更多
more: "Command.more",
// 我的订单
myOrder: "Command.myOrder",
// 我的工单
myWorkOrder: "Command.myWorkOrder",
// 反馈意见
feedbackCard: "Command.feedbackCard",
};

View File

@@ -18,7 +18,6 @@
.loading-container { .loading-container {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 4px 0;
max-width: 100%; // ✅ 限制最大宽度 max-width: 100%; // ✅ 限制最大宽度
} }

View File

@@ -5,7 +5,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 100px;
max-width: 100%; // ✅ 限制最大宽度 max-width: 100%; // ✅ 限制最大宽度
overflow-x: hidden; // ✅ 防止横向撑开 overflow-x: hidden; // ✅ 防止横向撑开
} }

View File

@@ -1,6 +1,8 @@
<template> <template>
<view class="chat-other border-box flex flex-col overflow-hidden pl-12"> <view
<text class="font-size-14 color-33">{{ text }}</text> class="chat-other border-box flex flex-col overflow-hidden pl-12 mt-6 mb-6"
>
<text class="font-size-14 color-333">{{ text }}</text>
<slot></slot> <slot></slot>
</view> </view>
</template> </template>
@@ -15,6 +17,4 @@ defineProps({
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
@import "./styles/index.scss";
</style>

View File

@@ -1,3 +0,0 @@
.chat-other {
margin: 6px 0;
}

View File

@@ -70,7 +70,6 @@
<AttachListComponent <AttachListComponent
v-if="item.question" v-if="item.question"
:question="item.question" :question="item.question"
@replySent="handleReply"
/> />
</template> </template>
</ChatCardAI> </ChatCardAI>
@@ -103,8 +102,8 @@
</scroll-view> </scroll-view>
<!-- 输入框区域 --> <!-- 输入框区域 -->
<view class="footer"> <view class="pb-safe-area">
<ChatQuickAccess @replySent="handleReplyInstruct" /> <ChatQuickAccess />
<ChatInputArea <ChatInputArea
ref="inputAreaRef" ref="inputAreaRef"
v-model="inputMessage" v-model="inputMessage"
@@ -121,12 +120,12 @@
</template> </template>
<script setup> <script setup>
import { onMounted, nextTick, onUnmounted, ref, defineEmits, watch } from "vue"; import { onMounted, nextTick, onUnmounted, ref, defineEmits } from "vue";
import { onLoad } from "@dcloudio/uni-app"; import { onLoad } from "@dcloudio/uni-app";
import { import {
SCROLL_TO_BOTTOM, SCROLL_TO_BOTTOM,
RECOMMEND_POSTS_TITLE, SEND_MESSAGE_CONTENT_TEXT,
SEND_COMMAND_TEXT, SEND_MESSAGE_COMMAND_TYPE,
NOTICE_EVENT_LOGOUT, NOTICE_EVENT_LOGOUT,
NOTICE_EVENT_LOGIN_SUCCESS, NOTICE_EVENT_LOGIN_SUCCESS,
} from "@/constant/constant"; } from "@/constant/constant";
@@ -264,24 +263,17 @@ const scrollToBottom = () => {
const setTimeoutScrollToBottom = () => setTimeout(() => scrollToBottom(), 100); const setTimeoutScrollToBottom = () => setTimeout(() => scrollToBottom(), 100);
// 发送普通消息 // 发送普通消息
const handleReply = (text) => { const handleReplyText = (text) => {
// 重置消息状态准备接收新的AI回复 // 重置消息状态准备接收新的AI回复
resetMessageState(); resetMessageState();
sendMessage(text); sendMessage(text);
setTimeoutScrollToBottom(); setTimeoutScrollToBottom();
}; };
// 是发送指令 // 是发送指令消息
const handleReplyInstruct = async (item) => { const handleReplyInstruct = async (item) => {
await checkToken(); await checkToken();
if (item.type === "MyOrder") {
// 订单
uni.navigateTo({
url: "/pages-order/order/list",
});
return;
}
commonType = item.type; commonType = item.type;
// 重置消息状态准备接收新的AI回复 // 重置消息状态准备接收新的AI回复
resetMessageState(); resetMessageState();
@@ -330,19 +322,17 @@ const addNoticeListener = () => {
}, 200); }, 200);
}); });
uni.$on(RECOMMEND_POSTS_TITLE, (value) => { uni.$on(SEND_MESSAGE_CONTENT_TEXT, (value) => {
console.log("RECOMMEND_POSTS_TITLE:", value); console.log("SEND_MESSAGE_CONTENT_TEXT:", value);
if (value && value.length > 0) { if (value && value.length > 0) {
handleReply(value); handleReplyText(value);
} }
}); });
uni.$on(SEND_COMMAND_TEXT, (value) => { uni.$on(SEND_MESSAGE_COMMAND_TYPE, (item) => {
console.log("SEND_COMMAND_TEXT:", value); console.log("SEND_MESSAGE_COMMAND_TYPE:", item);
if (value && value.length > 0) { if (item && item.type) {
commonType = "Command.quickBooking"; handleReplyInstruct(item);
sendMessage(value, true);
setTimeoutScrollToBottom();
} }
}); });
}; };
@@ -743,8 +733,8 @@ const stopRequest = () => {
onUnmounted(() => { onUnmounted(() => {
uni.$off(NOTICE_EVENT_LOGIN_SUCCESS); uni.$off(NOTICE_EVENT_LOGIN_SUCCESS);
uni.$off(SCROLL_TO_BOTTOM); uni.$off(SCROLL_TO_BOTTOM);
uni.$off(RECOMMEND_POSTS_TITLE); uni.$off(SEND_MESSAGE_CONTENT_TEXT);
uni.$off(SEND_COMMAND_TEXT); uni.$off(SEND_MESSAGE_COMMAND_TYPE);
uni.$off(NOTICE_EVENT_LOGOUT); uni.$off(NOTICE_EVENT_LOGOUT);
resetConfig(); resetConfig();
@@ -775,6 +765,4 @@ const resetConfig = () => {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
@import "./styles/index.scss";
</style>

View File

@@ -1,3 +0,0 @@
.footer {
padding-bottom: Max(env(safe-area-inset-bottom), 12px);
}

View File

@@ -20,109 +20,39 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { currentClientType, ClientType } from "@/constant/base"; import { Command } from "@/model/ChatModel";
import { SEND_MESSAGE_COMMAND_TYPE } from "@/constant/constant";
const itemList = ref([ const itemList = ref([
{ {
icon: "", icon: "",
title: "快速预定", title: "快速预定",
type: "quickBooking", type: Command.quickBooking,
}, },
{ {
icon: "", icon: "",
title: "探索发现", title: "探索发现",
type: "discovery", type: Command.discovery,
}, },
{ {
icon: "", icon: "",
title: "呼叫服务", title: "呼叫服务",
type: "callService", type: Command.createWorkOrderCard,
}, },
{ {
icon: "https://oss.nianxx.cn/mp/static/version_101/home/more.png", icon: "https://oss.nianxx.cn/mp/static/version_101/home/more.png",
title: "更多", title: "更多",
type: "more", type: Command.more,
}, },
]); ]);
const emits = defineEmits(["replySent"]);
const sendReply = (item) => { const sendReply = (item) => {
if (item.type === "more") { // 更多服务
if (item.type === Command.more) {
uni.$emit("SHOW_MORE_POPUP"); uni.$emit("SHOW_MORE_POPUP");
return; return;
} }
uni.$emit(SEND_MESSAGE_COMMAND_TYPE, item);
emits("replySent", item);
};
// onMounted(() => {
// initData();
// });
const initData = () => {
itemList.value =
currentClientType() === ClientType.TIANMU
? [
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_yuding.png",
showIcon: false,
title: "快速预定",
content: "预定门票、房间、餐食",
type: "Command.quickBooking",
},
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_find.png",
showIcon: false,
title: "探索发现",
content: "探索玩法、出片佳地",
type: "Command.discovery",
},
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_call.png",
showIcon: false,
title: "反馈意见",
content: "有意见告诉沐沐",
type: "Command.feedbackCard",
},
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_order.png",
showIcon: false,
title: "订单/工单",
content: "我的订单/工单",
type: "MyOrder",
},
]
: [
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_yuding.png",
showIcon: false,
title: "快速预定",
content: "预定门票、房间、餐食",
type: "Command.quickBooking",
},
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_find.png",
showIcon: false,
title: "探索发现",
content: "探索玩法、出片佳地",
type: "Command.discovery",
},
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_order.png",
showIcon: false,
title: "订单/工单",
content: "我的订单/工单",
type: "MyOrder",
},
{
icon: "https://oss.nianxx.cn/mp/static/quick/quick_icon_call.png",
showIcon: false,
title: "反馈意见",
content: "有意见告诉朵朵",
type: "Command.feedbackCard",
},
];
}; };
</script> </script>

View File

@@ -11,13 +11,13 @@
:duration="duration" :duration="duration"
> >
<swiper-item v-for="item in activityList" :key="item.id"> <swiper-item v-for="item in activityList" :key="item.id">
<view class="swiper-item" @click="handleClick(item)"> <view class="swiper-item" @click="handleClick()">
<image <image
class="swiper-img" class="swiper-img"
:src="item.activityCover" :src="item.activityCover"
mode="aspectFill" mode="aspectFill"
></image> ></image>
<view class="corner-btn">快速预定</view> <view class="corner-btn">{{ commandModel.title }}</view>
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>
@@ -26,7 +26,13 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { SEND_COMMAND_TEXT } from "@/constant/constant"; import { SEND_MESSAGE_COMMAND_TYPE } from "@/constant/constant";
const commandModel = ref({
icon: "",
title: "快速预定",
type: Command.quickBooking,
});
const autoplay = ref(true); const autoplay = ref(true);
const interval = ref(3000); const interval = ref(3000);
@@ -39,8 +45,8 @@ const props = defineProps({
}, },
}); });
const handleClick = (item) => { const handleClick = () => {
uni.$emit(SEND_COMMAND_TEXT, "快速预定"); uni.$emit(SEND_MESSAGE_COMMAND_TYPE, commandModel.value);
}; };
</script> </script>

View File

@@ -12,9 +12,12 @@
</template> </template>
<script setup> <script setup>
import { ref, nextTick, defineEmits } from "vue"; import { ref, nextTick } from "vue";
import { onMounted } from "vue"; import { onMounted } from "vue";
import { SCROLL_TO_BOTTOM } from "@/constant/constant"; import {
SCROLL_TO_BOTTOM,
SEND_MESSAGE_CONTENT_TEXT,
} from "@/constant/constant";
const props = defineProps({ const props = defineProps({
question: { question: {
@@ -24,10 +27,9 @@ const props = defineProps({
}); });
const tags = ref([]); const tags = ref([]);
const emits = defineEmits(["replySent"]);
const handleClick = (item) => { const handleClick = (item) => {
emits("replySent", item); uni.$emit(SEND_MESSAGE_CONTENT_TEXT, item);
}; };
onMounted(() => { onMounted(() => {

View File

@@ -1,5 +1,5 @@
<template> <template>
<view class="container"> <view class="w-full">
<template v-if="toolCall.picture && toolCall.picture.length > 0"> <template v-if="toolCall.picture && toolCall.picture.length > 0">
<ModuleTitle :title="图片详情" /> <ModuleTitle :title="图片详情" />
<ImageSwiper :images="toolCall.picture" /> <ImageSwiper :images="toolCall.picture" />
@@ -25,6 +25,4 @@ const props = defineProps({
}); });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss"></style>
@import "./styles/index.scss";
</style>

View File

@@ -1,4 +0,0 @@
.container {
width: 100%;
padding: 12px 0;
}

View File

@@ -20,7 +20,7 @@
</template> </template>
<script setup> <script setup>
import { RECOMMEND_POSTS_TITLE } from "@/constant/constant"; import { SEND_MESSAGE_CONTENT_TEXT } from "@/constant/constant";
import { defineProps } from "vue"; import { defineProps } from "vue";
import ModuleTitle from "@/components/ModuleTitle/index.vue"; import ModuleTitle from "@/components/ModuleTitle/index.vue";
@@ -33,7 +33,7 @@ const props = defineProps({
const sendReply = (item) => { const sendReply = (item) => {
const topic = item.userInputContent || item.topic.replace(/^#/, ""); const topic = item.userInputContent || item.topic.replace(/^#/, "");
uni.$emit(RECOMMEND_POSTS_TITLE, topic); uni.$emit(SEND_MESSAGE_CONTENT_TEXT, topic);
}; };
</script> </script>

View File

@@ -13,7 +13,7 @@
class="item border-box border-bottom pt-20 pb-20" class="item border-box border-bottom pt-20 pb-20"
v-for="(item, index) in list" v-for="(item, index) in list"
:key="index" :key="index"
@click="close" @click="handleClick(item)"
> >
<view class="flex flex-items-center flex-justify-center"> <view class="flex flex-items-center flex-justify-center">
<image v-if="item.icon" class="left" :src="item.icon" /> <image v-if="item.icon" class="left" :src="item.icon" />
@@ -40,6 +40,8 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { Command } from "@/model/ChatModel";
import { SEND_MESSAGE_COMMAND_TYPE } from "@/constant/constant";
const popup = ref(null); const popup = ref(null);
@@ -49,23 +51,23 @@ const list = ref([
title: "快速预定", title: "快速预定",
content: "预定门票、房间、餐食", content: "预定门票、房间、餐食",
btnText: "去预定", btnText: "去预定",
type: "quickBooking", type: Command.quickBooking,
path: "/pages/quickBooking/index", path: "",
}, },
{ {
icon: "https://oss.nianxx.cn/mp/static/version_101/home/tsfx.png", icon: "https://oss.nianxx.cn/mp/static/version_101/home/tsfx.png",
title: "探索发现", title: "探索发现",
content: "发现景点、活动、特色内容", content: "发现景点、活动、特色内容",
btnText: "去探索", btnText: "去探索",
type: "discovery", type: Command.discovery,
path: "/pages/discovery/index", path: "",
}, },
{ {
icon: "https://oss.nianxx.cn/mp/static/version_101/home/mddd.png", icon: "https://oss.nianxx.cn/mp/static/version_101/home/mddd.png",
title: "我的订单", title: "我的订单",
content: "查看门票、住宿、餐饮等订单", content: "查看门票、住宿、餐饮等订单",
btnText: "去查看", btnText: "去查看",
type: "myOrder", type: Command.myOrder,
path: "/pages-order/order/list", path: "/pages-order/order/list",
}, },
{ {
@@ -73,7 +75,7 @@ const list = ref([
title: "我的工单", title: "我的工单",
content: "查看服务工单、进度与处理情况", content: "查看服务工单、进度与处理情况",
btnText: "去查看", btnText: "去查看",
type: "myWorkOrder", type: Command.myWorkOrder,
path: "/pages/myWorkOrder/index", path: "/pages/myWorkOrder/index",
}, },
{ {
@@ -81,8 +83,8 @@ const list = ref([
title: "反馈意见", title: "反馈意见",
content: "提交使用问题、建议与需求", content: "提交使用问题、建议与需求",
btnText: "去反馈", btnText: "去反馈",
type: "feedback", type: Command.feedbackCard,
path: "/pages/feedback/index", path: "",
}, },
]); ]);
@@ -95,11 +97,12 @@ const close = () => {
}; };
const handleClick = (item) => { const handleClick = (item) => {
close();
if (item.path) { if (item.path) {
uni.navigateTo({ url: item.path }); uni.navigateTo({ url: item.path });
return;
} }
uni.$emit(SEND_MESSAGE_COMMAND_TYPE, item);
close();
}; };
// 接收更多服务 // 接收更多服务

View File

@@ -34,7 +34,7 @@
<script setup> <script setup>
import { defineProps } from "vue"; import { defineProps } from "vue";
import { RECOMMEND_POSTS_TITLE } from "@/constant/constant"; import { SEND_MESSAGE_CONTENT_TEXT } from "@/constant/constant";
import ModuleTitle from "@/components/ModuleTitle/index.vue"; import ModuleTitle from "@/components/ModuleTitle/index.vue";
const props = defineProps({ const props = defineProps({
@@ -46,7 +46,7 @@ const props = defineProps({
const sendReply = (item) => { const sendReply = (item) => {
const topic = item.userInputContent || item.topic.replace(/^#/, ""); const topic = item.userInputContent || item.topic.replace(/^#/, "");
uni.$emit(RECOMMEND_POSTS_TITLE, topic); uni.$emit(SEND_MESSAGE_CONTENT_TEXT, topic);
}; };
</script> </script>

View File

@@ -39,6 +39,14 @@
margin-bottom: 12px; margin-bottom: 12px;
} }
.mt-6 {
margin-top: 6px;
}
.mb-6 {
margin-bottom: 6px;
}
.ml-12 { .ml-12 {
margin-left: 12px; margin-left: 12px;
} }

View File

@@ -1,4 +1,24 @@
// 内边距 // 内边距
.p-6 {
padding: 6px;
}
.pt-6 {
padding-top: 6px;
}
.pb-6 {
padding-bottom: 6px;
}
.pl-6 {
padding-left: 6px;
}
.pr-6 {
padding-right: 6px;
}
.p-8 { .p-8 {
padding: 8px; padding: 8px;
} }
@@ -19,6 +39,14 @@
padding-bottom: 8px; padding-bottom: 8px;
} }
.pl-8 {
padding-left: 8px;
}
.pr-8 {
padding-right: 8px;
}
.p-12 { .p-12 {
padding: 12px; padding: 12px;
} }
@@ -27,6 +55,10 @@
padding-top: 12px; padding-top: 12px;
} }
.l-12 {
padding-left: 12px;
}
.pr-12 { .pr-12 {
padding-right: 12px; padding-right: 12px;
} }
@@ -66,3 +98,7 @@
.pb-20 { .pb-20 {
padding-bottom: 20px; padding-bottom: 20px;
} }
.pb-safe-area {
padding-bottom: Max(env(safe-area-inset-bottom), 12px);
}