This commit is contained in:
那些花儿
2025-09-17 17:52:09 +08:00
parent 9821aebd0a
commit 3f40ee599e
59 changed files with 3697 additions and 4029 deletions
@@ -2,6 +2,7 @@ package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
@@ -11,8 +12,11 @@ import com.budwk.app.sys.enums.SysFileEngineTypeEnum;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.services.SysConfigService;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.google.common.net.HttpHeaders;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -23,19 +27,21 @@ import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
@IocBean
@At("/platform/sys/file")
@Ok("json:full")
@Api(tags = "文件管理")
@Slf4j
public class SysFileController {
@Inject
private SysFileService sysFileService;
@Inject
private SysConfigService sysConfigService;
private SysFileMinIoUtil sysFileMinIoUtil;
@At("")
@Ok("beetl:/platform/sys/file/index.html")
@@ -110,7 +116,7 @@ public class SysFileController {
@SaCheckLogin
@ApiOperation("文件管理-转换HTML")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result convertHtml(TempFile file){
public Result convertHtml(TempFile file) {
return Result.success().addData(sysFileService.convertHtml(file));
}
@@ -141,5 +147,64 @@ public class SysFileController {
return Result.success(files);
}
@At
@SaCheckLogin
@ApiOperation("文件管理-视频播放")
@Ok("void")
public void videoPlay(String id, HttpServletRequest request, HttpServletResponse response) {
Sys_file sys_file = sysFileService.detail(id);
byte[] bytes = SysFileMinIoUtil.getFileBytes(sys_file.getBucket(), sys_file.getStoragePath());
// 设置响应头
String fileName = sys_file.getName();
String contentType = null;
switch (FileUtil.extName(fileName).toLowerCase()) {
case "mp4" -> contentType = "video/mp4";
case "avi" -> contentType = "video/x-msvideo";
case "mkv" -> contentType = "video/x-matroska";
case "mov" -> contentType = "video/quicktime";
case "wmv" -> contentType = "video/x-ms-wmv";
default -> contentType = "application/octet-stream";
}
response.setContentType(contentType);
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
String rangeHeader = request.getHeader(HttpHeaders.RANGE);
if (StrUtil.isNotBlank(rangeHeader) && rangeHeader.startsWith("bytes=")) {
// 处理Range请求
String[] ranges = rangeHeader.substring(6).split("-");
long start = StrUtil.isNotBlank(ranges[0]) ? Long.parseLong(ranges[0]) : 0;
long end = (ranges.length > 1 && StrUtil.isNotBlank(ranges[1])) ?
Long.parseLong(ranges[1]) : bytes.length - 1;
if (start >= bytes.length || end >= bytes.length) {
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + bytes.length);
response.setStatus(416);
return;
}
int contentLength = (int) (end - start + 1);
response.setStatus(206);
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
response.setHeader(HttpHeaders.CONTENT_RANGE, StrUtil.format("bytes {}-{}/{}", start, end, bytes.length));
try (OutputStream out = response.getOutputStream()) {
out.write(bytes, (int) start, contentLength);
} catch (IOException e) {
log.error("视频播放失败", e);
}
} else {
// 非Range请求
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(bytes.length));
try (OutputStream out = response.getOutputStream()) {
out.write(bytes);
} catch (IOException e) {
log.error("视频播放失败", e);
}
}
}
}
@@ -70,7 +70,7 @@ public class SysHomeController {
String userAgentStr = req.getHeader("User-Agent");
UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
if (!userAgent.isMobile()) {
return "beetl:/platform/sys/home/index.html";
return "beetl:/layouts/v4/home.html";
} else {
return "beetl:/platform/zhghh5/sys/home/index.html";
}
@@ -222,86 +222,6 @@ public class SysHomeController {
// return Result.success(hasPermisiionList);
}
@At
@SaCheckLogin
@ApiOperation("待办列表")
@Ok("json")
public Result listTodo(@Valid PageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
task.id,
inst.processInstanceName,
inst.processInstanceInitiatorName,
inst.processInstanceNodeName,
task.formUrl AS taskFormUrl,
task.formMobileUrl AS taskFormMobileUrl
FROM
`bpm_process_task` task
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId
WHERE
JSON_CONTAINS( task.assignments, @loginName )
AND task.taskStatus = 'ACTIVE'
GROUP BY
task.id
ORDER BY
task.createdOn DESC
""");
sql.setParam("loginName", "\"" + SecurityUtil.getUserLoginname() + "\"");
Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckLogin
@ApiOperation("已办列表")
@Ok("json")
public Result listDone(@Valid PageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
task.id,
inst.processInstanceName,
inst.processInstanceInitiatorName,
inst.processInstanceNodeName,
task.formUrl AS taskFormUrl,
task.formMobileUrl AS taskFormMobileUrl
FROM
`bpm_process_task` task
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId
WHERE
JSON_CONTAINS( task.assignments, @loginName )
AND task.taskStatus in ('COMPLETE','TRANSFER')
GROUP BY
task.id
ORDER BY
task.createdOn DESC
""");
sql.setParam("loginName", "\"" + SecurityUtil.getUserLoginname() + "\"");
Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckLogin
@ApiOperation("我的发起")
@Ok("json")
public Result listMyInitiation(@Valid PageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
id,
processInstanceName,
processInstanceInitiatorName,
processInstanceNodeName,
processInstanceUrl
FROM
bpm_process_instance
WHERE
processInstanceInitiatorLoginName = @loginName
ORDER BY processInstanceInitiationTime DESC
""");
sql.setParam("loginName", SecurityUtil.getUserLoginname());
Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckLogin
@@ -2,6 +2,7 @@ package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.budwk.app.sys.services.SysUserService;
import io.swagger.annotations.Api;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -13,6 +14,7 @@ import javax.servlet.http.HttpServletRequest;
@IocBean
@At("/platform/v4")
@Api(value = "V4首页")
public class SysHomeV4Controller {
@Inject
@@ -27,9 +29,6 @@ public class SysHomeV4Controller {
}
/**
* 首页门户
*/
@At("/home")
@Ok("beetl:/layouts/v4/home.html")
@SaCheckLogin
@@ -37,13 +36,6 @@ public class SysHomeV4Controller {
}
@At("/home2")
@Ok("beetl:/layouts/v4/home2.html")
@SaCheckLogin
public void home2() {
}
/**
* 应用中心
*/
@@ -64,6 +56,27 @@ public class SysHomeV4Controller {
}
/**
* 待办中心
*/
@At("/todo")
@Ok("beetl:/layouts/v4/todo.html")
@SaCheckLogin
public void todo(){
}
/**
* 消息中心
*/
@At("/msg")
@Ok("beetl:/layouts/v4/msg.html")
@SaCheckLogin
public void msg(){
}
/**
* 子系统
* @param appId 应用ID
@@ -2,6 +2,7 @@ package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
@@ -339,7 +340,11 @@ public class SysUserController {
@SaCheckLogin
public Result subAppMenus(@Param("appId") String appId) {
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
List<Sys_menu> list = Sys_menu.createTreeMenus(menus, appId);
List<Sys_menu> list = SysMenuUtil.createTreeMenus(menus, appId);
if (ObjectUtil.isEmpty(list)) {
List<Sys_menu> self = menus.stream().filter(menu -> menu.getId().equals(appId)).toList();
return Result.success().addData(self);
}
return Result.success(list);
}
@@ -0,0 +1,166 @@
package com.budwk.app.sys.controller.v4;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.message.models.GlobalMessage;
import com.budwk.app.zhgh.dayofficework.message.models.GlobalMessageReceiver;
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageSendService;
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@IocBean
@At("/platform/v4/msg")
@Api(value = "消息中心", tags = "消息中心接口")
@Ok("json:full")
public class SysV4MsgController {
@Inject
private Dao dao;
@Inject
private GlobalMessageService globalMessageService;
@Inject
private GlobalMessageSendService globalMessageSendService;
@At
@ApiOperation("获取消息列表")
@SaCheckLogin
public Result pageData(PageForm pageForm, @Param("isRead") int isRead, @Param("type") Integer type, HttpServletRequest req) {
Sql sql = Sqls.create("""
SELECT
m.id,
m.title,
m.content,
m.type,
r.isRead,
r.readTime
FROM
global_message m
INNER JOIN global_message_receiver r ON m.id = r.messageId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("m.status", "=", 2);
cnd.and("r.receiverId", "=", SecurityUtil.getUserId());
if (isRead == 0) {
cnd.and("r.isRead", "=", 0);
} else if (isRead == 1) {
cnd.and("r.isRead", "=", 1);
}
cnd.andEX("m.type", "=", type);
cnd.desc("m.sendTime");
sql.setCondition(cnd);
String title = "审批待办";
String content = "您有一个新的审批任务需要处理,请及时登录系统查看。";
List<String> receiverIds = Arrays.asList("17a7f8ad3ee947b4a26175049a9c253d");
// 自动发送到所有启用的渠道
// globalMessageSendService.sendMessage(title, content, 2, receiverIds, null);
Pagination pagination = globalMessageService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At("/stats")
@ApiOperation("获取消息统计信息")
@SaCheckLogin
public Result getStats() {
List<GlobalMessage> messageList = dao.query(GlobalMessage.class, Cnd.where(GlobalMessage::getStatus, "=", 2));
List<String> messageIds = messageList.stream().map(GlobalMessage::getId).toList();
// 查询总数
int totalCount = dao.count(GlobalMessageReceiver.class, Cnd.where(GlobalMessageReceiver::getReceiverId, "=", SecurityUtil.getUserId()).and(GlobalMessageReceiver::getMessageId, "in", messageIds));
// 查询未读数
int unreadCount = dao.count(GlobalMessageReceiver.class, Cnd.where(GlobalMessageReceiver::getReceiverId, "=", SecurityUtil.getUserId()).and(GlobalMessageReceiver::getIsRead, "=", 0).and(GlobalMessageReceiver::getMessageId, "in", messageIds));
// 查询已读数
int readCount = totalCount - unreadCount;
NutMap stats = NutMap.NEW()
.addv("total", totalCount)
.addv("unread", unreadCount)
.addv("read", readCount);
// .addv("typeStats", typeStats);
return Result.success(stats);
}
@At("/detail/?")
@ApiOperation("获取消息详情")
@SaCheckLogin
public Result getDetail(String messageId) {
GlobalMessageReceiver receiver = dao.fetch(GlobalMessageReceiver.class, Cnd.where(GlobalMessageReceiver::getMessageId, "=", messageId).and(GlobalMessageReceiver::getReceiverId, "=", SecurityUtil.getUserId()));
dao.fetchLinks(receiver, "globalMessage");
// 标记为已读
if (receiver != null && !receiver.getIsRead()) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
dao.update(receiver);
}
return Result.success(receiver);
}
@At("/read/?")
@ApiOperation("标记消息为已读")
public Result markAsRead(String messageId) {
GlobalMessageReceiver receiver = dao.fetch(GlobalMessageReceiver.class, Cnd.where("messageId", "=", messageId).and("receiverId", "=", SecurityUtil.getUserId()));
if (receiver != null && !receiver.getIsRead()) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
dao.update(receiver);
}
return Result.success();
}
@At("/read/batch")
@ApiOperation("批量标记消息为已读")
@SaCheckLogin
public Result batchMarkAsRead(@Param("messageIds") String[] messageIds) {
List<GlobalMessageReceiver> receivers = dao.query(GlobalMessageReceiver.class, Cnd.where("messageId", "in", messageIds).and("receiverId", "=", SecurityUtil.getUserId()));
for (GlobalMessageReceiver receiver : receivers) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
}
dao.update(receivers);
return Result.success();
}
@At("/read/all")
@ApiOperation("标记所有消息为已读")
@SaCheckLogin
public Result markAllAsRead() {
List<GlobalMessageReceiver> receivers = dao.query(GlobalMessageReceiver.class, Cnd.where("receiverId", "=", SecurityUtil.getUserId()));
for (GlobalMessageReceiver receiver : receivers) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
}
dao.update(receivers);
return Result.success();
}
}
@@ -132,21 +132,4 @@ public class Sys_menu extends BaseModel implements Serializable {
//子菜单
private List<Sys_menu> children = new ArrayList<>();
/**
* 前端菜单数据
*
* @param menus
* @param parentId
* @return
*/
public static List<Sys_menu> createTreeMenus(List<Sys_menu> menus, String parentId) {
List<Sys_menu> filterMenus = menus.stream().filter(v -> StringUtils.defaultString(v.getParentId(), "").equals(StringUtils.defaultString(parentId, ""))).collect(Collectors.toList());
for (Sys_menu menu : filterMenus) {
List<Sys_menu> childMenus = createTreeMenus(menus, menu.getId());
menu.setChildren(childMenus);
}
return new ArrayList<>(filterMenus);
}
}
@@ -147,7 +147,7 @@ public class SysFileServiceImpl extends BaseServiceImpl<Sys_file> implements Sys
@Override
public Sys_file detail(String id) {
return null;
return fetch(id);
}
@Override
@@ -181,13 +181,13 @@ public class SysFileServiceImpl extends BaseServiceImpl<Sys_file> implements Sys
String[] parts = srcValue.split(";base64,");
String base64Content = parts[1];
try{
try {
//转为在线地址 base64很喜欢被信息中心拦截
byte[] imageBytes = Base64.getDecoder().decode(base64Content);
String imgUrl = storageFile(SysFileEngineTypeEnum.MINIO.getValue(), genFileKey(R.UU32(), R.UU32() + ".png"), imageBytes, false);
String replacement = "<img src=\"" + imgUrl + "\">";
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}catch (Exception e){
} catch (Exception e) {
matcher.appendReplacement(sb, Matcher.quoteReplacement("<img src=>"));
}
}
@@ -13,6 +13,7 @@ import com.budwk.app.base.exception.UnknownAccountException;
import com.budwk.app.base.interceptor.sLog.SLogService;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.PwdUtil;
import com.budwk.app.base.utils.SysMenuUtil;
import com.budwk.app.sys.models.*;
import com.budwk.app.sys.services.SysMenuService;
import com.budwk.app.sys.services.SysRoleService;
@@ -126,27 +127,27 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
List<Sys_module> userModules = dao().query(Sys_module.class, Cnd.where("id", "in", allModuleIds.toArray()).asc(Sys_module::getSortNum));
//设置pc菜单到模块
if (Lang.isNotEmpty(pcModuleIds)) {
//用户的pc端模块
List<Sys_module> pcModules = userModules.stream().filter(module -> pcModuleIds.contains(module.getId())).toList();
//pc菜单转为树结构
List<Sys_menu> pcTreeMenus = Sys_menu.createTreeMenus(pcMenus, null);
for (Sys_module pcModule : pcModules) {
pcModule.setMenus(pcTreeMenus.stream().filter(menu -> menu.getModuleId().equals(pcModule.getId())).collect(Collectors.toList()));
}
user.setPcModuleMenus(pcModules);
}
//设置h5菜单到模块
if (Lang.isNotEmpty(h5ModuleIds)) {
//用户的h5端模块
List<Sys_module> h5Modules = userModules.stream().filter(module -> h5ModuleIds.contains(module.getId())).toList();
List<Sys_menu> h5TreeMenus = Sys_menu.createTreeMenus(h5Menus, null);
for (Sys_module h5Module : h5Modules) {
h5Module.setMenus(h5TreeMenus.stream().filter(menu -> menu.getModuleId().equals(h5Module.getId())).collect(Collectors.toList()));
}
user.setH5ModuleMenus(h5Modules);
}
// if (Lang.isNotEmpty(pcModuleIds)) {
// //用户的pc端模块
// List<Sys_module> pcModules = userModules.stream().filter(module -> pcModuleIds.contains(module.getId())).toList();
// //pc菜单转为树结构
// List<Sys_menu> pcTreeMenus = SysMenuUtil.createTreeMenus(pcMenus, null);
// for (Sys_module pcModule : pcModules) {
// pcModule.setMenus(pcTreeMenus.stream().filter(menu -> menu.getModuleId().equals(pcModule.getId())).collect(Collectors.toList()));
// }
// user.setPcModuleMenus(pcModules);
// }
//
// //设置h5菜单到模块
// if (Lang.isNotEmpty(h5ModuleIds)) {
// //用户的h5端模块
// List<Sys_module> h5Modules = userModules.stream().filter(module -> h5ModuleIds.contains(module.getId())).toList();
// List<Sys_menu> h5TreeMenus = SysMenuUtil.createTreeMenus(h5Menus, null);
// for (Sys_module h5Module : h5Modules) {
// h5Module.setMenus(h5TreeMenus.stream().filter(menu -> menu.getModuleId().equals(h5Module.getId())).collect(Collectors.toList()));
// }
// user.setH5ModuleMenus(h5Modules);
// }
return user;
}