Files
qiming/qiming-mobile/components/button-wrapper/button-wrapper.uvue

201 lines
5.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>