201 lines
5.9 KiB
Plaintext
201 lines
5.9 KiB
Plaintext
<template>
|
||
<!-- 按钮包装器,使用flex布局实现居中和换行 -->
|
||
<view class="button-wrapper" :style="{ 'justify-content': buttonAlign }">
|
||
<!-- 循环渲染按钮列表 -->
|
||
<view
|
||
v-for="(item, index) in chatSuggestList"
|
||
:key="index"
|
||
class="button-item"
|
||
hover-class="hover-class"
|
||
@click="handleButtonClick(item)"
|
||
>
|
||
<image
|
||
v-if="item?.icon"
|
||
:src="item.icon"
|
||
class="default-icon"
|
||
mode="scaleToFill"
|
||
alt=""
|
||
/>
|
||
<!-- 按钮文本,支持省略号显示 -->
|
||
<text class="button-text">{{
|
||
typeof item === "string" ? item : item.info
|
||
}}</text>
|
||
</view>
|
||
<!-- #ifdef H5 || WEB -->
|
||
<page-preview-iframe ref="pagePreviewIframeRef" />
|
||
<!-- #endif -->
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import type { GuidQuestionDto } from "@/types/interfaces/agent";
|
||
import {
|
||
checkPathParams,
|
||
fillPathParams,
|
||
objectToQueryString,
|
||
} from "@/utils/common";
|
||
import { GuidQuestionSetTypeEnum } from "@/types/enums/agent.uts";
|
||
import { API_BASE_URL } from "@/constants/config";
|
||
import { handleExternalLink } from "@/utils/system";
|
||
import { addTicketAndJumpToWebview } from "@/utils/commonBusiness";
|
||
import { useI18n } from "@/utils/i18n";
|
||
|
||
const props = defineProps({
|
||
buttonAlign: {
|
||
type: String,
|
||
default: "left",
|
||
},
|
||
chatSuggestList: {
|
||
type: Array as PropType<string[] | GuidQuestionDto[]>,
|
||
default: () => [],
|
||
},
|
||
});
|
||
|
||
const emit = defineEmits<{
|
||
buttonClick: [guideQuestionInfo: string]; // 按钮点击事件,传递被点击的按钮信息
|
||
}>();
|
||
const { t } = useI18n();
|
||
|
||
// #ifdef H5 || WEB
|
||
const pagePreviewIframeRef = ref<any>(null);
|
||
// #endif
|
||
|
||
const handleShowPage = (eventConfig: GuidQuestionDto) => {
|
||
// 提取参数(从 data 中获取)
|
||
const pathParams: Record<string, any> = {};
|
||
const params: Record<string, any> = {};
|
||
if (eventConfig.args && Array.isArray(eventConfig.args)) {
|
||
eventConfig.args.forEach((arg: any) => {
|
||
if (arg.inputType === "Path" && arg.name) {
|
||
pathParams[arg.name] = arg.bindValue;
|
||
}
|
||
if (arg.inputType === "Query" && arg.name && arg.bindValue) {
|
||
params[arg.name] = arg.bindValue;
|
||
}
|
||
});
|
||
}
|
||
|
||
// 检查路径模板中的变量是否在 data 中存在且值有效
|
||
if (checkPathParams(eventConfig.pageUrl as string, pathParams)) {
|
||
const pageUrl = fillPathParams(
|
||
eventConfig?.pageUrl as string,
|
||
pathParams,
|
||
);
|
||
|
||
// 构建完整的页面 URL
|
||
let webviewUrl;
|
||
// 如果没有参数,直接返回 uri
|
||
if (!params || Object.keys(params).length === 0) {
|
||
webviewUrl = pageUrl;
|
||
} else {
|
||
// 拼接 query 参数
|
||
const queryString = objectToQueryString(params);
|
||
webviewUrl = `${pageUrl}?${queryString}`;
|
||
}
|
||
|
||
// #ifdef H5 || WEB
|
||
let uri =
|
||
process.env.NODE_ENV === "production"
|
||
? `${window.location.origin}${webviewUrl}`
|
||
: `${API_BASE_URL}${webviewUrl}`;
|
||
// 打开引导问题页面弹窗
|
||
pagePreviewIframeRef.value?.handlePageOpen({
|
||
uri,
|
||
method: "browser_open_page",
|
||
data_type: "html",
|
||
request_id: "",
|
||
});
|
||
// #endif
|
||
|
||
// #ifdef MP-WEIXIN
|
||
addTicketAndJumpToWebview(webviewUrl, "inner", eventConfig.info);
|
||
// #endif
|
||
} else {
|
||
uni.showToast({
|
||
title: t("Mobile.ButtonWrapper.pagePathParamConfigError"),
|
||
icon: "none",
|
||
});
|
||
}
|
||
};
|
||
|
||
// 点击引导问题建议按钮事件
|
||
const handleButtonClick = (item: string | GuidQuestionDto) => {
|
||
if (typeof item === "string") {
|
||
emit("button-click", item);
|
||
} else {
|
||
if (item.type === GuidQuestionSetTypeEnum.Question) {
|
||
emit("button-click", item.info);
|
||
}
|
||
// 内置页面
|
||
else if (item.type === GuidQuestionSetTypeEnum.Page) {
|
||
// 打开页面
|
||
if (!item.pageUrl) {
|
||
uni.showToast({
|
||
title: t("Mobile.ButtonWrapper.pagePathConfigError"),
|
||
icon: "none",
|
||
});
|
||
return;
|
||
}
|
||
// 打开页面
|
||
handleShowPage(item);
|
||
}
|
||
// 外部页面
|
||
else if (item.type === GuidQuestionSetTypeEnum.Link) {
|
||
handleExternalLink(item.url);
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 按钮包装器 - 使用flex布局实现居中和换行 */
|
||
.button-wrapper {
|
||
display: flex; /* 弹性布局 */
|
||
flex-direction: row; /* 水平排列 */
|
||
flex-wrap: wrap; /* 允许换行 */
|
||
justify-content: center; /* center horizontally */
|
||
gap: 20rpx; /* 按钮间距 */
|
||
// padding: 0 20rpx; /* 左右内边距 */
|
||
overflow: hidden;
|
||
max-height: 235rpx;
|
||
|
||
/* 单个按钮样式 */
|
||
.button-item {
|
||
padding: 10rpx 15rpx; /* 内边距 */
|
||
background-color: rgba(12, 20, 102, 0.04); /* 浅灰色背景 */
|
||
border-radius: 16rpx; /* 圆角 */
|
||
min-width: 200rpx; /* 最小宽度 */
|
||
max-width: 670rpx; /* 最大宽度 */
|
||
flex-shrink: 0; /* 不允许收缩 */
|
||
transition: all 0.3s ease; /* 过渡动画 */
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
|
||
&.hover-class {
|
||
background-color: rgba(12, 20, 102, 0.08);
|
||
}
|
||
|
||
.default-icon {
|
||
width: 28rpx;
|
||
height: 28rpx;
|
||
border-radius: 4rpx;
|
||
}
|
||
|
||
/* 按钮文本样式 */
|
||
.button-text {
|
||
font-size: 28rpx; /* 字体大小 */
|
||
color: rgba(21, 23, 31, 0.7); /* 文字颜色 */
|
||
text-align: center; /* 文字居中 */
|
||
line-height: 44rpx; /* 行高 */
|
||
white-space: nowrap; /* 不换行 */
|
||
overflow: hidden; /* 隐藏溢出 */
|
||
text-overflow: ellipsis; /* 显示省略号 */
|
||
flex: 1; /* 占据剩余空间,使省略号生效 */
|
||
min-width: 0; /* 允许 flex 子元素缩小到内容以下 */
|
||
}
|
||
}
|
||
}
|
||
</style>
|