主席信箱

This commit is contained in:
=
2026-04-21 15:27:15 +08:00
parent c98c309d82
commit 83f84d78d9
17 changed files with 2668 additions and 0 deletions
@@ -0,0 +1,30 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.chairmanMailbox.models.ChairmanMailbox;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
@IocBean
@At("/platform/chairmanMailbox/common")
@Ok("json:full")
@Api("主席信箱公共接口")
public class ChairmanMailboxCommonController {
@Inject
private Dao dao;
@At
@SaCheckLogin
@ApiOperation("获取详情")
public Result info(@Param("id") String id) {
return Result.success(dao.fetch(ChairmanMailbox.class, id));
}
}
@@ -0,0 +1,20 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import io.swagger.annotations.Api;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@IocBean
@At("/platform/chairmanMailbox")
@Api("主席信箱入口")
public class ChairmanMailboxIndexController {
@At("/h5")
@Ok("beetl:/platform/zhghh5/democratic/chairmanMailbox/index.html")
@SaCheckLogin
public void h5() {
}
}
@@ -0,0 +1,53 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.chairmanMailbox.service.ChairmanMailboxService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
@IocBean
@At("/platform/chairmanMailbox/mine")
@Ok("json:full")
@Api("主席信箱-我的")
public class ChairmanMailboxMineController {
@Inject
private ChairmanMailboxService chairmanMailboxService;
@At("")
@Ok("beetl:/platform/zhgh/democratic/chairmanMailbox/mine/index.html")
@SaCheckPermission("chairmanMailbox.mine")
public void index() {
}
@At
@Ok("beetl:/platform/zhghh5/democratic/chairmanMailbox/mine/index.html")
@SaCheckPermission("h5.chairmanMailbox")
public void h5() {
}
@At
@SaCheckPermission(value = {"chairmanMailbox.mine", "h5.chairmanMailbox"}, mode = SaMode.OR)
public Result pageData(Integer pageNumber, Integer pageSize, String searchKeyword) {
return Result.success(chairmanMailboxService.pageMyData(pageNumber, pageSize, searchKeyword));
}
@At
@SaCheckPermission(value = {"chairmanMailbox.mine", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("删除")
@SLog(tag = "主席信箱-我的", msg = "删除")
public Result delete(@Param("id") String id) {
chairmanMailboxService.delete(id);
return Result.success();
}
}
@@ -0,0 +1,70 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.chairmanMailbox.models.ChairmanMailbox;
import com.budwk.app.zhgh.democratic.chairmanMailbox.service.ChairmanMailboxService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
@IocBean
@At("/platform/chairmanMailbox/query")
@Ok("json:full")
@Api("主席信箱管理")
public class ChairmanMailboxQueryController {
@Inject
private ChairmanMailboxService chairmanMailboxService;
@At("")
@Ok("beetl:/platform/zhgh/democratic/chairmanMailbox/query/index.html")
@SaCheckPermission("chairmanMailbox.query")
public void index() {
}
@At
@Ok("beetl:/platform/zhghh5/democratic/chairmanMailbox/query/index.html")
@SaCheckPermission("h5.chairmanMailbox")
public void h5() {
}
@At
@SaCheckPermission(value = {"chairmanMailbox.query", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("分页查询")
public Result pageData(Integer pageNumber, Integer pageSize, String searchKeyword, Integer isReply, String timeRange) {
return Result.success(chairmanMailboxService.pageQueryData(pageNumber, pageSize, searchKeyword, isReply, timeRange));
}
@At
@SaCheckPermission(value = {"chairmanMailbox.query", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("统计数据")
public Result getStats() {
return Result.success(chairmanMailboxService.getQueryStats());
}
@At
@SaCheckPermission(value = {"chairmanMailbox.query", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("回复信件")
@SLog(tag = "主席信箱-管理", msg = "回复信件")
public Result reply(@Param("data") ChairmanMailbox mailbox) {
chairmanMailboxService.reply(mailbox);
return Result.success();
}
@At
@SaCheckPermission(value = {"chairmanMailbox.query", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("删除")
public Result delete(@Param("id") String id) {
chairmanMailboxService.delete(id);
return Result.success();
}
}
@@ -0,0 +1,74 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.chairmanMailbox.models.ChairmanMailbox;
import com.budwk.app.zhgh.democratic.chairmanMailbox.service.ChairmanMailboxService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
@IocBean
@At("/platform/chairmanMailbox/write")
@Ok("json:full")
@Api("主席信箱填写")
public class ChairmanMailboxWriteController {
@Inject
private Dao dao;
@Inject
private ChairmanMailboxService chairmanMailboxService;
@At("")
@Ok("beetl:/platform/zhgh/democratic/chairmanMailbox/write/index.html")
@SaCheckPermission("chairmanMailbox.write")
public void index() {
}
@At
@Ok("beetl:/platform/zhghh5/democratic/chairmanMailbox/write/index.html")
@SaCheckPermission("h5.chairmanMailbox")
public void h5() {
}
@At
@SaCheckPermission(value = {"chairmanMailbox.write", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("获取当前登录人默认信息")
public Result currentUserInfo() {
return Result.success(chairmanMailboxService.getCurrentUserMailboxInfo());
}
@At
@SaCheckPermission(value = {"chairmanMailbox.write", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("保存草稿")
@SLog(tag = "主席信箱-填写", msg = "保存草稿")
public Result save(@Param("data") ChairmanMailbox mailbox) {
dao.insertOrUpdate(chairmanMailboxService.prepareSubmissionData(mailbox, 0));
return Result.success();
}
@At
@SaCheckPermission(value = {"chairmanMailbox.write", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("提交")
@SLog(tag = "主席信箱-填写", msg = "提交")
public Result submit(@Param("data") ChairmanMailbox mailbox) {
dao.insertOrUpdate(chairmanMailboxService.prepareSubmissionData(mailbox, 1));
return Result.success();
}
@At
@SaCheckPermission(value = {"chairmanMailbox.write", "h5.chairmanMailbox"}, mode = SaMode.OR)
@ApiOperation("获取详情")
public Result info(@Param("id") String id) {
return Result.success(dao.fetch(ChairmanMailbox.class, id));
}
}
@@ -0,0 +1,124 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.models;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.ColType;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Default;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.entity.annotation.TableMeta;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Table("chairman_mailbox")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("主席信箱")
@Data
public class ChairmanMailbox extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("提交人ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("提交人姓名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String userName;
@Column
@Comment("提交人工号")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String loginName;
@Column
@Comment("提交人单位ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitId;
@Column
@Comment("提交人单位名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unitName;
@Column
@Comment("提交人工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("提交人工会名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unionName;
@Column
@Comment("提交时间")
@ColDefine(type = ColType.DATETIME)
private Date submitTime;
@Column
@Comment("标题")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String title;
@Column
@Comment("内容")
@ColDefine(type = ColType.TEXT)
private String content;
@Column
@Comment("联系方式")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String concat;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> attachments;
@Column
@Comment("状态 0草稿 1已提交")
@ColDefine(type = ColType.INT)
@Default("1")
private Integer status;
@Column
@Comment("是否回复")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isReply;
@Column
@Comment("回复内容")
@ColDefine(type = ColType.TEXT)
private String replyContent;
@Column
@Comment("回复时间")
@ColDefine(type = ColType.DATETIME)
private Date replyTime;
@Column
@Comment("回复人ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String replyUserId;
@Column
@Comment("回复人姓名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String replyUserName;
}
@@ -0,0 +1,64 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.democratic.chairmanMailbox.models.ChairmanMailbox;
import org.nutz.lang.util.NutMap;
public interface ChairmanMailboxService extends BaseService<ChairmanMailbox> {
/**
* 获取当前登录人的默认写信信息,统一回显姓名、工号、单位、工会和联系方式。
*
* @return 当前登录人的默认写信信息
*/
ChairmanMailbox getCurrentUserMailboxInfo();
/**
* 组装信箱提交数据,统一补齐当前登录人信息、提交时间和提交状态。
*
* @param mailbox 信件数据
* @param status 状态,0表示草稿,1表示已提交
* @return 处理后的信件数据
*/
ChairmanMailbox prepareSubmissionData(ChairmanMailbox mailbox, int status);
/**
* 查询当前登录人已提交的信箱数据。
*
* @param pageNumber 页码
* @param pageSize 每页条数
* @param searchKeyword 关键字
* @return 分页数据
*/
Pagination<NutMap> pageMyData(Integer pageNumber, Integer pageSize, String searchKeyword);
/**
* 查询信箱管理列表。
*
* @param pageNumber 页码
* @param pageSize 每页条数
* @param searchKeyword 关键字
* @param isReply 回复状态
* @param timeRange 时间范围
* @return 分页数据
*/
Pagination<NutMap> pageQueryData(Integer pageNumber,
Integer pageSize,
String searchKeyword,
Integer isReply,
String timeRange);
/**
* 获取信箱管理统计数据。
*
* @return 统计结果
*/
NutMap getQueryStats();
/**
* 回复主席信箱。
*
* @param mailbox 回复内容
*/
void reply(ChairmanMailbox mailbox);
}
@@ -0,0 +1,161 @@
package com.budwk.app.zhgh.democratic.chairmanMailbox.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.democratic.chairmanMailbox.models.ChairmanMailbox;
import com.budwk.app.zhgh.democratic.chairmanMailbox.service.ChairmanMailboxService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.Date;
@IocBean(args = {"refer:dao"})
public class ChairmanMailboxServiceImpl extends BaseServiceImpl<ChairmanMailbox> implements ChairmanMailboxService {
public ChairmanMailboxServiceImpl(Dao dao) {
super(dao);
}
@Override
public ChairmanMailbox getCurrentUserMailboxInfo() {
ChairmanMailbox mailbox = new ChairmanMailbox();
View_user loginUser = dao().fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
if (loginUser != null) {
mailbox.setUserId(loginUser.getId());
mailbox.setUserName(loginUser.getUsername());
mailbox.setLoginName(loginUser.getLoginname());
mailbox.setUnitId(loginUser.getUnitId());
mailbox.setUnitName(loginUser.getUnitName());
mailbox.setUnionId(loginUser.getUnionId());
mailbox.setUnionName(loginUser.getUnionName());
mailbox.setConcat(loginUser.getMobile());
}
mailbox.setAttachments(null);
return mailbox;
}
@Override
public ChairmanMailbox prepareSubmissionData(ChairmanMailbox mailbox, int status) {
ChairmanMailbox result = ObjectUtil.defaultIfNull(mailbox, new ChairmanMailbox());
View_user loginUser = dao().fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
if (loginUser != null) {
result.setUserId(loginUser.getId());
result.setUserName(loginUser.getUsername());
result.setLoginName(loginUser.getLoginname());
result.setUnitId(loginUser.getUnitId());
result.setUnitName(loginUser.getUnitName());
result.setUnionId(loginUser.getUnionId());
result.setUnionName(loginUser.getUnionName());
if (StrUtil.isBlank(result.getConcat())) {
result.setConcat(loginUser.getMobile());
}
}
if (result.getSubmitTime() == null) {
result.setSubmitTime(new Date());
}
if (result.getIsReply() == null) {
result.setIsReply(false);
}
result.setStatus(status);
return result;
}
@Override
public Pagination<NutMap> pageMyData(Integer pageNumber, Integer pageSize, String searchKeyword) {
Sql sql = Sqls.create("""
SELECT id, title, content, userName, loginName, unitName, unionName, concat, submitTime, isReply, replyTime
FROM chairman_mailbox
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("createdBy", "=", SecurityUtil.getUserId());
cnd.and("status", "=", 1);
if (StrUtil.isNotBlank(searchKeyword)) {
cnd.where().andLike("title", searchKeyword);
}
cnd.desc("submitTime");
sql.setCondition(cnd);
return listPageMap(pageNumber, pageSize, sql);
}
@Override
public Pagination<NutMap> pageQueryData(Integer pageNumber,
Integer pageSize,
String searchKeyword,
Integer isReply,
String timeRange) {
Sql sql = Sqls.create("""
SELECT id, title, content, userName, loginName, unitName, unionName, concat, submitTime, isReply, replyTime, replyUserName
FROM chairman_mailbox
$condition
""");
Cnd cnd = buildQueryCondition(searchKeyword, isReply, timeRange);
cnd.desc("submitTime");
sql.setCondition(cnd);
return listPageMap(pageNumber, pageSize, sql);
}
@Override
public NutMap getQueryStats() {
return NutMap.NEW()
.addv("total", dao().count(ChairmanMailbox.class, buildQueryCondition(null, null, null)))
.addv("pending", dao().count(ChairmanMailbox.class, buildQueryCondition(null, 0, null)))
.addv("replied", dao().count(ChairmanMailbox.class, buildQueryCondition(null, 1, null)))
.addv("today", dao().count(ChairmanMailbox.class, buildQueryCondition(null, null, "today")));
}
@Override
public void reply(ChairmanMailbox mailbox) {
if (mailbox == null || StrUtil.isBlank(mailbox.getId())) {
return;
}
ChairmanMailbox data = dao().fetch(ChairmanMailbox.class, mailbox.getId());
if (data == null) {
return;
}
View_user loginUser = dao().fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
data.setIsReply(true);
data.setReplyContent(mailbox.getReplyContent());
data.setReplyTime(new Date());
data.setReplyUserId(SecurityUtil.getUserId());
if (loginUser != null) {
data.setReplyUserName(loginUser.getUsername());
}
dao().updateIgnoreNull(data);
}
/**
* 统一构建信箱管理查询条件,保证手机端和PC端逻辑一致。
*/
private Cnd buildQueryCondition(String searchKeyword, Integer isReply, String timeRange) {
Cnd cnd = Cnd.NEW();
cnd.and("status", "=", 1);
if (StrUtil.isNotBlank(searchKeyword)) {
cnd.and(new org.nutz.dao.util.cri.SqlExpressionGroup()
.orLike("title", searchKeyword)
.orLike("content", searchKeyword)
.orLike("userName", searchKeyword));
}
if (isReply != null) {
cnd.and("isReply", "=", isReply == 1);
}
if (StrUtil.isNotBlank(timeRange)) {
if ("today".equals(timeRange)) {
cnd.and(new Static("DATE(submitTime) = CURDATE()"));
} else if ("week".equals(timeRange)) {
cnd.and(new Static("YEARWEEK(submitTime, 1) = YEARWEEK(CURDATE(), 1)"));
} else if ("month".equals(timeRange)) {
cnd.and(new Static("DATE_FORMAT(submitTime, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')"));
}
}
return cnd;
}
}