@@ -253,6 +253,11 @@ | |||||
<artifactId>easyexcel-core</artifactId> | <artifactId>easyexcel-core</artifactId> | ||||
<version>3.1.2</version> | <version>3.1.2</version> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>com.ningdatech</groupId> | |||||
<artifactId>nd-file-starter</artifactId> | |||||
<version>1.0.0</version> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
<!-- 打包 --> | <!-- 打包 --> | ||||
<!--配置环境的profile--> | <!--配置环境的profile--> | ||||
@@ -0,0 +1,39 @@ | |||||
package com.ningdatech.pmapi.common.utils; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import com.ningdatech.basic.util.StrPool; | |||||
import org.springframework.util.NumberUtils; | |||||
import java.util.Arrays; | |||||
import java.util.Collections; | |||||
import java.util.List; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* <p> | |||||
* BizUtils | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 17:32 2023/1/29 | |||||
*/ | |||||
public class BizUtils { | |||||
private BizUtils() { | |||||
} | |||||
public static <T extends Number> List<T> splitToNum(String str, Class<T> aClass) { | |||||
if (StrUtil.isEmpty(str)) { | |||||
return Collections.emptyList(); | |||||
} | |||||
return Arrays.stream(str.split(StrPool.COMMA)) | |||||
.map(w -> NumberUtils.parseNumber(w, aClass)) | |||||
.collect(Collectors.toList()); | |||||
} | |||||
public static List<Long> splitToLong(String str) { | |||||
return splitToNum(str, Long.class); | |||||
} | |||||
} |
@@ -0,0 +1,70 @@ | |||||
package com.ningdatech.pmapi.sys.controller; | |||||
import com.ningdatech.basic.model.IdVo; | |||||
import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.pmapi.sys.entity.req.NoticeListReq; | |||||
import com.ningdatech.pmapi.sys.entity.req.NoticeSaveReq; | |||||
import com.ningdatech.pmapi.sys.entity.req.NoticeStatusModifyReq; | |||||
import com.ningdatech.pmapi.sys.entity.vo.NoticeDetailVO; | |||||
import com.ningdatech.pmapi.sys.entity.vo.NoticeListItemVO; | |||||
import com.ningdatech.pmapi.sys.manage.NoticeManage; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiOperation; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import javax.validation.Valid; | |||||
/** | |||||
* <p> | |||||
* 系统通知 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2022-07-21 | |||||
*/ | |||||
@RestController | |||||
@Api(tags = "消息管理") | |||||
@RequiredArgsConstructor | |||||
@RequestMapping("/api/v1/notice") | |||||
public class NoticeController { | |||||
private final NoticeManage noticeManage; | |||||
@PostMapping("/save") | |||||
@ApiOperation("新增通知") | |||||
public IdVo<Long> save(@Valid @RequestBody NoticeSaveReq req) { | |||||
return noticeManage.saveOrModify(req); | |||||
} | |||||
@GetMapping("/detail/{id}") | |||||
@ApiOperation("通知详情") | |||||
public NoticeDetailVO save(@PathVariable Long id) { | |||||
return noticeManage.detail(id); | |||||
} | |||||
@PostMapping("/enabled") | |||||
@ApiOperation("启用禁用") | |||||
public Boolean save(@Valid @RequestBody NoticeStatusModifyReq req) { | |||||
return noticeManage.changeEnabled(req); | |||||
} | |||||
@GetMapping("/dashboard/list") | |||||
@ApiOperation("工作台公告列表") | |||||
public PageVo<NoticeListItemVO> dashboardList(@RequestParam(required = false, defaultValue = "3") Integer limit) { | |||||
return noticeManage.dashboardList(limit); | |||||
} | |||||
@GetMapping("/manage/list") | |||||
@ApiOperation("公告管理列表") | |||||
public PageVo<NoticeListItemVO> listByManager(NoticeListReq req) { | |||||
return noticeManage.listByManager(req); | |||||
} | |||||
@DeleteMapping("/del") | |||||
@ApiOperation("删除公告") | |||||
public void delNotice(@RequestBody IdVo<Long> req) { | |||||
noticeManage.delNotice(req.getId()); | |||||
} | |||||
} |
@@ -0,0 +1,68 @@ | |||||
package com.ningdatech.pmapi.sys.entity; | |||||
import com.baomidou.mybatisplus.annotation.IdType; | |||||
import com.baomidou.mybatisplus.annotation.TableId; | |||||
import com.baomidou.mybatisplus.annotation.TableLogic; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
import java.time.LocalDateTime; | |||||
/** | |||||
* <p> | |||||
* 系统通知 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2022-07-21 | |||||
*/ | |||||
@Data | |||||
@TableName("nd_notice") | |||||
@ApiModel(value = "SysNotice对象", description = "系统通知") | |||||
public class Notice implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty("ID") | |||||
@TableId(type = IdType.AUTO) | |||||
private Long id; | |||||
@ApiModelProperty("消息类型") | |||||
private Integer type; | |||||
@ApiModelProperty("标题") | |||||
private String title; | |||||
@ApiModelProperty("内容") | |||||
private String content; | |||||
@ApiModelProperty("启用禁用") | |||||
private Boolean enabled; | |||||
@ApiModelProperty("附件ID") | |||||
private String attachment; | |||||
@ApiModelProperty("创建时间") | |||||
private LocalDateTime createOn; | |||||
@ApiModelProperty("创建人id") | |||||
private Long createBy; | |||||
@ApiModelProperty("最后修改时间") | |||||
private LocalDateTime updateOn; | |||||
@ApiModelProperty("最后修改人") | |||||
private Long updateBy; | |||||
@ApiModelProperty("是否删除") | |||||
@TableLogic | |||||
private Boolean deleted; | |||||
@ApiModelProperty("置顶时间") | |||||
private LocalDateTime setTopTime; | |||||
} |
@@ -0,0 +1,31 @@ | |||||
package com.ningdatech.pmapi.sys.entity.req; | |||||
import com.ningdatech.basic.model.PagePo; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
/** | |||||
* <p> | |||||
* DashboardNoticeListPo | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 00:32 2022/7/23 | |||||
*/ | |||||
@Data | |||||
@ApiModel("工作台消息列表查询") | |||||
@EqualsAndHashCode(callSuper = true) | |||||
public class NoticeListReq extends PagePo { | |||||
@ApiModelProperty("消息类型") | |||||
private Integer type; | |||||
@ApiModelProperty("公告标题") | |||||
private String title; | |||||
@ApiModelProperty("公告状态") | |||||
private Boolean enabled; | |||||
} |
@@ -0,0 +1,45 @@ | |||||
package com.ningdatech.pmapi.sys.entity.req; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.Valid; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* <p> | |||||
* MsgUpdatePo | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 21:35 2022/7/21 | |||||
*/ | |||||
@Data | |||||
@ApiModel("消息新增实体") | |||||
public class NoticeSaveReq { | |||||
@ApiModelProperty("ID") | |||||
private Long id; | |||||
@ApiModelProperty("通知标题") | |||||
@NotBlank(message = "通知标题不能为空") | |||||
private String title; | |||||
@ApiModelProperty("通知类型") | |||||
@NotNull(message = "通知类型不能为空") | |||||
private Integer type; | |||||
@ApiModelProperty("通知内容") | |||||
@NotBlank(message = "通知内容不能为空") | |||||
private String content; | |||||
@ApiModelProperty("附件ID编码") | |||||
private String attachment; | |||||
@ApiModelProperty("是否启用") | |||||
@NotNull(message = "是否启用不能为空") | |||||
private Boolean enabled; | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.ningdatech.pmapi.sys.entity.req; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* <p> | |||||
* NoticeStatusUpdatePo | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 22:32 2022/7/22 | |||||
*/ | |||||
@Data | |||||
@ApiModel("消息状态修改") | |||||
public class NoticeStatusModifyReq { | |||||
@ApiModelProperty("ID") | |||||
@NotNull(message = "ID不能为空") | |||||
private Long id; | |||||
@ApiModelProperty("状态:true 启用、false 停用") | |||||
@NotNull(message = "状态不能为空") | |||||
private Boolean status; | |||||
} |
@@ -0,0 +1,40 @@ | |||||
package com.ningdatech.pmapi.sys.entity.vo; | |||||
import com.ningdatech.file.entity.vo.result.AttachFileVo; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* NoticeDetailVo | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 16:56 2022/7/22 | |||||
*/ | |||||
@Data | |||||
@ApiModel("公告详情") | |||||
public class NoticeDetailVO { | |||||
@ApiModelProperty("ID") | |||||
private Long id; | |||||
@ApiModelProperty("标题") | |||||
private String title; | |||||
@ApiModelProperty("内容") | |||||
private String content; | |||||
@ApiModelProperty("状态") | |||||
private Boolean enabled; | |||||
@ApiModelProperty("公告类型") | |||||
private Integer type; | |||||
@ApiModelProperty("附件信息") | |||||
private List<AttachFileVo> attachments; | |||||
} |
@@ -0,0 +1,44 @@ | |||||
package com.ningdatech.pmapi.sys.entity.vo; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import lombok.experimental.Tolerate; | |||||
import java.time.LocalDateTime; | |||||
/** | |||||
* <p> | |||||
* ManageNoticeListItem | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 00:30 2022/7/23 | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
public class NoticeListItemVO { | |||||
@Tolerate | |||||
public NoticeListItemVO() { | |||||
} | |||||
@ApiModelProperty("公告ID") | |||||
private Long id; | |||||
@ApiModelProperty("公告类型") | |||||
private Integer type; | |||||
@ApiModelProperty("标题") | |||||
private String title; | |||||
@ApiModelProperty("创建时间") | |||||
private LocalDateTime createOn; | |||||
@ApiModelProperty("是否启用") | |||||
private Boolean enabled; | |||||
@ApiModelProperty("是否置顶") | |||||
private Boolean topped; | |||||
} |
@@ -0,0 +1,99 @@ | |||||
package com.ningdatech.pmapi.sys.manage; | |||||
import cn.hutool.core.bean.BeanUtil; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import com.ningdatech.basic.model.IdVo; | |||||
import com.ningdatech.basic.model.PageVo; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.ningdatech.file.entity.vo.result.AttachFileVo; | |||||
import com.ningdatech.file.service.FileService; | |||||
import com.ningdatech.pmapi.common.utils.BizUtils; | |||||
import com.ningdatech.pmapi.sys.entity.Notice; | |||||
import com.ningdatech.pmapi.sys.entity.req.NoticeListReq; | |||||
import com.ningdatech.pmapi.sys.entity.req.NoticeSaveReq; | |||||
import com.ningdatech.pmapi.sys.entity.req.NoticeStatusModifyReq; | |||||
import com.ningdatech.pmapi.sys.entity.vo.NoticeDetailVO; | |||||
import com.ningdatech.pmapi.sys.entity.vo.NoticeListItemVO; | |||||
import com.ningdatech.pmapi.sys.service.INoticeService; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* MsgManage | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 21:30 2022/7/21 | |||||
*/ | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class NoticeManage { | |||||
private final INoticeService noticeService; | |||||
private final FileService fileService; | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public IdVo<Long> saveOrModify(NoticeSaveReq req) { | |||||
Notice notice = BeanUtil.copyProperties(req, Notice.class); | |||||
noticeService.saveOrUpdate(notice); | |||||
return IdVo.of(notice.getId()); | |||||
} | |||||
public NoticeDetailVO detail(Long id) { | |||||
Notice notice = noticeService.getById(id); | |||||
NoticeDetailVO detail = BeanUtil.copyProperties(notice, NoticeDetailVO.class); | |||||
List<Long> fileIds = BizUtils.splitToLong(notice.getAttachment()); | |||||
List<AttachFileVo> attachFiles = fileService.getByIds(fileIds); | |||||
detail.setAttachments(attachFiles); | |||||
return detail; | |||||
} | |||||
public boolean changeEnabled(NoticeStatusModifyReq req) { | |||||
Notice notice = new Notice(); | |||||
notice.setId(req.getId()); | |||||
notice.setEnabled(req.getStatus()); | |||||
return noticeService.updateById(notice); | |||||
} | |||||
public PageVo<NoticeListItemVO> dashboardList(Integer limit) { | |||||
NoticeListReq req = new NoticeListReq(); | |||||
req.setPageSize(limit); | |||||
req.setEnabled(true); | |||||
return listByManager(req); | |||||
} | |||||
public PageVo<NoticeListItemVO> listByManager(NoticeListReq req) { | |||||
LambdaQueryWrapper<Notice> wrapper = Wrappers.lambdaQuery(Notice.class) | |||||
.eq(req.getEnabled() != null, Notice::getEnabled, req.getEnabled()) | |||||
.like(StrUtil.isNotBlank(req.getTitle()), Notice::getTitle, req.getTitle()) | |||||
.eq(req.getType() != null, Notice::getType, req.getType()) | |||||
.orderByDesc(Notice::getSetTopTime, Notice::getUpdateOn); | |||||
Page<Notice> page = noticeService.page(req.page(), wrapper); | |||||
if (page.getTotal() == 0) { | |||||
return PageVo.empty(); | |||||
} | |||||
List<NoticeListItemVO> tempDataList = CollUtils.convert(page.getRecords(), w -> NoticeListItemVO | |||||
.builder() | |||||
.id(w.getId()) | |||||
.type(w.getType()) | |||||
.title(w.getTitle()) | |||||
.enabled(w.getEnabled()) | |||||
.createOn(w.getCreateOn()) | |||||
.topped(w.getSetTopTime() != null) | |||||
.build()); | |||||
return PageVo.of(tempDataList, page.getTotal()); | |||||
} | |||||
public void delNotice(Long id){ | |||||
noticeService.removeById(id); | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.sys.mapper; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
import com.ningdatech.pmapi.sys.entity.Notice; | |||||
/** | |||||
* <p> | |||||
* 系统通知 Mapper 接口 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2022-07-21 | |||||
*/ | |||||
public interface NoticeMapper extends BaseMapper<Notice> { | |||||
} |
@@ -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="com.ningdatech.pmapi.sys.mapper.NoticeMapper"> | |||||
</mapper> |
@@ -0,0 +1,17 @@ | |||||
package com.ningdatech.pmapi.sys.service; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
import com.ningdatech.pmapi.sys.entity.Notice; | |||||
/** | |||||
* <p> | |||||
* 系统通知 服务类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2022-07-21 | |||||
*/ | |||||
public interface INoticeService extends IService<Notice> { | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.sys.service.impl; | |||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||||
import com.ningdatech.pmapi.sys.entity.Notice; | |||||
import com.ningdatech.pmapi.sys.mapper.NoticeMapper; | |||||
import com.ningdatech.pmapi.sys.service.INoticeService; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* 系统通知 服务实现类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2022-07-21 | |||||
*/ | |||||
@Service | |||||
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService { | |||||
} |
@@ -90,6 +90,10 @@ spring: | |||||
mybatis-plus: | mybatis-plus: | ||||
configuration: | configuration: | ||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | ||||
global-config: | |||||
db-config: | |||||
logic-delete-value: true | |||||
logic-not-delete-value: false | |||||
logging: | logging: | ||||
config: classpath:logback-spring.xml | config: classpath:logback-spring.xml | ||||
#日志配置 | #日志配置 | ||||