chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
<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>