Compare commits

...

2 Commits

Author SHA1 Message Date
曹鹏飞 e01e1deabf Merge remote-tracking branch '惠信/qms/develop' into qms/develop 2026-04-10 14:07:55 +08:00
曹鹏飞 bc2ed739e4 feat(notification): 实现质量通知管理功能
- 新增质量通知支持手动选择通知用户
- 编辑质量通知时校验状态并更新用户关联
- 删除质量通知时校验状态并删除关联数据
- 发布质量通知时设置状态和发布时间
- 支持分页查询质量通知列表并翻译状态名称
- 查询质量通知详情时包含通知用户和附件列表
- 实现质量通知用户关联的保存和管理逻辑
- 完善相关实体、请求对象、返回对象及数据库映射
- 增加文件上传、搜索、删除及压缩下载接口和实现
2026-04-10 14:07:20 +08:00
19 changed files with 1208 additions and 0 deletions

View File

@ -0,0 +1,117 @@
package com.nflg.qms.admin.controller;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.nflg.qms.admin.service.FileControllerService;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.exception.NflgException;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.qo.FileSearchQO;
import com.nflg.wms.common.pojo.qo.ZipDownloadQO;
import com.nflg.wms.common.pojo.vo.FileUploadVO;
import com.nflg.wms.common.pojo.vo.FileVO;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.starter.BaseController;
import com.nflg.wms.starter.annotation.ApiMark;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
* 文件
**/
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController extends BaseController {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
@Resource
private FileUploadService fileUploadService;
@Resource
private FileControllerService fileControllerService;
/**
* 上传单个文件(不带id)
* @param file 要上传的文件
* @return 可访问的文件url
*/
@PostMapping("uploadSingleFile1")
public ApiResult<FileUploadVO> uploadSingleFile1(@Valid @NotNull @RequestParam("file") MultipartFile file) {
try {
String fileName = file.getOriginalFilename();
String fileType = getFileType(fileName);
String url = fileUploadService.upload(buildFilePath(fileType), file);
return ApiResult.success(new FileUploadVO(0L, fileName, url));
} catch (Exception ex) {
log.error("上传文件失败", ex);
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
}
}
private String buildFilePath(String fileType) {
return StrUtil.format("admin/{}/{}/{}/{}{}", LocalDateTime.now().format(FORMATTER), UserUtil.getUserId()
, RandomUtil.randomString(4), IdUtil.fastUUID(), fileType);
}
private String getFileType(String fileName) {
return "." + FilenameUtils.getExtension(fileName);
}
/**
* 搜索文件
* @param request 搜索条件
* @return 搜索到的文件列表
*/
@PostMapping("searchFiles")
@ApiMark(moduleName = "文件管理", apiName = "搜索文件")
public ApiResult<PageData<FileVO>> searchFiles(@Valid @RequestBody FileSearchQO request) {
return ApiResult.success(fileControllerService.search(request));
}
/**
* 删除文件
* @param ids 文件id列表
*/
@PostMapping("deleteFile")
@ApiMark(moduleName = "文件管理", apiName = "删除文件")
public ApiResult<Void> deleteFile(@Valid @RequestBody @NotEmpty List<Long> ids) {
fileControllerService.deleteFile(ids);
return ApiResult.success();
}
/**
* 获取文件类型列表
* @return 文件类型列表
*/
@PostMapping("getFileTypes")
@ApiMark(moduleName = "文件管理", apiName = "获取文件类型列表")
public ApiResult<List<String>> getFileTypes(){
return ApiResult.success(fileControllerService.getFileTypes());
}
/**
* 文件压缩下载
* @param request 请求参数
*/
@PostMapping("zipDownload")
public ResponseEntity<byte[]> zipDownload(@Valid @RequestBody ZipDownloadQO request) throws IOException {
return fileControllerService.zipDownload(request);
}
}

View File

@ -0,0 +1,89 @@
package com.nflg.qms.admin.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nflg.qms.admin.service.QualityNotificationControllerService;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationAddQO;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationSearchQO;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationUpdateQO;
import com.nflg.wms.common.pojo.qo.EnableQO;
import com.nflg.wms.common.pojo.vo.QmsQualityNotificationVO;
import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.*;
/**
* 质量通知
*/
@RestController
@RequestMapping("/quality-notification")
public class QualityNotificationController extends BaseController {
@Resource
private QualityNotificationControllerService qualityNotificationControllerService;
/**
* 新增质量通知
*/
@PostMapping("add")
public ApiResult<Void> add(@Valid @RequestBody QmsQualityNotificationAddQO request) {
qualityNotificationControllerService.add(request);
return ApiResult.success();
}
/**
* 编辑质量通知
*/
@PostMapping("update")
public ApiResult<Void> update(@Valid @RequestBody QmsQualityNotificationUpdateQO request) {
qualityNotificationControllerService.update(request);
return ApiResult.success();
}
/**
* 删除质量通知
*/
@PostMapping("delete")
public ApiResult<Void> delete(@NotNull Long id) {
qualityNotificationControllerService.delete(id);
return ApiResult.success();
}
/**
* 发布质量通知
*/
@PostMapping("publish")
public ApiResult<Void> publish(@NotNull Long id) {
qualityNotificationControllerService.publish(id);
return ApiResult.success();
}
/**
* 分页查询质量通知列表
*/
@PostMapping("search")
public ApiResult<PageData<QmsQualityNotificationVO>> search(@Valid @RequestBody QmsQualityNotificationSearchQO request) {
IPage<QmsQualityNotificationVO> page = qualityNotificationControllerService.search(request);
return ApiResult.success(page);
}
/**
* 获取质量通知详情
*/
@GetMapping("detail")
public ApiResult<QmsQualityNotificationVO> detail(@NotNull Long id) {
return ApiResult.success(qualityNotificationControllerService.getDetail(id));
}
/**
* 启用/禁用质量通知
*/
@PostMapping("enable")
public ApiResult<Void> enable(@Valid @RequestBody EnableQO request) {
qualityNotificationControllerService.enable(request.getId(), request.getEnable());
return ApiResult.success();
}
}

View File

@ -0,0 +1,108 @@
package com.nflg.qms.admin.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.qo.FileSearchQO;
import com.nflg.wms.common.pojo.qo.ZipDownloadQO;
import com.nflg.wms.common.pojo.vo.FileVO;
import com.nflg.wms.common.util.DateTimeUtil;
import com.nflg.wms.common.util.PageUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.FileUploadRecord;
import com.nflg.wms.repository.service.IFileUploadRecordService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Component
public class FileControllerService {
private final OkHttpClient client = new OkHttpClient();
@Resource
private IFileUploadRecordService fileUploadRecordService;
public PageData<FileVO> search(@Valid FileSearchQO request) {
LocalDate endTime = request.getEndTime();
if (Objects.nonNull(endTime)) {
endTime = endTime.plusDays(1);
}
Page<FileUploadRecord> datas = fileUploadRecordService.lambdaQuery()
.eq(Objects.nonNull(request.getSource()), FileUploadRecord::getSource, request.getSource())
.eq(Objects.nonNull(request.getSourceId()), FileUploadRecord::getSourceId, request.getSourceId())
.eq(Objects.nonNull(request.getFileType()), FileUploadRecord::getFileType, request.getFileType())
.and(Objects.nonNull(request.getKey()), (wq) -> wq
.like(FileUploadRecord::getFileName, request.getKey())
.or()
.like(FileUploadRecord::getSourceId, request.getKey()))
.ge(Objects.nonNull(request.getStartTime()), FileUploadRecord::getCreateTime, request.getStartTime())
.lt(Objects.nonNull(endTime), FileUploadRecord::getCreateTime, endTime)
.orderByDesc(FileUploadRecord::getId)
.page(new Page<>(request.getPage(), request.getPageSize()));
return PageUtil.convert(datas, d -> Convert.convert(FileVO.class, d));
}
public void deleteFile(@Valid @NotEmpty List<Long> ids) {
fileUploadRecordService.removeBatchByIds(ids);
}
public List<String> getFileTypes() {
return fileUploadRecordService.getFileTypes();
}
public ResponseEntity<byte[]> zipDownload(@Valid ZipDownloadQO request) throws IOException {
List<String> urls = fileUploadRecordService.listByIds(request.getFileIds()).stream().map(FileUploadRecord::getUrl).collect(Collectors.toList());
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(urls)).throwMessage("没有需要下载的文件");
Path tempZipFile = Files.createTempFile("files", ".zip");
try (FileOutputStream fos = new FileOutputStream(tempZipFile.toFile());
ZipOutputStream zos = new ZipOutputStream(fos)) {
for (String fileUrl : urls) {
Request r = new Request.Builder().url(fileUrl).build();
try (Response response = client.newCall(r).execute()) {
if (response.isSuccessful() && response.body() != null) {
String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
// 使用流式处理将文件内容写入 ZIP 输出流
InputStream inputStream = response.body().byteStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) >= 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
}
}
}
}
byte[] zipContent = Files.readAllBytes(tempZipFile);
Files.deleteIfExists(tempZipFile);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+ DateTimeUtil.format(LocalDateTime.now(),"yyyyMMddHHmmss")+".zip");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(zipContent);
}
}

View File

@ -0,0 +1,327 @@
package com.nflg.qms.admin.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationAddQO;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationSearchQO;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationUpdateQO;
import com.nflg.wms.common.pojo.vo.FileVO;
import com.nflg.wms.common.pojo.vo.QmsQualityNotificationUserVO;
import com.nflg.wms.common.pojo.vo.QmsQualityNotificationVO;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.FileUploadRecord;
import com.nflg.wms.repository.entity.QmsQualityNotification;
import com.nflg.wms.repository.entity.QmsQualityNotificationUser;
import com.nflg.wms.repository.entity.User;
import com.nflg.wms.repository.service.IFileUploadRecordService;
import com.nflg.wms.repository.service.IQmsQualityNotificationService;
import com.nflg.wms.repository.service.IQmsQualityNotificationUserService;
import com.nflg.wms.repository.service.IUserService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 质量通知业务逻辑
*/
@Slf4j
@Component
public class QualityNotificationControllerService {
@Resource
private IQmsQualityNotificationService qualityNotificationService;
@Resource
private IQmsQualityNotificationUserService notificationUserService;
@Resource
private IUserService userService;
@Resource
private IFileUploadRecordService fileUploadRecordService;
/**
* 新增质量通知
*/
@Transactional
public void add(@Valid QmsQualityNotificationAddQO request) {
// 如果是手动选择用户必须提供用户ID列表
if (request.getTargetType() == 2) {
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(request.getUserIds()))
.throwMessage("手动选择用户时,用户列表不能为空");
}
String operator = UserUtil.getUserName();
Long operatorId = UserUtil.getUserId();
LocalDateTime now = LocalDateTime.now();
// 如果状态为已发布设置发布时间
LocalDateTime publishTime = null;
if (request.getStatus() == 2) {
publishTime = now;
}
QmsQualityNotification entity = new QmsQualityNotification()
.setNotificationTypeId(request.getNotificationTypeId())
.setTitle(request.getTitle())
.setTargetType(request.getTargetType())
.setContent(request.getContent())
.setStatus(request.getStatus())
.setState(1) // 默认启用
.setPublishTime(publishTime)
.setCreateById(operatorId)
.setCreateBy(operator)
.setCreateTime(now)
.setUpdateById(operatorId)
.setUpdateBy(operator)
.setUpdateTime(now);
qualityNotificationService.save(entity);
// 如果是手动选择用户保存用户关联
if (request.getTargetType() == 2 && CollectionUtil.isNotEmpty(request.getUserIds())) {
saveNotificationUsers(entity.getId(), request.getUserIds(), operator, operatorId, now);
}
}
/**
* 编辑质量通知
*/
@Transactional
public void update(@Valid QmsQualityNotificationUpdateQO request) {
QmsQualityNotification exist = qualityNotificationService.getById(request.getId());
VUtil.trueThrowBusinessError(Objects.isNull(exist)).throwMessage("通知不存在");
// 已发布的通知不允许编辑
VUtil.trueThrowBusinessError(exist.getStatus() == 2).throwMessage("已发布的通知不允许编辑");
// 如果是手动选择用户必须提供用户ID列表
if (request.getTargetType() == 2) {
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(request.getUserIds()))
.throwMessage("手动选择用户时,用户列表不能为空");
}
String operator = UserUtil.getUserName();
Long operatorId = UserUtil.getUserId();
LocalDateTime now = LocalDateTime.now();
qualityNotificationService.lambdaUpdate()
.eq(QmsQualityNotification::getId, request.getId())
.set(QmsQualityNotification::getNotificationTypeId, request.getNotificationTypeId())
.set(QmsQualityNotification::getTitle, request.getTitle())
.set(QmsQualityNotification::getTargetType, request.getTargetType())
.set(QmsQualityNotification::getContent, request.getContent())
.set(QmsQualityNotification::getStatus, request.getStatus())
.set(QmsQualityNotification::getUpdateById, operatorId)
.set(QmsQualityNotification::getUpdateBy, operator)
.set(QmsQualityNotification::getUpdateTime, now)
.update();
// 删除原有的用户关联
notificationUserService.lambdaUpdate()
.eq(QmsQualityNotificationUser::getNotificationId, request.getId())
.remove();
// 如果是手动选择用户重新保存用户关联
if (request.getTargetType() == 2 && CollectionUtil.isNotEmpty(request.getUserIds())) {
saveNotificationUsers(request.getId(), request.getUserIds(), operator, operatorId, now);
}
}
/**
* 删除质量通知
*/
@Transactional
public void delete(Long id) {
QmsQualityNotification exist = qualityNotificationService.getById(id);
VUtil.trueThrowBusinessError(Objects.isNull(exist)).throwMessage("通知不存在");
// 已发布的通知不允许删除
VUtil.trueThrowBusinessError(exist.getStatus() == 2).throwMessage("已发布的通知不允许删除");
// 删除通知
qualityNotificationService.removeById(id);
// 删除用户关联
notificationUserService.lambdaUpdate()
.eq(QmsQualityNotificationUser::getNotificationId, id)
.remove();
}
/**
* 发布质量通知
*/
@Transactional
public void publish(Long id) {
QmsQualityNotification exist = qualityNotificationService.getById(id);
VUtil.trueThrowBusinessError(Objects.isNull(exist)).throwMessage("通知不存在");
// 已发布的通知不能重复发布
VUtil.trueThrowBusinessError(exist.getStatus() == 2).throwMessage("通知已发布,不能重复发布");
String operator = UserUtil.getUserName();
Long operatorId = UserUtil.getUserId();
LocalDateTime now = LocalDateTime.now();
qualityNotificationService.lambdaUpdate()
.eq(QmsQualityNotification::getId, id)
.set(QmsQualityNotification::getStatus, 2)
.set(QmsQualityNotification::getPublishTime, now)
.set(QmsQualityNotification::getUpdateById, operatorId)
.set(QmsQualityNotification::getUpdateBy, operator)
.set(QmsQualityNotification::getUpdateTime, now)
.update();
}
/**
* 分页查询质量通知列表
*/
public IPage<QmsQualityNotificationVO> search(@Valid QmsQualityNotificationSearchQO request) {
IPage<QmsQualityNotificationVO> page = qualityNotificationService.search(request);
// 设置名称翻译
page.getRecords().forEach(this::translateNames);
return page;
}
/**
* 获取质量通知详情
*/
public QmsQualityNotificationVO getDetail(Long id) {
QmsQualityNotification entity = qualityNotificationService.getById(id);
VUtil.trueThrowBusinessError(Objects.isNull(entity)).throwMessage("通知不存在");
QmsQualityNotificationVO vo = new QmsQualityNotificationVO();
vo.setId(entity.getId());
vo.setNotificationTypeId(entity.getNotificationTypeId());
vo.setTitle(entity.getTitle());
vo.setTargetType(entity.getTargetType());
vo.setContent(entity.getContent());
vo.setStatus(entity.getStatus());
vo.setState(entity.getState());
vo.setPublishTime(entity.getPublishTime());
vo.setCreateById(entity.getCreateById());
vo.setCreateBy(entity.getCreateBy());
vo.setCreateTime(entity.getCreateTime());
vo.setUpdateById(entity.getUpdateById());
vo.setUpdateBy(entity.getUpdateBy());
vo.setUpdateTime(entity.getUpdateTime());
// 翻译名称
translateNames(vo);
// 如果是手动选择用户查询用户列表
if (entity.getTargetType() == 2) {
List<QmsQualityNotificationUser> users = notificationUserService.lambdaQuery()
.eq(QmsQualityNotificationUser::getNotificationId, id)
.list();
if (CollectionUtil.isNotEmpty(users)) {
List<Long> userIds = users.stream()
.map(QmsQualityNotificationUser::getUserId)
.collect(Collectors.toList());
List<User> userList = userService.listByIds(userIds);
List<QmsQualityNotificationUserVO> userVOs = new ArrayList<>();
for (QmsQualityNotificationUser nu : users) {
User user = userList.stream()
.filter(u -> u.getId().equals(nu.getUserId()))
.findFirst()
.orElse(null);
if (user != null) {
QmsQualityNotificationUserVO userVO = new QmsQualityNotificationUserVO();
userVO.setId(nu.getId());
userVO.setNotificationId(nu.getNotificationId());
userVO.setUserId(nu.getUserId());
userVO.setUserName(user.getUserName());
userVO.setUserCode(user.getUserCode());
userVOs.add(userVO);
}
}
vo.setUsers(userVOs);
}
}
// 查询附件列表
List<FileUploadRecord> files = fileUploadRecordService.lambdaQuery()
.eq(FileUploadRecord::getSourceId, id)
.list();
if (CollectionUtil.isNotEmpty(files)) {
List<FileVO> fileVOs = files.stream().map(f -> {
FileVO fileVO = new FileVO();
fileVO.setId(f.getId());
fileVO.setFileName(f.getFileName());
fileVO.setFileType(f.getFileType());
fileVO.setUrl(f.getUrl());
fileVO.setCreateBy(f.getCreateBy());
fileVO.setCreateTime(f.getCreateTime());
return fileVO;
}).collect(Collectors.toList());
vo.setAttachments(fileVOs);
}
return vo;
}
/**
* 保存通知用户关联
*/
private void saveNotificationUsers(Long notificationId, List<Long> userIds,
String operator, Long operatorId, LocalDateTime now) {
List<QmsQualityNotificationUser> users = userIds.stream()
.map(userId -> new QmsQualityNotificationUser()
.setNotificationId(notificationId)
.setUserId(userId)
.setCreateById(operatorId)
.setCreateBy(operator)
.setCreateTime(now))
.collect(Collectors.toList());
notificationUserService.saveBatch(users);
}
/**
* 翻译名称
*/
private void translateNames(QmsQualityNotificationVO vo) {
// 通知对象类型名称
if (vo.getTargetType() != null) {
vo.setTargetTypeName(vo.getTargetType() == 1 ? "全部" : "手动选择");
}
// 发布状态名称
if (vo.getStatus() != null) {
vo.setStatusName(vo.getStatus() == 1 ? "草稿" : "已发布");
}
// 启用状态名称
if (vo.getState() != null) {
vo.setStateName(vo.getState() == 1 ? "启用" : "禁用");
}
}
/**
* 启用/禁用质量通知
*/
@Transactional
public void enable(Long id, boolean enable) {
QmsQualityNotification exist = qualityNotificationService.getById(id);
VUtil.trueThrowBusinessError(Objects.isNull(exist)).throwMessage("通知不存在");
String operator = UserUtil.getUserName();
Long operatorId = UserUtil.getUserId();
LocalDateTime now = LocalDateTime.now();
qualityNotificationService.lambdaUpdate()
.eq(QmsQualityNotification::getId, id)
.set(QmsQualityNotification::getState, enable ? 1 : 2)
.set(QmsQualityNotification::getUpdateById, operatorId)
.set(QmsQualityNotification::getUpdateBy, operator)
.set(QmsQualityNotification::getUpdateTime, now)
.update();
}
}

View File

@ -0,0 +1,48 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 质量通知 新增参数
*/
@Data
public class QmsQualityNotificationAddQO {
/**
* 通知类型ID
*/
@NotNull(message = "通知类型不能为空")
private Long notificationTypeId;
/**
* 通知标题
*/
@NotBlank(message = "通知标题不能为空")
private String title;
/**
* 通知对象类型1=全部2=手动选择
*/
@NotNull(message = "通知对象类型不能为空")
private Integer targetType;
/**
* 通知用户ID列表targetType=2时必填
*/
private List<Long> userIds;
/**
* 通知内容HTML格式
*/
private String content;
/**
* 状态1=草稿2=已发布
*/
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@ -0,0 +1,32 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 质量通知 列表查询参数
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class QmsQualityNotificationSearchQO extends SearchBaseQO {
/**
* 通知标题
*/
private String title;
/**
* 通知类型ID
*/
private Long notificationTypeId;
/**
* 状态1=草稿2=已发布
*/
private Integer status;
/**
* 启用状态1=启用2=禁用
*/
private Integer state;
}

View File

@ -0,0 +1,54 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 质量通知 更新参数
*/
@Data
public class QmsQualityNotificationUpdateQO {
/**
* 主键
*/
@NotNull(message = "ID不能为空")
private Long id;
/**
* 通知类型ID
*/
@NotNull(message = "通知类型不能为空")
private Long notificationTypeId;
/**
* 通知标题
*/
@NotBlank(message = "通知标题不能为空")
private String title;
/**
* 通知对象类型1=全部2=手动选择
*/
@NotNull(message = "通知对象类型不能为空")
private Integer targetType;
/**
* 通知用户ID列表targetType=2时必填
*/
private List<Long> userIds;
/**
* 通知内容HTML格式
*/
private String content;
/**
* 状态1=草稿2=已发布
*/
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@ -0,0 +1,32 @@
package com.nflg.wms.common.pojo.vo;
import lombok.Data;
/**
* 通知用户关联 信息VO
*/
@Data
public class QmsQualityNotificationUserVO {
private Long id;
/**
* 通知ID
*/
private Long notificationId;
/**
* 用户ID
*/
private Long userId;
/**
* 用户姓名
*/
private String userName;
/**
* 用户工号
*/
private String userCode;
}

View File

@ -0,0 +1,110 @@
package com.nflg.wms.common.pojo.vo;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* 质量通知 信息VO
*/
@Data
public class QmsQualityNotificationVO {
private Long id;
/**
* 通知类型ID
*/
private Long notificationTypeId;
/**
* 通知类型名称
*/
private String notificationTypeName;
/**
* 通知标题
*/
private String title;
/**
* 通知对象类型1=全部2=手动选择
*/
private Integer targetType;
/**
* 通知对象类型名称
*/
private String targetTypeName;
/**
* 通知内容HTML格式
*/
private String content;
/**
* 状态1=草稿2=已发布
*/
private Integer status;
/**
* 状态名称
*/
private String statusName;
/**
* 启用状态1=启用2=禁用
*/
private Integer state;
/**
* 启用状态名称
*/
private String stateName;
/**
* 发布时间
*/
private LocalDateTime publishTime;
/**
* 创建人ID
*/
private Long createById;
/**
* 创建人姓名
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 最后更新人ID
*/
private Long updateById;
/**
* 最后更新人姓名
*/
private String updateBy;
/**
* 最后更新时间
*/
private LocalDateTime updateTime;
/**
* 通知用户列表仅详情返回
*/
private List<QmsQualityNotificationUserVO> users;
/**
* 附件列表
*/
private List<FileVO> attachments;
}

View File

@ -0,0 +1,93 @@
package com.nflg.wms.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 质量通知表
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
@TableName("qms_quality_notification")
public class QmsQualityNotification implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 通知类型ID关联dictionary_item表
*/
private Long notificationTypeId;
/**
* 通知标题
*/
private String title;
/**
* 通知对象类型1=全部2=手动选择
*/
private Integer targetType;
/**
* 通知内容HTML格式
*/
private String content;
/**
* 状态1=草稿2=已发布
*/
private Integer status;
/**
* 启用状态1=启用2=禁用
*/
private Integer state;
/**
* 发布时间
*/
private LocalDateTime publishTime;
/**
* 创建人ID
*/
private Long createById;
/**
* 创建人姓名
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 最后更新人ID
*/
private Long updateById;
/**
* 最后更新人姓名
*/
private String updateBy;
/**
* 最后更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,53 @@
package com.nflg.wms.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 通知用户关联表
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
@TableName("qms_quality_notification_user")
public class QmsQualityNotificationUser implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 通知ID
*/
private Long notificationId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建人ID
*/
private Long createById;
/**
* 创建人姓名
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@ -0,0 +1,16 @@
package com.nflg.wms.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationSearchQO;
import com.nflg.wms.common.pojo.vo.QmsQualityNotificationVO;
import com.nflg.wms.repository.entity.QmsQualityNotification;
/**
* 质量通知 Mapper 接口
*/
public interface QmsQualityNotificationMapper extends BaseMapper<QmsQualityNotification> {
IPage<QmsQualityNotificationVO> search(QmsQualityNotificationSearchQO request, Page<Object> page);
}

View File

@ -0,0 +1,11 @@
package com.nflg.wms.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nflg.wms.repository.entity.QmsQualityNotificationUser;
/**
* 通知用户关联 Mapper 接口
*/
public interface QmsQualityNotificationUserMapper extends BaseMapper<QmsQualityNotificationUser> {
}

View File

@ -0,0 +1,18 @@
package com.nflg.wms.repository.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.wms.common.pojo.qo.QmsQualityNotificationSearchQO;
import com.nflg.wms.common.pojo.vo.QmsQualityNotificationVO;
import com.nflg.wms.repository.entity.QmsQualityNotification;
/**
* 质量通知 服务类
*/
public interface IQmsQualityNotificationService extends IService<QmsQualityNotification> {
/**
* 分页查询质量通知列表
*/
IPage<QmsQualityNotificationVO> search(QmsQualityNotificationSearchQO request);
}

View File

@ -0,0 +1,11 @@
package com.nflg.wms.repository.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.wms.repository.entity.QmsQualityNotificationUser;
/**
* 通知用户关联 服务类
*/
public interface IQmsQualityNotificationUserService extends IService<QmsQualityNotificationUser> {
}

View File

@ -0,0 +1,23 @@
package com.nflg.wms.repository.service.impl;
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.nflg.wms.common.pojo.qo.QmsQualityNotificationSearchQO;
import com.nflg.wms.common.pojo.vo.QmsQualityNotificationVO;
import com.nflg.wms.repository.entity.QmsQualityNotification;
import com.nflg.wms.repository.mapper.QmsQualityNotificationMapper;
import com.nflg.wms.repository.service.IQmsQualityNotificationService;
import org.springframework.stereotype.Service;
/**
* 质量通知 服务实现类
*/
@Service
public class QmsQualityNotificationServiceImpl extends ServiceImpl<QmsQualityNotificationMapper, QmsQualityNotification> implements IQmsQualityNotificationService {
@Override
public IPage<QmsQualityNotificationVO> search(QmsQualityNotificationSearchQO request) {
return baseMapper.search(request, new Page<>(request.getPage(), request.getPageSize()));
}
}

View File

@ -0,0 +1,15 @@
package com.nflg.wms.repository.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.wms.repository.entity.QmsQualityNotificationUser;
import com.nflg.wms.repository.mapper.QmsQualityNotificationUserMapper;
import com.nflg.wms.repository.service.IQmsQualityNotificationUserService;
import org.springframework.stereotype.Service;
/**
* 通知用户关联 服务实现类
*/
@Service
public class QmsQualityNotificationUserServiceImpl extends ServiceImpl<QmsQualityNotificationUserMapper, QmsQualityNotificationUser> implements IQmsQualityNotificationUserService {
}

View File

@ -0,0 +1,46 @@
<?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.nflg.wms.repository.mapper.QmsQualityNotificationMapper">
<select id="search" resultType="com.nflg.wms.common.pojo.vo.QmsQualityNotificationVO">
SELECT q.id,
q.notification_type_id,
di.name as notification_type_name,
q.title,
q.target_type,
q.content,
q.status,
q.state,
q.publish_time,
q.create_by_id,
q.create_by,
q.create_time,
q.update_by_id,
q.update_by,
q.update_time
FROM qms_quality_notification q
LEFT JOIN dictionary_item di ON q.notification_type_id = di.id
<where>
<if test="request.title != null and request.title != ''">
AND q.title ilike concat('%', #{request.title}, '%')
</if>
<if test="request.notificationTypeId != null">
AND q.notification_type_id = #{request.notificationTypeId}
</if>
<if test="request.status != null">
AND q.status = #{request.status}
</if>
<if test="request.state != null">
AND q.state = #{request.state}
</if>
<if test="request.startDate != null">
AND q.create_time &gt;= #{request.startDate}
</if>
<if test="request.endDate != null">
AND q.create_time &lt;= #{request.endDate}
</if>
</where>
ORDER BY q.id DESC
</select>
</mapper>

View File

@ -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.nflg.wms.repository.mapper.QmsQualityNotificationUserMapper">
</mapper>