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智能体服务 ![](https://qcloudimg.tencent-cloud.cn/raw/97786aaaa15aa1f23e9bbd39a7a6762f.png) - 方式二:接入大模型 ![](https://qcloudimg.tencent-cloud.cn/raw/876d2238b5331a7bdcbd91a1b38b8248.png) -### 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 + +![](https://qcloudimg.tencent-cloud.cn/raw/bc2a7815b542b26f5931aa835514dc37.png) + +- 若未开通过云托管服务,需先开通云托管 + +![](https://qcloudimg.tencent-cloud.cn/raw/084b50f265e0335201801c3fb741d04d.png) + +#### 2. 配置 MCP Server + +- 以腾讯地图 MCP Server 举例,选择模板进行安装(按照指引获取腾讯地图平台API KEY后,配置环境变量) + +![](https://qcloudimg.tencent-cloud.cn/raw/a5b15af9bfff83008257a0c99d252b83.png) + +#### 3. agent 绑定 MCP Server tools + +- 在 agent 配置页点击添加MCP 服务,选择对应的MCP Server tools 使用 (此处腾讯地图示例可勾选 geocoder,placeSearchNearby, directionDriving, weather等工具) + +![](https://qcloudimg.tencent-cloud.cn/raw/b45a95e06ec0df8dab5c9d9ec7707faa.png) + + +#### 4. 开发自定义卡片组件 + +- 参照本工程中 apps/miniprogram-agent-ui/miniprogram/components/toolCard 目录内自定义工具卡片组件实现 + +![](https://qcloudimg.tencent-cloud.cn/raw/14a4a82810f0b45bde0c124cc8f3ed1c.png) + +#### 5. 卡片组件引用配置 + +- 自定义卡片组件引用声明配置(可在用户小程序项目全局app.json中配置 或 agent-ui组件index.json中配置) + +![](https://qcloudimg.tencent-cloud.cn/raw/cd1dc376a1e238f3186a2209e5875698.png) + +- agent-ui 组件内 customCard/index.wxml 中添加自定义组件 + +![](https://qcloudimg.tencent-cloud.cn/raw/b4cd35ccaa3e72189934ed59d35f7ae5.png) + +#### 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.name}} + + {{item.rating}} 分 + {{item.reviews}} 评论 + + + + + + {{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 @@ + + + + + + + {{isDay ? today.dayweather : today.nightweather}} + + + {{city}} {{isDay ? today.daytemp : today.nighttemp}}{{currentUnit}} + 最高:{{today.daytemp}}° 最低:{{today.nighttemp}}° + + + + + {{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}} + + + + + + 适用门店 + 40家门店适用 + + + + + + + + + + + + {{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": {