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

建发:共享空间优惠券

parent aa750d05
......@@ -12,9 +12,11 @@
通过智慧屏/APP/小程序的AI语音交互,可实现会所空间的快捷预约管理,提高会所利用率与运维效率,提升业主满意度
1、查 小区功能区列表(/third/screen/spaces/rooms)
2、查询可预约时间
2、预约付钱订单---->成功或失败
3、成功--->生产支付二维码-->支付
4、支付成功后---->提交订单(新)/third/screen/spaces/order/submit
3、预约必须一个小时起,不能隔天
3、预约订单,如果有优惠卷可抵消预约的时间,直接使用/third/screen/spaces/order/submit
4、优惠卷和金钱必须二选一,若价格为0,也必须使用优惠券
5、如果价格不为0,需要支付,先使用/third/mini/record-->支付二维码--->再使用/third/screen/spaces/order/submit
5、
- 机器人联动
通过智慧屏/APP/小程序的AI语音交互,可实现配送机器人/收垃圾机器人快捷预约上门服务,实现更加便捷下单,并支持语音对话。
- 社区活动推荐
......
package com.ikonke.konkeaialibabamcp;
import com.ikonke.konkeaialibabamcp.aitools.CDCSpacesTools;
import com.ikonke.konkeaialibabamcp.aitools.DeviceTools;
import com.ikonke.konkeaialibabamcp.aitools.WeatherTools;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
......@@ -17,8 +19,10 @@ public class KonkeAiAlibabaMcpApplication {
}
@Bean
public ToolCallbackProvider tools(DeviceTools deviceTools) {
return MethodToolCallbackProvider.builder().toolObjects(deviceTools).build();
public ToolCallbackProvider tools(DeviceTools deviceTools, WeatherTools weatherTools, CDCSpacesTools cdcSpacesTools) {
return MethodToolCallbackProvider.builder()
.toolObjects(deviceTools, weatherTools, cdcSpacesTools)
.build();
}
}
package com.ikonke.konkeaialibabamcp.aitools;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.ikonke.konkeaialibabamcp.service.cdc.spaces.SpacesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class CDCSpacesTools {
private final SpacesService spacesService;
public CDCSpacesTools(SpacesService spacesService) {
this.spacesService = spacesService;
}
@Tool(description = "根据房间ID和日期查询该日期可预约情况")
public JSONObject getAppointmentTimeByRoomId(@ToolParam(description = "设备的sn号,如:00226DA86A12")String sn,
@ToolParam(description = "查询的日志,如:2025-08-12")String date,
@ToolParam(description = "查询的房间ID")String roomId,
@ToolParam(description = "查询的房间的子空间ID,可省略")String subspaceId){
log.info("getAppointmentTimeByRoomId..获取预约时间..sn:{},time:{},roomId:{},roomSubspaceId:{}",sn,date,roomId,subspaceId);
return spacesService.getAppointmentTimeByRoomId(sn,date,roomId,subspaceId);
}
@Tool(description = "获取该房间ID下可使用的优惠卷")
public JSONArray getUserCoupons(@ToolParam(description = "设备的sn号,如:00226DA86A12")String sn,
@ToolParam(description = "查询的房间ID")String roomId){
log.info("getUserCoupons..获取用户优惠券..sn:{},roomId:{}",sn,roomId);
return spacesService.getUserCoupons(sn,roomId);
}
@Tool(description = "使用优惠卷预订房间")
public boolean bookingOrder(@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")String subspaceId,
@ToolParam(description = "使用的人数,必须大于1")int userQuantity,
@ToolParam(description = "使用的优惠券ID,不能为空")String couponId){
log.info("bookingOrder..预约订单..sn:{},beginTime:{},endTime:{},roomId:{},roomSubspaceId:{},userQuantity:{},couponId:{}",
sn,beginTime,endTime,roomId,subspaceId,userQuantity,couponId);
return spacesService.bookingOrder(sn,beginTime,endTime,roomId,subspaceId,userQuantity,couponId);
}
}
......@@ -6,7 +6,6 @@ import com.ikonke.konkeaialibabamcp.service.SycDeviceService;
import com.ikonke.konkeaialibabamcp.service.mongdbservice.DeviceStatusService;
import com.ikonke.konkeaialibabamcp.utils.CcuUtils;
import com.ikonke.konkeaialibabamcp.utils.KonkeIotUtils;
import com.ikonke.konkeaialibabamcp.utils.WeatherUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
......@@ -19,12 +18,11 @@ public class DeviceTools {
private final DeviceStatusService deviceStatusUtil;
private final KonkeIotUtils konkeIotServer;
private final SycDeviceService sycDeviceService;
private final WeatherUtils weatherUtils;
public DeviceTools(DeviceStatusService deviceStatusUtil, KonkeIotUtils konkeIotServer, SycDeviceService sycDeviceService, WeatherUtils weatherUtils){
public DeviceTools(DeviceStatusService deviceStatusUtil, KonkeIotUtils konkeIotServer, SycDeviceService sycDeviceService){
this.deviceStatusUtil = deviceStatusUtil;
this.konkeIotServer = konkeIotServer;
this.sycDeviceService = sycDeviceService;
this.weatherUtils = weatherUtils;
}
@Tool(description = "根据主机号和设备ID查询设备状态信息.")
......@@ -58,20 +56,6 @@ public class DeviceTools {
@Tool(description = "根据城市名查询当前的天气")
public String getWeatherNow(@ToolParam(description = "城市,如:成都、西安")String city){
log.info("根据城市名查询当前的天气....city:{}",city);
return weatherUtils.getWeatherNow(city);
}
@Tool(description = "根据城市名查询未来24小时的天气")
public String getWeatherHourly(@ToolParam(description = "城市,如:成都、西安")String city){
log.info("根据城市名查询未来24小时的天气...city:{}",city);
return weatherUtils.getWeatherHourly(city);
}
@Tool(description = "根据城市名查询未来7天的天气")
public String getWeatherDaily(@ToolParam(description = "城市,如:成都、西安")String city){
log.info("根据城市名查询未来7天的天气....city:{}",city);
return weatherUtils.getWeatherDaily(city);
}
}
package com.ikonke.konkeaialibabamcp.aitools;
import com.ikonke.konkeaialibabamcp.utils.WeatherUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class WeatherTools {
private final WeatherUtils weatherUtils;
public WeatherTools(WeatherUtils weatherUtils) {
this.weatherUtils = weatherUtils;
}
@Tool(description = "根据城市名查询当前的天气")
public String getWeatherNow(@ToolParam(description = "城市,如:成都、西安")String city){
log.info("根据城市名查询当前的天气....city:{}",city);
return weatherUtils.getWeatherNow(city);
}
@Tool(description = "根据城市名查询未来24小时的天气")
public String getWeatherHourly(@ToolParam(description = "城市,如:成都、西安")String city){
log.info("根据城市名查询未来24小时的天气...city:{}",city);
return weatherUtils.getWeatherHourly(city);
}
@Tool(description = "根据城市名查询未来7天的天气")
public String getWeatherDaily(@ToolParam(description = "城市,如:成都、西安")String city){
log.info("根据城市名查询未来7天的天气....city:{}",city);
return weatherUtils.getWeatherDaily(city);
}
}
......@@ -2,10 +2,12 @@ package com.ikonke.konkeaialibabamcp.controller;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.ikonke.konkeaialibabamcp.entity.mysql.CDCToken;
import com.ikonke.konkeaialibabamcp.service.cdc.CdcHttpUtils;
import com.ikonke.konkeaialibabamcp.service.cdc.spaces.SpacesService;
import com.ikonke.konkeaialibabamcp.service.mysqlservice.ICDCTokenService;
import com.ikonke.konkeaialibabamcp.utils.CcuUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -36,18 +38,24 @@ public class CDCController {
bySn.setSn(sn);
bySn.setAccessToken(token);
bySn.setState(CDCToken.STATE_ENABLED);
bySn.setCcuId(ccuName);
bySn.setCcuId(CcuUtils.getCcuName(ccuName));
bySn.setCreateTime(LocalDateTime.now());
tokenService.save(bySn);
}else{
CdcHttpUtils.CDCTokenCache.remove(sn);
if(bySn.getAccessToken().equals(token)
&& bySn.getSn().equals(sn)
&& bySn.getCcuId().equals(CcuUtils.getCcuName(ccuName))){
return true;
}else{
CdcHttpUtils.CDCTokenCache.remove(sn);
bySn.setAccessToken(token);
bySn.setRefreshToken(bySn.getAccessToken());
bySn.setState(CDCToken.STATE_ENABLED);
bySn.setCreateTime(LocalDateTime.now());
bySn.setCcuId(ccuName);
tokenService.updateById(bySn);
bySn.setAccessToken(token);
bySn.setRefreshToken(bySn.getAccessToken());
bySn.setState(CDCToken.STATE_ENABLED);
bySn.setCreateTime(LocalDateTime.now());
bySn.setCcuId(CcuUtils.getCcuName(ccuName));
tokenService.updateById(bySn);
}
}
return true;
}
......@@ -55,7 +63,22 @@ public class CDCController {
@GetMapping("/getSpacesList")
public JSONArray getSpacesList(@RequestParam(name = "sn") String sn){
log.info("getSpacesList..获取空间列表..sn:{}",sn);
return spacesService.findAll(sn);
JSONArray all = spacesService.findAll(sn);
if(!all.isEmpty()){
return all;
}else{
return null;
}
}
@GetMapping("/getAppointmentTimeByRoomId")
public JSONObject getAppointmentTimeByRoomId(@RequestParam(name = "sn")String sn,
@RequestParam(name = "time")String time,
@RequestParam(name = "roomId")String roomId,
@RequestParam(name = "roomSubspaceId",required = false)String roomSubspaceId){
log.info("getAppointmentTimeByRoomId..获取预约时间..sn:{},time:{},roomId:{},roomSubspaceId:{}",sn,time,roomId,roomSubspaceId);
return spacesService.getAppointmentTimeByRoomId(sn,time,roomId,roomSubspaceId);
}
}
package com.ikonke.konkeaialibabamcp.utils;
public class CDCUtils {
public static String[] time_segment = {"00:00-00:30","00:30-01:00","01:00-01:30","01:30-02:00","02:00-02:30","02:30-03:00","03:00-03:30","03:30-04:00","04:00-04:30","04:30-05:00",
"05:00-05:30","05:30-06:00","06:00-06:30","06:30-07:00","07:00-07:30","07:30-08:00","08:00-08:30","08:30-09:00","09:00-09:30","09:30-10:00","10:00-10:30","10:30-11:00",
"11:00-11:30","11:30-12:00","12:00-12:30","12:30-13:00","13:00-13:30","13:30-14:00","14:00-14:30","14:30-15:00","15:00-15:30","15:30-16:00","16:00-16:30","16:30-17:00",
"17:00-17:30","17:30-18:00","18:00-18:30","18:30-19:00","19:00-19:30","19:30-20:00","20:00-20:30","20:30-21:00","21:00-21:30","21:30-22:00","22:00-22:30","22:30-23:00",
"23:00-23:30","23:30-24:00"};//前面包含,后面不包含
/**
* 根据输入的时间(时分秒)找到在 time_segment 数组中的下标
*
* @param time 输入的时间,格式为 "HH:mm:ss",例如 "13:11:00"
* @return 对应的 time_segment 数组下标
*/
public static int getTimeSegmentIndex(String time) {
// 提取小时和分钟部分
String[] parts = time.split(":");
int hour = Integer.parseInt(parts[0]);
int minute = Integer.parseInt(parts[1]);
// 计算从00:00开始的分钟数
int totalMinutes = hour * 60 + minute;
// 每个时间段是30分钟,计算所属时间段的索引
int index = totalMinutes / 30;
// 确保索引在有效范围内
if (index >= 0 && index < time_segment.length) {
return index;
}
// 如果超出范围,返回 -1 表示未找到
return -1;
}
}
......@@ -17,8 +17,6 @@ spring:
name: konke-ai-alibaba-mcp-server
version: 0.0.1
type: ASYNC # Recommended for reactive applications
# ?? sse ????????? /sse
# ???????? ip:port/sse/mcp
sse-endpoint: /sse
sse-message-endpoint: /mcp
capabilities:
......@@ -46,3 +44,10 @@ cdc:
getListSpacesRoomUrl: ${cdc.url}/third/screen/spaces/rooms
getSpacesRoomDetailUrl: ${cdc.url}/third/screen/spaces/room/
getSpacesRoomBookingUrl: ${cdc.url}/third/screen/spaces/room/times
bookingSpacesRoomUrl: ${cdc.url}/third/mini/record
spacesRoomOrderUrl: ${cdc.url}/third/screen/spaces/order/submit
spacesCoupons:
getSpacesCouponsListUrl: ${cdc.url}/third/screen/spaces/coupons/all
receiveSpacesCouponsUrl: ${cdc.url}/third/screen/spaces/coupons/
getUserCouponsUrl: ${cdc.url}/third/screen/spaces/coupons/user
oneClickClaimCouponUrl: ${cdc.url}/third/screen/spaces/coupons/once
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