Merge branch 'V0.5.x' of https://gitee.com/open-iita/iotkit-parent into V0.5.x

* 'V0.5.x' of https://gitee.com/open-iita/iotkit-parent:
  fix:物模型枚举类型修改为字符串类型
  feat:添加物模型日志按设备集合查询接口
  feat:应用端添加相关接口
  feat:app接口添加规则相关接口
  fix:优化应用接口移除设备
  fix:添加应用端设置属性接口,设备vo添加位置属性

# Conflicts:
#	iot-dao/iot-temporal-service/src/main/java/cc/iotkit/temporal/IThingModelMessageData.java
#	iot-dao/iot-temporal-serviceImpl-iotdb/src/main/java/cc/iotkit/temporal/iotdb/service/ThingModelMessageDataImpl.java
V0.5.x
gaoyoulong 2024-04-10 15:48:32 +08:00
commit 8368eb0822
13 changed files with 265 additions and 77 deletions

View File

@ -998,59 +998,65 @@
}
},
"name": "温度",
"accessMode": "rw"
"accessMode": "rw",
"description": "温度",
"unit": "℃"
},
{
"identifier": "swing_modes",
"dataType": {
"type": "bool",
"type": "enum",
"specs": {
"0": "关",
"1": "开"
"off": "关",
"on": "开"
}
},
"name": "扫风开关",
"accessMode": "rw"
"accessMode": "rw",
"description": "扫风开关"
},
{
"identifier": "modes",
"dataType": {
"type": "enum",
"specs": {
"0": "制热",
"1": "关闭",
"2": "制冷",
"3": "送风"
"heat": "制热",
"off": "关闭",
"cool": "制冷",
"fan_only": "送风"
}
},
"name": "模式",
"accessMode": "rw"
"accessMode": "rw",
"description": "模式"
},
{
"identifier": "fan_modes",
"dataType": {
"type": "enum",
"specs": {
"0": "高",
"1": "中",
"2": "低"
"high": "高",
"medium": "中",
"low": "低"
}
},
"name": "风模式",
"accessMode": "rw"
"accessMode": "rw",
"description": "风模式"
},
{
"identifier": "presets_modes",
"identifier": "preset_modes",
"dataType": {
"type": "enum",
"specs": {
"0": "节能",
"1": "睡眠",
"2": "活动"
"eco": "节能",
"sleep": "睡眠",
"activity": "活动"
}
},
"name": "预设模式",
"accessMode": "rw"
"accessMode": "rw",
"description": "预设模式"
}
],
"services": [

View File

@ -4,7 +4,6 @@ import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.common.utils.StreamUtils;
import cc.iotkit.data.dao.*;
import cc.iotkit.data.manager.ICategoryData;
import cc.iotkit.data.manager.IDeviceInfoData;
@ -17,10 +16,7 @@ import cc.iotkit.model.device.message.DevicePropertyCache;
import cc.iotkit.model.product.Category;
import cc.iotkit.model.product.Product;
import cc.iotkit.model.stats.DataItem;
import cc.iotkit.model.system.SysDept;
import cc.iotkit.model.system.SysUser;
import cn.hutool.core.util.ObjectUtil;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
@ -41,8 +37,6 @@ import static cc.iotkit.data.model.QTbDeviceGroupMapping.tbDeviceGroupMapping;
import static cc.iotkit.data.model.QTbDeviceInfo.tbDeviceInfo;
import static cc.iotkit.data.model.QTbDeviceSubUser.tbDeviceSubUser;
import static cc.iotkit.data.model.QTbProduct.tbProduct;
import static cc.iotkit.data.model.QTbSysDept.tbSysDept;
import static cc.iotkit.data.model.QTbSysUser.tbSysUser;
@Primary
@Service
@ -485,8 +479,10 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData<DeviceI
}
private List<DeviceInfo> buildQuery(Predicate predicate) {
List<TbDeviceInfo> devices = jpaQueryFactory.select(Projections.bean(TbDeviceInfo.class,
tbDeviceInfo.deviceId, tbDeviceInfo.deviceName, tbDeviceInfo.state ))
List<TbDeviceInfo> devices = jpaQueryFactory.select(Projections.bean(TbDeviceInfo.class,tbDeviceInfo.uid,
tbDeviceInfo.deviceId, tbDeviceInfo.productKey,tbDeviceInfo.deviceName, tbDeviceInfo.state,tbDeviceInfo.createAt,
tbDeviceInfo.id,tbDeviceInfo.onlineTime,tbDeviceInfo.parentId,tbDeviceInfo.latitude,tbDeviceInfo.longitude,tbDeviceInfo.model,
tbDeviceInfo.offlineTime,tbDeviceInfo.secret))
.from(tbDeviceInfo)
.where(predicate).fetch();
return MapstructUtils.convert(devices, DeviceInfo.class);
@ -495,7 +491,8 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData<DeviceI
private Predicate buildQueryCondition(DeviceInfo device) {
return PredicateBuilder.instance()
.and(ObjectUtil.isNotNull(device.getId()), () -> tbDeviceInfo.id.eq(device.getId()))
.and(ObjectUtil.isNotNull(device.getState().isOnline()), () -> tbDeviceInfo.state.eq(device.getState().isOnline() ? "online" : "offline"))
.and(ObjectUtil.isNotNull(device.getDeviceName()), () -> tbDeviceInfo.deviceName.eq(device.getDeviceName()))
.and(ObjectUtil.isNotNull(device.getState()), () -> tbDeviceInfo.state.eq(device.getState().isOnline() ? "online" : "offline"))
.build();
}

View File

@ -38,7 +38,6 @@ public interface IThingModelMessageData {
*/
List<TimeData> getDeviceMessageStatsWithUid(String uid, long start, long end);
/**
*
* @param uid id
@ -56,6 +55,17 @@ public interface IThingModelMessageData {
List<TimeData> getDeviceDownMessageStatsWithUid(String uid, Long start, Long end);
/**
*
*
* @param deviceIds ids
* @param type
* @param identifier
* @param page
* @param size
*/
Paging<ThingModelMessage> findByTypeAndDeviceIds(List<String> deviceIds, String type,
String identifier, int page, int size);
void add(ThingModelMessage msg);

View File

@ -69,6 +69,27 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
.collect(Collectors.toList()));
}
@Override
public Paging<ThingModelMessage> findByTypeAndDeviceIds(List<String> deviceIds, String type,
String identifier,
int page, int size) {
BoolQueryBuilder builder = QueryBuilders.boolQuery();
builder.must(QueryBuilders.termQuery("type", type));
if (deviceIds.size()>0) {
builder.must(QueryBuilders.termsQuery("deviceId", deviceIds));
}
if (StringUtils.isNotBlank(identifier)) {
builder.must(QueryBuilders.matchPhraseQuery("identifier", identifier));
}
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(builder)
.withPageable(PageRequest.of(page - 1, size, Sort.by(Sort.Order.desc("time"))))
.build();
SearchHits<DocThingModelMessage> result = template.search(query, DocThingModelMessage.class);
return new Paging<>(result.getTotalHits(), result.getSearchHits().stream()
.map(m -> MapstructUtils.convert(m.getContent(), ThingModelMessage.class))
.collect(Collectors.toList()));
}
@Override
public List<TimeData> getDeviceMessageStatsWithUid(String uid, long start, long end) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()

View File

@ -43,6 +43,11 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
return null;
}
@Override
public Paging<ThingModelMessage> findByTypeAndDeviceIds(List<String> deviceIds, String type, String identifier, int page, int size) {
return new Paging<>();
}
@Override
public void add(ThingModelMessage msg) {
}

View File

@ -73,6 +73,46 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
.collect(Collectors.toList()));
}
@Override
public Paging<ThingModelMessage> findByTypeAndDeviceIds(List<String> deviceIds, String type,
String identifier,
int page, int size) {
String sql = "select time,mid,product_key,device_name,type,identifier,code,data,report_time " +
"from thing_model_message where type=? %s order by time desc limit %d offset %d";
//构建动态条件
List<Object> args = new ArrayList<>();
args.add(type);
StringBuilder sbCond = new StringBuilder();
if (deviceIds.size()>0) {
sbCond.append(" and deviceIds in (?) ");
args.add(String.join(",",deviceIds));
}
if (StringUtils.isNotBlank(identifier)) {
sbCond.append("and identifier=? ");
args.add(identifier);
}
sql = String.format(sql, sbCond.toString(), size, (page - 1) * size);
List<TbThingModelMessage> ruleLogs = tdTemplate.query(sql,
new BeanPropertyRowMapper<>(TbThingModelMessage.class),
args.toArray()
);
sql = String.format("select count(*) from thing_model_message where type=? %s",
sbCond.toString());
List<Long> counts = tdTemplate.queryForList(sql, Long.class, args.toArray());
long count = !counts.isEmpty() ? counts.get(0) : 0;
return new Paging<>(count, ruleLogs.stream().map(r ->
new ThingModelMessage(r.getTime().toString(), r.getMid(),
r.getDeviceId(), r.getProductKey(), r.getDeviceName(),
r.getUid(), r.getType(), r.getIdentifier(), r.getCode(),
JsonUtils.parseObject(r.getData(), Map.class),
r.getTime(), r.getReportTime()))
.collect(Collectors.toList()));
}
@Override
public List<TimeData> getDeviceMessageStatsWithUid(String uid, long start, long end) {
String sql = "select time,count(*) as data from(" +

View File

@ -9,21 +9,30 @@
*/
package cc.iotkit.manager.controller;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.api.Request;
import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.common.satoken.utils.LoginHelper;
import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.data.manager.ICategoryData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.data.manager.IUserInfoData;
import cc.iotkit.manager.dto.bo.device.DeviceLogQueryBo;
import cc.iotkit.manager.dto.bo.device.ServiceInvokeBo;
import cc.iotkit.manager.dto.bo.device.SetDeviceServicePorpertyBo;
import cc.iotkit.manager.dto.bo.ruleinfo.RuleInfoBo;
import cc.iotkit.manager.dto.vo.product.ProductVo;
import cc.iotkit.manager.dto.vo.ruleinfo.RuleInfoVo;
import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo;
import cc.iotkit.manager.model.vo.FindDeviceVo;
import cc.iotkit.manager.model.vo.SpaceDeviceVo;
import cc.iotkit.manager.service.*;
import cc.iotkit.model.InvokeResult;
import cc.iotkit.model.UserInfo;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.product.Category;
@ -67,9 +76,14 @@ public class SpaceDeviceController {
@Autowired
private DataOwnerService dataOwnerService;
@Autowired
private IRuleEngineService ruleEngineService;
@Autowired
private IUserInfoData userInfoData;
@Autowired
private IDeviceManagerService deviceServiceImpl;
//赋予应用端设备的服务和属性设置,关于应用的接口及相关权限设计后续完善,先打通链路
@Autowired
private DeviceCtrlService deviceCtrlService;
/**
* 使
@ -81,6 +95,15 @@ public class SpaceDeviceController {
return null;
}
@ApiOperation("设备日志")
@PostMapping("/deviceLogs")
public Paging<ThingModelMessage> logs(@Validated @RequestBody PageRequest<DeviceLogQueryBo> request) {
Home home = homeService.findByUserIdAndCurrent(LoginHelper.getUserId(), true);
List<SpaceDevice> spaceDevices = spaceDeviceService.findByHomeId(home.getId());
List<String> devIds=spaceDevices.stream().map((spaceDevice->spaceDevice.getDeviceId())).collect(Collectors.toList());
return spaceDeviceService.findByTypeAndDeviceIds(devIds,request.getData().getType(),"",request.getPageNum(),request.getPageSize());
}
/**
*
*/
@ -91,6 +114,8 @@ public class SpaceDeviceController {
return spaceDevices.stream().map((this::parseSpaceDevice)).collect(Collectors.toList());
}
/**
* /
*/
@ -140,6 +165,7 @@ public class SpaceDeviceController {
.deviceId(sd.getDeviceId())
.deviceName(device.getDeviceName())
.name(sd.getName())
.createTime(sd.getCreateTime())
.spaceId(sd.getSpaceId())
.spaceName(space.getName())
.productKey(device.getProductKey())
@ -180,6 +206,7 @@ public class SpaceDeviceController {
List<FindDeviceVo> findDeviceVos = new ArrayList<>();
DeviceInfo query=new DeviceInfo();
query.setDeviceName(mac);
query.setState(null);
List<DeviceInfo> devices = deviceInfoData.findAllByCondition(query);
if(devices == null){
return findDeviceVos;
@ -223,6 +250,51 @@ public class SpaceDeviceController {
return deviceServiceImpl.getDetail(request.getData());
}
@ApiOperation("保存规则")
@PostMapping("/saveRuleEngine")
public boolean saveRuleEngine(@RequestBody @Validated Request<RuleInfoBo> ruleInfoBo) {
return ruleEngineService.saveRule(ruleInfoBo.getData());
}
@ApiOperation("删除规则")
@PostMapping("/delRuleEngine")
public boolean delRuleEngine(@Validated @RequestBody Request<String> request) {
String ruleId = request.getData();
return ruleEngineService.deleteRule(ruleId);
}
@ApiOperation("停止规则")
@PostMapping("/stopRuleEngine")
public boolean stopRuleEngine(@Validated @RequestBody Request<String> request) {
String ruleId = request.getData();
return ruleEngineService.pauseRule(ruleId);
}
@ApiOperation("恢复规则")
@PostMapping("/startRuleEngine")
public boolean startRuleEngine(@Validated @RequestBody Request<String> request) {
String ruleId = request.getData();
return ruleEngineService.resumeRule(ruleId);
}
@ApiOperation("规则列表")
@PostMapping("/ruleEngineList")
public Paging<RuleInfoVo> ruleEngineList(@Validated @RequestBody PageRequest<RuleInfoBo> request) {
return ruleEngineService.selectPageList(request);
}
@ApiOperation("调用设备服务")
@PostMapping("/invokeService")
public InvokeResult invokeService(@RequestBody @Validated Request<ServiceInvokeBo> request) {
return new InvokeResult(deviceCtrlService.invokeService(request.getData().getDeviceId(), request.getData().getService(), request.getData().getArgs()));
}
@ApiOperation(value = "设备属性设置")
@PostMapping("/setProperty")
public InvokeResult setProperty(@RequestBody @Validated Request<SetDeviceServicePorpertyBo> request) {
return new InvokeResult(deviceCtrlService.setProperty(request.getData().getDeviceId(), request.getData().getArgs()));
}
/**
* REMOVE_DEVICE
*
@ -286,15 +358,15 @@ public class SpaceDeviceController {
/**
*
*/
@DeleteMapping(Constants.API_SPACE.REMOVE_DEVICE)
public void removeDevice(String deviceId) {
SpaceDevice spaceDevice = spaceDeviceService.findByDeviceId(deviceId);
@PostMapping(Constants.API_SPACE.REMOVE_DEVICE)
public void removeDevice(@RequestBody @Validated Request<String> request) {
SpaceDevice spaceDevice = spaceDeviceService.findByDeviceId(request.getData());
if (spaceDevice == null) {
throw new BizException(ErrCode.SPACE_DEVICE_NOT_FOUND);
}
spaceDeviceService.deleteById(spaceDevice.getId());
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(request.getData());
UserInfo userInfo = userInfoData.findById(LoginHelper.getUserId());
if (userInfo == null) {
throw new BizException(ErrCode.USER_NOT_FOUND);

View File

@ -13,6 +13,7 @@ import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.common.satoken.utils.LoginHelper;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.data.manager.IHomeData;
import cc.iotkit.data.manager.ISpaceData;
@ -128,6 +129,11 @@ public class UserInfoController {
userInfoData.deleteById(id);
}
@PostMapping("/getUserInfo")
public UserInfo getUserInfo() {
return userInfoData.findById(LoginHelper.getUserId());
}
@PostMapping("/client/user/save")
public void saveClientUser(@RequestBody UserInfo user) {
UserInfo oldUser = userInfoData.findById(user.getId());

View File

@ -79,4 +79,7 @@ public class DeviceInfoVo implements Serializable {
@ApiModelProperty(value = "所属分组")
private Map<String, DeviceInfo.Group> group;
@ApiModelProperty(value = "位置信息")
private DeviceInfo.Locate locate;
}

View File

@ -14,6 +14,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -85,6 +86,11 @@ public class SpaceDeviceVo {
*/
private String categoryName;
/**
*
*/
private Date createTime;
/**
*
*/

View File

@ -1,5 +1,7 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.model.space.SpaceDevice;
import java.util.List;
@ -23,4 +25,8 @@ public interface ISpaceDeviceService {
void deleteById (Long id);
SpaceDevice findById (Long id);
Paging<ThingModelMessage> findByTypeAndDeviceIds(List<String> deviceIds, String type,
String identifier,
int page, int size);
}

View File

@ -1,8 +1,14 @@
package cc.iotkit.manager.service.impl;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.manager.ISpaceDeviceData;
import cc.iotkit.manager.service.ISpaceDeviceService;
import cc.iotkit.model.space.SpaceDevice;
import cc.iotkit.temporal.IThingModelMessageData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -18,6 +24,9 @@ public class SpaceDeviceServiceImpl implements ISpaceDeviceService {
@Autowired
private ISpaceDeviceData spaceDeviceData;
@Autowired
private IThingModelMessageData thingModelMessageData;
@Override
public List<SpaceDevice> findByHomeIdAndCollect(Long homeId, boolean collect) {
return spaceDeviceData.findByHomeIdAndCollect(homeId,collect);
@ -52,4 +61,12 @@ public class SpaceDeviceServiceImpl implements ISpaceDeviceService {
public SpaceDevice findById(Long id) {
return spaceDeviceData.findById(id);
}
@Override
public Paging<ThingModelMessage> findByTypeAndDeviceIds(List<String> deviceIds, String type, String identifier, int page, int size) {
if(StringUtils.isEmpty(type)){
throw new BizException(ErrCode.PARAMS_EXCEPTION);
}
return thingModelMessageData.findByTypeAndDeviceIds(deviceIds,type,identifier,page,size);
}
}

View File

@ -149,9 +149,7 @@ public class SysLoginService {
if(sysApp==null){
throw new BizException("该应用未授权注册");
}
String url=authUrl+"?appid="+appId+"&secret="+sysApp.getAppSecret()+"&js_code="+xcxCode+"&grant_type=authorization_code";
String ret=WeChatUtil.httpRequest(url,"GET",null);
String openid = JsonUtils.parseMap(ret).getStr("openid");
String openid = WeChatUtil.getOpenId(appId,sysApp.getAppSecret(),xcxCode);
UserInfo user = null;
LoginHelper.setTenantId(sysApp.getTenantId());
try {
@ -319,6 +317,7 @@ public class SysLoginService {
user.setType(UserInfo.USER_TYPE_CLIENT);
user.setUid(openid);
user.setRoles(Collections.singletonList(Constants.ROLE_CLIENT));
user.setNickName("微信用户");
user.setSecret(AuthUtil.enCryptPwd(Constants.PWD_CLIENT_USER));
user.setTenantId(tenantId);
user = userInfoData.save(user);