commit
This commit is contained in:
+4
-18
@@ -128,27 +128,13 @@ public class ProposalDashboardController {
|
||||
nodes.addAll(taskNodes);
|
||||
nodes.addAll(feedbackNodes);
|
||||
|
||||
// 查询待办任务
|
||||
Sql todoSql = Sqls.create("""
|
||||
SELECT
|
||||
t.taskName,
|
||||
t.taskState
|
||||
FROM
|
||||
wf_process_task t
|
||||
INNER JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
INNER JOIN proposal_info info ON info.id = ins.businessNo
|
||||
WHERE
|
||||
info.sessionId = @sessionId
|
||||
""");
|
||||
todoSql.setParam("sessionId", sessionId);
|
||||
List<NutMap> todoTasks = processDefineService.listMap(todoSql);
|
||||
Map<String, NutMap> taskProposalCounts = proposalCommonService.countDashboardTaskProposals(sessionId);
|
||||
|
||||
for (NutMap node : nodes) {
|
||||
if (node.getString("type").equals("task")) {
|
||||
long todoCount = todoTasks.stream().filter(task -> task.getInt("taskState") == ProcessTaskStateEnum.DOING.getCode() && task.getString("taskName").equals(node.getString("id"))).count();
|
||||
node.put("todoCount", todoCount);
|
||||
long doneCount = todoTasks.stream().filter(task -> task.getInt("taskState") == ProcessTaskStateEnum.FINISHED.getCode() && task.getString("taskName").equals(node.getString("id"))).count();
|
||||
node.put("doneCount", doneCount);
|
||||
NutMap taskCount = taskProposalCounts.get(node.getString("id"));
|
||||
node.put("todoCount", taskCount == null ? 0 : taskCount.getLong("todoCount", 0L));
|
||||
node.put("doneCount", taskCount == null ? 0 : taskCount.getLong("doneCount", 0L));
|
||||
} else if (node.getString("type").equals("total")) {
|
||||
int count = dao.count(ProposalInfo.class, Cnd.where(ProposalInfo::getSessionId, "=", sessionId));
|
||||
node.put("count", count);
|
||||
|
||||
+1
-88
@@ -1,22 +1,13 @@
|
||||
package com.budwk.app.zhgh.democratic.proposal.controller.query;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
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.Dao;
|
||||
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.lang.util.NutMap;
|
||||
@@ -27,7 +18,6 @@ import org.nutz.mvc.annotation.Param;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@IocBean
|
||||
@@ -37,20 +27,6 @@ import java.util.Map;
|
||||
@Api(tags = "征集进度查询")
|
||||
public class ProposalQueryCollectProgressController {
|
||||
|
||||
/**
|
||||
* 征集进度表格允许排序的字段映射,值为查询中的真实字段或安全别名。
|
||||
*/
|
||||
private static final Map<String, String> COLLECT_PROGRESS_ORDER_COLUMNS = Map.ofEntries(
|
||||
Map.entry("code", "info.code"),
|
||||
Map.entry("name", "info.name"),
|
||||
Map.entry("createUserName", "info.createUserName"),
|
||||
Map.entry("delegationName", "delegationName"),
|
||||
Map.entry("inviteCount", "inviteCount"),
|
||||
Map.entry("finishCount", "finishCount"),
|
||||
Map.entry("curTaskName", "curTaskName"),
|
||||
Map.entry("instanceState", "instanceState")
|
||||
);
|
||||
|
||||
static List<NutMap> states = new ArrayList<>() {{
|
||||
add(NutMap.NEW().addv("code", 10).addv("id", 10).addv("name", "撰写提案"));
|
||||
add(NutMap.NEW().addv("code", 20).addv("id", 20).addv("name", "附议提案"));
|
||||
@@ -60,9 +36,6 @@ public class ProposalQueryCollectProgressController {
|
||||
|
||||
@Inject
|
||||
private ProposalCommonService proposalCommonService;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/democratic/proposal/query/collectProgress/index.html")
|
||||
@@ -74,67 +47,7 @@ public class ProposalQueryCollectProgressController {
|
||||
@SaCheckPermission("proposal.query.collectProgress")
|
||||
@ApiOperation(value = "分页列表")
|
||||
public Result pageData(@Valid @Param("pageForm") ProposalQueryComprehensiveParam pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
info.name,
|
||||
info.code,
|
||||
info.createUserName,
|
||||
type.NAME AS typeName,
|
||||
tcs.fullName AS sessionName,
|
||||
tcd.`name` AS delegationName,
|
||||
(SELECT count(1) FROM proposal_second WHERE proposalId = info.id) AS inviteCount,
|
||||
(SELECT count(1) FROM wf_process_task WHERE processInstanceId = ins.id AND taskName = 'second' AND taskState = 20) finishCount,
|
||||
ins.id AS instanceId,
|
||||
ins.state instanceState,
|
||||
t.displayName curTaskName
|
||||
FROM
|
||||
proposal_info info
|
||||
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
|
||||
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
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
// 征集进度必须按页面选中的教代会过滤,避免共享参数未处理sessionId导致跨届次查询。
|
||||
cnd.andEX("info.sessionId", "=", pageForm.getSessionId());
|
||||
ProposalQueryComprehensiveParam.buildSearch(cnd, pageForm);
|
||||
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 10)) {
|
||||
seg.or("t.taskName", "=", "startTask");
|
||||
}
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 20)) {
|
||||
seg.or("t.taskName", "=", "second");
|
||||
}
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 30)) {
|
||||
seg.or("t.taskName", "=", "delegation");
|
||||
}
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 40)) {
|
||||
seg.or("t.taskName", "not in", List.of("startTask", "second", "delegation"));
|
||||
seg.and("t.taskName", "is not", null);
|
||||
seg.or("ins.state","=", ProcessInstanceStateEnum.FINISHED.getCode());
|
||||
}
|
||||
if (!seg.isEmpty()) {
|
||||
cnd.and(seg);
|
||||
}
|
||||
cnd.groupBy("info.id");
|
||||
// 征集进度包含关联字段和人数统计别名,只允许白名单字段进入排序条件。
|
||||
proposalCommonService.applySafePageOrder(cnd, pageForm, COLLECT_PROGRESS_ORDER_COLUMNS);
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
List<NutMap> list = (List<NutMap>) pagination.getList();
|
||||
// for (NutMap row : list) {
|
||||
// int count = dao.count(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", row.getString("instanceId"))
|
||||
// .and(ProcessTask::getTaskName, "=", "second")
|
||||
// .and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())
|
||||
// );
|
||||
//
|
||||
//
|
||||
// }
|
||||
Pagination pagination = proposalCommonService.queryCollectProgress(pageForm);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
|
||||
+8
-6
@@ -77,6 +77,10 @@ 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
|
||||
@@ -90,19 +94,17 @@ public class ProposalQueryDelegationController {
|
||||
FROM
|
||||
teacher_congress_delegation dbt
|
||||
$condition
|
||||
""");
|
||||
""");
|
||||
Map<String, String> summaryOrderColumns = new HashMap<>(DELEGATION_SUMMARY_ORDER_COLUMNS);
|
||||
List<String> resultSqlParts = new ArrayList<>();
|
||||
int resultIndex = 0;
|
||||
for (Sys_dict dict : dictList) {
|
||||
String resultCode = dict.getCode();
|
||||
// 动态别名仅允许字母、数字和下划线,查询值使用参数绑定,避免字典内容进入SQL结构。
|
||||
// 动态别名和立案结果编码仅允许字母、数字和下划线;变量替换后新增的 @ 参数不会被 Nutz 再次解析,
|
||||
// 因此这里使用已校验的字典编码字面量,确保统计条件能正确传递给数据库。
|
||||
if (StrUtil.isBlank(resultCode) || !resultCode.matches("[A-Za-z0-9_]+")) {
|
||||
continue;
|
||||
}
|
||||
String paramName = "caseFilingResult" + resultIndex++;
|
||||
resultSqlParts.add(", (select count(1) from proposal_info info where info.delegationId = dbt.id and info.sessionId = dbt.sessionId and info.caseFilingResult = @" + paramName + ") AS `" + resultCode + "`");
|
||||
sql.setParam(paramName, resultCode);
|
||||
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));
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ public class ProposalSeniorBasicController {
|
||||
return Result.error("提案编号已存在");
|
||||
}
|
||||
|
||||
dao.update(proposalInfo,"^code|name|typeId|brief|measures|excerpt|suggestUnits|files$");
|
||||
dao.update(proposalInfo,"^code|caseFilingCode|name|typeId|brief|measures|excerpt|suggestUnits|files$");
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
+27
-1
@@ -103,7 +103,7 @@ public class ProposalMineController {
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/mine/index.html")
|
||||
@SaCheckPermission("proposal.mine")
|
||||
@SaCheckPermission("h5.proposal.mine")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
@@ -111,6 +111,18 @@ public class ProposalMineController {
|
||||
@SaCheckPermission("proposal.mine")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result pageData(@Valid ProposalSearchParam pageForm, String sessionId) {
|
||||
return queryPageData(pageForm, sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录人的提案分页数据。
|
||||
* PC 与 H5 入口共享同一数据范围和排序规则,避免两个端的列表结果不一致。
|
||||
*
|
||||
* @param pageForm 页面筛选及分页参数
|
||||
* @param sessionId 教代会届次ID
|
||||
* @return 当前登录人的提案分页结果
|
||||
*/
|
||||
private Result queryPageData(ProposalSearchParam pageForm, String sessionId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
@@ -158,6 +170,20 @@ public class ProposalMineController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的提案 H5 分页列表。
|
||||
* H5 使用独立权限标识,但查询口径与 PC 端保持一致。
|
||||
*
|
||||
* @param pageForm 页面筛选及分页参数
|
||||
* @param sessionId 教代会届次ID
|
||||
* @return 当前登录人的提案分页结果
|
||||
*/
|
||||
@At("/h5/pageData")
|
||||
@SaCheckPermission("h5.proposal.mine")
|
||||
public Result h5PageData(@Valid ProposalSearchParam pageForm, String sessionId) {
|
||||
return queryPageData(pageForm, sessionId);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.mine")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
|
||||
+27
-1
@@ -84,13 +84,25 @@ public class ProposalSecondedController {
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/seconded/index.html")
|
||||
@SaCheckPermission("proposal.seconded")
|
||||
@SaCheckPermission("h5.proposal.seconded")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.seconded")
|
||||
public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) {
|
||||
return queryPageData(pageForm, approval);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前登录附议人的提案分页数据。
|
||||
* PC 与 H5 入口共享同一待附议、已附议筛选口径。
|
||||
*
|
||||
* @param pageForm 页面筛选及分页参数
|
||||
* @param approval 是否查询已附议记录
|
||||
* @return 附议提案分页结果
|
||||
*/
|
||||
private Result queryPageData(ProposalSearchParam pageForm, boolean approval) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
@@ -165,6 +177,20 @@ public class ProposalSecondedController {
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提案附议 H5 分页列表。
|
||||
* H5 使用独立权限标识,但查询口径与 PC 端保持一致。
|
||||
*
|
||||
* @param pageForm 页面筛选及分页参数
|
||||
* @param approval 是否查询已附议记录
|
||||
* @return 附议提案分页结果
|
||||
*/
|
||||
@At("/h5/pageData")
|
||||
@SaCheckPermission("h5.proposal.seconded")
|
||||
public Result h5PageData(@Valid ProposalSearchParam pageForm, boolean approval) {
|
||||
return queryPageData(pageForm, approval);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.seconded")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
|
||||
+19
@@ -5,7 +5,9 @@ import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
|
||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
|
||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
@@ -171,4 +173,21 @@ public interface ProposalCommonService extends BaseService<ProposalInfo> {
|
||||
* 修改提案状态码
|
||||
*/
|
||||
void updateStateCode(String id, Integer stateCode);
|
||||
|
||||
/**
|
||||
* 查询提案征集进度列表。
|
||||
* 查询结果与页面既有筛选、排序语义保持一致,内部使用聚合关联避免逐行执行统计子查询。
|
||||
*
|
||||
* @param pageForm 征集进度页面的筛选、排序和分页参数
|
||||
* @return 包含征集进度统计字段的分页结果
|
||||
*/
|
||||
Pagination queryCollectProgress(ProposalQueryComprehensiveParam pageForm);
|
||||
|
||||
/**
|
||||
* 按提案去重统计指定届次各流程节点的待办和已办数量。
|
||||
*
|
||||
* @param sessionId 教代会届次ID
|
||||
* @return 键为流程节点编码、值为待办和已办数量的统计结果
|
||||
*/
|
||||
Map<String, NutMap> countDashboardTaskProposals(String sessionId);
|
||||
}
|
||||
|
||||
+172
-29
@@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.service.common;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -15,6 +16,7 @@ import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.param.ExportTableColumns;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
@@ -56,6 +58,7 @@ import org.nutz.dao.FieldFilter;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.Daos;
|
||||
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;
|
||||
@@ -85,6 +88,18 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
/** 办理页面允许导出的列表字段,避免请求参数携带非页面字段。 */
|
||||
private static final Map<String, Set<String>> WORKFLOW_EXPORT_COLUMNS = createWorkflowExportColumns();
|
||||
|
||||
/** 征集进度页面允许排序的字段,避免排序参数直接拼接到SQL。 */
|
||||
private static final Map<String, String> COLLECT_PROGRESS_ORDER_COLUMNS = Map.ofEntries(
|
||||
Map.entry("code", "info.code"),
|
||||
Map.entry("name", "info.name"),
|
||||
Map.entry("createUserName", "info.createUserName"),
|
||||
Map.entry("delegationName", "delegationName"),
|
||||
Map.entry("inviteCount", "inviteCount"),
|
||||
Map.entry("finishCount", "finishCount"),
|
||||
Map.entry("curTaskName", "curTaskName"),
|
||||
Map.entry("instanceState", "instanceState")
|
||||
);
|
||||
|
||||
//找出富文本里面上传的图片
|
||||
static String IMG_SRC_REGEX = "<img\\s+[^>]*src\\s*=\\s*([\"'])(/platform/sys/file/download\\?id=.*?)\\1[^>]*>";
|
||||
|
||||
@@ -107,6 +122,128 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
super(dao);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询提案征集进度。
|
||||
* 附议人数和已附议人数使用分组结果关联,避免原查询对每一条提案重复执行统计子查询;
|
||||
* 总数查询只保留筛选所需关联,避免分页统计重复执行列表中的统计计算。
|
||||
*
|
||||
* @param pageForm 页面筛选、排序和分页参数
|
||||
* @return 征集进度分页数据
|
||||
*/
|
||||
@Override
|
||||
public Pagination queryCollectProgress(ProposalQueryComprehensiveParam pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
info.name,
|
||||
info.code,
|
||||
info.createUserName,
|
||||
type.NAME AS typeName,
|
||||
tcs.fullName AS sessionName,
|
||||
tcd.`name` AS delegationName,
|
||||
COALESCE(secondStat.inviteCount, 0) AS inviteCount,
|
||||
COALESCE(taskStat.finishCount, 0) AS finishCount,
|
||||
ins.id AS instanceId,
|
||||
ins.state AS instanceState,
|
||||
t.displayName AS curTaskName
|
||||
FROM proposal_info info
|
||||
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
|
||||
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 (
|
||||
SELECT proposalId, COUNT(1) AS inviteCount
|
||||
FROM proposal_second
|
||||
GROUP BY proposalId
|
||||
) secondStat ON secondStat.proposalId = info.id
|
||||
LEFT JOIN (
|
||||
SELECT processInstanceId, COUNT(1) AS finishCount
|
||||
FROM wf_process_task
|
||||
WHERE taskName = 'second' AND taskState = 20
|
||||
GROUP BY processInstanceId
|
||||
) taskStat ON taskStat.processInstanceId = ins.id
|
||||
$condition
|
||||
""");
|
||||
Cnd dataCnd = buildCollectProgressCondition(pageForm);
|
||||
dataCnd.groupBy("info.id");
|
||||
applySafePageOrder(dataCnd, pageForm, COLLECT_PROGRESS_ORDER_COLUMNS);
|
||||
sql.setCondition(dataCnd);
|
||||
|
||||
Sql countSql = Sqls.create("""
|
||||
SELECT COUNT(DISTINCT info.id)
|
||||
FROM proposal_info info
|
||||
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
|
||||
$condition
|
||||
""");
|
||||
countSql.setCondition(buildCollectProgressCondition(pageForm));
|
||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql, countSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按提案ID去重统计数据看板的流程节点数量。
|
||||
* 同一提案因撤回、退回等再次经过同一节点时,任务表会保留多条已办记录;
|
||||
* 此处按提案统计,使看板数量与下方按提案展示的列表保持一致。
|
||||
*
|
||||
* @param sessionId 教代会届次ID
|
||||
* @return 以流程节点编码为键的待办、已办统计结果
|
||||
*/
|
||||
@Override
|
||||
public Map<String, NutMap> countDashboardTaskProposals(String sessionId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t.taskName,
|
||||
COUNT(DISTINCT CASE WHEN t.taskState = @doingState THEN info.id END) AS todoCount,
|
||||
COUNT(DISTINCT CASE WHEN t.taskState = @finishedState THEN info.id END) AS doneCount
|
||||
FROM wf_process_task t
|
||||
INNER JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
INNER JOIN proposal_info info ON info.id = ins.businessNo
|
||||
WHERE info.sessionId = @sessionId
|
||||
GROUP BY t.taskName
|
||||
""");
|
||||
sql.setParam("sessionId", sessionId);
|
||||
sql.setParam("doingState", ProcessTaskStateEnum.DOING.getCode());
|
||||
sql.setParam("finishedState", ProcessTaskStateEnum.FINISHED.getCode());
|
||||
List<NutMap> taskCounts = listMap(sql);
|
||||
return taskCounts.stream().collect(Collectors.toMap(task -> task.getString("taskName"), task -> task));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建征集进度列表和总数查询共用的筛选条件,确保两次查询返回同一数据范围。
|
||||
* 征集阶段条件保持页面原有的布尔组合方式,避免优化时改变既有查询结果。
|
||||
*
|
||||
* @param pageForm 页面筛选参数
|
||||
* @return 不含分组和排序的查询条件
|
||||
*/
|
||||
private Cnd buildCollectProgressCondition(ProposalQueryComprehensiveParam pageForm) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("info.sessionId", "=", pageForm.getSessionId());
|
||||
ProposalQueryComprehensiveParam.buildSearch(cnd, pageForm);
|
||||
|
||||
SqlExpressionGroup collectStageCondition = new SqlExpressionGroup();
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 10)) {
|
||||
collectStageCondition.or("t.taskName", "=", "startTask");
|
||||
}
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 20)) {
|
||||
collectStageCondition.or("t.taskName", "=", "second");
|
||||
}
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 30)) {
|
||||
collectStageCondition.or("t.taskName", "=", "delegation");
|
||||
}
|
||||
if (ArrayUtil.contains(pageForm.getCollectIds(), 40)) {
|
||||
collectStageCondition.or("t.taskName", "not in", List.of("startTask", "second", "delegation"));
|
||||
collectStageCondition.and("t.taskName", "is not", null);
|
||||
collectStageCondition.or("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
|
||||
}
|
||||
if (!collectStageCondition.isEmpty()) {
|
||||
cnd.and(collectStageCondition);
|
||||
}
|
||||
return cnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用业务页面提供的字段白名单构建排序条件,非法字段或非法排序方向将被忽略。
|
||||
*
|
||||
@@ -121,8 +258,14 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
return false;
|
||||
}
|
||||
|
||||
// H5 列表首次加载时可能不传排序字段;不可变 Map 不接受 null 键,直接保留页面默认排序。
|
||||
String pageOrderName = pageForm.getPageOrderName();
|
||||
if (StrUtil.isBlank(pageOrderName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 仅允许白名单中的字段参与排序,防止构造任意SQL排序字段。
|
||||
String orderColumn = allowedOrderColumns.get(pageForm.getPageOrderName());
|
||||
String orderColumn = allowedOrderColumns.get(pageOrderName);
|
||||
String orderBy = PageUtil.getOrder(pageForm.getPageOrderBy());
|
||||
if (StrUtil.isBlank(orderColumn) || StrUtil.isBlank(orderBy)) {
|
||||
return false;
|
||||
@@ -814,35 +957,35 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
|
||||
// 获取流程实例
|
||||
ProcessInstance processInstance = dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", id));
|
||||
if (processInstance != null) {
|
||||
// 主办办理情况
|
||||
ProcessTask masterUnitReplyTask = dao().fetch(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId())
|
||||
.and(ProcessTask::getTaskName, "in", List.of("master_reply", "opinion_master_reply"))
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())
|
||||
.desc(ProcessTask::getFinishTime)
|
||||
);
|
||||
if (masterUnitReplyTask != null) {
|
||||
// 办理解决情况
|
||||
String implementState = FlowUtil.variableToDict(masterUnitReplyTask.getVariable()).getStr("tf_implementState");
|
||||
info.put(implementState, "√");
|
||||
// 承办单位名称
|
||||
info.put("underTakeName", FlowUtil.variableToDict(masterUnitReplyTask.getVariable()).getStr("underTakeName"));
|
||||
}
|
||||
|
||||
// 主办办理情况
|
||||
ProcessTask masterUnitReplyTask = dao().fetch(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId())
|
||||
.and(ProcessTask::getTaskName, "in", List.of("master_reply", "opinion_master_reply"))
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())
|
||||
.desc(ProcessTask::getFinishTime)
|
||||
);
|
||||
if (masterUnitReplyTask != null) {
|
||||
// 办理解决情况
|
||||
String implementState = FlowUtil.variableToDict(masterUnitReplyTask.getVariable()).getStr("tf_implementState");
|
||||
info.put(implementState, "√");
|
||||
// 承办单位名称
|
||||
info.put("underTakeName", FlowUtil.variableToDict(masterUnitReplyTask.getVariable()).getStr("underTakeName"));
|
||||
}
|
||||
|
||||
|
||||
// 反馈评价
|
||||
ProcessTask feedbackTask = dao().fetch(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId())
|
||||
.and(ProcessTask::getTaskName, "=", "feedback")
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())
|
||||
.desc(ProcessTask::getFinishTime)
|
||||
);
|
||||
if (feedbackTask != null) {
|
||||
info.put(FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_feedback"), "√");
|
||||
info.put("tf_feedback", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_feedback"));
|
||||
info.put("tf_opinion", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_opinion"));
|
||||
info.put("tf_phone", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_phone"));
|
||||
info.put("tf_address", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_address"));
|
||||
info.put("tf_postcode", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_postcode"));
|
||||
// 反馈评价
|
||||
ProcessTask feedbackTask = dao().fetch(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId())
|
||||
.and(ProcessTask::getTaskName, "=", "feedback")
|
||||
.and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())
|
||||
.desc(ProcessTask::getFinishTime)
|
||||
);
|
||||
if (feedbackTask != null) {
|
||||
info.put(FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_feedback"), "√");
|
||||
info.put("tf_feedback", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_feedback"));
|
||||
info.put("tf_opinion", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_opinion"));
|
||||
info.put("tf_phone", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_phone"));
|
||||
info.put("tf_address", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_address"));
|
||||
info.put("tf_postcode", FlowUtil.variableToDict(feedbackTask.getVariable()).getStr("tf_postcode"));
|
||||
}
|
||||
}
|
||||
|
||||
HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy();
|
||||
|
||||
+12
-3
@@ -82,12 +82,12 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
throw new BaseException("提案信息不存在");
|
||||
}
|
||||
args.put("proposalId", proposalId);
|
||||
validateAndNormalizeCaseFilingCode(args);
|
||||
|
||||
List<String> proposalIds = proposalCommonService.mergeProposal(proposalId);
|
||||
if (ObjectUtil.isEmpty(proposalIds)) {
|
||||
proposalIds = List.of(proposalId);
|
||||
}
|
||||
validateAndNormalizeCaseFilingCode(args, proposalIds);
|
||||
|
||||
/*
|
||||
* 先同步 proposal_info 和承办单位,再执行 WF 流转,使查看页面及下一节点读取到的都是本次最新数据。
|
||||
@@ -111,12 +111,14 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并规范化立案编号。确定立案时必须传入不超过 20 个字符的编号;
|
||||
* 校验并规范化立案编号。确定立案时必须传入不超过 20 个字符且不与历史立案编号重复的编号;
|
||||
* 当前提案及并案提案不参与重复校验,保证流程回退后可按原编号重新提交。
|
||||
* 其他立案结果不保存编号,避免切换选项后把历史输入带入业务表和流程变量。
|
||||
*
|
||||
* @param args 流程提交参数,其中 tf_caseFilingResult 为立案结果,tf_caseFilingCode 为手工填写的立案编号
|
||||
* @param excludedProposalIds 当前办理的提案及并案提案主键,不参与历史重复判断
|
||||
*/
|
||||
private void validateAndNormalizeCaseFilingCode(Dict args) {
|
||||
private void validateAndNormalizeCaseFilingCode(Dict args, List<String> excludedProposalIds) {
|
||||
String caseFilingResultKey = FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingResult";
|
||||
String caseFilingCodeKey = FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingCode";
|
||||
String caseFilingTypeKey = FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingType";
|
||||
@@ -133,6 +135,13 @@ public class ProposalCommitteeFilingUnitServiceImpl extends BaseServiceImpl<Prop
|
||||
if (caseFilingCode.length() > 20) {
|
||||
throw new BaseException("立案编号不能超过20个字符");
|
||||
}
|
||||
Cnd duplicateCondition = Cnd.where("caseFilingCode", "=", caseFilingCode);
|
||||
if (!ObjectUtil.isEmpty(excludedProposalIds)) {
|
||||
duplicateCondition.and("id", "not in", excludedProposalIds);
|
||||
}
|
||||
if (dao().count(ProposalInfo.class, duplicateCondition) > 0) {
|
||||
throw new BaseException("立案编号已存在,请重新填写");
|
||||
}
|
||||
args.put(caseFilingCodeKey, caseFilingCode);
|
||||
}
|
||||
|
||||
|
||||
+41
-53
@@ -654,9 +654,12 @@ public class ProposalExportServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
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 proposal_reply_unit pru ON pru.proposalId = info.id
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
// 综合导出页面按当前选择的届次导出,避免公共查询参数的跨届次场景影响导出范围。
|
||||
cnd.andEX("info.sessionId", "=", pageForm.getSessionId());
|
||||
ProposalQueryComprehensiveParam.buildSearch(cnd, pageForm);
|
||||
cnd.groupBy("info.id");
|
||||
cnd.asc("info.code");
|
||||
@@ -687,46 +690,45 @@ public class ProposalExportServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
return StrUtil.blankToDefault(name, "unnamed").replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "_");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 ZIP 内唯一且合法的 Word 文件名,避免提案名称中的非法字符或重名条目导致整个压缩包缺文件。
|
||||
*
|
||||
* @param prefix 文档类型前缀
|
||||
* @param proposalRow 提案基础信息
|
||||
* @param entryNameCounts 已生成的基础文件名及其出现次数
|
||||
* @return 可以直接用于 ZipEntry 的文件名
|
||||
*/
|
||||
private String createUniqueZipDocxEntryName(String prefix, NutMap proposalRow, Map<String, Integer> entryNameCounts) {
|
||||
String baseName = sanitizeZipFileName(prefix + "-" + proposalRow.getString("code", "未编号") + "-" + proposalRow.getString("name", "未命名提案"));
|
||||
int sameNameCount = entryNameCounts.merge(baseName, 1, Integer::sum);
|
||||
return baseName + (sameNameCount > 1 ? "-" + sameNameCount : "") + ".docx";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportFeedBackAsZip(ProposalQueryComprehensiveParam pageForm, HttpServletResponse response) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
info.code,
|
||||
info.name
|
||||
FROM
|
||||
proposal_info info
|
||||
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
|
||||
LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.groupBy("info.id");
|
||||
ProposalQueryComprehensiveParam.buildSearch(cnd, pageForm);
|
||||
sql.setCondition(cnd);
|
||||
List<NutMap> list = listMap(sql);
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(bos);
|
||||
List<NutMap> list = queryProposalBaseList(pageForm);
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(bos)) {
|
||||
Map<String, Integer> entryNameCounts = new HashMap<>();
|
||||
for (NutMap proposalRow : list) {
|
||||
try (ByteArrayOutputStream docxByteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||
proposalCommonService.exportProposalFeedBackAsDocx(proposalRow.getString("id"), docxByteArrayOutputStream);
|
||||
ZipEntry zipEntry = new ZipEntry("反馈表-" + proposalRow.getString("code") + "-" + proposalRow.getString("name") + ".docx");
|
||||
if (docxByteArrayOutputStream.size() == 0) {
|
||||
throw new BaseException("提案【{}】反馈表生成失败", proposalRow.getString("code"));
|
||||
}
|
||||
ZipEntry zipEntry = new ZipEntry(createUniqueZipDocxEntryName("反馈表", proposalRow, entryNameCounts));
|
||||
zipOutputStream.putNextEntry(zipEntry);
|
||||
docxByteArrayOutputStream.writeTo(zipOutputStream);
|
||||
zipOutputStream.closeEntry();
|
||||
} catch (IOException e) {
|
||||
// 处理单个文件生成失败的情况
|
||||
e.printStackTrace();
|
||||
throw new BaseException("提案【{}】反馈表写入压缩包失败", proposalRow.getString("code"));
|
||||
}
|
||||
}
|
||||
zipOutputStream.close();
|
||||
zipOutputStream.finish();
|
||||
CommonDownloadUtil.download("提案反馈表压缩包.zip", bos.toByteArray(), response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("导出提案反馈表压缩包失败", e);
|
||||
throw new BaseException("导出提案反馈表压缩包失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,43 +836,29 @@ public class ProposalExportServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
||||
|
||||
@Override
|
||||
public void exportCollectZip(ProposalQueryComprehensiveParam pageForm, HttpServletResponse response) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
info.code,
|
||||
info.name
|
||||
FROM
|
||||
proposal_info info
|
||||
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
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.groupBy("info.id");
|
||||
ProposalQueryComprehensiveParam.buildSearch(cnd, pageForm);
|
||||
sql.setCondition(cnd);
|
||||
List<NutMap> list = listMap(sql);
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(bos);
|
||||
List<NutMap> list = queryProposalBaseList(pageForm);
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(bos)) {
|
||||
Map<String, Integer> entryNameCounts = new HashMap<>();
|
||||
for (NutMap proposalRow : list) {
|
||||
try (ByteArrayOutputStream docxByteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||
exportCollectDocx(proposalRow.getString("id"), docxByteArrayOutputStream);
|
||||
ZipEntry zipEntry = new ZipEntry("征集表-" + proposalRow.getString("code") + "-" + proposalRow.getString("name") + ".docx");
|
||||
if (docxByteArrayOutputStream.size() == 0) {
|
||||
throw new BaseException("提案【{}】征集表生成失败", proposalRow.getString("code"));
|
||||
}
|
||||
ZipEntry zipEntry = new ZipEntry(createUniqueZipDocxEntryName("征集表", proposalRow, entryNameCounts));
|
||||
zipOutputStream.putNextEntry(zipEntry);
|
||||
docxByteArrayOutputStream.writeTo(zipOutputStream);
|
||||
zipOutputStream.closeEntry();
|
||||
} catch (IOException e) {
|
||||
// 处理单个文件生成失败的情况
|
||||
e.printStackTrace();
|
||||
throw new BaseException("提案【{}】征集表写入压缩包失败", proposalRow.getString("code"));
|
||||
}
|
||||
}
|
||||
zipOutputStream.close();
|
||||
zipOutputStream.finish();
|
||||
CommonDownloadUtil.download("提案征集表压缩包.zip", bos.toByteArray(), response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error("导出提案征集表压缩包失败", e);
|
||||
throw new BaseException("导出提案征集表压缩包失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+80
-24
@@ -17,6 +17,8 @@ import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<Teacher_congress_institution_user> implements TeacherCongressInstitutionUserService {
|
||||
@Inject
|
||||
@@ -49,21 +51,9 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
||||
dao().insert(institutionUser);
|
||||
|
||||
Teacher_congress_institution institution = dao().fetch(Teacher_congress_institution.class, institutionId);
|
||||
if (institution.getCode().contains("TEACHER_CONGRESS_INSTITUTION_PROPOSAL_COMMITTEE") && identity.equals("主任")) {
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DIRECTOR);
|
||||
int existsRole = dao().count(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getTcSessionId, "=", sessionId)
|
||||
.and(Sys_user_role::getRoleId, "=", sysRole.getId())
|
||||
);
|
||||
if (existsRole == 0) {
|
||||
Sys_user_role insertSysUserRole = new Sys_user_role();
|
||||
insertSysUserRole.setRoleId(sysRole.getId());
|
||||
insertSysUserRole.setUserId(userId);
|
||||
insertSysUserRole.setTcSessionId(sessionId);
|
||||
dao().insert(insertSysUserRole);
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
// 提案审查委员会主任按届次同步提案委员会主任角色,兼容历史届次的旧机构编码。
|
||||
if (isProposalReviewCommittee(institution) && identity.equals("主任")) {
|
||||
grantProposalCommitteeDirectorRole(userId, sessionId);
|
||||
}
|
||||
if (institution.getCode().contains("TEACHER_CONGRESS_INSTITUTION_PROPOSAL_COMMITTEE") && identity.equals("副主任")) {
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DEPUTY_DIRECTOR);
|
||||
@@ -135,15 +125,8 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
||||
Teacher_congress_institution_user institutionUser = fetch(id);
|
||||
String institutionId = institutionUser.getInstitutionId();
|
||||
Teacher_congress_institution institution = dao().fetch(Teacher_congress_institution.class, institutionId);
|
||||
if (institution.getName().contains("提案工作委员会") && institutionUser.getIdentity().equals("主任")) {
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DIRECTOR);
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", institutionUser.getUserId())
|
||||
.and(Sys_user_role::getTcSessionId, "=", institutionUser.getSessionId())
|
||||
.and(Sys_user_role::getRoleId, "=", sysRole.getId())
|
||||
);
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
boolean proposalReviewCommitteeDirector = isProposalReviewCommittee(institution)
|
||||
&& institutionUser.getIdentity().equals("主任");
|
||||
if (institution.getName().contains("提案工作委员会") && institutionUser.getIdentity().equals("副主任")) {
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DEPUTY_DIRECTOR);
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", institutionUser.getUserId())
|
||||
@@ -173,5 +156,78 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
dao().delete(institutionUser);
|
||||
// 删除主任后,仅在同届次不存在其他提案审查委员会主任时撤销系统角色。
|
||||
if (proposalReviewCommitteeDirector) {
|
||||
revokeProposalCommitteeDirectorRoleIfUnused(institutionUser.getUserId(), institutionUser.getSessionId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断机构是否为提案审查委员会。ZXT001 为当前机构配置编码,旧编码用于兼容历史届次。
|
||||
*
|
||||
* @param institution 教代会机构
|
||||
* @return 是否属于提案审查委员会
|
||||
*/
|
||||
private boolean isProposalReviewCommittee(Teacher_congress_institution institution) {
|
||||
if (institution == null) {
|
||||
return false;
|
||||
}
|
||||
return "ZXT001".equals(institution.getCode())
|
||||
|| "TEACHER_CONGRESS_INSTITUTION_PROPOSAL_COMMITTEE".equals(institution.getCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* 为提案审查委员会主任授予当前届次的提案委员会主任角色,已有角色不重复写入。
|
||||
*
|
||||
* @param userId 用户主键
|
||||
* @param sessionId 教代会届次主键
|
||||
*/
|
||||
private void grantProposalCommitteeDirectorRole(String userId, String sessionId) {
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DIRECTOR);
|
||||
if (sysRole == null) {
|
||||
throw new BaseException("提案委员会主任角色不存在");
|
||||
}
|
||||
int existsRole = dao().count(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getTcSessionId, "=", sessionId)
|
||||
.and(Sys_user_role::getRoleId, "=", sysRole.getId())
|
||||
);
|
||||
if (existsRole > 0) {
|
||||
return;
|
||||
}
|
||||
Sys_user_role insertSysUserRole = new Sys_user_role();
|
||||
insertSysUserRole.setRoleId(sysRole.getId());
|
||||
insertSysUserRole.setUserId(userId);
|
||||
insertSysUserRole.setTcSessionId(sessionId);
|
||||
dao().insert(insertSysUserRole);
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当用户在当前届次不再担任任何提案审查委员会主任时,撤销对应系统角色。
|
||||
*
|
||||
* @param userId 用户主键
|
||||
* @param sessionId 教代会届次主键
|
||||
*/
|
||||
private void revokeProposalCommitteeDirectorRoleIfUnused(String userId, String sessionId) {
|
||||
List<Teacher_congress_institution_user> institutionUsers = dao().query(Teacher_congress_institution_user.class,
|
||||
Cnd.where(Teacher_congress_institution_user::getUserId, "=", userId)
|
||||
.and(Teacher_congress_institution_user::getSessionId, "=", sessionId)
|
||||
.and(Teacher_congress_institution_user::getIdentity, "=", "主任"));
|
||||
boolean stillDirector = institutionUsers.stream()
|
||||
.map(institutionUser -> dao().fetch(Teacher_congress_institution.class, institutionUser.getInstitutionId()))
|
||||
.anyMatch(this::isProposalReviewCommittee);
|
||||
if (stillDirector) {
|
||||
return;
|
||||
}
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DIRECTOR);
|
||||
if (sysRole == null) {
|
||||
return;
|
||||
}
|
||||
dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
||||
.and(Sys_user_role::getTcSessionId, "=", sessionId)
|
||||
.and(Sys_user_role::getRoleId, "=", sysRole.getId()));
|
||||
sysRoleService.clearCache();
|
||||
sysUserService.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user