Commit 86d2bd54 by zzrdark

1.修改 批量导入设备bug

2.增加单元测试框架(web,dao)
3.增加日志
parent 4fd1ea08
package com.mx.cneeds.common.result;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @ClassName WebSocketConnectionResult
* @Author zzrdark
* @Date 2020-08-04 10:25
* @Description TODO
**/
@Data
public class WebSocketConnectionResult implements Serializable {
private Long total;
private List<String> connections;
}
spring: spring:
profiles: profiles:
active: dev active: prod
application: application:
name: cneeds-server-authorization name: cneeds-server-authorization
server: server:
......
...@@ -199,6 +199,11 @@ public class DeviceController { ...@@ -199,6 +199,11 @@ public class DeviceController {
return new R().put("data",pageDto); return new R().put("data",pageDto);
} }
/**
* 导入设备
* @param devicesVo
* @return
*/
@PreAuthorize("hasRole('deviceManagement:device:add') or hasRole('admin')") @PreAuthorize("hasRole('deviceManagement:device:add') or hasRole('admin')")
@PostMapping("/device/importDevice") @PostMapping("/device/importDevice")
public R importDevice(DevicesVo devicesVo){ public R importDevice(DevicesVo devicesVo){
...@@ -326,7 +331,12 @@ public class DeviceController { ...@@ -326,7 +331,12 @@ public class DeviceController {
return R.ok(); return R.ok();
} }
@PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')") /**
* 适配配置
* @param vo
* @return
*/
@PreAuthorize("hasRole('configManagement:deviceChannel:edit') or hasRole('admin')")
@PostMapping("/deviceChannel/updateSettingDeviceChannel") @PostMapping("/deviceChannel/updateSettingDeviceChannel")
public R updateSettingDeviceChannel(DeviceInfoVo vo){ public R updateSettingDeviceChannel(DeviceInfoVo vo){
DeviceInfoDto dto = new DeviceInfoDto(); DeviceInfoDto dto = new DeviceInfoDto();
...@@ -353,6 +363,12 @@ public class DeviceController { ...@@ -353,6 +363,12 @@ public class DeviceController {
return R.ok().put("data",list); return R.ok().put("data",list);
} }
/**
* 批量配置
* @param vo
* @return
*/
@PreAuthorize("hasRole('admin') or hasRole('deviceManagement:device:add')") @PreAuthorize("hasRole('admin') or hasRole('deviceManagement:device:add')")
@PostMapping("/device/uploadDeivceChannelExcel") @PostMapping("/device/uploadDeivceChannelExcel")
public R uploadDeivceChannelExcel(@RequestBody UploadDeviceChannelExcelVo vo){ public R uploadDeivceChannelExcel(@RequestBody UploadDeviceChannelExcelVo vo){
...@@ -362,6 +378,11 @@ public class DeviceController { ...@@ -362,6 +378,11 @@ public class DeviceController {
return R.ok(); return R.ok();
} }
/**
* 批量导入设备
* @param vo
* @return
*/
@PreAuthorize("hasRole('admin') or hasRole('deviceManagement:device:add')") @PreAuthorize("hasRole('admin') or hasRole('deviceManagement:device:add')")
@PostMapping("/device/uploadDeivceExcel") @PostMapping("/device/uploadDeivceExcel")
public R uploadDeivceExcel(@RequestBody UploadDeviceChannelExcelVo vo){ public R uploadDeivceExcel(@RequestBody UploadDeviceChannelExcelVo vo){
...@@ -372,6 +393,10 @@ public class DeviceController { ...@@ -372,6 +393,10 @@ public class DeviceController {
} }
/**
* 下载
* @return
*/
@RequestMapping(value = "/device/downloadDeviceUploadFile", method = RequestMethod.GET) @RequestMapping(value = "/device/downloadDeviceUploadFile", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> downloadDeviceUploadFile(){ public ResponseEntity<InputStreamResource> downloadDeviceUploadFile(){
...@@ -399,6 +424,11 @@ public class DeviceController { ...@@ -399,6 +424,11 @@ public class DeviceController {
return response; return response;
} }
/**
*
* @param imeis
* @return
*/
@PreAuthorize("hasRole('configManagement:deviceChannel:list') or hasRole('admin')") @PreAuthorize("hasRole('configManagement:deviceChannel:list') or hasRole('admin')")
@RequestMapping("/device/queryDeviceChannelSetting") @RequestMapping("/device/queryDeviceChannelSetting")
public R queryDeviceChannelSetting(@RequestBody List<String> imeis){ public R queryDeviceChannelSetting(@RequestBody List<String> imeis){
...@@ -411,6 +441,11 @@ public class DeviceController { ...@@ -411,6 +441,11 @@ public class DeviceController {
return R.error(ResultCode.PARAMERROR,"参数错误"); return R.error(ResultCode.PARAMERROR,"参数错误");
} }
/**
* 删除渠道号统计信息
* @param vo
* @return
*/
@PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')") @PreAuthorize("hasRole('configManagement:deviceChannel:delete') or hasRole('admin')")
@RequestMapping("/deviceChannel/deleteStatisticsDeviceChannel") @RequestMapping("/deviceChannel/deleteStatisticsDeviceChannel")
public R deleteStatisticsDeviceChannel(StatisticsDeviceChannelVo vo){ public R deleteStatisticsDeviceChannel(StatisticsDeviceChannelVo vo){
...@@ -423,6 +458,11 @@ public class DeviceController { ...@@ -423,6 +458,11 @@ public class DeviceController {
return R.ok(); return R.ok();
} }
/**
* 终端检测参数是否正确 无权限
* @param vo
* @return
*/
@RequestMapping("/device/uploadNewDeviceInfo") @RequestMapping("/device/uploadNewDeviceInfo")
public R uploadNewDeviceInfo(DeviceInfoVo vo){ public R uploadNewDeviceInfo(DeviceInfoVo vo){
if (vo.getImei() == null || vo.getImei().isEmpty()){ if (vo.getImei() == null || vo.getImei().isEmpty()){
...@@ -469,7 +509,7 @@ public class DeviceController { ...@@ -469,7 +509,7 @@ public class DeviceController {
* @param seriesId * @param seriesId
* @return * @return
*/ */
// @PreAuthorize("hasRole('deviceManagement:device:list') or hasRole('admin')") @PreAuthorize("hasRole('deviceManagement:device:list') or hasRole('admin')")
@PostMapping("/deviceInfoExport/list") @PostMapping("/deviceInfoExport/list")
public R deviceInfoExportList(@RequestParam(required = false) Integer page, public R deviceInfoExportList(@RequestParam(required = false) Integer page,
@RequestParam(required = false) Integer pageSize, @RequestParam(required = false) Integer pageSize,
...@@ -501,6 +541,7 @@ public class DeviceController { ...@@ -501,6 +541,7 @@ public class DeviceController {
return new R().put("data",pageDto); return new R().put("data",pageDto);
} }
@PreAuthorize("hasRole('deviceManagement:device:list') or hasRole('admin')")
@PostMapping("/deviceInfoExport/uploadDeviceInfoExport") @PostMapping("/deviceInfoExport/uploadDeviceInfoExport")
public R uploadDeviceInfoExport(@RequestBody UploadDeviceChannelExcelVo vo) throws IOException { public R uploadDeviceInfoExport(@RequestBody UploadDeviceChannelExcelVo vo) throws IOException {
......
...@@ -3,8 +3,10 @@ package com.mx.cneeds.server.datashow.web.wechat; ...@@ -3,8 +3,10 @@ package com.mx.cneeds.server.datashow.web.wechat;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.mx.cneeds.common.constant.FilePath; import com.mx.cneeds.common.constant.FilePath;
import com.mx.cneeds.common.result.R; import com.mx.cneeds.common.result.R;
import com.mx.cneeds.common.result.WebSocketConnectionResult;
import com.mx.cneeds.server.wechat.common.dispatcher.MessageDispatcher; import com.mx.cneeds.server.wechat.common.dispatcher.MessageDispatcher;
import com.mx.cneeds.server.wechat.common.json.WechatJsonMessage; import com.mx.cneeds.server.wechat.common.json.WechatJsonMessage;
import com.mx.cneeds.server.wechat.websocket.config.NettyChannelManager;
import com.mx.hbasefile.hadoop.hdfs.api.HdfsTemplate; import com.mx.hbasefile.hadoop.hdfs.api.HdfsTemplate;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -41,6 +43,9 @@ public class WechatController { ...@@ -41,6 +43,9 @@ public class WechatController {
@Autowired @Autowired
private MessageDispatcher messageDispatcher; private MessageDispatcher messageDispatcher;
@Autowired
private NettyChannelManager nettyChannelManager;
@RequestMapping("/wechatFileUpload") @RequestMapping("/wechatFileUpload")
@ResponseBody @ResponseBody
public R upload(HttpServletRequest httpServletRequest, MultipartFile file) throws IOException { public R upload(HttpServletRequest httpServletRequest, MultipartFile file) throws IOException {
...@@ -92,4 +97,15 @@ public class WechatController { ...@@ -92,4 +97,15 @@ public class WechatController {
public void wechatMessageHttp(@RequestBody WechatJsonMessage jsonMessage){ public void wechatMessageHttp(@RequestBody WechatJsonMessage jsonMessage){
messageDispatcher.doWechatDispatcher(jsonMessage); messageDispatcher.doWechatDispatcher(jsonMessage);
} }
@RequestMapping("/getWebSocketConnection")
@ResponseBody
public WebSocketConnectionResult getWebSocketConnection(){
WebSocketConnectionResult R = new WebSocketConnectionResult();
R.setConnections(nettyChannelManager.getChannelsWcIds());
R.setTotal((long) R.getConnections().size());
return R;
}
} }
...@@ -9,6 +9,8 @@ import org.slf4j.Logger; ...@@ -9,6 +9,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
...@@ -66,6 +68,11 @@ public class NettyChannelManager { ...@@ -66,6 +68,11 @@ public class NettyChannelManager {
userChannels.put(user, channel); userChannels.put(user, channel);
} }
public String getUser(Channel channel){
return channel.attr(CHANNEL_ATTR_KEY_USER).get();
}
/** /**
* 将 Channel 从 {@link #channels} 和 {@link #userChannels} 中移除 * 将 Channel 从 {@link #channels} 和 {@link #userChannels} 中移除
* *
...@@ -121,4 +128,8 @@ public class NettyChannelManager { ...@@ -121,4 +128,8 @@ public class NettyChannelManager {
} }
} }
public List<String> getChannelsWcIds(){
return new LinkedList<>(userChannels.keySet());
}
} }
...@@ -31,6 +31,7 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter { ...@@ -31,6 +31,7 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void channelUnregistered(ChannelHandlerContext ctx) { public void channelUnregistered(ChannelHandlerContext ctx) {
log.debug("[WeChat_WebSocket]连接关闭WcId: {}", channelManager.getUser(ctx.channel()));
// 从管理器中移除 // 从管理器中移除
channelManager.remove(ctx.channel()); channelManager.remove(ctx.channel());
} }
......
...@@ -47,7 +47,7 @@ public class OperateWebsocketHandler extends ChannelInboundHandlerAdapter { ...@@ -47,7 +47,7 @@ public class OperateWebsocketHandler extends ChannelInboundHandlerAdapter {
// 增加用户信息 // 增加用户信息
nettyChannelManager.addUser(ctx.channel(),wcId); nettyChannelManager.addUser(ctx.channel(),wcId);
log.debug("服务端收到一个连接wcId为:{}",wcId); log.debug("[WeChat_WebSocket]连接开启wcId:{}",wcId);
//如果url包含参数,需要处理 //如果url包含参数,需要处理
if(uri.contains("?")){ if(uri.contains("?")){
......
...@@ -33,7 +33,7 @@ public class WechatMessageHandler implements MessageHandler<WechatMessageRequest ...@@ -33,7 +33,7 @@ public class WechatMessageHandler implements MessageHandler<WechatMessageRequest
BeanUtils.copyProperties(message.getData(),responseDataBean); BeanUtils.copyProperties(message.getData(),responseDataBean);
WechatMessageResponse wechatMessageResponse = new WechatMessageResponse(responseDataBean,message.getMessageType()); WechatMessageResponse wechatMessageResponse = new WechatMessageResponse(responseDataBean,message.getMessageType());
nettyChannelManager.send(message.getWcId(), new Invocation(ChatRedirectToUserRequest.TYPE, wechatMessageResponse)); nettyChannelManager.send(message.getWcId(), new Invocation(ChatRedirectToUserRequest.TYPE, wechatMessageResponse));
log.debug("微控返回消息:{}", JSON.toJSONString(wechatMessageResponse)); log.debug("WcId: {} 微控返回消息:{}", message.getWcId(), JSON.toJSONString(wechatMessageResponse));
} }
@Override @Override
......
...@@ -395,13 +395,12 @@ public class DeviceInfoController { ...@@ -395,13 +395,12 @@ public class DeviceInfoController {
@RequestMapping("/uploadDeivceExcel") @RequestMapping("/uploadDeivceExcel")
public void uploadDeivceExcel(@RequestBody UploadDeviceChannelExcelDto dto){ public void uploadDeivceExcel(@RequestBody UploadDeviceChannelExcelDto dto){
List<DeviceInfoEntity> list = new LinkedList<>();
dto.getInfos().forEach(info -> { dto.getInfos().forEach(info -> {
DeviceInfoEntity deviceInfoEntity = new DeviceInfoEntity(); DeviceInfoEntity deviceInfoEntity = new DeviceInfoEntity();
if (info.getImei() != null) { if (info.getImei() != null && deviceInfoService.queryDeviceByImei(info.getImei()) == null) {
deviceInfoEntity.setImei(info.getImei());
deviceInfoEntity.setImei(info.getImei());
// 可有可无iccid // 可有可无iccid
if (info.getIccid() != null) { if (info.getIccid() != null) {
...@@ -413,12 +412,11 @@ public class DeviceInfoController { ...@@ -413,12 +412,11 @@ public class DeviceInfoController {
deviceInfoEntity.setChannelRules(dto.getChannelRules()); deviceInfoEntity.setChannelRules(dto.getChannelRules());
deviceInfoEntity.setDeptId(dto.getDeptId()); deviceInfoEntity.setDeptId(dto.getDeptId());
deviceInfoEntity.setSeriesId(dto.getSeriesId()); deviceInfoEntity.setSeriesId(dto.getSeriesId());
deviceInfoService.save(deviceInfoEntity);
} }
list.add(deviceInfoEntity);
}); });
// 先新增设备数据 以及 渠道部分数据
deviceInfoService.saveBatch(list);
} }
/** /**
......
spring: spring:
profiles: profiles:
active: dev active: prod
application: application:
name: cneeds-server-logupload name: cneeds-server-logupload
......
...@@ -46,6 +46,18 @@ ...@@ -46,6 +46,18 @@
<version>${mysql.version}</version> <version>${mysql.version}</version>
</dependency> </dependency>
<!-- 方便等会写单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId> <!-- 单元测试,我们采用 H2 作为数据库 -->
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
......
spring: spring:
profiles: profiles:
active: dev active: prod
application: application:
name: cneeds-server-user name: cneeds-server-user
......
package com.mx.cneeds.server.user.dao;
import com.mx.cneeds.server.dao.SysDeptDao;
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
/**
* @ClassName SysDeptDaoTest
* @Author zzrdark
* @Date 2020-08-04 17:29
* @Description TODO
**/
@SpringBootTest
@RunWith(SpringRunner.class)
@MapperScan("com.mx.cneeds.server.dao")
public class SysDeptDaoTest extends TestCase {
@Autowired
private SysDeptDao sysDeptDao;
@Test
@Sql(scripts = "/sql/create_sys_dept.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(statements = "insert into `sys_dept` values (1,1,'root',0,'123456','dddd')")
@Sql(statements = "insert into `sys_dept` values (2,1,'root',0,'123456789','aaaa')")
@Sql(scripts = "/sql/drop_sys_dept.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testQueryDetpIdList(){
List<Long> longs = sysDeptDao.queryDetpIdList(1L);
//
for (long l : longs){
Assert.assertNotNull(l);
}
System.out.println("success");
}
}
package com.mx.cneeds.server.user.dao;
import com.mx.cneeds.server.dao.SysUserDao;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @ClassName SysUserDaoTest
* @Author zzrdark
* @Date 2020-08-04 17:10
* @Description TODO
**/
@SpringBootTest
@RunWith(SpringRunner.class)
@MapperScan("com.mx.cneeds.server.dao")
public class SysUserDaoTest extends TestCase {
@Autowired
private SysUserDao sysUserDao;
@Test
public void testSelectById() {
System.out.println(sysUserDao.hashCode());
System.out.println(1111);
}
}
package com.mx.cneeds.server.user.web;
import com.mx.cneeds.server.entity.SysUserEntity;
import com.mx.cneeds.server.user.service.SysUserDeptService;
import com.mx.cneeds.server.user.service.SysUserFuncService;
import com.mx.cneeds.server.user.service.SysUserRoleService;
import com.mx.cneeds.server.user.service.SysUserService;
import junit.framework.TestCase;
import org.hamcrest.core.IsEqual;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class SysUserControllerTest extends TestCase {
@Autowired
private MockMvc mockMvc;
@MockBean
private SysUserService sysUserService;
@MockBean
private SysUserRoleService sysUserRoleService;
@MockBean
private SysUserDeptService sysUserDeptService;
@MockBean
private SysUserFuncService sysUserFuncService;
public void setUp() throws Exception {
super.setUp();
}
public void tearDown() throws Exception {
}
@Test
public void testList() {
System.out.println("1111");
}
@Test
public void testInfoByUsername() throws Exception {
List<Long> longList = new LinkedList<>();
longList.add(1L);
longList.add(2L);
longList.add(3L);
SysUserEntity sysUserEntity = new SysUserEntity();
sysUserEntity.setUserId(1L);
sysUserEntity.setUsername("123456");
Mockito.when(sysUserService.queryUserByUsername("123456")).thenReturn(sysUserEntity);
Mockito.when(sysUserRoleService.queryRoleId(1L)).thenReturn(1L);
Mockito.when(sysUserDeptService.queryDeptIdList(1L)).thenReturn(longList);
Mockito.when(sysUserFuncService.queryFuncIdList(1L)).thenReturn(longList);
ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post("/sys/user/userinfo").param("username","123456"));
resultActions.andExpect(MockMvcResultMatchers.status().isOk());
resultActions.andExpect(MockMvcResultMatchers.jsonPath("userId",IsEqual.equalTo(1)));
resultActions.andExpect(MockMvcResultMatchers.jsonPath("username",IsEqual.equalTo("123456")));
}
}
\ No newline at end of file
spring:
# datasource 数据源配置内容
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
mqtt:
username: admin
password: public
host-url: tcp://120.25.162.101:1883
# client-id: zhjsbackground${random.value}
client-id: server
# default-topic: $SYS/brokers/+/clients/#
completionTimeout: 3000
keepAlive: 60
topics[0]:
topicname: device/+/+/push
qos: 0
topics[1]:
topicname: server/receive/
qos: 0
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.mx.cneeds.server.entity
global-config:
#数据库相关配置
db-config:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: AUTO
#字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
field-strategy: NOT_NULL
#驼峰下划线转换
column-underline: true
logic-delete-value: -1
logic-not-delete-value: 0
banner: false
#原生配置
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
jdbc-type-for-null: 'null'
\ No newline at end of file
CREATE TABLE sys_dept (
dept_id int AUTO_INCREMENT PRIMARY KEY,
parent_id int DEFAULT NULL COMMENT '上级部门ID,一级部门为0',
name varchar(50) DEFAULT NULL COMMENT '部门名称',
del_flag int DEFAULT NULL COMMENT '是否删除 -1:已删除 0:正常',
distributor_num varchar(50) DEFAULT NULL COMMENT '渠道商号',
remark varchar(255) DEFAULT NULL COMMENT '描述'
);
DROP TABLE `sys_dept`;
\ No newline at end of file
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