From 24e2d9e826507a5fb47bbb10e45861c205745ed2 Mon Sep 17 00:00:00 2001 From: = <=> Date: Tue, 14 Jul 2026 09:19:04 +0800 Subject: [PATCH 01/13] commit --- .../statistics/ClubStatisticsController.java | 15 +- .../club/service/SysClubExamineService.java | 7 + .../impl/SysClubExamineServiceImpl.java | 344 ++++++++++++------ .../impl/SysClubInfoManageServiceImpl.java | 107 ++++-- .../zhgh/club/vo/ClubUserCommonPageVo.java | 1 + .../app/zhgh/club/vo/ClubUserJoinVo.java | 1 + .../club/infoManage/exitManage/index.html | 16 +- .../zhgh/club/infoManage/exitManage/info.js | 148 ++++---- .../platform/zhgh/club/statistics/index.html | 7 +- 9 files changed, 428 insertions(+), 218 deletions(-) diff --git a/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java b/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java index 575ae938..acd6b017 100644 --- a/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java +++ b/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java @@ -425,6 +425,7 @@ public class ClubStatisticsController { } private Sql generateSql(String clubId, Boolean auditState, String userState, String sex, Boolean giveMoney) { + // 注册流程按社团去重后再关联,避免换届等流程复用社团ID时将会员人数重复统计。 Sql sql = Sqls.create(""" SELECT club.id, @@ -438,11 +439,22 @@ public class ClubStatisticsController { sum( CASE WHEN ('CLUB_PRESIDENT' MEMBER OF (cu.roleCode) or 'CLUB_VICE_PRESIDENT' MEMBER OF (cu.roleCode) or 'CLUB_SECRETARY' MEMBER OF (cu.roleCode) or 'CLUB_VICE_SECRETARY' MEMBER OF (cu.roleCode)) AND 1 = 1 $myCondition THEN 1 ELSE 0 END ) AS governing_body FROM sys_club club + INNER JOIN ( + SELECT DISTINCT registerInstance.businessNo + FROM wf_process_instance registerInstance + INNER JOIN wf_process_define registerDefine + ON registerDefine.id = registerInstance.processDefineId + WHERE registerInstance.state = @finishedState + AND registerInstance.delFlag = 0 + AND registerDefine.name = @registerProcessKey + AND registerDefine.delFlag = 0 + ) registeredClub ON registeredClub.businessNo = club.id LEFT JOIN club_user cu ON cu.clubId = club.id LEFT JOIN sys_user su ON cu.userId = su.id - LEFT JOIN wf_process_instance ins ON ins.businessNo = club.id $condition """); + sql.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode()); + sql.setParam("registerProcessKey", "XHZC"); Cnd cnd = Cnd.NEW(); if (auditState != null) { List examineRegisters = sysClubService.dao().query(SysClubExamineRegister.class, Cnd.where("year(registerDate)", "=", DateUtil.thisYear())); @@ -458,7 +470,6 @@ public class ClubStatisticsController { List myClubId = userRoles.stream().map(Sys_user_role::getClubId).toList(); cnd.and("club.id", "in", myClubId); } - cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode()); cnd.andEX("club.id", "=", clubId); cnd.and("club.dismiss", "=", false); cnd.groupBy("club.id"); diff --git a/src/main/java/com/budwk/app/zhgh/club/service/SysClubExamineService.java b/src/main/java/com/budwk/app/zhgh/club/service/SysClubExamineService.java index 5836c312..1a96c476 100644 --- a/src/main/java/com/budwk/app/zhgh/club/service/SysClubExamineService.java +++ b/src/main/java/com/budwk/app/zhgh/club/service/SysClubExamineService.java @@ -13,6 +13,13 @@ import java.util.List; public interface SysClubExamineService extends BaseService { + /** + * 按会员入会、退休、退会时间统计指定年度的在职和退休人数变化。 + * + * @param clubId 社团ID + * @param year 统计年度 + * @return 在职和退休人员的年初、增加、减少、年末人数 + */ List getClubUserNum(@Valid String clubId, Integer year); List getJgUser(@Valid String clubId); diff --git a/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubExamineServiceImpl.java b/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubExamineServiceImpl.java index 0811b055..e90aca78 100644 --- a/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubExamineServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubExamineServiceImpl.java @@ -10,7 +10,6 @@ import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.base.utils.PageUtil; import com.budwk.app.flow.enums.ProcessInstanceStateEnum; import com.budwk.app.flow.enums.ProcessTaskStateEnum; -import com.budwk.app.sys.services.SysDictService; import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.club.model.SysClub; @@ -32,14 +31,15 @@ import org.nutz.lang.Lang; import org.nutz.lang.util.NutMap; import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; @IocBean(args = {"refer:dao"}) public class SysClubExamineServiceImpl extends BaseServiceImpl implements SysClubExamineService { - @Inject - private SysDictService sysDictService; @Inject private SysClubService sysClubService; @@ -49,128 +49,244 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl getClubUserNum(String clubId, Integer year) { - // 定义统计的用户状态类型 - List userStateList = List.of("在职", "退休"); - List result = new ArrayList<>(); + Date yearStart = DateUtil.parse(year + "-01-01 00:00:00"); + Date nextYearStart = DateUtil.parse((year + 1) + "-01-01 00:00:00"); + List membershipPeriods = getMembershipPeriods(clubId); + NutMap activeResult = createUserChangeResult("在职"); + NutMap retiredResult = createUserChangeResult("退休"); - // 查询上一年度考核登记数据(用于获取年初人数) - SysClubExamineRegister examineRegister = dao().fetch(SysClubExamineRegister.class, - Cnd.where("year", "=", year - 1).and("clubId", "=", clubId)); + for (MembershipPeriod period : membershipPeriods) { + // 非正常历史会员没有退会时间且没有已完成退会申请时,无法确定所属年度,不计入统计。 + if (!period.normal && period.exitTime == null) { + continue; + } + if (isMemberAtYearBoundary(period, yearStart)) { + increaseResult(classifyAtBoundary(period, yearStart), activeResult, retiredResult, "yearFirstNum"); + } + if (isInYear(period.joinTime, yearStart, nextYearStart)) { + increaseResult(classifyAtEvent(period, period.joinTime), activeResult, retiredResult, "yearAddNum"); + } + if (isInYear(period.exitTime, yearStart, nextYearStart)) { + increaseResult(classifyBeforeEvent(period, period.exitTime), activeResult, retiredResult, "yearReduceNum"); + } + // 退休发生在会员有效期内时,作为在职减少一人、退休增加一人处理。 + if (isInYear(period.retireDate, yearStart, nextYearStart) + && period.joinTime.before(period.retireDate) + && (period.exitTime == null || period.exitTime.after(period.retireDate))) { + increaseResult("在职", activeResult, retiredResult, "yearReduceNum"); + increaseResult("退休", activeResult, retiredResult, "yearAddNum"); + } + if (isMemberAtYearBoundary(period, nextYearStart)) { + increaseResult(classifyAtBoundary(period, nextYearStart), activeResult, retiredResult, "thisYearNum"); + } + } + return List.of(activeResult, retiredResult); + } - // 构建社团用户申请记录查询SQL(关联用户信息、流程实例) - Sql sql = Sqls.create(""" + /** + * 合并旧系统会员生命周期与新系统已完成申请,生成可用于年度统计的入退会区间。 + * 旧系统记录负责迁移历史,新系统申请只补充旧记录缺失的退会时间和迁移后新增的入会周期。 + */ + private List getMembershipPeriods(String clubId) { + Sql legacySql = Sqls.create(""" SELECT - cu.*, - year(cu.applyDate) as applyYear, + cu.userId, + CAST(cu.joinTime AS DATETIME) joinTime, + STR_TO_DATE(NULLIF(cu.changeTime, ''), '%Y-%m-%d %H:%i:%s') exitTime, + cu.isNormal, u.userState, u.retireDate - FROM - club_user_apply cu - LEFT JOIN sys_user u ON cu.userId = u.id - LEFT JOIN wf_process_instance ins ON ins.businessNo = cu.id - $condition - """); - Cnd cnd = Cnd.NEW(); - cnd.and("cu.clubId", "=", clubId); - cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode()); - cnd.groupBy("cu.clubId, cu.userId, cu.mode"); - sql.setCondition(cnd); - List userList = listMap(sql); + FROM sys_club_user cu + LEFT JOIN sys_user u ON u.id = cu.userId + WHERE cu.clubId = @clubId + AND cu.status = 5 + AND cu.joinTime IS NOT NULL + AND cu.joinTime <> '' + """).setParam("clubId", clubId); + List periods = listMap(legacySql).stream() + .map(row -> new MembershipPeriod( + row.getString("userId"), + row.getTime("joinTime"), + row.getTime("exitTime"), + !Boolean.FALSE.equals(row.getBoolean("isNormal")), + true, + row.getString("userState"), + row.getTime("retireDate") + )) + .filter(period -> period.joinTime != null) + .collect(Collectors.toCollection(ArrayList::new)); - // 遍历在职/退休状态,分别统计人员变动数据 - for (String userState : userStateList) { - NutMap nutMap = new NutMap(); - nutMap.addv("userState", userState); + Sql applySql = Sqls.create(""" + SELECT + cu.userId, + cu.mode, + cu.applyDate, + cu.joinTime, + cu.exitTime, + u.userState, + u.retireDate + FROM club_user_apply cu + LEFT JOIN sys_user u ON u.id = cu.userId + WHERE cu.clubId = @clubId + AND COALESCE(cu.delFlag, 0) = 0 + AND EXISTS ( + SELECT 1 + FROM wf_process_instance ins + WHERE ins.businessNo = cu.id + AND ins.state = @finishedState + ) + ORDER BY cu.applyDate, cu.mode + """) + .setParam("clubId", clubId) + .setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode()); + List applications = listMap(applySql); + applications.sort(Comparator.comparing(row -> row.getTime("applyDate"), Comparator.nullsLast(Date::compareTo))); - // 根据用户状态匹配对应的人员类型集合 - List personTypeList = switch (userState) { - case "在职" -> List.of("在职", "在岗"); - case "退休" -> List.of("退休", "退休【变号】"); - default -> new ArrayList<>(); - }; - - // 过滤出符合当前人员类型的用户(非空判断避免NPE) - List personTypeUsers = userList.stream() - .filter(u -> StrUtil.isNotBlank(u.getString("userState")) - && personTypeList.contains(u.getString("userState"))) - .collect(Collectors.toList()); - - // 初始化年末人数为0 - int thisYearNum = 0; - if (!Lang.isEmpty(personTypeUsers)) { - // 统计年末人数:加入社团且无退出记录的用户数量 - List exitUserIds = personTypeUsers.stream() - .filter(u -> u.getInt("mode") == 0) - .map(u -> u.getString("userId")) - .toList(); - - thisYearNum = (int) personTypeUsers.stream() - .filter(u -> u.getInt("mode") == 1) - .filter(u -> !exitUserIds.contains(u.getString("userId"))) - .count(); + for (NutMap application : applications) { + Date applyDate = application.getTime("applyDate"); + Boolean mode = application.getBoolean("mode"); + if (applyDate == null || mode == null) { + continue; } - - // 统计今年退休人数:已入会且退休日期在本年度的用户 - int retireCount = (int) personTypeUsers.stream() - .filter(u -> u.getTime("retireDate") != null - && u.getInt("mode") == 1 - && DateUtil.year(u.getTime("retireDate")) == year) - .count(); - - // 封装年初人数:从上一年度登记数据中获取,无数据则为0 - if (Lang.isNotEmpty(examineRegister) && Lang.isNotEmpty(examineRegister.getChangeUserNum())) { - JSONObject uState = examineRegister.getChangeUserNum().stream() - .filter(c -> c.getStr("userState").equals(userState)) - .findFirst() - .orElse(null); - nutMap.addv("yearFirstNum", Lang.isEmpty(uState) ? 0 : uState.getInt("thisYearNum")); + if (mode) { + mergeJoinApplication(periods, application, applyDate); } else { - nutMap.addv("yearFirstNum", 0); + mergeExitApplication(periods, application, applyDate); } - - // 统计年度增加相关数据 - int joinThisYear = (int) personTypeUsers.stream() - .filter(u -> u.getInt("mode") == 1 && u.getInt("applyYear") == year) - .count(); - - int thisYearJoinAndRetire = (int) userList.stream() - .filter(u -> u.getInt("mode") == 1 && u.getInt("applyYear") == year - && u.getTime("retireDate") != null - && DateUtil.year(u.getTime("retireDate")) == year) - .count(); - - int beforeYearJoinAndRetire = (int) userList.stream() - .filter(u -> u.getInt("mode") == 1 && u.getInt("applyYear") == year - && u.getTime("retireDate") != null - && DateUtil.year(u.getTime("retireDate")) < year) - .count(); - - // 按用户状态封装年度增加人数 - nutMap.addv("yearAddNum", "在职".equals(userState) - ? joinThisYear + thisYearJoinAndRetire - : beforeYearJoinAndRetire + retireCount); - - // 统计年度减少相关数据 - int quitThisYear = (int) personTypeUsers.stream() - .filter(u -> u.getInt("mode") == 0 && u.getInt("applyYear") == year) - .count(); - - // 在职人员年度减少:退休人数+主动退出人数;退休人员仅统计主动退出 - if ("在职".equals(userState)) { - int retireThisYear = (int) userList.stream() - .filter(u -> u.getTime("retireDate") != null - && DateUtil.year(u.getTime("retireDate")) == year) - .count(); - nutMap.addv("yearReduceNum", retireThisYear + quitThisYear); - } else { - nutMap.addv("yearReduceNum", quitThisYear); - } - - // 封装年末人数 - nutMap.addv("thisYearNum", thisYearNum); - result.add(nutMap); } - return result; + return periods; + } + + /** + * 已迁移的入会申请与旧会员记录精确对应时不重复新增;迁移后的新申请以审核申请时间作为入会时间。 + */ + private void mergeJoinApplication(List periods, NutMap application, Date applyDate) { + String userId = application.getString("userId"); + Date applicationJoinTime = application.getTime("joinTime"); + boolean representedByLegacy = periods.stream() + .filter(period -> period.legacy && Objects.equals(period.userId, userId)) + .filter(period -> Objects.equals(period.joinTime, applicationJoinTime)) + .anyMatch(period -> period.exitTime == null || !applyDate.after(period.exitTime)); + boolean representedByNewPeriod = periods.stream() + .filter(period -> !period.legacy && Objects.equals(period.userId, userId)) + .anyMatch(period -> isMemberAt(period, applyDate)); + if (representedByLegacy || representedByNewPeriod) { + return; + } + periods.add(new MembershipPeriod( + userId, + applyDate, + null, + true, + false, + application.getString("userState"), + application.getTime("retireDate") + )); + } + + /** + * 退会申请优先关闭入会时间相同的会员周期;新系统复入会后再退会时关闭最近的有效周期。 + */ + private void mergeExitApplication(List periods, NutMap application, Date applyDate) { + String userId = application.getString("userId"); + Date applicationJoinTime = application.getTime("joinTime"); + Date exitTime = application.getTime("exitTime") == null ? applyDate : application.getTime("exitTime"); + MembershipPeriod target = periods.stream() + .filter(period -> Objects.equals(period.userId, userId)) + .filter(period -> Objects.equals(period.joinTime, applicationJoinTime)) + .filter(period -> period.exitTime == null) + .max(Comparator.comparing(period -> period.joinTime)) + .orElse(null); + if (target == null) { + target = periods.stream() + .filter(period -> Objects.equals(period.userId, userId)) + .filter(period -> period.exitTime == null && !period.joinTime.after(exitTime)) + .max(Comparator.comparing(period -> period.joinTime)) + .orElse(null); + } + if (target != null) { + target.exitTime = exitTime; + } + } + + private NutMap createUserChangeResult(String userState) { + return NutMap.NEW() + .addv("userState", userState) + .addv("yearFirstNum", 0) + .addv("yearAddNum", 0) + .addv("yearReduceNum", 0) + .addv("thisYearNum", 0); + } + + private void increaseResult(String userState, NutMap activeResult, NutMap retiredResult, String field) { + NutMap result = "退休".equals(userState) ? retiredResult : "在职".equals(userState) ? activeResult : null; + if (result != null) { + result.put(field, result.getInt(field) + 1); + } + } + + private boolean isInYear(Date date, Date yearStart, Date nextYearStart) { + return date != null && !date.before(yearStart) && date.before(nextYearStart); + } + + private boolean isMemberAt(MembershipPeriod period, Date date) { + return !period.joinTime.after(date) && (period.exitTime == null || period.exitTime.after(date)); + } + + private boolean isMemberAtYearBoundary(MembershipPeriod period, Date boundary) { + return period.joinTime.before(boundary) && (period.exitTime == null || !period.exitTime.before(boundary)); + } + + private String classifyAtBoundary(MembershipPeriod period, Date boundary) { + if (period.retireDate != null) { + return period.retireDate.before(boundary) ? "退休" : "在职"; + } + return normalizeUserState(period.userState); + } + + private String classifyAtEvent(MembershipPeriod period, Date eventTime) { + if (period.retireDate != null) { + return period.retireDate.after(eventTime) ? "在职" : "退休"; + } + return normalizeUserState(period.userState); + } + + private String classifyBeforeEvent(MembershipPeriod period, Date eventTime) { + if (period.retireDate != null) { + return period.retireDate.before(eventTime) ? "退休" : "在职"; + } + return normalizeUserState(period.userState); + } + + private String normalizeUserState(String userState) { + if (List.of("在职", "在岗").contains(userState)) { + return "在职"; + } + if (List.of("退休", "退休【变号】").contains(userState)) { + return "退休"; + } + return null; + } + + private static class MembershipPeriod { + private final String userId; + private final Date joinTime; + private Date exitTime; + private final boolean normal; + private final boolean legacy; + private final String userState; + private final Date retireDate; + + private MembershipPeriod(String userId, Date joinTime, Date exitTime, boolean normal, boolean legacy, + String userState, Date retireDate) { + this.userId = userId; + this.joinTime = joinTime; + this.exitTime = exitTime; + this.normal = normal; + this.legacy = legacy; + this.userState = userState; + this.retireDate = retireDate; + } } @Override diff --git a/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubInfoManageServiceImpl.java b/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubInfoManageServiceImpl.java index 9cc4424c..c4ad1c2f 100644 --- a/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubInfoManageServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/club/service/impl/SysClubInfoManageServiceImpl.java @@ -15,6 +15,7 @@ import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.base.Globals; import com.budwk.app.web.controllers.open.commons.service.CommonService; import com.budwk.app.zhgh.club.model.ClubUser; +import com.budwk.app.zhgh.club.model.SysClub; import com.budwk.app.zhgh.club.param.ClubUserPageForm; import com.budwk.app.zhgh.club.service.SysClubInfoManageService; import com.budwk.app.zhgh.club.service.SysClubService; @@ -41,6 +42,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -227,19 +229,23 @@ public class SysClubInfoManageServiceImpl extends BaseServiceImpl exitManagePageData(ClubUserPageForm pageForm) { Sql sql = Sqls.create(""" SELECT - info.id, - info.clubId, - info.userId, - info.roleCode AS applyRoleCode, - info.clubPosition, - info.email, - info.mobile, - info.birthday, - info.avatar, - info.sameTimeJoinOtherClubSituation, - info.awardsExperience, + COALESCE(info.id, scu.id) AS id, + scu.clubId, + scu.userId, + COALESCE(info.roleCode, scu.roleCode) AS applyRoleCode, + COALESCE(info.clubPosition, scu.position) AS clubPosition, + COALESCE(info.email, scu.email, u.email) AS email, + COALESCE(info.mobile, u.mobile) AS mobile, + COALESCE(info.birthday, u.birthday) AS birthday, + COALESCE(info.avatar, scu.avatar, u.avatar) AS avatar, + COALESCE(info.sameTimeJoinOtherClubSituation, scu.sameTimeJoinOtherClubSituation) AS sameTimeJoinOtherClubSituation, + COALESCE(info.awardsExperience, scu.awardsExperience) AS awardsExperience, info.signature, - info.applyDate, + COALESCE( + info.applyDate, + STR_TO_DATE(scu.changeTime, '%Y-%m-%d %H:%i:%s'), + STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(scu.exitAuditList, '$[0].auditTime')), '%Y-%m-%d %H:%i:%s') + ) AS applyDate, u.username AS userName, u.loginname AS loginName, u.sex, @@ -247,24 +253,32 @@ public class SysClubInfoManageServiceImpl extends BaseServiceImpl pagination = listPageVO(pageForm, sql, ClubUserCommonPageVo.class); List list = pagination.getList(ClubUserCommonPageVo.class); for (ClubUserCommonPageVo vo : list) { - vo.setRoleName(SysClubUserServiceImpl.convertRoleName(List.of(vo.getApplyRoleCode()))); + if (StrUtil.isNotBlank(vo.getApplyRoleCode())) { + vo.setRoleName(SysClubUserServiceImpl.convertRoleName(List.of(vo.getApplyRoleCode()))); + } } pagination.setList(list); return pagination; @@ -291,7 +307,30 @@ public class SysClubInfoManageServiceImpl extends BaseServiceImpl clubList = sysClubService.getMyManageClub().stream() + .sorted(Comparator.comparing(SysClub::getClubCode, Comparator.nullsLast(String::compareTo))) + .toList(); + nutMap.put("children", clubList); result.add(nutMap); return result; } diff --git a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserCommonPageVo.java b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserCommonPageVo.java index fb421266..0039f761 100644 --- a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserCommonPageVo.java +++ b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserCommonPageVo.java @@ -31,6 +31,7 @@ public class ClubUserCommonPageVo extends ClubUser { private String unionId; private String joinTime; private String exitTime; + private String exitType; private String applyRoleCode; private String roleName; diff --git a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java index c0ac0c8e..71d99f72 100644 --- a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java +++ b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java @@ -23,4 +23,5 @@ public class ClubUserJoinVo extends ClubUserApply { private String academicDegree; private String position; private String clubName; + private String exitType; } diff --git a/src/main/resources/views/platform/zhgh/club/infoManage/exitManage/index.html b/src/main/resources/views/platform/zhgh/club/infoManage/exitManage/index.html index 5ab88f44..b66e30f5 100644 --- a/src/main/resources/views/platform/zhgh/club/infoManage/exitManage/index.html +++ b/src/main/resources/views/platform/zhgh/club/infoManage/exitManage/index.html @@ -38,6 +38,13 @@ layout("/layouts/platform.html"){ + + +