回收柜设备对接v1

door
LI-CCONG\李聪聪 6 months ago
parent 45269fb21e
commit a0938c5677

@ -2,7 +2,9 @@ package cc.yunxi.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
@ -12,7 +14,11 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@Slf4j
@ -78,6 +84,26 @@ public class WebUtils {
return response != null && response.getStatus() < 300;
}
/**
* bytes body => key1=value1&key2=value2 => Map
* @param request
*/
public static Map<String, String> parseQueryString(HttpServletRequest request) throws Exception {
String queryString = WebUtils.getRequestPostStr(request);
queryString = URLUtil.decode(queryString, StandardCharsets.UTF_8);
Map<String, String> params = new LinkedHashMap<>();
for (String param : queryString.split("&")) {
if (!param.isEmpty()) {
String[] keyValue = param.split("=");
if (keyValue.length == 2) {
params.put(keyValue[0], keyValue[1]);
}
}
}
return params;
}
/**
* key1=value1&key2=value2
* key使 key1value1key2value2value3 key1=value1&key2=value2,value3

@ -0,0 +1,96 @@
package cc.yunxi.controller;
import cc.yunxi.common.domain.CommonResult;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.common.utils.WebUtils;
import cc.yunxi.domain.dto.QrCodeDTO;
import cc.yunxi.domain.vo.device.RecycleDeviceRespVO;
import cc.yunxi.domain.vo.device.RecycleDeviceRespVO.RecycleDeviceDoorVO;
import cc.yunxi.service.IRecycleDeviceService;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-03-10 09:04:53
*/
@Api(tags = "回收柜设备")
@RestController
@RequestMapping("/device")
@Slf4j
public class DeviceController {
@Resource
private IRecycleDeviceService deviceService;
@ApiOperation("设备状态上报")
@PostMapping("/device_state")
public CommonResult<String> deviceState(HttpServletRequest request) throws Exception {
// 1. 参数解析处理
Map<String, String> dataMap = WebUtils.parseQueryString(request);
String listDoor = dataMap.remove("listDoor");
RecycleDeviceRespVO recycleDeviceRespVO = BeanUtils.copyBean(dataMap, RecycleDeviceRespVO.class);
if(StrUtil.isNotEmpty(listDoor)) {
JSONArray jsonArray = JSONUtil.parseArray(listDoor);
List<RecycleDeviceDoorVO> deviceDoorVOList = BeanUtils.copyList(jsonArray, RecycleDeviceDoorVO.class);
recycleDeviceRespVO.setListDoor(deviceDoorVOList);
}
log.info("recycleDeviceRespVO = {}", recycleDeviceRespVO);
deviceService.saveDeviceInfo(recycleDeviceRespVO);
return CommonResult.success("ok");
}
@ApiOperation("请求登陆")
@GetMapping("/login_name")
public CommonResult<String> loginName(@RequestBody QrCodeDTO qrCodeDTO) {
// 处理数据
String devsn = qrCodeDTO.getDevsn();
Integer devid = qrCodeDTO.getDevid();
return CommonResult.success("ok");
}
@SneakyThrows
@ApiOperation("上传投递重量")
@GetMapping("/delivery_data")
public CommonResult<String> deliveryData(HttpServletRequest request) {
String queryString = request.getQueryString();
String parameters = WebUtils.getParameters(request);
String requestBody = WebUtils.getRequestPostStr(request);
log.info("deliveryData receive params = {}", parameters);
log.info("deliveryData receive json = {}", requestBody);
return CommonResult.success(queryString);
}
@SneakyThrows
@ApiOperation("上传清运重量")
@GetMapping("/clean_data")
public CommonResult<String> cleanData(HttpServletRequest request) {
String queryString = request.getQueryString();
String parameters = WebUtils.getParameters(request);
String requestBody = WebUtils.getRequestPostStr(request);
log.info("cleanData receive params = {}", parameters);
log.info("cleanData receive json = {}", requestBody);
return CommonResult.success(queryString);
}
}

@ -0,0 +1,41 @@
package cc.yunxi.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.models.auth.In;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
@ApiModel(description = "二维码扫描后请求实体")
public class QrCodeDTO {
@ApiModelProperty(value = "phoneNo", required = true)
@NotBlank(message = "手机号缺失")
private String phoneNo;
@ApiModelProperty(value = "devsn", required = true)
@NotBlank(message = "devsn缺失")
private String devsn;
@ApiModelProperty(value = "orgid", required = true)
@NotNull(message = "机构id缺失")
private Integer orgid;
@ApiModelProperty(value = "devid", required = true)
@NotNull(message = "设备id缺失")
private Integer devid;
@ApiModelProperty(value = "qrtype", required = true)
@NotNull(message = "二维码标识缺失")
private Integer qrtype;
@ApiModelProperty(value = "devtype", required = true)
@NotNull(message = "设备类型缺失")
private Integer devtype;
}

@ -0,0 +1,84 @@
package cc.yunxi.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:33:58
*/
@Data
@TableName("nx_recycle_device")
@ApiModel(value = "RecycleDevice对象", description = "回收柜设备表")
public class RecycleDevice {
@ApiModelProperty("主键id")
@EqualsAndHashCode.Exclude
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@ApiModelProperty("设备编码")
@TableField("devsn")
private String devsn;
@ApiModelProperty("烟雾报警 0未报警 1报警")
@TableField("allSmoke")
private Integer allSmoke;
@ApiModelProperty("是否满溢 0未满溢 1满溢")
@TableField("isSpill")
private Integer isSpill;
@ApiModelProperty("是否超重报警 0未报警 1报警")
@TableField("weightSpill")
private Integer weightSpill;
@ApiModelProperty("是否压缩报警 0未报警 1报警")
@TableField("compressdSpill")
private Integer compressdSpill;
@ApiModelProperty("当前设备整体重量,多筒累加 kg")
@TableField("weight")
private Double weight;
@ApiModelProperty("筒数量")
@TableField("size")
private Integer size;
@ApiModelProperty("配置的版本号")
@TableField("appConfigVersion")
private String appConfigVersion;
@ApiModelProperty("创建时间")
@TableField("f_creator_time")
private LocalDateTime createTime;
@ApiModelProperty("更新时间")
@TableField("f_last_modify_time")
private LocalDateTime updateTime;
@ApiModelProperty("公司id")
@TableField("company_id")
private String companyId;
@ApiModelProperty("组织id")
@TableField("organize_json_id")
private String organizeJsonId;
}

@ -0,0 +1,78 @@
package cc.yunxi.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:34:14
*/
@Getter
@Setter
@TableName("nx_recycle_device_door")
@ApiModel(value = "RecycleDeviceDoor对象", description = "回收设备筒表")
public class RecycleDeviceDoor {
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@ApiModelProperty("设备编码")
@TableField("devsn")
private String devsn;
@ApiModelProperty("筒编号")
@TableField("doorid")
private String doorid;
@ApiModelProperty("烟雾报警状态 0未报警 1报警")
@TableField("allSmoke")
private Integer allSmoke;
@ApiModelProperty("满溢报警状态 0未报警 1报警")
@TableField("isSpill")
private Integer isSpill;
@ApiModelProperty("重量报警状态 0未报警 1报警")
@TableField("weightSpill")
private Integer weightSpill;
@ApiModelProperty("压缩状态 >0 压缩中 0未压缩")
@TableField("compressdSpill")
private Integer compressdSpill;
@ApiModelProperty("重量 kg")
@TableField("weight")
private Double weight;
@ApiModelProperty("投递门状态 0关闭 1打开")
@TableField("OpenDoorState")
private Integer openDoorState;
@ApiModelProperty("清运门状态 0关闭 1打开")
@TableField("cleanDoorState")
private Integer cleanDoorState;
@ApiModelProperty("创建时间")
@TableField("f_creator_time")
private LocalDateTime createTime;
@ApiModelProperty("更新时间")
@TableField("f_last_modify_time")
private LocalDateTime updateTime;
}

@ -0,0 +1,91 @@
package cc.yunxi.domain.vo.device;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:33:58
*/
@ApiModel(value = "RecycleDeviceRespVO", description = "回收柜设备上报 Request V0")
@Data
@Accessors(chain = true)
public class RecycleDeviceRespVO {
@ApiModelProperty("设备编码")
private String devsn;
@ApiModelProperty("烟雾报警 0未报警 1报警")
private Integer allSmoke;
@ApiModelProperty("是否满溢 0未满溢 1满溢")
private Integer isSpill;
@ApiModelProperty("是否超重报警 0未报警 1报警")
private Integer weightSpill;
@ApiModelProperty("是否压缩报警 0未报警 1报警")
private Integer compressedSpill;
@ApiModelProperty("当前设备整体重量,多筒累加 kg")
private Double weight;
@ApiModelProperty("筒数量")
private Integer size;
@ApiModelProperty("配置的版本号")
private String appConfigVersion;
@ApiModelProperty("筒列表")
@Valid
private List<RecycleDeviceDoorVO> listDoor;
@ApiModel(value = "RecycleDeviceRespVO")
@Data
@Accessors(chain = true)
public static class RecycleDeviceDoorVO {
@ApiModelProperty("设备编码")
private String doorid;
@ApiModelProperty("烟雾报警状态 0未报警 1报警")
private Integer allSmoke;
@ApiModelProperty("满溢报警状态 0未报警 1报警")
private Integer isSpill;
@ApiModelProperty("重量报警状态 0未报警 1报警")
private Integer weightSpill;
@ApiModelProperty("压缩状态 >0 压缩中 0未压缩")
private Integer compressdSpill;
@ApiModelProperty("重量 kg")
private Double weight;
@ApiModelProperty("投递门状态 0关闭 1打开")
private Integer openDoorState;
@ApiModelProperty("清运门状态 0关闭 1打开")
private Integer cleanDoorState;
}
}

@ -31,11 +31,12 @@ public class StatsInterceptor implements HandlerInterceptor {
String contentType = request.getContentType();
String data = "其他复杂请求数据不记录!";
if(HttpMethod.POST.name().equals(method) && !contentType.equals(MediaType.MULTIPART_FORM_DATA_VALUE)) {
if (contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
data = WebUtils.getRequestPostStr(request);
} else if (contentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
data = WebUtils.getParameters(request);
}
// if (contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
// data = WebUtils.getRequestPostStr(request);
// } else if (contentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
// data = WebUtils.getParameters(request); // 存在bug post弃用getParameters
// }
data = WebUtils.getRequestPostStr(request);
} else if (HttpMethod.GET.name().equals(method)) {
data = WebUtils.getParameters(request);
}

@ -0,0 +1,18 @@
package cc.yunxi.mapper;
import cc.yunxi.domain.po.RecycleDeviceDoor;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author ccongli
* @since 2024-04-11 10:34:14
*/
@Mapper
public interface RecycleDeviceDoorMapper extends BaseMapper<RecycleDeviceDoor> {
}

@ -0,0 +1,18 @@
package cc.yunxi.mapper;
import cc.yunxi.domain.po.RecycleDevice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author ccongli
* @since 2024-04-11 10:33:58
*/
@Mapper
public interface RecycleDeviceMapper extends BaseMapper<RecycleDevice> {
}

@ -0,0 +1,34 @@
package cc.yunxi.service;
import cc.yunxi.domain.po.RecycleDeviceDoor;
import cc.yunxi.domain.vo.device.RecycleDeviceRespVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.session.SqlSession;
import javax.validation.Valid;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:34:14
*/
public interface IRecycleDeviceDoorService extends IService<RecycleDeviceDoor> {
boolean updateBatchByQueryWrapper(Collection<RecycleDeviceDoor> entityList,
Function<RecycleDeviceDoor, LambdaUpdateWrapper> queryWrapperFunction);
}

@ -0,0 +1,30 @@
package cc.yunxi.service;
import cc.yunxi.domain.po.RecycleDevice;
import cc.yunxi.domain.vo.device.RecycleDeviceRespVO;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:33:58
*/
public interface IRecycleDeviceService extends IService<RecycleDevice> {
/**
*
*/
RecycleDevice getDeviceInfo(String devsn);
/**
*
*/
void saveDeviceInfo(@Valid RecycleDeviceRespVO recycleDeviceRespVO);
}

@ -0,0 +1,47 @@
package cc.yunxi.service.impl;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.domain.po.RecycleDevice;
import cc.yunxi.domain.po.RecycleDeviceDoor;
import cc.yunxi.domain.vo.device.RecycleDeviceRespVO;
import cc.yunxi.mapper.RecycleDeviceDoorMapper;
import cc.yunxi.service.IRecycleDeviceDoorService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.binding.MapperMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.Collection;
import java.util.function.Function;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:34:14
*/
@Service
@Validated
public class RecycleDeviceDoorServiceImpl extends ServiceImpl<RecycleDeviceDoorMapper, RecycleDeviceDoor> implements IRecycleDeviceDoorService {
// 批量更新
public boolean updateBatchByQueryWrapper(Collection<RecycleDeviceDoor> entityList,
Function<RecycleDeviceDoor, LambdaUpdateWrapper> wrapperFunction) {
String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE);
return this.executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
MapperMethod.ParamMap param = new MapperMethod.ParamMap<>();
param.put(Constants.ENTITY, entity);
param.put(Constants.WRAPPER, wrapperFunction.apply(entity));
sqlSession.update(sqlStatement, param);
});
}
}

@ -0,0 +1,84 @@
package cc.yunxi.service.impl;
import cc.yunxi.common.domain.LambdaQueryWrapperX;
import cc.yunxi.common.domain.LambdaUpdateWrapperX;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.domain.po.RecycleDevice;
import cc.yunxi.domain.po.RecycleDeviceDoor;
import cc.yunxi.domain.vo.device.RecycleDeviceRespVO;
import cc.yunxi.mapper.RecycleDeviceDoorMapper;
import cc.yunxi.mapper.RecycleDeviceMapper;
import cc.yunxi.service.IRecycleDeviceDoorService;
import cc.yunxi.service.IRecycleDeviceService;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-04-11 10:33:58
*/
@Service
public class RecycleDeviceServiceImpl extends ServiceImpl<RecycleDeviceMapper, RecycleDevice> implements IRecycleDeviceService {
@Resource
private IRecycleDeviceDoorService recycleDeviceDoorService;
@Override
public RecycleDevice getDeviceInfo(String devsn) {
LambdaQueryWrapperX<RecycleDevice> wrapperX = new LambdaQueryWrapperX();
wrapperX.eq(RecycleDevice::getDevsn, devsn);
return this.getOne(wrapperX, false);
}
/**
*
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void saveDeviceInfo(RecycleDeviceRespVO recycleDeviceRespVO) {
RecycleDevice recycleDevice = BeanUtils.copyBean(recycleDeviceRespVO, RecycleDevice.class);
List<RecycleDeviceDoor> deviceDoorList = BeanUtils.copyList(recycleDeviceRespVO.getListDoor(), RecycleDeviceDoor.class);
RecycleDevice deviceInfo = this.getDeviceInfo(recycleDevice.getDevsn());
LocalDateTime now = LocalDateTime.now();
if (ObjectUtil.isEmpty(deviceInfo)) { // 添加
recycleDevice.setCreateTime(now); // 组织机构维护 todo
this.save(recycleDevice);
deviceDoorList.forEach(v -> {
v.setDevsn(recycleDevice.getDevsn());
v.setCreateTime(now);
});
recycleDeviceDoorService.saveBatch(deviceDoorList);
} else { // 更新
LambdaUpdateWrapperX<RecycleDevice> wrapperX = new LambdaUpdateWrapperX<>();
wrapperX.eq(RecycleDevice::getDevsn, deviceInfo.getDevsn());
recycleDevice.setUpdateTime(now);
this.update(recycleDevice, wrapperX);
LambdaUpdateWrapper<RecycleDeviceDoor> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(RecycleDeviceDoor::getDevsn, deviceInfo.getDevsn());
deviceDoorList.forEach(v -> v.setUpdateTime(now));
recycleDeviceDoorService.updateBatchByQueryWrapper(deviceDoorList, v -> updateWrapper);
}
}
}

@ -100,6 +100,7 @@ nxhs:
- /api/test/**
- /api/file/download
- /api/index/products
- /api/device/**
adminKey: 8bd2aa89033ead51c505e44994e42189 # 后台接口访问Key
upload:
basePath: /upload/

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.yunxi.mapper.RecycleDeviceDoorMapper">
</mapper>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cc.yunxi.mapper.RecycleDeviceMapper">
</mapper>
Loading…
Cancel
Save