增加设备聊天记录接口,设备聊天内容推送到秋果数字空间app

This commit is contained in:
wulin 2023-09-27 16:23:02 +08:00
parent e9ac89e0da
commit 6e939eb801
34 changed files with 12254 additions and 42247 deletions

View File

@ -1,16 +1,15 @@
package com.qiuguo.iot.base.enums;
/*
* 问答枚举
* 动作类型
* 作者吴林
* */
// 0 大预言普通问答 1 天气 2 音乐 3 闹钟 4talk_answer_config配置回答
// 动作类型0文本播放 1音频播放 2 U3D动作 3物联网设备动作
public enum AskTypeEnum {
LANGUAGE_MODEL(0, "大语言模型"),
WEATHER(1, "天气"),
SOUND(2, "音乐"),
ALARM(3, "闹钟"),
SYS_CONFIG(4, "后台配置的"),
TTS(0, "文本大语言播放"),
SOUND(1, "音频播放"),
U3D(2, "U3D动作"),
DEVICE(3, "物联网设备动作")
;
AskTypeEnum(Integer c, String n){
code = c;
@ -18,6 +17,7 @@ public enum AskTypeEnum {
}
private Integer code;
private String name;
public Integer getCode() {
return code;
}

View File

@ -0,0 +1,24 @@
package com.qiuguo.iot.base.enums;
/*
* 设备编码
* 作者吴林
* */
// 0响铃一次time指定的时间 1每天 2指定星期
public enum DeviceCodeEnum {
BOX(0, "qgbox"),
;
DeviceCodeEnum(Integer c, String n){
code = c;
name = n;
}
private Integer code;
private String name;
public Integer getCode(){
return code;
}
public String getName(){
return name;
}
}

View File

@ -6,8 +6,14 @@ package com.qiuguo.iot.base.enums;
* */
// 0系统内置 1指定声音
public enum IsDeleteEnum {
NOT_DELETE,//未删除
DELETE,//删除
NOT_DELETE(0),//未删除
DELETE(1),//删除
;
IsDeleteEnum(Integer c){
code = c;
}
private Integer code;
public Integer getCode() {
return code;
}
}

View File

@ -0,0 +1,26 @@
package com.qiuguo.iot.base.enums;
/*
* 是否
* 作者吴林
* */
// 0 1
public enum OrderByEnum {
DESC(0, "0"),//升序
ASC(1, "1"),//降序
;
OrderByEnum(Integer c, String n){
code = c;
name = n;
}
private Integer code;
private String name;
public Integer getCode() {
return code;
}
public String getName(){
return name;
}
}

View File

@ -5,13 +5,11 @@ package com.qiuguo.iot.base.enums;
* 作者吴林
* */
// 动作类型0文本播放 1音频播放 2 U3D动作 3物联网设备动作
public enum ActionTypeEnum {
TTS(0, "文本播放"),
SOUND(1, "音频播放"),
U3D(2, "U3D动作"),
DEVICE(3, "物联网设备动作")
public enum RespCodeEnum {
SUCESS(200, "返回成功"),
FAILD(500, "异常"),
;
ActionTypeEnum(Integer c, String n){
RespCodeEnum(Integer c, String n){
code = c;
name = n;
}
@ -26,8 +24,8 @@ public enum ActionTypeEnum {
return name;
}
public static ActionTypeEnum getEnumWithCode(Integer c){
for (ActionTypeEnum e:values()
public static RespCodeEnum getEnumWithCode(Integer c){
for (RespCodeEnum e:values()
) {
if(e.getCode().compareTo(c) == 0){
return e;
@ -35,8 +33,8 @@ public enum ActionTypeEnum {
}
return null;
}
public static ActionTypeEnum getEnumWithName(String name){
for (ActionTypeEnum e:values()
public static RespCodeEnum getEnumWithName(String name){
for (RespCodeEnum e:values()
) {
if(e.getName().equals(name)){
return e;

View File

@ -6,8 +6,15 @@ package com.qiuguo.iot.base.enums;
* */
// 0 1
public enum YesNo {
NO,//未删除
YES,//删除
NO(0),//未删除
YES(1),//删除
;
YesNo(Integer c){
code = c;
}
private Integer code;
public Integer getCode() {
return code;
}
}

View File

@ -49,7 +49,7 @@ public class DeviceUserTalkRecordEntity extends GenericEntity<Long> {
@Column(name = "ask_value", length = 255, nullable = false)
private String askValue;
@Comment("问答类型 0 大预言普通问答 1 天气 2 音乐 3 闹钟 4talk_answer_config配置回答")
@Comment("回答类型0文本问答 1iOT控制 2天气 3闹钟 4U3D")
@Column(name = "ask_type", nullable = false)
private Integer askType;

View File

@ -0,0 +1,52 @@
package com.qiuguo.iot.data.resp.device;
import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.data.entity.device.DeviceUserTalkRecordEntity;
import lombok.Data;
import java.util.Date;
/**
* <p>
* </p>*设备信息对话记录返回类
* @author wulin
* @since 2023-09-27
*/
@Data
public class DeviceTalkRecordResp {
//
private Long id;
//当前用户当前设备问话一次标识考虑到可能有多个第三方回答
//创建时间
private Date createTime;
private Integer askNumber;
//用户id
private Long userId;
//设备id
private Long deviceId;
//问话内容
private String text;
//回答类型0文本问答 1iOT控制 2天气 3闹钟 4U3D
private Integer askType;
private Integer AskOrAnswer = 0;
public DeviceTalkRecordResp(){
}
public DeviceTalkRecordResp(DeviceUserTalkRecordEntity entity, Integer aa){
id = entity.getId();
createTime = entity.getCreateTime();
askNumber = entity.getAskNumber();
userId = entity.getUserId();
deviceId = entity.getDeviceId();
if(aa.equals(YesNo.YES.getCode())){
text = entity.getAskValue();
}else{
text = entity.getAnswerValue();
}
AskOrAnswer = aa;
askType = entity.getAskType();
}
}

View File

@ -1,5 +1,11 @@
package com.qiuguo.iot.data.resp.device;
import com.qiuguo.iot.data.entity.device.DeviceUserTalkRecordEntity;
import lombok.Data;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* <p>
* </p>*设备信息对话记录返回类
@ -12,6 +18,8 @@ public class DeviceUserTalkRecordResp {
//
private Long id;
//当前用户当前设备问话一次标识考虑到可能有多个第三方回答
//创建时间
private Date createTime;
private Integer askNumber;
//用户id
private Long userId;
@ -19,7 +27,7 @@ public class DeviceUserTalkRecordResp {
private Long deviceId;
//问话内容
private String askValue;
//问答类型 0 大预言普通问答 1 天气 2 音乐 3 闹钟 4talk_answer_config配置回答
//回答类型0文本问答 1iOT控制 2天气 3闹钟 4U3D
private Integer askType;
//问题关键字
private String askKey;
@ -31,4 +39,22 @@ public class DeviceUserTalkRecordResp {
private String answerThirdValue;
//是否返回给用户0 1
private Integer isReturn;
public DeviceUserTalkRecordResp(){
}
public DeviceUserTalkRecordResp(DeviceUserTalkRecordEntity entity){
id = entity.getId();
createTime = entity.getCreateTime();
askNumber = entity.getAskNumber();
userId = entity.getUserId();
deviceId = entity.getDeviceId();
askValue = entity.getAskValue();
askType = entity.getAskType();
askKey = entity.getAskKey();
answerValue = entity.getAnswerValue();
answerThirdId = entity.getAnswerThirdId();
answerThirdValue = entity.getAnswerThirdValue();
isReturn = entity.getIsReturn();
}
}

View File

@ -264,6 +264,17 @@ public class DeviceUserBindService extends GenericReactiveCrudService<DeviceUser
.execute();
}
/***
* 设置同类型设备为非主设备
* @param userId
* @param code
*/
public Mono<Integer> setNoMain(Long userId, Integer code) {
return createUpdate()
.set("is_main", 0)
.set("modify_time", new Date())
.where("user_id", userId).and("is_main", 1).and("is_delete", code)
.execute();
}
}

View File

@ -6,6 +6,7 @@ import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.data.entity.device.DeviceUserTalkRecordEntity;
import com.qiuguo.iot.data.request.device.DeviceUserTalkRecordRequest;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.ezorm.core.param.Sort;
import org.hswebframework.ezorm.rdb.mapping.ReactiveQuery;
import org.hswebframework.ezorm.rdb.mapping.ReactiveUpdate;
import org.hswebframework.ezorm.rdb.operator.dml.query.SortOrder;
@ -15,7 +16,10 @@ import org.hswebframework.web.crud.service.GenericReactiveCrudService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* <p>
* 设备信息对话记录服务类
@ -141,18 +145,26 @@ public class DeviceUserTalkRecordService extends GenericReactiveCrudService<Devi
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getIsReturn, request.getIsReturn());
}
SortOrder sortOrder = null;
QueryParamEntity param = QueryParamEntity.of(reactiveQuery.getParam());
if(StringUtils.isNotEmpty(request.getOrder())){
if(StringUtils.isNotEmpty(request.getSort()) && request.getSort().compareTo("0") == 0){
sortOrder = SortOrder.desc(request.getOrder());
}else{
sortOrder = SortOrder.asc(request.getOrder());
}
//sortOrder.setColumn(request.getOrder());
reactiveQuery = reactiveQuery.orderBy(sortOrder);
Sort sort = new Sort();
sort.setName(request.getOrder());
sort.desc();
param.setSorts(Arrays.asList(sort));
//List<Sort> sort = new Sort();
}
QueryParamEntity param = QueryParamEntity.of(reactiveQuery.getParam());
param.setPageIndex(request.getCurrPage());
param.setPageSize(request.getPageSize());
param.setPaging(true);
//param.setSorts();
param.setFirstPageIndex(1);
return queryPager(param);

View File

@ -273,6 +273,10 @@ public class SystemTalkAnswerConfigService extends GenericReactiveCrudService<Sy
public SystemTalkAnswerConfigEntity getSystemTalkWithKey(String key) {
return group.get(key);
if(group.containsKey(key)){
return group.get(key);
}
return null;
}
}

View File

@ -14,4 +14,9 @@ public class Action {
private String time;//具体时间
private List<String> lbs;//一些城市地狱名词
/***
* 原始记录话语
*/
private String ask;//原话
}

View File

@ -17,13 +17,14 @@ public class Actions {
public Actions() {}
public Actions(Nlp nlp){
public Actions(Nlp nlp, String ask){
actions = new ArrayList<>();
nlp.getKeys().sort(Comparator.comparing(NlpKey::getType)); //解析,按照type从小到大排序
Action action = new Action();
String name = "";
action.setName(new ArrayList<>());
action.setLbs(new ArrayList<>());
action.setAsk(ask);
for (NlpKey key : nlp.getKeys()
) {

View File

@ -16,7 +16,7 @@ public class NlpService {
public Mono<Actions> getActionWithLacSingle(String text){
return liguoNlpService.geSingletNlp(text).map(nlp -> {
return new Actions(nlp);
return new Actions(nlp, text);
});
}
}

View File

@ -5,14 +5,22 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.base.constans.RedisConstans;
import com.qiuguo.iot.base.enums.DeviceTypeEnum;
import com.qiuguo.iot.base.enums.OrderByEnum;
import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.data.entity.device.DeviceInfoEntity;
import com.qiuguo.iot.data.entity.device.DeviceUserTalkRecordEntity;
import com.qiuguo.iot.data.request.device.DeviceInfoRequest;
import com.qiuguo.iot.data.request.device.DeviceUserTalkRecordRequest;
import com.qiuguo.iot.data.resp.device.DeviceTalkRecordResp;
import com.qiuguo.iot.data.resp.device.DeviceUserTalkRecordResp;
import com.qiuguo.iot.data.service.device.DeviceBatchService;
import com.qiuguo.iot.data.service.device.DeviceInfoService;
import com.qiuguo.iot.data.service.device.DeviceUserTalkRecordService;
import com.qiuguo.iot.third.service.TuyaDeviceConnector;
import com.qiuguo.iot.user.api.resp.device.DeviceInitResp;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -24,6 +32,9 @@ import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@Slf4j
@ -45,6 +56,9 @@ public class DeviceController {
@Resource
private ReactiveStringRedisTemplate reactiveStringRedisTemplate;
@Resource
private DeviceUserTalkRecordService deviceUserTalkRecordService;
@Value("${device.timeout}")
private Long timeOut;//2分钟
@ -121,6 +135,33 @@ public class DeviceController {
}
@PostMapping("/talk/records")
public Mono<PagerResult<DeviceTalkRecordResp>> talkRecords(@RequestBody DeviceUserTalkRecordRequest request){
if(StringUtils.isNotEmpty(request.getOrder()) && StringUtils.isNotEmpty(request.getOrder())){
//默认按照时间倒叙排序
request.setOrder("create_time");
request.setOrder(OrderByEnum.DESC.getName());
}
return deviceUserTalkRecordService.selectDeviceUserTalkRecordsByRequest(request)
.map(deviceUserTalkRecordEntityPagerResult -> {
PagerResult<DeviceTalkRecordResp> pagerResult = new PagerResult<>();
pagerResult.setTotal(deviceUserTalkRecordEntityPagerResult.getTotal());
pagerResult.setPageSize(deviceUserTalkRecordEntityPagerResult.getPageSize());
pagerResult.setPageIndex(deviceUserTalkRecordEntityPagerResult.getPageIndex());
List<DeviceTalkRecordResp> list = new ArrayList<>();
for (DeviceUserTalkRecordEntity d :deviceUserTalkRecordEntityPagerResult.getData()
) {
list.add(new DeviceTalkRecordResp(d, YesNo.YES.getCode()));
list.add(new DeviceTalkRecordResp(d, YesNo.NO.getCode()));
}
pagerResult.setData(list);
return pagerResult;
});
}
@GetMapping("/deviceBySnId")
public Mono<JSONArray> aa(@RequestParam("sn") String sn){

View File

@ -1,5 +1,5 @@
server:
port: 8080
port: 8081
spring:
application:
name: qiuguo-iot-box-user-api

View File

@ -6,6 +6,7 @@ import com.qiuguo.iot.box.websocket.api.domain.box.resp.BoxMessageResp;
import com.qiuguo.iot.box.websocket.api.domain.user.UserSession;
import com.qiuguo.iot.box.websocket.api.handler.BoxWebSocketHandler;
import com.qiuguo.iot.box.websocket.api.handler.CustomerWebSocketHandler;
import com.qiuguo.iot.box.websocket.api.service.WebsocketService;
import com.qiuguo.iot.data.service.system.SystemTalkAnswerConfigService;
import com.qiuguo.iot.data.service.system.SystemTalkBindDeviceService;
import com.qiuguo.iot.third.nlp.Nlp;
@ -24,42 +25,18 @@ import reactor.core.publisher.Mono;
@RequestMapping("/websocket")
public class WebsocketController {
@Autowired
BoxWebSocketHandler boxWebSocketHandler;
@Autowired
CustomerWebSocketHandler customerWebSocketHandler;
WebsocketService websocketService;
@Autowired
LacNlpService lacNlpService;
@Autowired
SystemTalkAnswerConfigService systemTalkAnswerConfigService;
@GetMapping("/push/message")
public Mono<String> pushMessage(@RequestParam String message, @RequestParam String id, @RequestParam Integer type) {
if(type == 0){
//设备推送
BoxSession boxSession = boxWebSocketHandler.getBoxSessionWithSn(id);
if(boxSession != null){
BoxMessageResp resp = new BoxMessageResp();
resp.setType(0);
resp.setText(message);
boxSession.getSink().next(boxSession.getSession().textMessage(JSONObject.toJSONString(resp)));
return Mono.just("推送成功");
}
return Mono.just("设备未上线");
}else{
//用户推送
UserSession userSession = customerWebSocketHandler.getUserSessionWithUserId(Long.parseLong(id));
if(userSession != null){
BoxMessageResp resp = new BoxMessageResp();
resp.setType(0);
resp.setText(message);
userSession.getSink().next(userSession.getSession().textMessage(JSONObject.toJSONString(resp)));
return Mono.just("推送成功");
}
return Mono.just("用户未上线");
}
return websocketService.pushMessage(message, id, type);
}
@GetMapping("/init/sysTalkAnswer")

View File

@ -13,4 +13,12 @@ public class BaseSession {
protected String logId;//当前请求日志ID
protected String customerIP;//客户端IP
/***
* 用户id
*/
protected Long userId;
/***
* 当前使用的BoxId如果未绑定那么就是0
*/
protected Long deviceId = 0l;
}

View File

@ -8,5 +8,5 @@ import reactor.core.publisher.FluxSink;
@Data
public class UserSession extends BaseSession {
Long userId;
}

View File

@ -1,12 +1,16 @@
package com.qiuguo.iot.box.websocket.api.handler;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.base.enums.RespCodeEnum;
import com.qiuguo.iot.base.enums.WebSocketReqTypeEnum;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.box.websocket.api.domain.BaseSession;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxSession;
import com.qiuguo.iot.box.websocket.api.domain.box.resp.BoxMessageResp;
import com.qiuguo.iot.box.websocket.api.domain.user.UserSession;
import com.qiuguo.iot.box.websocket.api.service.WebsocketService;
import com.qiuguo.iot.data.entity.device.DeviceUserBindEntity;
import com.qiuguo.iot.data.entity.device.DeviceUserTalkRecordEntity;
import com.qiuguo.iot.data.entity.system.SystemTalkAnswerConfigEntity;
import com.qiuguo.iot.data.entity.system.SystemTalkBindDeviceEntity;
import com.qiuguo.iot.data.request.device.DeviceUserBindRequest;
@ -15,6 +19,7 @@ import com.qiuguo.iot.data.request.third.ThirdWeatherInfoRequest;
import com.qiuguo.iot.data.resp.third.weather.TianqiapiItemResp;
import com.qiuguo.iot.data.resp.third.weather.WeatherResp;
import com.qiuguo.iot.data.service.device.DeviceUserBindService;
import com.qiuguo.iot.data.service.device.DeviceUserTalkRecordService;
import com.qiuguo.iot.data.service.system.SystemAddressService;
import com.qiuguo.iot.data.service.system.SystemTalkAnswerConfigService;
import com.qiuguo.iot.data.service.system.SystemTalkBindDeviceService;
@ -31,6 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class BaseWebSocketProcess {
@ -53,6 +59,14 @@ public class BaseWebSocketProcess {
@Autowired
protected SystemAddressService systemAddressService;
@Autowired
protected DeviceUserTalkRecordService deviceUserTalkRecordService;
protected static ConcurrentHashMap<Long, UserSession> userGroup = new ConcurrentHashMap<>();
protected static ConcurrentHashMap<String, BoxSession> boxGroup = new ConcurrentHashMap<>();
protected void processAction(Actions actions, Long userId, BaseSession baseSession) {
//目前只处理第一条动作
Action action = actions.getActions().get(0);
@ -60,72 +74,78 @@ public class BaseWebSocketProcess {
SystemTalkAnswerConfigEntity talkAnswerConfigEntity =
systemTalkAnswerConfigService.getSystemTalkWithKey(action.getAction());
log.info("匹配到自定义指令{}", talkAnswerConfigEntity);
BoxMessageResp resp = new BoxMessageResp();
resp.setType(talkAnswerConfigEntity.getAnswerType());
if(talkAnswerConfigEntity.getAnswerType().equals(WebSocketReqTypeEnum.IOT.getCode())){
String deviceName = action.getName().get(0);
DeviceUserBindRequest deviceUserBindRequest = new DeviceUserBindRequest();
deviceUserBindRequest.setUserId(userId);
deviceUserBindRequest.setPageSize(2);
deviceUserBindRequest.setBindName(deviceName);
if(talkAnswerConfigEntity == null){
log.info("调用千问");
sendMessage(action, baseSession, 0, "这里会调用千问回答");
}
else if(talkAnswerConfigEntity.getAnswerType().equals(WebSocketReqTypeEnum.IOT.getCode())){
//查询是否有相关设备
deviceUserBindService.selectDeviceUserBindsByRequest(deviceUserBindRequest)
.defaultIfEmpty(new PagerResult<>(0, null))
.map(binds ->{
if(binds.getTotal() == 0){
//返回告诉没有备
if(action.getName().size() == 0){
String deviceName = action.getName().get(0);
DeviceUserBindRequest deviceUserBindRequest = new DeviceUserBindRequest();
deviceUserBindRequest.setUserId(userId);
deviceUserBindRequest.setPageSize(2);
deviceUserBindRequest.setBindName(deviceName);
resp.setText("未找到相关设备,无法操做!");
baseSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
}else if(binds.getTotal() > 1){
//返回告诉有多个设备请详细说明具体说明设备
resp.setText("您有多个相同设备,请明确说明");
baseSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
}else{
//查询是否有相关指令绑定
DeviceUserBindEntity deviceUserBindEntity = binds.getData().get(0);
SystemTalkBindDeviceRequest systemTalkBindDeviceRequest = new SystemTalkBindDeviceRequest();
systemTalkBindDeviceRequest.setCategoryCode(deviceUserBindEntity.getCategoryCode());
systemTalkBindDeviceRequest.setSystemTalkId(talkAnswerConfigEntity.getId());
systemTalkBindDeviceService.selectSystemTalkBindDeviceByRequest(systemTalkBindDeviceRequest)
.defaultIfEmpty(new SystemTalkBindDeviceEntity())
.map(systemTalkBindDeviceEntity -> {
if(systemTalkBindDeviceEntity.getId() == null){
//通知不支持的指令
resp.setText(deviceName + "不支持" + action.getAction() + "指令!");
baseSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
}else{
//调用涂鸦
TuyaQuery query = new TuyaQuery();
query.setDeviceId(deviceUserBindEntity.getOtherDeviceId());
query.setValue(action.getStatus());
query.setUserHandlingDeviceId(systemTalkBindDeviceEntity.getUserHandlingId());
tuyaDeviceService.controlDevice(query).map(isOk ->{
if(isOk){
//通知打开灯成功
String msg = talkAnswerConfigEntity.getAnswerValue().replaceAll("#name#", deviceName);
if(StringUtils.isNotEmpty(action.getStatus())){
msg.replace("#value#", action.getStatus());
//查询是否有相关设备
deviceUserBindService.selectDeviceUserBindsByRequest(deviceUserBindRequest)
.defaultIfEmpty(new PagerResult<>(0, null))
.map(binds ->{
if(binds.getTotal() == 0){
//返回告诉没有备
sendMessage(action, baseSession, talkAnswerConfigEntity.getAnswerType(), "未找到相关设备,无法操做!");
}else if(binds.getTotal() > 1){
//返回告诉有多个设备请详细说明具体说明设备
sendMessage(action, baseSession, talkAnswerConfigEntity.getAnswerType(), "您有多个相同设备,请明确说明");
}else{
//查询是否有相关指令绑定
DeviceUserBindEntity deviceUserBindEntity = binds.getData().get(0);
SystemTalkBindDeviceRequest systemTalkBindDeviceRequest = new SystemTalkBindDeviceRequest();
systemTalkBindDeviceRequest.setCategoryCode(deviceUserBindEntity.getCategoryCode());
systemTalkBindDeviceRequest.setSystemTalkId(talkAnswerConfigEntity.getId());
systemTalkBindDeviceService.selectSystemTalkBindDeviceByRequest(systemTalkBindDeviceRequest)
.defaultIfEmpty(new SystemTalkBindDeviceEntity())
.map(systemTalkBindDeviceEntity -> {
if(systemTalkBindDeviceEntity.getId() == null){
//通知不支持的指令
sendMessage(action, baseSession, talkAnswerConfigEntity.getAnswerType(), deviceName + "不支持" + action.getAction() + "指令!");
}else{
//调用涂鸦
TuyaQuery query = new TuyaQuery();
query.setDeviceId(deviceUserBindEntity.getOtherDeviceId());
query.setValue(action.getStatus());
query.setUserHandlingDeviceId(systemTalkBindDeviceEntity.getUserHandlingId());
tuyaDeviceService.controlDevice(query).map(isOk ->{
String msg = "";
if(isOk.getCode().equals(RespCodeEnum.SUCESS.getCode())){
//通知打开灯成功
msg = talkAnswerConfigEntity.getAnswerValue().replaceAll("#name#", deviceName);
if(StringUtils.isNotEmpty(action.getStatus())){
msg.replace("#value#", action.getStatus());
}
log.info("执行指令");
}else{
//通知开灯失败;
msg = talkAnswerConfigEntity.getAnswerValueFaild().replaceAll("#name#", deviceName);
log.info("执行指令失败");
}
resp.setText(msg);
sendMessage(action, baseSession, talkAnswerConfigEntity.getAnswerType(), msg);
log.info("执行指令");
}else{
//通知开灯失败;
resp.setText(talkAnswerConfigEntity.getAnswerValueFaild().replaceAll("#name#", deviceName));
log.info("执行指令失败");
}
baseSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
return isOk;
}).subscribe();
}
return systemTalkBindDeviceEntity;
}).subscribe();
return isOk;
}).subscribe();
}
return systemTalkBindDeviceEntity;
}).subscribe();
}
return Mono.empty();
}).subscribe();
}else{
sendMessage(action, baseSession, talkAnswerConfigEntity.getAnswerType(), "未找到对应的设备");
}
}
return Mono.empty();
}).subscribe();
}else if(talkAnswerConfigEntity.getAnswerType().equals(WebSocketReqTypeEnum.WEATHER.getCode())){
@ -142,23 +162,67 @@ public class BaseWebSocketProcess {
weatherService.tianqiApi(req).map(t ->{
log.info("查询的天气{}", JSONObject.toJSONString(t));
TianqiapiItemResp item = null;
if(StringUtils.isNotEmpty(action.getTime())){
//匹配对应的日期
}else{
item = t.getData().get(0);
}
String msg = "";
if(item != null){
//返回给客户端播报内容
resp.setText(t.getCity() + "天气" + item.getNarrative() + ",空气质量" + item.getAir_level()
+ ",湿度" + item.getHumidity() + ",最高气温" + item.getTem1() + ",最低气温" + item.getTem2());
msg = t.getCity() + "天气" + item.getNarrative() + ",空气质量" + item.getAir_level()
+ ",湿度" + item.getHumidity() + ",最低气温" + item.getTem2();
}else{
resp.setText(talkAnswerConfigEntity.getAnswerValueFaild());
msg = talkAnswerConfigEntity.getAnswerValueFaild();
log.info("执行指令失败");
}
baseSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
sendMessage(action, baseSession, talkAnswerConfigEntity.getAnswerType(), msg);
return t;
}).subscribe();
}
}
private void sendMessage(Action action, BaseSession baseSession, Integer type, String message){
BoxMessageResp resp = new BoxMessageResp();
resp.setType(type);
resp.setText(message);
DeviceUserTalkRecordEntity talkRecord = new DeviceUserTalkRecordEntity();
talkRecord.setAskType(type);
talkRecord.setAskValue(action.getAsk());
talkRecord.setAskKey(action.getAction());
talkRecord.setAnswerValue(message);
talkRecord.setUserId(baseSession.getUserId());
talkRecord.setDeviceId(baseSession.getDeviceId());
deviceUserTalkRecordService.insertDeviceUserTalkRecord(talkRecord).map(i ->{
baseSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
if(this instanceof BoxWebSocketHandler){
log.info("推送通知到客户端");
UserSession userSession = getUserSessionWithUserId(baseSession.getUserId());
if(userSession != null){
userSession.getSink().next(baseSession.getSession().textMessage(JSONObject.toJSONString(resp)));
}
}
return Mono.empty();
}).subscribe();//保存聊天记录
}
public BoxSession getBoxSessionWithSn(String sn) {
if(boxGroup.containsKey(sn)){
return boxGroup.get(sn);
}
return null;
}
public UserSession getUserSessionWithUserId(Long userId) {
if(userGroup.containsKey(userId)){
return userGroup.get(userId);
}
return null;
}
}

View File

@ -4,7 +4,10 @@ import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.base.annotation.WebSocketMapping;
import com.qiuguo.iot.base.constans.RedisConstans;
import com.qiuguo.iot.base.enums.DeviceCodeEnum;
import com.qiuguo.iot.base.enums.DeviceTypeEnum;
import com.qiuguo.iot.base.enums.WebSocketReqTypeEnum;
import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.base.utils.StringUtils;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxSession;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxTalkMessage;
@ -67,7 +70,7 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
public static ConcurrentHashMap<String, BoxSession> group = new ConcurrentHashMap<>();
@Override
public Mono<Void> handle(WebSocketSession session) {
@ -117,8 +120,9 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
boxSession.setSn(sn);
boxSession.setCustomerIP(ip);
boxSession.setSession(session);
boxSession.setUserId(userId);
boxSession.setLogId(MDC.get(LogMdcConfiguration.PRINT_LOG_ID));
group.put(sn, boxSession);
boxGroup.put(sn, boxSession);
Mono<Void> output = session.send(Flux.create(sink -> boxSession.setSink(sink))).then();
// Mono.zip() 会将多个 Mono 合并为一个新的 Mono任何一个 Mono 产生 error complete 都会导致合并后的 Mono
@ -126,7 +130,7 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
return Mono.zip(input, output).doFinally(signalType -> {
// MDC.put(LogMdcConfiguration.PRINT_LOG_ID, requestId);
group.remove(boxSession.getSn());//断链后及时移除
boxGroup.remove(boxSession.getSn());//断链后及时移除
log.info("设备断开连接SN{}", boxSession.getSn());
// MDC.remove(LogMdcConfiguration.PRINT_LOG_ID);
}).then();
@ -159,15 +163,21 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
String wifiMd5 = MD5.create().digestHex(dv.getWifiMac()).toUpperCase();
String btMd5 = MD5.create().digestHex(dv.getBtMac()).toUpperCase();
String signalMd5 = MD5.create().digestHex(snMd5 + wifiMd5 + btMd5 + linkTime + dv.getKey()).toUpperCase();
BoxSession boxSession = getBoxSessionWithSn(sn);
if(!signalMd5.equals(signature)){
log.info("设备{},验签失败", sn);
//session.send(session.textMessage(""));
BoxSession boxSession = getBoxSessionWithSn(sn);
if(boxSession != null){
boxSession.getSink().next(boxSession.getSession().textMessage("验签失败"));
boxSession.getSession().close().subscribe();
}
boxSession.getSession().close().subscribe();
}else{
log.info("设备{},验签成功", sn);
if(boxSession != null){
boxSession.setDeviceId(dv.getId());
}
bindBox(dv, userId);
}
return Mono.empty();
@ -187,18 +197,26 @@ public class BoxWebSocketHandler extends BaseWebSocketProcess implements WebSock
if(entity.getId() == null){
entity.setUserId(userId);
entity.setDeviceId(dv.getId());
return deviceUserBindService.insertDeviceUserBind(entity).map(l ->{
log.info("绑定成功SN{} userId:{}", dv, userId);
return entity;
//设置未主设备
entity.setIsMain(YesNo.YES.getCode());
entity.setCategoryCode(DeviceCodeEnum.BOX.getName());
deviceUserBindService.setNoMain(userId, DeviceTypeEnum.GUO_BOX.getCode()).defaultIfEmpty(0).map(m ->{
log.info("解除历史isMain标注个数{}", m);
deviceUserBindService.insertDeviceUserBind(entity).map(l ->{
log.info("绑定成功SN{} userId:{}", dv, userId);
//下面所有的以前未主设备改成非主设备
return Mono.empty();
}).subscribe();
return Mono.empty();
}).subscribe();
}
return entity;
return Mono.empty();
}).subscribe();
}
public BoxSession getBoxSessionWithSn(String sn) {
return group.get(sn);
}
}

View File

@ -3,12 +3,16 @@ package com.qiuguo.iot.box.websocket.api.handler;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.base.annotation.WebSocketMapping;
import com.qiuguo.iot.base.constans.RedisConstans;
import com.qiuguo.iot.base.enums.YesNo;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxSession;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxTalkMessage;
import com.qiuguo.iot.box.websocket.api.domain.user.UserSession;
import com.qiuguo.iot.box.websocket.api.domain.user.UserTalkMessage;
import com.qiuguo.iot.box.websocket.api.filter.LogMdcConfiguration;
import com.qiuguo.iot.box.websocket.api.filter.LogWebFilter;
import com.qiuguo.iot.data.entity.device.DeviceUserBindEntity;
import com.qiuguo.iot.data.request.device.DeviceUserBindRequest;
import com.qiuguo.iot.data.service.device.DeviceUserBindService;
import com.qiuguo.iot.third.nlp.action.Actions;
import com.qiuguo.iot.third.service.NlpService;
import lombok.extern.slf4j.Slf4j;
@ -37,7 +41,10 @@ public class CustomerWebSocketHandler extends BaseWebSocketProcess implements We
@Value("${device.timeout}")
private Long timeOut;//2分钟
public static ConcurrentHashMap<Long, UserSession> group = new ConcurrentHashMap<>();
@Resource
protected DeviceUserBindService deviceUserBindService;
@Resource
private ReactiveStringRedisTemplate reactiveStringRedisTemplate;
@ -49,7 +56,8 @@ public class CustomerWebSocketHandler extends BaseWebSocketProcess implements We
HandshakeInfo handshakeInfo = session.getHandshakeInfo();
HttpHeaders headers = handshakeInfo.getHeaders();
//List<String> tokens = headers.get("token");
String token = headers.get("token").get(0);
String type = headers.get("api-type").get(0);
String token = headers.get("api-token").get(0);
Long userId = Long.valueOf(headers.get("userId").get(0));
Long linkTime = Long.parseLong(headers.get("time").get(0));
if(checkTimeout && System.currentTimeMillis() - linkTime > timeOut){
@ -59,7 +67,7 @@ public class CustomerWebSocketHandler extends BaseWebSocketProcess implements We
}
String ip = headers.get(LogWebFilter.HEAD_IP).get(0);
ReactiveValueOperations<String, String> operations = reactiveStringRedisTemplate.opsForValue();
operations.get(RedisConstans.DEVICE_INFO + userId).defaultIfEmpty("ba2ef9fd8a70a6ac72c38aa6a46be4f6").flatMap(s -> {
operations.get(RedisConstans.DEVICE_INFO + userId).defaultIfEmpty("ec3299ec9dd4c45517639999aeb4bad7").flatMap(s -> {
if(com.qiuguo.iot.base.utils.StringUtils.isNotBlank(s)){
if(!token.equals(s)){
log.info("验签失败{}", userId);
@ -68,8 +76,27 @@ public class CustomerWebSocketHandler extends BaseWebSocketProcess implements We
userSession.getSink().next(session.textMessage("非法登录"));
}
session.close().subscribe();
}else{
//
log.info("验签成功{}", userId);
DeviceUserBindRequest request = new DeviceUserBindRequest();
request.setUserId(userId);
request.setIsMain(YesNo.YES.getCode());
deviceUserBindService.selectDeviceUserBindByRequest(request)
.defaultIfEmpty(new DeviceUserBindEntity())
.map(deviceUserBindEntity -> {
if(deviceUserBindEntity.getId() != null){
log.info("用户绑定信息为{}", deviceUserBindEntity);
UserSession userSession = getUserSessionWithUserId(userId);
if(userSession != null){
userSession.setDeviceId(deviceUserBindEntity.getDeviceId());
}
}
return Mono.empty();
}).subscribe();
}
}
return Mono.empty();
}).subscribe();
@ -100,7 +127,7 @@ public class CustomerWebSocketHandler extends BaseWebSocketProcess implements We
userSession.setSession(session);
userSession.setCustomerIP(ip);
userSession.setLogId(MDC.get(LogMdcConfiguration.PRINT_LOG_ID));
group.put(userId, userSession);
userGroup.put(userId, userSession);
Mono<Void> output = session.send(Flux.create(sink -> userSession.setSink(sink))).then();
// Mono.zip() 会将多个 Mono 合并为一个新的 Mono任何一个 Mono 产生 error complete 都会导致合并后的 Mono
@ -108,13 +135,11 @@ public class CustomerWebSocketHandler extends BaseWebSocketProcess implements We
return Mono.zip(input, output).doFinally(signalType -> {
// MDC.put(LogMdcConfiguration.PRINT_LOG_ID, requestId);
group.remove(userSession.getUserId());//断链后及时移除
userGroup.remove(userSession.getUserId());//断链后及时移除
log.info("用户断开连接SN{}", userSession.getUserId());
// MDC.remove(LogMdcConfiguration.PRINT_LOG_ID);
}).then();
}
public UserSession getUserSessionWithUserId(Long userId) {
return group.get(userId);
}
}

View File

@ -0,0 +1,57 @@
package com.qiuguo.iot.box.websocket.api.service;
import com.alibaba.fastjson.JSONObject;
import com.qiuguo.iot.box.websocket.api.domain.box.BoxSession;
import com.qiuguo.iot.box.websocket.api.domain.box.resp.BoxMessageResp;
import com.qiuguo.iot.box.websocket.api.domain.user.UserSession;
import com.qiuguo.iot.box.websocket.api.handler.BoxWebSocketHandler;
import com.qiuguo.iot.box.websocket.api.handler.CustomerWebSocketHandler;
import com.qiuguo.iot.data.service.system.SystemTalkAnswerConfigService;
import com.qiuguo.iot.third.nlp.Nlp;
import com.qiuguo.iot.third.service.LacNlpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@Service
@Slf4j
public class WebsocketService {
@Autowired
BoxWebSocketHandler boxWebSocketHandler;
@Autowired
CustomerWebSocketHandler customerWebSocketHandler;
public Mono<String> pushMessage(String message, String id, Integer type) {
if(type == 0){
//设备推送
BoxSession boxSession = boxWebSocketHandler.getBoxSessionWithSn(id);
if(boxSession != null){
BoxMessageResp resp = new BoxMessageResp();
resp.setType(0);
resp.setText(message);
boxSession.getSink().next(boxSession.getSession().textMessage(JSONObject.toJSONString(resp)));
return Mono.just("推送成功");
}
return Mono.just("设备未上线");
}else{
//用户推送
UserSession userSession = customerWebSocketHandler.getUserSessionWithUserId(Long.parseLong(id));
if(userSession != null){
BoxMessageResp resp = new BoxMessageResp();
resp.setType(0);
resp.setText(message);
userSession.getSink().next(userSession.getSession().textMessage(JSONObject.toJSONString(resp)));
return Mono.just("推送成功");
}
return Mono.just("用户未上线");
}
}
}

View File

@ -1,5 +1,5 @@
server:
port: 8081
port: 8080
spring:
application:
name: qiuguo-iot-box-websocket

View File

@ -82,7 +82,7 @@ public class MysqlMain {
}
List<TablesBean> list = new ArrayList<>();
list.add(new TablesBean("system_address"));
list.add(new TablesBean("device_user_talk_record"));
//list.add(new TablesBean("user_room"));
List<TablesBean> list2 = new ArrayList<TablesBean>();

View File

@ -0,0 +1,88 @@
package com.admin.service.impl;
import org.apache.commons.lang3.StringUtils;
import java.util.Date;
/**
* <p>
* 设备信息对话记录Controller类
* </p>
*
* @author wulin
* @since 2023-09-27
*/
@RestController
@Slf4j
@RequestMapping("/DeviceUserTalkRecord")
public class DeviceUserTalkRecordController{
@Autowired
private DeviceUserTalkRecordService deviceUserTalkRecordService;
@PostMapping("/info")
public Mono<DeviceUserTalkRecordResp> selectDeviceUserTalkRecordByRequest(@RequestBody DeviceUserTalkRecordRequest request){
return deviceUserTalkRecordService.selectDeviceUserTalkRecordByRequest(request).map(d -> {return new DeviceUserTalkRecordResp(d);});
}
@PostMapping("/list")
public Mono<PagerResult<DeviceUserTalkRecordResp>> selectDeviceUserTalkRecordsByRequest(@RequestBody DeviceUserTalkRecordRequest request){
return deviceUserTalkRecordService.selectDeviceInfosByRequest(request).map(d -> {
PagerResult<DeviceUserTalkRecordResp> result = new PagerResult<>();
result.setPageIndex(d.getPageIndex());
result.setPageSize(d.getPageSize());
result.setTotal(d.getTotal());
List<DeviceUserTalkRecordResp> ds = d.getData().stream().map(new Function<DeviceUserTalkRecordEntity, DeviceUserTalkRecordResp>() {
@Override
public DeviceInfoResp apply(DeviceUserTalkRecordEntity entity) {
return new DeviceUserTalkRecordResp(entity);
}
}
).collect(Collectors.toList());
result.setData(ds);
return result;
});
}
@GetMapping("/id")
public Mono<DeviceUserTalkRecordResp> selectDeviceUserTalkRecordById(@RequestParam Long id){
return deviceUserTalkRecordService.selectDeviceUserTalkRecordById(id).map(d -> {return new DeviceUserTalkRecordResp(d);});
}
@PostMapping("/save")
public Mono<Integer> insertDeviceUserTalkRecord(@RequestBody DeviceUserTalkRecordEntity entity){
return deviceUserTalkRecordService.insertDeviceUserTalkRecord(entity);
}
@PostMapping("/update")
public Mono<Integer> updateDeviceUserTalkRecordById(@RequestBody DeviceUserTalkRecordEntity entity){
return deviceUserTalkRecordService.updateDeviceUserTalkRecordById(entity);
}
@PostMapping("/updateCover")
public Mono<Integer> updateCoverDeviceUserTalkRecordById(@RequestBody DeviceUserTalkRecordEntity entity){
return deviceUserTalkRecordService.updateCoverDeviceUserTalkRecordById(entity);
}
@PostMapping("/delete")
public Mono<Integer> deleteDeviceUserTalkRecordById(@RequestParam Long id){
return deviceUserTalkRecordService.deleteDeviceUserTalkRecordById(id);
}
}

View File

@ -0,0 +1,76 @@
package com.qiuguo.iot.data.entity;
import org.hswebframework.ezorm.rdb.mapping.annotation.Comment;
import org.hswebframework.web.crud.annotation.EnableEntityEvent;
import org.hswebframework.web.api.crud.entity.GenericEntity;
import javax.persistence.Column;
import javax.persistence.Table;import lombok.Data;
import java.util.Date;
/**
* <p>
* </p>*设备信息对话记录表
* @author wulin
* @since 2023-09-27
*/
@Data
@Comment("设备信息对话记录表")
@Table(name = "device_user_talk_record")
@EnableEntityEvent
public class DeviceUserTalkRecordEntity extends GenericEntity<Long> {
@Comment("id")
@Column(name = "id", length = 11, nullable = false, unique = true)
private Long id;
@Comment("是否删除0 否 1 删除")
@Column(name = "is_delete", nullable = false)
private Integer isDelete;
@Comment("创建时间")
@Column(name = "create_time")
private Date createTime;
@Comment("修改时间")
@Column(name = "modify_time")
private Date modifyTime;
@Comment("当前用户当前设备问话一次标识(考虑到可能有多个第三方回答)")
@Column(name = "ask_number")
private Integer askNumber;
@Comment("用户id")
@Column(name = "user_id", nullable = false)
private Long userId;
@Comment("设备id")
@Column(name = "device_id", nullable = false)
private Long deviceId;
@Comment("问话内容")
@Column(name = "ask_value", length = 255, nullable = false)
private String askValue;
@Comment("回答类型0文本问答 1iOT控制 2天气 3闹钟 4U3D 和system_talk_answer_config中answer_type保持一致")
@Column(name = "ask_type", nullable = false)
private Integer askType;
@Comment("问题关键字")
@Column(name = "ask_key", length = 100)
private String askKey;
@Comment("回答内容传给box")
@Column(name = "answer_value", length = 255, nullable = false)
private String answerValue;
@Comment("回答第三方模型third_config_infoask_type=4时为talk_answer_config的id")
@Column(name = "answer_third_id", nullable = false)
private Long answerThirdId;
@Comment("第三方回答原始内容")
@Column(name = "answer_third_value", length = 255)
private String answerThirdValue;
@Comment("是否返回给用户0 否 1 是")
@Column(name = "is_return", nullable = false)
private Integer isReturn;
}

View File

@ -0,0 +1,59 @@
package com.qiuguo.iot.data.entity;
import lombok.Data;
import java.util.Date;
/**
* <p>
*设备信息对话记录请求类
* @author wulin
* @since 2023-09-27
*/
@Data
public class DeviceUserTalkRecordRequest implements java.io.Serializable {
private int currPage = 1;
private int pageSize = 10;
private String sort;
private String order;
//
private Long id;
//是否删除0 1 删除
private Integer isDelete;
//创建时间
private Date createTime;
//创建时间搜索开始
private Date createTimeStart;
//创建时间搜索结束
private Date createTimeEnd;
//修改时间
private Date modifyTime;
//修改时间搜索开始
private Date modifyTimeStart;
//修改时间搜索结束
private Date modifyTimeEnd;
//当前用户当前设备问话一次标识考虑到可能有多个第三方回答
private Integer askNumber;
//用户id
private Long userId;
//设备id
private Long deviceId;
//问话内容
private String askValue;
//回答类型0文本问答 1iOT控制 2天气 3闹钟 4U3D 和system_talk_answer_config中answer_type保持一致
private Integer askType;
//问题关键字
private String askKey;
//回答内容传给box
private String answerValue;
//回答第三方模型third_config_infoask_type=4时为talk_answer_config的id
private Long answerThirdId;
//第三方回答原始内容
private String answerThirdValue;
//是否返回给用户0 1
private Integer isReturn;
}

View File

@ -0,0 +1,57 @@
package com.qiuguo.iot.data.entity;
import lombok.Data;
import java.util.Date;
/**
* <p>
* </p>*设备信息对话记录返回类
* @author wulin
* @since 2023-09-27
*/
@Data
public class DeviceUserTalkRecordResp {
public DeviceUserTalkRecordResp(){
}
public DeviceUserTalkRecordResp(DeviceUserTalkRecordEntity entity){
id = entity.getId();
createTime = entity.getCreateTime();
modifyTime = entity.getModifyTime();
askNumber = entity.getAskNumber();
userId = entity.getUserId();
deviceId = entity.getDeviceId();
askValue = entity.getAskValue();
askType = entity.getAskType();
askKey = entity.getAskKey();
answerValue = entity.getAnswerValue();
answerThirdId = entity.getAnswerThirdId();
answerThirdValue = entity.getAnswerThirdValue();
isReturn = entity.getIsReturn();
}
//
private Long id;
//创建时间
private Date createTime;
//修改时间
private Date modifyTime;
//当前用户当前设备问话一次标识考虑到可能有多个第三方回答
private Integer askNumber;
//用户id
private Long userId;
//设备id
private Long deviceId;
//问话内容
private String askValue;
//回答类型0文本问答 1iOT控制 2天气 3闹钟 4U3D 和system_talk_answer_config中answer_type保持一致
private Integer askType;
//问题关键字
private String askKey;
//回答内容传给box
private String answerValue;
//回答第三方模型third_config_infoask_type=4时为talk_answer_config的id
private Long answerThirdId;
//第三方回答原始内容
private String answerThirdValue;
//是否返回给用户0 1
private Integer isReturn;
}

View File

@ -0,0 +1,238 @@
package com.admin.service.impl;
import org.apache.commons.lang3.StringUtils;
import java.util.Date;
/**
* <p>
* 设备信息对话记录服务类
* </p>
*
* @author wulin
* @since 2023-09-27
*/
@Service
@Slf4j
public class DeviceUserTalkRecordService extends GenericReactiveCrudService<DeviceUserTalkRecordEntity, Long> {
public Mono<DeviceUserTalkRecordEntity> selectDeviceUserTalkRecordByRequest(DeviceUserTalkRecordRequest request){
ReactiveQuery<DeviceUserTalkRecordEntity> reactiveQuery = createQuery();
reactiveQuery = reactiveQuery.and("is_delete", 0);
if(request.getId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getId, request.getId());
}
if(request.getIsDelete() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getIsDelete, request.getIsDelete());
}
if(request.getCreateTime() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getCreateTime, request.getCreateTime());
}
if(request.getModifyTime() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getModifyTime, request.getModifyTime());
}
if(request.getAskNumber() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAskNumber, request.getAskNumber());
}
if(request.getUserId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getUserId, request.getUserId());
}
if(request.getDeviceId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getDeviceId, request.getDeviceId());
}
if(StringUtils.isNotEmpty(request.getAskValue())){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAskValue, request.getAskValue());
}
if(request.getAskType() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAskType, request.getAskType());
}
if(StringUtils.isNotEmpty(request.getAskKey())){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAskKey, request.getAskKey());
}
if(StringUtils.isNotEmpty(request.getAnswerValue())){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAnswerValue, request.getAnswerValue());
}
if(request.getAnswerThirdId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAnswerThirdId, request.getAnswerThirdId());
}
if(StringUtils.isNotEmpty(request.getAnswerThirdValue())){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAnswerThirdValue, request.getAnswerThirdValue());
}
if(request.getIsReturn() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getIsReturn, request.getIsReturn());
}
SortOrder sortOrder = null;
if(StringUtils.isNotEmpty(request.getOrder())){
if(StringUtils.isNotEmpty(request.getSort()) && request.getSort().compareTo("0") == 0){
sortOrder = SortOrder.desc(request.getOrder());
}else{
sortOrder = SortOrder.asc(request.getOrder());
}
reactiveQuery = reactiveQuery.orderBy(sortOrder);
}
return reactiveQuery.fetchOne();
}
public Mono<PagerResult<DeviceUserTalkRecordEntity>> selectDeviceUserTalkRecordsByRequest(DeviceUserTalkRecordRequest request){
ReactiveQuery<DeviceUserTalkRecordEntity> reactiveQuery = createQuery();
reactiveQuery = reactiveQuery.and("is_delete", 0);
if(request.getId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getId, request.getId());
}
if(request.getIsDelete() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getIsDelete, request.getIsDelete());
}
if(request.getCreateTimeStart() != null){
reactiveQuery = reactiveQuery.gte(DeviceUserTalkRecordRequest::getCreateTime, request.getCreateTimeStart());
}
if(request.getCreateTimeEnd() != null){
reactiveQuery = reactiveQuery.lte(DeviceUserTalkRecordRequest::getCreateTime, request.getCreateTimeEnd());
}
if(request.getModifyTimeStart() != null){
reactiveQuery = reactiveQuery.gte(DeviceUserTalkRecordRequest::getModifyTime, request.getModifyTimeStart());
}
if(request.getModifyTimeEnd() != null){
reactiveQuery = reactiveQuery.lte(DeviceUserTalkRecordRequest::getModifyTime, request.getModifyTimeEnd());
}
if(request.getAskNumber() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAskNumber, request.getAskNumber());
}
if(request.getUserId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getUserId, request.getUserId());
}
if(request.getDeviceId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getDeviceId, request.getDeviceId());
}
if(StringUtils.isNotEmpty(request.getAskValue())){
reactiveQuery = reactiveQuery.$like$(DeviceUserTalkRecordRequest::getAskValue, request.getAskValue());
}
if(request.getAskType() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAskType, request.getAskType());
}
if(StringUtils.isNotEmpty(request.getAskKey())){
reactiveQuery = reactiveQuery.$like$(DeviceUserTalkRecordRequest::getAskKey, request.getAskKey());
}
if(StringUtils.isNotEmpty(request.getAnswerValue())){
reactiveQuery = reactiveQuery.$like$(DeviceUserTalkRecordRequest::getAnswerValue, request.getAnswerValue());
}
if(request.getAnswerThirdId() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getAnswerThirdId, request.getAnswerThirdId());
}
if(StringUtils.isNotEmpty(request.getAnswerThirdValue())){
reactiveQuery = reactiveQuery.$like$(DeviceUserTalkRecordRequest::getAnswerThirdValue, request.getAnswerThirdValue());
}
if(request.getIsReturn() != null){
reactiveQuery = reactiveQuery.and(DeviceUserTalkRecordRequest::getIsReturn, request.getIsReturn());
}
SortOrder sortOrder = null;
if(StringUtils.isNotEmpty(request.getOrder())){
if(StringUtils.isNotEmpty(request.getSort()) && request.getSort().compareTo("0") == 0){
sortOrder = SortOrder.desc(request.getOrder());
}else{
sortOrder = SortOrder.asc(request.getOrder());
}
reactiveQuery = reactiveQuery.orderBy(sortOrder);
}
QueryParamEntity param = QueryParamEntity.of(reactiveQuery.getParam());
param.setPageIndex(request.getCurrPage());
param.setPageSize(request.getPageSize());
param.setPaging(true);
param.setFirstPageIndex(1);
return queryPager(param);
}
public Mono<DeviceUserTalkRecordEntity> selectDeviceUserTalkRecordById(Long id){
return createQuery()
.and("is_delete", 0)
.and("id", id)
.fetchOne();
}
public Mono<Integer> insertDeviceUserTalkRecord(DeviceUserTalkRecordEntity entity){
entity.setId(null);
entity.setCreateTime(null);
entity.setModifyTime(null);
return insert(entity);
}
public Mono<Integer> updateDeviceUserTalkRecordById(DeviceUserTalkRecordEntity entity){
ReactiveUpdate<DeviceUserTalkRecordEntity> update = createUpdate()
.set(DeviceUserTalkRecordEntity::getModifyTime, new Date());
if(entity.getIsDelete() != null){
update = update.set(DeviceUserTalkRecordEntity::getIsDelete, entity.getIsDelete());
}
if(entity.getAskNumber() != null){
update = update.set(DeviceUserTalkRecordEntity::getAskNumber, entity.getAskNumber());
}
if(entity.getUserId() != null){
update = update.set(DeviceUserTalkRecordEntity::getUserId, entity.getUserId());
}
if(entity.getDeviceId() != null){
update = update.set(DeviceUserTalkRecordEntity::getDeviceId, entity.getDeviceId());
}
if(StringUtils.isNotEmpty(entity.getAskValue())){
update = update.set(DeviceUserTalkRecordEntity::getAskValue, entity.getAskValue());
}
if(entity.getAskType() != null){
update = update.set(DeviceUserTalkRecordEntity::getAskType, entity.getAskType());
}
if(StringUtils.isNotEmpty(entity.getAskKey())){
update = update.set(DeviceUserTalkRecordEntity::getAskKey, entity.getAskKey());
}
if(StringUtils.isNotEmpty(entity.getAnswerValue())){
update = update.set(DeviceUserTalkRecordEntity::getAnswerValue, entity.getAnswerValue());
}
if(entity.getAnswerThirdId() != null){
update = update.set(DeviceUserTalkRecordEntity::getAnswerThirdId, entity.getAnswerThirdId());
}
if(StringUtils.isNotEmpty(entity.getAnswerThirdValue())){
update = update.set(DeviceUserTalkRecordEntity::getAnswerThirdValue, entity.getAnswerThirdValue());
}
if(entity.getIsReturn() != null){
update = update.set(DeviceUserTalkRecordEntity::getIsReturn, entity.getIsReturn());
}
return update.where(DeviceUserTalkRecordEntity::getId, entity.getId()).and("is_delete", 0).execute();
}
public Mono<Integer> updateCoverDeviceUserTalkRecordById(DeviceUserTalkRecordEntity entity){
ReactiveUpdate<DeviceUserTalkRecordEntity> update = createUpdate()
.set(DeviceUserTalkRecordEntity::getModifyTime, new Date());
update = update.set(DeviceUserTalkRecordEntity::getIsDelete, entity.getIsDelete());
update = update.set(DeviceUserTalkRecordEntity::getAskNumber, entity.getAskNumber());
update = update.set(DeviceUserTalkRecordEntity::getUserId, entity.getUserId());
update = update.set(DeviceUserTalkRecordEntity::getDeviceId, entity.getDeviceId());
update = update.set(DeviceUserTalkRecordEntity::getAskValue, entity.getAskValue());
update = update.set(DeviceUserTalkRecordEntity::getAskType, entity.getAskType());
update = update.set(DeviceUserTalkRecordEntity::getAskKey, entity.getAskKey());
update = update.set(DeviceUserTalkRecordEntity::getAnswerValue, entity.getAnswerValue());
update = update.set(DeviceUserTalkRecordEntity::getAnswerThirdId, entity.getAnswerThirdId());
update = update.set(DeviceUserTalkRecordEntity::getAnswerThirdValue, entity.getAnswerThirdValue());
update = update.set(DeviceUserTalkRecordEntity::getIsReturn, entity.getIsReturn());
return update.where(DeviceUserTalkRecordEntity::getId, entity.getId()).and("is_delete", 0).execute();
}
public Mono<Integer> deleteDeviceUserTalkRecordById(Long id){
return createUpdate()
.set("is_delete", 1)
.set("modify_time", new Date())
.where("id", id)
.execute();
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long