From 6b4a3c0525f2ca9a7542a1f17591e51582200a1e Mon Sep 17 00:00:00 2001 From: zhouhefeng Date: Wed, 22 Jul 2026 13:52:20 +0800 Subject: [PATCH] commit --- .../sys/controller/SysLoginController.java | 130 +++- .../impl/ActivityCultureServiceImpl.java | 2 +- .../transact/ProposalCaseCheckController.java | 12 + .../ProposalCommitteeFilingController.java | 11 + ...ProposalCommitteeFilingUnitController.java | 11 + .../ProposalDelegationController.java | 11 + .../ProposalFeedbackEvaluationController.java | 11 + .../transact/ProposalPreAuditController.java | 12 + ...roposalSchoolLeaderApprovalController.java | 11 + .../ProposalUnderTakeReplyController.java | 11 + .../service/common/ProposalCommonService.java | 14 + .../common/ProposalCommonServiceImpl.java | 295 ++++++++- .../TeacherCongressInstitutionController.java | 78 +-- ...TeacherCongressInstitutionUserService.java | 2 +- ...herCongressInstitutionUserServiceImpl.java | 25 +- .../resources/views/layouts/v4/home/act.js | 25 +- .../resources/views/layouts/v4/home/entry.js | 45 +- .../views/platform/sys/data/tool/index.html | 604 +++++++++++------- .../activity/sports/infoManage/addActivity.js | 9 + .../zhgh/activity/sports/reading/index.html | 8 +- .../proposal/transact/caseCheck/index.html | 11 + .../transact/committeeFiling/index.html | 11 + .../transact/committeeFilingUnit/index.html | 11 + .../proposal/transact/delegation/index.html | 11 + .../proposal/transact/feedback/index.html | 13 +- .../proposal/transact/preAudit/index.html | 11 + .../transact/schoolLeaderApproval/index.html | 13 +- .../proposal/transact/unitReply/index.html | 11 + .../teachercongress/institution/basicTable.js | 201 ++---- .../teachercongress/institution/index.html | 61 +- .../teachercongress/institution/tree.js | 23 +- .../teachercongress/institution/userTable.js | 109 +--- .../member/apply/common/commonQuery.html | 4 +- .../member/change/common/commonQuery.html | 4 +- .../member/change/record/index.html | 4 +- .../member/info/common/commonQuery.html | 4 +- 36 files changed, 1159 insertions(+), 670 deletions(-) diff --git a/src/main/java/com/budwk/app/sys/controller/SysLoginController.java b/src/main/java/com/budwk/app/sys/controller/SysLoginController.java index e78a0a5d..7ad931a5 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysLoginController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysLoginController.java @@ -41,15 +41,11 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Base64; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; @IocBean @@ -58,6 +54,11 @@ import java.util.UUID; @Api(tags = "登录") public class SysLoginController { private static final Log log = Logs.get(); + private static final LoginRsaKeyRing LOGIN_RSA_KEY_RING = new LoginRsaKeyRing(); + /** + * TODO: 临时屏蔽 localhost 平台登录验证码,恢复时改为 false。 + */ + private static final boolean DISABLE_LOGIN_CAPTCHA = true; @Inject private SysUserService sysUserService; @Inject @@ -123,14 +124,20 @@ public class SysLoginController { } try { // 验证码校验 - try { - validateService.checkCode(captchaKey, captchaCode); - } catch (BaseException e) { - return Result.error(e.getMessage()); + if (!isLoginCaptchaDisabled(req)) { + try { + validateService.checkCode(captchaKey, captchaCode); + } catch (BaseException e) { + return Result.error(e.getMessage()); + } } // 解密密码 - String decryptPwd = validateService.decryptPwd(keyId, password); + LoginRsaKey rsaKey = LOGIN_RSA_KEY_RING.getPrivateKey(keyId); + if (rsaKey == null) { + throw new BaseException("Login key expired, please refresh the login page"); + } + String decryptPwd = RsaUtils.decrypt(password, rsaKey.privateKey); if (decryptPwd == null) { throw new BaseException("用户登录失败"); } @@ -153,6 +160,17 @@ public class SysLoginController { } } + private boolean isLoginCaptchaDisabled(HttpServletRequest req) { + if (!DISABLE_LOGIN_CAPTCHA || req == null) { + return false; + } + String serverName = req.getServerName(); + return "localhost".equalsIgnoreCase(serverName) + || "127.0.0.1".equals(serverName) + || "0:0:0:0:0:0:0:1".equals(serverName) + || "::1".equals(serverName); + } + @At(value = "/platform/sso/login", top = true) @Ok("re") @ApiOperation("用户cas登录统一入口") @@ -267,25 +285,89 @@ public class SysLoginController { @ApiOperation("获取公钥") public Object publicKey() { try { - // 生成密钥对 - KeyPair keyPair = RsaUtils.generateKeyPair(); - String publicKeyStr = RsaUtils.getPublicKeyBase64(keyPair.getPublic()); - String privateKeyStr = RsaUtils.getPrivateKeyBase64(keyPair.getPrivate()); - - // 生成 UUID 作为 keyId - String keyId = UUID.randomUUID().toString().replace("-", ""); - - // 私钥存入 Redis,5 分钟过期,也防止恶意刷密钥 - redisService.setex(RedisConstant.RSA_KEY_PREFIX + keyId, 5 * 60, privateKeyStr); - - // 返回给前端 + LoginRsaKey rsaKey = LOGIN_RSA_KEY_RING.currentKey(); return Result.success(Map.of( - "publicKey", publicKeyStr, - "keyId", keyId + "publicKey", rsaKey.publicKey, + "keyId", rsaKey.keyId, + "expireAt", rsaKey.encryptExpireAt )); } catch (Exception e) { log.error("生成 RSA 密钥失败", e); return Result.error("系统异常"); } } + + private static class LoginRsaKeyRing { + private static final long ACTIVE_MILLIS = 30 * 60 * 1000L; + private static final long DECRYPT_GRACE_MILLIS = 10 * 60 * 1000L; + private final ConcurrentHashMap keys = new ConcurrentHashMap<>(); + private volatile LoginRsaKey current; + + LoginRsaKey currentKey() throws Exception { + long now = System.currentTimeMillis(); + LoginRsaKey key = current; + if (key != null && now < key.encryptExpireAt) { + return key; + } + synchronized (this) { + key = current; + now = System.currentTimeMillis(); + if (key == null || now >= key.encryptExpireAt) { + key = generateKey(now); + current = key; + keys.put(key.keyId, key); + cleanup(now); + } + return key; + } + } + + LoginRsaKey getPrivateKey(String keyId) { + if (StrUtil.isBlank(keyId)) { + return null; + } + long now = System.currentTimeMillis(); + LoginRsaKey key = keys.get(keyId); + if (key == null) { + return null; + } + if (now >= key.decryptExpireAt) { + keys.remove(keyId); + return null; + } + return key; + } + + private LoginRsaKey generateKey(long now) throws Exception { + KeyPair keyPair = RsaUtils.generateKeyPair(); + String keyId = UUID.randomUUID().toString().replace("-", ""); + return new LoginRsaKey( + keyId, + RsaUtils.getPublicKeyBase64(keyPair.getPublic()), + keyPair.getPrivate(), + now + ACTIVE_MILLIS, + now + ACTIVE_MILLIS + DECRYPT_GRACE_MILLIS + ); + } + + private void cleanup(long now) { + keys.entrySet().removeIf(entry -> now >= entry.getValue().decryptExpireAt); + } + } + + private static class LoginRsaKey { + private final String keyId; + private final String publicKey; + private final PrivateKey privateKey; + private final long encryptExpireAt; + private final long decryptExpireAt; + + private LoginRsaKey(String keyId, String publicKey, PrivateKey privateKey, long encryptExpireAt, long decryptExpireAt) { + this.keyId = keyId; + this.publicKey = publicKey; + this.privateKey = privateKey; + this.encryptExpireAt = encryptExpireAt; + this.decryptExpireAt = decryptExpireAt; + } + } } diff --git a/src/main/java/com/budwk/app/zhgh/activity/culture/service/impl/ActivityCultureServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/culture/service/impl/ActivityCultureServiceImpl.java index bb26209a..762aebcb 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/culture/service/impl/ActivityCultureServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/activity/culture/service/impl/ActivityCultureServiceImpl.java @@ -64,7 +64,7 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl SELECT gh.id, gh.name unionname, - ( SELECT count( 1 ) FROM `user` WHERE id IN ( $scopeUserSql ) AND unionId = gh.id ) as teacherCount + ( SELECT count( 1 ) FROM `vw_user` WHERE id IN ( $scopeUserSql ) AND unionId = gh.id ) as teacherCount FROM sys_union gh diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java index f96e9315..6cd1af9a 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java @@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; 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.flow.enums.ProcessTaskStateEnum; @@ -21,7 +22,9 @@ 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.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.util.List; @@ -116,6 +119,15 @@ public class ProposalCaseCheckController { return Result.success(pagination); } + @At + @Ok("void") + @SaCheckPermission("proposal.caseCheck") + @ApiOperation("导出列表") + public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval, + @Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) { + proposalCommonService.exportWorkflowList("caseCheck", pageForm, approval, tableColumns, response); + } + @At @SaCheckPermission("proposal.caseCheck") @ApiOperation("查询当前提案承办单位") diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java index 78306070..f3f487a3 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java @@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.lang.Dict; 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.enums.ProcessTaskStateEnum; import com.budwk.app.web.commons.auth.utils.AuthUtil; @@ -28,6 +29,7 @@ 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 @@ -114,6 +116,15 @@ public class ProposalCommitteeFilingController { return Result.success(pagination); } + @At + @Ok("void") + @SaCheckPermission("proposal.committeeFiling") + @ApiOperation("导出列表") + public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval, + @Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) { + proposalCommonService.exportWorkflowList("committeeFiling", pageForm, approval, tableColumns, response); + } + @At @SaCheckPermission("proposal.committeeFiling") @ApiOperation("并案审核") diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java index e2883d49..38d4af98 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java @@ -6,6 +6,7 @@ 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.base.service.BaseService; import com.budwk.app.flow.entity.ProcessInstance; @@ -36,6 +37,7 @@ 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 @@ -127,6 +129,15 @@ public class ProposalCommitteeFilingUnitController { return Result.success(pagination); } + @At + @Ok("void") + @SaCheckPermission("proposal.committeeFilingUnit") + @ApiOperation("导出列表") + public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval, + @Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) { + proposalCommonService.exportWorkflowList("committeeFilingUnit", pageForm, approval, tableColumns, response); + } + @At @SaCheckPermission("proposal.committeeFilingUnit") @ApiOperation("执行任务") diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalDelegationController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalDelegationController.java index 8249ac24..cd024a5a 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalDelegationController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalDelegationController.java @@ -4,6 +4,7 @@ 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; @@ -32,6 +33,7 @@ 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; /** @@ -127,4 +129,13 @@ 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); + } + } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalFeedbackEvaluationController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalFeedbackEvaluationController.java index 537882a7..bef308e3 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalFeedbackEvaluationController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalFeedbackEvaluationController.java @@ -5,6 +5,7 @@ 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; @@ -26,6 +27,7 @@ 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 @@ -116,6 +118,15 @@ 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("获取立案信息") diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java index e3e7fa16..a2381d9d 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java @@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; 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.flow.enums.ProcessTaskStateEnum; @@ -20,7 +21,9 @@ 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.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.util.List; @@ -113,4 +116,13 @@ public class ProposalPreAuditController { Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql); return Result.success(pagination); } + + @At + @Ok("void") + @SaCheckPermission("proposal.preAudit") + @ApiOperation("导出列表") + public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval, + @Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) { + proposalCommonService.exportWorkflowList("preAudit", pageForm, approval, tableColumns, response); + } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java index 4c8625b4..7561186b 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java @@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil; 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.base.vo.LabelValueVO; import com.budwk.app.flow.constant.FlowConst; @@ -38,6 +39,7 @@ import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; import javax.validation.Valid; +import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; @@ -144,6 +146,15 @@ public class ProposalSchoolLeaderApprovalController { return Result.success(pagination); } + @At + @Ok("void") + @SaCheckPermission("proposal.schoolLeaderApproval") + @ApiOperation("导出列表") + public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval, + @Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) { + proposalCommonService.exportWorkflowList("schoolLeaderApproval", pageForm, approval, tableColumns, response); + } + @At @SaCheckPermission("proposal.schoolLeaderApproval") @ApiOperation("获取主办单位") diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java index 53f9cb7c..47e4a5d8 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java @@ -5,6 +5,7 @@ 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; @@ -37,6 +38,7 @@ 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; @@ -170,6 +172,15 @@ 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); + } + /** * 承办单位答复节点撤回需要基于整组当前节点判断。 * 只有“当前流程正在办理的节点”和“这条列表记录所属节点”完全一致时,才允许撤回; diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java index 7d6f645d..207a0ade 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java @@ -2,8 +2,10 @@ package com.budwk.app.zhgh.democratic.proposal.service.common; import com.budwk.app.base.service.BaseService; 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.ProposalSearchParam; import org.nutz.dao.Cnd; import org.nutz.lang.util.NutMap; @@ -137,6 +139,18 @@ public interface ProposalCommonService extends BaseService { */ void exportYearReport(String sessionId, HttpServletResponse response); + /** + * 按办理页面当前筛选条件和可见列导出提案列表。 + * + * @param pageCode 页面代码,用于固定查询范围、数据权限和排序白名单 + * @param pageForm 页面筛选条件 + * @param approval 审核状态筛选条件 + * @param tableColumns 当前页面可见列 + * @param response HTTP 响应 + */ + void exportWorkflowList(String pageCode, ProposalSearchParam pageForm, boolean approval, + ExportTableColumns[] tableColumns, HttpServletResponse response); + /** * 合并提案 diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java index 7487dc25..b19294ff 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java @@ -7,8 +7,13 @@ import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; 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.service.impl.BaseServiceImpl; import com.budwk.app.base.utils.CommonDownloadUtil; @@ -19,6 +24,7 @@ import com.budwk.app.flow.engine.FlowEngine; 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.ProcessInstanceStateEnum; import com.budwk.app.flow.enums.ProcessTaskStateEnum; import com.budwk.app.flow.vo.ProcessTaskVO; import com.budwk.app.sys.models.Sys_dict; @@ -28,11 +34,13 @@ import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.sys.services.SysDictService; import com.budwk.app.sys.services.SysRoleService; import com.budwk.app.sys.services.SysUserService; +import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.base.Globals; import com.budwk.app.zhgh.democratic.proposal.constants.ProposalState; import com.budwk.app.zhgh.democratic.proposal.models.*; import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService; import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate; import com.budwk.app.zhgh.democratic.teachercongress.delegate.service.TeacherCongressDelegateService; @@ -55,6 +63,7 @@ import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.Strings; import org.nutz.lang.util.NutMap; +import org.apache.poi.ss.usermodel.Workbook; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; @@ -73,6 +82,9 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp /** PC端提案列表页面的排序字段白名单,页面代码由对应Controller固定传入。 */ private static final Map> PROPOSAL_LIST_ORDER_COLUMNS = createProposalListOrderColumns(); + /** 办理页面允许导出的列表字段,避免请求参数携带非页面字段。 */ + private static final Map> WORKFLOW_EXPORT_COLUMNS = createWorkflowExportColumns(); + //找出富文本里面上传的图片 static String IMG_SRC_REGEX = "]*src\\s*=\\s*([\"'])(/platform/sys/file/download\\?id=.*?)\\1[^>]*>"; @@ -204,6 +216,219 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp return Collections.unmodifiableMap(columns); } + /** + * 按办理页面当前筛选条件和可见列导出列表,查询范围与页面分页列表保持一致。 + * + * @param pageCode 页面代码 + * @param pageForm 页面筛选条件 + * @param approval 审核状态 + * @param tableColumns 页面可见列 + * @param response HTTP 响应 + */ + @Override + public void exportWorkflowList(String pageCode, ProposalSearchParam pageForm, boolean approval, + ExportTableColumns[] tableColumns, HttpServletResponse response) { + List exportColumns = getWorkflowExportColumns(pageCode, tableColumns); + if (exportColumns.isEmpty()) { + throw Lang.makeThrow("请选择至少一个列表字段后再导出"); + } + + Sql sql = buildWorkflowExportSql(pageCode, pageForm, approval); + List rows = listMap(sql); + convertWorkflowExportValues(rows, pageCode); + + List excelColumns = new ArrayList<>(); + for (ExportTableColumns column : exportColumns) { + excelColumns.add(new ExcelExportEntity(column.getLabel(), column.getProp(), 20)); + } + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + exportParams.setTitle("提案列表"); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelColumns, rows); + CommonDownloadUtil.download("提案列表.xlsx", workbook, response); + } + + /** 根据页面代码构造导出查询,保证数据权限、筛选条件及排序规则与列表页一致。 */ + private Sql buildWorkflowExportSql(String pageCode, ProposalSearchParam pageForm, boolean approval) { + boolean isUnitReply = "unitReply".equals(pageCode); + boolean isSchoolLeaderApproval = "schoolLeaderApproval".equals(pageCode); + boolean requiresUnionFilter = Set.of("preAudit", "committeeFiling", "committeeFilingUnit", + "schoolLeaderApproval", "caseCheck").contains(pageCode); + String taskName = getWorkflowTaskName(pageCode); + + String schoolLeaderColumns = isSchoolLeaderApproval ? """ + 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, + """ : ""; + String auditUserColumn = (isSchoolLeaderApproval || isUnitReply) + ? "GROUP_CONCAT(DISTINCT ta.actorName, '(', ta.actorAccount, ')') AS auditUser," + : ""; + String unitReplyColumns = isUnitReply ? """ + COALESCE(NULLIF(t.variable->>'$.underTakeName', ''), replyUnit.unitName) AS underTakeName, + CASE + WHEN JSON_EXTRACT(t.variable, '$.underTakeIsMaster') IS NOT NULL + THEN IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') = true, 1, 0) + ELSE IFNULL(replyUnit.isMaster, 0) + END AS underTakeIsMaster, + """ : ""; + String unionJoin = requiresUnionFilter ? "LEFT JOIN vw_user vu ON vu.id = info.createUserId" : ""; + String schoolLeaderJoin = isSchoolLeaderApproval ? "LEFT JOIN proposal_reply_unit pru ON pru.proposalId = info.id" : ""; + String unitReplyJoin = isUnitReply + ? "LEFT JOIN proposal_reply_unit replyUnit ON replyUnit.proposalId = info.id AND replyUnit.unitId = ta.actorUnitId\n LEFT JOIN sys_user transferUser ON transferUser.id = t.variable->>'$.tf_transferUserId'" + : ""; + + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + IF(mer.proposalId IS NOT NULL, 1, 0) AS merge, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.state AS instanceState, + t.finishTime, + %s + %s + %s + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName), '结束') AS curTaskName + FROM wf_process_task t + 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 + 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 + %s + %s + %s + $condition + """.formatted(schoolLeaderColumns, auditUserColumn, unitReplyColumns, unionJoin, schoolLeaderJoin, unitReplyJoin)); + + Cnd cnd = Cnd.NEW(); + if (isUnitReply) { + cnd.and("t.taskName", "in", List.of("unit_reply", "two_unit_reply", "opinion_unit_reply")); + if (!"superadmin".equals(SecurityUtil.getUserLoginname())) { + cnd.and("ta.actorId", "=", SecurityUtil.getUserId()); + } + } else { + cnd.and("t.taskName", "=", taskName); + if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + } + } + if (approval) { + cnd.and("t.taskState", "in", isUnitReply + ? List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.TRANSFER.getCode()) + : List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } + if (requiresUnionFilter) { + cnd.andEX("vu.unionId", "=", pageForm.getUnionId()); + } + ProposalSearchParam.buildSearch(cnd, pageForm); + cnd.groupBy("t.id"); + if (!applySafeProposalListOrder(cnd, pageForm, pageCode)) { + cnd.desc("t.createdAt"); + } + sql.setCondition(cnd); + return sql; + } + + /** 获取页面对应的流程任务编码,页面代码不匹配时拒绝导出。 */ + private String getWorkflowTaskName(String pageCode) { + Map taskNames = Map.of( + "delegation", "delegation", + "preAudit", "preAudit", + "committeeFiling", "committee", + "committeeFilingUnit", "committeeFilingUnit", + "schoolLeaderApproval", "schoolLeader", + "feedbackEvaluation", "feedback", + "caseCheck", "caseCheck" + ); + String taskName = taskNames.get(pageCode); + if (StrUtil.isBlank(taskName) && !"unitReply".equals(pageCode)) { + throw Lang.makeThrow("不支持的提案列表导出页面"); + } + return taskName; + } + + /** 将字典、枚举及组合字段转换为与列表页面相同的显示文本。 */ + private void convertWorkflowExportValues(List rows, String pageCode) { + Map caseFilingResultMap = sysDictService.getSubListByCode("PROPOSAL_CASE_FILING_RESULT") + .stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName)); + Map processStateMap = Arrays.stream(ProcessInstanceStateEnum.values()) + .collect(Collectors.toMap(ProcessInstanceStateEnum::getCode, ProcessInstanceStateEnum::getMessage)); + for (NutMap row : rows) { + if ("schoolLeaderApproval".equals(pageCode)) { + row.put("undertakeUnits", formatUndertakeUnits(row)); + } + // 所有含“是否并案”列的办理页面统一导出“是/否”,避免未并案记录出现空白。 + row.put("merge", row.getInt("merge") == 1 ? "是" : "否"); + if ("unitReply".equals(pageCode)) { + row.put("underTakeIsMaster", row.getInt("underTakeIsMaster") == 1 ? "主办" : "协办"); + } + row.put("caseFilingResult", caseFilingResultMap.getOrDefault(row.getString("caseFilingResult"), row.getString("caseFilingResult"))); + Integer instanceState = row.getInt("instanceState"); + row.put("instanceState", processStateMap.getOrDefault(instanceState, row.getString("instanceState"))); + } + } + + /** 校领导审批页按页面展示规则拼接承办单位。 */ + private String formatUndertakeUnits(NutMap row) { + String masterUnitNames = StrUtil.nullToEmpty(row.getString("masterUnitName")); + String slaveUnitNames = StrUtil.nullToEmpty(row.getString("slaveUnitNames")); + if ("SUGGESTION".equals(row.getString("caseFilingResult"))) { + return StrUtil.isNotBlank(masterUnitNames) ? masterUnitNames : slaveUnitNames; + } + if ("CONFIRM_FILING".equals(row.getString("caseFilingResult"))) { + List unitNames = new ArrayList<>(); + if (StrUtil.isNotBlank(masterUnitNames)) { + unitNames.add("主办:" + masterUnitNames); + } + if (StrUtil.isNotBlank(slaveUnitNames)) { + unitNames.add("协办:" + slaveUnitNames); + } + return StrUtil.join(";", unitNames); + } + return ""; + } + + /** 根据页面列定义过滤导出字段,确保导出范围只包含列表可展示字段。 */ + private List getWorkflowExportColumns(String pageCode, ExportTableColumns[] tableColumns) { + Set allowedColumns = WORKFLOW_EXPORT_COLUMNS.get(pageCode); + if (allowedColumns == null || tableColumns == null) { + return List.of(); + } + return Arrays.stream(tableColumns) + .filter(Objects::nonNull) + .filter(column -> StrUtil.isNotBlank(column.getLabel()) && allowedColumns.contains(column.getProp())) + .collect(Collectors.toList()); + } + + /** 初始化各办理页面可导出的列表字段白名单。 */ + private static Map> createWorkflowExportColumns() { + Set commonColumns = Set.of("code", "caseFilingCode", "name", "createUserName", "typeName", + "sessionName", "delegationName", "curTaskName", "instanceState"); + Map> columns = new HashMap<>(); + columns.put("delegation", commonColumns); + columns.put("preAudit", commonColumns); + columns.put("caseCheck", Set.of("code", "caseFilingCode", "name", "createUserName", "typeName", + "sessionName", "delegationName", "curTaskName", "instanceState", "finishTime")); + columns.put("committeeFiling", Set.of("code", "caseFilingCode", "name", "typeName", "sessionName", + "caseFilingResult", "delegationName", "curTaskName", "instanceState")); + columns.put("committeeFilingUnit", Set.of("code", "caseFilingCode", "name", "typeName", "sessionName", + "caseFilingResult", "delegationName", "curTaskName", "instanceState")); + columns.put("schoolLeaderApproval", Set.of("code", "caseFilingCode", "name", "typeName", "undertakeUnits", + "merge", "curTaskName", "auditUser", "instanceState")); + columns.put("unitReply", Set.of("code", "caseFilingCode", "name", "typeName", "caseFilingResult", + "merge", "underTakeName", "underTakeIsMaster", "curTaskName", "auditUser", "instanceState")); + columns.put("feedbackEvaluation", Set.of("code", "caseFilingCode", "name", "typeName", "merge", + "curTaskName", "instanceState")); + return Collections.unmodifiableMap(columns); + } + /** * 按白名单字段对统计结果执行后端排序,数字按数值比较,文本按中文区域规则比较。 * @@ -407,8 +632,11 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp } // 按任务节点分组 - Map> taskGroups = doneTaskVos.stream().collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName)); + Map> taskGroups = doneTaskVos.stream() + .filter(Objects::nonNull) + .collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName)); docData.putAll(taskGroups); + putProposalExportTaskAliases(id, taskGroups, docData); // 提案附议 List secondInfos = new ArrayList<>(); @@ -479,22 +707,79 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp Configure config = Configure.builder() .bind("secondedList", policy) .bind("seconders", policy) + .bind("提案附议", policy) + .bind("提案委委员审议", policy) .bind("brief", htmlRenderPolicy) .bind("measures", htmlRenderPolicy) .bind("taskFormData.tf_opinion", htmlRenderPolicy) .build(); - Map renderDocCellDataMap = MapUtil.of("proposal", docCellDataMap); - renderDocCellDataMap.put("secondedList", secondInfos); - renderDocCellDataMap.put("delegationAuditList", delegationAuditList); + // 数据库模板使用平铺占位符(例如 {{code}}、{{sessionName}}),不能将基础字段嵌套到 proposal 节点。 + // 流程节点分组已写入 docData,附议人与代表团审核列表也必须写入同一上下文,才能被模板的循环标签识别。 + docData.put("secondedList", secondInfos); + docData.put("delegationAuditList", delegationAuditList); try { - XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("proposal"), config).render(renderDocCellDataMap).writeAndClose(byteArrayOutputStream); + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("proposal"), config).render(docData).writeAndClose(byteArrayOutputStream); } catch (IOException e) { log.error("提案导出失败{},提案id:{}", e.getMessage(), id); } } + /** + * 将现行工作流节点映射到历史提案表模板使用的区块名称,并按主协办单位拆分办理答复。 + * 模板仍使用旧节点名称时,避免已完成的意见和答复因键名不一致而无法渲染。 + * + * @param proposalId 提案ID,用于查询主办单位 + * @param taskGroups 已完成任务按显示名称分组后的数据 + * @param docData Word 模板的平铺渲染数据 + */ + private void putProposalExportTaskAliases(String proposalId, Map> taskGroups, + NutMap docData) { + putTaskAlias(docData, "提案委主任审核", taskGroups.get("校工会预审核")); + putTaskAlias(docData, "提案委主任意见", taskGroups.get("提案委员会立案")); + putTaskAlias(docData, "提案委委员审议", taskGroups.get("委员会确认承办单位")); + + List replyTasks = taskGroups.get("承办单位答复"); + if (Lang.isEmpty(replyTasks)) { + return; + } + Sql masterUnitSql = Sqls.create("SELECT unitName FROM proposal_reply_unit WHERE proposalId = @proposalId AND isMaster = 1") + .setParam("proposalId", proposalId); + List masterUnitRows = listMap(masterUnitSql); + Set masterUnitNames = masterUnitRows.stream() + .map(row -> row.getString("unitName")) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + List masterReplyTasks = new ArrayList<>(); + List slaveReplyTasks = new ArrayList<>(); + for (ProcessTaskVO replyTask : replyTasks) { + Dict taskFormData = replyTask.getTaskFormData(); + String unitName = taskFormData == null ? null : taskFormData.getStr("unitName"); + if (masterUnitNames.contains(unitName)) { + masterReplyTasks.add(replyTask); + } else { + slaveReplyTasks.add(replyTask); + } + } + putTaskAlias(docData, "主办单位答复", masterReplyTasks); + putTaskAlias(docData, "协办单位答复", slaveReplyTasks); + } + + /** + * 仅在存在已完成任务时写入模板区块,空任务不触发 Word 条件标签。 + * + * @param docData Word 模板的平铺渲染数据 + * @param templateKey Word 模板中的条件或循环标签名称 + * @param tasks 对应的已完成流程任务 + */ + private void putTaskAlias(NutMap docData, String templateKey, List tasks) { + if (Lang.isNotEmpty(tasks)) { + docData.put(templateKey, tasks); + } + } + @Override public void exportProposalFeedBackAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) { if (id == null || id.isEmpty()) { diff --git a/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/controller/TeacherCongressInstitutionController.java b/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/controller/TeacherCongressInstitutionController.java index bddf399e..2dcb71d7 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/controller/TeacherCongressInstitutionController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/controller/TeacherCongressInstitutionController.java @@ -25,7 +25,6 @@ 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; -import org.nutz.lang.Strings; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; @@ -69,32 +68,25 @@ public class TeacherCongressInstitutionController { Teacher_congress_institution rootInstitution = new Teacher_congress_institution(); rootInstitution.setId("0"); rootInstitution.setParentId(""); - rootInstitution.setName("两代会组织机构"); + rootInstitution.setName("教代会机构"); rootInstitution.setLocation(0); institutionList.add(rootInstitution); - List> treeNodes = institutionList.stream().map(institution -> { - TreeNode treeNode = new TreeNode<>(institution.getId(), institution.getParentId(), institution.getName(), institution.getLocation()); - treeNode.setExtra(Map.of("code", Strings.sNull(institution.getCode()))); - return treeNode; - }).toList(); + List> treeNodes = institutionList.stream().map(institution -> new TreeNode<>(institution.getId(), institution.getParentId(), institution.getName(), institution.getLocation())).toList(); List> treeList = TreeUtil.build(treeNodes, ""); return Result.success(treeList); } /** - * 获取新增机构表单使用的固定机构字典树。 + * 表单中的树结构 * - * @param sessionId 当前教代会届次ID,用于保持接口参数与机构管理页面上下文一致 - * @return Result,data.treeList 为级联组件树结构,data.treeFlat 为名称和代码回填使用的扁平字典列表 + * @param sessionId + * @return */ @At @SaCheckPermission("tc.institution") public Result formTree(@Valid String sessionId) { Sys_dict institutionFixedDict = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", "TEACHER_CONGRESS_INSTITUTION_FIXED")); - if (ObjectUtil.isEmpty(institutionFixedDict)) { - return Result.error("未配置双代会固定机构字典"); - } List children = sysDictService.query(Cnd.where(Sys_dict::getPath, "like", institutionFixedDict.getPath() + "%")); List> treeNodes = children.stream().map(sysDict -> { TreeNode treeNode = new TreeNode<>(sysDict.getId(), sysDict.getParentId(), sysDict.getName(), sysDict.getLocation()); @@ -105,16 +97,6 @@ public class TeacherCongressInstitutionController { return Result.success(Map.of("treeFlat", children, "treeList", treeList)); } - @At - @SaCheckPermission("tc.institution") - public Result specialCommitteeRoleOptions() { - Sys_dict parent = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", "SPECIAL_COMMITTEE_ROLES")); - if (ObjectUtil.isEmpty(parent)) { - return Result.success(List.of()); - } - List children = sysDictService.query(Cnd.where(Sys_dict::getPath, "like", parent.getPath() + "%").and(Sys_dict::getId, "!=", parent.getId()).asc(Sys_dict::getLocation)); - return Result.success(children); - } /** * 机构分页查询 @@ -131,30 +113,24 @@ public class TeacherCongressInstitutionController { cnd.and("parentId", "=", parentId); cnd.and("sessionId", "=", sessionId); cnd.asc("location"); - cnd.asc("code"); Pagination pagination = baseService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), "teacher_congress_institution", cnd); return Result.success(pagination); } /** - * 添加当前届次的机构。 + * 添加机构 * - * @param institution 机构数据,包含 sessionId、name、code、parentId、location 和 introduce;parentId 可能是固定字典ID - * @return Result,机构重复或父级不存在时返回错误,否则返回成功 + * @param institution + * @return */ @At @SaCheckPermission("tc.institution") - @Aop(TransAop.READ_COMMITTED) public Result insert(Teacher_congress_institution institution) { if (dao.count(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getCode, "=", institution.getCode()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())) > 0) { return Result.error("机构已存在"); } - if (StrUtil.isNotBlank(institution.getParentId()) && !institution.getParentId().equals("0") && dao.count(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getId, "=", institution.getParentId()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())) == 0) { - // 级联框提交的是固定字典父级ID,需要按机构代码匹配当前届次的实际父机构。 + if (StrUtil.isNotBlank(institution.getParentId()) && !institution.getParentId().equals("0")) { Sys_dict sysDict = sysDictService.fetch(Cnd.where(Sys_dict::getId, "=", institution.getParentId())); - if (ObjectUtil.isEmpty(sysDict)) { - return Result.error("父级机构不存在"); - } Teacher_congress_institution parentInstitution = dao.fetch(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getCode, "=", sysDict.getCode()) .and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId()) @@ -170,40 +146,15 @@ public class TeacherCongressInstitutionController { } /** - * 更新机构名称、描述和排序。 + * 删除机构 * - * @param institution 机构数据,id 标识待更新机构,name、introduce、location 为可更新内容 - * @return Result,机构不存在时返回错误,否则返回成功 + * @param id + * @return */ - @At - @SaCheckPermission("tc.institution") - @Aop(TransAop.READ_COMMITTED) - public Result update(Teacher_congress_institution institution) { - Teacher_congress_institution dbInstitution = dao.fetch(Teacher_congress_institution.class, institution.getId()); - if (ObjectUtil.isEmpty(dbInstitution)) { - return Result.error("机构不存在"); - } - dbInstitution.setName(institution.getName()); - dbInstitution.setIntroduce(institution.getIntroduce()); - dbInstitution.setLocation(institution.getLocation()); - dao.update(dbInstitution); - return Result.success(); - } - @At @SaCheckPermission("tc.institution") @Aop(TransAop.READ_COMMITTED) public Result delete(@Valid String id) { - Teacher_congress_institution institution = dao.fetch(Teacher_congress_institution.class, id); - if (ObjectUtil.isEmpty(institution)) { - return Result.error("机构不存在"); - } - List siblingList = dao.query(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getParentId, "=", institution.getParentId()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId()).asc(Teacher_congress_institution::getLocation).asc(Teacher_congress_institution::getCode)); - for (int i = 0; i < siblingList.size() && i < 6; i++) { - if (id.equals(siblingList.get(i).getId())) { - return Result.error("你选择的组织机构是两代会基本机构,不允许删除。"); - } - } dao.delete(Teacher_congress_institution.class, id); dao.clear(Teacher_congress_institution_user.class, Cnd.where("institutionId", "=", id)); return Result.success(); @@ -263,8 +214,8 @@ public class TeacherCongressInstitutionController { @SaCheckPermission("tc.institution") @SLog(tag = "教代会-机构设置", msg = "添加人员") @Aop(TransAop.READ_COMMITTED) - public Result userInsert(@Valid String userId, @Valid String institutionId, @Valid String sessionId, @Valid String identity, String roleCode) { - teacherCongressInstitutionUserService.userInsert(userId, institutionId, sessionId, identity, roleCode); + public Result userInsert(@Valid String userId, @Valid String institutionId, @Valid String sessionId, @Valid String identity) { + teacherCongressInstitutionUserService.userInsert(userId, institutionId, sessionId, identity); return Result.success(); } @@ -276,7 +227,6 @@ public class TeacherCongressInstitutionController { */ @At @SaCheckPermission("tc.institution") - @Aop(TransAop.READ_COMMITTED) public Result userDelete(@Valid String id) { teacherCongressInstitutionUserService.userDelete(id); return Result.success(); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/service/TeacherCongressInstitutionUserService.java b/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/service/TeacherCongressInstitutionUserService.java index 83472c4b..302aa97f 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/service/TeacherCongressInstitutionUserService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/service/TeacherCongressInstitutionUserService.java @@ -14,7 +14,7 @@ public interface TeacherCongressInstitutionUserService extends BaseService
- + +
{{ item.name }}
@@ -167,7 +168,7 @@ const entry = { .app-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); justify-items: center; justify-content: start; gap: 12px 18px; @@ -185,13 +186,17 @@ const entry = { display: flex; flex-direction: column; align-items: center; + justify-content: flex-start; border-radius: 8px; background: #fff; width: 100%; - max-width: 100%; + max-width: 108px; + min-width: 0; + box-sizing: border-box; padding: 6px; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; + overflow: hidden; } .app-item:hover { @@ -200,24 +205,46 @@ const entry = { } .app-icon { - width: 46px; - height: 46px; + width: 56px; + height: 56px; margin-bottom: 8px; + display: flex; + align-items: center; + justify-content: center; + flex: 0 0 56px; + overflow: hidden; + border-radius: 8px; + background: #f5f8ff; } - .app-icon img { - width: 100%; - height: 100%; - object-fit: contain; + .app-icon img, + .app-icon-img { + display: block; + width: 56px !important; + height: 56px !important; + max-width: 56px !important; + max-height: 56px !important; + object-fit: contain !important; + border-radius: 8px; + } + + .app-icon-fallback { + color: #409eff; + font-size: 24px; } .app-name { min-height: 34px; + width: 100%; font-size: 12px; color: #333; line-height: 1.4; word-break: break-word; text-align: center; + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; } .app-empty { diff --git a/src/main/resources/views/platform/sys/data/tool/index.html b/src/main/resources/views/platform/sys/data/tool/index.html index c632e51b..b7ec0121 100644 --- a/src/main/resources/views/platform/sys/data/tool/index.html +++ b/src/main/resources/views/platform/sys/data/tool/index.html @@ -4,225 +4,268 @@ layout("/layouts/platform.html"){
- -
- 高级工具 + +
+ DataKid
-
-
- - - - - - +
+
+ + + + + + -
-
-
- - - 搜索 - 当前选择:{{ formData.tableName }} -
- - -
- {{ item.table_name }} - ({{ item.table_comment }}) + + + +
+ + + + + 当前选中:{{ formData.tableName }} + +
+ + + + {{ item.table_name }}{{ item.table_comment ? " ( " + item.table_comment + " )" : "" }} rows: {{ item.table_rows || 0 }} -
-
-
-
+ + + + -
-
- - - 搜索 - {{ formData.tableName }} -
- - -
- {{ item.column_name }} - ({{ item.column_comment }}) + + +
+ + + + + {{ formData.tableName }} + +
+ + + + {{ item.column_name }}{{ item.column_comment ? " ( " + item.column_comment + " )" : "" }} {{ item.column_type }} -
-
-
-
+ + + + -
- - - - - - - - - - - -
+ + + + + + + + + + + + + + + -
-
- - + + + + + + 追加或更新 仅追加 @@ -230,13 +273,8 @@ layout("/layouts/platform.html"){ - - + + - + - +
将文件拖到此处,或点击上传
-
仅支持 `xls`、`xlsx` 文件
+
只能上传 xls/xlsx 文件
-
-
+ + -
-
- -
- 共 {{ result.total || 0 }} 条,成功 {{ result.success || 0 }} 条 + + + +
{{ resultSummary }}
+
+ + 下载错误记录 +
-
- 下载错误记录 -
-
-
-
+ + + -
@@ -316,11 +359,16 @@ layout("/layouts/platform.html"){ relation: [], plugins: [], fileList: [], + cacheTableName: "", result: { total: 0, success: 0, cacheKey: "" }, + formRules: { + method: [{ required: true, message: "必填", trigger: ["blur", "change"] }], + field: [{ required: true, message: "必填", trigger: ["blur", "change"] }] + }, formData: { tableName: "", columns: [], @@ -331,6 +379,29 @@ layout("/layouts/platform.html"){ } }, computed: { + primaryButtonText() { + if (this.active === 3 && this.formData.method === 3) { + return "更新" + } + return "下一步" + }, + resultSummary() { + const total = this.result.total || 0 + const success = this.result.success || 0 + const fail = Math.max(total - success, 0) + if (fail > 0) { + return "总记录数 " + total + " 条,成功 " + success + " 条,失败 " + fail + " 条!" + } + return "总记录数 " + total + " 条,成功 " + success + " 条!" + }, + resultProgressStatus() { + const total = this.result.total || 0 + const success = this.result.success || 0 + if (total > 0 && success < total) { + return "exception" + } + return "success" + }, resultPercentage() { if (!this.result.total) { return 0 @@ -339,6 +410,7 @@ layout("/layouts/platform.html"){ } }, methods: { + loc, normalizeRecord(item) { const normalized = {} Object.keys(item || {}).forEach(key => { @@ -398,66 +470,75 @@ layout("/layouts/platform.html"){ .filter(item => this.formData.columns.includes(item.column_name)) .map(item => Object.assign({}, item, { relation: "" })) }, - async nextStep() { + async next() { if (this.active === 0) { if (!this.formData.tableName) { - this.$message.warning("请选择数据表") + this.$notify({ + title: "警告", + message: "请选择数据表", + type: "warning" + }) return } - await this.loadColumns() - this.formData.columns = [] - this.formData.field = "" + if (this.cacheTableName !== this.formData.tableName) { + await this.loadColumns() + this.formData.columns = [] + this.formData.field = "" + this.cacheTableName = this.formData.tableName + } } else if (this.active === 1) { if (!this.formData.columns.length) { - this.$message.warning("请至少选择一个字段") + this.$notify({ + title: "警告", + message: "请选择数据列", + type: "warning" + }) return } this.buildRelation() } else if (this.active === 2) { - const hasEmptyRelation = this.relation.some(item => !item.relation) - if (hasEmptyRelation) { - this.$message.warning("请填写所有 Excel 表头对应关系") + if (this.relation.find(item => !item.relation)) { + this.$notify({ + title: "警告", + message: "存在未填写的目标列", + type: "warning" + }) return } } else if (this.active === 3) { - const success = await this.submitImport() + const success = await this.doSubmit() if (!success) { return } } - this.active += 1 + + this.$refs.carousel.next() + this.active++ }, - prevStep() { - if (this.active > 0) { - this.active -= 1 + prev() { + if (this.active <= 0) { + return } + this.$refs.carousel.prev() + this.active-- }, - handleFileRemove(file, fileList) { - this.fileList = fileList - }, - handleFileChange(file, fileList) { - const extension = ((file.name || "").split(".").pop() || "").toLowerCase() - const removeIndex = fileList.findIndex(item => item.uid === file.uid) - if (!["xls", "xlsx"].includes(extension)) { - this.$message.warning("仅支持 xls、xlsx 文件") - if (removeIndex > -1) { - fileList.splice(removeIndex, 1) - } - } else if (file.size === 0) { - this.$message.warning("上传文件不能为空") - if (removeIndex > -1) { - fileList.splice(removeIndex, 1) - } - } - this.fileList = fileList - }, - async submitImport() { - if ([1, 3].includes(this.formData.method) && !this.formData.field) { - this.$message.warning("请选择关键字段") + validateSubmitForm() { + let validForm = true + this.$refs.form.validate(valid => { + validForm = valid + }) + if (!validForm || !this.fileList.length) { + this.$notify({ + title: "警告", + message: "存在未填写的必填项", + type: "warning" + }) return false } - if (!this.fileList.length) { - this.$message.warning("请上传 Excel 文件") + return true + }, + async doSubmit() { + if (!this.validateSubmitForm()) { return false } @@ -476,18 +557,45 @@ layout("/layouts/platform.html"){ "Content-Type": "multipart/form-data" } }) + if (resp.code !== 0) { - this.$message.error(resp.msg) + this.$notify.error({ + title: "错误", + message: resp.msg + }) + this.result = { total: 0, success: 0, cacheKey: "" } return false } + this.result = resp.data || { total: 0, success: 0, cacheKey: "" } - this.$message.success(resp.msg) return true } finally { this.loading = false } }, - restart() { + handleFileRemove(file, fileList) { + this.fileList = fileList + }, + handleFileChange(file, fileList) { + const extension = ((file.name || "").split(".").pop() || "").toLowerCase() + const remove = () => { + const removeIndex = fileList.findIndex(item => item.uid === file.uid) + if (removeIndex > -1) { + fileList.splice(removeIndex, 1) + } + } + + if (file.size === 0) { + this.$message.warning("您选择的是空文件") + remove() + } else if (!["xls", "xlsx"].includes(extension)) { + this.$message.warning("上传文件只能是 xls/xlsx 格式") + remove() + } + + this.fileList = fileList + }, + carry() { this.active = 0 this.tableKeyword = "" this.columnKeyword = "" @@ -495,6 +603,7 @@ layout("/layouts/platform.html"){ this.filteredColumns = [] this.relation = [] this.fileList = [] + this.cacheTableName = "" this.result = { total: 0, success: 0, @@ -511,6 +620,7 @@ layout("/layouts/platform.html"){ this.$refs.upload.clearFiles() } this.filterTables() + this.$refs.carousel.setActiveItem(0) } }, async created() { diff --git a/src/main/resources/views/platform/zhgh/activity/sports/infoManage/addActivity.js b/src/main/resources/views/platform/zhgh/activity/sports/infoManage/addActivity.js index 8c0097c1..eb3f9027 100644 --- a/src/main/resources/views/platform/zhgh/activity/sports/infoManage/addActivity.js +++ b/src/main/resources/views/platform/zhgh/activity/sports/infoManage/addActivity.js @@ -161,6 +161,12 @@ + + + + + + @@ -208,6 +209,7 @@ layout("/layouts/platform.html"){ return { tableColumns: [ {label: "提案编号", prop: "code"}, + {label: "立案编号", prop: "caseFilingCode"}, {label: "提案名称", prop: "name", width: "200px"}, {label: "提案类别", prop: "typeName"}, {label: "届次", prop: "sessionName"}, @@ -231,6 +233,15 @@ layout("/layouts/platform.html"){ } }, methods: { + exportList() { + this.$downLoad(loc() + "/exportList", { + pageForm: JSON.stringify(this.pageForm), + approval: this.pageForm.approval, + tableColumns: JSON.stringify(this.tableColumns.filter(function (item) { + return item.visible !== false + })) + }) + }, /** * “作为建议”场景下只保留办理单位,协办单位和立案类型都要及时清空, * 避免旧表单值跟着一起提交到流程里。 diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html index 580fe080..04d3bd1d 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html @@ -25,6 +25,7 @@ layout("/layouts/platform.html"){ + 导出 已审核 未审核 @@ -107,6 +108,7 @@ layout("/layouts/platform.html"){ return { tableColumns: [ {label: "提案编号", prop: "code"}, + {label: "立案编号", prop: "caseFilingCode"}, {label: "提案名称", prop: "name", width: "200px"}, {label: "提案人", prop: "createUserName", width: "80px"}, {label: "提案类别", prop: "typeName"}, @@ -122,6 +124,15 @@ layout("/layouts/platform.html"){ } }, methods: { + exportList() { + this.$downLoad(loc() + "/exportList", { + pageForm: JSON.stringify(this.pageForm), + approval: this.pageForm.approval, + tableColumns: JSON.stringify(this.tableColumns.filter(function (item) { + return item.visible !== false + })) + }) + }, openView(row) { this.$refs.guava.edit(() => { this.showApprovalForm = false diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/feedback/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/feedback/index.html index dbcbff21..f72b54e6 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/feedback/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/feedback/index.html @@ -25,7 +25,8 @@ layout("/layouts/platform.html"){ - + + 导出 已审核 未审核 @@ -119,6 +120,7 @@ layout("/layouts/platform.html"){ return { tableColumns: [ {label: "提案编号", prop: "code"}, + {label: "立案编号", prop: "caseFilingCode"}, {label: "提案名称", prop: "name", width: "200px"}, {label: "提案类别", prop: "typeName"}, {label: "是否并案", prop: "merge"}, @@ -135,6 +137,15 @@ layout("/layouts/platform.html"){ } }, methods: { + exportList() { + this.$downLoad(loc() + "/exportList", { + pageForm: JSON.stringify(this.pageForm), + approval: this.pageForm.approval, + tableColumns: JSON.stringify(this.tableColumns.filter(function (item) { + return item.visible !== false + })) + }) + }, openView(row) { this.$refs.guava.edit(() => { this.showApprovalForm = false diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html index dddbadb6..11b1c3f6 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html @@ -36,6 +36,7 @@ layout("/layouts/platform.html"){ + 导出 已审核 未审核 @@ -111,6 +112,7 @@ layout("/layouts/platform.html"){ return { tableColumns: [ {label: "提案编号", prop: "code"}, + {label: "立案编号", prop: "caseFilingCode"}, {label: "提案名称", prop: "name", width: "200px"}, {label: "提案人", prop: "createUserName", width: "80px"}, {label: "提案类别", prop: "typeName"}, @@ -134,6 +136,15 @@ layout("/layouts/platform.html"){ this.listUnion() }, methods: { + exportList() { + this.$downLoad(loc() + "/exportList", { + pageForm: JSON.stringify(this.pageForm), + approval: this.pageForm.approval, + tableColumns: JSON.stringify(this.tableColumns.filter(function (item) { + return item.visible !== false + })) + }) + }, openView(row) { this.$refs.guava.edit(() => { this.showApprovalForm = false diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html index 195c9407..85cbd8e2 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html @@ -58,7 +58,8 @@ layout("/layouts/platform.html"){ - + + 导出 已审核 未审核 @@ -145,6 +146,7 @@ layout("/layouts/platform.html"){ return { tableColumns: [ {label: "提案编号", prop: "code"}, + {label: "立案编号", prop: "caseFilingCode"}, {label: "提案名称", prop: "name", width: "200px"}, {label: "提案类别", prop: "typeName"}, {label: "办理单位", prop: "undertakeUnits", width: "260px"}, @@ -164,6 +166,15 @@ layout("/layouts/platform.html"){ } }, methods: { + exportList() { + this.$downLoad(loc() + "/exportList", { + pageForm: JSON.stringify(this.pageForm), + approval: this.pageForm.approval, + tableColumns: JSON.stringify(this.tableColumns.filter(function (item) { + return item.visible !== false + })) + }) + }, /** * 校领导审批列表需要按立案结果切换办理单位展示口径: * 确定立案显示主办/协办,作为建议只显示办理单位。 diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html index 8f3a595f..ad3ffac3 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html @@ -97,6 +97,7 @@ layout("/layouts/platform.html"){ + 导出 已审核 未审核 @@ -288,6 +289,7 @@ layout("/layouts/platform.html"){ return { tableColumns: [ {label: "提案编号", prop: "code"}, + {label: "立案编号", prop: "caseFilingCode"}, {label: "提案名称", prop: "name", width: "200px"}, {label: "提案类别", prop: "typeName"}, {label: "立案结果", prop: "caseFilingResult"}, @@ -319,6 +321,15 @@ layout("/layouts/platform.html"){ } }, methods: { + exportList() { + this.$downLoad(loc() + "/exportList", { + pageForm: JSON.stringify(this.pageForm), + approval: this.pageForm.approval, + tableColumns: JSON.stringify(this.tableColumns.filter(function (item) { + return item.visible !== false + })) + }) + }, openView(row) { this.$refs.guava.edit(() => { this.showApprovalForm = false diff --git a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/basicTable.js b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/basicTable.js index 6035b106..46e08c08 100644 --- a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/basicTable.js +++ b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/basicTable.js @@ -2,74 +2,47 @@ const BASIC_TABLE_COMPONENT = { template: `
- - + + - 新建机构 + 新建机构 - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
@@ -83,33 +56,27 @@ const BASIC_TABLE_COMPONENT = { parentId: { type: String, required: true - }, - parentName: { - type: String, - default: "" } }, data() { return { rules: { - institutionPath: [{ type: "array", required: true, message: "请选择机构", trigger: "change" }], name: [{ required: true, message: "必填", trigger: ["change", "blur"] }], code: [{ required: true, message: "必填", trigger: ["change", "blur"] }], - parentId: [{ required: true, message: "必填", trigger: ["change", "blur"] }], - location: [{ required: true, message: "必填", trigger: ["change", "blur"] }] + parentId: [{ required: true, message: "必填", trigger: ["change", "blur"] }] }, parentData: {}, parentIds: [], + ids: [], treeList: [], treeFlat: [], - cascaderProps: { + props: { checkStrictly: true, multiple: false, label: "name", value: "id" }, - dialogFormVisible: false, - isEdit: false + dialogFormVisible: false } }, methods: { @@ -128,75 +95,38 @@ const BASIC_TABLE_COMPONENT = { }) }, openAdd() { - this.isEdit = false this.dialogFormVisible = true - this.formData = { - institutionPath: [], - parentId: this.parentId, - location: 0 - } - this.listFormTree() - }, - openEdit(row) { - this.isEdit = true - this.dialogFormVisible = true - this.formData = { - ...row, - location: row.location || 0 - } - }, - /** - * 加载“双代会固定机构”字典树,新增机构只能从该树中选择。 - * 接口返回 treeList 用于级联展示,treeFlat 用于按所选字典ID回填名称和代码。 - */ - listFormTree() { - this.$axios.post("/platform/teacherCongress/institution/formTree", { - sessionId: this.sessionId - }).then((res) => { + this.formData = {} + this.ids = [] + $.post("/platform/teacherCongress/institution/formTree", { sessionId: this.sessionId }).then((res) => { if (res.code === 0) { - this.treeList = res.data.treeList || [] - this.treeFlat = res.data.treeFlat || [] + this.treeList = res.data.treeList + this.treeFlat = res.data.treeFlat } }) }, - /** - * 固定机构选择变化后回填业务名称和机构代码;清空选择时同步清空旧值。 - */ - institutionChange(institutionPath) { - const institutionId = institutionPath.length ? institutionPath[institutionPath.length - 1] : null - const institution = this.treeFlat.find(item => item.id === institutionId) - this.$set(this.formData, "name", institution ? institution.name : "") - this.$set(this.formData, "code", institution ? institution.code : "") - }, - isBasicInstitution(index) { - const pageNumber = this.pageForm.pageNumber || 1 - const pageSize = this.pageForm.pageSize || 10 - return (pageNumber - 1) * pageSize + index < 6 + // 上级机构选择变化 + parentChange(val) { + const id = val[val.length - 1] + const tree = this.treeFlat.find((tree) => tree.id === id) + this.$set(this.formData, "code", tree?.code) + this.$set(this.formData, "name", tree?.name) }, doSubmit() { this.$refs.formRef.validate((valid) => { - if (!valid) { - return + this.formData.id = this.ids[this.ids.length - 1] + this.formData.parentId = this.ids[this.ids.length - 2] || this.parentId + this.formData.sessionId = this.sessionId + if (valid) { + this.$axios.post(loc() + "/insert", this.formData).then((res) => { + if (res.code === 0) { + this.dialogFormVisible = false + this.$message.success(res.msg) + this.doSearch() + this.$emit("refresh", null) + } + }) } - const params = { - ...this.formData, - sessionId: this.sessionId - } - if (!this.isEdit) { - const institutionPath = this.formData.institutionPath || [] - // 下级机构先提交固定字典中的父级ID,由后端转换为当前届次的实际父机构ID。 - params.parentId = institutionPath.length > 1 ? institutionPath[institutionPath.length - 2] : this.parentId - delete params.institutionPath - } - const url = this.isEdit ? loc() + "/update" : loc() + "/insert" - this.$axios.post(url, params).then((res) => { - if (res.code === 0) { - this.dialogFormVisible = false - this.$message.success(res.msg) - this.doSearch() - this.$emit("refresh", null) - } - }) }) }, @@ -215,18 +145,5 @@ const BASIC_TABLE_COMPONENT = { }) }) } - }, - style: /*language=CSS*/ ` - .institution-description { - white-space: pre-wrap; - word-break: break-word; - line-height: 1.5; - } - - .disabled-delete-link { - color: #c0c4cc; - cursor: not-allowed; - font-size: 12px; - } - ` + } } diff --git a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/index.html b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/index.html index 41290d94..9de0f8ef 100644 --- a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/index.html @@ -9,27 +9,21 @@ layout("/layouts/platform.html"){ - - - - - - - - + + @@ -49,17 +43,16 @@ layout("/layouts/platform.html"){ "basic-table": BASIC_TABLE_COMPONENT }, computed: { - // 根节点即使尚无子机构也要展示机构列表,确保空届次可以创建第一条机构。 - hasChildInstitution() { - return this.currentTreeData && (this.currentTreeData.id === "0" || (this.currentTreeData.children && this.currentTreeData.children.length > 0)) + showInstitutionTable() { + const hasChildren = this.currentTreeData?.children?.length > 0 + return hasChildren } }, data() { return { currentTreeNode: null, currentTreeData: null, - sessionId: null, - activeTab: "institution" + sessionId: null } }, methods: { @@ -67,28 +60,14 @@ layout("/layouts/platform.html"){ this.currentTreeData = data this.currentTreeNode = node this.sessionId = sessionId - if (this.hasChildInstitution) { - this.activeTab = "institution" - } else if (this.activeTab === "institution") { - this.activeTab = "user" - } - this.refreshActiveTab() - }, - handleTabClick() { - this.refreshActiveTab() - }, - refreshActiveTab() { this.$nextTick(() => { - if (this.activeTab === "institution") { + if (this.showInstitutionTable) { this.$refs.basicTableRef && this.$refs.basicTableRef.doSearch() } else { this.$refs.userTableRef && this.$refs.userTableRef.doSearch() } }) }, - refreshTree() { - this.$refs.treeRef.listTree(this.currentTreeData && this.currentTreeData.id) - }, openEdit(row) {} }, created() {} diff --git a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/tree.js b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/tree.js index a5ecea6f..a66d8b2d 100644 --- a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/tree.js +++ b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/tree.js @@ -46,30 +46,11 @@ const TREE_COMPONENT = { this.$emit("node-click", data, node, this.sessionId) }, filterNode() {}, - findTreeNode(list, id) { - if (!id || !list) { - return null - } - for (const item of list) { - if (item.id === id) { - return item - } - const child = this.findTreeNode(item.children, id) - if (child) { - return child - } - } - return null - }, - listTree(selectedId) { + listTree() { this.$axios.post("/platform/teacherCongress/institution/leftTree", { sessionId: this.sessionId }).then((res) => { if (res.code === 0) { this.treeData = res.data - if (this.treeData && this.treeData.length > 0) { - this.treeData[0].name = "两代会组织机构" - } - const selectedNode = this.findTreeNode(this.treeData, selectedId) || this.treeData[0] - this.$emit("node-click", selectedNode, null, this.sessionId) + this.$emit("node-click", this.treeData[0], null, this.sessionId) } }) }, diff --git a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/userTable.js b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/userTable.js index e80960ce..a941ff4f 100644 --- a/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/userTable.js +++ b/src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/userTable.js @@ -3,73 +3,58 @@ const USER_TABLE_COMPONENT = {
- - - - - -
- 搜索 -
-
+ + " @keyup.enter.native="doSearch"> + + + +
+ 搜索 +
+
- 设置人员 - + 设置人员 + - - - - - - - - - + + + + + + + + + - +
- + - - - - - - - + - -
- 注意:如果需要跟角色绑定,请在数据字典双代会组织机构中添加对应的角色标识。 -
- @@ -83,10 +68,6 @@ const USER_TABLE_COMPONENT = { institutionId: { required: true, type: String - }, - institutionCode: { - type: String, - default: "" } }, data() { @@ -94,17 +75,10 @@ const USER_TABLE_COMPONENT = { formRules: { sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }], userId: [{ required: true, message: "必填", trigger: ["change", "blur"] }], - identity: [{ required: true, message: "必填", trigger: ["change", "blur"] }], - roleCode: [{ required: true, message: "必填", trigger: ["change", "blur"] }] + identity: [{ required: true, message: "必填", trigger: ["change", "blur"] }] }, dialogVisible: false, - sessionOptions: [], - roleOptions: [] - } - }, - computed: { - needRole() { - return ["ZWH001", "ZXWYH", "DBZGSCXZ"].includes(this.institutionCode) + sessionOptions: [] } }, methods: { @@ -162,18 +136,6 @@ const USER_TABLE_COMPONENT = { }) }, - listRoleOptions() { - if (!this.needRole) { - this.roleOptions = [] - return - } - this.$axios.post("/platform/teacherCongress/institution/specialCommitteeRoleOptions").then((res) => { - if (res.code === 0) { - this.roleOptions = res.data || [] - } - }) - }, - openAdd() { this.dialogVisible = true this.formData = { @@ -181,7 +143,6 @@ const USER_TABLE_COMPONENT = { institutionId: this.institutionId } this.listSession() - this.listRoleOptions() } } } diff --git a/src/main/resources/views/platform/zhgh/staffmanage/member/apply/common/commonQuery.html b/src/main/resources/views/platform/zhgh/staffmanage/member/apply/common/commonQuery.html index 48786812..19ed14a0 100644 --- a/src/main/resources/views/platform/zhgh/staffmanage/member/apply/common/commonQuery.html +++ b/src/main/resources/views/platform/zhgh/staffmanage/member/apply/common/commonQuery.html @@ -36,10 +36,10 @@ code="USER_PREPARED_BY_TYPE" multiple collapse-tags> --> - + diff --git a/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/commonQuery.html b/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/commonQuery.html index 56fa6003..97d56c7f 100644 --- a/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/commonQuery.html +++ b/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/commonQuery.html @@ -25,10 +25,10 @@ - + - + diff --git a/src/main/resources/views/platform/zhgh/staffmanage/member/info/common/commonQuery.html b/src/main/resources/views/platform/zhgh/staffmanage/member/info/common/commonQuery.html index 2464f42d..eedae74a 100644 --- a/src/main/resources/views/platform/zhgh/staffmanage/member/info/common/commonQuery.html +++ b/src/main/resources/views/platform/zhgh/staffmanage/member/info/common/commonQuery.html @@ -39,10 +39,10 @@ - +