新增版本更新通知

This commit is contained in:
miguannan
2026-05-08 14:27:56 +08:00
parent ad95f612a0
commit ea5c4cef7b
9 changed files with 630 additions and 85 deletions

View File

@@ -0,0 +1,19 @@
package org.nl.extInterface.wms.service.dto;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
@Data
public class CreateTaskRequest {
private String houseCode;
private String systemCode;
private JSONObject parameters;
private String taskCode;
private String taskType;
private String taskCreateDateTime;
private String containerCode;
private String containerType;
private String locationFrom;
private String locationTo;
private Integer priority;
}

View File

@@ -0,0 +1,89 @@
package org.nl.system.controller.notice;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.domain.query.PageQuery;
import org.nl.system.service.notice.IVersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* 版本更新通知控制器
*
* @author miguannan
* @date 2026-05-06
*/
@Slf4j
@RestController
@RequestMapping("/api/version")
public class VersionController {
@Autowired
private IVersionService versionService;
/**
* 发布版本更新通知
*
* @param json 版本信息
* @return ResponseEntity
*/
@PostMapping("/release")
@SaCheckPermission("version:release")
public ResponseEntity<Object> release(@RequestBody JSONObject json) {
versionService.releaseVersion(json);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 获取当前版本信息(供前端轮询)
*
* @return 版本信息
*/
@GetMapping("/current")
@SaIgnore
public ResponseEntity<Object> current() {
return new ResponseEntity<>(versionService.getCurrentVersion(), HttpStatus.OK);
}
/**
* 查询版本通知列表
*
* @param pageQuery 分页参数
* @return 版本通知分页数据
*/
@GetMapping("/list")
@SaCheckPermission("version:list")
public ResponseEntity<Object> list(PageQuery pageQuery) {
return new ResponseEntity<>(versionService.listVersions(pageQuery), HttpStatus.OK);
}
/**
* 修改版本通知
*
* @param json 通知信息id, title, content
* @return ResponseEntity
*/
@PutMapping("/update")
@SaCheckPermission("version:edit")
public ResponseEntity<Object> update(@RequestBody JSONObject json) {
versionService.updateVersion(json);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* 删除版本通知
*
* @param id 通知ID
* @return ResponseEntity
*/
@DeleteMapping("/delete/{id}")
@SaCheckPermission("version:del")
public ResponseEntity<Object> delete(@PathVariable String id) {
versionService.deleteVersion(id);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,53 @@
package org.nl.system.service.notice;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.nl.common.domain.query.PageQuery;
import org.nl.system.service.notice.dao.SysNotice;
import java.util.Map;
/**
* 版本更新通知服务接口
*
* @author miguannan
* @date 2026-05-06
*/
public interface IVersionService {
/**
* 发布版本更新通知
*
* @param json 版本信息version, title, content
*/
void releaseVersion(JSONObject json);
/**
* 获取当前版本信息
*
* @return 包含 version、enabled、pollInterval、releaseTime 的 Map
*/
Map<String, Object> getCurrentVersion();
/**
* 查询版本通知列表
*
* @param pageQuery 分页参数
* @return 版本通知分页数据
*/
IPage<SysNotice> listVersions(PageQuery pageQuery);
/**
* 修改版本通知
*
* @param json 通知信息id, title, content
*/
void updateVersion(JSONObject json);
/**
* 删除版本通知
*
* @param id 通知ID
*/
void deleteVersion(String id);
}

View File

@@ -0,0 +1,187 @@
package org.nl.system.service.notice.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
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.extension.plugins.pagination.Page;
import org.nl.common.domain.query.PageQuery;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.enums.NoticeEnum;
import org.nl.common.exception.BadRequestException;
import org.nl.common.mnt.websocket.MsgType;
import org.nl.common.mnt.websocket.SocketMsg;
import org.nl.common.mnt.websocket.WebSocketServer;
import org.nl.system.service.notice.ISysNoticeService;
import org.nl.system.service.notice.IVersionService;
import org.nl.system.service.notice.dao.SysNotice;
import org.nl.system.service.notice.dao.mapper.SysNoticeMapper;
import org.nl.system.service.param.ISysParamService;
import org.nl.system.service.param.dao.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 版本更新通知服务实现
*
* @author miguannan
* @date 2026-05-06
*/
@Slf4j
@Service
public class VersionServiceImpl implements IVersionService {
@Autowired
private ISysNoticeService noticeService;
@Autowired
private ISysParamService paramService;
@Autowired
private SysNoticeMapper noticeMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void releaseVersion(JSONObject json) {
String version = json.getString("version");
String title = json.getString("title");
String content = json.getString("content");
if (StrUtil.isBlank(version)) {
throw new BadRequestException("版本号不能为空");
}
if (StrUtil.isBlank(title)) {
throw new BadRequestException("标题不能为空");
}
// 检查是否已有相同版本的未读通知,避免重复发布
long count = noticeMapper.selectCount(new LambdaQueryWrapper<SysNotice>()
.eq(SysNotice::getNotice_type, "version_update")
.likeRight(SysNotice::getNotice_title, version + " "));
if (count > 0) {
throw new BadRequestException("已存在相同版本发布信息,请先处理后再发布");
}
// 1. 创建通知记录
noticeService.createNotice(content, version + " " + title, "version_update");
// 2. 更新系统版本号
Param appVersionParam = paramService.findByCode("app_version");
if (appVersionParam == null) {
throw new BadRequestException("系统参数 app_version 不存在,请先执行初始化脚本");
}
appVersionParam.setValue(version);
paramService.update(appVersionParam);
// 3. WebSocket 广播给所有在线用户
JSONObject msgData = new JSONObject();
msgData.put("data", "version_update");
msgData.put("version", version);
msgData.put("title", title);
SocketMsg socketMsg = new SocketMsg(msgData, MsgType.INFO);
try {
WebSocketServer.sendInfo(socketMsg, null);
} catch (IOException e) {
log.error("版本更新WebSocket广播失败", e);
}
}
@Override
public Map<String, Object> getCurrentVersion() {
Map<String, Object> result = new HashMap<>();
// 当前版本号
Param appVersionParam = paramService.findByCode("app_version");
String version = (appVersionParam != null) ? appVersionParam.getValue() : "1.0.0";
// 功能开关
Param enabledParam = paramService.findByCode("version_notify_enabled");
boolean enabled = (enabledParam == null) || "true".equals(enabledParam.getValue());
// 轮询间隔
Param intervalParam = paramService.findByCode("version_notify_poll_interval");
int pollInterval = 30;
if (intervalParam != null && StrUtil.isNotBlank(intervalParam.getValue())) {
try {
pollInterval = Integer.parseInt(intervalParam.getValue());
} catch (NumberFormatException e) {
log.warn("version_notify_poll_interval 值非法: {}", intervalParam.getValue());
}
}
result.put("version", version);
result.put("enabled", enabled);
result.put("pollInterval", pollInterval);
// 最新版本通知的发布时间
SysNotice latest = noticeMapper.selectOne(new QueryWrapper<SysNotice>()
.eq("notice_type", "version_update")
.orderByDesc("create_time")
.last("LIMIT 1"));
if (latest != null) {
result.put("releaseTime", latest.getCreate_time());
// notice_title 存储格式为 "version title",分离出版本号和标题
String noticeTitle = latest.getNotice_title();
if (StrUtil.isNotBlank(noticeTitle) && noticeTitle.startsWith(version + " ")) {
result.put("title", noticeTitle.substring(version.length() + 1));
} else {
result.put("title", noticeTitle);
}
result.put("content", latest.getNotice_content());
}
return result;
}
@Override
public IPage<SysNotice> listVersions(PageQuery pageQuery) {
LambdaQueryWrapper<SysNotice> lam = new LambdaQueryWrapper<>();
lam.eq(SysNotice::getNotice_type, "version_update")
.orderByDesc(SysNotice::getCreate_time);
IPage<SysNotice> pages = new Page<>(pageQuery.getPage() + 1, pageQuery.getSize());
noticeMapper.selectPage(pages, lam);
return pages;
}
@Override
public void updateVersion(JSONObject json) {
String id = json.getString("id");
String title = json.getString("title");
String content = json.getString("content");
if (StrUtil.isBlank(id)) {
throw new BadRequestException("ID不能为空");
}
if (StrUtil.isBlank(title)) {
throw new BadRequestException("标题不能为空");
}
SysNotice notice = noticeMapper.selectById(id);
if (notice == null || !"version_update".equals(notice.getNotice_type())) {
throw new BadRequestException("版本通知不存在");
}
notice.setNotice_title(title);
notice.setNotice_content(content);
noticeMapper.updateById(notice);
}
@Override
public void deleteVersion(String id) {
if (StrUtil.isBlank(id)) {
throw new BadRequestException("ID不能为空");
}
SysNotice notice = noticeMapper.selectById(id);
if (notice == null || !"version_update".equals(notice.getNotice_type())) {
throw new BadRequestException("版本通知不存在");
}
noticeMapper.deleteById(id);
}
}