Merge remote-tracking branch 'refs/remotes/origin/feature_主分支合并UI优化' into feature_教代会代表证
# Conflicts: # src/main/java/com/budwk/app/sys/controller/SysConfController.java
This commit is contained in:
@@ -12,6 +12,8 @@ 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.SqlExpressionGroup;
|
||||
import org.nutz.dao.util.cri.Static;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
@@ -51,7 +53,8 @@ public class FlowTodoCenterController {
|
||||
t.h5FormKey,
|
||||
t.createdAt,
|
||||
t.finishTime,
|
||||
t.variable,
|
||||
t.variable AS taskVariable,
|
||||
ins.variable,
|
||||
ins.state AS instanceState,
|
||||
ins.id AS instanceId,
|
||||
ins.businessNo,
|
||||
@@ -66,7 +69,14 @@ public class FlowTodoCenterController {
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
// 普通待办仍按进行中任务查询;提案进入团长审核后,补充展示尚未附议的已废弃 second 任务。
|
||||
SqlExpressionGroup todoTaskGroup = Cnd.exps("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
SqlExpressionGroup proposalSecondGroup = Cnd.exps("t.taskState", "=", ProcessTaskStateEnum.ABANDON.getCode())
|
||||
.and("t.taskName", "=", "second")
|
||||
.and(new Static("EXISTS (SELECT 1 FROM proposal_second ps WHERE ps.proposalId = ins.businessNo AND ps.seconderId = ta.actorId AND ps.isAgree IS NULL)"))
|
||||
.and(new Static("EXISTS (SELECT 1 FROM wf_process_task dt WHERE dt.processInstanceId = t.processInstanceId AND dt.taskName = 'delegation' AND dt.taskState = 10)"));
|
||||
todoTaskGroup.or(proposalSecondGroup);
|
||||
cnd.and(todoTaskGroup);
|
||||
cnd.and("ta.actorId", "=", SecurityUtil.getUserId());
|
||||
cnd.andEX("def.category", "=", category);
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
@@ -96,7 +106,8 @@ public class FlowTodoCenterController {
|
||||
t.h5FormKey,
|
||||
t.createdAt,
|
||||
t.finishTime,
|
||||
t.variable,
|
||||
t.variable AS taskVariable,
|
||||
ins.variable,
|
||||
ins.state AS instanceState,
|
||||
ins.id AS instanceId,
|
||||
ins.businessNo,
|
||||
@@ -223,7 +234,27 @@ public class FlowTodoCenterController {
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
WHERE
|
||||
ta.actorId = @userId
|
||||
AND t.taskState = 10
|
||||
AND (
|
||||
t.taskState = 10
|
||||
OR (
|
||||
t.taskState = 99
|
||||
AND t.taskName = 'second'
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM proposal_second ps
|
||||
WHERE ps.proposalId = (SELECT businessNo FROM wf_process_instance WHERE id = t.processInstanceId)
|
||||
AND ps.seconderId = ta.actorId
|
||||
AND ps.isAgree IS NULL
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM wf_process_task dt
|
||||
WHERE dt.processInstanceId = t.processInstanceId
|
||||
AND dt.taskName = 'delegation'
|
||||
AND dt.taskState = 10
|
||||
)
|
||||
)
|
||||
)
|
||||
""");
|
||||
todoSql.setParam("userId", SecurityUtil.getUserId());
|
||||
todoSql.setCallback(Sqls.callback.integer());
|
||||
|
||||
@@ -6,7 +6,9 @@ import lombok.Setter;
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Index;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.entity.annotation.TableIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@@ -22,6 +24,9 @@ import java.util.Date;
|
||||
@Getter
|
||||
@Setter
|
||||
@Table("wf_process_instance")
|
||||
@TableIndexes({
|
||||
@Index(name = "INDEX_WF_PROCESS_INSTANCE_BUSINESS_NO", fields = {"businessNo"}, unique = false)
|
||||
})
|
||||
@Comment("流程实例")
|
||||
public class ProcessInstance extends BaseModel {
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ import lombok.Setter;
|
||||
import org.nutz.dao.entity.annotation.Column;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Index;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.entity.annotation.TableIndexes;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
@@ -19,6 +21,9 @@ import java.util.Date;
|
||||
@Getter
|
||||
@Setter
|
||||
@Table("wf_process_task")
|
||||
@TableIndexes({
|
||||
@Index(name = "INDEX_WF_PROCESS_TASK_INSTANCE_STATE", fields = {"processInstanceId", "taskState"}, unique = false)
|
||||
})
|
||||
@Comment("流程任务")
|
||||
public class ProcessTask extends BaseModel {
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.budwk.app.flow.engine.event.ProcessPublisher;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.*;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
@@ -22,6 +24,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@IocBean
|
||||
public class FlowCommonService {
|
||||
@@ -61,11 +64,13 @@ public class FlowCommonService {
|
||||
|
||||
args.put(FlowConst.SUBMIT_TYPE, submitType);
|
||||
|
||||
Sys_unit sysUnit = dao.fetch(Sys_unit.class, Cnd.where("id", "=", SecurityUtil.getUnitId()));
|
||||
|
||||
// 设置办理人信息到表单参数
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "userName", SecurityUtil.getUserUsername());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "loginName", SecurityUtil.getUserLoginname());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitId", SecurityUtil.getUnitId());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", SecurityUtil.getUnitId());
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unitName", Optional.of(sysUnit).map(Sys_unit::getName).orElse(""));
|
||||
args.put(FlowConst.TASK_FORM_DATA_PREFIX + "unionId", SecurityUtil.getUnionId());
|
||||
|
||||
if (ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.ROLLBACK.getCode())) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RedisConstant;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.sys.models.Sys_config;
|
||||
import com.budwk.app.sys.services.SysConfigService;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
@@ -140,18 +139,19 @@ public class SysConfController {
|
||||
@At
|
||||
@Ok("json:full")
|
||||
@SaCheckPermission("sys.manager.conf")
|
||||
public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
|
||||
public Object data(@Param("pageNumber") int pageNumber,
|
||||
@Param("pageSize") int pageSize,
|
||||
@Param("pageOrderName") String pageOrderName,
|
||||
@Param("pageOrderBy") String pageOrderBy,
|
||||
@Param("configKey") String configKey) {
|
||||
try {
|
||||
ensureAppImageConfig("AppHomeImg", "PC首页轮播图");
|
||||
ensureAppImageConfig("H5AppHomeImg", "移动端首页轮播图");
|
||||
ensureAppImageConfig("AppFeaturedActivityImg", "精彩活动页顶部图片");
|
||||
ensureAppImageConfig("AppFestivalBenefitImg", "节日福利页顶部图片");
|
||||
ensureAppImageConfig("TeacherCongressCardBackImg", "教代会代表证背景图片");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
|
||||
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
|
||||
}
|
||||
return Result.success().addData(sysConfigService.listPage(pageNumber, pageSize, cnd));
|
||||
return Result.success().addData(sysConfigService.pageData(
|
||||
pageNumber, pageSize, pageOrderName, pageOrderBy, configKey));
|
||||
} catch (Exception e) {
|
||||
return Result.error();
|
||||
}
|
||||
|
||||
@@ -154,10 +154,15 @@ public class SysHomeController {
|
||||
.and(Sys_menu::getPlatform, "=", platform)
|
||||
);
|
||||
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
|
||||
List<String> allMenuIds = menus.stream().map(Sys_menu::getId).toList();
|
||||
Set<String> allMenuIds = menus.stream().map(Sys_menu::getId).collect(Collectors.toSet());
|
||||
Set<String> allParentMenuIds = menus.stream()
|
||||
.map(Sys_menu::getParentId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
List<Sys_menu> sysMenus = list.stream()
|
||||
// 推荐项必须同时属于当前用户已授权菜单,避免首页展示无权限入口。
|
||||
.filter(menu -> allMenuIds.contains(menu.getId()))
|
||||
// 应用有已授权子菜单,或根菜单自身有链接且已授权时,才允许在首页展示入口。
|
||||
.filter(menu -> allParentMenuIds.contains(menu.getId())
|
||||
|| (StrUtil.isNotBlank(menu.getHref()) && allMenuIds.contains(menu.getId())))
|
||||
.sorted(Comparator.comparing(Sys_menu::getLocation, Comparator.nullsLast(Integer::compareTo))
|
||||
.thenComparing(Sys_menu::getId))
|
||||
.toList();
|
||||
@@ -175,7 +180,7 @@ public class SysHomeController {
|
||||
.and(Sys_menu::getPlatform, "=", platform)
|
||||
);
|
||||
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
|
||||
List<String> allMenuIds = menus.stream().map(Sys_menu::getId).toList();
|
||||
Set<String> allMenuIds = menus.stream().map(Sys_menu::getId).collect(Collectors.toSet());
|
||||
List<Sys_menu> sysMenus = list.stream()
|
||||
// 推荐项必须同时属于当前用户已授权菜单,避免首页展示无权限入口。
|
||||
.filter(menu -> allMenuIds.contains(menu.getId()))
|
||||
|
||||
@@ -419,14 +419,13 @@ public class SysRoleController {
|
||||
public Object user(@Param("roleId") String roleId, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword,
|
||||
@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
|
||||
try {
|
||||
Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_user_role b,sys_unit c WHERE a.unitid=c.id and a.id=b.userId and b.roleId=@roleId $s $o");
|
||||
Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_user_role b,sys_unit c WHERE a.unitid=c.id and a.id=b.userId and enable='1' and b.roleId=@roleId $s $o");
|
||||
sql.params().set("roleId", roleId);
|
||||
if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) {
|
||||
sql.vars().set("s", " and a." + searchName + " like '%" + searchKeyword + "%'");
|
||||
}
|
||||
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
|
||||
sql.vars().set("o", " order by a." + pageOrderName + " " + PageUtil.getOrder(pageOrderBy));
|
||||
|
||||
}
|
||||
return Result.success().addData(sysUserService.listPage(pageNumber, pageSize, sql));
|
||||
} catch (Exception e) {
|
||||
@@ -554,20 +553,9 @@ public class SysRoleController {
|
||||
@Ok("json:full")
|
||||
@SaCheckLogin
|
||||
public Result getRoleNames(){
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
GROUP_CONCAT(DISTINCT sr.`name`) roleNames
|
||||
FROM
|
||||
`sys_user_role` sur
|
||||
LEFT JOIN sys_role sr ON sr.id = sur.roleId
|
||||
WHERE
|
||||
sur.userId = @userId
|
||||
ORDER BY
|
||||
sr.sort DESC
|
||||
""").setParam("userId", SecurityUtil.getUserId());
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
sysRoleService.dao().execute(sql);
|
||||
return Result.success(sql.getResult());
|
||||
// 首页身份与菜单、接口权限使用同一启用角色集合。
|
||||
String roleNames = sysUserService.getEnabledRoleNames(SecurityUtil.getUserId());
|
||||
return Result.success(NutMap.NEW().addv("roleNames", roleNames));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,8 @@ public class SysSignatureController {
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result update(@Param("file") TempFile tempFile) {
|
||||
String url = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), tempFile);
|
||||
Sys_user_signature sysUserSignature = dao.fetch(Sys_user_signature.class);
|
||||
// 签字记录必须按当前登录用户读取,避免后续用户更新时覆盖其他用户的签字。
|
||||
Sys_user_signature sysUserSignature = dao.fetch(Sys_user_signature.class, Cnd.where(Sys_user_signature::getUserId, "=", SecurityUtil.getUserId()));
|
||||
if (ObjectUtil.isNull(sysUserSignature)) {
|
||||
sysUserSignature = new Sys_user_signature();
|
||||
}
|
||||
|
||||
@@ -456,10 +456,16 @@ public class SysUnionController {
|
||||
unionCadre.setIsJoin(true);
|
||||
dao.insert(unionCadre);
|
||||
|
||||
// 去走工作流
|
||||
// 校级管理员新增普通干部时直接授权,不生成无实际审核意义的流程数据。
|
||||
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
if (isAdmin) {
|
||||
sysUnionService.assignBranchUnionRole(userId, role.getId(), unionId, List.of());
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
// 非校级管理员仍按原业务发起基层干部授权审核流程。
|
||||
Dict args = Dict.create();
|
||||
args.set("submit", isAdmin ? "admin" : "branch");
|
||||
args.set("submit", "branch");
|
||||
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
|
||||
args.set(FlowConst.FORM_DATA, unionCadre);
|
||||
|
||||
@@ -470,20 +476,12 @@ public class SysUnionController {
|
||||
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
|
||||
}
|
||||
|
||||
if (isAdmin) {
|
||||
// 如果是管理员,直接加角色
|
||||
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId).and("unionId", "=", unionId));
|
||||
sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", userId).add("unionId", unionId));
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起二级党委书记授权审批。一个审批申请可关联当前分工会下的多个单位。
|
||||
* 审核通过后由流程拦截器按单位写入角色,避免影响普通分工会角色的授权方式。
|
||||
* 新增二级党委书记授权。校级管理员直接按单位授权,其他用户发起审批,
|
||||
* 审核通过后由流程拦截器按单位写入角色。
|
||||
*
|
||||
* @param userId 人员ID
|
||||
* @param unionId 分工会ID
|
||||
@@ -536,11 +534,18 @@ public class SysUnionController {
|
||||
unionCadre.setIsJoin(true);
|
||||
dao.insert(unionCadre);
|
||||
|
||||
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
if (isAdmin) {
|
||||
// 校级管理员直接按所选单位授权,不创建 JCGHWY 流程实例和审核任务。
|
||||
sysUnionService.assignBranchUnionRole(userId, role.getId(), unionId, distinctUnitIds);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
// 非校级管理员保留原审批流程,并将所选单位随表单传给审核通过拦截器。
|
||||
JSONObject formData = JSONUtil.parseObj(unionCadre);
|
||||
formData.set("unitIds", distinctUnitIds);
|
||||
Dict args = Dict.create();
|
||||
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
args.set("submit", isAdmin ? "admin" : "branch");
|
||||
args.set("submit", "branch");
|
||||
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
|
||||
args.set(FlowConst.FORM_DATA, formData.toString());
|
||||
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JCGHWY", unionCadre.getId(), SecurityUtil.getUserId(), args);
|
||||
@@ -624,22 +629,21 @@ public class SysUnionController {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询当前分工会的组成单位。
|
||||
*
|
||||
* @param pageForm 分页和查询参数;pageNumber 为页码,pageSize 为每页条数,searchKeyword 为单位编码或名称
|
||||
* @param unionId 分工会ID,不能为空
|
||||
* @return Result;data 为 Pagination,list 是当前页单位列表,totalCount 是符合条件的单位总数
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("分工会组成单位分页")
|
||||
@SaCheckPermission("sys.manager.union")
|
||||
public Result branchUnionPartUnitPageData(PageForm pageForm, String unionId) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("unionId", "=", unionId);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.orLike("`name`", pageForm.getSearchKeyword());
|
||||
seg.orLike("unitcode", pageForm.getSearchKeyword());
|
||||
cnd.and(seg);
|
||||
public Result branchUnionPartUnitPageData(@Valid PageForm pageForm, String unionId) {
|
||||
if (StrUtil.isBlank(unionId)) {
|
||||
return Result.error("分工会参数不能为空");
|
||||
}
|
||||
cnd.desc("unitcode");
|
||||
|
||||
List<Sys_unit> list = dao.query(Sys_unit.class, cnd);
|
||||
return Result.success(list);
|
||||
return Result.success(sysUnitService.pageBranchUnionPartUnits(pageForm, unionId));
|
||||
}
|
||||
|
||||
@At
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.sys.controller.v4;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
@@ -50,6 +51,7 @@ public class SysV4MsgController {
|
||||
m.title,
|
||||
m.content,
|
||||
m.type,
|
||||
m.sendTime,
|
||||
r.isRead,
|
||||
r.readTime
|
||||
FROM
|
||||
@@ -69,6 +71,10 @@ public class SysV4MsgController {
|
||||
|
||||
|
||||
cnd.andEX("m.type", "=", type);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
String keyword = "%" + pageForm.getSearchKeyword() + "%";
|
||||
cnd.and(Cnd.exps("m.title", "like", keyword).or("m.content", "like", keyword));
|
||||
}
|
||||
cnd.desc("m.sendTime");
|
||||
sql.setCondition(cnd);
|
||||
|
||||
|
||||
@@ -211,6 +211,12 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@DataCenterColumn(name = "教职工类别码", key = "RYLX", dict = "USER_PERSON_TYPE")
|
||||
private String personType;
|
||||
|
||||
@Column
|
||||
@Comment("待确认状态:0不用确认、1待确认、2已确认")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
@Default("0")
|
||||
private Integer pendingConfirmStatus;
|
||||
|
||||
@Column
|
||||
@Comment("编制类别码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
|
||||
@@ -16,6 +16,15 @@ public class Sys_user_role {
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户角色关系是否启用。普通角色默认启用,教代会届次切换时按届次统一刷新。
|
||||
*/
|
||||
@Column
|
||||
@Comment("是否启用:1启用,0禁用")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("1")
|
||||
private Boolean enable = true;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String unitId;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.budwk.app.sys.services;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.sys.models.Sys_config;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
|
||||
@@ -16,4 +17,17 @@ public interface SysConfigService extends BaseService<Sys_config> {
|
||||
List<Sys_config> getAllList();
|
||||
|
||||
Sys_config getValueByKey(String key);
|
||||
|
||||
/**
|
||||
* 分页查询系统参数,支持按参数名模糊查询和安全排序。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
* @param pageSize 每页条数
|
||||
* @param pageOrderName 排序字段
|
||||
* @param pageOrderBy 排序方向
|
||||
* @param configKey 参数名关键字
|
||||
* @return 系统参数分页数据
|
||||
*/
|
||||
Pagination<Sys_config> pageData(int pageNumber, int pageSize, String pageOrderName,
|
||||
String pageOrderBy, String configKey);
|
||||
}
|
||||
|
||||
@@ -3,5 +3,18 @@ package com.budwk.app.sys.services;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SysUnionService extends BaseService<Sys_union> {
|
||||
|
||||
/**
|
||||
* 直接分配分工会干部角色。普通干部传空单位集合时按分工会写入一条角色关系;
|
||||
* 二级党委书记传单位集合时按单位分别写入角色关系。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @param unionId 分工会ID
|
||||
* @param unitIds 授权单位ID集合,普通干部角色传空集合
|
||||
*/
|
||||
void assignBranchUnionRole(String userId, String roleId, String unionId, List<String> unitIds);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.budwk.app.sys.services;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
|
||||
@@ -7,6 +9,15 @@ import com.budwk.app.sys.models.Sys_unit;
|
||||
* Created by wizzer on 2016/12/22.
|
||||
*/
|
||||
public interface SysUnitService extends BaseService<Sys_unit> {
|
||||
/**
|
||||
* 分页查询指定分工会的组成单位。
|
||||
*
|
||||
* @param pageForm 分页和查询参数;pageNumber 为页码,pageSize 为每页条数,searchKeyword 为单位编码或名称
|
||||
* @param unionId 分工会ID,用于限制只查询当前分工会的组成单位
|
||||
* @return 分页结果;list 为当前页单位数据,totalCount 为符合条件的单位总数
|
||||
*/
|
||||
Pagination<Sys_unit> pageBranchUnionPartUnits(PageForm pageForm, String unionId);
|
||||
|
||||
/**
|
||||
* 保存单位
|
||||
*
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.exception.UnknownAccountException;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_menu;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -31,6 +32,21 @@ public interface SysUserService extends BaseService<Sys_user> {
|
||||
*/
|
||||
List<String> getRoleCodeList(Sys_user user);
|
||||
|
||||
/**
|
||||
* 查询用户当前启用的角色关系对应角色,供菜单、接口权限和首页身份统一使用。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 当前启用且角色本身未禁用的角色列表
|
||||
*/
|
||||
List<Sys_role> getEnabledRoles(String userId);
|
||||
|
||||
/**
|
||||
* 查询用户当前启用角色的显示名称。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 去重并按角色顺序排列的角色名称
|
||||
*/
|
||||
String getEnabledRoleNames(String userId);
|
||||
|
||||
/**
|
||||
* 获取用户的菜单
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package com.budwk.app.sys.services.impl;
|
||||
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.sys.models.Sys_config;
|
||||
import com.budwk.app.sys.services.SysConfigService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.Strings;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by wizzer on 2016/12/23.
|
||||
@@ -32,4 +36,32 @@ public class SysConfigServiceImpl extends BaseServiceImpl<Sys_config> implements
|
||||
}
|
||||
return sys_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询系统参数。参数名使用模糊匹配,排序字段限定在列表可展示字段内,
|
||||
* 防止未经校验的前端字段直接进入排序 SQL。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
* @param pageSize 每页条数
|
||||
* @param pageOrderName 排序字段
|
||||
* @param pageOrderBy 排序方向
|
||||
* @param configKey 参数名关键字
|
||||
* @return 系统参数分页数据
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Pagination<Sys_config> pageData(int pageNumber, int pageSize, String pageOrderName,
|
||||
String pageOrderBy, String configKey) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (Strings.isNotBlank(configKey)) {
|
||||
cnd.where().andLike("configKey", configKey.trim());
|
||||
}
|
||||
Set<String> sortableColumns = Set.of("configKey", "configValue", "note");
|
||||
if (sortableColumns.contains(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
|
||||
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
|
||||
} else {
|
||||
cnd.asc("configKey");
|
||||
}
|
||||
return listPage(pageNumber, pageSize, cnd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,12 @@ import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
|
||||
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeOrigin;
|
||||
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
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.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -50,6 +53,10 @@ import java.util.stream.Collectors;
|
||||
@IocBean
|
||||
public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService {
|
||||
private static final int BATCH_SIZE = 500;
|
||||
/** 不需要人工确认。 */
|
||||
private static final int PENDING_CONFIRM_STATUS_NONE = 0;
|
||||
/** 数据源缺失,等待人工确认。 */
|
||||
private static final int PENDING_CONFIRM_STATUS_PENDING = 1;
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@@ -154,6 +161,10 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
for (Sys_user_source source : sources) {
|
||||
Sys_user user = userMap.get(source.getLoginname());
|
||||
source.setMember(null);
|
||||
String unitId = source.getUnitId();
|
||||
if (StringUtils.isNotBlank(unitId) && unitId.length() == 5) {
|
||||
source.setUnitId(unitId.substring(0, 3));
|
||||
}
|
||||
|
||||
// 创建用户对象
|
||||
Sys_user u = new Sys_user();
|
||||
@@ -174,7 +185,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
* 全量更新已有用户时置空,避免 updateIgnoreNull 把已迁移的基金会员标识覆盖为非会员。
|
||||
*/
|
||||
u.setAidFundMember(null);
|
||||
|
||||
u.setPersonType(null);
|
||||
needDoUpdateList.add(u);
|
||||
}
|
||||
|
||||
@@ -346,6 +357,12 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
RoleEventPublisher.broadcast(new RoleEventMsg(unitId, RoleConstant.PROPOSAL_BRANCH_SCHOOL_LEADER.name(), RoleEventMsg.RENEW_ROLE));
|
||||
}
|
||||
|
||||
/*
|
||||
* 所有异步用户更新完成后再校正待确认状态,避免主事务提前锁定 sys_user,
|
||||
* 导致异步更新线程等待主事务释放行锁而形成相互等待。
|
||||
*/
|
||||
reconcilePendingConfirmStatus(updateParam.getPullTime());
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
log.info("全量更新用户数据完成,耗时: {} 毫秒", (endTime - startTime));
|
||||
|
||||
@@ -356,6 +373,49 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
+ " 条";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定批次的完整数据源校正系统用户待确认状态。
|
||||
* 已人工确认且仍未重新出现的人员保持已确认状态,避免每次全量更新重复转为待确认。
|
||||
*
|
||||
* @param pullTime 本次全量数据的拉取时间
|
||||
*/
|
||||
private void reconcilePendingConfirmStatus(String pullTime) {
|
||||
Sql resetStatusSql = Sqls.create("""
|
||||
UPDATE sys_user userInfo
|
||||
SET userInfo.pendingConfirmStatus = @noneStatus
|
||||
WHERE userInfo.personType IN ('教职工', '劳务派遣人员')
|
||||
AND userInfo.pendingConfirmStatus <> @noneStatus
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM sys_user_source sourceInfo
|
||||
WHERE sourceInfo.pullTime = @pullTime
|
||||
AND sourceInfo.loginname = userInfo.loginname
|
||||
AND sourceInfo.personType IN ('教职工', '劳务派遣人员')
|
||||
)
|
||||
""");
|
||||
resetStatusSql.setParam("noneStatus", PENDING_CONFIRM_STATUS_NONE);
|
||||
resetStatusSql.setParam("pullTime", pullTime);
|
||||
dao.execute(resetStatusSql);
|
||||
|
||||
Sql pendingStatusSql = Sqls.create("""
|
||||
UPDATE sys_user userInfo
|
||||
SET userInfo.pendingConfirmStatus = @pendingStatus
|
||||
WHERE userInfo.personType IN ('教职工', '劳务派遣人员')
|
||||
AND IFNULL(userInfo.pendingConfirmStatus, @noneStatus) = @noneStatus
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM sys_user_source sourceInfo
|
||||
WHERE sourceInfo.pullTime = @pullTime
|
||||
AND sourceInfo.loginname = userInfo.loginname
|
||||
AND sourceInfo.personType IN ('教职工', '劳务派遣人员')
|
||||
)
|
||||
""");
|
||||
pendingStatusSql.setParam("pendingStatus", PENDING_CONFIRM_STATUS_PENDING);
|
||||
pendingStatusSql.setParam("noneStatus", PENDING_CONFIRM_STATUS_NONE);
|
||||
pendingStatusSql.setParam("pullTime", pullTime);
|
||||
dao.execute(pendingStatusSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建变更的历史数据
|
||||
*
|
||||
|
||||
@@ -2,13 +2,65 @@ package com.budwk.app.sys.services.impl;
|
||||
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.sys.services.SysRoleService;
|
||||
import com.budwk.app.sys.services.SysUnionService;
|
||||
import com.budwk.app.sys.services.SysUserService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class SysUnionServiceImpl extends BaseServiceImpl<Sys_union> implements SysUnionService {
|
||||
|
||||
@Inject
|
||||
private SysRoleService sysRoleService;
|
||||
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
|
||||
public SysUnionServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接分配分工会干部角色,并在授权完成后统一清理权限缓存。
|
||||
* 普通角色按分工会授权一次,包含单位的角色按每个单位分别授权。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @param unionId 分工会ID
|
||||
* @param unitIds 授权单位ID集合,普通干部角色传空集合
|
||||
*/
|
||||
@Override
|
||||
public void assignBranchUnionRole(String userId, String roleId, String unionId, List<String> unitIds) {
|
||||
// 先清理同一用户在当前分工会下的相同角色,保证重新授权后不存在重复关系。
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", roleId)
|
||||
.and(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getUnionId, "=", unionId));
|
||||
|
||||
if (unitIds == null || unitIds.isEmpty()) {
|
||||
Sys_user_role userRole = new Sys_user_role();
|
||||
userRole.setRoleId(roleId);
|
||||
userRole.setUserId(userId);
|
||||
userRole.setUnionId(unionId);
|
||||
dao().insert(userRole);
|
||||
} else {
|
||||
// 二级党委书记按选中的单位分别生成角色关系,供后续单位级权限判断使用。
|
||||
for (String unitId : unitIds) {
|
||||
Sys_user_role userRole = new Sys_user_role();
|
||||
userRole.setRoleId(roleId);
|
||||
userRole.setUserId(userId);
|
||||
userRole.setUnionId(unionId);
|
||||
userRole.setUnitId(unitId);
|
||||
dao().insert(userRole);
|
||||
}
|
||||
}
|
||||
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.budwk.app.sys.services.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RedisConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.services.SysUnitService;
|
||||
@@ -10,6 +12,7 @@ import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Strings;
|
||||
@@ -26,6 +29,22 @@ public class SysUnitServiceImpl extends BaseServiceImpl<Sys_unit> implements Sys
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按单位编码或名称筛选当前分工会的组成单位,并按单位编码倒序分页。
|
||||
*/
|
||||
@Override
|
||||
public Pagination<Sys_unit> pageBranchUnionPartUnits(PageForm pageForm, String unionId) {
|
||||
Cnd cnd = Cnd.where("unionId", "=", unionId);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup keywordCondition = new SqlExpressionGroup();
|
||||
keywordCondition.orLike("`name`", pageForm.getSearchKeyword());
|
||||
keywordCondition.orLike("unitcode", pageForm.getSearchKeyword());
|
||||
cnd.and(keywordCondition);
|
||||
}
|
||||
cnd.desc("unitcode");
|
||||
return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), Sys_unit.class, cnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增单位
|
||||
*
|
||||
|
||||
@@ -67,19 +67,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
@Override
|
||||
@CacheResult(cacheKey = "${userId}_getPermissionList")
|
||||
public List<String> getPermissionList(String userId) {
|
||||
Sys_user user = this.fetch(userId);
|
||||
if (user == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
this.fetchLinks(user, "roles");
|
||||
if (user.getRoles() == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> permissionList = new ArrayList<String>();
|
||||
for (Sys_role role : user.getRoles()) {
|
||||
if (!role.isDisabled()) {
|
||||
permissionList.addAll(sysRoleService.getPermissionList(role));
|
||||
}
|
||||
// Sa-Token接口权限只汇总启用的用户角色关系,历史届次角色不再参与鉴权。
|
||||
for (Sys_role role : getEnabledRoles(userId)) {
|
||||
permissionList.addAll(sysRoleService.getPermissionList(role));
|
||||
}
|
||||
// 追加public公共角色权限
|
||||
permissionList.addAll(sysRoleService.getPermissionList(sysRoleService.fetch(Cnd.where("code", "=", "public"))));
|
||||
@@ -94,12 +85,63 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
*/
|
||||
@CacheResult(cacheKey = "${user.id}_getRoleCodeList")
|
||||
public List<String> getRoleCodeList(Sys_user user) {
|
||||
dao().fetchLinks(user, "roles");
|
||||
List<String> roleNameList = new ArrayList<String>();
|
||||
for (Sys_role role : user.getRoles()) {
|
||||
if (!role.isDisabled()) roleNameList.add(role.getCode());
|
||||
if (user == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return roleNameList;
|
||||
// AuthUtil.hasRole与Sa-Token角色判断共用启用角色集合。
|
||||
return getEnabledRoles(user.getId()).stream()
|
||||
.map(Sys_role::getCode)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户当前启用角色。用户角色关系和角色本身必须同时处于启用状态。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 当前启用角色列表
|
||||
*/
|
||||
@Override
|
||||
@CacheResult(cacheKey = "${userId}_getEnabledRoles")
|
||||
public List<Sys_role> getEnabledRoles(String userId) {
|
||||
if (StrUtil.isBlank(userId) || fetch(userId) == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT DISTINCT
|
||||
role.*
|
||||
FROM
|
||||
sys_role role
|
||||
INNER JOIN sys_user_role userRole ON userRole.roleId = role.id
|
||||
WHERE
|
||||
userRole.userId = @userId
|
||||
AND userRole.enable = @t
|
||||
AND role.disabled = @f
|
||||
ORDER BY role.sort DESC, role.id
|
||||
""");
|
||||
sql.setParam("userId", userId);
|
||||
sql.setParam("t", true);
|
||||
sql.setParam("f", false);
|
||||
sql.setCallback(Sqls.callback.entities());
|
||||
sql.setEntity(dao().getEntity(Sys_role.class));
|
||||
dao().execute(sql);
|
||||
return sql.getList(Sys_role.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总用户当前启用角色名称,首页展示与菜单及接口权限保持相同数据口径。
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 逗号分隔的角色名称
|
||||
*/
|
||||
@Override
|
||||
public String getEnabledRoleNames(String userId) {
|
||||
return getEnabledRoles(userId).stream()
|
||||
.map(Sys_role::getName)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +203,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
*/
|
||||
// @CacheResult(cacheKey = "${userId}_getMenus")
|
||||
public List<Sys_menu> getMenus(String userId) {
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and d.disabled=@f) and a.disabled=@f and a.showit=@t and a.type='menu' order by a.location ASC,a.path asc");
|
||||
// 菜单仅使用启用的用户角色关系,普通角色与当前开启届次角色保持原有权限。
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f and a.showit=@t and a.type='menu' order by a.location ASC,a.path asc");
|
||||
sql.params().set("userId", userId);
|
||||
sql.params().set("f", false);
|
||||
sql.params().set("t", true);
|
||||
@@ -176,9 +219,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
*/
|
||||
// @CacheResult(cacheKey = "${userId}_getMenusAndButtons")
|
||||
public List<Sys_menu> getMenusAndButtons(String userId) {
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
|
||||
sql.params().set("userId", userId);
|
||||
sql.params().set("f", false);
|
||||
sql.params().set("t", true);
|
||||
return sysMenuService.listEntity(sql);
|
||||
}
|
||||
|
||||
@@ -195,9 +239,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
*/
|
||||
@CacheResult(cacheKey = "${userId}_getDatas")
|
||||
public List<Sys_menu> getDatas(String userId) {
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and d.disabled=@f) and a.disabled=@f and a.type='data' order by a.location ASC,a.path asc");
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + " b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f and a.type='data' order by a.location ASC,a.path asc");
|
||||
sql.params().set("userId", userId);
|
||||
sql.params().set("f", false);
|
||||
sql.params().set("t", true);
|
||||
return sysMenuService.listEntity(sql);
|
||||
}
|
||||
|
||||
@@ -232,9 +277,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
*/
|
||||
@CacheResult(cacheKey = "${userId}_${pid}_getRoleMenus")
|
||||
public List<Sys_menu> getRoleMenus(String userId, String pid) {
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
|
||||
Sql sql = Sqls.create("select distinct a.* from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
|
||||
sql.params().set("userId", userId);
|
||||
sql.params().set("f", false);
|
||||
sql.params().set("t", true);
|
||||
if (Strings.isNotBlank(pid)) {
|
||||
sql.vars().set("m", "a.parentId='" + pid + "'");
|
||||
} else {
|
||||
@@ -251,9 +297,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
*/
|
||||
@CacheResult(cacheKey = "${userId}_${pid}_hasChildren")
|
||||
public boolean hasChildren(String userId, String pid) {
|
||||
Sql sql = Sqls.create("select count(*) from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
|
||||
Sql sql = Sqls.create("select count(*) from sys_menu a,sys_role_menu b where a.id=b.menuId and " + "$m and b.roleId in(select c.roleId from sys_user_role c,sys_role d where c.roleId=d.id and c.userId=@userId and c.enable=@t and d.disabled=@f) and a.disabled=@f order by a.location ASC,a.path asc");
|
||||
sql.params().set("userId", userId);
|
||||
sql.params().set("f", false);
|
||||
sql.params().set("t", true);
|
||||
if (Strings.isNotBlank(pid)) {
|
||||
sql.vars().set("m", "a.parentId='" + pid + "'");
|
||||
} else {
|
||||
@@ -387,6 +434,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
user.setUnion(union);
|
||||
}
|
||||
user = this.fillMenu(user);
|
||||
// 登录用户返回给前端的角色同样只保留启用关系,避免历史届次角色继续触发页面 hasRole 判断。
|
||||
user.setRoles(this.getEnabledRoles(userId));
|
||||
user.setPermissions(this.getPermissionList(userId));
|
||||
return user;
|
||||
}
|
||||
|
||||
+2
@@ -196,6 +196,8 @@ public class ActivityCultureApplyActivityController {
|
||||
}
|
||||
|
||||
private void cleanNewActivityData(ActivityTissue tissue) {
|
||||
// 从模板另存或直接新建的活动必须进入活动列表,不能继承来源活动的模板状态。
|
||||
tissue.setTemplateStatus(ActivityTissue.TEMPLATE_STATUS_UNSET);
|
||||
tissue.setId(null);
|
||||
tissue.setAuditId(null);
|
||||
tissue.setState(null);
|
||||
|
||||
+10
-30
@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
@@ -69,8 +70,9 @@ public class ActivityCultureInfoManageController {
|
||||
public Result pageData(PageForm page, String year,
|
||||
String name,
|
||||
String unionId,
|
||||
@Valid Integer activity_type) {
|
||||
return Result.success(activityCultureService.pageData(page, year, name, unionId, activity_type));
|
||||
@Valid Integer activity_type,
|
||||
Integer templateStatus) {
|
||||
return Result.success(activityCultureService.pageData(page, year, name, unionId, activity_type, templateStatus));
|
||||
}
|
||||
|
||||
@At
|
||||
@@ -90,47 +92,25 @@ public class ActivityCultureInfoManageController {
|
||||
}
|
||||
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("activity.culture.infoManage.school")
|
||||
@SaCheckPermission(value = {"activity.culture.infoManage.school", "activity.culture.infoManage.union"}, mode = SaMode.OR)
|
||||
public Result setTemplate(@Valid String id) {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
ActivityTissue tissue = activityCultureService.fetch(id);
|
||||
if (tissue == null) {
|
||||
return Result.error("活动不存在");
|
||||
String errorMessage = activityCultureService.setTemplate(id);
|
||||
if (StrUtil.isNotBlank(errorMessage)) {
|
||||
return Result.error(errorMessage);
|
||||
}
|
||||
if (tissue.getActivity_type() == null || tissue.getActivity_type() != 40001) {
|
||||
return Result.error("仅校工会文化活动可设为模板");
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = activityCultureService.dao().fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = tissue.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
activityCultureService.dao().insertOrUpdate(sysHomeTemplate);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("activity.culture.infoManage.school")
|
||||
@SaCheckPermission(value = {"activity.culture.infoManage.school", "activity.culture.infoManage.union"}, mode = SaMode.OR)
|
||||
public Result cancelTemplate(@Valid String id) {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
activityCultureService.dao().delete(Sys_home_template.class, id);
|
||||
activityCultureService.cancelTemplate(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ import java.util.List;
|
||||
@Table("activity_tissue")
|
||||
public class ActivityTissue extends BaseModel implements Serializable, SysHomeConvert {
|
||||
|
||||
/** 未设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_UNSET = 0;
|
||||
|
||||
/** 已设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_SET = 1;
|
||||
|
||||
@Column
|
||||
@Name
|
||||
@Comment("ID")
|
||||
@@ -236,6 +242,12 @@ public class ActivityTissue extends BaseModel implements Serializable, SysHomeCo
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean isUnseal;
|
||||
|
||||
@Column
|
||||
@Comment("模板设置状态(0:未设置,1:已设置)")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
@Default("0")
|
||||
private Integer templateStatus;
|
||||
|
||||
@Column
|
||||
@Comment("物品")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
|
||||
+27
-1
@@ -21,7 +21,33 @@ public interface ActivityCultureService extends BaseService<ActivityTissue> {
|
||||
|
||||
void doEditActivity(ActivityTissue tissue);
|
||||
|
||||
Object pageData(PageForm page, String year, String name, String unionId, Integer activity_type);
|
||||
/**
|
||||
* 分页查询文化活动。
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param year 年度
|
||||
* @param name 活动名称
|
||||
* @param unionId 工会ID
|
||||
* @param activity_type 活动类型
|
||||
* @param templateStatus 模板设置状态,为空时不限制
|
||||
* @return 文化活动分页数据
|
||||
*/
|
||||
Object pageData(PageForm page, String year, String name, String unionId, Integer activity_type, Integer templateStatus);
|
||||
|
||||
/**
|
||||
* 将校工会或分工会文化活动设置为工作模板,并同步模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return 空字符串表示成功,否则返回业务错误信息
|
||||
*/
|
||||
String setTemplate(String id);
|
||||
|
||||
/**
|
||||
* 取消校工会或分工会文化活动模板,并同步模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
void cancelTemplate(String id);
|
||||
|
||||
NutMap findOne(String id);
|
||||
|
||||
|
||||
+63
-3
@@ -6,6 +6,7 @@ import com.budwk.app.base.model.Audit;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.models.Sys_home_template;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.basic.service.ActivityBasicScopeService;
|
||||
@@ -14,6 +15,8 @@ import com.budwk.app.zhgh.activity.culture.models.ActivityTissuePerson;
|
||||
import com.budwk.app.zhgh.activity.culture.service.ActivityCultureService;
|
||||
import com.budwk.app.zhgh.club.model.SysClub;
|
||||
import com.budwk.app.zhgh.club.service.SysClubService;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
@@ -21,6 +24,7 @@ import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
@@ -85,7 +89,7 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object pageData(PageForm page, String year, String name, String unionId, Integer activity_type) {
|
||||
public Object pageData(PageForm page, String year, String name, String unionId, Integer activity_type, Integer templateStatus) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
@@ -110,7 +114,7 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
|
||||
t.variable taskVariable,
|
||||
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
|
||||
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask') AS startTaskId,
|
||||
IF(sht.id IS NULL, 0, 1) AS isTemplate
|
||||
tissue.templateStatus AS isTemplate
|
||||
FROM
|
||||
activity_tissue tissue
|
||||
LEFT JOIN sys_union uni ON uni.id = tissue.unionId
|
||||
@@ -119,7 +123,6 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
|
||||
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = tissue.id
|
||||
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN sys_home_template sht ON sht.id = tissue.id
|
||||
$condition
|
||||
""");
|
||||
|
||||
@@ -127,6 +130,8 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
|
||||
cnd.andEX("tissue.projectTypeCode", "!=", "50004");
|
||||
cnd.andEX("tissue.unionId", "=", unionId);
|
||||
cnd.andEX("tissue.activity_type", "=", activity_type);
|
||||
// 校工会管理页按页签传入模板状态;其他文化活动页面不传时保持原查询范围。
|
||||
cnd.andEX("tissue.templateStatus", "=", templateStatus);
|
||||
cnd.groupBy("tissue.id");
|
||||
|
||||
if (Strings.isNotBlank(name)) {
|
||||
@@ -159,6 +164,61 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
|
||||
return this.listPageMap(page.getPageNumber(), page.getPageSize(), sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将校工会或分工会文化活动转换为工作模板,并保留模板中心已维护的展示配置。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return 空字符串表示成功,否则返回业务错误信息
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public String setTemplate(String id) {
|
||||
ActivityTissue tissue = fetch(id);
|
||||
if (tissue == null) {
|
||||
return "活动不存在";
|
||||
}
|
||||
if (tissue.getActivity_type() == null || !List.of(40001, 40002).contains(tissue.getActivity_type())) {
|
||||
return "仅校工会或分工会文化活动可设为模板";
|
||||
}
|
||||
|
||||
Sys_home_template oldHomeTemplate = dao().fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = tissue.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
// 重复设置时保留模板中心人工配置,避免覆盖置顶、推送、排序及模板素材。
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao().insertOrUpdate(sysHomeTemplate);
|
||||
dao().update(ActivityTissue.class,
|
||||
Chain.make("templateStatus", ActivityTissue.TEMPLATE_STATUS_SET),
|
||||
Cnd.where("id", "=", id));
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板中心记录并将文化活动恢复为未设置模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void cancelTemplate(String id) {
|
||||
dao().delete(Sys_home_template.class, id);
|
||||
dao().update(ActivityTissue.class,
|
||||
Chain.make("templateStatus", ActivityTissue.TEMPLATE_STATUS_UNSET),
|
||||
Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap findOne(String id) {
|
||||
Sql sql = Sqls.create("""
|
||||
|
||||
+7
@@ -87,6 +87,9 @@ public class FamilyActivityApplyController {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("id", "=", id);
|
||||
cnd.andEX("`year`", "=", year);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.and("activityName", "like", "%" + pageForm.getSearchKeyword().trim() + "%");
|
||||
}
|
||||
//查询报名中
|
||||
if (activityType == 2) {
|
||||
cnd.and(new Static("now() < activitySignUpEndTime"));
|
||||
@@ -117,6 +120,7 @@ public class FamilyActivityApplyController {
|
||||
@Param(value = "courseTypeId") String courseTypeId,
|
||||
@Param(value = "activityId") String activityId,
|
||||
@Param(value = "assortTypes") String[] assortTypes,
|
||||
@Param(value = "searchKeyword") String searchKeyword,
|
||||
@Param(value = "dataType") String dataType) {
|
||||
FamilyActivity activity = dao.fetch(FamilyActivity.class, activityId);
|
||||
Sql sql = Sqls.create("""
|
||||
@@ -131,6 +135,9 @@ public class FamilyActivityApplyController {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("type.id", "=", courseTypeId);
|
||||
cnd.and("tsuc.activityId", "=", activityId);
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
cnd.and("tsuc.courseName", "like", "%" + searchKeyword.trim() + "%");
|
||||
}
|
||||
if(Lang.isNotEmpty(assortTypes)) {
|
||||
cnd.and("tsuc.assort", "in", assortTypes);
|
||||
}
|
||||
|
||||
+9
-31
@@ -6,7 +6,6 @@ import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
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.sys.models.Sys_home_activity;
|
||||
@@ -68,20 +67,15 @@ public class FamilyActivityController {
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "activityName") String activityName) {
|
||||
@Param(value = "activityName") String activityName,
|
||||
@Param(value = "templateStatus") Integer templateStatus) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year", "=", year);
|
||||
cnd.and(Cnd.likeEX("activityName", activityName));
|
||||
// 有模板管理角色时前端按页签传入状态;普通用户不传时保持原列表范围。
|
||||
cnd.andEX("templateStatus", "=", templateStatus);
|
||||
cnd.orderBy("createdAt", "desc");
|
||||
Pagination<FamilyActivity> pagination = familyActivityManageService.pageData(pageForm, cnd);
|
||||
List<FamilyActivity> list = pagination.getList(FamilyActivity.class);
|
||||
if (list != null && !list.isEmpty()) {
|
||||
List<String> ids = list.stream().map(FamilyActivity::getId).toList();
|
||||
List<Sys_home_template> templateList = dao.query(Sys_home_template.class, Cnd.where("id", "in", ids));
|
||||
List<String> templateIds = templateList.stream().map(Sys_home_template::getId).toList();
|
||||
list.forEach(activity -> activity.setIsTemplate(templateIds.contains(activity.getId())));
|
||||
}
|
||||
return Result.success().addData(pagination);
|
||||
return Result.success().addData(familyActivityManageService.pageData(pageForm, cnd));
|
||||
}
|
||||
|
||||
@At
|
||||
@@ -91,27 +85,9 @@ public class FamilyActivityController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
FamilyActivity activity = familyActivityManageService.fetch(id);
|
||||
if (activity == null) {
|
||||
if (!familyActivityManageService.setTemplate(id)) {
|
||||
return Result.error("活动不存在");
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = dao.fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = activity.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao.insertOrUpdate(sysHomeTemplate);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -122,7 +98,7 @@ public class FamilyActivityController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
dao.delete(Sys_home_template.class, id);
|
||||
familyActivityManageService.cancelTemplate(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -224,6 +200,8 @@ public class FamilyActivityController {
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
// 直接新建或从模板另存时明确重置状态,防止前端历史字段被带回。
|
||||
activity.setTemplateStatus(FamilyActivity.TEMPLATE_STATUS_UNSET);
|
||||
activity.setId(null);
|
||||
activity.setIsTemplate(false);
|
||||
activity.setCreatedBy(null);
|
||||
|
||||
@@ -25,6 +25,12 @@ import java.util.List;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyActivity extends BaseModel implements Serializable, SysHomeConvert {
|
||||
|
||||
/** 未设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_UNSET = 0;
|
||||
|
||||
/** 已设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_SET = 1;
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
@@ -114,6 +120,12 @@ public class FamilyActivity extends BaseModel implements Serializable, SysHomeCo
|
||||
|
||||
private Boolean isTemplate;
|
||||
|
||||
@Column
|
||||
@Comment("模板设置状态(0:未设置,1:已设置)")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
@Default("0")
|
||||
private Integer templateStatus;
|
||||
|
||||
@Column
|
||||
@Comment("活动类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
|
||||
@@ -50,6 +50,21 @@ public interface FamilyActivityService extends BaseService<FamilyActivity> {
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, Cnd cnd);
|
||||
|
||||
/**
|
||||
* 将亲子活动设置为工作模板,并同步模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return true 表示活动存在且设置成功,false 表示活动不存在
|
||||
*/
|
||||
boolean setTemplate(String id);
|
||||
|
||||
/**
|
||||
* 取消亲子活动模板,并同步模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
void cancelTemplate(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 手机端分页查询
|
||||
|
||||
+54
-1
@@ -6,6 +6,7 @@ import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.models.Sys_home_template;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.*;
|
||||
@@ -48,7 +49,8 @@ public class FamilyActivityServiceImpl extends BaseServiceImpl<FamilyActivity> i
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void add(FamilyActivity activity, FamilyCourse course) {
|
||||
|
||||
// 新建活动(包括从模板另存)统一归入活动列表,不能继承来源活动的模板状态。
|
||||
activity.setTemplateStatus(FamilyActivity.TEMPLATE_STATUS_UNSET);
|
||||
dao().insert(activity);
|
||||
|
||||
//插入类型限制
|
||||
@@ -215,6 +217,57 @@ public class FamilyActivityServiceImpl extends BaseServiceImpl<FamilyActivity> i
|
||||
return pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将亲子活动转换为工作模板,并保留模板中心已维护的展示配置。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return true 表示活动存在且设置成功,false 表示活动不存在
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public boolean setTemplate(String id) {
|
||||
FamilyActivity activity = fetch(id);
|
||||
if (activity == null) {
|
||||
return false;
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = dao().fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = activity.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
// 重复设置时保留模板中心人工配置,避免覆盖置顶、推送、排序及模板素材。
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao().insertOrUpdate(sysHomeTemplate);
|
||||
dao().update(FamilyActivity.class,
|
||||
Chain.make("templateStatus", FamilyActivity.TEMPLATE_STATUS_SET),
|
||||
Cnd.where("id", "=", id));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板中心记录并将亲子活动恢复为未设置模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void cancelTemplate(String id) {
|
||||
dao().delete(Sys_home_template.class, id);
|
||||
dao().update(FamilyActivity.class,
|
||||
Chain.make("templateStatus", FamilyActivity.TEMPLATE_STATUS_UNSET),
|
||||
Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
+7
-23
@@ -65,7 +65,8 @@ public class ActivitySportsInfoManageController {
|
||||
@Param(value = "gameStyle") String gameStyle,
|
||||
@Param(value = "query") String query,
|
||||
@Param(value = "activityId") String activityId,
|
||||
@Param(value = "activityLevel") String activityLevel) {
|
||||
@Param(value = "activityLevel") String activityLevel,
|
||||
@Param(value = "templateStatus") Integer templateStatus) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -91,13 +92,12 @@ public class ActivitySportsInfoManageController {
|
||||
school.activityCode,
|
||||
school.foundDate,
|
||||
school.applyType,
|
||||
IF(sht.id IS NULL, 0, 1) isTemplate,
|
||||
school.templateStatus isTemplate,
|
||||
(SELECT COUNT(1) FROM activity_school_apply asa WHERE asa.activityId = school.id and status=2) applyNum
|
||||
FROM
|
||||
activity_school school
|
||||
LEFT JOIN activity_basic_settings ba ON ba.`code` = school.activityLevel
|
||||
LEFT JOIN sys_union un ON un.id = school.belongUnionId
|
||||
LEFT JOIN sys_home_template sht ON sht.id = school.id
|
||||
$condition
|
||||
""");
|
||||
|
||||
@@ -121,6 +121,8 @@ public class ActivitySportsInfoManageController {
|
||||
|
||||
cnd.andEX("school.activityLevel", "=", activityLevel);
|
||||
cnd.andEX("school.gameStyle", "=", gameStyle);
|
||||
// 管理员页签传入模板状态;未展示页签的用户不传该参数,继续查询原完整列表。
|
||||
cnd.andEX("school.templateStatus", "=", templateStatus);
|
||||
cnd.andEX("YEAR(school.applyStartTime)", "=", year);
|
||||
if (StrUtil.isNotBlank(name)) {
|
||||
cnd.and(Cnd.likeEX("school.name", name));
|
||||
@@ -141,27 +143,9 @@ public class ActivitySportsInfoManageController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
ActivitySchool activitySchool = activitySportsService.fetch(id);
|
||||
if (activitySchool == null) {
|
||||
if (!activitySportsService.setTemplate(id)) {
|
||||
return Result.error("活动不存在");
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = dao.fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = activitySchool.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao.insertOrUpdate(sysHomeTemplate);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -172,7 +156,7 @@ public class ActivitySportsInfoManageController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
dao.delete(Sys_home_template.class, id);
|
||||
activitySportsService.cancelTemplate(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -64,8 +64,8 @@ public class H5ActivitySportsApplyUserController {
|
||||
|
||||
@At
|
||||
@SaCheckPermission("h5.activity.sports.applyUser")
|
||||
public Result activityData(Integer year, Integer isActivity, Integer applyStatus) {
|
||||
return Result.success(activitySportsApplyUserService.activityData(year, isActivity, applyStatus));
|
||||
public Result activityData(Integer year, Integer isActivity, Integer applyStatus, String searchKeyword) {
|
||||
return Result.success(activitySportsApplyUserService.activityData(year, isActivity, applyStatus, searchKeyword));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +171,18 @@ public class ActivitySchool extends BaseModel implements Serializable , SysHomeC
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Integer isSave;
|
||||
|
||||
/** 未设置为工作模板。 */
|
||||
public static final int TEMPLATE_STATUS_UNSET = 0;
|
||||
|
||||
/** 已设置为工作模板。 */
|
||||
public static final int TEMPLATE_STATUS_SET = 1;
|
||||
|
||||
@Column
|
||||
@Comment("模板设置状态(0:未设置 1:已设置)")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
@Default("0")
|
||||
private Integer templateStatus;
|
||||
|
||||
@Column
|
||||
@Comment("小程序活动封面")
|
||||
@ColDefine(type = ColType.VARCHAR,width = 100)
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ public class ActivitySportsApplyUserPageParam extends PageForm {
|
||||
private String applyType;
|
||||
private String isAudit;
|
||||
private String groupName;
|
||||
private String searchKeyword;
|
||||
private String activityId;
|
||||
private String eventId;
|
||||
private String year;
|
||||
|
||||
+11
@@ -19,6 +19,17 @@ public interface ActivitySportsApplyUserService extends BaseService<ActivityScho
|
||||
|
||||
Pagination activityData(Integer year, Integer isActivity,Integer applyStatus);
|
||||
|
||||
/**
|
||||
* 根据年份、活动状态、报名状态和活动名称查询体育活动。
|
||||
*
|
||||
* @param year 活动年份
|
||||
* @param isActivity 活动状态
|
||||
* @param applyStatus 当前用户报名状态
|
||||
* @param searchKeyword 活动名称模糊查询关键词
|
||||
* @return 体育活动分页数据
|
||||
*/
|
||||
Pagination activityData(Integer year, Integer isActivity, Integer applyStatus, String searchKeyword);
|
||||
|
||||
List<NutMap> getEvents(String activityId);
|
||||
|
||||
Object getUnionCoachLeaderHead(String activityId,String unionId);
|
||||
|
||||
@@ -18,5 +18,20 @@ public interface ActivitySportsService extends BaseService<ActivitySchool> {
|
||||
|
||||
void doDelete(String id);
|
||||
|
||||
/**
|
||||
* 将体育活动设置为工作模板,并同步活动表中的模板设置状态。
|
||||
*
|
||||
* @param id 体育活动ID
|
||||
* @return 活动存在且设置成功时返回 true,活动不存在时返回 false
|
||||
*/
|
||||
boolean setTemplate(String id);
|
||||
|
||||
/**
|
||||
* 取消体育活动的工作模板,并同步活动表中的模板设置状态。
|
||||
*
|
||||
* @param id 体育活动ID
|
||||
*/
|
||||
void cancelTemplate(String id);
|
||||
|
||||
void exportXlsx(String id, String unionId, HttpServletResponse response);
|
||||
}
|
||||
|
||||
+21
@@ -122,6 +122,9 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
cnd.and(new Static("(SELECT COUNT(1) FROM activity_school_apply WHERE eventId = ase.eventId AND activityId = ase.activityId AND userId='%s')%s0".formatted(SecurityUtil.getUserId(), (pageParam.getIsAudit().equals("true") ? ">" : "="))));
|
||||
}
|
||||
cnd.and("ase.activityId", "=", pageParam.getActivityId());
|
||||
if (StrUtil.isNotBlank(pageParam.getSearchKeyword())) {
|
||||
cnd.and("eve.allName", "like", "%" + pageParam.getSearchKeyword().trim() + "%");
|
||||
}
|
||||
cnd.andEX("ase.eventId", "=", pageParam.getEventId());
|
||||
cnd.andEX("YEAR(school.applyStartTime)", "=", pageParam.getYear());
|
||||
|
||||
@@ -144,6 +147,20 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
|
||||
@Override
|
||||
public Pagination activityData(Integer year, Integer isActivity, Integer applyStatus) {
|
||||
return activityData(year, isActivity, applyStatus, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据筛选条件及活动名称查询当前用户可见的体育活动。
|
||||
*
|
||||
* @param year 活动年份
|
||||
* @param isActivity 活动状态
|
||||
* @param applyStatus 当前用户报名状态
|
||||
* @param searchKeyword 活动名称模糊查询关键词
|
||||
* @return 体育活动分页数据
|
||||
*/
|
||||
@Override
|
||||
public Pagination activityData(Integer year, Integer isActivity, Integer applyStatus, String searchKeyword) {
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -183,6 +200,10 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
|
||||
cnd.and("school.isSave", "!=", true);
|
||||
|
||||
if (Lang.isNotEmpty(searchKeyword)) {
|
||||
cnd.and("school.NAME", "like", "%" + searchKeyword.trim() + "%");
|
||||
}
|
||||
|
||||
//查询报名中
|
||||
if (isActivity == 2) {
|
||||
cnd.and(new Static("now() >applyStartTime and now() < applyEndTime"));
|
||||
|
||||
+56
@@ -8,6 +8,7 @@ import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.DateUtil;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.models.Sys_home_template;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnion;
|
||||
@@ -61,6 +62,8 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
||||
}
|
||||
activitySchool.setFoundDate(DateUtil.getDate());
|
||||
activitySchool.setClose(false);
|
||||
// 新建活动只能从“未设置模板”状态开始,防止客户端提交模板状态造成数据不一致。
|
||||
activitySchool.setTemplateStatus(ActivitySchool.TEMPLATE_STATUS_UNSET);
|
||||
ActivitySchool school = insert(activitySchool);
|
||||
addTeam(school.getId(), events);
|
||||
|
||||
@@ -190,6 +193,59 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
||||
dao().delete(Sys_home_activity.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将活动内容转换为首页工作模板,并在同一事务内更新活动模板状态。
|
||||
* 重复设置时保留管理员在工作模板管理中维护的名称、图标、文件及排序配置。
|
||||
*
|
||||
* @param id 体育活动ID
|
||||
* @return 活动存在且设置成功时返回 true,否则返回 false
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public boolean setTemplate(String id) {
|
||||
ActivitySchool activitySchool = fetch(id);
|
||||
if (activitySchool == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sys_home_template oldHomeTemplate = dao().fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = activitySchool.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
// 模板业务数据随活动刷新,模板管理页面维护的展示配置继续沿用。
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao().insertOrUpdate(sysHomeTemplate);
|
||||
dao().update(ActivitySchool.class,
|
||||
Chain.make("templateStatus", ActivitySchool.TEMPLATE_STATUS_SET),
|
||||
Cnd.where("id", "=", id));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除首页工作模板,并在同一事务内将活动恢复为未设置模板状态。
|
||||
*
|
||||
* @param id 体育活动ID
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void cancelTemplate(String id) {
|
||||
dao().delete(Sys_home_template.class, id);
|
||||
dao().update(ActivitySchool.class,
|
||||
Chain.make("templateStatus", ActivitySchool.TEMPLATE_STATUS_UNSET),
|
||||
Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportXlsx(String id, String unionId, HttpServletResponse response) {
|
||||
try {
|
||||
|
||||
+7
@@ -93,6 +93,9 @@ public class TrainSignUpApplyController {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("id", "=", id);
|
||||
cnd.andEX("`year`", "=", year);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.and(Cnd.likeEX("activityName", pageForm.getSearchKeyword()));
|
||||
}
|
||||
//查询报名中
|
||||
if (activityType == 2) {
|
||||
cnd.and(new Static("now() < activitySignUpEndTime"));
|
||||
@@ -123,6 +126,7 @@ public class TrainSignUpApplyController {
|
||||
@Param(value = "courseTypeId") String courseTypeId,
|
||||
@Param(value = "activityId") String activityId,
|
||||
@Param(value = "assortTypes") String[] assortTypes,
|
||||
@Param(value = "searchKeyword") String searchKeyword,
|
||||
@Param(value = "dataType") String dataType) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -156,6 +160,9 @@ public class TrainSignUpApplyController {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("type.id", "=", courseTypeId);
|
||||
cnd.and("tsuc.activityId", "=", activityId);
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
cnd.and("tsuc.courseName", "like", "%" + searchKeyword.trim() + "%");
|
||||
}
|
||||
|
||||
if (Lang.isNotEmpty(assortTypes)) {
|
||||
cnd.and("tsuc.assort", "in", assortTypes);
|
||||
|
||||
+7
-31
@@ -6,7 +6,6 @@ import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
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.flow.entity.ProcessInstance;
|
||||
@@ -72,20 +71,15 @@ public class TrainSignUpManageController {
|
||||
@SaCheckPermission("trainSignUp.manage")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "activityName") String activityName) {
|
||||
@Param(value = "activityName") String activityName,
|
||||
@Param(value = "templateStatus") Integer templateStatus) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year", "=", year);
|
||||
cnd.and(Cnd.likeEX("activityName", activityName));
|
||||
// 具备模板管理角色时,前端按页签传入状态;普通用户不传时仍保持原列表范围。
|
||||
cnd.andEX("templateStatus", "=", templateStatus);
|
||||
cnd.orderBy("createdAt", "desc");
|
||||
Pagination<TrainSignUpActivity> pagination = trainSignUpActivityManageService.pageData(pageForm, cnd);
|
||||
List<TrainSignUpActivity> list = pagination.getList(TrainSignUpActivity.class);
|
||||
if (list != null && !list.isEmpty()) {
|
||||
List<String> ids = list.stream().map(TrainSignUpActivity::getId).toList();
|
||||
List<Sys_home_template> templateList = dao.query(Sys_home_template.class, Cnd.where("id", "in", ids));
|
||||
List<String> templateIds = templateList.stream().map(Sys_home_template::getId).toList();
|
||||
list.forEach(activity -> activity.setIsTemplate(templateIds.contains(activity.getId())));
|
||||
}
|
||||
return Result.success().addData(pagination);
|
||||
return Result.success().addData(trainSignUpActivityManageService.pageData(pageForm, cnd));
|
||||
}
|
||||
|
||||
@At
|
||||
@@ -95,27 +89,9 @@ public class TrainSignUpManageController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
TrainSignUpActivity activity = trainSignUpActivityManageService.fetch(id);
|
||||
if (activity == null) {
|
||||
if (!trainSignUpActivityManageService.setTemplate(id)) {
|
||||
return Result.error("活动不存在");
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = dao.fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = activity.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao.insertOrUpdate(sysHomeTemplate);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -126,7 +102,7 @@ public class TrainSignUpManageController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
dao.delete(Sys_home_template.class, id);
|
||||
trainSignUpActivityManageService.cancelTemplate(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ import java.util.List;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class TrainSignUpActivity extends BaseModel implements Serializable, SysHomeConvert {
|
||||
|
||||
/** 未设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_UNSET = 0;
|
||||
|
||||
/** 已设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_SET = 1;
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
@@ -112,6 +118,12 @@ public class TrainSignUpActivity extends BaseModel implements Serializable, SysH
|
||||
|
||||
private Boolean isTemplate;
|
||||
|
||||
@Column
|
||||
@Comment("模板设置状态(0:未设置,1:已设置)")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
@Default("0")
|
||||
private Integer templateStatus;
|
||||
|
||||
@Column
|
||||
@Comment("活动类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
|
||||
+15
@@ -59,6 +59,21 @@ public interface TrainSignUpActivityService extends BaseService<TrainSignUpActiv
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, Cnd cnd);
|
||||
|
||||
/**
|
||||
* 将品牌活动设置为工作模板,并同步活动表中的模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return true 表示活动存在且设置成功,false 表示活动不存在
|
||||
*/
|
||||
boolean setTemplate(String id);
|
||||
|
||||
/**
|
||||
* 取消品牌活动工作模板,并同步活动表中的模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
void cancelTemplate(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 手机端分页查询
|
||||
|
||||
+55
-1
@@ -5,6 +5,7 @@ import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.models.Sys_home_template;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyActivity;
|
||||
@@ -53,7 +54,8 @@ public class TrainSignUpActivityServiceImpl extends BaseServiceImpl<TrainSignUpA
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void add(TrainSignUpActivity activity, TrainSignUpCourse course) {
|
||||
|
||||
// 新建活动(包括从模板另存)统一归入活动列表,不能继承来源活动的模板状态。
|
||||
activity.setTemplateStatus(TrainSignUpActivity.TEMPLATE_STATUS_UNSET);
|
||||
dao().insert(activity);
|
||||
|
||||
//插入类型限制
|
||||
@@ -289,6 +291,58 @@ public class TrainSignUpActivityServiceImpl extends BaseServiceImpl<TrainSignUpA
|
||||
return pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将品牌活动转换为工作模板,并原样保留模板中心已维护的展示配置。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return true 表示活动存在且设置成功,false 表示活动不存在
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public boolean setTemplate(String id) {
|
||||
TrainSignUpActivity activity = fetch(id);
|
||||
if (activity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sys_home_template oldHomeTemplate = dao().fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = activity.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
// 重复设置时保留模板中心人工配置,避免覆盖置顶、推送、排序及模板素材。
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao().insertOrUpdate(sysHomeTemplate);
|
||||
dao().update(TrainSignUpActivity.class,
|
||||
Chain.make("templateStatus", TrainSignUpActivity.TEMPLATE_STATUS_SET),
|
||||
Cnd.where("id", "=", id));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板中心记录并将活动恢复为未设置模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void cancelTemplate(String id) {
|
||||
dao().delete(Sys_home_template.class, id);
|
||||
dao().update(TrainSignUpActivity.class,
|
||||
Chain.make("templateStatus", TrainSignUpActivity.TEMPLATE_STATUS_UNSET),
|
||||
Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
+6
-49
@@ -7,10 +7,8 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HtmlUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
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.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.models.Sys_home_template;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
@@ -53,8 +51,6 @@ public class ActivityWorksCollectionManageController {
|
||||
@Inject
|
||||
private ActivityWorksCollectionService activityWorksCollectionService;
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private SysMsgService sysMsgService;
|
||||
@Inject
|
||||
private ActivityBasicScopeService activityBasicScopeService;
|
||||
@@ -67,31 +63,8 @@ public class ActivityWorksCollectionManageController {
|
||||
|
||||
@At
|
||||
@SaCheckPermission("activity.workscollection.manage")
|
||||
public Result pageData(@Valid PageForm pageForm, Long year) {
|
||||
Sql sql = Sqls.create("""
|
||||
select
|
||||
wc.id,
|
||||
wc.name,
|
||||
wc.createdAt,
|
||||
wc.startDateTime,
|
||||
wc.endDateTime,
|
||||
wc.enable,
|
||||
IF(sht.id IS NULL, 0, 1) isTemplate,
|
||||
u.username as userName
|
||||
from
|
||||
activity_works_collection wc
|
||||
LEFT JOIN vw_user u on u.id = wc.createdBy
|
||||
LEFT JOIN sys_home_template sht ON sht.id = wc.id
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year(startDateTime)", "=", year);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.where().andLike("name", pageForm.getSearchKeyword());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
public Result pageData(@Valid PageForm pageForm, Long year, Integer templateStatus) {
|
||||
return Result.success(activityWorksCollectionService.pageData(pageForm, year, templateStatus));
|
||||
}
|
||||
|
||||
@At
|
||||
@@ -100,27 +73,9 @@ public class ActivityWorksCollectionManageController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
Activity_works_collection worksCollection = dao.fetch(Activity_works_collection.class, id);
|
||||
if (worksCollection == null) {
|
||||
if (!activityWorksCollectionService.setTemplate(id)) {
|
||||
return Result.error("活动不存在");
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = dao.fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = worksCollection.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao.insertOrUpdate(sysHomeTemplate);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -130,7 +85,7 @@ public class ActivityWorksCollectionManageController {
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
return Result.error("无权操作");
|
||||
}
|
||||
dao.delete(Sys_home_template.class, id);
|
||||
activityWorksCollectionService.cancelTemplate(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -165,6 +120,8 @@ public class ActivityWorksCollectionManageController {
|
||||
if (worksCollection == null) {
|
||||
return;
|
||||
}
|
||||
// 新建或从模板另存的活动必须进入活动列表,不能继承来源活动的模板状态。
|
||||
worksCollection.setTemplateStatus(Activity_works_collection.TEMPLATE_STATUS_UNSET);
|
||||
worksCollection.setId(null);
|
||||
worksCollection.setCreatedBy(null);
|
||||
worksCollection.setCreatedAt(null);
|
||||
|
||||
+12
@@ -22,6 +22,12 @@ import java.util.List;
|
||||
@Comment("作品征集活动")
|
||||
public class Activity_works_collection extends BaseModel implements SysHomeConvert {
|
||||
|
||||
/** 未设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_UNSET = 0;
|
||||
|
||||
/** 已设置为活动模板。 */
|
||||
public static final int TEMPLATE_STATUS_SET = 1;
|
||||
|
||||
@Name
|
||||
@Comment("ID")
|
||||
@PrevInsert(uu32 = true)
|
||||
@@ -110,6 +116,12 @@ public class Activity_works_collection extends BaseModel implements SysHomeConve
|
||||
@Default(value = "1")
|
||||
private Boolean isSubmit;
|
||||
|
||||
@Column
|
||||
@Comment("模板设置状态(0:未设置,1:已设置)")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
@Default("0")
|
||||
private Integer templateStatus;
|
||||
|
||||
@Column
|
||||
@Comment("主办单位")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
|
||||
+29
-1
@@ -1,11 +1,39 @@
|
||||
package com.budwk.app.zhgh.activity.workscollection.service;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection;
|
||||
|
||||
/**
|
||||
* 作品征集活动配置服务。
|
||||
*/
|
||||
public interface ActivityWorksCollectionService {
|
||||
public interface ActivityWorksCollectionService extends BaseService<Activity_works_collection> {
|
||||
|
||||
/**
|
||||
* 分页查询作品征集活动。
|
||||
*
|
||||
* @param pageForm 分页及关键字参数
|
||||
* @param year 活动年度
|
||||
* @param templateStatus 模板设置状态,为空时不限制
|
||||
* @return 作品征集活动分页数据
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, Long year, Integer templateStatus);
|
||||
|
||||
/**
|
||||
* 将作品征集活动设置为工作模板,并同步模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
* @return true 表示设置成功,false 表示活动不存在
|
||||
*/
|
||||
boolean setTemplate(String id);
|
||||
|
||||
/**
|
||||
* 取消作品征集活动模板,并同步模板状态。
|
||||
*
|
||||
* @param id 活动ID
|
||||
*/
|
||||
void cancelTemplate(String id);
|
||||
|
||||
/**
|
||||
* 校验编辑活动时删除的主题类型、作品类型是否已被投稿引用。
|
||||
|
||||
+89
-1
@@ -2,13 +2,22 @@ package com.budwk.app.zhgh.activity.workscollection.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_home_template;
|
||||
import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection;
|
||||
import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection_upload;
|
||||
import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_subjectType;
|
||||
import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_worksType;
|
||||
import com.budwk.app.zhgh.activity.workscollection.service.ActivityWorksCollectionService;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
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.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -20,14 +29,93 @@ import java.util.stream.Collectors;
|
||||
* 作品征集活动配置服务实现。
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class ActivityWorksCollectionServiceImpl implements ActivityWorksCollectionService {
|
||||
public class ActivityWorksCollectionServiceImpl extends BaseServiceImpl<Activity_works_collection> implements ActivityWorksCollectionService {
|
||||
|
||||
private final Dao dao;
|
||||
|
||||
public ActivityWorksCollectionServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按年度、关键字及模板状态分页查询作品征集活动。
|
||||
*/
|
||||
@Override
|
||||
public Pagination pageData(PageForm pageForm, Long year, Integer templateStatus) {
|
||||
Sql sql = Sqls.create("""
|
||||
select
|
||||
wc.id,
|
||||
wc.name,
|
||||
wc.createdAt,
|
||||
wc.startDateTime,
|
||||
wc.endDateTime,
|
||||
wc.enable,
|
||||
wc.templateStatus,
|
||||
wc.templateStatus isTemplate,
|
||||
u.username as userName
|
||||
from
|
||||
activity_works_collection wc
|
||||
LEFT JOIN vw_user u on u.id = wc.createdBy
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year(wc.startDateTime)", "=", year);
|
||||
cnd.andEX("wc.templateStatus", "=", templateStatus);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.where().andLike("wc.name", pageForm.getSearchKeyword());
|
||||
}
|
||||
cnd.desc("wc.createdAt");
|
||||
sql.setCondition(cnd);
|
||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将作品征集活动转换为工作模板,并保留模板中心已维护的展示配置。
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public boolean setTemplate(String id) {
|
||||
Activity_works_collection worksCollection = dao.fetch(Activity_works_collection.class, id);
|
||||
if (worksCollection == null) {
|
||||
return false;
|
||||
}
|
||||
Sys_home_template oldHomeTemplate = dao.fetch(Sys_home_template.class, id);
|
||||
Sys_home_template sysHomeTemplate = worksCollection.covertToSysHomeTemplate();
|
||||
if (oldHomeTemplate != null) {
|
||||
// 重复设置时保留模板中心人工配置,避免覆盖置顶、推送、排序及模板素材。
|
||||
sysHomeTemplate.setTop(oldHomeTemplate.getTop());
|
||||
sysHomeTemplate.setPush(oldHomeTemplate.getPush());
|
||||
sysHomeTemplate.setSortNo(oldHomeTemplate.getSortNo());
|
||||
if (oldHomeTemplate.getTemplateName() != null) {
|
||||
sysHomeTemplate.setTemplateName(oldHomeTemplate.getTemplateName());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateIcon() != null) {
|
||||
sysHomeTemplate.setTemplateIcon(oldHomeTemplate.getTemplateIcon());
|
||||
}
|
||||
if (oldHomeTemplate.getTemplateFile() != null) {
|
||||
sysHomeTemplate.setTemplateFile(oldHomeTemplate.getTemplateFile());
|
||||
}
|
||||
}
|
||||
dao.insertOrUpdate(sysHomeTemplate);
|
||||
dao.update(Activity_works_collection.class,
|
||||
Chain.make("templateStatus", Activity_works_collection.TEMPLATE_STATUS_SET),
|
||||
Cnd.where("id", "=", id));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板中心记录并将作品征集活动恢复为未设置模板状态。
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void cancelTemplate(String id) {
|
||||
dao.delete(Sys_home_template.class, id);
|
||||
dao.update(Activity_works_collection.class,
|
||||
Chain.make("templateStatus", Activity_works_collection.TEMPLATE_STATUS_UNSET),
|
||||
Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validateReferencedTypesBeforeUpdate(Activity_works_collection worksCollection) {
|
||||
if (worksCollection == null || StrUtil.isBlank(worksCollection.getId())) {
|
||||
|
||||
+4
-2
@@ -76,7 +76,8 @@ public class ClubExamineApplyController {
|
||||
if(year == null) {
|
||||
return Result.error("年份信息为空,请核查");
|
||||
}
|
||||
List<SysClubExamineRegister> list = dao.query(SysClubExamineRegister.class, Cnd.where("clubId", "=", clubId).and("year(registerDate)", "=", year).andEX("id", "!=", id));
|
||||
// 同一社团的年度重复申请校验以登记年度为准,不能按申请时间判断。
|
||||
List<SysClubExamineRegister> list = dao.query(SysClubExamineRegister.class, Cnd.where("clubId", "=", clubId).and("year", "=", year).andEX("id", "!=", id));
|
||||
List<ProcessInstance> instanceList = dao.query(
|
||||
ProcessInstance.class,
|
||||
Cnd.where(ProcessInstance::getBusinessNo, "in", list.stream().map(SysClubExamineRegister::getId).toList())
|
||||
@@ -146,8 +147,9 @@ public class ClubExamineApplyController {
|
||||
if(StrUtil.isBlank(clubId)) {
|
||||
return Result.error("社团信息为空,请核查");
|
||||
}
|
||||
// 上年度结余按登记年度查询,避免申请时间跨年导致取错数据。
|
||||
SysClubExamineRegister register = dao.fetch(SysClubExamineRegister.class, Cnd.where("clubId", "=", clubId)
|
||||
.and("YEAR(registerDate)", "=", DateUtil.thisYear() - 1));
|
||||
.and("year", "=", DateUtil.thisYear() - 1));
|
||||
if (Lang.isNotEmpty(register)) {
|
||||
List<JSONObject> list = register.getIncomeCensus();
|
||||
float surplus = list.get(0).getFloat("surplus");
|
||||
|
||||
+2
-1
@@ -87,7 +87,8 @@ public class ClubExamineMineController {
|
||||
nutMap.setv("clubName", register.getClubName());
|
||||
nutMap.setv("create_time", register.getFoundTime());
|
||||
nutMap.setv("dues_standard", register.getDue());
|
||||
nutMap.setv("year", register.getRegisterDate().substring(0, 4));
|
||||
// 生成材料中的年度与列表展示的登记年度保持一致。
|
||||
nutMap.setv("year", register.getYear());
|
||||
nutMap.setv("registerDate", register.getRegisterDate());
|
||||
nutMap.setv("incomeCensus", incomeCensus);
|
||||
nutMap.setv("jgUser", jgUser);
|
||||
|
||||
+3
-1
@@ -90,10 +90,12 @@ public class ClubAuditManagerController {
|
||||
cnd.andEX("year(info.creatTime)", "=", pageForm.getYear());
|
||||
|
||||
cnd.and("t.taskName", "=", "ef81777f-22fb-4fe4-9800-909e6c681210");
|
||||
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
|
||||
if (approval) {
|
||||
// 已审核是全量历史,不能因历史工作流参与人不同而遗漏参考库迁移记录。
|
||||
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
|
||||
} else {
|
||||
// 未审核只展示当前登录人实际可以处理的待办任务。
|
||||
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
|
||||
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
}
|
||||
|
||||
|
||||
+145
-3
@@ -2,10 +2,14 @@ package com.budwk.app.zhgh.club.controller.infoManage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.sys.models.Sys_file;
|
||||
import com.budwk.app.sys.utils.SysFileMinIoUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.club.param.ClubUserPageForm;
|
||||
import com.budwk.app.zhgh.club.service.SysClubInfoManageService;
|
||||
@@ -14,12 +18,24 @@ 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.json.Json;
|
||||
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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* @Author: JyuHsin
|
||||
@@ -32,6 +48,8 @@ import java.util.List;
|
||||
@At("/platform/club/infoManage/schoolAuditReport")
|
||||
public class ClubSchoolAuditReportController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ClubSchoolAuditReportController.class);
|
||||
|
||||
@Inject
|
||||
private SysClubInfoManageService clubInfoManageService;
|
||||
|
||||
@@ -44,6 +62,71 @@ public class ClubSchoolAuditReportController {
|
||||
@SaCheckPermission("club.infoManage.schoolAuditReport")
|
||||
public Result pageData(@Valid ClubUserPageForm pageForm,
|
||||
@Param(value = "approval") Boolean approval) {
|
||||
Sql sql = buildPageDataSql(pageForm, approval);
|
||||
Pagination pagination = clubInfoManageService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出当前筛选范围内的换届报告附件压缩包。
|
||||
*
|
||||
* @param pageForm 页面查询条件
|
||||
* @param approval 审核状态,与列表页保持一致
|
||||
* @param response HTTP 下载响应
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("club.infoManage.schoolAuditReport")
|
||||
public void exportRefreshReportZip(@Valid ClubUserPageForm pageForm,
|
||||
@Param(value = "approval") Boolean approval,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<NutMap> reportList = clubInfoManageService.listMap(buildPageDataSql(pageForm, approval));
|
||||
response.setContentType("application/zip");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode("换届报告.zip"));
|
||||
|
||||
// 显式指定 UTF-8,确保压缩包内中文目录和文件名正常显示。
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()), StandardCharsets.UTF_8)) {
|
||||
Set<String> entryNames = new HashSet<>();
|
||||
for (NutMap report : reportList) {
|
||||
String filesJson = report.getString("files");
|
||||
if (StrUtil.isBlank(filesJson)) {
|
||||
continue;
|
||||
}
|
||||
List<JSONObject> files = Json.fromJsonAsList(JSONObject.class, filesJson);
|
||||
String folderName = buildFolderName(report);
|
||||
for (int index = 0; index < files.size(); index++) {
|
||||
JSONObject fileInfo = files.get(index);
|
||||
Sys_file sysFile = findSysFile(fileInfo);
|
||||
if (sysFile == null) {
|
||||
log.warn("换届报告附件不存在,报告ID:{},附件:{}", report.getString("id"), fileInfo);
|
||||
continue;
|
||||
}
|
||||
byte[] fileBytes = SysFileMinIoUtil.getFileBytes(sysFile.getBucket(), sysFile.getStoragePath());
|
||||
if (fileBytes == null || fileBytes.length == 0) {
|
||||
log.warn("换届报告附件内容为空,报告ID:{},附件ID:{}", report.getString("id"), sysFile.getId());
|
||||
continue;
|
||||
}
|
||||
String fileName = StrUtil.blankToDefault(fileInfo.getStr("name"), fileInfo.getStr("filename"));
|
||||
if (StrUtil.isBlank(fileName)) {
|
||||
fileName = sysFile.getName();
|
||||
}
|
||||
String entryName = buildUniqueEntryName(folderName + "/" + sanitizeFileName(fileName), entryNames);
|
||||
zipOutputStream.putNextEntry(new ZipEntry(entryName));
|
||||
zipOutputStream.write(fileBytes);
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建列表与导出共用的换届报告查询,确保“查什么导什么”。
|
||||
*
|
||||
* @param pageForm 页面查询条件
|
||||
* @param approval 审核状态
|
||||
* @return 已绑定筛选条件的查询对象
|
||||
*/
|
||||
private Sql buildPageDataSql(ClubUserPageForm pageForm, Boolean approval) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
@@ -79,7 +162,7 @@ public class ClubSchoolAuditReportController {
|
||||
|
||||
cnd.and("t.taskName", "=", "d4323546-8d09-419e-88d4-7b15862ca29d");
|
||||
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
|
||||
if (approval) {
|
||||
if (Boolean.TRUE.equals(approval)) {
|
||||
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
|
||||
} else {
|
||||
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
@@ -96,8 +179,67 @@ public class ClubSchoolAuditReportController {
|
||||
|
||||
cnd.groupBy("t.id");
|
||||
sql.setCondition(cnd);
|
||||
return sql;
|
||||
}
|
||||
|
||||
Pagination pagination = clubInfoManageService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
/**
|
||||
* 兼容新旧附件 JSON 结构,按附件 ID 或下载地址查找文件元数据。
|
||||
*
|
||||
* @param fileInfo 附件 JSON 信息
|
||||
* @return 系统文件记录;未找到时返回 null
|
||||
*/
|
||||
private Sys_file findSysFile(JSONObject fileInfo) {
|
||||
String fileId = fileInfo.getStr("id");
|
||||
if (StrUtil.isNotBlank(fileId)) {
|
||||
return clubInfoManageService.dao().fetch(Sys_file.class, fileId);
|
||||
}
|
||||
String fileUrl = fileInfo.getStr("url");
|
||||
if (StrUtil.isBlank(fileUrl)) {
|
||||
return null;
|
||||
}
|
||||
return clubInfoManageService.dao().fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", fileUrl));
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用社团名称建立目录,方便按换届报告来源查阅。
|
||||
*
|
||||
* @param report 换届报告记录
|
||||
* @return Zip 内目录名称
|
||||
*/
|
||||
private String buildFolderName(NutMap report) {
|
||||
return sanitizeFileName(report.getString("clubName"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留附件原始文件名;同一社团目录存在同名文件时追加序号,避免覆盖。
|
||||
*
|
||||
* @param entryName 原始 Zip 条目名称
|
||||
* @param entryNames 已写入的 Zip 条目名称
|
||||
* @return 唯一的 Zip 条目名称
|
||||
*/
|
||||
private String buildUniqueEntryName(String entryName, Set<String> entryNames) {
|
||||
if (entryNames.add(entryName)) {
|
||||
return entryName;
|
||||
}
|
||||
int extensionIndex = entryName.lastIndexOf('.');
|
||||
String name = extensionIndex > entryName.lastIndexOf('/') ? entryName.substring(0, extensionIndex) : entryName;
|
||||
String extension = extensionIndex > entryName.lastIndexOf('/') ? entryName.substring(extensionIndex) : "";
|
||||
int index = 2;
|
||||
String uniqueEntryName;
|
||||
do {
|
||||
uniqueEntryName = name + "(" + index + ")" + extension;
|
||||
index++;
|
||||
} while (!entryNames.add(uniqueEntryName));
|
||||
return uniqueEntryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除 Zip 条目路径分隔符,避免附件名影响压缩包目录结构。
|
||||
*
|
||||
* @param fileName 原始文件名
|
||||
* @return 可安全写入 Zip 的文件名
|
||||
*/
|
||||
private String sanitizeFileName(String fileName) {
|
||||
return StrUtil.blankToDefault(fileName, "未命名文件").replace("/", "_").replace("\\", "_");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,14 @@ public class SysClubExamineRegister extends BaseModel {
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<JSONObject> yearActivityList;
|
||||
|
||||
/**
|
||||
* 旧版年审表保存的年度活动明细,保留该字段用于查看迁移历史数据。
|
||||
*/
|
||||
@Column
|
||||
@Comment("旧版年度活动明细")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<JSONObject> yearActivitys;
|
||||
|
||||
@Column
|
||||
@Comment("财务收支情况统计json")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
|
||||
@@ -24,6 +24,10 @@ public class ClubUserPageForm extends PageForm {
|
||||
private Integer auditType;
|
||||
private Integer source;
|
||||
private Integer year;
|
||||
/** 社团评优申报开始年度筛选条件。 */
|
||||
private String applyStartYear;
|
||||
/** 社团评优申报结束年度筛选条件。 */
|
||||
private String applyEndYear;
|
||||
private Boolean giveMoney;
|
||||
private Integer radioType;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,9 @@ public class SysClubEvaluateServiceImpl extends BaseServiceImpl<SysClubEvaluate>
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
cnd.andEX("info.clubId", "=", pageForm.getClubId());
|
||||
cnd.andEX("year(info.applyTime)", "=", pageForm.getYear());
|
||||
// 评优年度以申报填写的起止年度为准,不能使用申请提交时间所在年份代替。
|
||||
cnd.andEX("info.applyStartYear", "=", pageForm.getApplyStartYear());
|
||||
cnd.andEX("info.applyEndYear", "=", pageForm.getApplyEndYear());
|
||||
cnd.and("info.userId", "=", SecurityUtil.getUserId());
|
||||
|
||||
cnd.groupBy("info.id");
|
||||
@@ -144,7 +146,9 @@ public class SysClubEvaluateServiceImpl extends BaseServiceImpl<SysClubEvaluate>
|
||||
""");
|
||||
|
||||
cnd.andEX("ce.clubId", "=", pageForm.getClubId());
|
||||
cnd.andEX("year(ce.applyTime)", "=", pageForm.getYear());
|
||||
// 审核列表与参考项目保持一致,分别按申报开始年度和申报结束年度筛选。
|
||||
cnd.andEX("ce.applyStartYear", "=", pageForm.getApplyStartYear());
|
||||
cnd.andEX("ce.applyEndYear", "=", pageForm.getApplyEndYear());
|
||||
|
||||
if (pageForm.getAudit()) {
|
||||
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
@@ -33,8 +34,10 @@ import org.nutz.lang.util.NutMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
@@ -119,6 +122,7 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
||||
Sql applySql = Sqls.create("""
|
||||
SELECT
|
||||
cu.userId,
|
||||
cu.id,
|
||||
cu.mode,
|
||||
cu.applyDate,
|
||||
cu.joinTime,
|
||||
@@ -129,17 +133,25 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
||||
LEFT JOIN sys_user u ON u.id = cu.userId
|
||||
WHERE cu.clubId = @clubId
|
||||
AND COALESCE(cu.delFlag, 0) = 0
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM wf_process_instance ins
|
||||
WHERE ins.businessNo = cu.id
|
||||
AND ins.state = @finishedState
|
||||
)
|
||||
ORDER BY cu.applyDate, cu.mode
|
||||
""")
|
||||
.setParam("clubId", clubId)
|
||||
.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode());
|
||||
.setParam("clubId", clubId);
|
||||
List<NutMap> applications = listMap(applySql);
|
||||
if (!applications.isEmpty()) {
|
||||
// 流程状态改为按当前社团申请批量查询,避免相关子查询对流程实例表重复扫描。
|
||||
List<String> applicationIds = applications.stream()
|
||||
.map(application -> application.getString("id"))
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toList());
|
||||
List<ProcessInstance> finishedInstances = applicationIds.isEmpty() ? new ArrayList<>()
|
||||
: dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", applicationIds)
|
||||
.and(ProcessInstance::getState, "=", ProcessInstanceStateEnum.FINISHED.getCode()));
|
||||
Set<String> finishedBusinessNos = finishedInstances.stream()
|
||||
.map(ProcessInstance::getBusinessNo)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
applications.removeIf(application -> !finishedBusinessNos.contains(application.getString("id")));
|
||||
}
|
||||
applications.sort(Comparator.comparing(row -> row.getTime("applyDate"), Comparator.nullsLast(Date::compareTo)));
|
||||
|
||||
for (NutMap application : applications) {
|
||||
@@ -259,6 +271,10 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
||||
}
|
||||
|
||||
private String normalizeUserState(String userState) {
|
||||
// 历史成员数据可能未同步人员状态,空值不参与在职、退休人数统计。
|
||||
if (StrUtil.isBlank(userState)) {
|
||||
return null;
|
||||
}
|
||||
if (List.of("在职", "在岗").contains(userState)) {
|
||||
return "在职";
|
||||
}
|
||||
@@ -476,6 +492,8 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
||||
// 查询主表数据并关联明细数据
|
||||
ClubExamineVo clubExamineVo = fetchVO(sql, ClubExamineVo.class);
|
||||
if (Lang.isNotEmpty(clubExamineVo)) {
|
||||
// 详情页统一使用V4字段,兼容尚未改写JSON内容的V3年审记录。
|
||||
normalizeActivityData(clubExamineVo);
|
||||
List<SysClubExamineRegisterDetailed> detailedList = dao().query(SysClubExamineRegisterDetailed.class,
|
||||
Cnd.where("registerId", "=", id).asc("location"));
|
||||
clubExamineVo.setDetailedList(detailedList);
|
||||
@@ -512,6 +530,116 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
||||
return clubExamineVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将旧版年审活动和计划字段转换为查看页统一使用的V4字段,避免历史数据在页面中显示为空。
|
||||
*
|
||||
* @param examineVo 年审详情
|
||||
*/
|
||||
private void normalizeActivityData(ClubExamineVo examineVo) {
|
||||
examineVo.setSummaryFiles(normalizeSummaryFiles(examineVo.getSummaryFiles()));
|
||||
examineVo.setChangeUserNum(normalizeChangeUserNum(examineVo.getChangeUserNum()));
|
||||
List<JSONObject> yearActivitySource = examineVo.getYearActivityList();
|
||||
if (yearActivitySource == null || yearActivitySource.isEmpty()) {
|
||||
yearActivitySource = examineVo.getYearActivitys();
|
||||
}
|
||||
examineVo.setYearActivityList(yearActivitySource == null ? new ArrayList<>()
|
||||
: yearActivitySource.stream()
|
||||
.map(item -> normalizeActivityItem(item, true))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
List<JSONObject> planSource = examineVo.getPlans();
|
||||
examineVo.setPlans(planSource == null ? new ArrayList<>()
|
||||
: planSource.stream()
|
||||
.map(item -> normalizeActivityItem(item, false))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将V3年审记录中的年度减少字段转换为查看页统一使用的V4字段。
|
||||
* 历史年审必须展示申请时保存的数据,不能按当前会员状态重新统计。
|
||||
*
|
||||
* @param changeUserNum 年审记录保存的成员变化数据
|
||||
* @return 兼容V3、V4字段的成员变化数据
|
||||
*/
|
||||
private List<JSONObject> normalizeChangeUserNum(List<JSONObject> changeUserNum) {
|
||||
if (changeUserNum == null || changeUserNum.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return changeUserNum.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.peek(item -> {
|
||||
if (!item.containsKey("yearReduceNum") && item.containsKey("yearEditNum")) {
|
||||
item.set("yearReduceNum", item.get("yearEditNum"));
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将V3工作总结附件的文件主键包装为V4文件预览组件所需的response.data格式。
|
||||
*
|
||||
* @param summaryFiles 原始工作总结附件
|
||||
* @return 可供文件预览组件读取的附件数据
|
||||
*/
|
||||
private List<JSONObject> normalizeSummaryFiles(List<JSONObject> summaryFiles) {
|
||||
if (summaryFiles == null || summaryFiles.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return summaryFiles.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(file -> {
|
||||
JSONObject response = file.getJSONObject("response");
|
||||
if (response != null && StrUtil.isNotBlank(response.getStr("data"))) {
|
||||
return file;
|
||||
}
|
||||
String fileId = file.getStr("id");
|
||||
if (StrUtil.isBlank(fileId)) {
|
||||
return null;
|
||||
}
|
||||
JSONObject normalizedFile = new JSONObject();
|
||||
normalizedFile.set("response", new JSONObject().set("data", fileId));
|
||||
return normalizedFile;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 兼容V3活动字段(hdsj、mc、zbdw、hddd、cjrs、hjqk)和V4活动字段。
|
||||
*
|
||||
* @param source 原始活动或计划数据
|
||||
* @param includeResult 是否包含本年度活动的参加人数和获奖情况
|
||||
* @return 供查看页使用的统一字段数据
|
||||
*/
|
||||
private JSONObject normalizeActivityItem(JSONObject source, boolean includeResult) {
|
||||
JSONObject item = new JSONObject();
|
||||
item.set("activityName", getActivityValue(source, "activityName", "mc"));
|
||||
item.set("activityUnit", getActivityValue(source, "activityUnit", "zbdw"));
|
||||
item.set("activityAddress", getActivityValue(source, "activityAddress", "hddd"));
|
||||
if (includeResult) {
|
||||
item.set("activityTime", getActivityValue(source, "activityTime", "hdsj"));
|
||||
item.set("joinNum", getActivityValue(source, "joinNum", "cjrs"));
|
||||
item.set("prize", getActivityValue(source, "prize", "hjqk"));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优先读取V4字段;历史记录没有该字段时回退读取对应的V3字段。
|
||||
*
|
||||
* @param source 原始JSON数据
|
||||
* @param currentField V4字段名
|
||||
* @param legacyField V3字段名
|
||||
* @return 兼容后的字段值
|
||||
*/
|
||||
private String getActivityValue(JSONObject source, String currentField, String legacyField) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
String currentValue = source.getStr(currentField);
|
||||
return StrUtil.isNotBlank(currentValue) ? currentValue : source.getStr(legacyField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> getYearActivityExportData(String id) {
|
||||
ClubExamineVo examineVo = this.findOne(id);
|
||||
@@ -619,7 +747,8 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
||||
*/
|
||||
private void buildPageBaseCondition(Cnd cnd, ClubUserPageForm pageForm, String tableAlias) {
|
||||
if (pageForm.getYear() != null) {
|
||||
cnd.andEX("YEAR(" + tableAlias + ".registerDate)", "=", pageForm.getYear());
|
||||
// 年度查询应与列表展示的登记年度保持一致,不能使用申请时间推算年度。
|
||||
cnd.andEX(tableAlias + ".year", "=", pageForm.getYear());
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageForm.getClubId())) {
|
||||
cnd.andEX(tableAlias + ".clubId", "=", pageForm.getClubId());
|
||||
|
||||
@@ -17,6 +17,10 @@ public class ClubEvaluatePageVo {
|
||||
private String foundTime;
|
||||
private String typeName;
|
||||
private Date applyTime;
|
||||
/** 社团评优申报开始年度。 */
|
||||
private String applyStartYear;
|
||||
/** 社团评优申报结束年度。 */
|
||||
private String applyEndYear;
|
||||
|
||||
private String instanceId;
|
||||
private String businessNo;
|
||||
|
||||
+47
-11
@@ -11,6 +11,7 @@ import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.nutz.dao.Cnd;
|
||||
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;
|
||||
@@ -43,22 +44,26 @@ public class ArticleAnalysisController {
|
||||
@At
|
||||
@SaCheckPermission("article.analysis")
|
||||
@ApiOperation(value = "统计分析")
|
||||
public Result overview() {
|
||||
public Result overview(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
List<ArticleAnalysisOverviewVO> list = new ArrayList<>();
|
||||
|
||||
// 获取总投稿量
|
||||
list.add(ArticleAnalysisOverviewVO.builder()
|
||||
.label("总投稿量")
|
||||
.value(articleService.count())
|
||||
.value(articleService.count(buildStatisticsCondition(startDate, endDate, unionId, clubId)))
|
||||
.icon("el-icon-document")
|
||||
.bgColor("rgba(24, 103, 176, 0.1)")
|
||||
.trend(null)
|
||||
.build());
|
||||
|
||||
// 获取本月投稿量
|
||||
long monthlyCount = articleService.count(Cnd.where("MONTH(submitTime)", "=", DateUtil.thisMonth() + 1));
|
||||
Cnd monthlyCondition = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
monthlyCondition.and("MONTH(submitTime)", "=", DateUtil.thisMonth() + 1);
|
||||
long monthlyCount = articleService.count(monthlyCondition);
|
||||
//上月投稿量
|
||||
long lastMonthCount = articleService.count(Cnd.where("MONTH(submitTime)", "=", DateUtil.offsetMonth(new Date(), -1)));
|
||||
Cnd lastMonthCondition = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
lastMonthCondition.and("MONTH(submitTime)", "=", DateUtil.month(DateUtil.offsetMonth(new Date(), -1)) + 1);
|
||||
long lastMonthCount = articleService.count(lastMonthCondition);
|
||||
|
||||
list.add(ArticleAnalysisOverviewVO.builder()
|
||||
.label("本月投稿")
|
||||
@@ -70,7 +75,9 @@ public class ArticleAnalysisController {
|
||||
|
||||
// 获取活跃投稿人数
|
||||
DateTime dateTime = DateUtil.offsetMonth(new Date(), -1);
|
||||
long activeUsers = Math.max(articleService.count(Cnd.where("submitTime", ">=", dateTime).groupBy("userId")), 0L);
|
||||
Cnd activeUserCondition = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
activeUserCondition.and("submitTime", ">=", dateTime).groupBy("userId");
|
||||
long activeUsers = Math.max(articleService.count(activeUserCondition), 0L);
|
||||
list.add(ArticleAnalysisOverviewVO.builder()
|
||||
.label("活跃投稿人")
|
||||
.value(activeUsers)
|
||||
@@ -81,7 +88,11 @@ public class ArticleAnalysisController {
|
||||
|
||||
|
||||
// 获取参与分工会数量
|
||||
long unionCount = articleService.count(Sqls.create("SELECT COUNT(distinct unionId) FROM article WHERE unionId IS NOT NULL"));
|
||||
Sql unionCountSql = Sqls.create("SELECT COUNT(distinct unionId) FROM article $condition");
|
||||
Cnd unionCountCondition = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
unionCountCondition.and("unionId", "IS NOT", null);
|
||||
unionCountSql.setCondition(unionCountCondition);
|
||||
long unionCount = articleService.count(unionCountSql);
|
||||
list.add(ArticleAnalysisOverviewVO.builder()
|
||||
.label("参与分工会")
|
||||
.value(unionCount)
|
||||
@@ -91,7 +102,11 @@ public class ArticleAnalysisController {
|
||||
.build());
|
||||
|
||||
// 获取参与社团数量
|
||||
long clubCount = articleService.count(Sqls.create("SELECT COUNT(distinct clubId) FROM article WHERE clubId IS NOT NULL"));
|
||||
Sql clubCountSql = Sqls.create("SELECT COUNT(distinct clubId) FROM article $condition");
|
||||
Cnd clubCountCondition = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
clubCountCondition.and("clubId", "IS NOT", null);
|
||||
clubCountSql.setCondition(clubCountCondition);
|
||||
long clubCount = articleService.count(clubCountSql);
|
||||
list.add(ArticleAnalysisOverviewVO.builder()
|
||||
.label("参与社团")
|
||||
.value(clubCount)
|
||||
@@ -102,22 +117,43 @@ public class ArticleAnalysisController {
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建概览统计的筛选条件,与图表接口保持相同的时间范围、分工会和社团口径。
|
||||
*/
|
||||
private Cnd buildStatisticsCondition(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (startDate != null && endDate != null) {
|
||||
cnd.and(Cnd.cri().where().andBetween("submitTime", startDate, endDate));
|
||||
}
|
||||
cnd.andEX("unionId", "=", unionId);
|
||||
cnd.andEX("clubId", "=", clubId);
|
||||
return cnd;
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("article.analysis")
|
||||
@ApiOperation(value = "投稿趋势")
|
||||
public Result trend(@Valid String type, Date startDate, Date endDate) {
|
||||
List<NutMap> submissionTrend = articleAnalysisService.getSubmissionTrend(type, startDate, endDate);
|
||||
public Result trend(@Valid String type, Date startDate, Date endDate, String unionId, String clubId) {
|
||||
List<NutMap> submissionTrend = articleAnalysisService.getSubmissionTrend(type, startDate, endDate, unionId, clubId);
|
||||
return Result.success(submissionTrend);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("article.analysis")
|
||||
@ApiOperation(value = "分工会投稿分布")
|
||||
public Result distribution(Date startDate, Date endDate) {
|
||||
List<NutMap> unionDistribution = articleAnalysisService.getUnionDistribution(startDate, endDate);
|
||||
public Result distribution(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
List<NutMap> unionDistribution = articleAnalysisService.getUnionDistribution(startDate, endDate, unionId, clubId);
|
||||
return Result.success(unionDistribution);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("article.analysis")
|
||||
@ApiOperation(value = "社团投稿分布")
|
||||
public Result clubDistribution(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
List<NutMap> clubDistribution = articleAnalysisService.getClubDistribution(startDate, endDate, unionId, clubId);
|
||||
return Result.success(clubDistribution);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("article.analysis")
|
||||
@ApiOperation(value = "投稿排名")
|
||||
|
||||
+6
-2
@@ -52,6 +52,7 @@ public class ArticleMineController {
|
||||
@SaCheckPermission("article.mine")
|
||||
@ApiOperation("分页查询")
|
||||
public Result pageData(@Valid ArticleInfoPageParam pageForm) {
|
||||
// 每篇投稿仅关联最新的一条待办任务,避免多办理人或并行待办将同一投稿重复展示。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
@@ -79,8 +80,11 @@ public class ArticleMineController {
|
||||
FROM
|
||||
article info
|
||||
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
|
||||
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN wf_process_task t ON t.id = (
|
||||
SELECT MAX(currentTask.id)
|
||||
FROM wf_process_task currentTask
|
||||
WHERE currentTask.processInstanceId = ins.id AND currentTask.taskState = 10
|
||||
)
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
+7
-2
@@ -13,12 +13,17 @@ public interface ArticleAnalysisService extends BaseService<Article> {
|
||||
/**
|
||||
* 获取投稿趋势数据
|
||||
*/
|
||||
List<NutMap> getSubmissionTrend(String type, Date startDate, Date endDate);
|
||||
List<NutMap> getSubmissionTrend(String type, Date startDate, Date endDate, String unionId, String clubId);
|
||||
|
||||
/**
|
||||
* 获取分工会投稿分布
|
||||
*/
|
||||
List<NutMap> getUnionDistribution(Date startDate, Date endDate);
|
||||
List<NutMap> getUnionDistribution(Date startDate, Date endDate, String unionId, String clubId);
|
||||
|
||||
/**
|
||||
* 获取社团投稿分布
|
||||
*/
|
||||
List<NutMap> getClubDistribution(Date startDate, Date endDate, String unionId, String clubId);
|
||||
|
||||
/**
|
||||
* 获取排行榜数据
|
||||
|
||||
+46
-10
@@ -22,7 +22,7 @@ public class ArticleAnalysisServiceImpl extends BaseServiceImpl<Article> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> getSubmissionTrend(String type, Date startDate, Date endDate) {
|
||||
public List<NutMap> getSubmissionTrend(String type, Date startDate, Date endDate, String unionId, String clubId) {
|
||||
String groupFormat = switch (type) {
|
||||
case "week" -> "%Y-%u"; // 按周分组
|
||||
case "month" -> "%Y-%m"; // 按月分组
|
||||
@@ -40,10 +40,8 @@ public class ArticleAnalysisServiceImpl extends BaseServiceImpl<Article> impleme
|
||||
""");
|
||||
sql.setParam("groupFormat",groupFormat);
|
||||
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if(ObjectUtil.isAllNotEmpty(startDate,endDate)){
|
||||
cnd.and(Cnd.cri().where().andBetween("submitTime", startDate, endDate));
|
||||
}
|
||||
Cnd cnd = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
cnd.groupBy("DATE_FORMAT(submitTime, @groupFormat)");
|
||||
sql.setCondition(cnd);
|
||||
|
||||
return listMap(sql);
|
||||
@@ -53,7 +51,7 @@ public class ArticleAnalysisServiceImpl extends BaseServiceImpl<Article> impleme
|
||||
* 获取分工会投稿分布
|
||||
*/
|
||||
@Override
|
||||
public List<NutMap> getUnionDistribution(Date startDate, Date endDate) {
|
||||
public List<NutMap> getUnionDistribution(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
unionName AS type,
|
||||
@@ -62,10 +60,7 @@ public class ArticleAnalysisServiceImpl extends BaseServiceImpl<Article> impleme
|
||||
article
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if(ObjectUtil.isAllNotEmpty(startDate,endDate)){
|
||||
cnd.and(Cnd.cri().where().andBetween("submitTime", startDate, endDate));
|
||||
}
|
||||
Cnd cnd = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
cnd.groupBy("unionId","unionName");
|
||||
cnd.desc("value");
|
||||
sql.setCondition(cnd);
|
||||
@@ -73,6 +68,47 @@ public class ArticleAnalysisServiceImpl extends BaseServiceImpl<Article> impleme
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取社团投稿分布
|
||||
*/
|
||||
@Override
|
||||
public List<NutMap> getClubDistribution(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
clubName AS type,
|
||||
COUNT(*) AS value
|
||||
FROM
|
||||
article
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = buildStatisticsCondition(startDate, endDate, unionId, clubId);
|
||||
cnd.and("clubId", "IS NOT", null);
|
||||
cnd.groupBy("clubId", "clubName");
|
||||
cnd.desc("value");
|
||||
sql.setCondition(cnd);
|
||||
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为统计图表统一拼接时间范围和分工会筛选条件,保证各图表的查询口径一致。
|
||||
*
|
||||
* @param startDate 查询开始日期,为空时不限制开始时间
|
||||
* @param endDate 查询结束日期,为空时不限制结束时间
|
||||
* @param unionId 分工会 ID,为空时查询全部分工会
|
||||
* @param clubId 社团 ID,为空时查询全部社团
|
||||
* @return 可直接设置到统计 SQL 的查询条件
|
||||
*/
|
||||
private Cnd buildStatisticsCondition(Date startDate, Date endDate, String unionId, String clubId) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (ObjectUtil.isAllNotEmpty(startDate, endDate)) {
|
||||
cnd.and(Cnd.cri().where().andBetween("submitTime", startDate, endDate));
|
||||
}
|
||||
cnd.andEX("unionId", "=", unionId);
|
||||
cnd.andEX("clubId", "=", clubId);
|
||||
return cnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排行榜数据
|
||||
*/
|
||||
|
||||
+13
-3
@@ -9,9 +9,11 @@ import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.asset.model.Asset;
|
||||
import com.budwk.app.zhgh.dayofficework.asset.model.AssetDepreciationRecord;
|
||||
@@ -27,6 +29,7 @@ import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -157,9 +160,16 @@ public class AssetManageController {
|
||||
@SaCheckPermission(value = {"asset.manage", "asset.stocktaking", "h5.asset.stocktaking"}, mode = SaMode.OR)
|
||||
public Result searchAssetUseUser(String query) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.where().orLike("username", query);
|
||||
cnd.where().orLike("loginname", query);
|
||||
cnd.where().orLike("id", query);
|
||||
// 三个关键词条件必须整体分组,避免 OR 条件绕过分工会数据范围。
|
||||
SqlExpressionGroup searchGroup = new SqlExpressionGroup();
|
||||
searchGroup.orLike("username", query);
|
||||
searchGroup.orLike("loginname", query);
|
||||
searchGroup.orLike("id", query);
|
||||
cnd.and(searchGroup);
|
||||
// 分工会侧盘点人员只能选择本分工会成员,校工会和系统管理员保留全校查询范围。
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
cnd.and("unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
id,
|
||||
|
||||
+7
-31
@@ -1,12 +1,8 @@
|
||||
package com.budwk.app.zhgh.dayofficework.birthdayWishes.task;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.budwk.app.sys.models.Sys_msg;
|
||||
import com.budwk.app.sys.services.SysMsgService;
|
||||
import com.budwk.app.zhgh.staffmanage.birthday.service.UserBirthdayService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.json.Json;
|
||||
@@ -15,16 +11,12 @@ import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean
|
||||
@Slf4j
|
||||
public class BirthdayWishesTask implements Job {
|
||||
|
||||
@Inject
|
||||
protected SysMsgService sysMsgService;
|
||||
@Inject
|
||||
protected Dao dao;
|
||||
private UserBirthdayService userBirthdayService;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -34,28 +26,12 @@ public class BirthdayWishesTask implements Job {
|
||||
log.info("=================================参数:{}", Json.toJson(dataMap));
|
||||
|
||||
String planName = dataMap.getString("name");
|
||||
|
||||
String today = DateUtil.today();
|
||||
String title = planName + today;
|
||||
String content = dataMap.getString("template");
|
||||
|
||||
Sys_msg msg = new Sys_msg();
|
||||
msg.setTitle(planName + today);
|
||||
msg.setType("user");
|
||||
msg.setSendType("show");
|
||||
msg.setSendAt(DateUtil.current());
|
||||
msg.setNote(dataMap.getString("template"));
|
||||
|
||||
// 查询今天生日的会员用户
|
||||
Sql sql = Sqls.create("SELECT loginname FROM sys_user WHERE member = 1 AND MONTH(birthday) = MONTH(CURRENT_DATE) AND DAY(birthday) = DAY(CURRENT_DATE)");
|
||||
sql.setCallback(Sqls.callback.strList());
|
||||
dao.execute(sql);
|
||||
List<String> users = sql.getList(String.class);
|
||||
// 转为数组
|
||||
String[] userArray = users.toArray(String[]::new);
|
||||
log.info("=================================查询今天生日会员用户:{}", users);
|
||||
|
||||
if(userArray.length > 0){
|
||||
log.info("=================================发送消息:{}", msg);
|
||||
sysMsgService.saveMsg(msg, userArray, true);
|
||||
}
|
||||
// 统一由生日服务查询当天生日会员、生成移动端链接并记录系统推送日志。
|
||||
int receiverCount = userBirthdayService.sendTodayBirthdayMessages(title, content);
|
||||
log.info("=================================当天生日通知进入发送队列人数:{}", receiverCount);
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -58,6 +58,10 @@ public class BuildHomeKpiWriteDynamicTableRenderPolicy extends DynamicTableRende
|
||||
// 处理合并
|
||||
if(ObjectUtil.isNotEmpty(dataList)){
|
||||
for (int[] value : groupRanges.values()) {
|
||||
// 单条明细无需合并;POI 不支持对同一行进行纵向合并。
|
||||
if (value[0] == value[1]) {
|
||||
continue;
|
||||
}
|
||||
TableTools.mergeCellsVertically(xwpfTable, 0, value[0] + 1, value[1] + 1);
|
||||
TableTools.mergeCellsVertically(xwpfTable, 1, value[0] + 1, value[1] + 1);
|
||||
TableTools.mergeCellsVertically(xwpfTable, 4, value[0] + 1, value[1] + 1);
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ public class BuildHomeKpiWriteController {
|
||||
buildHomeKpiWriteService.exportDocx(id, os);
|
||||
// 下载生成的文件
|
||||
CommonDownloadUtil.download(
|
||||
"南京邮电大学分工会教职工之家建设考核评议自评表.docx",
|
||||
"中国地质大学分工会教职工之家建设考核评议自评表.docx",
|
||||
os.toByteArray(),
|
||||
response
|
||||
);
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ public class BuildHomeLogBookController {
|
||||
template.render(map).writeAndClose(os);
|
||||
// 下载生成的文件
|
||||
CommonDownloadUtil.download(
|
||||
"南京邮电大学分工会建家记录册.docx",
|
||||
"中国地质大学分工会建家记录册.docx",
|
||||
os.toByteArray(),
|
||||
response
|
||||
);
|
||||
|
||||
+21
-2
@@ -2,6 +2,7 @@ package com.budwk.app.zhgh.dayofficework.buildHome.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
@@ -104,8 +105,13 @@ public class BuildHomeMaterialQueryController {
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("buildHome.material.query")
|
||||
public void exportZip(String actId, HttpServletResponse response) throws IOException {
|
||||
BuildHomeAct act = buildHomeActService.fetch(actId);
|
||||
if (act == null) {
|
||||
throw new IllegalArgumentException("未找到评比事项");
|
||||
}
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t1.id,
|
||||
@@ -123,7 +129,6 @@ public class BuildHomeMaterialQueryController {
|
||||
AND t2.actId = @actId
|
||||
LEFT JOIN build_home_act t3 ON t3.id = t2.actId
|
||||
AND t3.id = @actId
|
||||
WHERE t1.id = '3742a919fb6847f7a8dbe051a2ef0025'
|
||||
GROUP BY
|
||||
t1.id,
|
||||
t2.unionId
|
||||
@@ -135,7 +140,9 @@ public class BuildHomeMaterialQueryController {
|
||||
|
||||
// 2. 设置响应头
|
||||
response.setContentType("application/zip");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"工会文件汇总.zip\"");
|
||||
// 使用评比事项名称作为压缩包名称,避免下载文件无法区分来源。
|
||||
String zipFileName = sanitizeFileName(act.getName()) + "汇总材料.zip";
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + URLUtil.encode(zipFileName));
|
||||
|
||||
// 3. 使用try-with-resources创建ZIP输出流
|
||||
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
||||
@@ -164,6 +171,18 @@ public class BuildHomeMaterialQueryController {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清理评比事项名称中的 Windows 文件名非法字符,确保浏览器可正常保存压缩包。
|
||||
*
|
||||
* @param fileName 原始评比事项名称
|
||||
* @return 可用于下载文件名的评比事项名称
|
||||
*/
|
||||
private String sanitizeFileName(String fileName) {
|
||||
String sanitizedFileName = StrUtil.blankToDefault(fileName, "评比事项");
|
||||
return sanitizedFileName.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
}
|
||||
|
||||
|
||||
private void processFileList(ZipOutputStream zos, String unionName, String fileType, String filesJson) throws IOException {
|
||||
if (StrUtil.isNotBlank(filesJson)) {
|
||||
List<NutMap> files = Json.fromJsonAsList(NutMap.class, filesJson);
|
||||
|
||||
+3
-1
@@ -110,7 +110,9 @@ public class CadreTrainingMineController {
|
||||
cnd.where().andLike(CadreTrainingAct::getName, pageForm.getSearchKeyword());
|
||||
}
|
||||
cnd.desc("info.applyTime");
|
||||
cnd.and("info.userId", "=", SecurityUtil.getUserId());
|
||||
// 本人报名和本人代他人报名的记录都应在“我的报名”中展示。
|
||||
cnd.and(Cnd.exps("info.userId", "=", SecurityUtil.getUserId())
|
||||
.or("info.applyUserId", "=", SecurityUtil.getUserId()));
|
||||
sql.setCondition(cnd);
|
||||
Pagination<NutMap> pagination = cadreTrainingSignUpService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
|
||||
+5
-1
@@ -67,8 +67,9 @@ public class CadreTrainingSignUpController {
|
||||
@SaCheckPermission("cadreTraining.branchUnionSignUp")
|
||||
@ApiOperation("分页查询")
|
||||
public Result pageData(@Valid PageForm pageForm,Integer year, boolean isEnrolled) {
|
||||
// 同一活动存在多条代报名记录时,活动列表仅展示一次。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
SELECT DISTINCT
|
||||
info.*,
|
||||
CASE WHEN cts.id IS NOT NULL THEN 1 ELSE 0 END AS isEnrolled
|
||||
FROM
|
||||
@@ -101,6 +102,9 @@ public class CadreTrainingSignUpController {
|
||||
List<ProcessInstance> instances = new ArrayList<>();
|
||||
|
||||
for (CadreTrainingSignUp signUp : cadreTrainingSignUps) {
|
||||
// 代报名记录必须以当前登录人为报名操作人,供“已报名”和“我的报名”按操作人查询。
|
||||
signUp.setApplyUserId(SecurityUtil.getUserId());
|
||||
signUp.setApplyUserUserName(SecurityUtil.getUserUsername());
|
||||
if (StrUtil.isBlank(signUp.getId())) {
|
||||
signUp.setApplyTime(new Date());
|
||||
}
|
||||
|
||||
+15
-9
@@ -79,21 +79,27 @@ public class HonorSummaryController {
|
||||
@At
|
||||
@SaCheckPermission("honor.honorLevel.Summary")
|
||||
public Result honorLevelData(HonorPageForm pageForm) {
|
||||
|
||||
List<HonorBasicSettings> query = dao.query(HonorBasicSettings.class, Cnd.where("queryTypeCode", "in",
|
||||
List.of(HonorTypeOrigin.HONOR_SCHOOL_LEVEL.name(), HonorTypeOrigin.HONOR_PROVINCIAL_LEVEL.name(), HonorTypeOrigin.HONOR_NATIONAL_LEVEL.name())));
|
||||
String schoolHonorId = query.stream().filter(v->v.getQueryTypeCode().equals(HonorTypeOrigin.HONOR_SCHOOL_LEVEL.name())).findFirst().orElse(new HonorBasicSettings()).getId();
|
||||
String provincialHonorId = query.stream().filter(v->v.getQueryTypeCode().equals(HonorTypeOrigin.HONOR_PROVINCIAL_LEVEL.name())).findFirst().orElse(new HonorBasicSettings()).getId();
|
||||
String nationalHonorId = query.stream().filter(v->v.getQueryTypeCode().equals(HonorTypeOrigin.HONOR_NATIONAL_LEVEL.name())).findFirst().orElse(new HonorBasicSettings()).getId();
|
||||
HonorBasicSettings levelRoot = dao.fetch(HonorBasicSettings.class,
|
||||
Cnd.where("queryTypeCode", "=", HonorTypeOrigin.HONOR_LEVEL.name()));
|
||||
List<HonorBasicSettings> levelList = levelRoot == null ? List.of() : dao.query(HonorBasicSettings.class,
|
||||
Cnd.where("parentId", "=", levelRoot.getId()));
|
||||
String schoolHonorId = levelList.stream().filter(item -> "校内".equals(item.getName()))
|
||||
.findFirst().orElse(new HonorBasicSettings()).getId();
|
||||
String provincialHonorId = levelList.stream().filter(item -> "省部级".equals(item.getName()))
|
||||
.findFirst().orElse(new HonorBasicSettings()).getId();
|
||||
String nationalHonorId = levelList.stream().filter(item -> "国家级".equals(item.getName()))
|
||||
.findFirst().orElse(new HonorBasicSettings()).getId();
|
||||
|
||||
Cnd cnd = Cnd.NEW();
|
||||
// honor.honorLevel 直接保存荣誉等级项 ID,按“荣誉等级”下的具体等级项统计。
|
||||
// 历史荣誉记录可能未保存 unionId,统计时仅在 unionId 为空时按 unionName 回退关联。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
id,
|
||||
name as unionname,
|
||||
( SELECT COUNT( 1 ) FROM honor h WHERE h.honorLevel = @nationalLevel AND h.unionId = un.id $cnd) nationalLevelNum,
|
||||
( SELECT COUNT( 1 ) FROM honor h WHERE h.honorLevel = @provincial AND h.unionId = un.id $cnd) provincialNum ,
|
||||
( SELECT COUNT( 1 ) FROM honor h WHERE h.honorLevel = @schoolLevel AND h.unionId = un.id $cnd) schoolLevelNum
|
||||
( SELECT COUNT( 1 ) FROM honor h WHERE h.honorLevel = @nationalLevel AND (h.unionId = un.id OR ((h.unionId IS NULL OR h.unionId = '') AND h.unionName = un.name)) $cnd) nationalLevelNum,
|
||||
( SELECT COUNT( 1 ) FROM honor h WHERE h.honorLevel = @provincial AND (h.unionId = un.id OR ((h.unionId IS NULL OR h.unionId = '') AND h.unionName = un.name)) $cnd) provincialNum ,
|
||||
( SELECT COUNT( 1 ) FROM honor h WHERE h.honorLevel = @schoolLevel AND (h.unionId = un.id OR ((h.unionId IS NULL OR h.unionId = '') AND h.unionName = un.name)) $cnd) schoolLevelNum
|
||||
FROM
|
||||
sys_union un $condition
|
||||
""").setParam("nationalLevel", nationalHonorId).setParam("provincial", provincialHonorId).setParam("schoolLevel", schoolHonorId);
|
||||
|
||||
+4
-4
@@ -163,17 +163,17 @@ public class MeetingManageController {
|
||||
cnd.andEX("u.unitId", "=", unitId);
|
||||
cnd.and(Cnd.likeEX("u.sex", sex));
|
||||
if (StrUtil.isNotBlank(roleId)) {
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s')".formatted(roleId)));
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s' and enable='1')".formatted(roleId)));
|
||||
}
|
||||
// 选择届次但未选择角色时,按届次筛选全部相关人员;同时选择角色时限定为同一角色关联记录。
|
||||
if (StrUtil.isBlank(roleId) && StrUtil.isNotBlank(teacherCongressSessionId)) {
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where tcSessionId = '%s')".formatted(teacherCongressSessionId)));
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where enable='1' and tcSessionId = '%s')".formatted(teacherCongressSessionId)));
|
||||
}
|
||||
if (StrUtil.isNotBlank(roleId) && StrUtil.isNotBlank(teacherCongressSessionId)) {
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s' and tcSessionId = '%s')".formatted(roleId, teacherCongressSessionId)));
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s' and enable='1' and tcSessionId = '%s')".formatted(roleId, teacherCongressSessionId)));
|
||||
}
|
||||
if (StrUtil.isNotBlank(roleId) && StrUtil.isNotBlank(workerCongressSessionId)) {
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s' and wcSessionId = '%s')".formatted(roleId, workerCongressSessionId)));
|
||||
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s' and enable='1' and wcSessionId = '%s')".formatted(roleId, workerCongressSessionId)));
|
||||
}
|
||||
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.and(pageForm.getSearchName(), "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
|
||||
+4
-2
@@ -115,8 +115,10 @@ public class MeetingOnlineController {
|
||||
@At("/getRealTimeData/?")
|
||||
@Ok("json:full")
|
||||
@SaCheckLogin
|
||||
public Result getRealTimeData(String timePeriodId) {
|
||||
List<MeetingTimePeriodUser> signInUser = onlineService.getSignInUser(timePeriodId);
|
||||
public Result getRealTimeData(String timePeriodId,
|
||||
@Param(value = "signRankOrder") String signRankOrder) {
|
||||
// 签到人员排序统一交由Service处理,控制器只负责接收前端排序方向并返回实时数据。
|
||||
List<MeetingTimePeriodUser> signInUser = onlineService.getSignInUser(timePeriodId, signRankOrder);
|
||||
List<Map<String, Object>> countData = onlineService.getRealTimeData(timePeriodId);
|
||||
return Result.success(Map.of("countData", countData, "userData", signInUser));
|
||||
}
|
||||
|
||||
+10
-1
@@ -18,6 +18,15 @@ import java.util.Map;
|
||||
public interface MeetingOnlineService extends BaseService<MeetingInfo> {
|
||||
|
||||
List<MeetingTimePeriodUser> exportSignature(String timePeriodId);
|
||||
List<MeetingTimePeriodUser> getSignInUser(String timePeriodId);
|
||||
|
||||
/**
|
||||
* 查询指定会议时段的签到人员,并根据签到名次要求排序。
|
||||
*
|
||||
* @param timePeriodId 会议时段ID
|
||||
* @param signRankOrder 签到名次排序方向,ascending为升序,其他值按降序处理
|
||||
* @return 已签到人员列表
|
||||
*/
|
||||
List<MeetingTimePeriodUser> getSignInUser(String timePeriodId, String signRankOrder);
|
||||
|
||||
List<Map<String, Object>> getRealTimeData(String timePeriodId);
|
||||
}
|
||||
|
||||
+12
-8
@@ -70,13 +70,16 @@ public class MeetingOnlineServiceImpl extends BaseServiceImpl<MeetingInfo> imple
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MeetingTimePeriodUser> getSignInUser(String timePeriodId) {
|
||||
return dao().query(
|
||||
MeetingTimePeriodUser.class,
|
||||
Cnd.where(MeetingTimePeriodUser::getTimePeriodId, "=", timePeriodId)
|
||||
.and(MeetingTimePeriodUser::getSignStatus, "=", true)
|
||||
.desc("signTime")
|
||||
);
|
||||
public List<MeetingTimePeriodUser> getSignInUser(String timePeriodId, String signRankOrder) {
|
||||
Cnd cnd = Cnd.where(MeetingTimePeriodUser::getTimePeriodId, "=", timePeriodId)
|
||||
.and(MeetingTimePeriodUser::getSignStatus, "=", true);
|
||||
// 签到名次由签到时间确定,只识别固定方向参数,禁止将前端排序内容直接拼接到SQL中。
|
||||
if ("ascending".equals(signRankOrder)) {
|
||||
cnd.asc("signTime");
|
||||
} else {
|
||||
cnd.desc("signTime");
|
||||
}
|
||||
return dao().query(MeetingTimePeriodUser.class, cnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,7 +136,8 @@ public class MeetingOnlineServiceImpl extends BaseServiceImpl<MeetingInfo> imple
|
||||
Sys_role formalRole = roleService.getByCode(formalRoleCode);
|
||||
Sys_role attendanceRole = roleService.getByCode(attendanceRoleCode);
|
||||
|
||||
List<String> signedInUserIds = getSignInUser(timePeriodId).stream()
|
||||
// 代表签到统计只关心已签到人员集合,使用默认降序查询即可。
|
||||
List<String> signedInUserIds = getSignInUser(timePeriodId, "descending").stream()
|
||||
.map(MeetingTimePeriodUser::getUserId)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
/**
|
||||
* 分工会预算统计服务。
|
||||
*
|
||||
* <p>统一封装分工会预算使用情况和经费收支情况的全量汇总查询,
|
||||
* 汇总口径与列表查询保持一致,不受分页参数影响。</p>
|
||||
*/
|
||||
public interface OutlayManageUnionStatisticsService extends BaseService {
|
||||
|
||||
/**
|
||||
* 查询分工会预算使用情况的全量合计。
|
||||
*
|
||||
* @param year 统计年度
|
||||
* @param unionId 分工会主键,管理员可为空查询全部
|
||||
* @return 包含 totalQuota、usedQuota、surplusQuota 的合计数据
|
||||
*/
|
||||
NutMap queryUseDetailSummary(Integer year, String unionId);
|
||||
|
||||
/**
|
||||
* 查询分工会经费收支使用情况的全量合计。
|
||||
*
|
||||
* @param year 统计年度
|
||||
* @param unionId 分工会主键,管理员可为空查询全部
|
||||
* @return 包含各项收入、支出和余额字段的合计数据
|
||||
*/
|
||||
NutMap queryIncomeExpenseSummary(Integer year, String unionId);
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionStatisticsService;
|
||||
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.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
/**
|
||||
* 分工会预算统计服务实现。
|
||||
*
|
||||
* <p>汇总查询在数据库端完成,避免只汇总当前分页数据,
|
||||
* 同时复用列表的年度、分工会和权限过滤条件。</p>
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class OutlayManageUnionStatisticsServiceImpl extends BaseServiceImpl implements OutlayManageUnionStatisticsService {
|
||||
|
||||
public OutlayManageUnionStatisticsServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap queryUseDetailSummary(Integer year, String unionId) {
|
||||
Cnd cnd = buildUnionManageCondition(year, unionId, false);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
COALESCE(SUM(totalQuota), 0) AS totalQuota,
|
||||
COALESCE(SUM(usedQuota), 0) AS usedQuota,
|
||||
COALESCE(SUM(COALESCE(totalQuota, 0) - COALESCE(usedQuota, 0)), 0) AS surplusQuota
|
||||
FROM outlay_manage_union mu $condition
|
||||
""");
|
||||
sql.setCondition(cnd);
|
||||
return executeMap(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap queryIncomeExpenseSummary(Integer year, String unionId) {
|
||||
Cnd cnd = buildUnionManageCondition(year, unionId, true);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
COALESCE(SUM(t.beginMoney), 0) AS beginMoney,
|
||||
COALESCE(SUM(t.feeJanApr), 0) AS feeJanApr,
|
||||
COALESCE(SUM(t.feeMayAug), 0) AS feeMayAug,
|
||||
COALESCE(SUM(t.feeSepDec), 0) AS feeSepDec,
|
||||
COALESCE(SUM(t.awardMoney), 0) AS awardMoney,
|
||||
COALESCE(SUM(t.usedMoney), 0) AS usedMoney,
|
||||
COALESCE(SUM(t.remainMoney), 0) AS remainMoney
|
||||
FROM (
|
||||
SELECT
|
||||
mu.unionId,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateHeadMoney ELSE 0 END), 0) AS beginMoney,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateMoney ELSE 0 END), 0) AS feeJanApr,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 2 THEN au.allocateMoney ELSE 0 END), 0) AS feeMayAug,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 3 THEN au.allocateMoney ELSE 0 END), 0) AS feeSepDec,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 4 THEN au.allocateMoney ELSE 0 END), 0) AS awardMoney,
|
||||
COALESCE(mu.usedQuota, 0) AS usedMoney,
|
||||
COALESCE(mu.totalQuota, 0) - COALESCE(mu.usedQuota, 0) AS remainMoney
|
||||
FROM outlay_manage_union mu
|
||||
LEFT JOIN outlay_allocate_union au ON au.year = mu.year
|
||||
AND au.unionId = mu.unionId
|
||||
AND au.delFlag = 0
|
||||
LEFT JOIN sys_union su ON su.id = mu.unionId
|
||||
$condition
|
||||
GROUP BY mu.year, mu.unionId, mu.usedQuota, mu.totalQuota
|
||||
) t
|
||||
""");
|
||||
sql.setCondition(cnd);
|
||||
return executeMap(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造两个列表共用的预算主表过滤条件,保证汇总和分页列表权限口径一致。
|
||||
*/
|
||||
private Cnd buildUnionManageCondition(Integer year, String unionId, boolean includeDelFlag) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (includeDelFlag) {
|
||||
cnd.and("mu.delFlag", "=", false);
|
||||
}
|
||||
cnd.and("mu.year", "=", year == null ? DateUtil.thisYear() : year);
|
||||
cnd.and("mu.totalQuota", "IS NOT", null);
|
||||
cnd.andEX("mu.unionId", "=", unionId);
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
cnd.and("mu.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
return cnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行单行统计查询,并在无数据时返回各字段为零的结果,方便前端直接展示。
|
||||
*/
|
||||
private NutMap executeMap(Sql sql) {
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao().execute(sql);
|
||||
NutMap result = (NutMap) sql.getResult();
|
||||
return result == null ? NutMap.NEW() : result;
|
||||
}
|
||||
}
|
||||
+13
@@ -14,6 +14,7 @@ import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionStatisticsService;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo.OutlayUnionIncomeExpenseVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -44,6 +45,8 @@ public class OutlayManageUnionIncomeExpenseController {
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private OutlayManageUnionStatisticsService outlayManageUnionStatisticsService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/union/incomeExpense/index.html")
|
||||
@@ -60,6 +63,16 @@ public class OutlayManageUnionIncomeExpenseController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前筛选范围内全部分工会经费收支合计,不受分页参数影响。
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("查询经费收支合计")
|
||||
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
|
||||
public Result summary(Integer year, String unionId) {
|
||||
return Result.success(outlayManageUnionStatisticsService.queryIncomeExpenseSummary(year, unionId));
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出")
|
||||
|
||||
+13
@@ -12,6 +12,7 @@ import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.model.OutlayUseDetail;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayUseDetailService;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.service.OutlayManageUnionStatisticsService;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.model.OutLayAllocateUnion;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -46,6 +47,8 @@ public class OutlayManageUnionUseDetailController {
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private OutlayUseDetailService outlayUseDetailService;
|
||||
@Inject
|
||||
private OutlayManageUnionStatisticsService outlayManageUnionStatisticsService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/union/useDetail/index.html")
|
||||
@@ -81,6 +84,16 @@ public class OutlayManageUnionUseDetailController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前筛选范围内全部分工会预算使用情况合计,不受分页参数影响。
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("查询预算使用情况合计")
|
||||
@SaCheckPermission("outlay.outlayManage.union.useDetail")
|
||||
public Result summary(Integer year, String unionId) {
|
||||
return Result.success(outlayManageUnionStatisticsService.queryUseDetailSummary(year, unionId));
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@ApiOperation("某个分工会预算使用详情")
|
||||
|
||||
+4
-1
@@ -85,9 +85,12 @@ public class UnionReimburseCollectController {
|
||||
@Param(value = "reimburseProject") String reimburseProject) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*
|
||||
info.*,
|
||||
ins.id AS instanceId,
|
||||
ins.processDefineId AS instanceProcessDefineId
|
||||
FROM
|
||||
union_reimburse info
|
||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
+23
-7
@@ -84,12 +84,26 @@ public class ProposalConfigUnitController {
|
||||
u2.username AS unitLeader
|
||||
FROM
|
||||
proposal_undertake t1
|
||||
LEFT JOIN sys_user_role sur1 ON sur1.underTakeId = t1.id
|
||||
AND sur1.roleId = ( SELECT r.id FROM sys_role r WHERE r.CODE = @PROPOSAL_BRANCH_SCHOOL_LEADER )
|
||||
LEFT JOIN sys_user u1 ON u1.id = sur1.userId
|
||||
LEFT JOIN sys_user_role sur2 ON sur2.underTakeId = t1.id
|
||||
AND sur2.roleId = ( SELECT r.id FROM sys_role r WHERE r.CODE = @PROPOSAL_UNIT_LEADER)
|
||||
LEFT JOIN sys_user u2 ON u2.id = sur2.userId
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
sur.underTakeId,
|
||||
GROUP_CONCAT(DISTINCT u.username ORDER BY u.username SEPARATOR '、') AS username,
|
||||
GROUP_CONCAT(DISTINCT u.loginname ORDER BY u.loginname SEPARATOR ',') AS loginname
|
||||
FROM sys_user_role sur
|
||||
LEFT JOIN sys_user u ON u.id = sur.userId
|
||||
WHERE sur.roleId = (SELECT r.id FROM sys_role r WHERE r.CODE = @PROPOSAL_BRANCH_SCHOOL_LEADER)
|
||||
GROUP BY sur.underTakeId
|
||||
) u1 ON u1.underTakeId = t1.id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
sur.underTakeId,
|
||||
GROUP_CONCAT(DISTINCT u.username ORDER BY u.username SEPARATOR '、') AS username,
|
||||
GROUP_CONCAT(DISTINCT u.loginname ORDER BY u.loginname SEPARATOR ',') AS loginname
|
||||
FROM sys_user_role sur
|
||||
LEFT JOIN sys_user u ON u.id = sur.userId
|
||||
WHERE sur.roleId = (SELECT r.id FROM sys_role r WHERE r.CODE = @PROPOSAL_UNIT_LEADER)
|
||||
GROUP BY sur.underTakeId
|
||||
) u2 ON u2.underTakeId = t1.id
|
||||
$condition
|
||||
""");
|
||||
sql.setParam("PROPOSAL_BRANCH_SCHOOL_LEADER", RoleConstant.PROPOSAL_BRANCH_SCHOOL_LEADER.name());
|
||||
@@ -121,7 +135,9 @@ public class ProposalConfigUnitController {
|
||||
@SLog(tag = "提案", msg = "承办单位同步系统单位")
|
||||
public Result syncSysUnit() {
|
||||
Sql sql = Sqls.create("select code from proposal_undertake");
|
||||
List<Sys_unit> sysUnits = dao.query(Sys_unit.class, Cnd.where(Sys_unit::getUnitcode, "not in", sql).and(Sys_unit::getUnitTypeCode, "=", 1));
|
||||
// 三位单位编号即提案业务使用的二级单位,不再叠加系统单位层级条件。
|
||||
List<Sys_unit> sysUnits = dao.query(Sys_unit.class, Cnd.where(Sys_unit::getUnitcode, "not in", sql)
|
||||
.and("CHAR_LENGTH(TRIM(unitcode))", "=", 3));
|
||||
List<ProposalUndertake> proposalUndertakes = sysUnits.stream().map(unit -> {
|
||||
ProposalUndertake proposalUndertake = new ProposalUndertake();
|
||||
proposalUndertake.setId(unit.getId());
|
||||
|
||||
+19
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.query;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
||||
@@ -15,6 +16,7 @@ import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -51,6 +53,23 @@ public class ProposalQueryCollectProgressController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按征集进度页面筛选条件及当前可见字段导出 Excel。
|
||||
*
|
||||
* @param pageForm 页面筛选和排序参数
|
||||
* @param tableColumns 当前可见字段,顺序即导出列顺序
|
||||
* @param response HTTP 响应,返回 XSSF Excel
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.query.collectProgress")
|
||||
@ApiOperation(value = "自定义导出征集进度")
|
||||
public void exportCustomAsExcel(@Valid @Param("pageForm") ProposalQueryComprehensiveParam pageForm,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns,
|
||||
HttpServletResponse response) {
|
||||
proposalCommonService.exportCollectProgressAsExcel(pageForm, tableColumns, response);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation(value = "获取征集状态")
|
||||
@SaCheckPermission("proposal.query.collectProgress")
|
||||
|
||||
+18
-108
@@ -1,21 +1,13 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.query;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO;
|
||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
||||
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
@@ -24,9 +16,6 @@ import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
@IocBean
|
||||
@At("/platform/proposal/query/comprehensive")
|
||||
@Slf4j
|
||||
@@ -34,25 +23,6 @@ import java.util.Map;
|
||||
@Api(tags = "提案综合查询")
|
||||
public class ProposalQueryComprehensiveController {
|
||||
|
||||
/**
|
||||
* 综合查询表格允许排序的字段映射,值为查询中的真实字段或安全别名。
|
||||
*/
|
||||
private static final Map<String, String> COMPREHENSIVE_ORDER_COLUMNS = Map.ofEntries(
|
||||
Map.entry("code", "info.code"),
|
||||
Map.entry("name", "info.name"),
|
||||
Map.entry("createUserName", "info.createUserName"),
|
||||
Map.entry("typeName", "typeName"),
|
||||
Map.entry("delegationName", "delegationName"),
|
||||
Map.entry("caseFilingResult", "info.caseFilingResult"),
|
||||
Map.entry("caseFilingType", "info.caseFilingType"),
|
||||
Map.entry("merge", "merge"),
|
||||
Map.entry("undertakeUnits", "undertakeUnitsOrder"),
|
||||
Map.entry("curTaskName", "curTaskName"),
|
||||
Map.entry("instanceState", "instanceState")
|
||||
);
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@@ -66,84 +36,24 @@ public class ProposalQueryComprehensiveController {
|
||||
@SaCheckPermission("proposal.query.comprehensive")
|
||||
@ApiOperation(value = "分页列表")
|
||||
public Result pageData(@Valid @Param("pageForm") ProposalQueryComprehensiveParam pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
IF(mer.proposalId IS NOT NULL, 1, 0) AS merge,
|
||||
type.name AS typeName,
|
||||
tcs.fullName AS sessionName,
|
||||
tcd.`name` AS delegationName,
|
||||
ins.id AS instanceId,
|
||||
ins.businessNo,
|
||||
ins.state instanceState,
|
||||
ins.variable instanceVariable,
|
||||
ins.processDefineId instanceProcessDefineId,
|
||||
t.displayName curTaskName,
|
||||
GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 1 THEN pru.unitName END) AS masterUnitName,
|
||||
GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 0 THEN pru.unitName END) AS slaveUnitNames,
|
||||
GROUP_CONCAT(DISTINCT pru.unitName ORDER BY pru.isMaster DESC, pru.unitName) AS undertakeUnitsOrder
|
||||
FROM
|
||||
proposal_info info
|
||||
LEFT JOIN proposal_type type on type.id = info.typeId
|
||||
LEFT JOIN proposal_merge mer ON mer.proposalId = info.id
|
||||
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
|
||||
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
|
||||
LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName
|
||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
|
||||
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10
|
||||
LEFT JOIN proposal_reply_unit pru ON pru.proposalId = info.id
|
||||
LEFT JOIN wf_process_task replyTask on replyTask.processInstanceId = ins.id
|
||||
$condition
|
||||
""");
|
||||
// AND replyTask.taskState = 20 AND replyTask.taskName in ('master_reply','slave_reply','opinion_master_reply')
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (ArrayUtil.isNotEmpty(pageForm.getOrigins()) && StrUtil.isNotBlank(pageForm.getCommonKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
return Result.success(proposalCommonService.queryComprehensive(pageForm));
|
||||
}
|
||||
|
||||
// 案名
|
||||
if (ArrayUtil.contains(pageForm.getOrigins(), "name")) {
|
||||
for (String keyword : pageForm.getCommonKeyword().split(" ")) {
|
||||
seg.orLike("info.name", keyword);
|
||||
}
|
||||
}
|
||||
|
||||
// 案由
|
||||
if (ArrayUtil.contains(pageForm.getOrigins(), "brief")) {
|
||||
for (String keyword : pageForm.getCommonKeyword().split(" ")) {
|
||||
seg.orLike("info.brief", keyword);
|
||||
}
|
||||
}
|
||||
|
||||
// 提案人
|
||||
if (ArrayUtil.contains(pageForm.getOrigins(), "createUserName")) {
|
||||
for (String keyword : pageForm.getCommonKeyword().split(" ")) {
|
||||
seg.orLike("info.createUserName", keyword);
|
||||
seg.orLike("info.createUserLoginName", keyword);
|
||||
}
|
||||
}
|
||||
|
||||
// 答复内容
|
||||
if (ArrayUtil.contains(pageForm.getOrigins(), "answer")) {
|
||||
for (String keyword : pageForm.getCommonKeyword().split(" ")) {
|
||||
seg.orLike("JSON_EXTRACT(replyTask.variable,'$.tf_opinion')", keyword);
|
||||
}
|
||||
}
|
||||
|
||||
if (!seg.isEmpty()) {
|
||||
cnd.and(seg);
|
||||
}
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(pageForm.getUnderTakeUnitId())) {
|
||||
cnd.andEX("pru.unitId", "=", pageForm.getUnderTakeUnitId());
|
||||
}
|
||||
ProposalQueryComprehensiveParam.buildSearch(cnd, pageForm);
|
||||
cnd.groupBy("info.id");
|
||||
// 综合查询包含多表字段及聚合别名,只允许白名单字段进入排序条件。
|
||||
proposalCommonService.applySafePageOrder(cnd, pageForm, COMPREHENSIVE_ORDER_COLUMNS);
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
/**
|
||||
* 按综合查询页面当前筛选条件和列设置导出 Excel。
|
||||
*
|
||||
* @param pageForm 页面筛选及排序参数
|
||||
* @param tableColumns 列设置中当前可见的字段,顺序即 Excel 列顺序
|
||||
* @param response HTTP 响应,返回 XSSF 格式的 Excel 文件
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.query.comprehensive")
|
||||
@ApiOperation(value = "自定义导出综合查询列表")
|
||||
public void exportCustomAsExcel(@Valid @Param("pageForm") ProposalQueryComprehensiveParam pageForm,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns,
|
||||
HttpServletResponse response) {
|
||||
proposalCommonService.exportComprehensiveAsExcel(pageForm, tableColumns, response);
|
||||
}
|
||||
|
||||
@At
|
||||
|
||||
+24
-62
@@ -1,14 +1,11 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.query;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_dict;
|
||||
import com.budwk.app.sys.services.SysDictService;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
|
||||
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -21,10 +18,10 @@ 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
@IocBean
|
||||
@@ -34,15 +31,6 @@ import java.util.Map;
|
||||
@Api(tags = "代表团提案统计")
|
||||
public class ProposalQueryDelegationController {
|
||||
|
||||
/**
|
||||
* 代表团汇总表固定列的安全排序映射,动态立案结果列在查询时追加。
|
||||
*/
|
||||
private static final Map<String, String> DELEGATION_SUMMARY_ORDER_COLUMNS = Map.of(
|
||||
"dbtName", "dbt.name",
|
||||
"TOTAL", "TOTAL",
|
||||
"caseRate", "caseRateOrder"
|
||||
);
|
||||
|
||||
/**
|
||||
* 代表团提案明细表允许排序的字段映射。
|
||||
*/
|
||||
@@ -62,10 +50,6 @@ public class ProposalQueryDelegationController {
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@Inject
|
||||
private SysDictService sysDictService;
|
||||
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/democratic/proposal/query/delegation/index.html")
|
||||
@SaCheckPermission("proposal.query.delegation")
|
||||
@@ -77,48 +61,26 @@ public class ProposalQueryDelegationController {
|
||||
@ApiOperation("代表团提案统计")
|
||||
@SaCheckPermission("proposal.query.delegation")
|
||||
public Result pageData(PageForm pageForm, String sessionId) {
|
||||
// 统计必须明确限定届次,空参数不能退化为跨届次汇总,避免页面异步初始化时展示错误数据。
|
||||
if (StrUtil.isBlank(sessionId)) {
|
||||
return Result.success(List.of());
|
||||
}
|
||||
List<Sys_dict> dictList = sysDictService.getSubListByCode("PROPOSAL_CASE_FILING_RESULT");
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
dbt.id,
|
||||
dbt.`name` AS dbtName,
|
||||
(select count(1) from proposal_info info where info.delegationId = dbt.id and info.sessionId = dbt.sessionId ) as TOTAL,
|
||||
(select count(1) from proposal_info info where info.delegationId = dbt.id and info.sessionId = dbt.sessionId and info.isSubmit = 1 ) as SUBMIT_COUNT
|
||||
$resultSql,
|
||||
(select count(1) from proposal_info info where info.delegationId = dbt.id and info.sessionId = dbt.sessionId and info.caseFilingResult = @confirmFiling)
|
||||
/ NULLIF((select count(1) from proposal_info info where info.delegationId = dbt.id and info.sessionId = dbt.sessionId), 0) AS caseRateOrder
|
||||
FROM
|
||||
teacher_congress_delegation dbt
|
||||
$condition
|
||||
""");
|
||||
Map<String, String> summaryOrderColumns = new HashMap<>(DELEGATION_SUMMARY_ORDER_COLUMNS);
|
||||
List<String> resultSqlParts = new ArrayList<>();
|
||||
for (Sys_dict dict : dictList) {
|
||||
String resultCode = dict.getCode();
|
||||
// 动态别名和立案结果编码仅允许字母、数字和下划线;变量替换后新增的 @ 参数不会被 Nutz 再次解析,
|
||||
// 因此这里使用已校验的字典编码字面量,确保统计条件能正确传递给数据库。
|
||||
if (StrUtil.isBlank(resultCode) || !resultCode.matches("[A-Za-z0-9_]+")) {
|
||||
continue;
|
||||
}
|
||||
resultSqlParts.add(", (select count(1) from proposal_info info where info.delegationId = dbt.id and info.sessionId = dbt.sessionId and info.caseFilingResult = '" + resultCode + "') AS `" + resultCode + "`");
|
||||
summaryOrderColumns.put(resultCode, "`" + resultCode + "`");
|
||||
}
|
||||
sql.setVar("resultSql", String.join("", resultSqlParts));
|
||||
sql.setParam("confirmFiling", "CONFIRM_FILING");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("dbt.sessionId", "=", sessionId);
|
||||
if (!AuthUtil.hasRoleOr("SYSADMIN", "SCHOOL_UNION_ADMIN")) {
|
||||
}
|
||||
// 未选择排序时保留原有代表团编码升序,选择后仅应用白名单字段。
|
||||
if (!proposalCommonService.applySafePageOrder(cnd, pageForm, summaryOrderColumns)) {
|
||||
cnd.asc("dbt.`code`");
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return Result.success(baseService.listMap(sql));
|
||||
return Result.success(proposalCommonService.queryDelegationStatistics(pageForm, sessionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按当前届次、排序及页面可见字段导出代表团统计。
|
||||
*
|
||||
* @param pageForm 页面排序参数
|
||||
* @param sessionId 教代会届次ID
|
||||
* @param tableColumns 当前可见字段
|
||||
* @param response HTTP 响应,返回 XSSF Excel
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("自定义导出代表团提案统计")
|
||||
@SaCheckPermission("proposal.query.delegation")
|
||||
public void exportCustomAsExcel(@Valid @Param("pageForm") PageForm pageForm,
|
||||
@Param("sessionId") String sessionId,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns,
|
||||
HttpServletResponse response) {
|
||||
proposalCommonService.exportDelegationStatisticsAsExcel(pageForm, sessionId, tableColumns, response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+28
-111
@@ -1,28 +1,19 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.query;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.engine.util.FlowUtil;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit;
|
||||
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 承办单位办理统计
|
||||
@@ -33,16 +24,6 @@ import java.util.stream.Collectors;
|
||||
@Ok("json:full")
|
||||
public class ProposalQueryUnitReplyController {
|
||||
|
||||
/**
|
||||
* 承办单位办理统计允许排序的字段白名单。
|
||||
*/
|
||||
private static final Set<String> UNIT_REPLY_ORDER_COLUMNS = Set.of(
|
||||
"unitName", "sum", "masterSum", "masterReplySum", "masterNoReplySum",
|
||||
"slaveSum", "slaveReplySum", "slaveNoReplySum"
|
||||
);
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@@ -64,94 +45,30 @@ public class ProposalQueryUnitReplyController {
|
||||
* caseFilingResult:立案结果字典值,对应 proposal_info.caseFilingResult,为空时不限制立案结果。
|
||||
* 返回值:Result.data 中包含 tableData 统计行列表,以及 slaveNeedReply 协办单位是否需要答复配置。
|
||||
*/
|
||||
// 提案配置 协办是否需要答复
|
||||
ProposalConfig proposalConfig = dao.fetch(ProposalConfig.class, Cnd.NEW());
|
||||
boolean slaveNeedReply = proposalConfig.getSlaveUnitNeedReply();
|
||||
return Result.success().addData(proposalCommonService.queryUnitReplyStatistics(
|
||||
pageForm, sessionId, undertakeUnitId, caseFilingResult));
|
||||
}
|
||||
|
||||
// 当前届次所有的提案ID
|
||||
Cnd proposalCnd = Cnd.where(ProposalInfo::getSessionId, "=", sessionId);
|
||||
proposalCnd.andEX(ProposalInfo::getCaseFilingResult, "=", caseFilingResult);
|
||||
List<String> proposalIds = dao.query(ProposalInfo.class, proposalCnd)
|
||||
.stream()
|
||||
.map(ProposalInfo::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if(proposalIds.isEmpty()){
|
||||
return Result.success().addData(Map.of("tableData", Collections.EMPTY_LIST, "slaveNeedReply", slaveNeedReply));
|
||||
}
|
||||
|
||||
|
||||
// 关联所有的实例ID
|
||||
Sql instSql = Sqls.create("select id from wf_process_instance where businessNo in (@proposalIds)");
|
||||
instSql.setParam("proposalIds", proposalIds);
|
||||
instSql.setCallback(Sqls.callback.strList());
|
||||
dao.execute(instSql);
|
||||
List<String> instIds = instSql.getList(String.class);
|
||||
|
||||
// 提案委员会立案分配的承办单位
|
||||
Cnd cnd = Cnd.where(ProposalReplyUnit::getProposalId, "in", proposalIds);
|
||||
cnd.andEX(ProposalReplyUnit::getUnitId, "=", undertakeUnitId);
|
||||
List<ProposalReplyUnit> replyUnits = dao.query(ProposalReplyUnit.class, cnd);
|
||||
|
||||
// 承办单位答复记录
|
||||
List<ProcessTask> replyTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instIds).and(ProcessTask::getTaskName, "in", List.of("two_unit_reply","unit_reply","master_reply", "slave_reply", "opinion_master_reply")).and(ProcessTask::getTaskState, "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.DOING.getCode())));
|
||||
|
||||
// 承办单位
|
||||
List<NutMap> tableData = new ArrayList<>();
|
||||
|
||||
replyUnits.stream().collect(Collectors.groupingBy(ProposalReplyUnit::getUnitCode)).forEach((k, v) -> {
|
||||
NutMap tableRow = NutMap.NEW();
|
||||
tableRow.put("id", k);
|
||||
v.stream().findAny().ifPresent(item -> {
|
||||
tableRow.put("unitName", item.getUnitName());
|
||||
tableRow.put("unitCode", item.getUnitCode());
|
||||
});
|
||||
|
||||
// 提案总数
|
||||
tableRow.put("sum", v.size());
|
||||
// 主办提案数
|
||||
tableRow.put("masterSum", v.stream().filter(unit -> Objects.equals(unit.getUnitCode(), k) && unit.getIsMaster()).count());
|
||||
// 协办提案数
|
||||
tableRow.put("slaveSum", v.stream().filter(unit -> Objects.equals(unit.getUnitCode(), k) && !unit.getIsMaster()).count());
|
||||
|
||||
// 主办提案已答复数
|
||||
long masterReplySum = replyTasks.stream().filter(x ->
|
||||
FlowUtil.variableToNutMap(x.getVariable()).getString("underTakeId", "").equals(k)
|
||||
&& FlowUtil.variableToNutMap(x.getVariable()).getBoolean("underTakeIsMaster")
|
||||
&& x.getTaskState().equals(ProcessTaskStateEnum.FINISHED.getCode())
|
||||
).map(ProcessTask::getProcessInstanceId).distinct().count();
|
||||
|
||||
// 主办提案未答复数
|
||||
long masterNoReplySum = replyTasks.stream().filter(x ->
|
||||
FlowUtil.variableToNutMap(x.getVariable()).getString("underTakeId", "").equals(k)
|
||||
&& FlowUtil.variableToNutMap(x.getVariable()).getBoolean("underTakeIsMaster")
|
||||
&& x.getTaskState().equals(ProcessTaskStateEnum.DOING.getCode())
|
||||
).map(ProcessTask::getProcessInstanceId).distinct().count();
|
||||
|
||||
// 协办提案已答复数
|
||||
long slaveReplySum = replyTasks.stream().filter(x ->
|
||||
FlowUtil.variableToNutMap(x.getVariable()).getString("underTakeId", "").equals(k)
|
||||
&& !FlowUtil.variableToNutMap(x.getVariable()).getBoolean("underTakeIsMaster")
|
||||
&& x.getTaskState().equals(ProcessTaskStateEnum.FINISHED.getCode())
|
||||
).map(ProcessTask::getProcessInstanceId).distinct().count();
|
||||
|
||||
// 协办提案未答复数
|
||||
long slaveNoReplySum = replyTasks.stream().filter(x ->
|
||||
FlowUtil.variableToNutMap(x.getVariable()).getString("underTakeId", "").equals(k)
|
||||
&& !FlowUtil.variableToNutMap(x.getVariable()).getBoolean("underTakeIsMaster")
|
||||
&& x.getTaskState().equals(ProcessTaskStateEnum.DOING.getCode())
|
||||
).map(ProcessTask::getProcessInstanceId).distinct().count();
|
||||
|
||||
tableRow.put("masterReplySum", masterReplySum);
|
||||
tableRow.put("masterNoReplySum", masterNoReplySum);
|
||||
tableRow.put("slaveReplySum", slaveReplySum);
|
||||
tableRow.put("slaveNoReplySum", slaveNoReplySum);
|
||||
|
||||
tableData.add(tableRow);
|
||||
});
|
||||
|
||||
// 统计结果生成后在服务层按白名单字段排序,避免前端字段参与任意业务处理。
|
||||
proposalCommonService.sortStatisticsRows(tableData, pageForm, UNIT_REPLY_ORDER_COLUMNS);
|
||||
return Result.success().addData(Map.of("tableData", tableData, "slaveNeedReply", slaveNeedReply));
|
||||
/**
|
||||
* 按当前筛选条件及页面可见字段导出承办单位办理统计。
|
||||
*
|
||||
* @param pageForm 页面排序参数
|
||||
* @param sessionId 教代会届次ID
|
||||
* @param undertakeUnitId 承办单位ID
|
||||
* @param caseFilingResult 立案结果编码
|
||||
* @param tableColumns 当前可见字段
|
||||
* @param response HTTP 响应,返回 XSSF Excel
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.query.unitReply")
|
||||
public void exportCustomAsExcel(@Valid @Param("pageForm") PageForm pageForm,
|
||||
@Param("sessionId") String sessionId,
|
||||
@Param("undertakeUnitId") String undertakeUnitId,
|
||||
@Param("caseFilingResult") String caseFilingResult,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns,
|
||||
HttpServletResponse response) {
|
||||
proposalCommonService.exportUnitReplyStatisticsAsExcel(pageForm, sessionId, undertakeUnitId,
|
||||
caseFilingResult, tableColumns, response);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ public class ProposalQueryYearReportController {
|
||||
*/
|
||||
private static final Map<String, String> YEAR_REPORT_ORDER_COLUMNS = Map.ofEntries(
|
||||
Map.entry("code", "info.code"),
|
||||
Map.entry("caseFilingCode", "info.caseFilingCode"),
|
||||
Map.entry("name", "info.name"),
|
||||
Map.entry("createUserName", "info.createUserName"),
|
||||
Map.entry("typeName", "typeName"),
|
||||
|
||||
+26
-101
@@ -1,31 +1,19 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.query;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.engine.util.FlowUtil;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.sys.models.Sys_dict;
|
||||
import com.budwk.app.sys.services.SysDictService;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit;
|
||||
import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService;
|
||||
import io.swagger.annotations.Api;
|
||||
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 java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
@IocBean
|
||||
@At("/platform/proposal/query/underTake/satisfaction")
|
||||
@@ -33,17 +21,6 @@ import java.util.stream.Collectors;
|
||||
@Api(tags = "提案承办单位满意度")
|
||||
public class ProposalUnderTakeSatisfactionController {
|
||||
|
||||
/**
|
||||
* 满意度统计固定列的排序白名单,动态满意度列在查询时追加。
|
||||
*/
|
||||
private static final Set<String> SATISFACTION_ORDER_COLUMNS = Set.of(
|
||||
"unitName", "sum", "masterSum", "slaveSum"
|
||||
);
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SysDictService sysDictService;
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
|
||||
@@ -65,80 +42,28 @@ public class ProposalUnderTakeSatisfactionController {
|
||||
@At
|
||||
@SaCheckPermission("proposal.query.underTake.satisfaction")
|
||||
public Result data(PageForm pageForm, String sessionId, String undertakeUnitId) {
|
||||
List<Sys_dict> feedbackCodes = sysDictService.getSubListByCode("PROPOSAL_FEEDBACK");
|
||||
Set<String> orderColumns = new HashSet<>(SATISFACTION_ORDER_COLUMNS);
|
||||
// 动态满意度列仅从后端字典加入白名单,不接受前端自行扩展字段。
|
||||
feedbackCodes.stream()
|
||||
.map(Sys_dict::getCode)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.forEach(orderColumns::add);
|
||||
|
||||
// 当前届次所有的提案ID
|
||||
Sql sql = Sqls.create("select id from proposal_info where sessionId = @sessionId").setParam("sessionId", sessionId);
|
||||
sql.setCallback(Sqls.callback.strList());
|
||||
dao.execute(sql);
|
||||
List<String> proposalIds = sql.getList(String.class);
|
||||
|
||||
if (proposalIds.isEmpty()) {
|
||||
return Result.success(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
// 关联所有的实例ID
|
||||
Sql instSql = Sqls.create("select id from wf_process_instance where businessNo in (@proposalIds)");
|
||||
instSql.setParam("proposalIds", proposalIds);
|
||||
instSql.setCallback(Sqls.callback.strList());
|
||||
dao.execute(instSql);
|
||||
List<String> instIds = instSql.getList(String.class);
|
||||
|
||||
// 提案委员会立案分配的承办单位
|
||||
Cnd cnd = Cnd.where(ProposalReplyUnit::getProposalId, "in", proposalIds);
|
||||
cnd.andEX(ProposalReplyUnit::getUnitId, "=", undertakeUnitId);
|
||||
List<ProposalReplyUnit> replyUnits = dao.query(ProposalReplyUnit.class, cnd);
|
||||
|
||||
// 反馈评分记录
|
||||
// List<ProcessTask> feedbackTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instIds)
|
||||
// .and(ProcessTask::getTaskName, "=", "feedback")
|
||||
// .and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode()));
|
||||
|
||||
// 承办单位
|
||||
List<NutMap> tableData = new ArrayList<>();
|
||||
|
||||
replyUnits.stream().collect(Collectors.groupingBy(ProposalReplyUnit::getUnitCode)).forEach((k, v) -> {
|
||||
NutMap tableRow = NutMap.NEW();
|
||||
tableRow.put("id", k);
|
||||
v.stream().findAny().ifPresent(item -> {
|
||||
tableRow.put("unitName", item.getUnitName());
|
||||
tableRow.put("unitCode", item.getUnitCode());
|
||||
});
|
||||
|
||||
// 提案总数
|
||||
tableRow.put("sum", v.size());
|
||||
// 主办提案数
|
||||
tableRow.put("masterSum", v.stream().filter(unit -> Objects.equals(unit.getUnitCode(), k) && unit.getIsMaster()).count());
|
||||
// 协办提案数
|
||||
tableRow.put("slaveSum", v.stream().filter(unit -> Objects.equals(unit.getUnitCode(), k) && !unit.getIsMaster()).count());
|
||||
|
||||
// 该单位负责的提案
|
||||
List<String> thisUnitProposalIds = v.stream().map(ProposalReplyUnit::getProposalId).toList();
|
||||
List<ProcessInstance> instances = dao.query(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", thisUnitProposalIds));
|
||||
List<Long> thisUnitInstIds = instances.stream().map(ProcessInstance::getId).toList();
|
||||
|
||||
// 反馈评分记录
|
||||
List<ProcessTask> feedbackTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", thisUnitInstIds)
|
||||
.and(ProcessTask::getTaskName, "=", "feedback")
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode()));
|
||||
|
||||
for (Sys_dict code : feedbackCodes) {
|
||||
long count = feedbackTasks.stream().filter(task -> FlowUtil.variableToNutMap(task.getVariable()).getString("tf_feedback", "").equals(code.getCode())).map(ProcessTask::getProcessInstanceId).distinct().count();
|
||||
tableRow.put(code.getCode(), count);
|
||||
}
|
||||
tableData.add(tableRow);
|
||||
});
|
||||
|
||||
// 汇总完成后在服务层执行白名单排序,数字列按数值顺序处理。
|
||||
proposalCommonService.sortStatisticsRows(tableData, pageForm, orderColumns);
|
||||
return Result.success(tableData);
|
||||
return Result.success(proposalCommonService.queryUnderTakeSatisfactionStatistics(
|
||||
pageForm, sessionId, undertakeUnitId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 按当前届次、承办单位和页面可见字段导出满意度统计。
|
||||
*
|
||||
* @param pageForm 页面排序参数
|
||||
* @param sessionId 教代会届次ID
|
||||
* @param undertakeUnitId 承办单位ID
|
||||
* @param tableColumns 当前可见字段
|
||||
* @param response HTTP 响应,返回 XSSF Excel
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.query.underTake.satisfaction")
|
||||
public void exportCustomAsExcel(@Valid @Param("pageForm") PageForm pageForm,
|
||||
@Param("sessionId") String sessionId,
|
||||
@Param("undertakeUnitId") String undertakeUnitId,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns,
|
||||
HttpServletResponse response) {
|
||||
proposalCommonService.exportUnderTakeSatisfactionAsExcel(
|
||||
pageForm, sessionId, undertakeUnitId, tableColumns, response);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -101,7 +101,8 @@ public class ProposalExpeditingController {
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("t.taskName", "in", List.of("master_reply", "slave_reply", "opinion_master_reply"));
|
||||
// 催办列表只展示现行 WF 承办答复环节中尚未完成的主办、二次答复及意见答复任务。
|
||||
cnd.and("t.taskName", "in", List.of("unit_reply", "two_unit_reply", "opinion_unit_reply"));
|
||||
|
||||
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name()) && !AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
|
||||
|
||||
+12
-2
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.transact;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
@@ -55,8 +56,17 @@ public class ProposalCaseCheckController {
|
||||
public void index() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开提案委员会审查手机端列表页。
|
||||
*/
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/caseCheck/index.html")
|
||||
@SaCheckPermission("h5.proposal.caseCheck")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.caseCheck")
|
||||
@SaCheckPermission(value = {"proposal.caseCheck", "h5.proposal.caseCheck"}, mode = SaMode.OR)
|
||||
@ApiOperation("分页列表")
|
||||
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
|
||||
Sql sql = Sqls.create("""
|
||||
@@ -129,7 +139,7 @@ public class ProposalCaseCheckController {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.caseCheck")
|
||||
@SaCheckPermission(value = {"proposal.caseCheck", "h5.proposal.caseCheck"}, mode = SaMode.OR)
|
||||
@ApiOperation("查询当前提案承办单位")
|
||||
public Result listReplyUnits(String proposalId) {
|
||||
return Result.success(proposalCaseCheckService.listReplyUnits(proposalId));
|
||||
|
||||
-1
@@ -49,7 +49,6 @@ public class ProposalCommissionerController {
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.commissioner")
|
||||
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
|
||||
|
||||
+11
@@ -125,6 +125,17 @@ public class ProposalCommitteeFilingController {
|
||||
proposalCommonService.exportWorkflowList("committeeFiling", pageForm, approval, tableColumns, response);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.committeeFiling")
|
||||
@ApiOperation("执行单案立案审核任务")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result executeTask(@Param("data") String data) {
|
||||
// data 包含流程任务ID、提交类型、立案结果及主协办单位;Service 校验负责人后执行 WF,成功返回统一 Result。
|
||||
Dict args = Json.fromJson(Dict.class, data);
|
||||
proposalCommitteeFilingService.executeFlowTask(args);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.committeeFiling")
|
||||
@ApiOperation("并案审核")
|
||||
|
||||
+2
-1
@@ -47,6 +47,7 @@ public class ProposalControlController {
|
||||
@SaCheckPermission("proposal.control")
|
||||
@ApiOperation("分页列表")
|
||||
public Result pageData(@Valid ProposalSearchParam pageForm) {
|
||||
// 状态调整属于提案业务,只保留能够关联到 proposal_info 的 WF 任务,排除其他业务流程产生的空白行。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
@@ -72,7 +73,7 @@ public class ProposalControlController {
|
||||
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
|
||||
LEFT JOIN proposal_info info ON info.id = ins.businessNo
|
||||
INNER JOIN proposal_info info ON info.id = ins.businessNo
|
||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||
LEFT JOIN teacher_congress_session tcs ON tcs.id = info.sessionId
|
||||
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId
|
||||
|
||||
-13
@@ -4,7 +4,6 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
||||
@@ -30,10 +29,8 @@ 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;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -67,7 +64,6 @@ public class ProposalDelegationController {
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.delegation")
|
||||
@ApiOperation("分页列表")
|
||||
@@ -129,13 +125,4 @@ public class ProposalDelegationController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.delegation")
|
||||
@ApiOperation("导出列表")
|
||||
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||
proposalCommonService.exportWorkflowList("delegation", pageForm, approval, tableColumns, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-12
@@ -5,7 +5,6 @@ import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
@@ -27,7 +26,6 @@ import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
@IocBean
|
||||
@@ -54,7 +52,6 @@ public class ProposalFeedbackEvaluationController {
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||
@ApiOperation("分页列表")
|
||||
@@ -118,15 +115,6 @@ public class ProposalFeedbackEvaluationController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||
@ApiOperation("导出列表")
|
||||
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||
proposalCommonService.exportWorkflowList("feedbackEvaluation", pageForm, approval, tableColumns, response);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||
@ApiOperation("获取立案信息")
|
||||
|
||||
+5
@@ -52,6 +52,11 @@ public class ProposalPreAuditController {
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/preAudit/index.html")
|
||||
@SaCheckPermission("proposal.preAudit")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.preAudit")
|
||||
|
||||
-1
@@ -74,7 +74,6 @@ public class ProposalSchoolLeaderApprovalController {
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.schoolLeaderApproval")
|
||||
@ApiOperation("分页列表")
|
||||
|
||||
+11
@@ -134,6 +134,9 @@ public class ProposalSecondedController {
|
||||
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
|
||||
LEFT JOIN wf_process_task dt ON dt.processInstanceId = ins.id
|
||||
AND dt.taskName = 'delegation' AND dt.taskState = 20
|
||||
AND (dt.variable ->> '$.submitType') IN ('1', '2')
|
||||
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
|
||||
LEFT JOIN proposal_info info ON info.id = ins.businessNo
|
||||
LEFT JOIN proposal_second ps ON ps.proposalId = info.id AND ps.seconderId = @seconderId
|
||||
@@ -157,6 +160,8 @@ public class ProposalSecondedController {
|
||||
} else {
|
||||
// 未附议页签只展示当前登录附议人尚未处理的记录。
|
||||
cnd.and("ps.isAgree", "is", null);
|
||||
// 团长选择同意或不同意后均截止附议;退回提案人不视为最终审核结果。
|
||||
cnd.and("dt.id", "is", null);
|
||||
// 待附议列表只展示两类任务:
|
||||
// 1. invite / second 节点任务
|
||||
// 2. delegation / committee 节点,且任务状态必须是已废弃(99)
|
||||
@@ -216,6 +221,9 @@ public class ProposalSecondedController {
|
||||
if (Strings.isBlank(proposalId) || Strings.isBlank(taskActorUserId) || taskId == null || submitType == null) {
|
||||
return Result.error("参数错误");
|
||||
}
|
||||
if (proposalSecondedService.isDelegationReviewed(proposalId)) {
|
||||
return Result.error("团长已完成审核,当前提案不能继续附议");
|
||||
}
|
||||
|
||||
// 先定位 wf_process_task,确保本次请求能准确命中需要完成的附议任务,再更新两张业务表。
|
||||
ProcessTask processTask = this.getSecondTask(taskId, taskActorUserId);
|
||||
@@ -294,6 +302,9 @@ public class ProposalSecondedController {
|
||||
if (args.getLong("processTaskId") == null || Strings.isBlank(proposalId) || Strings.isBlank(taskActorUserId) || submitType == null) {
|
||||
return Result.error("参数错误");
|
||||
}
|
||||
if (proposalSecondedService.isDelegationReviewed(proposalId)) {
|
||||
return Result.error("团长已完成审核,当前提案不能继续附议");
|
||||
}
|
||||
flowCommonService.executeTask(args);
|
||||
proposalSecondedService.updateSecondRecord(proposalId, taskActorUserId, opinion, submitType);
|
||||
return Result.success();
|
||||
|
||||
-11
@@ -5,7 +5,6 @@ import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
@@ -38,7 +37,6 @@ import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
@@ -172,15 +170,6 @@ public class ProposalUnderTakeReplyController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("proposal.unitReply")
|
||||
@ApiOperation("导出列表")
|
||||
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||
proposalCommonService.exportWorkflowList("unitReply", pageForm, approval, tableColumns, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 承办单位答复节点撤回需要基于整组当前节点判断。
|
||||
* 只有“当前流程正在办理的节点”和“这条列表记录所属节点”完全一致时,才允许撤回;
|
||||
|
||||
+5
-1
@@ -73,6 +73,10 @@ public class ProposalCaseFilingInterceptor implements FlowInterceptor {
|
||||
Dict dict = JSONUtil.toBean(processTask.getVariable(), Dict.class);
|
||||
dict.set(FlowConst.TASK_FORM_DATA_PREFIX + "helpunitreply", helpUnitReply);
|
||||
processTask.setVariable(JSONUtil.toJsonStr(dict));
|
||||
dao.update(processTask);
|
||||
/*
|
||||
* 当前任务对象是在任务完成前加载的,其中 finishTime、operator 仍为空。
|
||||
* 这里只更新拦截器实际修改的流程变量,避免整行更新覆盖 WF 已写入的办理时间和办理人。
|
||||
*/
|
||||
dao.update(processTask, "variable");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
@Accessors(chain = true)
|
||||
@Table("proposal_reply_unit")
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
@TableIndexes({
|
||||
@Index(name = "INDEX_PROPOSAL_REPLY_UNIT_PROPOSAL_UNIT", fields = {"proposalId", "unitId"}, unique = false)
|
||||
})
|
||||
@Comment("提案信息")
|
||||
public class ProposalReplyUnit extends BaseModel {
|
||||
|
||||
|
||||
+29
-3
@@ -19,6 +19,8 @@ public class ProposalQueryComprehensiveParam extends PageForm {
|
||||
private String name;
|
||||
@ApiModelProperty(name = "提案编号")
|
||||
private String code;
|
||||
@ApiModelProperty(name = "立案编号")
|
||||
private String caseFilingCode;
|
||||
@ApiModelProperty(name = "教代会ID")
|
||||
private String sessionId;
|
||||
@ApiModelProperty(name = "search session id")
|
||||
@@ -61,15 +63,22 @@ public class ProposalQueryComprehensiveParam extends PageForm {
|
||||
@ApiModelProperty(name = "通用关键字")
|
||||
private String commonKeyword;
|
||||
|
||||
@ApiModelProperty(name = "提案名称或编号搜索字段,仅支持name、code、caseFilingCode")
|
||||
private String proposalSearchField;
|
||||
|
||||
@ApiModelProperty(name = "提案名称或编号搜索内容")
|
||||
private String proposalKeyword;
|
||||
|
||||
@ApiModelProperty(name = "搜索关键字")
|
||||
private String createUserKeyword;
|
||||
|
||||
|
||||
/**
|
||||
* 构建通用查询参数
|
||||
* 将综合查询参数追加到查询条件中,无返回值,处理结果直接写入 cnd。
|
||||
*
|
||||
* @param cnd cnd
|
||||
* @param searchParam searchParam
|
||||
* @param cnd 查询条件容器,用于接收届次、名称/编号、提案人、组织及立案条件
|
||||
* @param searchParam 页面查询参数;proposalSearchField 传 name、code 或 caseFilingCode,
|
||||
* proposalKeyword 传对应字段的模糊搜索内容
|
||||
*/
|
||||
public static void buildSearch(Cnd cnd, ProposalQueryComprehensiveParam searchParam) {
|
||||
if (cnd == null) {
|
||||
@@ -84,6 +93,19 @@ public class ProposalQueryComprehensiveParam extends PageForm {
|
||||
// Isolated single-session filter for pages that should not reuse sessionId semantics.
|
||||
cnd.andEX("info.sessionId", "=", searchParam.getSearchSessionId());
|
||||
|
||||
// 名称/编号组合搜索仅允许三个固定字段,前端提交值不能直接作为SQL字段使用。
|
||||
if (StrUtil.isNotBlank(searchParam.getProposalKeyword())) {
|
||||
String proposalSearchColumn = switch (StrUtil.blankToDefault(searchParam.getProposalSearchField(), "name")) {
|
||||
case "name" -> "info.name";
|
||||
case "code" -> "info.code";
|
||||
case "caseFilingCode" -> "info.caseFilingCode";
|
||||
default -> null;
|
||||
};
|
||||
if (proposalSearchColumn != null) {
|
||||
cnd.where().andLike(proposalSearchColumn, searchParam.getProposalKeyword());
|
||||
}
|
||||
}
|
||||
|
||||
//提案名称
|
||||
if (StrUtil.isNotBlank(searchParam.getName())) {
|
||||
cnd.where().andLike("info.name", searchParam.getName());
|
||||
@@ -92,6 +114,10 @@ public class ProposalQueryComprehensiveParam extends PageForm {
|
||||
if (StrUtil.isNotBlank(searchParam.getCode())) {
|
||||
cnd.where().andLike("info.code", searchParam.getCode());
|
||||
}
|
||||
// 立案编号由立案环节生成,支持按已生成编号进行模糊检索。
|
||||
if (StrUtil.isNotBlank(searchParam.getCaseFilingCode())) {
|
||||
cnd.where().andLike("info.caseFilingCode", searchParam.getCaseFilingCode());
|
||||
}
|
||||
//代表团ID
|
||||
cnd.andEX("info.delegationId", "=", searchParam.getDelegationId());
|
||||
if (StrUtil.isNotBlank(searchParam.getCreateUserName())) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user