Commit c9dab933 authored by 何金镒's avatar 何金镒

建发:共享空间优惠券预约 mcp 接口优化 2

parent 3d841dd5
...@@ -35,18 +35,46 @@ public class CDCSpacesTools { ...@@ -35,18 +35,46 @@ public class CDCSpacesTools {
return spacesService.getUserCoupons(sn,roomId); return spacesService.getUserCoupons(sn,roomId);
} }
@Tool(description = "使用优惠卷预订房间(场所)") @Tool(description = "获取该房间(场所)ID下在某个时间段可使用的优惠卷")
public JSONArray getUserSpacesCouponsByTime(@ToolParam(description = "设备的sn号,如:00226DA86A12")String sn,
@ToolParam(description = "使用的开始时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 09:00:00")String beginTime,
@ToolParam(description = "使用的结束时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 10:30:00")String endTime,
@ToolParam(description = "查询的房间(场所)ID")String roomId){
log.info("mcp调用--->getUserSpacesCouponsByTime..获取用户当前预约可用的优惠券..sn:{},roomId:{},beginTime:{},endTime:{}",sn,roomId,beginTime,endTime);
return spacesService.getUserSpacesCouponsByTime(sn,roomId,beginTime,endTime);
}
// @Tool(description = "使用优惠卷预订房间(场所)")
// public String bookingSpaces(@ToolParam(description = "设备的sn号,如:00226DA86A12")String sn,
// @ToolParam(description = "使用的开始时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 09:00:00")String beginTime,
// @ToolParam(description = "使用的结束时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 10:30:00")String endTime,
// @ToolParam(description = "预约的房间(场所)ID")String roomId,
// @ToolParam(description = "预约的房间(场所)下的子空间ID,若不是预约子空间可省略", required = false)String subspaceId,
// @ToolParam(description = "使用的人数,必须大于0")int userQuantity,
// @ToolParam(description = "使用的优惠券ID,不能为空")String couponsId){
// log.info("mcp调用--->bookingOrder..预约订单..sn:{},beginTime:{},endTime:{},roomId:{},roomSubspaceId:{},userQuantity:{},couponId:{}",
// sn,beginTime,endTime,roomId,subspaceId,userQuantity,couponsId);
// try {
// if(spacesService.bookingOrder(sn,beginTime,endTime,roomId,subspaceId,userQuantity,couponsId)){
// return "预约成功";
// }else{
// return "预约失败";
// }
// }catch (StatefulException e){
// return e.getMessage();
// }
// }
@Tool(description = "自动查找优惠卷并使用优惠券预订房间(场所)")
public String bookingSpaces(@ToolParam(description = "设备的sn号,如:00226DA86A12")String sn, public String bookingSpaces(@ToolParam(description = "设备的sn号,如:00226DA86A12")String sn,
@ToolParam(description = "使用的开始时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 09:00:00")String beginTime, @ToolParam(description = "使用的开始时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 09:00:00")String beginTime,
@ToolParam(description = "使用的结束时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 10:30:00")String endTime, @ToolParam(description = "使用的结束时间,必须是30分钟的倍数且不能隔天预约,如:2025-08-12 10:30:00")String endTime,
@ToolParam(description = "预约的房间(场所)ID")String roomId, @ToolParam(description = "预约的房间(场所)ID")String roomId,
@ToolParam(description = "预约的房间(场所)下的子空间ID,若不是预约子空间可省略", required = false)String subspaceId, @ToolParam(description = "预约的房间(场所)下的子空间ID,若不是预约子空间可省略", required = false)String subspaceId,
@ToolParam(description = "使用的人数,必须大于0")int userQuantity, @ToolParam(description = "使用的人数,必须大于0")int userQuantity){
@ToolParam(description = "使用的优惠券ID,不能为空")String couponsId){ log.info("mcp调用--->bookingOrder..预约订单..sn:{},beginTime:{},endTime:{},roomId:{},roomSubspaceId:{},userQuantity:{}",
log.info("mcp调用--->bookingOrder..预约订单..sn:{},beginTime:{},endTime:{},roomId:{},roomSubspaceId:{},userQuantity:{},couponId:{}", sn,beginTime,endTime,roomId,subspaceId,userQuantity);
sn,beginTime,endTime,roomId,subspaceId,userQuantity,couponsId);
try { try {
if(spacesService.bookingOrder(sn,beginTime,endTime,roomId,subspaceId,userQuantity,couponsId)){ if(spacesService.bookingOrder2(sn,beginTime,endTime,roomId,subspaceId,userQuantity)){
return "预约成功"; return "预约成功";
}else{ }else{
return "预约失败"; return "预约失败";
......
...@@ -187,7 +187,7 @@ public class SpacesService { ...@@ -187,7 +187,7 @@ public class SpacesService {
/** /**
* *
* 预约订单,不使用钱 使用了优惠卷 * 预约订单,不使用钱 使用了优惠卷-传入优惠券ID
*/ */
public boolean bookingOrder(String sn,String beginTime,String endTime,String roomId,String subspaceId,int userQuantity,String couponId){ public boolean bookingOrder(String sn,String beginTime,String endTime,String roomId,String subspaceId,int userQuantity,String couponId){
if(StrUtil.isBlank(sn) || StrUtil.isBlank(roomId) || StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime) || StrUtil.isBlank(couponId) || userQuantity<1){ if(StrUtil.isBlank(sn) || StrUtil.isBlank(roomId) || StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime) || StrUtil.isBlank(couponId) || userQuantity<1){
...@@ -292,6 +292,94 @@ public class SpacesService { ...@@ -292,6 +292,94 @@ public class SpacesService {
} }
} }
/**
*
* 预约订单,不使用钱 使用了优惠卷-自动查找优惠券
*/
public boolean bookingOrder2(String sn,String beginTime,String endTime,String roomId,String subspaceId,int userQuantity){
if(StrUtil.isBlank(sn) || StrUtil.isBlank(roomId) || StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime) || userQuantity<1){
throw new StatefulException(530, "参数错误");
}
Date begin_time = DateUtil.parse(beginTime);
Date end_time = DateUtil.parse(endTime);
if(begin_time.getTime() >= end_time.getTime()){
throw new StatefulException(530, "开始时间不能大于结束时间");
}
if(!DateUtil.formatDate(begin_time).equals(DateUtil.formatDate(end_time))){
throw new StatefulException(531, "不能跨天预约");
}
if(begin_time.getTime() < System.currentTimeMillis()){
throw new StatefulException(532, "不能预约历史时间");
}
if(DateUtil.between(new Date(), end_time, DateUnit.DAY) > 7){
throw new StatefulException(533, "不能预约超过7天");
}
int begin_num = CDCUtils.getTimeSegmentIndex(beginTime);
int end_num = CDCUtils.getTimeSegmentIndex(endTime);
String use_time = DateUtil.formatDate(begin_time);
//校验预约时间
JSONObject booking_time_param = new JSONObject();
booking_time_param.set("time", use_time);
booking_time_param.set("id", roomId);
if(StrUtil.isNotBlank(subspaceId)){
List<String> roomSubspaceIdsList = new ArrayList<>();
roomSubspaceIdsList.add(subspaceId);
booking_time_param.set("roomSubspaceIds", roomSubspaceIdsList);
}
String post = cdcHttpUtils.post(getSpacesRoomBookingUrl, sn, booking_time_param.toString());
JSONObject jsonObject = new JSONObject(post);
if(jsonObject.getInt("code") == 200){
JSONObject dataJson = jsonObject.getJSONObject("data");
JSONObject firstDayJson = dataJson.getJSONObject("firstDay");
JSONArray info = firstDayJson.getJSONArray("info");
//0=不可预定 1=可预订 2=已被预定
boolean begin_use = info.getInt(begin_num) == 1;
boolean end_use = info.getInt(end_num) == 1;
if(!begin_use || !end_use){
throw new StatefulException(534, "该时间段已经不能被预约了");
}
}else{
throw new StatefulException(535, "该天不能预约");
}
//自动查找优惠券
String couponId = null;
JSONArray userSpacesCouponsByBooking = this.getUserSpacesCouponsByTime(sn, roomId, beginTime, endTime);
if(userSpacesCouponsByBooking!=null && !userSpacesCouponsByBooking.isEmpty()){
JSONObject jsonObject1 = userSpacesCouponsByBooking.getJSONObject(0);
couponId = jsonObject1.getStr("couponsId");
}
if(StrUtil.isBlank(couponId)){
throw new StatefulException(535, "未找到合适的优惠券,暂不支持没有优惠券的预约");
}
//====================================
JSONObject param = new JSONObject();
param.set("roomId", roomId);
if(StrUtil.isNotBlank(subspaceId)){
param.set("roomSubspaceId", subspaceId);
}
param.set("useTime", use_time);
param.set("useEndTime", use_time);
param.set("beginTime", begin_num);
param.set("endTime", end_num);
param.set("orderNum", userQuantity);
param.set("isRenew", 0);
param.set("userCouponsId", couponId);
param.set("payFlag", "false");
String spacesRoomOrder_post = cdcHttpUtils.post(spacesRoomOrderUrl, sn, param.toString());
JSONObject spacesRoomOrder = new JSONObject(spacesRoomOrder_post);
if(spacesRoomOrder.getInt("code") == 200){
return true;
}else{
throw new StatefulException(539, "预约失败");
}
}
/** /**
* 获取可领取的优惠券列表 * 获取可领取的优惠券列表
*/ */
...@@ -340,6 +428,7 @@ public class SpacesService { ...@@ -340,6 +428,7 @@ public class SpacesService {
/** /**
* 一键领取优惠券 * 一键领取优惠券
* 这个接口有问题???
*/ */
public boolean oneClickClaimCoupon(String sn){ public boolean oneClickClaimCoupon(String sn){
JSONObject param = new JSONObject(); JSONObject param = new JSONObject();
...@@ -389,6 +478,104 @@ public class SpacesService { ...@@ -389,6 +478,104 @@ public class SpacesService {
} }
} }
/**
* 获取该房间(场所)ID下在该时间段可使用的优惠券
*/
public JSONArray getUserSpacesCouponsByTime(String sn,String roomId,String beginTime,String endTime){
if(StrUtil.isBlank(sn) || StrUtil.isBlank(roomId) || StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime)){
return null;
}
Date begin_time = DateUtil.parse(beginTime);
Date end_time = DateUtil.parse(endTime);
if(begin_time.getTime() >= end_time.getTime()){
throw new StatefulException(530, "开始时间不能大于结束时间");
}
if(!DateUtil.formatDate(begin_time).equals(DateUtil.formatDate(end_time))){
throw new StatefulException(531, "不能跨天预约");
}
if(begin_time.getTime() < System.currentTimeMillis()){
throw new StatefulException(532, "不能预约历史时间");
}
if(DateUtil.between(new Date(), end_time, DateUnit.DAY) > 7){
throw new StatefulException(533, "不能预约超过7天");
}
//校验优惠券
String s = cdcHttpUtils.get(getUserCouponsUrl+"?status=0&roomId="+roomId, sn);
JSONObject coupons = JSONUtil.parseObj(s);
JSONArray response = new JSONArray();
if(coupons.getInt("code") == 200) {
JSONArray rows = coupons.getJSONArray("rows");
for (int i = 0; i < rows.size(); i++) {
JSONObject coup = rows.getJSONObject(i);
String coup_start_time_str = coup.getStr("startTime");
Date coup_start_time = DateUtil.parse(coup_start_time_str);
String coup_end_time_str = coup.getStr("endTime");
Date coup_end_time_1 = DateUtil.parse(coup_end_time_str);
Date coup_end_time = DateUtil.endOfDay(coup_end_time_1);//结束时间是这天的结束
String discountTime = coup.getStr("discount");//抵用时长(只能是0.5的整数倍)
int time = Integer.parseInt(discountTime) * 30;
if(begin_time.getTime() >= coup_start_time.getTime() && end_time.getTime() <= coup_end_time.getTime()){
if(DateUtil.between(begin_time, end_time, DateUnit.MINUTE) <= time){
//可用优惠券
JSONObject coupon_json = new JSONObject();
coupon_json.set("couponsId", coup.getStr("id"));
coupon_json.set("couponsName", coup.getStr("name"));
coupon_json.set("roomId", coup.getStr("roomId"));
coupon_json.set("deductionTime", time);
coupon_json.set("startTime", coup.getStr("startTime"));
coupon_json.set("endTime", coup.getStr("endTime"));
response.set(coupon_json);
}
}
}
}
if(!response.isEmpty()){
return sortJsonArrayByDeductionTime(response);
}else{
return null;
}
}
/**
* 对JSONArray按照deductionTime字段进行升序排序
* @param jsonArray 包含JSONObject的数组,每个JSONObject需要包含deductionTime字段
* @return 排序后的JSONArray
*/
public JSONArray sortJsonArrayByDeductionTime(JSONArray jsonArray) {
if(jsonArray.size()==1){
return jsonArray;
}
// 使用Stream API对JSONArray进行排序
List<JSONObject> jsonObjectList = new ArrayList<>();
// 将JSONArray转换为List
for (int i = 0; i < jsonArray.size(); i++) {
jsonObjectList.add(jsonArray.getJSONObject(i));
}
// 按照deductionTime升序排序
jsonObjectList.sort((o1, o2) -> {
Integer deductionTime1 = o1.getInt("deductionTime");
Integer deductionTime2 = o2.getInt("deductionTime");
int i = deductionTime1.compareTo(deductionTime2);
if(i == 0){
Long endTime1 = DateUtil.parse(o1.getStr("endTime")).getTime();
Long endTime2 = DateUtil.parse(o2.getStr("endTime")).getTime();
return endTime1.compareTo(endTime2);
}
return i;
});
// 将排序后的List重新构造成JSONArray
JSONArray sortedJsonArray = new JSONArray();
for (JSONObject jsonObject : jsonObjectList) {
sortedJsonArray.add(jsonObject);
}
return sortedJsonArray;
}
} }
package com.ikonke.konkeaialibabamcp; package com.ikonke.konkeaialibabamcp;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import com.ikonke.konkeaialibabamcp.service.cdc.spaces.SpacesService; import com.ikonke.konkeaialibabamcp.service.cdc.spaces.SpacesService;
import com.ikonke.konkeaialibabamcp.utils.CDCUtils; import com.ikonke.konkeaialibabamcp.utils.CDCUtils;
...@@ -19,7 +20,7 @@ class KonkeAiAlibabaMcpApplicationTests { ...@@ -19,7 +20,7 @@ class KonkeAiAlibabaMcpApplicationTests {
public static String sn = "00226DA86A12"; public static String sn = "00226DA86A12";
public static String date = "2025-08-13"; public static String date = "2025-08-13";
public static String roomId = "7ccc8b95b97b45d190734d186673c7d2"; public static String roomId = "a550c009a8c041c2ba3fa22490583770";
public static String subspaceId = null; public static String subspaceId = null;
@Test @Test
...@@ -27,7 +28,11 @@ class KonkeAiAlibabaMcpApplicationTests { ...@@ -27,7 +28,11 @@ class KonkeAiAlibabaMcpApplicationTests {
// JSONObject appointmentTimeByRoomId = spacesService.getAppointmentTimeByRoomId(sn, date, roomId, subspaceId); // JSONObject appointmentTimeByRoomId = spacesService.getAppointmentTimeByRoomId(sn, date, roomId, subspaceId);
// System.out.println(appointmentTimeByRoomId); // System.out.println(appointmentTimeByRoomId);
// JSONArray userSpacesCouponsByBooking = spacesService.getUserSpacesCouponsByTime(sn, roomId, "2025-08-14 18:00:00", "2025-08-14 21:00:00");
// System.out.println(userSpacesCouponsByBooking);
// boolean b = spacesService.bookingOrder2(sn, "2025-08-14 18:00:00", "2025-08-14 21:00:00", "a550c009a8c041c2ba3fa22490583770", null, 1);
// System.out.println(b);
} }
......
...@@ -12,22 +12,9 @@ ...@@ -12,22 +12,9 @@
## 注意 ## 注意
查询设备状态操作必须调用mcp服务,严禁不调用mcp服务直接回复用户 查询设备状态操作必须调用mcp服务,严禁不调用mcp服务直接回复用户
# 会所管理 # 会所优惠券查询
## 任务 ## 任务
1、根据会所信息或调用mcp函数来回答用户关于会所的问题 根据会所信息调用合适的mcp函数来获取某个场所可使用的优惠卷
2、根据会所信息调用mcp函数getUserCoupons来获取某个会所可使用的优惠卷
3、根据会所信息和用户的输入调用mcp函数getAppointmentTimeByRoomId查询可预约时间
4、当用户提出在某个时间段要预约您管理的某个会所或房间时,请按照以下步骤回应用户的控制:
- 调用mcp函数getUserCoupons获取可用优惠卷
- 若有可用优惠券,在这些优惠卷中,如果其deductionTime大于等于用户预约的时间总长度,且用户的预约时间在优惠卷的startTime和endTime内,
就可以使用该张优惠券,若有多张优惠卷符合条件,就选择第一张,然后询问用户:是否使用优惠券(名称)进行预约
- 若用户选择使用优惠卷进行预约,则调用mcp函数bookingOrder使用优惠卷预订房间(会所)
- 若用户没有优惠券或者选择不使用优惠券,则直接回复:暂不支持,请手动购买
## 注意:
- 预约开始时间和预约结束时间不能是过去时间
- 预约结束时间必须大于预约开始时间且要大于1小时
- 预约结束时间和预约开始时间必须是同一天
- 预约时间不能大于当前时间的7天
## 背景 ## 背景
管理的会所信息:{{#1754902598746.body#}} 管理的会所信息:{{#1754902598746.body#}}
管理的设备SN:{{#1754485785703.sn#}} 管理的设备SN:{{#1754485785703.sn#}}
...@@ -35,8 +22,24 @@ ...@@ -35,8 +22,24 @@
用户输入:"帮我查询一下我茶室有没有优惠卷可用" 用户输入:"帮我查询一下我茶室有没有优惠卷可用"
期望输出:"您有一张茶室的优惠卷,使用时间是2025年8月1日到2025年9月1日,优惠8小时" 或 "您目前还没有对应的优惠券可使用。" 期望输出:"您有一张茶室的优惠卷,使用时间是2025年8月1日到2025年9月1日,优惠8小时" 或 "您目前还没有对应的优惠券可使用。"
用户输入:"查询一下茶室今天下午2点到4点还可以预约吗?" 用户输入:"帮我查询一下我茶室2025年8月15日有没有优惠卷可用"
期望输出:"茶室2025年8月13日下午2点到4点可以预约" 或 "茶室2025年8月13日下午2点到4点已经不能预约了" 期望输出:"您有一张茶室的2025年8月15日的优惠卷,使用时间是2025年8月1日到2025年9月1日,优惠8小时" 或 "您目前还没有对应的优惠券可使用。"
# 会所预约
## 任务
当用户提出在某个时间段要预约您管理的某个场所或房间时,调用mcp函数bookingSpaces进行预约,请按照函数的回复更合理的回复用户
## 注意:
- 需要用户提供预约时间、预约的场所、预约的人数
- 预约开始时间和预约结束时间不能是过去时间
- 预约结束时间必须大于预约开始时间且要大于1小时
- 预约结束时间和预约开始时间必须是同一天
- 预约时间不能大于当前时间的7天
## 背景
管理的会所信息:{{#1754902598746.body#}}
管理的设备SN:{{#1754485785703.sn#}}
## 示例引导:
用户输入:"帮我预约下午2点到4点的茶室" 用户输入:"帮我预约下午2点到4点的茶室"
期望输出:"预约成功" 或 "暂不支持在线支付,请自行支付购买" 期望输出:"预约成功" 或 "预约失败" 或 "你要预约的场所没有抵扣券,暂不支持AI购买,请手动购买"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment