diff --git a/CHANGELOG.md b/CHANGELOG.md
index c56ee77..93b21c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,18 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+## [1.10.0](https://github.com/TencentCloudBase/cloudbase-agent-ui/compare/v1.9.1...v1.10.0) (2025-04-23)
+
+
+### Features
+
+* support tencentmap card ([5c4437b](https://github.com/TencentCloudBase/cloudbase-agent-ui/commit/5c4437b3be43aca84433d2ae75ccfb21f6912cf3))
+
+
+### Bug Fixes
+
+* fix readme ([cee725d](https://github.com/TencentCloudBase/cloudbase-agent-ui/commit/cee725d566199b1865164e4687b5d45f8e6344c2))
+
### [1.9.1](https://github.com/TencentCloudBase/cloudbase-agent-ui/compare/v1.9.0...v1.9.1) (2025-04-21)
diff --git a/README.md b/README.md
index 081d6f1..08832ef 100644
--- a/README.md
+++ b/README.md
@@ -18,14 +18,17 @@ Agent UI 演示效果图
- **企业级功能集成** 流式输出/联网搜索/深度思考/多轮会话 开箱即用
- **多模型支持** 深度兼容 DeepSeek、Hunyuan 等主流大模型
- **配置即开发** 通过配置快速接入组件能力,无需处理复杂通信逻辑
+- **支持 MCP Server 调用&自定义工具卡片** 对接云开发MCP Server能力,支持开发者定制工具卡片展示
## 📦 使用指南
-### 1. 开通环境
+### 组件集成
+
+#### 1. 开通环境
Agent UI 微信小程序组件依赖**微信云开发**服务,需先开通云开发环境
-#### 1.1 开通微信云开发
+##### 1.1 开通微信云开发
开通方式,点击开发者工具顶部“云开发” 进行开通
@@ -33,21 +36,21 @@ Agent UI 微信小程序组件依赖**微信云开发**服务,需先开通云
如已开通微信云开发服务,请跳转至[云开发平台](https://tcb.cloud.tencent.com/dev)创建AI服务。
-#### 1.2、创建AI服务
+##### 1.2、创建AI服务
- 方式一:直接使用agent智能体服务

- 方式二:接入大模型

-### 2. 获取组件
+#### 2. 获取组件
可通过以下两种方式获取组件包代码
1. **克隆仓库到本地,提取其中components/agent-ui 目录使用**
2. **下载GitHub Release 包 agent-ui.zip,直接使用**
-### 3. 微信小程序项目引入组件
+#### 3. 微信小程序项目引入组件
1. **配置云开发环境ID**
打开 miniprogram/app.js 文件,配置云开发环境ID。
@@ -117,6 +120,54 @@ Page({
})
```
+### 自定义 MCP 工具卡片
+
+> 以下示例流程以结合腾讯地图 MCP Server 开发自定义工具卡片举例说明
+
+#### 1. 开通 MCP 能力
+
+- 进入云开发平台 AI+ MCP 页面,点击创建MCP Server
+
+
+
+- 若未开通过云托管服务,需先开通云托管
+
+
+
+#### 2. 配置 MCP Server
+
+- 以腾讯地图 MCP Server 举例,选择模板进行安装(按照指引获取腾讯地图平台API KEY后,配置环境变量)
+
+
+
+#### 3. agent 绑定 MCP Server tools
+
+- 在 agent 配置页点击添加MCP 服务,选择对应的MCP Server tools 使用 (此处腾讯地图示例可勾选 geocoder,placeSearchNearby, directionDriving, weather等工具)
+
+
+
+
+#### 4. 开发自定义卡片组件
+
+- 参照本工程中 apps/miniprogram-agent-ui/miniprogram/components/toolCard 目录内自定义工具卡片组件实现
+
+
+
+#### 5. 卡片组件引用配置
+
+- 自定义卡片组件引用声明配置(可在用户小程序项目全局app.json中配置 或 agent-ui组件index.json中配置)
+
+
+
+- agent-ui 组件内 customCard/index.wxml 中添加自定义组件
+
+
+
+#### 6. 卡片效果
+
+
+
+
## 🏗 项目结构
```bash
diff --git a/apps/miniprogram-agent-ui/miniprogram/app.js b/apps/miniprogram-agent-ui/miniprogram/app.js
index 05a0244..22bb594 100644
--- a/apps/miniprogram-agent-ui/miniprogram/app.js
+++ b/apps/miniprogram-agent-ui/miniprogram/app.js
@@ -10,7 +10,7 @@ App({
// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
- env: "luke-agent-dev-7g1nc8tqc2ab76af",
+ env: "luke-personal-test-new-8d0d90f5f",
traceUser: true,
});
}
diff --git a/apps/miniprogram-agent-ui/miniprogram/app.json b/apps/miniprogram-agent-ui/miniprogram/app.json
index f56c3b4..1644158 100644
--- a/apps/miniprogram-agent-ui/miniprogram/app.json
+++ b/apps/miniprogram-agent-ui/miniprogram/app.json
@@ -1,8 +1,11 @@
{
- "pages": [
- "pages/index/index",
- "pages/chatBot/chatBot"
- ],
+ "pages": ["pages/index/index", "pages/chatBot/chatBot", "pages/foodBuy/foodBuy"],
+ "usingComponents": {
+ "custom-map": "/components/toolCard/map/index",
+ "custom-weather": "/components/toolCard/weather/index",
+ "custom-food-list": "/components/toolCard/food-list/index",
+ "custom-business-list": "/components/toolCard/business-list/index"
+ },
"window": {
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
@@ -20,4 +23,4 @@
"uploadFile": 60000,
"downloadFile": 60000
}
-}
\ No newline at end of file
+}
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.js b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.js
new file mode 100644
index 0000000..2d55529
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.js
@@ -0,0 +1,18 @@
+Component({
+ properties: {
+ name: {
+ type: String,
+ value: "",
+ },
+ toolParams: {
+ type: Object,
+ value: {},
+ },
+ toolData: {
+ type: Object,
+ value: {},
+ },
+ },
+ data: {},
+ lifetimes: {},
+});
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.json b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.wxml b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.wxml
new file mode 100644
index 0000000..18d11d1
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.wxml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.wxss b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.wxss
new file mode 100644
index 0000000..40e4487
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/customCard/index.wxss
@@ -0,0 +1,3 @@
+.customCard {
+ margin: 15px 0px;
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.js b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.js
index 6d2cf98..4543984 100644
--- a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.js
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.js
@@ -1202,6 +1202,7 @@ Component({
let endTime = null; // 记录结束思考时间
let index = 0;
for await (let event of res.eventStream) {
+ // console.log("event", event);
const { chatStatus } = this.data;
if (chatStatus === 0) {
isManuallyPaused = true;
@@ -1360,6 +1361,7 @@ Component({
const callBody = {
id: tool_call.id,
name: this.transformToolName(tool_call.function.name),
+ rawParams: tool_call.function.arguments,
callParams: "```json\n" + JSON.stringify(tool_call.function.arguments, null, 2) + "\n```",
content: "",
};
@@ -1376,9 +1378,11 @@ Component({
// tool_call 场景,调用响应
if (type === "tool-result") {
const { toolCallId, result } = dataJson;
+ // console.log("tool-result", result);
if (lastValue.toolCallList && lastValue.toolCallList.length) {
const lastToolCallObj = lastValue.toolCallList.find((item) => item.id === toolCallId);
if (lastToolCallObj && !lastToolCallObj.callResult) {
+ lastToolCallObj.rawResult = result;
lastToolCallObj.callResult = "```json\n" + JSON.stringify(result, null, 2) + "\n```";
this.setData({
[`chatRecords[${lastValueIndex}].toolCallList`]: lastValue.toolCallList,
@@ -1405,6 +1409,7 @@ Component({
[`chatRecords[${lastValueIndex}].content`]: lastValue.content,
});
}
+ // console.log("this.data.chatRecords", this.data.chatRecords);
this.setData({
chatStatus: 0,
[`chatRecords[${lastValueIndex}].hiddenBtnGround`]: isManuallyPaused,
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.json b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.json
index 04c44b3..1f5e8c4 100644
--- a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.json
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.json
@@ -1,9 +1,10 @@
{
"component": true,
"usingComponents": {
- "markdownPreview":"/components/agent-ui/wd-markdown/index",
- "FoldedCard":"/components/agent-ui/collapse/index",
+ "markdownPreview": "/components/agent-ui/wd-markdown/index",
+ "FoldedCard": "/components/agent-ui/collapse/index",
"chatFile": "/components/agent-ui/chatFile/index",
- "feedback":"/components/agent-ui/feedback/index"
+ "feedback": "/components/agent-ui/feedback/index",
+ "customCard": "/components/agent-ui/customCard/index"
}
-}
\ No newline at end of file
+}
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.wxml b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.wxml
index 69490df..dbb5521 100644
--- a/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.wxml
+++ b/apps/miniprogram-agent-ui/miniprogram/components/agent-ui/index.wxml
@@ -55,7 +55,7 @@
-
+
@@ -141,6 +141,7 @@
+
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/assets/eye.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/assets/eye.svg
new file mode 100644
index 0000000..73e793d
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/assets/eye.svg
@@ -0,0 +1,5 @@
+
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/assets/phone-call.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/assets/phone-call.svg
new file mode 100644
index 0000000..15ccd52
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/assets/phone-call.svg
@@ -0,0 +1,13 @@
+
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.js b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.js
new file mode 100644
index 0000000..1e6b4e9
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.js
@@ -0,0 +1,91 @@
+Component({
+ properties: {
+ // 组件的属性列表
+ name: {
+ type: String,
+ value: "",
+ },
+ toolData: {
+ type: Object,
+ value: {},
+ },
+ },
+ methods: {
+ // 点击卡片跳转到详情页
+ onCardTap(e) {
+ const id = e.currentTarget.dataset.id;
+ // wx.navigateTo({
+ // url: `/pages/restaurant-detail/index?id=${id}`,
+ // });
+ },
+
+ // 点击呼叫按钮
+ onCallTap(e) {
+ const phone = e.currentTarget.dataset.phone;
+ wx.makePhoneCall({
+ phoneNumber: phone,
+ fail: () => {
+ wx.showToast({
+ title: "呼叫失败",
+ icon: "none",
+ });
+ },
+ });
+ },
+ getRandomImage() {
+ const randomIndex = Math.floor(Math.random() * this.data.mockBusinessList.length);
+ return this.data.mockBusinessList[randomIndex];
+ },
+ },
+ lifetimes: {
+ attached() {
+ // 根据 name 区分处理不同 tool 调用情况
+ const { name, toolData } = this.data;
+ // 将详细的结构化地址转换为经纬度坐标
+ if (name === "placeSearchNearby") {
+ console.log("toolData", toolData);
+ const { content } = toolData;
+ if (content[0].type === "text") {
+ const contentData = JSON.parse(content[0].text);
+ const { data } = contentData;
+ console.log("placeSearchNearby data", data);
+ this.setData({
+ restaurants: data.map((item, index) => ({
+ // ...item,
+ image: this.getRandomImage(),
+ description: `私房菜 ${item.ad_info.city}${item.ad_info.district} 私房菜打卡人气榜第${index + 1}名`,
+ rating: 4.2,
+ reviews: 1923,
+ id: item.id,
+ name: item.title,
+ address: item.address,
+ telephone: item.tel,
+ category: item.category,
+ distance: item._distance,
+ city: item.ad_info.city,
+ area: item.ad_info.district,
+ })),
+ isFoodCategory: data[0].category.includes("美食"),
+ });
+ }
+ }
+ },
+ },
+ data: {
+ mockBusinessList: [
+ "https://poi-pic.cdn.bcebos.com/swd/a98b9547-20b8-3f4c-903b-51694ed27090.jpg",
+ "https://poi-pic.cdn.bcebos.com/swd/8fa8c9a7-f061-3bbe-9e1c-cf370e92e814.jpg",
+ "https://poi-pic.cdn.bcebos.com/swd/9c9a246a-463c-343f-8448-252edf2864ab.jpg",
+ "https://photo-meituan.cdn.bcebos.com/photo/1736586257678cf0aa25fcaa1c0d86c3e009da6448",
+ "https://photo-meituan.cdn.bcebos.com/photo/16922109814d07935406d27bf3e16a7844ae00fdef",
+ "https://poi-pic.cdn.bcebos.com/swd/3a633f56-991f-3d0b-ba5c-6517140c72f1.jpg",
+ "https://poi-pic.cdn.bcebos.com/swd/2652750e-fe5d-3827-9254-0e272ab904b2.jpg",
+ "https://poi-pic.cdn.bcebos.com/swd/90a78fdc-fecc-3930-9271-8095da7ad209.jpg",
+ // "https://qcloud.dpfile.com/pc/saQroau_MHTJgh_qZJ2aG…2vfCF2ubeXzk49OsGrXt_KYDCngOyCwZK-s3fqawWswzk.jpg",
+ "https://poi-pic.cdn.bcebos.com/swd/4061ecf3-e403-38de-9ad4-16549f4e8269.jpg",
+ "http://hiphotos.baidu.com/space/pic/item/e850352ac65c1038a7059ed5ba119313b07e89aa.jpg",
+ ],
+ restaurants: [],
+ isFoodCategory: true, // 是否为美食分类
+ },
+});
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.json b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.wxml b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.wxml
new file mode 100644
index 0000000..61e72df
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.wxml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.description}} {{item.distance}}米
+
+
+
+
+
+ 电话: {{item.telephone}}
+ 地址: {{item.address}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.wxss b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.wxss
new file mode 100644
index 0000000..437709b
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/business-list/index.wxss
@@ -0,0 +1,113 @@
+.restaurant-list {
+ display: flex;
+ flex-direction: column;
+ padding: 20rpx;
+ background-color: #f5f5f5;
+ max-height: 900px;
+ border-radius: 8px;
+}
+
+.restaurant-content {
+ flex: 1;
+ overflow-y: scroll;
+}
+
+.restaurant-box {
+ /* display: flex;
+ flex-direction: row; */
+ background-color: #fff;
+ border-radius: 16rpx;
+ /* box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); */
+ margin-bottom: 20rpx;
+ overflow: hidden;
+}
+
+.restaurant-card {
+ display: flex;
+ flex-direction: row;
+ /* background-color: #fff; */
+ /* border-radius: 16rpx; */
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
+ /* margin-bottom: 20rpx; */
+ /* overflow: hidden; */
+}
+
+.restaurant-image {
+ width: 200rpx;
+ height: 200rpx;
+ border-radius: 16rpx 0 0 16rpx;
+}
+
+.restaurant-info {
+ flex: 1;
+ padding: 20rpx;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.restaurant-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 10rpx;
+}
+
+.restaurant-name {
+ font-size: 32rpx;
+ font-weight: bold;
+ color: #333;
+ width: 65%;
+}
+
+.rating {
+ display: flex;
+ align-items: left;
+ flex-direction: column;
+}
+
+.score {
+ font-size: 28rpx;
+ color: #ff9900;
+ font-weight: bold;
+}
+
+.reviews {
+ font-size: 24rpx;
+ color: #999;
+ /* margin-left: 10rpx; */
+ margin-right: 10rpx;
+}
+
+.description {
+ font-size: 26rpx;
+ color: #666;
+ margin-bottom: 10rpx;
+}
+
+.contact-info {
+ font-size: 24rpx;
+ color: #999;
+ margin-bottom: 10rpx;
+}
+
+.phone, .address {
+ display: block;
+}
+
+.call-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: #000;
+ color: #fff;
+ font-size: 28rpx;
+ border-radius: 14rpx;
+ padding: 14rpx 20rpx;
+}
+
+.call-icon {
+ width: 30rpx;
+ height: 30rpx;
+ margin-right: 10rpx;
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.js b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.js
new file mode 100644
index 0000000..5a93501
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.js
@@ -0,0 +1,54 @@
+Component({
+ properties: {
+ // 组件的属性列表
+ name: {
+ type: String,
+ value: "",
+ },
+ toolData: {
+ type: Object,
+ value: {},
+ },
+ },
+ data: {
+ foodList: [
+ {
+ id: 1,
+ name: "北京烤鸭",
+ image: "https://6c75-luke-personal-test-new-8d0d90f5f-1259218801.tcb.qcloud.la/%E7%83%A4%E9%B8%AD.png",
+ price: 100,
+ },
+ {
+ id: 2,
+ name: "冰糖雪梨",
+ image: "https://6c75-luke-personal-test-new-8d0d90f5f-1259218801.tcb.qcloud.la/%E5%86%B0%E7%B3%96.png",
+ price: 20,
+ },
+ {
+ id: 3,
+ name: "小酥肉",
+ image: "https://6c75-luke-personal-test-new-8d0d90f5f-1259218801.tcb.qcloud.la/%E9%85%A5%E8%82%89.png",
+ price: 19,
+ },
+ {
+ id: 4,
+ name: "麻辣小龙虾",
+ image: "https://6c75-luke-personal-test-new-8d0d90f5f-1259218801.tcb.qcloud.la/%E9%BE%99%E8%99%BE.png",
+ price: 299,
+ },
+ ],
+ },
+ methods: {
+ // 添加点击事件处理函数
+ onFoodItemTap: function (e) {
+ console.log("tofood e", e);
+ const foodId = e.currentTarget.dataset.id;
+ const foodItem = this.data.foodList.find((item) => item.id === foodId);
+
+ // 将商品数据存储到全局数据或通过页面参数传递
+ wx.navigateTo({
+ url: `/pages/foodBuy/foodBuy?id=${foodId}`,
+ });
+ },
+ },
+});
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.json b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.wxml b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.wxml
new file mode 100644
index 0000000..ff6ebe8
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.wxml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ {{item.name}}
+ ¥{{item.price}}
+
+
+
+
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.wxss b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.wxss
new file mode 100644
index 0000000..80626ee
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/food-list/index.wxss
@@ -0,0 +1,54 @@
+.food-card-list {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 16rpx;
+ padding: 16rpx 0rpx;
+}
+
+.food-card {
+ border-radius: 16rpx;
+ overflow: hidden;
+ background-color: #ffffff;
+ box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 16rpx;
+}
+
+.food-image {
+ width: 100%;
+ height: 260rpx;
+ border-radius: 8rpx;
+}
+
+.food-info {
+ margin-top: 8rpx;
+ text-align: center;
+}
+
+.food-name {
+ font-size: 28rpx;
+ font-weight: bold;
+ color: #333333;
+}
+
+.food-price {
+ font-size: 24rpx;
+ color: #999999;
+ margin-top: 4rpx;
+}
+
+.add-button {
+ margin-top: 12rpx;
+ width: 48rpx;
+ height: 48rpx;
+ border-radius: 50%;
+ background-color: #60a5fa;
+ color: #ffffff;
+ font-size: 32rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: none;
+}
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/east.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/east.svg
new file mode 100644
index 0000000..191f251
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/east.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/north.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/north.svg
new file mode 100644
index 0000000..82c4a99
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/north.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/northeast.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/northeast.svg
new file mode 100644
index 0000000..29ac907
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/northeast.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/northwest.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/northwest.svg
new file mode 100644
index 0000000..c9a3e2e
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/northwest.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/south.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/south.svg
new file mode 100644
index 0000000..20e193a
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/south.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/southeast.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/southeast.svg
new file mode 100644
index 0000000..79168c9
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/southeast.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/southwest.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/southwest.svg
new file mode 100644
index 0000000..9c0ce76
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/southwest.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/west.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/west.svg
new file mode 100644
index 0000000..19b5c87
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/assets/west.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.js b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.js
new file mode 100644
index 0000000..7cb7c18
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.js
@@ -0,0 +1,192 @@
+// 地图相关的组件
+Component({
+ properties: {
+ // 组件的属性列表
+ name: {
+ type: String,
+ value: "",
+ },
+ toolData: {
+ type: Object,
+ value: {},
+ },
+ toolParams: {
+ type: Object,
+ value: {},
+ },
+ },
+ data: {
+ latitude: 30,
+ longitude: 114,
+ scale: 10,
+ markers: [
+ {
+ id: 1,
+ latitude: 30,
+ longitude: 114,
+ width: 20,
+ height: 30,
+ },
+ ],
+ adcode: "", // 地址邮政编码
+ routeSteps: [], // 路线规划步骤
+ routeMode: "", // driving, bicycling, walking
+ routeInfo: {},
+ },
+ lifetimes: {
+ attached() {
+ // 根据 name 区分处理不同 tool 调用情况
+ const { name, toolData } = this.data;
+ // 将详细的结构化地址转换为经纬度坐标
+ if (name === "geocoder") {
+ console.log("toolData", toolData);
+ const { content } = toolData;
+ if (content[0].type === "text") {
+ const contentData = JSON.parse(content[0].text);
+ console.log("geocoder data", contentData);
+ const {
+ result: {
+ location: { lat, lng },
+ },
+ } = contentData;
+ this.setData({
+ latitude: lat,
+ longitude: lng,
+ markers: [
+ {
+ id: 1,
+ latitude: lat,
+ longitude: lng,
+ width: 20,
+ height: 30,
+ },
+ ],
+ });
+ }
+ }
+ // 地点搜索 查指定位置周边的点信息
+ if (name === "placeSearchNearby") {
+ // console.log("toolData", toolData);
+ const { content } = toolData;
+ if (content[0].type === "text") {
+ const { location } = this.data.toolParams;
+ const locationInfo = location.split(",");
+ const contentData = JSON.parse(content[0].text);
+ console.log("placeSearchNearby data", contentData);
+ const { data } = contentData;
+ this.setData({
+ latitude: locationInfo[0],
+ longitude: locationInfo[1],
+ markers: data.map((item, index) => ({
+ id: index,
+ latitude: item.location.lat,
+ longitude: item.location.lng,
+ width: 20,
+ height: 30,
+ })),
+ routeMode: "driving",
+ scale: 13,
+ });
+ }
+ }
+ // 路线规划
+ if (name === "directionDriving") {
+ console.log("toolData", toolData);
+ const { content } = toolData;
+ if (content[0].type === "text") {
+ const { from, to } = this.data.toolParams;
+ const fromInfo = from.split(",");
+ const toInfo = to.split(",");
+ const contentData = JSON.parse(content[0].text);
+ console.log("directionDriving data", contentData);
+ const {
+ result: { routes },
+ } = contentData;
+
+ if (routes.length) {
+ const firstRoute = routes[0];
+ const { polyline, steps } = firstRoute; //TODO: 需解压转化为经纬度坐标对数组
+ const transformPolyline = this.transformRawPolyline(polyline);
+ console.log("transformPolyline", transformPolyline);
+ const startAndEndPair = [
+ {
+ id: 1,
+ latitude: fromInfo[0],
+ longitude: fromInfo[1],
+ width: 20,
+ height: 30,
+ },
+ {
+ id: 2,
+ latitude: toInfo[0],
+ longitude: toInfo[1],
+ width: 20,
+ height: 30,
+ },
+ ];
+ this.setData({
+ latitude: fromInfo[0],
+ longitude: fromInfo[1],
+ markers: startAndEndPair,
+ polyline: [
+ {
+ points: transformPolyline,
+ color: "#1AC36D",
+ width: 4,
+ dottedLine: false,
+ },
+ ],
+ routeMode: "driving",
+ routeSteps: steps.map((item) => ({
+ icon: this.transformDirection(item.dir_desc),
+ instruction: item.instruction,
+ distance: item.distance,
+ })),
+ });
+ }
+
+ // const { data } = contentData;
+ // this.setData({
+ // latitude: locationInfo[0],
+ // longitude: locationInfo[1],
+ // markers: data.map((item, index) => ({
+ // id: item.index,
+ // latitude: item.location.lat,
+ // longitude: item.location.lng,
+ // })),
+ // routeMode: "driving",
+ // });
+ }
+ }
+ },
+ },
+ methods: {
+ transformDirection(direction) {
+ // 转换方向
+ const directionMap = {
+ 北: "north",
+ 南: "south",
+ 东: "east",
+ 西: "west",
+ 东北: "northeast",
+ 西北: "northwest",
+ 东南: "southeast",
+ 西南: "southwest",
+ };
+ return directionMap[direction];
+ },
+ transformRawPolyline(polyline) {
+ let transformPolyline = [];
+ for (let i = 2; i < polyline.length; i++) {
+ polyline[i] = polyline[i - 2] + polyline[i] / 1000000;
+ }
+ for (let i = 0; i < polyline.length; i += 2) {
+ transformPolyline.push({
+ latitude: polyline[i],
+ longitude: polyline[i + 1],
+ });
+ }
+ return transformPolyline;
+ },
+ },
+});
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.json b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.wxml b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.wxml
new file mode 100644
index 0000000..7d0fdf7
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.wxml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 起
+
+ 从我的位置出发
+
+
+
+
+
+
+
+ {{item.instruction}}
+ 长度 {{item.distance}} 米
+
+
+
+
+ 终
+
+ 终点
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.wxss b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.wxss
new file mode 100644
index 0000000..d496d05
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/map/index.wxss
@@ -0,0 +1,86 @@
+.route-list {
+ display: flex;
+ flex-direction: column;
+ max-height: 400px;
+ background-color: #fff;
+ padding-right: 20px;
+ border-radius: 8px;
+}
+
+.route-header {
+ display: flex;
+ align-items: center;
+ padding: 20rpx;
+ border-bottom: 1px solid #eee;
+}
+
+.back-icon {
+ width: 40rpx;
+ height: 40rpx;
+ margin-right: 20rpx;
+}
+
+.route-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ color: #333;
+}
+
+.route-content {
+ flex: 1;
+ overflow-y: scroll;
+ padding: 20rpx;
+}
+
+.route-item {
+ display: flex;
+ align-items: flex-start;
+ padding: 20rpx 0;
+ border-bottom: 1px solid #f5f5f5;
+}
+
+.route-item:last-child {
+ border-bottom: none;
+}
+
+.icon {
+ width: 40rpx;
+ height: 40rpx;
+ margin-right: 20rpx;
+}
+
+.details {
+ display: flex;
+ flex-direction: column;
+}
+
+.instruction {
+ font-size: 28rpx;
+ color: #333;
+}
+
+.direction {
+ font-size: 24rpx;
+ color: #999;
+ margin-top: 4rpx;
+}
+
+.start .icon {
+ background-color: #07c160;
+ border-radius: 50%;
+ color: white;
+ font-size: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.end .icon {
+ background-color: #DE544e;
+ border-radius: 50%;
+ color: white;
+ font-size: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/cloudy.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/cloudy.svg
new file mode 100644
index 0000000..9a4bc7d
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/cloudy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/overcast.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/overcast.svg
new file mode 100644
index 0000000..d52b7d9
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/overcast.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/rainy.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/rainy.svg
new file mode 100644
index 0000000..a08fe79
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/rainy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/snowy.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/snowy.svg
new file mode 100644
index 0000000..2b917dd
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/snowy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/sunny.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/sunny.svg
new file mode 100644
index 0000000..9950200
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/sunny.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/sunnyovercast.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/sunnyovercast.svg
new file mode 100644
index 0000000..7a11d86
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/sunnyovercast.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/thunderstorm.svg b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/thunderstorm.svg
new file mode 100644
index 0000000..69954f9
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/assets/thunderstorm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.js b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.js
new file mode 100644
index 0000000..3a15949
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.js
@@ -0,0 +1,129 @@
+Component({
+ properties: {
+ // 组件的属性列表
+ name: {
+ type: String,
+ value: "",
+ },
+ toolData: {
+ type: Object,
+ value: {},
+ },
+ },
+ data: {
+ isDay: false,
+ // currentTemp: 29,
+ currentUnit: "°C",
+ // highTemp: 33,
+ // lowTemp: 21,
+ // hourlyUnit: "°C",
+ // hourlyData: [
+ // { time: "8AM", temp: 26 },
+ // { time: "9AM", temp: 28 },
+ // { time: "10AM", temp: 30 },
+ // { time: "11AM", temp: 32 },
+ // { time: "12PM", temp: 33 },
+ // ],
+ city: "",
+ forecasts: [],
+ today: {},
+ },
+ lifetimes: {
+ attached() {
+ // 可以在这里动态设置城市天气数据
+ // 根据 name 区分处理不同 tool 调用情况
+ const { name, toolData } = this.data;
+ if (name === "weather") {
+ console.log("toolData", toolData);
+ const { content } = toolData;
+ if (content[0].type === "text") {
+ const contentData = JSON.parse(content[0].text);
+ const {
+ result: { forecast },
+ } = contentData;
+ console.log("forecast", forecast);
+ const isDay = this.checkIsDay();
+ if (forecast.length) {
+ const todayForecast = forecast[0];
+ const { city, district, infos } = todayForecast;
+ const todayInfo = infos[0];
+ this.setData({
+ isDay,
+ city,
+ forecasts: infos.map((item) => {
+ const { date, week, day, night } = item;
+ const dateInfo = date.split("-");
+ return {
+ // ...item,
+ dayweather: day.weather,
+ nightweather: night.weather,
+ daytemp: day.temperature,
+ nighttemp: night.temperature,
+ date: `${dateInfo[1]}/${dateInfo[2]}`,
+ dayweatherIcon: this.transformWeather(day.weather),
+ nightweatherIcon: this.transformWeather(night.weather),
+ };
+ }),
+ today: {
+ daytemp: todayInfo.day.temperature,
+ nighttemp: todayInfo.night.temperature,
+ dayweather: todayInfo.day.weather,
+ nightweather: todayInfo.night.weather,
+ dayweatherIcon: this.transformWeather(todayInfo.day.weather),
+ nightweatherIcon: this.transformWeather(todayInfo.night.weather),
+ },
+ });
+ }
+ // this.setData({
+ // isDay,
+ // city,
+ // forecasts: forecasts.map((item) => {
+ // const { date } = item;
+ // const dateInfo = date.split("-");
+ // return {
+ // ...item,
+ // date: `${dateInfo[1]}/${dateInfo[2]}`,
+ // dayweatherIcon: this.transformWeather(item.dayweather),
+ // nightweatherIcon: this.transformWeather(item.nightweather),
+ // };
+ // }),
+ // today: {
+ // daytemp: forecasts[0].daytemp,
+ // nighttemp: forecasts[0].nighttemp,
+ // daywind: forecasts[0].daywind,
+ // nightwind: forecasts[0].nightwind,
+ // dayweather: forecasts[0].dayweather,
+ // nightweather: forecasts[0].nightweather,
+ // dayweatherIcon: this.transformWeather(forecasts[0].dayweather),
+ // nightweatherIcon: this.transformWeather(forecasts[0].nightweather),
+ // },
+ // });
+ }
+ }
+ },
+ },
+ methods: {
+ checkIsDay() {
+ const currentHour = new Date().getHours();
+ this.setData({
+ isDay: currentHour >= 6 && currentHour < 18,
+ });
+ },
+ transformWeather(weather) {
+ // 转换天气
+ const weatherMap = {
+ 晴: "sunny",
+ 多云: "cloudy",
+ 阴: "overcast",
+ 雨: "rainy",
+ 雪: "snowy",
+ 雷阵雨: "thunderstorm",
+ 大雨: "rainy",
+ 中雨: "rainy",
+ 小雨: "rainy",
+ 晴间多云: "sunnyovercast",
+ };
+ return weatherMap[weather] || "sunny";
+ },
+ },
+});
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.json b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.wxml b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.wxml
new file mode 100644
index 0000000..1ee903a
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.wxml
@@ -0,0 +1,26 @@
+
+
+
+
+
+ {{item.date}}
+
+
+ {{isDay ? item.dayweather : item.nightweather}}
+
+
+ {{item.nighttemp}}°~{{item.daytemp}}°
+
+
+
+
diff --git a/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.wxss b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.wxss
new file mode 100644
index 0000000..328e2a0
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/components/toolCard/weather/index.wxss
@@ -0,0 +1,99 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ gap: 16rpx;
+ border-radius: 32rpx;
+ padding: 16rpx;
+ /* max-width: 500rpx; */
+ /* width: 100%; */
+}
+
+.day {
+ background-color: #60a5fa;
+}
+
+.night {
+ background-color: #312e81;
+}
+
+.header {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.temp-container {
+ display: flex;
+ flex-direction: row;
+ gap: 8rpx;
+ align-items: center;
+}
+
+.temp-circle {
+ width: 80rpx;
+ height: 80rpx;
+ border-radius: 50%;
+}
+
+.day-circle {
+ background-color: #facc15;
+}
+
+.night-circle {
+ background-color: #c7d2fe;
+}
+
+.temp-text {
+ font-size: 48rpx;
+ font-weight: 500;
+ color: #f0f9ff;
+}
+
+.city-text {
+ font-size: 38rpx;
+ font-weight: 500;
+ color: #f0f9ff;
+}
+
+.high-low-text {
+ color: #f0f9ff;
+ font-size: 14px;
+}
+
+.hourly-container {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
+
+.hourly-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8rpx;
+}
+
+.hour-text {
+ color: #dbeafe;
+ font-size: 24rpx;
+}
+
+.hour-circle {
+ width: 48rpx;
+ height: 48rpx;
+ border-radius: 50%;
+}
+
+.hour-day-circle {
+ background-color: #facc15;
+}
+
+.hour-night-circle {
+ background-color: #e0e7ff;
+}
+
+.hour-temp {
+ color: #f0f9ff;
+ font-size: 28rpx;
+}
diff --git a/apps/miniprogram-agent-ui/miniprogram/imgs/back.svg b/apps/miniprogram-agent-ui/miniprogram/imgs/back.svg
new file mode 100644
index 0000000..303fd2d
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/imgs/back.svg
@@ -0,0 +1,3 @@
+
diff --git a/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.js b/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.js
index bcd16e2..4446621 100644
--- a/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.js
+++ b/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.js
@@ -14,7 +14,7 @@ Page({
// resourceEnv: "chriscc-demo-7ghlpjf846d46d2d",
// },
agentConfig: {
- botId: "bot-db3cab4a", // agent id,
+ botId: "bot-c5167aab", // agent id,
allowWebSearch: true, // 允许客户端选择启用联网搜索
allowUploadFile: true, // 允许上传文件
allowPullRefresh: true, // 允许下拉刷新
diff --git a/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.wxml b/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.wxml
index 5a1a982..de560ce 100644
--- a/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.wxml
+++ b/apps/miniprogram-agent-ui/miniprogram/pages/chatBot/chatBot.wxml
@@ -1,4 +1,5 @@
-
+
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.js b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.js
new file mode 100644
index 0000000..7873689
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.js
@@ -0,0 +1,58 @@
+Page({
+ data: {
+ selectedOption: 1,
+ foodDetail: {
+ id: 4,
+ name: "凉面饮品单人餐",
+ image: "https://6c75-luke-personal-test-new-8d0d90f5f-1259218801.tcb.qcloud.la/%E9%BE%99%E8%99%BE.png",
+ price: 15.8,
+ originalPrice: 24,
+ shopName: "肥肥虾庄·金牌油焖大虾",
+ location: "光谷之星店",
+ rating: 4.5,
+ sold: "5000+",
+ discount: "6.6折",
+ description: "肥肥的嫩嫩冰粉,料足清爽",
+ validPeriod: "2024.4.11 至 2025.4.25 23:59",
+ shopInfo: {
+ address: "距您8.0km,高科园路18号中建光谷之星F地块商业街...",
+ businessHours: "00:00-02:00 11:00-24:00",
+ },
+ },
+ },
+
+ onLoad: function (options) {
+ const foodId = options.id;
+ // 在实际应用中,这里应该从服务器或本地存储获取商品详情
+ // 这里使用静态数据模拟
+ console.log("加载商品ID:", foodId);
+ },
+
+ // 选择商品选项
+ selectOption: function (e) {
+ const optionId = e.currentTarget.dataset.id;
+ this.setData({
+ selectedOption: optionId,
+ });
+
+ // 根据选项更新价格
+ if (optionId === 2) {
+ this.setData({
+ "foodDetail.price": this.data.foodDetail.price * 2,
+ "foodDetail.originalPrice": this.data.foodDetail.originalPrice * 2,
+ "foodDetail.name": "肥肥菜虾双人餐",
+ });
+ } else {
+ this.setData({
+ "foodDetail.price": 15.8,
+ "foodDetail.originalPrice": 24,
+ "foodDetail.name": "单人餐",
+ });
+ }
+ },
+
+ // 返回上一页
+ navigateBack: function () {
+ wx.navigateBack();
+ },
+});
diff --git a/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.json b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.wxml b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.wxml
new file mode 100644
index 0000000..2c98cdc
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.wxml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+ ¥{{foodDetail.price}}
+ ¥{{foodDetail.originalPrice}}
+
+
+
+
+ {{foodDetail.name}}
+
+ ¥{{foodDetail.price * 2}}
+ ¥{{foodDetail.originalPrice * 2}}
+
+
+
+
+
+
+
+ 券后价 · 已售{{foodDetail.sold}}
+
+ ¥{{foodDetail.price}}
+ {{foodDetail.discount}} 共减{{(foodDetail.originalPrice - foodDetail.price)}}元
+ ¥{{foodDetail.originalPrice}}
+
+ 特价团限量·低价
+
+
+
+
+
+
+ 支持送礼物
+
+ 赠送好友
+
+
+
+
+
+
+ {{foodDetail.name}}
+ {{foodDetail.description}}
+
+
+
+
+
+
+
+
+ 服务保障
+ 免预约 · 随时退 · 过期自动退
+
+
+
+
+ 有效期限
+ {{foodDetail.validPeriod}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{foodDetail.shopName}}
+ {{foodDetail.rating}}
+
+ 小龙虾 光谷/东湖高新区 ¥120/人
+
+
+
+ {{foodDetail.shopInfo.address}}
+
+
+
+
+ 营业中 {{foodDetail.shopInfo.businessHours}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ¥5
+ 领现金
+
+
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.wxss b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.wxss
new file mode 100644
index 0000000..6c6d980
--- /dev/null
+++ b/apps/miniprogram-agent-ui/miniprogram/pages/foodBuy/foodBuy.wxss
@@ -0,0 +1,403 @@
+page {
+ background-color: #f5f5f5;
+}
+
+.food-detail {
+ position: relative;
+ width: 100%;
+}
+
+/* 顶部背景和导航 */
+.header {
+ position: relative;
+ width: 100%;
+ height: 400rpx;
+}
+
+.header-bg {
+ width: 100%;
+ height: 100%;
+}
+
+.header-nav {
+ position: absolute;
+ top: 80rpx;
+ left: 0;
+ right: 0;
+ display: flex;
+ justify-content: space-between;
+ padding: 0 30rpx;
+}
+
+.nav-left {
+ width: 60rpx;
+ height: 60rpx;
+ border-radius: 50%;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.icon-back {
+ width: 30rpx;
+ height: 30rpx;
+}
+
+.nav-right {
+ display: flex;
+ gap: 20rpx;
+}
+
+.nav-right image {
+ width: 60rpx;
+ height: 60rpx;
+ border-radius: 50%;
+ background-color: rgba(0, 0, 0, 0.5);
+ padding: 10rpx;
+}
+
+/* 商品选项区 */
+.product-options {
+ margin-top: -30rpx;
+ display: flex;
+ padding: 0 30rpx;
+ gap: 20rpx;
+}
+
+.option-item {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ background-color: white;
+ border-radius: 16rpx;
+ padding: 20rpx;
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
+ position: relative;
+}
+
+.option-item.selected {
+ border: 2rpx solid #ff5000;
+}
+
+.option-image {
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 10rpx;
+}
+
+.option-price {
+ font-size: 32rpx;
+ color: #ff5000;
+ font-weight: bold;
+ /* margin-top: 10rpx; */
+}
+
+.option-original-price {
+ font-size: 24rpx;
+ color: #999;
+ text-decoration: line-through;
+}
+
+.option-name {
+ font-size: 26rpx;
+ margin-top: 10rpx;
+}
+
+/* 价格区 */
+.price-section {
+ margin-top: 20rpx;
+ background-color: white;
+ padding: 30rpx;
+ position: relative;
+}
+
+.price-tag {
+ font-size: 28rpx;
+ color: #666;
+}
+
+.price-display {
+ display: flex;
+ align-items: baseline;
+ margin-top: 10rpx;
+}
+
+.current-price {
+ font-size: 48rpx;
+ color: #ff5000;
+ font-weight: bold;
+}
+
+.discount-info {
+ margin-left: 20rpx;
+ font-size: 24rpx;
+ color: white;
+ background-color: #ff5000;
+ padding: 4rpx 10rpx;
+ border-radius: 6rpx;
+}
+
+.original-price {
+ margin-left: 20rpx;
+ font-size: 28rpx;
+ color: #999;
+ text-decoration: line-through;
+}
+
+.special-tag {
+ position: absolute;
+ right: 30rpx;
+ top: 40rpx;
+ background-color: #ffe8d9;
+ color: #ff5000;
+ font-size: 28rpx;
+ padding: 4rpx 10rpx;
+ border-radius: 6rpx;
+ font-weight: bold;
+}
+
+.special-tag text {
+ font-size: 24rpx;
+ font-weight: normal;
+ margin-left: 10rpx;
+}
+
+/* 服务信息区 */
+.service-section {
+ margin-top: 20rpx;
+ background-color: white;
+}
+
+.gift-support {
+ display: flex;
+ align-items: center;
+ padding: 30rpx;
+ border-bottom: 1rpx solid #eee;
+}
+
+.gift-icon {
+ width: 40rpx;
+ height: 40rpx;
+ margin-right: 10rpx;
+}
+
+.send-gift {
+ margin-left: auto;
+ color: #999;
+ font-size: 28rpx;
+ display: flex;
+ align-items: center;
+}
+
+.arrow-right {
+ width: 30rpx;
+ height: 30rpx;
+ margin-left: 6rpx;
+}
+
+/* 商品信息 */
+.product-info {
+ padding: 30rpx;
+}
+
+.product-name {
+ font-size: 36rpx;
+ font-weight: bold;
+ margin-bottom: 20rpx;
+}
+
+.product-desc {
+ font-size: 28rpx;
+ color: #666;
+ margin-bottom: 30rpx;
+ padding: 10rpx 0;
+ border-bottom: 1rpx solid #eee;
+}
+
+.info-section {
+ margin-bottom: 20rpx;
+}
+
+.info-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20rpx;
+}
+
+.info-header text {
+ font-size: 30rpx;
+ font-weight: bold;
+}
+
+.info-more {
+ color: #999;
+ font-size: 28rpx;
+ display: flex;
+ align-items: center;
+}
+
+.service-guarantee, .validity-period {
+ display: flex;
+ justify-content: space-between;
+ padding: 20rpx 0;
+ font-size: 30rpx;
+}
+
+.guarantee-details, .period-details {
+ color: #999;
+ font-size: 28rpx;
+}
+
+.applicable-stores {
+ margin-top: 20rpx;
+ padding-top: 20rpx;
+ border-top: 1rpx solid #eee;
+}
+
+.store-header {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 20rpx;
+}
+
+.store-header text:first-child {
+ font-size: 30rpx;
+ font-weight: bold;
+}
+
+.store-count {
+ color: #999;
+ font-size: 28rpx;
+ display: flex;
+ align-items: center;
+}
+
+/* 店铺卡片 */
+.shop-card {
+ background-color: #f9f9f9;
+ border-radius: 16rpx;
+ padding: 20rpx;
+ display: flex;
+ margin-top: 20rpx;
+ margin-bottom: 100rpx;
+}
+
+.shop-image {
+ width: 120rpx;
+ height: 120rpx;
+ border-radius: 10rpx;
+ margin-right: 20rpx;
+}
+
+.shop-info {
+ flex: 1;
+}
+
+.shop-name-row {
+ display: flex;
+ align-items: center;
+ margin-bottom: 10rpx;
+}
+
+.shop-icon {
+ width: 30rpx;
+ height: 30rpx;
+ margin-right: 6rpx;
+}
+
+.shop-name {
+ font-size: 28rpx;
+ font-weight: bold;
+ flex: 1;
+}
+
+.shop-rating {
+ font-size: 28rpx;
+ color: #ff5000;
+ font-weight: bold;
+}
+
+.shop-location {
+ font-size: 26rpx;
+ color: #666;
+ margin-bottom: 10rpx;
+}
+
+.shop-popular {
+ font-size: 26rpx;
+ color: #666;
+ margin-bottom: 20rpx;
+ display: flex;
+ align-items: center;
+}
+
+.crown-icon {
+ width: 30rpx;
+ height: 30rpx;
+ margin-left: 6rpx;
+ margin-right: 6rpx;
+}
+
+.shop-address, .shop-hours {
+ display: flex;
+ align-items: center;
+ font-size: 26rpx;
+ color: #666;
+ margin-bottom: 10rpx;
+}
+
+.location-icon, .clock-icon {
+ width: 30rpx;
+ height: 30rpx;
+ margin-right: 6rpx;
+}
+
+/* 底部购买按钮 */
+.bottom-button {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 20rpx;
+ background-color: white;
+ box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
+}
+
+.buy-now-btn {
+ background-color: #ff5000;
+ color: white;
+ border-radius: 40rpx;
+ font-size: 32rpx;
+ font-weight: bold;
+ padding: 20rpx 0;
+}
+
+/* 红包悬浮按钮 */
+.floating-coupon {
+ position: fixed;
+ right: 30rpx;
+ bottom: 180rpx;
+ background-color: #ff5000;
+ width: 80rpx;
+ height: 80rpx;
+ border-radius: 50%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4rpx 10rpx rgba(255, 80, 0, 0.3);
+}
+
+.coupon-amount {
+ color: white;
+ font-size: 32rpx;
+ font-weight: bold;
+}
+
+.coupon-text {
+ color: white;
+ font-size: 20rpx;
+}
\ No newline at end of file
diff --git a/apps/miniprogram-agent-ui/project.private.config.json b/apps/miniprogram-agent-ui/project.private.config.json
index b5ce4ef..703fd4b 100644
--- a/apps/miniprogram-agent-ui/project.private.config.json
+++ b/apps/miniprogram-agent-ui/project.private.config.json
@@ -4,7 +4,7 @@
"urlCheck": true,
"coverView": true,
"lazyloadPlaceholderEnable": false,
- "skylineRenderEnable": false,
+ "skylineRenderEnable": true,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": true,
@@ -21,4 +21,4 @@
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "cloudbase-agent-ui",
"libVersion": "3.7.10"
-}
\ No newline at end of file
+}
diff --git a/components/agent-ui/customCard/index.js b/components/agent-ui/customCard/index.js
new file mode 100644
index 0000000..2d55529
--- /dev/null
+++ b/components/agent-ui/customCard/index.js
@@ -0,0 +1,18 @@
+Component({
+ properties: {
+ name: {
+ type: String,
+ value: "",
+ },
+ toolParams: {
+ type: Object,
+ value: {},
+ },
+ toolData: {
+ type: Object,
+ value: {},
+ },
+ },
+ data: {},
+ lifetimes: {},
+});
diff --git a/components/agent-ui/customCard/index.json b/components/agent-ui/customCard/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/components/agent-ui/customCard/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/components/agent-ui/customCard/index.wxml b/components/agent-ui/customCard/index.wxml
new file mode 100644
index 0000000..18d11d1
--- /dev/null
+++ b/components/agent-ui/customCard/index.wxml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/agent-ui/customCard/index.wxss b/components/agent-ui/customCard/index.wxss
new file mode 100644
index 0000000..40e4487
--- /dev/null
+++ b/components/agent-ui/customCard/index.wxss
@@ -0,0 +1,3 @@
+.customCard {
+ margin: 15px 0px;
+}
\ No newline at end of file
diff --git a/components/agent-ui/index.js b/components/agent-ui/index.js
index 6d2cf98..00a238d 100644
--- a/components/agent-ui/index.js
+++ b/components/agent-ui/index.js
@@ -1202,6 +1202,7 @@ Component({
let endTime = null; // 记录结束思考时间
let index = 0;
for await (let event of res.eventStream) {
+ console.log("event", event);
const { chatStatus } = this.data;
if (chatStatus === 0) {
isManuallyPaused = true;
@@ -1360,6 +1361,7 @@ Component({
const callBody = {
id: tool_call.id,
name: this.transformToolName(tool_call.function.name),
+ rawParams: tool_call.function.arguments,
callParams: "```json\n" + JSON.stringify(tool_call.function.arguments, null, 2) + "\n```",
content: "",
};
@@ -1376,9 +1378,11 @@ Component({
// tool_call 场景,调用响应
if (type === "tool-result") {
const { toolCallId, result } = dataJson;
+ console.log("tool-result", result);
if (lastValue.toolCallList && lastValue.toolCallList.length) {
const lastToolCallObj = lastValue.toolCallList.find((item) => item.id === toolCallId);
if (lastToolCallObj && !lastToolCallObj.callResult) {
+ lastToolCallObj.rawResult = result;
lastToolCallObj.callResult = "```json\n" + JSON.stringify(result, null, 2) + "\n```";
this.setData({
[`chatRecords[${lastValueIndex}].toolCallList`]: lastValue.toolCallList,
@@ -1405,6 +1409,7 @@ Component({
[`chatRecords[${lastValueIndex}].content`]: lastValue.content,
});
}
+ console.log("this.data.chatRecords", this.data.chatRecords);
this.setData({
chatStatus: 0,
[`chatRecords[${lastValueIndex}].hiddenBtnGround`]: isManuallyPaused,
diff --git a/components/agent-ui/index.json b/components/agent-ui/index.json
index 04c44b3..1f5e8c4 100644
--- a/components/agent-ui/index.json
+++ b/components/agent-ui/index.json
@@ -1,9 +1,10 @@
{
"component": true,
"usingComponents": {
- "markdownPreview":"/components/agent-ui/wd-markdown/index",
- "FoldedCard":"/components/agent-ui/collapse/index",
+ "markdownPreview": "/components/agent-ui/wd-markdown/index",
+ "FoldedCard": "/components/agent-ui/collapse/index",
"chatFile": "/components/agent-ui/chatFile/index",
- "feedback":"/components/agent-ui/feedback/index"
+ "feedback": "/components/agent-ui/feedback/index",
+ "customCard": "/components/agent-ui/customCard/index"
}
-}
\ No newline at end of file
+}
diff --git a/components/agent-ui/index.wxml b/components/agent-ui/index.wxml
index 69490df..dbb5521 100644
--- a/components/agent-ui/index.wxml
+++ b/components/agent-ui/index.wxml
@@ -55,7 +55,7 @@
-
+
@@ -141,6 +141,7 @@
+
diff --git a/package-lock.json b/package-lock.json
index 17e5c8a..e00cc8e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "cloudbase-agent-ui",
- "version": "1.9.1",
+ "version": "1.10.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cloudbase-agent-ui",
- "version": "1.9.1",
+ "version": "1.10.0",
"license": "MIT",
"dependencies": {
"standard-version": "^9.5.0"
diff --git a/package.json b/package.json
index 15a4de4..b522d2f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cloudbase-agent-ui",
- "version": "1.9.1",
+ "version": "1.10.0",
"description": "微信小程序 Agent UI组件",
"main": "index.js",
"directories": {