feat(iot): 重构物模型参数创建逻辑

- 移除 EventParam、ProductParam、ServeParam 等中间表
-将参数创建、更新和删除逻辑移至 ParamService
- 为 Param 实体添加 deptId 字段
- 优化 Bulletin 相关代码,增加单元测试
This commit is contained in:
zhuangtianxiang 2024-12-26 14:30:02 +08:00
parent 5e508a5db2
commit a9c7236a4e
29 changed files with 430 additions and 256 deletions

View File

@ -52,6 +52,11 @@ public class Attachment implements Serializable {
public LocalDateTime uploadTime; public LocalDateTime uploadTime;
/**
* 部门ID(权限)
*/
public Long deptId;
/** /**
* 文件下载链接 * 文件下载链接
*/ */

View File

@ -76,6 +76,11 @@ public class Device extends BaseEntity {
*/ */
public Long productId; public Long productId;
/**
* 部门ID(权限)
*/
public Long deptId;
/** /**
* 所属产品 * 所属产品
*/ */

View File

@ -32,7 +32,7 @@ public class ProductController {
* 创建产品 * 创建产品
* *
* @param dto 创建的产品 * @param dto 创建的产品
* @return * @return 新的产品
*/ */
@PostMapping @PostMapping
public Product create(@RequestBody ProductDto dto) { public Product create(@RequestBody ProductDto dto) {

View File

@ -1,20 +0,0 @@
package com.zsc.edu.gateway.modules.iot.product.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* @author zhuang
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@TableName("iot_product_param")
public class ProductParam {
private Long productId;
private Long paramId;
}

View File

@ -1,10 +0,0 @@
package com.zsc.edu.gateway.modules.iot.product.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.iot.product.entity.ProductParam;
/**
* @author zhuang
*/
public interface ProductParamRepository extends BaseMapper<ProductParam> {
}

View File

@ -15,8 +15,6 @@ public interface ProductService extends IService<Product> {
Product update(ProductDto dto, Long id); Product update(ProductDto dto, Long id);
// Page<Product> page(Page<Product> page, ProductQuery query);
Product detail(Long id); Product detail(Long id);
boolean delete(Long id); boolean delete(Long id);

View File

@ -1,17 +0,0 @@
package com.zsc.edu.gateway.modules.iot.tsl.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* @author zhuang
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@TableName("iot_event_param")
public class EventParam {
private Long eventId;
private Long paramId;
}

View File

@ -1,21 +0,0 @@
package com.zsc.edu.gateway.modules.iot.tsl.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* @author zhuang
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@TableName("iot_serve_param")
public class ServeParam {
private Long serveId;
private Long paramId;
}

View File

@ -1,10 +0,0 @@
package com.zsc.edu.gateway.modules.iot.tsl.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.iot.tsl.entity.EventParam;
/**
* @author zhuang
*/
public interface EventParamRepository extends BaseMapper<EventParam> {
}

View File

@ -1,7 +0,0 @@
package com.zsc.edu.gateway.modules.iot.tsl.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.iot.tsl.entity.ServeParam;
public interface ServeParamRepository extends BaseMapper<ServeParam> {
}

View File

@ -15,8 +15,6 @@ public interface EventService extends IService<Event> {
Event update(EventDto dto, Long id); Event update(EventDto dto, Long id);
// IPage<Event> page(Page<Event> page, EventQuery query);
Event detail(Long id); Event detail(Long id);
boolean delete(Long id); boolean delete(Long id);

View File

@ -1,14 +1,8 @@
package com.zsc.edu.gateway.modules.iot.tsl.service; package com.zsc.edu.gateway.modules.iot.tsl.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.modules.iot.product.dto.ProductDto;
import com.zsc.edu.gateway.modules.iot.product.entity.ProductParam;
import com.zsc.edu.gateway.modules.iot.tsl.dto.EventDto;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ServeDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.EventParam;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.iot.tsl.entity.ServeParam;
import java.util.List; import java.util.List;
@ -16,7 +10,10 @@ import java.util.List;
* @author zhuang * @author zhuang
*/ */
public interface ParamService extends IService<Param> { public interface ParamService extends IService<Param> {
List<Long> paramCreate(List<ParamDto> params);
boolean paramUpdate(List<ParamDto> paramDto, List<Long> paramIds); Boolean create(List<ParamDto> params, Long id, Param.ForeignType foreignType);
Boolean update(List<ParamDto> paramDto, Long id);
Boolean delete(Long id);
} }

View File

@ -15,8 +15,6 @@ public interface ServeService extends IService<Serve> {
Serve update(ServeDto dto, Long id); Serve update(ServeDto dto, Long id);
// IPage<Serve> page(Page<Serve> page, ServeQuery query);
Serve detail(Long id); Serve detail(Long id);
Boolean delete(Long id); Boolean delete(Long id);

View File

@ -1,30 +1,17 @@
package com.zsc.edu.gateway.modules.iot.tsl.service.impl; package com.zsc.edu.gateway.modules.iot.tsl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.exception.ConstraintException; import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.modules.iot.tsl.dto.EventDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.EventDto;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Event; import com.zsc.edu.gateway.modules.iot.tsl.entity.Event;
import com.zsc.edu.gateway.modules.iot.tsl.entity.EventParam;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.EventMapper; import com.zsc.edu.gateway.modules.iot.tsl.mapper.EventMapper;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.ParamMapper;
import com.zsc.edu.gateway.modules.iot.tsl.query.EventQuery;
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventRepository; import com.zsc.edu.gateway.modules.iot.tsl.repo.EventRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.service.EventService; import com.zsc.edu.gateway.modules.iot.tsl.service.EventService;
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService; import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author Yao * @author Yao
*/ */
@ -32,9 +19,6 @@ import java.util.stream.Collectors;
@AllArgsConstructor @AllArgsConstructor
public class EventServiceImpl extends ServiceImpl<EventRepository, Event> implements EventService { public class EventServiceImpl extends ServiceImpl<EventRepository, Event> implements EventService {
private final EventMapper mapper; private final EventMapper mapper;
private final ParamMapper paramMapper;
private final ParamRepository paramRepo;
private final EventParamRepository eventParamRepo;
private final ParamService paramService; private final ParamService paramService;
/** /**
@ -47,10 +31,7 @@ public class EventServiceImpl extends ServiceImpl<EventRepository, Event> implem
} }
Event event = mapper.toEntity(dto); Event event = mapper.toEntity(dto);
save(event); save(event);
List<EventParam> eventParams = paramService.paramCreate(dto.getOutputs()).stream() paramService.create(dto.getOutputs(), event.getId(), Param.ForeignType.EVENT);
.map(paramId -> new EventParam(event.getId(), paramId))
.toList();
eventParamRepo.insert(eventParams);
return event; return event;
} }
/** /**
@ -61,24 +42,9 @@ public class EventServiceImpl extends ServiceImpl<EventRepository, Event> implem
Event event = baseMapper.selectById(id); Event event = baseMapper.selectById(id);
mapper.convert(dto, event); mapper.convert(dto, event);
updateById(event); updateById(event);
paramService.paramUpdate(dto.getOutputs(), paramService.update(dto.getOutputs(), event.getId());
eventParamRepo.selectList(new LambdaQueryWrapper<EventParam>()
.eq(EventParam::getEventId, event.getId()))
.stream()
.map(EventParam::getParamId)
.collect(Collectors.toList()));
return event; return event;
} }
/**
* 分页查询物模型事件
*
* @param query 查询表单
* @param page 分页参数
*/
// @Override
// public IPage<Event> page(Page<Event> page, EventQuery query) {
// return baseMapper.page(page, query);
// }
/** /**
* 查询详情 * 查询详情
@ -96,16 +62,6 @@ public class EventServiceImpl extends ServiceImpl<EventRepository, Event> implem
@Override @Override
public boolean delete(Long id) { public boolean delete(Long id) {
removeById(id); removeById(id);
LambdaQueryWrapper<EventParam> wrapper = new LambdaQueryWrapper<>(); return paramService.delete(id);
wrapper.eq(EventParam::getEventId, id);
List<EventParam> eventParams = eventParamRepo.selectList(wrapper);
if (!eventParams.isEmpty()) {
List<Long> paramIds = eventParams.stream()
.map(EventParam::getParamId)
.toList();
paramRepo.deleteByIds(paramIds);
}
eventParamRepo.delete(wrapper);
return true;
} }
} }

View File

@ -2,24 +2,16 @@ package com.zsc.edu.gateway.modules.iot.tsl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.modules.iot.product.dto.ProductDto;
import com.zsc.edu.gateway.modules.iot.product.entity.ProductParam;
import com.zsc.edu.gateway.modules.iot.product.repo.ProductParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ServeDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.EventParam;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.iot.tsl.entity.ServeParam;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.ParamMapper; import com.zsc.edu.gateway.modules.iot.tsl.mapper.ParamMapper;
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository; import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ServeParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService; import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@ -31,24 +23,24 @@ import java.util.stream.IntStream;
public class ParamServiceImpl extends ServiceImpl<ParamRepository, Param> implements ParamService { public class ParamServiceImpl extends ServiceImpl<ParamRepository, Param> implements ParamService {
private final ParamMapper mapper; private final ParamMapper mapper;
private final ParamMapper paramMapper; private final ParamMapper paramMapper;
private final EventParamRepository eventParamRepository;
private final ProductParamRepository productParamRepository;
private final ServeParamRepository serveParamRepository;
@Override @Override
public List<Long> paramCreate(List<ParamDto> params) { public Boolean create(List<ParamDto> params, Long id, Param.ForeignType foreignType) {
List<Long> paramIds = new ArrayList<>();
List<Param> paramsToInsert = params.stream() List<Param> paramsToInsert = params.stream()
.map(mapper::toEntity) .map(dto -> {
Param param = mapper.toEntity(dto);
param.setForeignId(id);
param.setForeignType(foreignType);
return param;
})
.collect(Collectors.toList()); .collect(Collectors.toList());
baseMapper.insert(paramsToInsert); baseMapper.insert(paramsToInsert);
paramsToInsert.forEach(param -> paramIds.add(param.getId())); return true;
return paramIds;
} }
@Override @Override
public boolean paramUpdate(List<ParamDto> paramDto, List<Long> paramIds) { public Boolean update(List<ParamDto> paramDto, Long id) {
List<Param> params = baseMapper.selectByIds(paramIds); List<Param> params = baseMapper.selectList(new LambdaQueryWrapper<Param>()
.eq(Objects.nonNull(id), Param::getForeignId, id));
if (!params.isEmpty() && !paramDto.isEmpty()) { if (!params.isEmpty() && !paramDto.isEmpty()) {
List<Param> updatedParams = IntStream.range(0, Math.min(params.size(), paramDto.size())) List<Param> updatedParams = IntStream.range(0, Math.min(params.size(), paramDto.size()))
.parallel() .parallel()
@ -64,5 +56,10 @@ public class ParamServiceImpl extends ServiceImpl<ParamRepository, Param> implem
return true; return true;
} }
//TODO 整合方法方法一保持现状但是会有多个联表多个entity多个repo方法二建新联表其中values(product_id,serve_id,event_id,param_id)一表联三表 @Override
public Boolean delete(Long id) {
return baseMapper.delete(new LambdaQueryWrapper<Param>()
.eq(Objects.nonNull(id), Param::getForeignId, id)) > 0;
}
} }

View File

@ -1,18 +1,11 @@
package com.zsc.edu.gateway.modules.iot.tsl.service.impl; package com.zsc.edu.gateway.modules.iot.tsl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.exception.ConstraintException; import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ServeDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ServeDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.*; import com.zsc.edu.gateway.modules.iot.tsl.entity.*;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.ParamMapper;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.ServeMapper; import com.zsc.edu.gateway.modules.iot.tsl.mapper.ServeMapper;
import com.zsc.edu.gateway.modules.iot.tsl.query.ServeQuery;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ServeParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ServeRepository; import com.zsc.edu.gateway.modules.iot.tsl.repo.ServeRepository;
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService; import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
import com.zsc.edu.gateway.modules.iot.tsl.service.ServeService; import com.zsc.edu.gateway.modules.iot.tsl.service.ServeService;
@ -21,8 +14,6 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
@ -33,8 +24,6 @@ import java.util.stream.Stream;
public class ServeServiceImpl extends ServiceImpl<ServeRepository, Serve> implements ServeService { public class ServeServiceImpl extends ServiceImpl<ServeRepository, Serve> implements ServeService {
private final ServeMapper mapper; private final ServeMapper mapper;
private final ParamRepository paramRepository;
private final ServeParamRepository serveParamRepository;
private final ParamService paramService; private final ParamService paramService;
/** /**
* 新建功能 * 新建功能
@ -46,10 +35,9 @@ public class ServeServiceImpl extends ServiceImpl<ServeRepository, Serve> implem
} }
Serve serve = mapper.toEntity(dto); Serve serve = mapper.toEntity(dto);
save(serve); save(serve);
List<ServeParam> serveParams = paramService.paramCreate(dto.getParams()).stream() List<ParamDto> params = new ArrayList<>(dto.getInputs());
.map(paramId -> new ServeParam(serve.getId(), paramId)) params.addAll(dto.getOutputs());
.toList(); paramService.create(params, serve.getId(), Param.ForeignType.SERVE);
serveParamRepository.insert(serveParams);
return serve; return serve;
} }
/** /**
@ -60,26 +48,12 @@ public class ServeServiceImpl extends ServiceImpl<ServeRepository, Serve> implem
Serve serve = baseMapper.selectById(id); Serve serve = baseMapper.selectById(id);
mapper.convert(dto, serve); mapper.convert(dto, serve);
updateById(serve); updateById(serve);
paramService.paramUpdate(dto.getParams(), List<ParamDto> params = new ArrayList<>(dto.getInputs());
serveParamRepository.selectList(new LambdaQueryWrapper<ServeParam>() params.addAll(dto.getOutputs());
.eq(ServeParam::getServeId, serve.getId())) paramService.update(params, serve.getId());
.stream()
.map(ServeParam::getParamId)
.collect(Collectors.toList()));
return serve; return serve;
} }
/**
* 分页查询功能
*
* @param query 查询表单
* @param page 分页参数
*/
// @Override
// public IPage<Serve> page(Page<Serve> page, ServeQuery query) {
// return baseMapper.page(page, query);
// }
/** /**
* 查询详情 * 查询详情
* @param id 主键 * @param id 主键
@ -89,19 +63,16 @@ public class ServeServiceImpl extends ServiceImpl<ServeRepository, Serve> implem
public Serve detail(Long id) { public Serve detail(Long id) {
return baseMapper.selectById(id); return baseMapper.selectById(id);
} }
/**
* 删除功能
*
* @param id serveId
* @return true
*/
@Override @Override
public Boolean delete(Long id) { public Boolean delete(Long id) {
removeById(id); removeById(id);
LambdaQueryWrapper<ServeParam> wrapper = new LambdaQueryWrapper<>(); return paramService.delete(id);
wrapper.eq(ServeParam::getServeId, id);
List<ServeParam> serveParam = serveParamRepository.selectList(wrapper);
if (!serveParam.isEmpty()) {
List<Long> paramIds = serveParam.stream()
.map(ServeParam::getParamId)
.toList();
paramRepository.deleteByIds(paramIds);
}
serveParamRepository.delete(wrapper);
return true;
} }
} }

View File

@ -33,6 +33,11 @@ public class Bulletin extends BaseEntity {
*/ */
public State state = State.edit; public State state = State.edit;
/**
* 部门ID(权限)
*/
public Long deptId;
/** /**
* 是否置顶 * 是否置顶
*/ */

View File

@ -57,4 +57,8 @@ public class Message extends BaseEntity {
*/ */
public String content; public String content;
/**
* 部门ID(权限)
*/
public Long deptId;
} }

View File

@ -31,5 +31,7 @@ public interface UserMessageService extends IService<UserMessage> {
boolean markAsRead(UserDetailsImpl userDetails, List<Long> messageIds); boolean markAsRead(UserDetailsImpl userDetails, List<Long> messageIds);
boolean markAllAsRead(UserDetailsImpl userDetails);
IPage<AdminMessageVo> getAdminMessagePage(Page<UserMessageVo> page, AdminMessageQuery query); IPage<AdminMessageVo> getAdminMessagePage(Page<UserMessageVo> page, AdminMessageQuery query);
} }

View File

@ -1,7 +1,6 @@
package com.zsc.edu.gateway.modules.notice.service.impl; package com.zsc.edu.gateway.modules.notice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -101,10 +100,7 @@ public class UserMessageServiceImpl extends ServiceImpl<UserMessageRepository, U
@Override @Override
public boolean markAsRead(UserDetailsImpl userDetails, List<Long> messageIds) { public boolean markAsRead(UserDetailsImpl userDetails, List<Long> messageIds) {
if (CollectionUtils.isEmpty(messageIds)) { if (CollectionUtils.isEmpty(messageIds)) {
return this.lambdaUpdate().eq(UserMessage::getUserId, userDetails.getId()) throw new RuntimeException("您输入的集合为空");
.set(UserMessage::getIsRead, true)
.set(UserMessage::getReadTime, LocalDateTime.now())
.update();
} }
return this.lambdaUpdate().eq(UserMessage::getUserId, userDetails.getId()) return this.lambdaUpdate().eq(UserMessage::getUserId, userDetails.getId())
.in(UserMessage::getMessageId, messageIds) .in(UserMessage::getMessageId, messageIds)
@ -113,6 +109,16 @@ public class UserMessageServiceImpl extends ServiceImpl<UserMessageRepository, U
.update(); .update();
} }
/**
* 全部已读
*/
@Override
public boolean markAllAsRead(UserDetailsImpl userDetails) {
return this.lambdaUpdate().eq(UserMessage::getUserId, userDetails.getId())
.set(UserMessage::getIsRead, true)
.set(UserMessage::getReadTime, LocalDateTime.now())
.update();
}
/** /**
* 管理员查询消息列表 * 管理员查询消息列表
@ -177,7 +183,7 @@ public class UserMessageServiceImpl extends ServiceImpl<UserMessageRepository, U
sms.set(message.sms); sms.set(message.sms);
}); });
Message message = new Message(payload.type, true, email.get(), sms.get(), Message message = new Message(payload.type, true, email.get(), sms.get(),
payload.html, payload.type.name(), payload.content); payload.html, payload.type.name(), payload.content, null);
messageRepo.insert(message); messageRepo.insert(message);
Set<UserMessage> userMessages = receivers.stream().map(user -> Set<UserMessage> userMessages = receivers.stream().map(user ->
new UserMessage(null, user.getId(), message.getId(), true, null)).collect(Collectors.toSet()); new UserMessage(null, user.getId(), message.getId(), true, null)).collect(Collectors.toSet());

View File

@ -25,5 +25,11 @@ public class Authority extends BaseEntity {
* 启用状态 * 启用状态
*/ */
private Boolean enabled = true; private Boolean enabled = true;
/**
* 部门ID(权限)
*/
public Long deptId;
} }

View File

@ -29,6 +29,11 @@ public class Role extends BaseEntity {
*/ */
private Boolean enabled = true; private Boolean enabled = true;
/**
* 部门ID(权限)
*/
public Long deptId;
/** /**
* 权限集合 * 权限集合
*/ */

View File

@ -495,7 +495,7 @@ VALUES (1, 'Device1', TRUE, 1, 'HW1.0', 'FW1.0', 'FactoryA', 'Client1', 1, '{"pa
(10, 'Device10', FALSE, 10, 'HW1.9', 'FW1.9', 'FactoryJ', 'Client10', 10, '{"param10": "value10"}', (10, 'Device10', FALSE, 10, 'HW1.9', 'FW1.9', 'FactoryJ', 'Client10', 10, '{"param10": "value10"}',
'{"prop10": "value10"}', 'Admin', CURRENT_TIMESTAMP, 'Admin', CURRENT_TIMESTAMP, 'Remark10'); '{"prop10": "value10"}', 'Admin', CURRENT_TIMESTAMP, 'Admin', CURRENT_TIMESTAMP, 'Remark10');
INSERT INTO iot_product (id, name, type_string, model, link, create_by, create_time, update_by, update_time, remark, INSERT INTO iot_product (id, name, product_type, model, link, create_by, create_time, update_by, update_time, remark,
dept_id) dept_id)
VALUES (1, 'Product1', 'TypeA', 'ModelX', 1, 'Admin', CURRENT_TIMESTAMP, 'Admin', CURRENT_TIMESTAMP, 'Remark1', 101), VALUES (1, 'Product1', 'TypeA', 'ModelX', 1, 'Admin', CURRENT_TIMESTAMP, 'Admin', CURRENT_TIMESTAMP, 'Remark1', 101),
(2, 'Product2', 'TypeB', 'ModelY', 2, 'Admin', CURRENT_TIMESTAMP, 'Admin', CURRENT_TIMESTAMP, 'Remark2', 102), (2, 'Product2', 'TypeB', 'ModelY', 2, 'Admin', CURRENT_TIMESTAMP, 'Admin', CURRENT_TIMESTAMP, 'Remark2', 102),
@ -556,4 +556,53 @@ VALUES (1, 'serve1', 'Service 1', 'This is service 1'),
(9, 'serve9', 'Service 9', 'This is service 9'), (9, 'serve9', 'Service 9', 'This is service 9'),
(10, 'serve10', 'Service 10', 'This is service 10'); (10, 'serve10', 'Service 10', 'This is service 10');
alter table iot_device
add dept_id bigint;
comment on column iot_device.dept_id is '部门权限id';
alter table iot_param
add dept_id bigint;
comment on column iot_param.dept_id is '部门权限id';
alter table iot_serve
add dept_id bigint;
comment on column iot_serve.dept_id is '部门权限id';
alter table iot_event
add dept_id bigint;
comment on column iot_event.dept_id is '部门权限id';
alter table iot_event
add dept_id bigint;
comment on column iot_event.dept_id is '部门权限id';
alter table sys_bulletin
add dept_id bigint;
comment on column sys_bulletin.dept_id is '部门权限id';
alter table sys_bulletin
add dept_id bigint;
comment on column sys_bulletin.dept_id is '部门权限id';
alter table sys_message
add dept_id bigint;
comment on column sys_message.dept_id is '部门权限id';
alter table sys_authority
add dept_id bigint;
comment on column sys_authority.dept_id is '部门权限id';
alter table sys_role
add dept_id bigint;
comment on column sys_role.dept_id is '部门权限id';

View File

@ -0,0 +1,16 @@
package com.zsc.edu.gateway.domain;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
public class BaseParamBuilder {
public Long id = 1L;
public String identifier;
public String name;
public String remark;
public BaseParamBuilder() {
remark = randomAlphabetic(5);
identifier = randomAlphabetic(5);
name = randomAlphabetic(5);
}
}

View File

@ -11,7 +11,7 @@ public class DeptBuilder extends BaseEntityBuilder {
public Dept parent; public Dept parent;
public Long pid; public Long pid;
public HashSet<Dept> children; public List<Dept> children;
public static DeptBuilder aDept(){ public static DeptBuilder aDept(){
@ -34,7 +34,7 @@ public class DeptBuilder extends BaseEntityBuilder {
return this; return this;
} }
public DeptBuilder children(HashSet<Dept> children) { public DeptBuilder children(List<Dept> children) {
this.children = children; this.children = children;
return this; return this;
} }
@ -44,7 +44,7 @@ public class DeptBuilder extends BaseEntityBuilder {
Dept dept = new Dept(); Dept dept = new Dept();
dept.setName(name); dept.setName(name);
dept.setPid(pid); dept.setPid(pid);
dept.setChildren((List<Dept>) children); dept.setChildren(children);
return dept; return dept;
} }

View File

@ -0,0 +1,44 @@
package com.zsc.edu.gateway.domain;
import com.zsc.edu.gateway.modules.iot.tsl.entity.DataType;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
public class ParamBuilder extends BaseParamBuilder {
public DataType dataType;
public String uint;
public Param.Type type;
public Param.ForeignType foreignType;
public static ParamBuilder aParam() {
return new ParamBuilder();
}
public ParamBuilder dataType(DataType dataType) {
this.dataType = dataType;
return this;
}
public ParamBuilder uint(String uint) {
this.uint = uint;
return this;
}
public ParamBuilder type(Param.Type type) {
this.type = type;
return this;
}
public ParamBuilder foreignType(Param.ForeignType foreignType) {
this.foreignType = foreignType;
return this;
}
public Param build() {
Param param = new Param();
param.setUint(uint);
param.setType(type);
param.setForeignType(foreignType);
param.setDataType(dataType);
return param;
}
}

View File

@ -0,0 +1,91 @@
package com.zsc.edu.gateway.rest;
import com.zsc.edu.gateway.MockMvcConfigBase;
import com.zsc.edu.gateway.domain.BulletinBuilder;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
import com.zsc.edu.gateway.modules.notice.dto.BulletinDto;
import com.zsc.edu.gateway.modules.notice.entity.Bulletin;
import com.zsc.edu.gateway.modules.notice.service.BulletinService;
import com.zsc.edu.gateway.modules.system.controller.AuthorityController;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(AuthorityController.class)
public class BulletinControllerTest extends MockMvcConfigBase {
@Spy
private static Bulletin bulletin1;
private static Bulletin bulletin2;
@MockBean
private BulletinService service;
@BeforeAll
static void beforeAll() {
bulletin1 = BulletinBuilder.bBulletin().title("title1").content("content1").top(true).build();
bulletin1.setId(1L);
bulletin2 = BulletinBuilder.bBulletin().title("title2").content("content2").top(false).build();
}
@Test
void create() throws Exception {
BulletinDto dto = new BulletinDto();
dto.setTitle(bulletin1.getTitle());
dto.setContent(bulletin1.getContent());
dto.setTop(bulletin1.getTop());
when(service.create(any(UserDetailsImpl.class), any(BulletinDto.class))).thenReturn(bulletin1);
mockMvc.perform(post("/api/rest/bulletin")
.with(csrf().asHeader())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(dto))
)
.andExpect(status().isOk())
.andDo(print());
verify(service).create(any(UserDetailsImpl.class), any(BulletinDto.class));
}
@Test
void list() throws Exception {
List<Bulletin> bulletins = Lists.newArrayList(bulletin1, bulletin2);
when(service.list()).thenReturn(bulletins);
mockMvc.perform(get("/api/rest/bulletin").with(user(userDetails))
).andExpect(status().isOk()).andDo(print());
verify(service).list();
}
@Test
void update() throws Exception {
BulletinDto dto = new BulletinDto();
dto.setTitle(bulletin1.getTitle());
dto.setContent(bulletin1.getContent());
dto.setTop(bulletin1.getTop());
when(service.update(any(UserDetailsImpl.class), any(BulletinDto.class), anyLong())).thenReturn(true);
mockMvc.perform(patch("/api/rest/bulletin/{id}", bulletin1.getId())
.with(csrf().asHeader())
.with(user(userDetails))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(dto))
)
.andExpect(status().isOk())
.andDo(print());
verify(service).update(any(UserDetailsImpl.class), any(BulletinDto.class), anyLong());
}
}

View File

@ -14,25 +14,41 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class BulletinServiceTest { public class BulletinServiceTest {
@Resource @Resource
private BulletinService service; private BulletinService service;
@Resource @Resource
private BulletinRepository repo; private BulletinRepository repo;
Bulletin bulletin1; private Bulletin bulletin1;
Bulletin bulletin2; private Bulletin bulletin2;
private UserDetailsImpl userDetails;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
bulletin1 = BulletinBuilder.bBulletin().title("测试1").build(); userDetails = new UserDetailsImpl();
repo.insert(bulletin1); userDetails.setUsername("admin");
bulletin2 = BulletinBuilder.bBulletin().title("测试2").build(); bulletin1 = createAndInsertBulletin("测试1");
repo.insert(bulletin2); bulletin2 = createAndInsertBulletin("测试2");
}
@AfterEach
void tearDown() {
// 清理所有测试公告
List<String> titlesToDelete = Arrays.asList("测试1", "测试2", "测试3", "测试");
repo.delete(new QueryWrapper<Bulletin>().in("title", titlesToDelete));
}
private Bulletin createAndInsertBulletin(String title) {
Bulletin bulletin = BulletinBuilder.bBulletin().title(title).build();
repo.insert(bulletin);
return bulletin;
} }
@Test @Test
@ -45,45 +61,38 @@ public class BulletinServiceTest {
@Test @Test
void createBulletin() { void createBulletin() {
BulletinDto dto = new BulletinDto(); BulletinDto dto = createBulletinDto("测试", true, "测试测试", "测试公告增加");
dto.setTitle("测试");
dto.setTop(true);
dto.setContent("测试测试");
dto.setRemark("测试公告增加");
BulletinDto dto2 = new BulletinDto();
dto2.setTitle(bulletin2.getTitle());
// dto2.setTop(bulletin2.isTop());
dto2.setRemark(bulletin2.getRemark());
UserDetailsImpl userDetails = new UserDetailsImpl();
userDetails.setUsername("admin");
Bulletin bulletin = service.create(userDetails, dto); Bulletin bulletin = service.create(userDetails, dto);
assertNotNull(bulletin.getId()); assertNotNull(bulletin.getId());
List<Bulletin> list = service.list(); List<Bulletin> list = service.list();
assertEquals(3, list.size()); assertEquals(3, list.size());
// 不能创建其他已存在标题公告 // 不能创建其他已存在标题公告
assertThrows(ConstraintException.class, () -> service.create(userDetails, dto2)); assertThrows(ConstraintException.class, () -> service.create(userDetails, createBulletinDto(bulletin2.getTitle(), false, "", "")));
} }
@Test @Test
void updateBulletin() { void updateBulletin() {
BulletinDto dto = new BulletinDto(); BulletinDto dto = createBulletinDto("测试3", true, "测试测", "测试公告更新");
dto.setTitle("测试3"); assertTrue(service.update(userDetails, dto, bulletin2.getId()));
dto.setContent("测试测");
dto.setTop(true); Bulletin updatedBulletin = service.getOne(new LambdaQueryWrapper<Bulletin>().eq(Bulletin::getTitle, dto.getTitle()));
dto.setRemark("测试公告更新"); assertNotNull(updatedBulletin);
UserDetailsImpl userDetails = new UserDetailsImpl(); assertEquals(dto.getTitle(), updatedBulletin.getTitle());
userDetails.setUsername("admin"); assertEquals(bulletin2.getId(), updatedBulletin.getId());
assertTrue(service.update(userDetails, dto, bulletin2.id));
Bulletin bulletin = service.getOne(new LambdaQueryWrapper<Bulletin>().eq(Bulletin::getTitle, dto.getTitle())); // 不能改为其他已存在的同名公告
assertEquals(bulletin.getTitle(), dto.getTitle()); assertThrows(ConstraintException.class,
assertEquals(bulletin.getId(), bulletin2.id); () -> service.update(userDetails, createBulletinDto(bulletin1.getTitle(), true, "测试测试", "测试公告更新"), bulletin2.getId()));
// 不能改为其他已存在的同名同代码部门
// assertThrows(ConstraintException.class,
// () -> service.update(userDetails, new BulletinDto(bulletin1.getTitle(), true, null, null), bulletin2.id));
} }
@AfterEach private BulletinDto createBulletinDto(String title, boolean top, String content, String remark) {
void tearDown() { BulletinDto dto = new BulletinDto();
repo.delete(new QueryWrapper<>()); dto.setTitle(title);
dto.setTop(top);
dto.setContent(content);
dto.setRemark(remark);
return dto;
} }
} }

View File

@ -0,0 +1,97 @@
package com.zsc.edu.gateway.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zsc.edu.gateway.domain.ParamBuilder;
import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.DataType;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
public class ParamServiceTest {
@Autowired
private ParamService service;
@Autowired
private ParamRepository repo;
private Param param1;
private Param param2;
@BeforeEach
void setUp() {
param1 = ParamBuilder.aParam().uint("测试1").build();
repo.insert(param1);
param2 = ParamBuilder.aParam().uint("测试2").build();
repo.insert(param2);
}
@Test
void list() {
LambdaQueryWrapper<Param> queryWrapper = new LambdaQueryWrapper<>();
assertEquals(2, service.list(queryWrapper.like(Param::getUint, "测试")).size());
assertEquals(1, service.list(queryWrapper.eq(Param::getUint, param1.getUint())).size());
// assertEquals(2, service.list().size());
}
@Test
void createParams() {
List<ParamDto> params = createParamDtoList();
Long foreignId = 1L;
Boolean result = service.create(params, foreignId, null);
assertTrue(result);
List<Param> insertedParams = service.list(new LambdaQueryWrapper<Param>().like(Param::getName, "PARAM_NAME"));
assertEquals(2, insertedParams.size()); // 因为setUp方法已经插入了两个参数
}
@Test
void updateParams() {
ParamDto dto = new ParamDto();
dto.setName("PARAM_NAME_UPDATE");
dto.setIdentifier("测试更新");
List<ParamDto> params = new ArrayList<>();
params.add(dto);
assertTrue(service.update(params, param2.getId()));
// 确保获取到的 param 对象是最新的
Param param = repo.selectById(param2.getId());
assertNotNull(param); // 确保 param 不为空
// 更新后的 identifier 应该是 "测试更新"
assertEquals("测试更新", param.getIdentifier());
assertEquals(param2.getId(), param.getId());
}
@AfterEach
void tearDown() {
repo.delete(new LambdaQueryWrapper<Param>()
.in(Param::getId, param1.getId(), param2.getId())
.or()
.in(Param::getName, "PARAM_NAME_1", "PARAM_NAME_2", "PARAM_NAME_UPDATE"));
}
private List<ParamDto> createParamDtoList() {
ParamDto paramDto1 = new ParamDto();
paramDto1.setName("PARAM_NAME_1");
paramDto1.setIdentifier("PARAM_VALUE_1");
paramDto1.setDataType(DataType.DATE);
ParamDto paramDto2 = new ParamDto();
paramDto2.setName("PARAM_NAME_2");
paramDto2.setIdentifier("PARAM_VALUE_2");
paramDto2.setDataType(DataType.DATE);
return Arrays.asList(paramDto1, paramDto2);
}
}