Compare commits

19 Commits
Author SHA1 Message Date
c-chenxs1 e3f32fe72b feat: 优化人员拉取和数据字典部分2 2026-10-29 15:52:02 +08:00
c-chenxs1 b885f449c7 feat: 优化人员拉取和数据字典部分 2026-10-29 15:29:55 +08:00
c-chenxs1 3f441828a1 Merge branch 'feat_可同步长江大学的优化_fix' into feat_本工会单独业务 2026-10-29 10:45:35 +08:00
c-chenxs1 a0732fdb08 Merge branch 'feat_可同步长江大学的优化_fix' into feat_本工会单独业务 2026-10-28 15:26:58 +08:00
c-chenxs1 db26813635 feat: move 2026-10-28 15:22:43 +08:00
c-chenxs1 d18d9bda6d Merge branch 'feat_可同步长江大学的优化_fix'
# Conflicts:
#	.gitignore
2026-10-28 13:54:48 +08:00
c-chenxs1 0fb779ff5a feat: v3版疗休养优化9 2026-10-27 11:59:57 +08:00
c-chenxs1 55e94de004 feat: v3版疗休养优化8 2026-10-27 09:12:52 +08:00
c-chenxs1 d452d4ad92 feat: v3版疗休养优化7 2026-10-26 18:19:28 +08:00
c-chenxs1 6ea864cb64 feat: v3版疗休养优化6 2026-10-26 17:33:07 +08:00
c-chenxs1 56cc3fee91 feat: v3版疗休养优化6 2026-10-26 16:50:49 +08:00
c-chenxs1 4c03b389d4 feat: v3版疗休养优化5 2026-10-26 15:27:53 +08:00
c-chenxs1 fcb6ba7e2d feat: v3版疗休养优化4 2026-10-26 14:28:19 +08:00
c-chenxs1 65fac78cfb feat: v3版疗休养优化3 2026-10-26 13:35:39 +08:00
c-chenxs1 2d20959355 feat: v3版疗休养优化2 2026-10-26 09:49:06 +08:00
c-chenxs1 1a1946b1f8 feat: v3版疗休养优化 2026-10-26 09:45:30 +08:00
c-chenxs1 7f2ac97dea feat: v3版疗休养 2026-10-26 09:21:26 +08:00
c-chenxs1 82713327db feat: v3版疗休养 2026-10-26 09:19:45 +08:00
c-chenxs1 d598f1bf0f feat: 补充角色工作流 2026-10-23 17:12:29 +08:00
184 changed files with 48078 additions and 12 deletions
-1
View File
@@ -49,5 +49,4 @@ Thumbs.db
.trae/pr-creator/SKILL.md .trae/pr-creator/SKILL.md
.trae/update-docs/SKILL.md .trae/update-docs/SKILL.md
.trae/webapp-testing/SKILL.md .trae/webapp-testing/SKILL.md
outputs outputs
@@ -83,6 +83,7 @@ public class MainLauncher {
Globals.AppBase = Mvcs.getServletContext().getContextPath(); Globals.AppBase = Mvcs.getServletContext().getContextPath();
Globals.AppRoot = Mvcs.getServletContext().getRealPath("/"); Globals.AppRoot = Mvcs.getServletContext().getRealPath("/");
init_sys(); init_sys();
ioc.get(com.budwk.app.zhgh.staffbenefit.therapyRecuperation.TherapyRecuperationModule.class);
// 2026年10月3日 12:01:28;操作人:wxg:先升级会员表及补齐历史资料,再处理缴费快照和启动计划任务;不依赖 DEBUG。 // 2026年10月3日 12:01:28;操作人:wxg:先升级会员表及补齐历史资料,再处理缴费快照和启动计划任务;不依赖 DEBUG。
SysClubUserService members = ioc.get(SysClubUserService.class, "sysClubUserServiceImpl"); SysClubUserService members = ioc.get(SysClubUserService.class, "sysClubUserServiceImpl");
members.upgradeMemberSchema(); members.upgradeMemberSchema();
@@ -50,6 +50,11 @@ RoleConstant {
BRANCH_UNION_SHENGGHUO_WY("分工会生活委员"), BRANCH_UNION_SHENGGHUO_WY("分工会生活委员"),
BRANCH_UNION_TIAOJIE_WY("分工会调解委员"), BRANCH_UNION_TIAOJIE_WY("分工会调解委员"),
BRANCH_UNION_WENTI_SPORTS("分工会文体福利委员"), BRANCH_UNION_WENTI_SPORTS("分工会文体福利委员"),
BRANCH_UNION_YOUTH_WORK_COMMITTEE("分工会青工委委员"),
BRANCH_UNION_WOMEN_WORK_COMMITTEE("分工会女工委委员"),
BRANCH_UNION_WELFARE_COMMITTEE("分工会福利委员"),
BRANCH_UNION_SPORTS_COMMITTEE("分工会文体委员"),
BRANCH_UNION_PUBLICITY_COMMITTEE("分工会宣传委员"),
UNIT_PARTY_SECRETARY("单位党委书记"), UNIT_PARTY_SECRETARY("单位党委书记"),
@@ -0,0 +1,54 @@
package com.budwk.app.flow.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.AssignmentHandler;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.List;
public class FlowBranchUnionPublicityCommitteeHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.BRANCH_UNION_PUBLICITY_COMMITTEE);
if (role == null || role.isDisabled()) {
throw new BaseException("分工会宣传委员角色未配置或已禁用,请联系校工会!");
}
String unionId = StrUtil.blankToDefault(execution.getArgs().getStr(FlowConst.INITIATOR_UNIT_UNION_ID), SecurityUtil.getUnionId());
if (StrUtil.isBlank(unionId)) {
throw new BaseException("无法确定所属分工会,请联系校工会!");
}
List<Sys_user_role> relations = dao.query(Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnionId, "=", unionId)
.and(Sys_user_role::getEnable, "=", true));
List<String> userIds = relations.stream().map(Sys_user_role::getUserId)
.filter(StrUtil::isNotBlank).distinct().toList();
if (userIds.isEmpty()) {
throw new BaseException("分工会宣传委员没有设置,请联系校工会!");
}
return userIds;
}
@Override
public String getMessage() {
return "流程发起人所属分工会宣传委员";
}
@Override
public int getOrder() {
return 15;
}
}
@@ -0,0 +1,54 @@
package com.budwk.app.flow.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.AssignmentHandler;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.List;
public class FlowBranchUnionSportsCommitteeHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.BRANCH_UNION_SPORTS_COMMITTEE);
if (role == null || role.isDisabled()) {
throw new BaseException("分工会文体委员角色未配置或已禁用,请联系校工会!");
}
String unionId = StrUtil.blankToDefault(execution.getArgs().getStr(FlowConst.INITIATOR_UNIT_UNION_ID), SecurityUtil.getUnionId());
if (StrUtil.isBlank(unionId)) {
throw new BaseException("无法确定所属分工会,请联系校工会!");
}
List<Sys_user_role> relations = dao.query(Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnionId, "=", unionId)
.and(Sys_user_role::getEnable, "=", true));
List<String> userIds = relations.stream().map(Sys_user_role::getUserId)
.filter(StrUtil::isNotBlank).distinct().toList();
if (userIds.isEmpty()) {
throw new BaseException("分工会文体委员没有设置,请联系校工会!");
}
return userIds;
}
@Override
public String getMessage() {
return "流程发起人所属分工会文体委员";
}
@Override
public int getOrder() {
return 14;
}
}
@@ -0,0 +1,54 @@
package com.budwk.app.flow.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.AssignmentHandler;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.List;
public class FlowBranchUnionWelfareCommitteeHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.BRANCH_UNION_WELFARE_COMMITTEE);
if (role == null || role.isDisabled()) {
throw new BaseException("分工会福利委员角色未配置或已禁用,请联系校工会!");
}
String unionId = StrUtil.blankToDefault(execution.getArgs().getStr(FlowConst.INITIATOR_UNIT_UNION_ID), SecurityUtil.getUnionId());
if (StrUtil.isBlank(unionId)) {
throw new BaseException("无法确定所属分工会,请联系校工会!");
}
List<Sys_user_role> relations = dao.query(Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnionId, "=", unionId)
.and(Sys_user_role::getEnable, "=", true));
List<String> userIds = relations.stream().map(Sys_user_role::getUserId)
.filter(StrUtil::isNotBlank).distinct().toList();
if (userIds.isEmpty()) {
throw new BaseException("分工会福利委员没有设置,请联系校工会!");
}
return userIds;
}
@Override
public String getMessage() {
return "流程发起人所属分工会福利委员";
}
@Override
public int getOrder() {
return 13;
}
}
@@ -0,0 +1,54 @@
package com.budwk.app.flow.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.AssignmentHandler;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.List;
public class FlowBranchUnionWomenWorkCommitteeHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.BRANCH_UNION_WOMEN_WORK_COMMITTEE);
if (role == null || role.isDisabled()) {
throw new BaseException("分工会女工委委员角色未配置或已禁用,请联系校工会!");
}
String unionId = StrUtil.blankToDefault(execution.getArgs().getStr(FlowConst.INITIATOR_UNIT_UNION_ID), SecurityUtil.getUnionId());
if (StrUtil.isBlank(unionId)) {
throw new BaseException("无法确定所属分工会,请联系校工会!");
}
List<Sys_user_role> relations = dao.query(Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnionId, "=", unionId)
.and(Sys_user_role::getEnable, "=", true));
List<String> userIds = relations.stream().map(Sys_user_role::getUserId)
.filter(StrUtil::isNotBlank).distinct().toList();
if (userIds.isEmpty()) {
throw new BaseException("分工会女工委委员没有设置,请联系校工会!");
}
return userIds;
}
@Override
public String getMessage() {
return "流程发起人所属分工会女工委委员";
}
@Override
public int getOrder() {
return 12;
}
}
@@ -0,0 +1,54 @@
package com.budwk.app.flow.handler;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.AssignmentHandler;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.engine.model.TaskModel;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import java.util.List;
public class FlowBranchUnionYouthWorkCommitteeHandler implements AssignmentHandler {
@Override
public List<String> assign(TaskModel model, Execution execution) {
Dao dao = ServiceContext.find(Dao.class);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
Sys_role role = sysRoleService.getByCode(RoleConstant.BRANCH_UNION_YOUTH_WORK_COMMITTEE);
if (role == null || role.isDisabled()) {
throw new BaseException("分工会青工委委员角色未配置或已禁用,请联系校工会!");
}
String unionId = StrUtil.blankToDefault(execution.getArgs().getStr(FlowConst.INITIATOR_UNIT_UNION_ID), SecurityUtil.getUnionId());
if (StrUtil.isBlank(unionId)) {
throw new BaseException("无法确定所属分工会,请联系校工会!");
}
List<Sys_user_role> relations = dao.query(Sys_user_role.class,
Cnd.where(Sys_user_role::getRoleId, "=", role.getId())
.and(Sys_user_role::getUnionId, "=", unionId)
.and(Sys_user_role::getEnable, "=", true));
List<String> userIds = relations.stream().map(Sys_user_role::getUserId)
.filter(StrUtil::isNotBlank).distinct().toList();
if (userIds.isEmpty()) {
throw new BaseException("分工会青工委委员没有设置,请联系校工会!");
}
return userIds;
}
@Override
public String getMessage() {
return "流程发起人所属分工会青工委委员";
}
@Override
public int getOrder() {
return 11;
}
}
@@ -98,6 +98,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column @Column
@Comment("证件类型") @Comment("证件类型")
@ColDefine(type = ColType.VARCHAR, width = 30) @ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "证件类型", key = "SFZJLXDM", dict = "USER_ID_CARD_TYPE")
private String idCardType; private String idCardType;
@Column @Column
@@ -133,6 +134,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column @Column
@Comment("岗位类别") @Comment("岗位类别")
@ColDefine(type = ColType.VARCHAR, width = 50) @ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "聘岗类型", key = "ZYJSGWLBDMMC")
private String jobCategory; private String jobCategory;
@Column @Column
@@ -222,7 +224,7 @@ public class Sys_user extends BaseModel implements Serializable {
private Integer pendingConfirmStatus; private Integer pendingConfirmStatus;
@Column @Column
@Comment("编制类别码") @Comment("编制类别")
@ColDefine(type = ColType.VARCHAR, width = 30) @ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "编制类别", key = "BZLBDMMC") @DataCenterColumn(name = "编制类别", key = "BZLBDMMC")
private String preparedBy; private String preparedBy;
@@ -295,6 +297,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Comment("是否双肩挑") @Comment("是否双肩挑")
@ColDefine(type = ColType.BOOLEAN) @ColDefine(type = ColType.BOOLEAN)
@Default(value = "0") @Default(value = "0")
@DataCenterColumn(name = "是否双肩挑", key = "SFSJT")
private Boolean manyUnit; private Boolean manyUnit;
@Column @Column
@@ -1,5 +1,6 @@
package com.budwk.app.sys.models; package com.budwk.app.sys.models;
import com.budwk.app.sys.annotation.DataCenterColumn;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -31,6 +32,30 @@ public class Sys_user_source extends Sys_user {
@ColDefine(type = ColType.VARCHAR, width = 255) @ColDefine(type = ColType.VARCHAR, width = 255)
private String unitName; private String unitName;
@Column
@Comment("最高学历代码")
@ColDefine(type = ColType.VARCHAR, width = 20)
@DataCenterColumn(name = "最高学历代码", key = "ZGXLDM")
private String educationCode;
@Column
@Comment("最高学位代码")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "最高学位代码", key = "XWDM")
private String academicDegreeCode;
@Column
@Comment("编制类别代码")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "编制类别代码", key = "BZLBDM")
private String preparedByCode;
@Column
@Comment("聘岗类型代码")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "聘岗类型代码", key = "ZYJSGWLBDM")
private String jobCategoryCode;
@Column @Column
@Comment("拉取时间") @Comment("拉取时间")
@ColDefine(type = ColType.DATETIME) @ColDefine(type = ColType.DATETIME)
@@ -98,7 +98,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
synchronized (SysDataUserPullServiceImpl.class) { synchronized (SysDataUserPullServiceImpl.class) {
if (fieldMappings == null) { if (fieldMappings == null) {
List<FieldMapping> mappings = new ArrayList<>(); List<FieldMapping> mappings = new ArrayList<>();
Field[] fields = Sys_user.class.getDeclaredFields(); Field[] fields = cn.hutool.core.util.ReflectUtil.getFields(Sys_user_source.class);
for (Field field : fields) { for (Field field : fields) {
DataCenterColumn annotation = field.getAnnotation(DataCenterColumn.class); DataCenterColumn annotation = field.getAnnotation(DataCenterColumn.class);
if (annotation != null) { if (annotation != null) {
@@ -200,6 +200,8 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
mapping.field.set(sysUser, raw.getStr(mapping.key)); mapping.field.set(sysUser, raw.getStr(mapping.key));
} }
} }
} else if (mapping.field.getType() == Boolean.class) {
mapping.field.set(sysUser, raw.getBool(mapping.key));
} else if (mapping.field.getType() == Date.class) { } else if (mapping.field.getType() == Date.class) {
String dateText = StrUtil.trim(raw.getStr(mapping.key)); String dateText = StrUtil.trim(raw.getStr(mapping.key));
if (StrUtil.isNotBlank(dateText)) { if (StrUtil.isNotBlank(dateText)) {
@@ -10,7 +10,6 @@ import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log; import org.nutz.log.Log;
import org.nutz.log.Logs; import org.nutz.log.Logs;
import org.nutz.plugins.mvc.websocket.AbstractWsEndpoint; import org.nutz.plugins.mvc.websocket.AbstractWsEndpoint;
import org.nutz.plugins.mvc.websocket.NutWsConfigurator;
import org.nutz.plugins.mvc.websocket.WsHandler; import org.nutz.plugins.mvc.websocket.WsHandler;
import redis.clients.jedis.*; import redis.clients.jedis.*;
@@ -21,7 +20,7 @@ import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ServerEndpoint(value = "/websocket", configurator = NutWsConfigurator.class) @ServerEndpoint(value = "/websocket", configurator = WkWsConfigurator.class)
@IocBean(create = "init") // 使用NutWsConfigurator的必备条件 @IocBean(create = "init") // 使用NutWsConfigurator的必备条件
public class WkWebSocket extends AbstractWsEndpoint implements PubSub { public class WkWebSocket extends AbstractWsEndpoint implements PubSub {
protected static final Log log = Logs.get(); protected static final Log log = Logs.get();
@@ -0,0 +1,20 @@
package com.budwk.app.web.commons.ext.websocket;
import org.nutz.plugins.mvc.websocket.NutWsConfigurator;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
public class WkWsConfigurator extends NutWsConfigurator {
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
// WebSocket升级不一定经过Nutz请求链,只使用当前握手的会话,避免读取已回收的MVC请求。
Object session = request.getHttpSession();
if (session == null) {
config.getUserProperties().remove("HttpSession");
} else {
config.getUserProperties().put("HttpSession", session);
}
}
}
@@ -0,0 +1,197 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation;
import com.budwk.app.sys.models.*;
import com.budwk.app.sys.services.SysMenuService;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.*;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.*;
import org.nutz.dao.*;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.trans.Trans;
import java.util.*;
@IocBean(create = "init")
public class TherapyRecuperationModule {
public static final String ROOT = "/platform/inclusiveTherapyV3";
public static final String[][] SCREENS = {
{"config", "基础设置", "/TheRapyConfig", "TheRapyConfig"},
{"agency", "旅行社管理", "/travelAgency", "travelAgency"},
{"line", "线路管理", "/line", "line"},
{"base", "目的地管理", "/baseManagement", "TheBaseManagement"},
{"branchSelect", "分工会选择线路", "/lineFghSelect?mode=1", "lineFghSelect"},
{"schoolSelect", "校工会选择线路", "/lineXghSelect?mode=2", "lineXghSelect"},
{"overview", "线路选择查询", "/lineSelectionOverview", "lineSelectionOverview"},
{"cluster", "线路组团", "/lineCluster", "lineCluster"},
{"adjustment", "线路调剂", "/lineAdjustment", "line.adjustment"},
{"import", "参加人员导入", "/joinUserImport", "joinUser.import"},
{"branchAudit", "分工会审核", "/TheRapyAudit", "TheRapyAudit"},
{"travelAudit", "自由组团审核", "/TheRapyTravelAudit", "TheRapyTravelAudit"},
{"schoolAudit", "校工会审核", "/TheRapyXghAudit", "TheRapyXghAudit"},
{"branchQuery", "分工会信息查询", "/query", "TheRapyQuery"},
{"userQuery", "校工会信息查询", "/user/query", "TheRapyUserQuery"},
{"queryStatistics", "满意度统计", "/query/statics", "queryStatics"},
{"lineStatistics", "成团结果通知", "/statistics", "statistics"},
{"agencyStatistics", "人数统计", "/travelAgencyMonthlyStatistics", "travelAgencyMonthlyStatistics"},
{"unionStatistics", "分工会线路选择统计", "/statistics/unionLineNumberStatistics", "unionLineNumberStatistics"}
};
public static final List<String> MENU_SCREENS = List.of("agency", "line", "branchSelect", "schoolSelect",
"queryStatistics", "branchQuery", "userQuery", "overview", "lineStatistics", "config",
"unionStatistics", "agencyStatistics");
@Inject
private Dao dao;
@Inject
private SysMenuService sysMenuService;
@Inject
private SysRoleService sysRoleService;
@Inject
private SysUserService sysUserService;
public void init() {
Class<?>[] tables = {TheRapyRecuperationBaseManagement.class, TheRapyRecuperationCluster.class,
TheRapyRecuperationClusterMember.class, TheRapyRecuperationConfig.class,
TheRapyRecuperationEnroll.class, TheRapyRecuperationEnrollBed.class,
TheRapyRecuperationEnrollChangeRecord.class, TheRapyRecuperationEnrollCompanion.class,
TheRapyRecuperationLine.class, TheRapyRecuperationLineUnionSelect.class,
TheRapyRecuperationLot.class, TheRapyRecuperationTravelAgency.class,
TherapyAudit.class, TherapyAuditState.class};
for (Class<?> table : tables) dao.create(table, false);
createView("inclusive_therapy_v3_user", "SELECT u.*, u.arrivalAtSchoolDate AS schoolTime FROM vw_user u");
createView("inclusive_therapy_v3_union", "SELECT u.*, u.name AS unionname FROM sys_union u");
createView("inclusive_therapy_v3_unit", "SELECT u.* FROM sys_unit u");
Trans.exec(() -> {
seedStates();
seedVersion();
seedConfig();
seedMenus();
});
}
private void createView(String name, String select) {
org.nutz.dao.sql.Sql exists = Sqls.create("SELECT COUNT(1) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name=@name");
exists.setParam("name", name);
exists.setCallback(Sqls.callback.integer());
dao.execute(exists);
if (exists.getInt() == 0) dao.execute(Sqls.create("CREATE VIEW " + name + " AS " + select));
}
private void seedStates() {
int[] ids = {2710, 2715, 2720, 2725, 2730, 2735, 2750};
String[] names = {"待分工会审核", "分工会审核不通过", "待选择线路分工会审核", "选择线路分工会不通过",
"待校工会审核", "校工会审核不通过", "审核通过"};
for (int i = 0; i < ids.length; i++) {
if (dao.fetch(TherapyAuditState.class, ids[i]) != null) continue;
TherapyAuditState state = new TherapyAuditState();
state.setStateId(ids[i]);
state.setStateName(names[i]);
state.setStateColor(ids[i] == 2750 ? "#67c23a" : ids[i] % 10 == 5 ? "#f56c6c" : "#e6a23c");
dao.insert(state);
}
}
private void seedVersion() {
if (dao.fetch(Sys_config.class, "staffTherapyRecuperationVersion") != null) return;
Sys_config setting = new Sys_config();
setting.setConfigKey("staffTherapyRecuperationVersion");
setting.setConfigValue("zjnu");
setting.setNote("普惠疗休养独立子模块报名规则版本");
dao.insert(setting);
}
private void seedConfig() {
if (dao.count(TheRapyRecuperationConfig.class) != 0) return;
TheRapyRecuperationConfig config = new TheRapyRecuperationConfig();
config.setConfigName("普惠疗休养配置");
config.setIsSnLine(false);
config.setIsSwLine(false);
config.setTravelAudit(false);
config.setBedInfo(true);
config.setFamilyInfo(1);
config.setOutsideQuotaProportion(0D);
config.setUnionLineNumberConfigs(new ArrayList<>());
dao.insert(config);
}
private void seedMenus() {
Sys_menu existing = dao.fetch(Sys_menu.class, Cnd.where("href", "like", "/platform/recuperation%").and("platform", "=", "pc"));
Sys_module module = existing == null ? null : dao.fetch(Sys_module.class, existing.getModuleId());
if (module == null) module = dao.fetch(Sys_module.class, Cnd.where("name", "=", "职工福利").and("platform", "=", "pc"));
if (module == null) {
module = new Sys_module();
module.setName("职工福利");
module.setPlatform("pc");
module.setSortNum(50);
module.setFaIcon("fa fa-heart");
dao.insert(module);
}
Sys_menu root = addMenu(module.getId(), "", "普惠疗休养", ROOT, "inclusiveTherapyV3", "pc");
List<Sys_role> roles = dao.query(Sys_role.class, Cnd.where("disabled", "=", false));
for (String[] screen : SCREENS) {
Sys_menu menu = addMenu(module.getId(), root.getId(), screen[1], ROOT + screen[2],
"inclusiveTherapyV3." + screen[3], "pc");
int position = MENU_SCREENS.indexOf(screen[0]);
dao.update(Sys_menu.class, Chain.make("showit", position >= 0)
.add("location", position >= 0 ? position + 1 : MENU_SCREENS.size() + 1), Cnd.where("id", "=", menu.getId()));
for (Sys_role role : roles) {
String code = role.getCode();
boolean school = List.of("sysadmin", "superadmin", "A06", "SchoolUnionMemberAdmin", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "SCHOOL_UNION_MEMBER_ADMIN").contains(code);
boolean branch = List.of("H03", "H04", "H06", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN").contains(code)
&& Set.of("line", "base", "branchSelect", "branchAudit", "travelAudit", "branchQuery", "overview", "cluster", "adjustment").contains(screen[0]);
if (school || branch) {
grant(role.getId(), root.getId());
grant(role.getId(), menu.getId());
}
}
}
Sys_menu signup = addMenu(module.getId(), root.getId(), "疗休养报名", ROOT + "/mobile/index", "inclusiveTherapyV3.signup", "pc");
dao.update(Sys_menu.class, Chain.make("showit", false), Cnd.where("id", "=", signup.getId()));
Sys_module h5Module = dao.fetch(Sys_module.class, Cnd.where("name", "=", module.getName()).and("platform", "=", "h5"));
if (h5Module == null) {
h5Module = new Sys_module();
h5Module.setName(module.getName());
h5Module.setPlatform("h5");
h5Module.setSortNum(module.getSortNum());
h5Module.setFaIcon("fa fa-heart");
dao.insert(h5Module);
}
Sys_menu mobile = addMenu(h5Module.getId(), "", "普惠疗休养", ROOT + "/mobile/index", "inclusiveTherapyV3.mobile", "h5");
for (Sys_role role : roles) {
if (List.of("public", "PUBLIC", "MEMBER", "sysadmin", "superadmin", "SYSADMIN").contains(role.getCode())) {
grant(role.getId(), root.getId());
grant(role.getId(), signup.getId());
grant(role.getId(), mobile.getId());
}
}
sysMenuService.clearCache();
sysRoleService.clearCache();
sysUserService.clearCache();
}
private Sys_menu addMenu(String moduleId, String parentId, String name, String href, String permission, String platform) {
Sys_menu menu = dao.fetch(Sys_menu.class, Cnd.where("permission", "=", permission));
if (menu != null) return menu;
menu = new Sys_menu();
menu.setModuleId(moduleId);
menu.setName(name);
menu.setHref(href);
menu.setPermission(permission);
menu.setPlatform(platform);
menu.setType("menu");
menu.setTarget("_self");
menu.setIcon("fa fa-heart");
menu.setShowit(true);
menu.setDisabled(false);
sysMenuService.save(menu, parentId, Collections.emptyList());
return menu;
}
private void grant(String roleId, String menuId) {
if (dao.count("sys_role_menu", Cnd.where("roleId", "=", roleId).and("menuId", "=", menuId)) == 0) {
dao.insert("sys_role_menu", Chain.make("roleId", roleId).add("menuId", menuId));
}
}
}
@@ -0,0 +1,32 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.common;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
public class TherapyRecuperationCommon {
public static String getRemarkBySchoolTime(String schoolTime) {
if(StrUtil.isNotBlank(schoolTime)) {
String[] patterns = {
"yyyy-MM-dd",
"yyyy/MM/dd",
"yyyy-MM",
"yyyy/MM",
"yyyyMM",
"yyyyMMdd",
"yyyy年MM月dd日",
"yyyy年M月d日"
};
DateTime schoolDate = DateUtil.parse(schoolTime, patterns);
DateTime time = DateUtil.parse(DateUtil.thisYear() + "-07-01");
int compareResult = DateUtil.compare(schoolDate, time);
return compareResult >= 0 ? ("入校时间为:" + schoolTime + ",疗休养额度为1500。") : "";
} else {
return "";
}
}
}
@@ -0,0 +1,24 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import java.util.Date;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationJoinUserImportExcelMode
* @Description: 参加人员导入excel mode
* @Author zxc
* @Date 2022/6/14:11:10
* @Version V1.0
**/
@Data
public class TheRapyRecuperationJoinUserImportExcelMode {
@Excel(name = "工号")
private String loginName;
@Excel(name = "参加时间", format = "yyyyMMdd")
private Date takePartInTime;
}
@@ -0,0 +1,33 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.SelectEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationSignUpMode
* @Description: 线路创建模式
* @Author zxc
* @Date 2022/6/2:15:22
* @Version V1.0
**/
@AllArgsConstructor
@Getter
@SelectEnum
public enum TheRapyRecuperationLineCreateMode {
/**
* 分工会
*/
UNION(1, "分工会"),
/**
* 校工会
*/
SCHOOL(2, "校工会");
private final int value;
private final String label;
}
@@ -0,0 +1,31 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.SelectEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationProvinceType
* @Description: TODO
* @Author zxc
* @Date 2022/6/2:14:08
* @Version V1.0
**/
@AllArgsConstructor
@Getter
@SelectEnum
public enum TheRapyRecuperationProvinceType {
/**
* 省内
*/
provinceIn("省内线路", "省内"),
/**
* 省外
*/
provinceOut("省外线路", "省外");
private final String label;
private final String value;
}
@@ -0,0 +1,34 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.SelectEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationSignUpMode
* @Description: 报名模式
* @Author zxc
* @Date 2022/6/2:15:22
* @Version V1.0
**/
@AllArgsConstructor
@Getter
@SelectEnum
public enum TheRapyRecuperationSignUpMode {
/**
* 分工会模式
*/
UNION(1, "分工会组织", new String[]{"H04", "A06", "sysadmin"}),
/**
* 自由模式
*/
FREE(2, "校工会组织", new String[]{"A06", "sysadmin"});
private final int value;
private final String label;
private final String[] roles;
}
@@ -0,0 +1,39 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant;
/**
* 审核状态
*/
public interface TheRapyRecuperationState {
/**
* 待分工会审核
*/
Integer UNIT = 2710;
/**
* 分工会审核不通过
*/
Integer UNITFAIL = 2715;
/**
* 待选择线路分工会审核
*/
Integer LINEUNIT = 2720;
/**
* 选择线路分工会不通过
*/
Integer LINEUNITFAIL = 2725;
/**
* 待校工会审核
*/
Integer SCHOOL = 2730;
/**
* 校工会审核不通过
*/
Integer SCHOOLFAIL = 2735;
/**
* 审核通过
*/
Integer PASS = 2750;
}
@@ -0,0 +1,70 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.SelectEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationType
* @Description: 疗休养分类
* @Author zxc
* @Date 2022/6/2:14:02
* @Version V1.0
**/
@AllArgsConstructor
@Getter
@SelectEnum
public enum TheRapyRecuperationType {
/**
* 省内线路
*/
provinceInLine("省内线路", 0, TheRapyRecuperationProvinceType.provinceIn.getValue(), "/assets/staffbenefit/therapyRecuperation/img/in.png"),
/**
* 省外线路
*/
provinceOutLine("省外线路", 1, TheRapyRecuperationProvinceType.provinceOut.getValue(), "/assets/staffbenefit/therapyRecuperation/img/out.png"),
/**
* 省内旅行社
*/
provinceInTravelAgency("自由组团", 2, TheRapyRecuperationProvinceType.provinceIn.getValue(), "/assets/staffbenefit/therapyRecuperation/img/lxs.png"),
/**
* 酒店
*/
provinceInHotel("目的地疗休养", 3, TheRapyRecuperationProvinceType.provinceIn.getValue(), "/assets/staffbenefit/therapyRecuperation/img/lxs.png");
/**
* 学校自由组织
*/
// schoolFree("学校自由报名", 3, TheRapyRecuperationProvinceType.provinceIn.getValue(), "/assets/staffbenefit/therapyRecuperation/img/lxs.png");
private final String label;
private final int value;
private final String regionType;
/**
* 缓存状态map k->value v->TheRapyRecuperationProvinceType.value
*/
public static Map<Integer, String> typeMap = new HashMap<>();
/**
* 缓存状态map k->value v->TheRapyRecuperationProvinceType
*/
public static Map<Integer, TheRapyRecuperationType> objMap = new HashMap<>();
static {
TheRapyRecuperationType[] values = TheRapyRecuperationType.values();
for (TheRapyRecuperationType t : values) {
typeMap.put(t.getValue(), t.getRegionType());
objMap.put(t.getValue(), t);
}
}
private final String imgUrl;
}
@@ -0,0 +1,156 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.enums.SysFileEngineTypeEnum;
import com.budwk.app.sys.models.*;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.*;
import org.nutz.dao.*;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
@IocBean
@At("/platform/inclusiveTherapyV3/common")
@Ok("json:full")
public class TherapyCommonController {
@Inject
private Dao dao;
@Inject
private SysFileService sysFileService;
@At
@SaCheckLogin
public Result enumOptions(String enumName) throws ReflectiveOperationException {
if (!Set.of("TheRapyRecuperationType", "TheRapyRecuperationProvinceType", "TheRapyRecuperationSignUpMode",
"TheRapyRecuperationLineCreateMode").contains(enumName)) return Result.error("未知选项类型");
Class<?> type = Class.forName("com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant." + enumName);
List<NutMap> options = new ArrayList<>();
for (Object value : type.getEnumConstants()) {
NutMap option = NutMap.NEW().addv("label", type.getMethod("getLabel").invoke(value))
.addv("value", type.getMethod("getValue").invoke(value));
if ("TheRapyRecuperationType".equals(enumName)) {
option.addv("imgUrl", type.getMethod("getImgUrl").invoke(value));
option.addv("regionType", type.getMethod("getRegionType").invoke(value));
}
options.add(option);
}
return Result.success(options);
}
@At({"/unions", "/getUnion"})
@SaCheckLogin
public Result unions(Boolean isPermission) {
Cnd cnd = Cnd.NEW();
cnd.asc("unionCode");
if (Boolean.TRUE.equals(isPermission) && !TherapyContext.hasAnyRoles("sysadmin,A06")) {
cnd.and("id", "=", TherapyContext.getUnionId());
}
return Result.success(dao.query(TherapyUnion.class, cnd));
}
@At({"/units", "/getUnit", "/unionUnits", "/getUnitsByUnions"})
@SaCheckLogin
public Result units(String unionId, String unionid) {
String id = Strings.isBlank(unionId) ? unionid : unionId;
return Result.success(dao.query(Sys_unit.class, Cnd.NEW().andEX("unionId", "=", id).asc("location")));
}
@At
@SaCheckLogin
public Result dictOptions(String code) {
Sys_dict parent = dao.fetch(Sys_dict.class, Cnd.where("code", "=", code));
return Result.success(parent == null ? Collections.emptyList() : dao.query(Sys_dict.class,
Cnd.where("parentId", "=", parent.getId()).and("disabled", "=", false).asc("location")));
}
@At
@SaCheckLogin
public Result getValue(String key) {
if (!Set.of("recuperationVersion", "staffTherapyRecuperationVersion").contains(key)) return Result.error("未知配置");
Sys_config config = dao.fetch(Sys_config.class, "staffTherapyRecuperationVersion");
return Result.success((Object) (config == null ? "zjnu" : config.getConfigValue()));
}
@At
@SaCheckLogin
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result uploadFile(TempFile file) {
if (file == null) return Result.error("请选择文件");
String id = sysFileService.uploadReturnId(SysFileEngineTypeEnum.MINIO.getValue(), file);
Sys_file uploaded = sysFileService.fetch(id);
return Result.success(fileInfo(uploaded));
}
private NutMap fileInfo(Sys_file file) {
return NutMap.NEW().addv("id", file.getId()).addv("filename", file.getName())
.addv("filepath", file.getDownloadPath()).addv("url", file.getDownloadPath())
.addv("name", file.getName()).addv("downloadPath", file.getDownloadPath())
.addv("engine", file.getEngine()).addv("bucket", file.getBucket())
.addv("objName", file.getObjName()).addv("storagePath", file.getStoragePath())
.addv("suffix", file.getSuffix()).addv("sizeKb", file.getSizeKb()).addv("sizeInfo", file.getSizeInfo());
}
@At
@SaCheckLogin
public Result fileInfo(String[] ids) {
List<NutMap> result = new ArrayList<>();
if (ids != null) for (String id : ids) {
Sys_file file = sysFileService.fetch(id);
if (file != null) result.add(fileInfo(file));
}
return Result.success(result);
}
@At
@SaCheckLogin
@POST
public Result deleteFile(String id) {
if (Strings.isBlank(id)) return Result.error("缺少文件ID");
Sys_file file = sysFileService.fetch(id);
if (file == null) return Result.success();
if (!Objects.equals(file.getCreatedBy(), TherapyContext.getUserId())
&& !TherapyContext.hasAnyRoles("sysadmin,A06")) return Result.error("无权删除此文件");
sysFileService.delete(Collections.singletonList(id));
return Result.success();
}
@At({"/preview", "/download"})
@SaCheckLogin
@Ok("void")
public void preview(String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
if (id != null && id.startsWith("/platform/sys/file/download?id=")) {
id = id.substring(id.indexOf("?id=") + 4);
}
sysFileService.download(id, request, response);
}
@At
@SaCheckLogin
@Ok("void")
public void downloadTemplate(String filePath, String fileName, HttpServletResponse response) throws IOException {
String name = filePath == null ? "" : filePath.substring(filePath.lastIndexOf('/') + 1);
if (!Set.of("TravelAgencyImport.xlsx", "TravelEnrollImport.xlsx").contains(name)) {
response.sendError(404);
return;
}
try (InputStream in = getClass().getResourceAsStream("/static/assets/staffbenefit/therapyRecuperation/templates/" + name)) {
if (in == null) {
response.sendError(404);
return;
}
TherapyDownload.excelResponse(response, Strings.isBlank(fileName) ? name : fileName);
in.transferTo(response.getOutputStream());
}
}
}
@@ -0,0 +1,44 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.TherapyRecuperationModule;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@IocBean
@At("/platform/inclusiveTherapyV3")
public class TherapyWorkspaceController {
@At("")
@SaCheckLogin
@Ok("void")
public void index(String screen, HttpServletResponse response) throws IOException {
if (screen == null) {
for (String key : TherapyRecuperationModule.MENU_SCREENS) {
for (String[] candidate : TherapyRecuperationModule.SCREENS) {
if (candidate[0].equals(key) && StpUtil.hasPermission("inclusiveTherapyV3." + candidate[3])) {
screen = key;
break;
}
}
if (screen != null) break;
}
}
String url = TherapyRecuperationModule.ROOT + "/mobile/index";
if (screen != null && !"signup".equals(screen)) {
boolean found = false;
for (String[] candidate : TherapyRecuperationModule.SCREENS) {
if (candidate[0].equals(screen)) {
StpUtil.checkPermission("inclusiveTherapyV3." + candidate[3]);
url = TherapyRecuperationModule.ROOT + candidate[2];
found = true;
break;
}
}
if (!found) throw new IllegalArgumentException("未知的普惠疗休养页面");
}
response.sendRedirect(url);
}
}
@@ -0,0 +1,617 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.audit;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyMessage;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyAudit;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyAuditState;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyUser;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationAuditService;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.dao.util.cri.Static;
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.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.trans.Trans;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@IocBean
@At("/platform/inclusiveTherapyV3/TheRapyAudit")
@Ok("json:full")
public class TheRapyRecuperationAuditController {
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/audit/TheRapyAudit.html")
@SaCheckPermission("inclusiveTherapyV3.TheRapyAudit")
public void index() {
}
@Inject
private TherapyContext vi;
@Inject
private TheRapyRecuperationAuditService auditService;
@Inject
private Dao dao;
@Inject
private TherapyMessage msgApi;
@At
@ViReturn
@SaCheckLogin
public Object getXlByUnion(Integer state, String unionId, String regionalNature, String year, String endYear, Integer signUpMode, String agencyId) {
List<NutMap> xlByUnion = auditService.getXlByUnion(state, unionId, regionalNature, year, endYear, signUpMode, agencyId);
return xlByUnion;
}
@At
@ViReturn
@SaCheckLogin
public Object getXlByUnionAudit(String unionId, String regionalNature, String year, Integer signUpMode) {
Sql sql = Sqls.create("""
SELECT
line.id,
line.lineName,
line.regionalNature,
ts.id as selectId,
ts.playStartTime,
ts.playEndTime
FROM
inclusive_therapy_v3_line_union_select ts
LEFT JOIN inclusive_therapy_v3_line line ON line.id = ts.lineId
$condition
""");
Cnd cnd = Cnd.NEW();
if (TherapyContext.hasAnyRoles("sysadmin,A06")) {
cnd.andEX("ts.unionId", "=", unionId);
} else {
cnd.and("ts.unionId", "=", vi.getUnionId());
}
cnd.andEX("YEAR(ts.selectTime)", "=", year);
cnd.andEX("line.regionalNature", "=", regionalNature);
cnd.andEX("line.signUpMode", "=", signUpMode);
cnd.groupBy("line.id");
sql.setCondition(cnd);
return auditService.listMap(sql);
}
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyAudit")
public Object pageData(PageForm pageForm, String year, String unionId,
String unitId, String state, String takePartInLineId,
String isAudit, String regionalNature, String lotId,
String selectId) {
Sql sql = Sqls.create("""
SELECT
enroll.*,
lineu.lineId,
line.lineName,
line.regionalNature,
'教职工' userNature,
state.stateColor,
state.stateName,
CONCAT(DATE_FORMAT(lineu.playStartTime,'%m月%d日'),'-',DATE_FORMAT(lineu.playEndTime,'%m月%d日')) AS linePlayTime,
IF
( enroll.takePartInUnionId != enroll.selfUnionId, TRUE, FALSE ) isTransferIn,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) isFamily,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) num
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_line_union_select lineu ON lineu.id=enroll.takePartInLineId
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
LEFT JOIN inclusive_therapy_v3_audit_state state ON state.stateId = enroll.stateId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("line.regionalNature", "=", regionalNature);
cnd.andEX("YEAR(enroll.signingUptime)", "=", year);
cnd.andEX("enroll.selfUnionId", "=", unionId);
cnd.and("enroll.takePartInLineId", "is not", null);
cnd.andEX("enroll.selfUnitId", "=", unitId);
cnd.andEX("lineu.lineId", "=", takePartInLineId);
cnd.andEX("enroll.isNormal", "=", true);
cnd.andEX("lineu.signUpMode", "=", 1);
cnd.andEX("lineu.id", "=", selectId);
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
}
if (Strings.isNotBlank(state)) {
if (state.equals("1")) {
cnd.andEX("enroll.takePartInUnionId", "=", TherapyContext.getUnionId());
cnd.andEX("enroll.selfUnionId", "=", TherapyContext.getUnionId());
} else if (state.equals("2")) {
cnd.andEX("enroll.takePartInUnionId", "!=", TherapyContext.getUnionId());
cnd.andEX("enroll.selfUnionId", "=", TherapyContext.getUnionId());
} else if (state.equals("3")) {
cnd.andEX("enroll.selfUnionId", "!=", TherapyContext.getUnionId());
cnd.andEX("enroll.takePartInUnionId", "=", TherapyContext.getUnionId());
}
}
if (Strings.isNotBlank(isAudit)) {
if (isAudit.equals("true")) {
if (state.equals("2") || state.equals("1")) {
cnd.and(new Static("""
(( enroll.stateId = %s OR enroll.stateId = %s OR enroll.stateId = %s ) AND enroll.selfUnionId = '%s' )
""".formatted(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNIT, TheRapyRecuperationState.PASS, vi.getUnionId())));
} else if (state.equals("3")) {
cnd.and(new Static("""
((enroll.stateId = %s OR enroll.stateId=%s )AND enroll.takePartInUnionId='%s')
""".formatted(TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.PASS, vi.getUnionId())));
} else {
/*cnd.and(new Static("""
((( enroll.stateId = %s OR enroll.stateId = %s OR enroll.stateId = %s ) AND enroll.selfUnionId = '%s' )
OR
((enroll.stateId = %s OR enroll.stateId=%s )AND enroll.takePartInUnionId='%s'))
""".formatted(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNIT, TheRapyRecuperationState.PASS, vi.getUnionId(), TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.PASS, vi.getUnionId())));*/
cnd.and(new Static("""
((enroll.stateId = %s OR enroll.stateId=%s )AND enroll.takePartInUnionId='%s')
""".formatted(TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.PASS, vi.getUnionId())));
}
} else {
cnd.and(new Static("""
((enroll.stateId = %s AND enroll.selfUnionId='%s')OR (enroll.stateId = %s AND enroll.takePartInUnionId='%s'))
""".formatted(TheRapyRecuperationState.UNIT, vi.getUnionId(), TheRapyRecuperationState.LINEUNIT, vi.getUnionId())));
}
} else {
//屏蔽了本工会选择其他工会线路的人员
// cnd.and(Cnd.exps("enroll.selfUnionId", "=", vi.getUnionId()).or("enroll.takePartInUnionId", "=", vi.getUnionId()));
cnd.and("enroll.takePartInUnionId", "=", vi.getUnionId());
}
cnd.desc("enroll.signingUptime");
cnd.desc("enroll.unitName");
// cnd.having(Cnd.where("isTransferIn","=",0));
sql.setCondition(cnd);
return auditService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@At
@ViReturn
@SaCheckLogin
public Object findOne(String id) {
NutMap one = auditService.findOne(id);
return one;
}
/**
* 单个审核
*
* @param id
* @param flag
* @param isTransferIn
* @param auditOpinion
* @return
*/
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyAudit")
public Object doAudit(String id, boolean flag, Boolean adjustment, boolean isTransferIn, String auditOpinion) {
Trans.exec(() -> {
TheRapyRecuperationEnroll enroll = auditService.dao().fetch(TheRapyRecuperationEnroll.class, id);
TherapyAudit audit = new TherapyAudit();
audit.setAuditOpinion(auditOpinion);
audit.setAuditor(TherapyContext.getUserId());
audit.setLoginname((String) TherapyContext.getPrincipalProperty("loginname"));
audit.setUsername((String) TherapyContext.getPrincipalProperty("username"));
audit.setAuditTime(new Date());
audit.setAuditPass(flag);
TherapyAudit insert = auditService.insert(audit);
if (enroll.getStateId().equals(TheRapyRecuperationState.UNIT)) {
enroll.setSelfUnionAuditId(insert.getId());
} else {
enroll.setJoinLineUnionAuditId(insert.getId());
}
//如果通过
if (flag) {
//如果参加的线路分工会是自己分工会的,并且状态等于分工会审核
if (enroll.getTakePartInUnionId().equals(TherapyContext.getUnionId()) && enroll.getStateId().equals(TheRapyRecuperationState.UNIT)) {
enroll.setStateId(TheRapyRecuperationState.PASS);
} else {
//否则就是不是参加的自己分工会线路,就需要线路分工会审核
if (enroll.getStateId().equals(TheRapyRecuperationState.UNIT)) {
enroll.setStateId(TheRapyRecuperationState.LINEUNIT);
} else {
enroll.setStateId(TheRapyRecuperationState.PASS);
}
}
} else {
if (enroll.getStateId().equals(TheRapyRecuperationState.UNIT)) {
enroll.setStateId(TheRapyRecuperationState.UNITFAIL);
} else {
enroll.setStateId(TheRapyRecuperationState.LINEUNITFAIL);
}
}
auditService.updateIgnoreNull(enroll);
auditMsg(enroll.getStateId(), enroll.getLoginName(), adjustment, enroll.getTakePartInLineId());
if (adjustment) {
// enroll.setNormal(false);
auditService.dao().clear(TheRapyRecuperationEnroll.class, Cnd.where("id", "=", enroll.getId()));
}
});
return null;
}
/**
* 撤回
*
* @param id
* @return
*/
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyAudit")
public Object doRecall(String id) {
TheRapyRecuperationEnroll enroll = auditService.dao().fetch(TheRapyRecuperationEnroll.class, id);
TheRapyRecuperationLineUnionSelect unionSelect = auditService.dao().fetch(TheRapyRecuperationLineUnionSelect.class, Cnd.where("id", "=", enroll.getTakePartInLineId()));
if (enroll.getStateId().equals(TheRapyRecuperationState.UNITFAIL)) {
enroll.setStateId(TheRapyRecuperationState.UNIT);
enroll.setSelfUnionAuditId(null);
} else if (enroll.getStateId().equals(TheRapyRecuperationState.LINEUNIT)) {
enroll.setStateId(TheRapyRecuperationState.UNIT);
enroll.setSelfUnionAuditId(null);
} else if (enroll.getStateId().equals(TheRapyRecuperationState.LINEUNITFAIL)) {
enroll.setStateId(TheRapyRecuperationState.LINEUNIT);
enroll.setSelfUnionAuditId(null);
// } else if (enroll.getStateId().equals(TheRapyRecuperationState.PASS) && enroll.getSelfUnionId().equals(vi.getUnionId())) {
} else if (enroll.getStateId().equals(TheRapyRecuperationState.PASS) && enroll.getSelfUnionId().equals(unionSelect.getUnionId())) {
enroll.setStateId(TheRapyRecuperationState.UNIT);
enroll.setSelfUnionAuditId(null);
// } else if (enroll.getStateId().equals(TheRapyRecuperationState.PASS) && enroll.getTakePartInUnionId().equals(vi.getUnionId())) {
} else if (enroll.getStateId().equals(TheRapyRecuperationState.PASS) && enroll.getTakePartInUnionId().equals(unionSelect.getUnionId())) {
enroll.setStateId(TheRapyRecuperationState.LINEUNIT);
enroll.setJoinLineUnionAuditId(null);
}
auditService.update(enroll);
return null;
}
/**
* 批量审核
*
* @param ids
* @param auditOpinion
* @param flag
* @return
*/
@At
@ViReturn
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("inclusiveTherapyV3.TheRapyAudit")
public Object doOnekeyAudit(String[] ids, String auditOpinion, boolean flag, Boolean adjustment) {
TherapyAudit audit = new TherapyAudit();
audit.setAuditOpinion(auditOpinion);
audit.setAuditor(TherapyContext.getUserId());
audit.setLoginname((String) TherapyContext.getPrincipalProperty("loginname"));
audit.setUsername((String) TherapyContext.getPrincipalProperty("username"));
audit.setAuditTime(new Date());
audit.setAuditPass(flag);
TherapyAudit insert = auditService.insert(audit);
List<String> enrollIdList = new ArrayList<>();
for (String id : ids) {
TheRapyRecuperationEnroll enroll = auditService.dao().fetch(TheRapyRecuperationEnroll.class, id);
//如果状态等于分工会审核,并且参加的线路分工会也是自己的工会,就代表自己参加自己的工会线路
if (enroll.getStateId().equals(TheRapyRecuperationState.UNIT) && enroll.getTakePartInUnionId().equals(vi.getUnionId())) {
enroll.setStateId(flag ? TheRapyRecuperationState.PASS : TheRapyRecuperationState.UNITFAIL);
enroll.setSelfUnionAuditId(insert.getId());
//如果状态等于分工会审核,并且参加的线路分工会不是自己的工会,就代表参加的不是自己工会的线路,就需要线路分工会审核
} else if (enroll.getStateId().equals(TheRapyRecuperationState.UNIT) && !enroll.getTakePartInUnionId().equals(vi.getUnionId())) {
enroll.setStateId(flag ? TheRapyRecuperationState.LINEUNIT : TheRapyRecuperationState.UNITFAIL);
enroll.setSelfUnionAuditId(insert.getId());
} else {
enroll.setStateId(flag ? TheRapyRecuperationState.PASS : TheRapyRecuperationState.LINEUNITFAIL);
enroll.setJoinLineUnionAuditId(insert.getId());
}
if (adjustment) {
// enroll.setNormal(false);
enrollIdList.add(id);
}
auditService.updateIgnoreNull(enroll);
auditMsg(enroll.getStateId(), enroll.getLoginName(), adjustment, enroll.getTakePartInLineId());
}
auditService.dao().clear(TheRapyRecuperationEnroll.class, Cnd.where("id", "in", enrollIdList));
return null;
}
/**
* 审核发短信
*
* @param stateId
* @param loginName
* @param takePartInLineId
*/
private void auditMsg(Integer stateId, String loginName, Boolean adjustment, String takePartInLineId) {
TherapyUser user = auditService.dao().fetch(TherapyUser.class, Cnd.where("loginname", "=", loginName));
TheRapyRecuperationLineUnionSelect unionSelect = auditService.dao().fetch(TheRapyRecuperationLineUnionSelect.class, Cnd.where("id", "=", takePartInLineId));
TheRapyRecuperationLine theRapyRecuperationLine = auditService.dao().fetch(TheRapyRecuperationLine.class, Cnd.where("id", "=", unionSelect.getLineId()));
TherapyAuditState auditState = auditService.dao().fetch(TherapyAuditState.class, Cnd.where("stateId", "=", stateId));
String content = "【智慧工会】%s老师您好,您报名的%s线路因报名人数不足已取消,请尽快进入智慧工会重新选择线路。"
.formatted(user.getUsername(), theRapyRecuperationLine.getLineName());
List list = List.of(Map.of("type", "User", "userId", user.getLoginname(), "name", user.getUsername()));
if (stateId.equals(TheRapyRecuperationState.PASS)) {
content = "【智慧工会】%s老师您好,您报名的%s线路已组团成功,请按约定出行。"
.formatted(user.getUsername(), theRapyRecuperationLine.getLineName());
}
//msgApi.sendMsg(content, list, "疗休养", " IntelligenceMode", MsgApi.sendMode.normal.name());
}
/**
* 查询报名人员的工会有哪些,并分组
*
* @return
*/
@At
@ViReturn
@SaCheckLogin
public Object getBmUserUnion() {
Sql sql = Sqls.create("""
SELECT
unionName unionname,
selfUnionId id
FROM
`inclusive_therapy_v3_enroll`
$condition
""");
Cnd cnd = Cnd.NEW();
if (!TherapyContext.hasAnyRoles("sysadmin,H06")) {
cnd.and("takePartInLineId", "IS NOT", null);
cnd.and("takePartInLineId", "!=", "");
cnd.and(Cnd.exps("takePartInUnionId", "=", vi.getUnionId()).or("selfUnionId", "=", vi.getUnionId()));
//cnd.and("selfUnionId", "=", vi.getUnionId());
}
cnd.groupBy("selfUnionId");
sql.setCondition(cnd);
List<NutMap> unionList = auditService.listMap(sql);
return unionList;
}
/**
* 查询报名数量
*
* @return
*/
@At
@ViReturn
@SaCheckLogin
public Object getApplyNumAudit(String takePartInLineId, String mode, String isAudit, Integer year, String selectId) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
String unionId = TherapyContext.getUnionId();
Sql sql = Sqls.create("""
SELECT
COUNT(1) as signUpNum,
$val as familyNumber
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_line_union_select lineu ON lineu.id = enroll.takePartInLineId
$condition
""");
String val = "";
if (config.getFamilyInfo() == 1) {
val = "IFNULL(sum(familyNumber),0)";
} else {
val = "IFNULL((select count(1) from inclusive_therapy_v3_enroll_companion where trreId = enroll.id),0)";
}
sql.setVar("val", val);
Sql sql2 = sql;
Sql sql3 = sql;
Sql sql4 = sql;
if (StrUtil.isBlank(isAudit)) {
//本公会人员(自己线路)
Cnd cnd1 = Cnd.NEW();
cnd1.andEX("takePartInUnionId", "=", unionId)
.and("selfUnionId", "=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.andEX("signUpMode", "=", 1)
.andEX("lineu.id", "=", selectId);
if (StrUtil.isNotBlank(mode)) {
cnd1.and("stateId", "=", TheRapyRecuperationState.PASS);
}
sql.setCondition(cnd1);
NutMap map = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map());
int count1 = Integer.parseInt(String.valueOf(map.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map.getOrDefault("familyNumber", 0)));
//本工会人员(其他路线)
Cnd cnd2 = Cnd.NEW();
cnd2.and("takePartInUnionId", "!=", unionId)
.and("selfUnionId", "=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.andEX("signUpMode", "=", 1)
.andEX("lineu.id", "=", selectId);
if (StrUtil.isNotBlank(mode)) {
cnd2.and("stateId", "=", TheRapyRecuperationState.PASS);
}
sql2.setCondition(cnd2);
NutMap map2 = (NutMap) Daos.query(dao, sql2.toString(), Sqls.callback.map());
int count2 = Integer.parseInt(String.valueOf(map2.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map2.getOrDefault("familyNumber", 0)));
//其他工会人员(选我线路)
Cnd cnd3 = Cnd.NEW();
cnd3.and("takePartInUnionId", "=", unionId)
.and("selfUnionId", "!=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.andEX("signUpMode", "=", 1)
.andEX("lineu.id", "=", selectId);
if (StrUtil.isNotBlank(mode)) {
cnd3.and("stateId", "=", TheRapyRecuperationState.PASS);
}
sql3.setCondition(cnd3);
NutMap map3 = (NutMap) Daos.query(dao, sql3.toString(), Sqls.callback.map());
int count3 = Integer.parseInt(String.valueOf(map3.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map3.getOrDefault("familyNumber", 0)));
//选择校工会线路人员
Cnd cnd4 = Cnd.NEW();
cnd4.and("selfUnionId", "=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.andEX("signUpMode", "=", 2)
.andEX("lineu.id", "=", selectId);
if (StrUtil.isNotBlank(mode)) {
cnd4.and("stateId", "=", TheRapyRecuperationState.PASS);
}
sql4.setCondition(cnd4);
NutMap map4 = (NutMap) Daos.query(dao, sql4.toString(), Sqls.callback.map());
int count4 = Integer.parseInt(String.valueOf(map4.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map4.getOrDefault("familyNumber", 0)));
return Map.of("count1", count1, "count2", count2, "count3", count3, "count4", count4);
}
if ("true".equals(isAudit)) {
//本公会人员(自己线路)
Cnd cnd1 = Cnd.NEW();
cnd1.and("takePartInUnionId", "=", unionId)
.and("selfUnionId", "=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.and("stateId", ">", TheRapyRecuperationState.UNIT)
.andEX("signUpMode", "=", 1);
sql.setCondition(cnd1);
NutMap map = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map());
int count1 = Integer.parseInt(String.valueOf(map.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map.getOrDefault("familyNumber", 0)));
//本工会人员(其他路线)
// Cnd cnd2 = Cnd.NEW();
// cnd2.and("takePartInUnionId", "!=", unionId)
// .and("selfUnionId", "=", unionId)
// .and("isNormal", "=", true)
// .and("takePartInLineId", "is not", null)
// .andEX("YEAR(signingUptime)", "=", year)
// .and("stateId", ">", TheRapyRecuperationState.UNIT)
// .andEX("signUpMode", "=", 1);
// sql2.setCondition(cnd2);
// int count2 = auditService.count(sql2);
//其他工会人员(选我线路)
Cnd cnd3 = Cnd.NEW();
cnd3.and("takePartInUnionId", "=", unionId)
.and("selfUnionId", "!=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.and("stateId", ">", TheRapyRecuperationState.LINEUNIT)
.andEX("signUpMode", "=", 1);
sql3.setCondition(cnd3);
NutMap map3 = (NutMap) Daos.query(dao, sql3.toString(), Sqls.callback.map());
int count3 = Integer.parseInt(String.valueOf(map3.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map3.getOrDefault("familyNumber", 0)));
// return Map.of("count1", count1, "count2", count2, "count3", count3);
return Map.of("count1", count1, "count3", count3);
}
if ("false".equals(isAudit)) {
//本公会人员(自己线路)
Cnd cnd1 = Cnd.NEW();
cnd1.and("takePartInUnionId", "=", unionId)
.and("selfUnionId", "=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.and("stateId", "=", TheRapyRecuperationState.UNIT)
.andEX("signUpMode", "=", 1);
sql.setCondition(cnd1);
NutMap map = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map());
int count1 = Integer.parseInt(String.valueOf(map.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map.getOrDefault("familyNumber", 0)));
//本工会人员(其他路线)
// Cnd cnd2 = Cnd.NEW();
// cnd2.and("takePartInUnionId", "!=", unionId)
// .and("selfUnionId", "=", unionId)
// .and("isNormal", "=", true)
// .and("takePartInLineId", "is not", null)
// .andEX("YEAR(signingUptime)", "=", year)
// .and("stateId", "=", TheRapyRecuperationState.UNIT)
// .andEX("signUpMode", "=", 1);
// sql2.setCondition(cnd2);
// int count2 = auditService.count(sql2);
//其他工会人员(选我线路)
Cnd cnd3 = Cnd.NEW();
cnd3.and("takePartInUnionId", "=", unionId)
.and("selfUnionId", "!=", unionId)
.and("isNormal", "=", true)
.and("takePartInLineId", "is not", null)
.andEX("lineu.lineId", "=", takePartInLineId)
.andEX("YEAR(signingUptime)", "=", year)
.and("stateId", "=", TheRapyRecuperationState.LINEUNIT)
.andEX("signUpMode", "=", 1);
sql3.setCondition(cnd3);
NutMap map3 = (NutMap) Daos.query(dao, sql3.toString(), Sqls.callback.map());
int count3 = Integer.parseInt(String.valueOf(map3.getOrDefault("signUpNum", 0))) + Integer.parseInt(String.valueOf(map3.getOrDefault("familyNumber", 0)));
// return Map.of("count1", count1, "count2", count2, "count3", count3);
return Map.of("count1", count1, "count3", count3);
}
return null;
}
}
@@ -0,0 +1,237 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.audit;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyAudit;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationAuditService;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.dao.util.cri.Static;
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.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.trans.Trans;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
* @Author zzr
* @name:TheRapyRecuperationTranlAuditController
* @Date 2024/5/22 9:59
* @注释
*/
@IocBean
@At("/platform/inclusiveTherapyV3/TheRapyTravelAudit")
@Ok("json:full")
public class TheRapyRecuperationTravelAuditController {
@Inject
private TheRapyRecuperationAuditService theRapyRecuperationAuditService;
@Inject
private TherapyContext vi;
@Inject
private Dao dao;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/audit/TheRapyTravelAudit.html")
@SaCheckPermission("inclusiveTherapyV3.TheRapyTravelAudit")
public void index() {
}
@At
@ViReturn
public Object pageData(PageForm pageForm,
@Param(value = "agencyId") String agencyId,
@Param(value = "year") String year,
@Param(value = "unionId") String unionId,
@Param(value = "unitId") String unitId,
@Param(value = "isAudit") String isAudit){
Sql sql = Sqls.create("""
SELECT
enroll.*,
state.stateColor,
state.stateName,
ta.travelAgencyName,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) isFamily
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_audit_state state ON state.stateId = enroll.stateId
left join inclusive_therapy_v3_travel_agency ta on ta.id = enroll.takePartInTravelAgencyId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(enroll.signingUptime)", "=", year);
cnd.and("enroll.selfUnionId", "=", StrUtil.isBlank(unionId) ? TherapyContext.getUnionId() : unionId);
cnd.and("enroll.takePartInTravelAgencyId", "is not", null);
cnd.and("enroll.takePartInTravelAgencyId", "!=", "");
cnd.andEX("enroll.selfUnitId", "=", unitId);
cnd.andEX("enroll.isNormal", "=", true);
cnd.andEX("enroll.takePartInTravelAgencyId", "=", agencyId);
if (isAudit.equals("true")) {
cnd.and("enroll.stateId", ">", TheRapyRecuperationState.UNIT);
} else if (isAudit.equals("false")){
cnd.and("enroll.stateId", "=", TheRapyRecuperationState.UNIT);
}
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
}
cnd.desc("enroll.signingUptime");
cnd.desc("enroll.unitName");
sql.setCondition(cnd);
return theRapyRecuperationAuditService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@At
@ViReturn
@SaCheckLogin
public Object getBmUserUnion() {
Sql sql = Sqls.create("""
SELECT
unionName unionname,
selfUnionId id
FROM
`inclusive_therapy_v3_enroll`
$condition
""");
Cnd cnd = Cnd.NEW();
if (!TherapyContext.hasAnyRoles("sysadmin,H06")) {
cnd.and("takePartInTravelAgencyId", "IS NOT", null);
cnd.and("takePartInTravelAgencyId", "!=", "");
cnd.and("selfUnionId", "=", vi.getUnionId());
}
cnd.groupBy("selfUnionId");
sql.setCondition(cnd);
List<NutMap> unionList = theRapyRecuperationAuditService.listMap(sql);
return unionList;
}
@At
@ViReturn
@SaCheckLogin
public Object getApplyNumAudit(String agencyId, String isAudit, Integer year) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
String unionId = TherapyContext.getUnionId();
Sql sql = Sqls.create("""
SELECT
count(1) as signUpNum,
$val as familyNumber
FROM
`inclusive_therapy_v3_enroll` enroll
$condition
""");
String val = "";
if(config.getFamilyInfo() == 1) {
val = "IFNULL(sum(familyNumber),0)";
} else {
val = "IFNULL((select count(1) from inclusive_therapy_v3_enroll_companion where trreId = enroll.id),0)";
}
sql.setVar("val", val);
Cnd cnd = Cnd.NEW();
if (isAudit.equals("true")) {
cnd.and("enroll.stateId", ">", TheRapyRecuperationState.UNIT);
} else if (isAudit.equals("false")){
cnd.and("enroll.stateId", "=", TheRapyRecuperationState.UNIT);
}
cnd.andEX("takePartInTravelAgencyId", "=", agencyId);
cnd.andEX("year(signingUptime)", "=", year);
cnd.and("takePartInTravelAgencyId", "is not", null);
cnd.and("takePartInTravelAgencyId", "!=", "");
cnd.and("selfUnionId", "=", unionId);
cnd.andEX("enroll.takePartInTravelAgencyId", "=", agencyId);
sql.setCondition(cnd);
NutMap map = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map());
int count1 = Integer.parseInt(String.valueOf(map.getOrDefault("signUpNum",0)))
+ Integer.parseInt(String.valueOf(map.getOrDefault("familyNumber",0)));
return Map.of("count1", count1);
}
@At
@ViReturn
@SaCheckLogin
public Object doAudit(String id, boolean flag,Boolean adjustment, String auditOpinion) {
Trans.exec(() -> {
TheRapyRecuperationEnroll enroll = dao.fetch(TheRapyRecuperationEnroll.class, id);
TherapyAudit audit = new TherapyAudit();
audit.setAuditOpinion(auditOpinion);
audit.setAuditor(TherapyContext.getUserId());
audit.setLoginname((String) TherapyContext.getPrincipalProperty("loginname"));
audit.setUsername((String) TherapyContext.getPrincipalProperty("username"));
audit.setAuditTime(new Date());
audit.setAuditPass(flag);
TherapyAudit insert = dao.insert(audit);
enroll.setSelfUnionAuditId(insert.getId());
enroll.setStateId(flag ? TheRapyRecuperationState.PASS : TheRapyRecuperationState.UNITFAIL);
dao.updateIgnoreNull(enroll);
// auditMsg(enroll.getStateId(), enroll.getLoginName(),adjustment, enroll.getTakePartInLineId());
if (adjustment){
// enroll.setNormal(false);
dao.clear(TheRapyRecuperationEnroll.class,Cnd.where("id","=",enroll.getId()));
}
});
return null;
}
@At
@ViReturn
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
public Object doOnekeyAudit(String[] ids, String auditOpinion, boolean flag, Boolean adjustment) {
TherapyAudit audit = new TherapyAudit();
audit.setAuditOpinion(auditOpinion);
audit.setAuditor(TherapyContext.getUserId());
audit.setLoginname((String) TherapyContext.getPrincipalProperty("loginname"));
audit.setUsername((String) TherapyContext.getPrincipalProperty("username"));
audit.setAuditTime(new Date());
audit.setAuditPass(flag);
TherapyAudit insert = dao.insert(audit);
List<String> enrollIdList = new ArrayList<>();
for (String id : ids) {
TheRapyRecuperationEnroll enroll = dao.fetch(TheRapyRecuperationEnroll.class, id);
enroll.setSelfUnionAuditId(insert.getId());
enroll.setStateId(flag ? TheRapyRecuperationState.PASS : TheRapyRecuperationState.UNITFAIL);
dao.updateIgnoreNull(enroll);
//auditMsg(enroll.getStateId(), enroll.getLoginName(),adjustment, enroll.getTakePartInLineId());
}
dao.clear(TheRapyRecuperationEnroll.class,Cnd.where("id","in",enrollIdList));
return null;
}
@At
@ViReturn
@SaCheckLogin
public Object doRecall(String id) {
TheRapyRecuperationEnroll enroll = dao.fetch(TheRapyRecuperationEnroll.class, id);
enroll.setStateId(TheRapyRecuperationState.UNIT);
enroll.setSelfUnionAuditId(null);
dao.update(enroll);
return null;
}
}
@@ -0,0 +1,355 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.audit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyMessage;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyAudit;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.*;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationAuditService;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.trans.Trans;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@IocBean
@At("/platform/inclusiveTherapyV3/TheRapyXghAudit")
@Ok("json:full")
public class TheRapyRecuperationXghAuditController {
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/audit/TheRapyXghAudit.html")
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public void index() {
}
@Inject
private TherapyContext vi;
@Inject
private TheRapyRecuperationAuditService auditService;
@Inject
private Dao dao;
@Inject("refer:staffTherapyDataService")
private BaseService baseService;
@Inject("refer:staffTherapyDataService")
private TherapyService viService;
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public Object pageData(PageForm pageForm, String year, String unionId,
String unitId, String state, String takePartInLineId,
String isAudit, String regionalNature, String lotId,
String selectId) {
Sql sql = Sqls.create("""
SELECT
enroll.*,
line.lineName,
line.id as lineId,
line.regionalNature,
'教职工' userNature,
state.stateColor,
state.stateName,
CONCAT(DATE_FORMAT(rs.playStartTime,'%m月%d日'),'-',DATE_FORMAT(rs.playEndTime,'%m月%d日')) AS linePlayTime,
IF
( enroll.takePartInUnionId != enroll.selfUnionId, TRUE, FALSE ) isTransferIn,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) isFamily,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) num
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN `inclusive_therapy_v3_line_union_select` rs ON rs.id = enroll.takePartInLineId
LEFT JOIN `inclusive_therapy_v3_line` line on line.id=rs.lineId
LEFT JOIN inclusive_therapy_v3_audit_state state ON state.stateId = enroll.stateId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("line.regionalNature", "=", regionalNature);
cnd.andEX("YEAR(enroll.signingUptime)", "=", year);
cnd.andEX("enroll.selfUnionId", "=", unionId);
cnd.and("enroll.takePartInLineId", "is not", null);
cnd.andEX("enroll.selfUnitId", "=", unitId);
cnd.andEX("line.id", "=", takePartInLineId);
cnd.andEX("enroll.isNormal", "=", true);
cnd.andEX("rs.signUpMode", "=", "2");
cnd.andEX("rs.id", "=", selectId);
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
}
if (Strings.isNotBlank(isAudit)) {
if (isAudit.equals("true")) {
cnd.and(new Static("enroll.stateId = %s".formatted(TheRapyRecuperationState.PASS)));
} else {
cnd.and(new Static("enroll.stateId = %s".formatted(TheRapyRecuperationState.SCHOOL)));
}
} else {
cnd.and(new Static("( enroll.stateId = %s OR enroll.stateId = %s OR enroll.stateId = %s)".
formatted(TheRapyRecuperationState.SCHOOL, TheRapyRecuperationState.SCHOOLFAIL, TheRapyRecuperationState.PASS)));
}
cnd.desc("enroll.signingUptime");
cnd.desc("enroll.unitName");
sql.setCondition(cnd);
return auditService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public Object getLineNumber(PageForm pageForm, String year, String unionId,
String unitId, String state, String takePartInLineId,
String isAudit, String regionalNature, String lotId, String selectId) {
Sql sql = Sqls.create("""
SELECT
enroll.*,
line.lineName,
line.id as lineId,
line.regionalNature,
'教职工' userNature,
state.stateColor,
state.stateName,
IF
( enroll.takePartInUnionId != enroll.selfUnionId, TRUE, FALSE ) isTransferIn,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) isFamily,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) num
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN `inclusive_therapy_v3_line_union_select` rs ON rs.id = enroll.takePartInLineId
LEFT JOIN `inclusive_therapy_v3_line` line on line.id=rs.lineId
LEFT JOIN inclusive_therapy_v3_audit_state state ON state.stateId = enroll.stateId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("line.regionalNature", "=", regionalNature);
cnd.andEX("YEAR(enroll.signingUptime)", "=", year);
cnd.andEX("enroll.selfUnionId", "=", unionId);
cnd.and("enroll.takePartInLineId", "is not", null);
cnd.andEX("enroll.selfUnitId", "=", unitId);
cnd.andEX("line.id", "=", takePartInLineId);
cnd.andEX("enroll.isNormal", "=", true);
cnd.andEX("rs.signUpMode", "=", "2");
cnd.andEX("rs.id", "=", selectId);
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
}
if (Strings.isNotBlank(isAudit)) {
if (isAudit.equals("true")) {
cnd.and(new Static("enroll.stateId = %s".formatted(TheRapyRecuperationState.PASS)));
} else {
cnd.and(new Static("enroll.stateId = %s".formatted(TheRapyRecuperationState.SCHOOL)));
}
} else {
cnd.and(new Static("( enroll.stateId = %s OR enroll.stateId = %s OR enroll.stateId = %s)".
formatted(TheRapyRecuperationState.SCHOOL, TheRapyRecuperationState.SCHOOLFAIL, TheRapyRecuperationState.PASS)));
}
cnd.desc("enroll.signingUptime");
cnd.desc("enroll.unitName");
sql.setCondition(cnd);
List<NutMap> nutMaps = auditService.listMap(sql);
int familyNumber = nutMaps.stream().filter(o -> StrUtil.isNotBlank(o.getString("familyNumber"))).mapToInt(o -> o.getInt("familyNumber")).sum();
return familyNumber + nutMaps.size();
}
/**
* 单个审核
*
* @param id
* @param flag
* @param isTransferIn
* @param auditOpinion
* @return
*/
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public Object doAudit(String id, boolean flag, boolean isTransferIn, String auditOpinion, Boolean adjustment) {
Trans.exec(() -> {
TheRapyRecuperationEnroll enroll = auditService.dao().fetch(TheRapyRecuperationEnroll.class, id);
TherapyAudit audit = new TherapyAudit();
audit.setAuditOpinion(auditOpinion);
audit.setAuditor(TherapyContext.getUserId());
audit.setLoginname((String) TherapyContext.getPrincipalProperty("loginname"));
audit.setUsername((String) TherapyContext.getPrincipalProperty("username"));
audit.setAuditTime(new Date());
audit.setAuditPass(flag);
TherapyAudit insert = auditService.insert(audit);
enroll.setSchoolUnionAuditId(insert.getId());
//如果通过
if (flag) {
enroll.setStateId(TheRapyRecuperationState.PASS);
} else {//审核不通过
enroll.setStateId(TheRapyRecuperationState.SCHOOLFAIL);
}
auditService.updateIgnoreNull(enroll);
auditService.schoolAudit(enroll.getStateId(), enroll.getLoginName(), adjustment, enroll.getTakePartInLineId());
if (adjustment) {
// enroll.setNormal(false);
auditService.dao().clear(TheRapyRecuperationEnroll.class, Cnd.where("id", "=", enroll.getId()));
}
});
return null;
}
/**
* 撤回
*
* @param id
* @return
*/
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public Object doRecall(String id) {
TheRapyRecuperationEnroll enroll = auditService.dao().fetch(TheRapyRecuperationEnroll.class, id);
enroll.setStateId(TheRapyRecuperationState.SCHOOL);
enroll.setSchoolUnionAuditId(null);
auditService.update(enroll);
return null;
}
/**
* 批量审核
*
* @param ids
* @param auditOpinion
* @param flag
* @return
*/
@At
@ViReturn
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public Object doOnekeyAudit(String[] ids, String auditOpinion, boolean flag, Boolean adjustment) {
TherapyAudit audit = new TherapyAudit();
audit.setAuditOpinion(auditOpinion);
audit.setAuditor(TherapyContext.getUserId());
audit.setLoginname((String) TherapyContext.getPrincipalProperty("loginname"));
audit.setUsername((String) TherapyContext.getPrincipalProperty("username"));
audit.setAuditTime(new Date());
audit.setAuditPass(flag);
TherapyAudit insert = auditService.insert(audit);
//List<TheRapyRecuperationEnroll> enrollList = auditService.dao().query(TheRapyRecuperationEnroll.class, Cnd.where("id", "in", ids));
List<String> enrollIdList = new ArrayList<>();
for (String id : ids) {
TheRapyRecuperationEnroll enroll = auditService.dao().fetch(TheRapyRecuperationEnroll.class, id);
enroll.setStateId(flag ? TheRapyRecuperationState.PASS : TheRapyRecuperationState.SCHOOLFAIL);
enroll.setSchoolUnionAuditId(insert.getId());
auditService.updateIgnoreNull(enroll);
auditService.schoolAudit(enroll.getStateId(), enroll.getLoginName(), adjustment, enroll.getTakePartInLineId());
if (adjustment) {
// enroll.setNormal(false);
enrollIdList.add(id);
}
}
auditService.dao().clear(TheRapyRecuperationEnroll.class, Cnd.where("id", "in", enrollIdList));
return null;
}
/**
* 校工会选择线路查询
*
* @return
*/
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.TheRapyXghAudit")
public Object getXghLine() {
Sql sql = Sqls.create("""
SELECT
line.*,
un.unionname
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_line_union_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
LEFT JOIN inclusive_therapy_v3_union un ON un.id = enroll.takePartInUnionId
where line.signUpMode='2' and line.createMode='2'
group by line.id
""");
return baseService.listMap(sql);
}
@At
@ViReturn
@SaCheckLogin
public Object getLinePlayTimeByLineId(String lineId,
@Param(value = "signUpMode") Integer signUpMode,
@Param(value = "year") Integer year,
@Param(value = "startYear")Integer startYear,
@Param(value = "endYear")Integer endYear,
@Param(value = "flag") Boolean flag) {
Cnd cnd = Cnd.NEW();
cnd.and("lineId", "=", lineId);
if (flag == null || !flag){
cnd.andEX("signUpMode", "=", signUpMode);
cnd.and("YEAR(selectTime)", "=", year);
} else {
cnd.and("YEAR(selectTime)", ">=", startYear);
cnd.and("YEAR(selectTime)", "<=", endYear);
}
List<TheRapyRecuperationLineUnionSelect> query = dao.query(TheRapyRecuperationLineUnionSelect.class, cnd);
//.and("selectUserId", "=", ShiroUtil.getUserId()).and("unionId", "=", Vi.getUnionId()));
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
List<NutMap> nutMaps = new ArrayList<>();
query.forEach(v -> {
String startTime = DateUtil.formatChineseDate(v.getPlayStartTime(), false, false).substring(5);
String endTime = DateUtil.formatChineseDate(v.getPlayEndTime(), false, false).substring(5);
NutMap map = new NutMap();
List<TheRapyRecuperationEnroll> enrollList = dao.query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "=", v.getId())
.and("isNormal", "=", true)
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
int hasSignNumber;
if (config.getFamilyInfo() == 1) {
int sum = enrollList.stream().mapToInt(TheRapyRecuperationEnroll::getFamilyNumber).sum();
hasSignNumber = enrollList.size() + sum;
} else {
List<String> list = enrollList.stream().map(TheRapyRecuperationEnroll::getId).collect(Collectors.toList());
List<TheRapyRecuperationEnrollCompanion> companions = dao.query(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", list));
hasSignNumber = enrollList.size() + companions.size();
}
map.setv("times", startTime + "-" + endTime + "(报名人数:" + hasSignNumber + ",其中家属:" + (hasSignNumber - enrollList.size()) + "人)");
map.setv("selectId", v.getId());
nutMaps.add(map);
});
return nutMaps;
}
}
@@ -0,0 +1,360 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.baseManage;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.dao.CndPlus;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationBaseManagement;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLot;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.baseManage.TheRapyRecuperationBaseManagerService;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.stream.Collectors;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.baseManage.TheBaseManagerController
* @Description: 疗休养基地管理
* @Author zzr
* @Date 2023/6/5
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/baseManagement")
@Ok("json:full")
public class TheRapyRecuperationBaseManagerController {
@Inject("refer:staffTherapyDataService")
private BaseService baseService;
@Inject
private Dao dao;
@Inject
private TheRapyRecuperationBaseManagerService theRapyRecuperationBaseManagerService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/baseManage/baseManagement.html")
@SaCheckPermission("inclusiveTherapyV3.TheBaseManagement")
public void index() {
}
/**
* 分页展示
*
* @param pageForm 分页对象
* @param year 查询参数
* @param lotId 标段时间
* @param baseName 基地名
* @param unionId 分工会
* @param travelAgencyId 旅行社
* @param regionalNature 活动范围
* @return {@link Object}
*/
@At
@POST
@Ok("json:full")
@ViReturn
@SaCheckRole(value = {"sysadmin", "A06", "H04", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN"}, mode = SaMode.OR)
public Object pageData(PageForm pageForm, Integer year, String lotId, String baseName, String unionId, String travelAgencyId, String regionalNature) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
tb.id,
tb.sortNumber,
tb.baseName,
tb.regionalNature,
tb.year,
tb.isDisabled,
tb.lotId,
tb.createUnionId,
tb.signUpStartTime,
tb.signUpEndTime,
tb.changeEndTime,
tb.createMode,
tb.activityStartTime,
tb.activityEndTime,
tb.files,
tb.baseContactPerson,
tb.baseContactNumber,
tb.files AS fileId,
gh.unionname createUnionName,
u.username createUserName,
ta.travelAgencyName,
ta.contact,
ta.contactMobileNumber,
ta.officialWebsite
FROM
`inclusive_therapy_v3_base_management` tb
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = tb.travelAgencyId
LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = tb.createUnionid
LEFT JOIN inclusive_therapy_v3_user u ON u.id = tb.opBy
$condition
""");
cnd.where().andEX("tb.`year`", "=", year);
cnd.where().andEX("tb.lotId", "=", lotId);
cnd.and(Cnd.likeEX("tb.baseName", baseName));
cnd.and(Cnd.likeEX("tb.travelAgencyId", travelAgencyId));
cnd.and(Cnd.likeEX("tb.regionalNature", regionalNature));
cnd.desc("tb.`year`");
cnd.asc("tb.sortNumber");
cnd.asc("tb.id");
if (!TherapyContext.hasAnyRoles(List.of("sysadmin", "A06"))) {
if (TherapyContext.hasRole("H04")) {
cnd.and("tb.createUnionId", "=", TherapyContext.getUnionId());
}
} else {
cnd.andEX("tb.createUnionId", "=", unionId);
}
sql.setCondition(cnd);
return baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
/**
* 是否启用基地线路
*
* @param id 基地线路id
* @return {@link Object}
*/
@At("/openClosedBase/?")
@POST
@ViReturn
@SaCheckLogin
public Object openClosedBase(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
//位运算 取反
dao.update(TheRapyRecuperationBaseManagement.class, Chain.makeSpecial("isDisabled", "isDisabled ^ 1"), Cnd.where("id", "=", id));
return null;
}
/**
* 查询一条基地线路
*
* @param id
* @return
*/
@At("/selectBaseManageById/?")
@ViReturn
@SaCheckLogin
public Object selectBaseManageById(String id) {
Assert.notBlank(id);
return dao.fetchLinks(dao.fetch(TheRapyRecuperationBaseManagement.class, id), "travelAgency");
}
/**
* 新增/修改
*
* @param baseManagement 基地线路
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
@SaCheckRole(value = {"sysadmin", "A06", "H04", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN"}, mode = SaMode.OR)
public Object doSubmit(@Param("base") TheRapyRecuperationBaseManagement baseManagement) {
baseManagement.setOpBy((String) TherapyContext.getPrincipalProperty("id"));
baseManagement.setCreateUnionId((String) TherapyContext.getPrincipalProperty("unionid"));
baseManagement.setOpAt(String.valueOf(new Date().getTime()));
dao.insertOrUpdate(baseManagement);
return null;//deleteBase
}
/**
* 删除线路
*
* @param id 线路id
* @return {@link Object}
*/
@At("/deleteBase/?")
@POST
@ViReturn
@SaCheckLogin
public Object deleteBase(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
dao.delete(TheRapyRecuperationBaseManagement.class, id);
return null;
}
/**
* 查询所有酒店
*
* @return {@link Object}
*/
@At("/listAllBase")
@POST
@ViReturn
@SaCheckLogin
public Object listAllBase(String startYear, String endYear, String year) {
Sql sql = Sqls.create("select * from `inclusive_therapy_v3_base_management` tb left join `inclusive_therapy_v3_lot` lot on lot.id=tb.lotId $condition");
CndPlus cnd = new CndPlus();
cnd.andEX("tb.`year`", ">=", startYear);
cnd.andEX("tb.`year`", "<=", endYear);
cnd.andEX("tb.`year`", "=", year);
sql.setCondition(cnd);
return baseService.listMap(sql);
}
/**
* 手机端酒店介绍所有信息
*
* @param id id
* @return {@link Object}
*/
@At("/selectBaseAllInfo")
@GET
@ViReturn
@SaCheckLogin
public Object selectBaseAllInfo(@Param("id") String id) {
Assert.notBlank(id);
return theRapyRecuperationBaseManagerService.selectBaseAllInfo(id);
}
/**
* 目的地导入模版
*
* @param response
*/
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.TheBaseManagement")
public void exportTemplate(HttpServletResponse response) {
try {
//查旅行社,转数组
List<TheRapyRecuperationTravelAgency> travelAgencys = dao.query(TheRapyRecuperationTravelAgency.class, Cnd.NEW().desc("serialNumber"));
List<String> excelTravelAgencyList = travelAgencys.stream().map(v -> v.getTravelAgencyName() + "_" + v.getId()).collect(Collectors.toList());
String[] excelTravelAgencyArrs = excelTravelAgencyList.toArray(new String[excelTravelAgencyList.size()]);
//查标段,转数组
List<TheRapyRecuperationLot> lots = dao.query(TheRapyRecuperationLot.class, Cnd.NEW().asc("id"));
List<String> excelLotList = lots.stream().map(v -> v.getLotName() + "_" + v.getId()).collect(Collectors.toList());
String[] excelLotArrs = excelLotList.toArray(new String[excelLotList.size()]);
TherapyDownload.excelResponse(response, "目的地导入模版.xls");
Class<TheRapyRecuperationBaseManagement> excelModeClass = TheRapyRecuperationBaseManagement.class;
Field[] excelModeClassDeclaredFields = excelModeClass.getDeclaredFields();
//字段过滤
List<Field> needAddReplaceFields = Arrays.stream(excelModeClassDeclaredFields).filter(v -> List.of("travelAgencyId", "lotId", "regionalNature", "isDisabled", "createMode").contains(v.getName())).collect(Collectors.toList());
for (Field field : needAddReplaceFields) {
Excel excelAnnotation = field.getAnnotation(Excel.class);
if (Lang.isNotEmpty(excelAnnotation)) {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelAnnotation);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map e = (Map) memberValues.get(invocationHandler);
e.put("addressList", true);
if (field.getName().equals("travelAgencyId")) {
e.put("replace", excelTravelAgencyArrs);
} else if (field.getName().equals("lotId")) {
e.put("replace", excelLotArrs);
} else if (field.getName().equals("regionalNature")) {
e.put("replace", new String[]{"省内_省内", "省外_省外"});
} else if (field.getName().equals("createMode")) {
e.put("replace", new String[]{"校工会_1", "分工会_2"});
} else if (field.getName().equals("isDisabled")) {
e.put("replace", new String[]{"是_1", "否_0"});
}
}
}
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook sheets = ExcelExportUtil.exportExcel(exportParams, TheRapyRecuperationBaseManagement.class, new ArrayList<>());
ServletOutputStream outputStream = response.getOutputStream();
sheets.write(outputStream);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 目的地导入
*
* @param file
* @return
*/
@At
@ViReturn
@SaCheckLogin
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@Aop(TransAop.READ_COMMITTED)
public Object importBaseManager(TempFile file) {
if (Lang.isEmpty(file)) {
return Result.error("上传的文件不能为空");
}
String extName = FileUtil.extName(file.getFile());
if (!List.of("xls", "xlsx").contains(extName.toLowerCase())) {
return Result.error("请上传xls,xlsx文件");
}
List<TheRapyRecuperationBaseManagement> excelList;
try {
ImportParams importParams = new ImportParams();
excelList = ExcelImportUtil.importExcel(file.getFile(), TheRapyRecuperationBaseManagement.class, importParams);
} catch (Exception e) {
e.printStackTrace();
return Result.error("读取不到数据,请检查excel文件格式");
}
if (Lang.isEmpty(excelList)) {
return Result.error("读取不到数据,请检查excel文件格式");
}
try {
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getBaseName())) || excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getTravelAgencyId()))) {
return Result.error("目的地名称和旅行社名称不能为空");
}
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLotId())) || excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getRegionalNature()))) {
return Result.error("时间标段和活动范围不能为空");
}
excelList.forEach(v -> v.setOpBy((String) TherapyContext.getPrincipalProperty("id")));
dao.insertOrUpdate(excelList);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,728 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.basicManage;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.sys.models.Sys_office_template;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
import com.budwk.app.sys.models.Sys_user_source;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationLineCreateMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyLineImportExcelMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyLineImportImageMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyTravelLineExcelMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLot;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFShape;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.stream.Collectors;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.basicManage.TheRapyRecuperationLineController
* @Description: 疗休养线路管理
* @Author zxc
* @Date 2022/5/31:09:34
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/line")
@Ok("json:full")
@Slf4j
public class TheRapyRecuperationLineController {
/**
* 新线路导入模板表头占用1行,图片锚点行号需减去表头行数后才能对应导入数据下标。
*/
private static final int LINE_IMPORT_HEADER_ROWS = 1;
/**
* 新线路导入模板中“联系方式”列下标,设置为文本格式避免手机号被Excel转成科学计数法。
*/
private static final int LINE_IMPORT_CONTACT_PHONE_COLUMN_INDEX = 12;
/**
* 新线路导入模板中“移动端缩略图”列下标,用于定位Excel内嵌图片。
*/
private static final int LINE_IMPORT_THUMBNAIL_COLUMN_INDEX = 15;
@Inject
private TheRapyRecuperationLineService lineService;
@Inject
private Dao dao;
@Inject
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.line")
public void downloadTemplate(HttpServletResponse response) throws IOException {
String templateCode = "inclusive_therapy_v3_line_import";
try (InputStream in = sysOfficeTemplateUtil.getTemplate(templateCode)) {
Sys_office_template template = dao.fetch(Sys_office_template.class, Cnd.where("templateCode", "=", templateCode));
TherapyDownload.excelResponse(response, template.getTemplateName());
if (template.getTemplateName().toLowerCase(Locale.ROOT).endsWith(".xls")) {
response.setContentType("application/vnd.ms-excel");
}
in.transferTo(response.getOutputStream());
}
}
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/basicManage/line.html")
@SaCheckPermission("inclusiveTherapyV3.line")
public void index() {
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @return {@link Object}
*/
@At
@POST
@Ok("json:full")
@ViReturn
@SaCheckRole(value = {"sysadmin", "A06", "H04", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN"}, mode = SaMode.OR)
public Object pageData(PageForm pageForm, Integer startYear , Integer endYear, String keywords, String travelAgencyId, String lineName, String unionId, String lotId, Integer signUpMode) {
Cnd cnd = Cnd.NEW();
cnd.andEX("line.`year`", ">=", startYear);
cnd.andEX("line.`year`", "<=", endYear);
cnd.andEX("line.travelAgencyId", "=", travelAgencyId);
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("line.signUpMode", "=", signUpMode);
cnd.and(Cnd.likeEX("line.lineName", lineName));
/*if (StrUtil.isNotBlank(keywords)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("line.lineName", keywords);
seg.orLike("line.travelAgencyName", keywords);
cnd.and(seg);
}*/
if (!com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.hasAnyRoles(List.of("sysadmin", "A06"))) {
if (com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.hasRole("H04")) {
cnd.and("line.createUnionId", "=", TherapyContext.getUnionId());
}
} else {
cnd.andEX("line.createUnionId", "=", unionId);
}
cnd.desc("line.year").asc("line.serialNumber");
return lineService.pageData(pageForm, cnd);
}
@At
@POST
@ViReturn
@SaCheckLogin
@SaCheckRole(value = {"sysadmin", "A06", "H04", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN"}, mode = SaMode.OR)
public Object getNo() {
Object serialNumber = dao.func2(TheRapyRecuperationLine.class, "max", "serialNumber");
serialNumber = Objects.requireNonNullElse(serialNumber, 0);
return Integer.parseInt(serialNumber.toString()) + 1;
}
/**
* 提交
*
* @param line 线路
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
@SaCheckRole(value = {"sysadmin", "A06", "H04", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN"}, mode = SaMode.OR)
public Object doSubmit(TheRapyRecuperationLine line) {
if (StrUtil.isBlank(line.getId())) {
if (lineService.count(Cnd.where("serialNumber", "=", line.getSerialNumber())) > 0) {
return Result.error("编号已存在");
}
lineService.addLine(line);
} else {
if (lineService.count(Cnd.where("serialNumber", "=", line.getSerialNumber()).and("id", "!=", line.getId())) > 0) {
return Result.error("编号已存在");
}
lineService.editLine(line);
}
return null;
}
/**
* 开启或关闭线路
*
* @param id 线路id
* @return {@link Object}
*/
@At("/openClosedLine/?")
@POST
@ViReturn
@SaCheckLogin
public Object openClosedLine(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
lineService.openClosedLine(id);
return null;
}
/**
* 删除线路
*
* @param id 线路id
* @return {@link Object}
*/
@At("/deleteLine/?")
@POST
@ViReturn
@SaCheckLogin
public Object deleteLine(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
lineService.deleteLine(id);
return null;
}
/**
* 查询线路详细信息
*
* @param id id
* @return {@link Object}
*/
@At("/selectLineInfoById/?")
@ViReturn
@SaCheckLogin
public Object selectLineInfoById(String id) {
Assert.notBlank(id);
return lineService.selectLineInfoById(id);
}
/**
* 根据分工会选择的线路id查询所该线路报名的人
*
* @param pageForm 页面形式
* @param id id
* @return {@link Object}
*/
@At("/selectLineUser")
@ViReturn
@SaCheckLogin
public Object selectLineUser(PageForm pageForm, String id, String unionId) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
return lineService.selectLineUser(pageForm, id, unionId);
}
@At("/getCreateMode")
@ViReturn
@SaCheckLogin
public Object getCreateMode() {
boolean hasSchoolAdminRole = com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.hasAnyRoles(List.of("sysadmin", "A06"));
if (hasSchoolAdminRole) {
return TheRapyRecuperationLineCreateMode.SCHOOL.getValue();
}
return TheRapyRecuperationLineCreateMode.UNION.getValue();
}
/**
* 查看各个分工会设置的时间信息
*
* @param id 线路id
* @return {@link Object}
*/
@At("/viewUnionSelectTimeInfo/?")
@ViReturn
@SaCheckLogin
public Object viewUnionSelectTimeInfo(String id) {
Assert.notBlank(id);
return lineService.viewUnionSelectTimeInfo(id);
}
/**
* 是否有权限
*
* @return {@link Object}
*/
@At
@ViReturn
@SaCheckLogin
public Object hasAnyRoles(@Param("roles") String[] roles) {
boolean b = TherapyContext.hasAnyRoles(roles);
return b;
}
/**
* 旅行社
*
* @return {@link Object}
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.line")
public Object getTravelAgencyOptions(Integer year) {
List<TheRapyRecuperationTravelAgency> travelAgencies = lineService.dao().query(TheRapyRecuperationTravelAgency.class, Cnd.NEW().andEX("year","=",year).asc("serialNumber"));
return travelAgencies;
}
/**
* 线路导入
*
* @param file
* @return
*/
@At
@ViReturn
@SaCheckLogin
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@Aop(TransAop.READ_COMMITTED)
public Object travelLineImport(TempFile file) {
if (Lang.isEmpty(file)) {
return Result.error("上传的文件不能为空");
}
String extName = FileUtil.extName(file.getFile());
if (!List.of("xls", "xlsx").contains(extName.toLowerCase())) {
return Result.error("请上传xls,xlsx文件");
}
List<TheRapyTravelLineExcelMode> excelList;
try {
ImportParams importParams = new ImportParams();
excelList = ExcelImportUtil.importExcel(file.getFile(), TheRapyTravelLineExcelMode.class, importParams);
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("读取不到数据,请检查excel文件格式");
}
if (Lang.isEmpty(excelList)) {
return Result.error("读取不到数据,请检查excel文件格式");
}
try {
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getTravelAgencyId()))) {
return Result.error("旅行社名称不能为空");
}
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLotId())) || excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getRegionalNature()))) {
return Result.error("时间标段和活动范围不能为空");
}
List<TheRapyRecuperationLine> list = new ArrayList<>();
for (TheRapyTravelLineExcelMode mode : excelList) {
TheRapyRecuperationLine line = new TheRapyRecuperationLine();
line.setYear(mode.getYear());
line.setSerialNumber(mode.getSerialNumber());
line.setLineName(mode.getLineName());
line.setTravelAgencyId(mode.getTravelAgencyId());
line.setRegionalNature(mode.getRegionalNature());
line.setContent(mode.getContent());
line.setMinimumGroupSize(mode.getMinimumGroupSize());
if (mode.getIsDisabled().equals("是")) {
line.setDisabled(false);
} else if (mode.getIsDisabled().equals("否")) {
line.setDisabled(true);
}
line.setEstimatedCost(mode.getEstimatedCost());
line.setLotId(mode.getLotId());
// line.setLineContact(mode.getLineContact());
// line.setLineContactPhone(mode.getLineContactPhone());
list.add(line);
}
dao.insert(list);
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("导入失败");
}
return null;
}
/**
* 线路导入模版
*
* @param response
*/
/**
* 按线路管理页面字段导入线路。
*
* @param file Excel文件
* @return 导入结果
*/
@At
@ViReturn
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.line")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@Aop(TransAop.READ_COMMITTED)
public Object importLineByPageFields(TempFile file) {
if (Lang.isEmpty(file)) {
return Result.error("上传的文件不能为空");
}
String extName = FileUtil.extName(file.getFile());
if (!List.of("xls", "xlsx").contains(extName.toLowerCase())) {
return Result.error("请上传xls,xlsx文件");
}
List<TheRapyLineImportExcelMode> excelList;
Map<Integer, TheRapyLineImportImageMode> imageMap;
try {
ImportParams importParams = new ImportParams();
excelList = ExcelImportUtil.importExcel(file.getFile(), TheRapyLineImportExcelMode.class, importParams);
fillLineImportContactPhone(excelList, file.getFile());
imageMap = extractLineImportImages(file.getFile(), extName);
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("读取不到数据,请检查excel文件格式");
}
if (Lang.isEmpty(excelList)) {
return Result.error("读取不到数据,请检查excel文件格式");
}
try {
int count = lineService.importLineByPageFields(excelList, imageMap);
return Result.success("成功导入" + count + "条线路");
} catch (Exception e) {
log.error(e.getMessage());
return Result.error(e.getMessage());
}
}
/**
* 下载按线路管理页面字段生成的新线路导入模板。
*
* @param response 响应对象
*/
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.line")
public void exportPageFieldsTemplate(HttpServletResponse response) {
try {
// 标段下拉复用页面配置接口返回的标段数据。
List<TheRapyRecuperationLot> lots = dao.query(TheRapyRecuperationLot.class, Cnd.NEW().asc("id"));
List<String> excelLots = lots.stream().map(v -> v.getLotName() + "_" + v.getId()).collect(Collectors.toList());
List<Field> needAddReplaceFields = Arrays.stream(TheRapyLineImportExcelMode.class.getDeclaredFields())
.filter(v -> List.of("lotId", "regionalNature", "signUpMode", "isEnabled", "familySignUp").contains(v.getName()))
.collect(Collectors.toList());
for (Field field : needAddReplaceFields) {
Excel excelAnnotation = field.getAnnotation(Excel.class);
if (Lang.isEmpty(excelAnnotation)) {
continue;
}
InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelAnnotation);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map e = (Map) memberValues.get(invocationHandler);
e.put("addressList", true);
if (field.getName().equals("lotId")) {
e.put("replace", excelLots.toArray(new String[0]));
} else if (field.getName().equals("regionalNature")) {
e.put("replace", buildRegionalNatureExcelOptions());
} else if (field.getName().equals("signUpMode")) {
e.put("replace", buildSignUpModeExcelOptions());
} else if (field.getName().equals("isEnabled") || field.getName().equals("familySignUp")) {
e.put("replace", new String[]{"是_是", "否_否"});
}
}
TherapyDownload.excelResponse(response, "线路导入模板.xlsx");
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook sheets = ExcelExportUtil.exportExcel(exportParams, TheRapyLineImportExcelMode.class, new ArrayList<>());
applyLineImportTemplateCellStyle(sheets);
ServletOutputStream outputStream = response.getOutputStream();
sheets.write(outputStream);
outputStream.close();
} catch (Exception e) {
log.error(e.getMessage());
}
}
/**
* 设置新线路导入模板的关键列格式。
*
* @param workbook 导出的模板工作簿
*/
private void applyLineImportTemplateCellStyle(Workbook workbook) {
Sheet sheet = workbook.getSheetAt(0);
DataFormat dataFormat = workbook.createDataFormat();
CellStyle textStyle = workbook.createCellStyle();
textStyle.setDataFormat(dataFormat.getFormat("@"));
// 联系方式按字符串字段处理,模板层面先把整列设置为文本格式。
sheet.setDefaultColumnStyle(LINE_IMPORT_CONTACT_PHONE_COLUMN_INDEX, textStyle);
sheet.setColumnWidth(LINE_IMPORT_CONTACT_PHONE_COLUMN_INDEX, 20 * 256);
sheet.setColumnWidth(LINE_IMPORT_THUMBNAIL_COLUMN_INDEX, 20 * 256);
}
/**
* 按Excel显示文本重读“联系方式”列,确保长手机号等内容按字符串导入。
*
* @param excelList EasyPoi读取出的导入数据
* @param excelFile Excel文件
* @throws Exception Excel读取失败时抛出异常
*/
private void fillLineImportContactPhone(List<TheRapyLineImportExcelMode> excelList, File excelFile) throws Exception {
DataFormatter dataFormatter = new DataFormatter();
try (InputStream inputStream = new FileInputStream(excelFile);
Workbook workbook = WorkbookFactory.create(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
for (int i = 0; i < excelList.size(); i++) {
Row row = sheet.getRow(i + LINE_IMPORT_HEADER_ROWS);
if (row == null) {
continue;
}
Cell cell = row.getCell(LINE_IMPORT_CONTACT_PHONE_COLUMN_INDEX);
if (cell == null) {
continue;
}
// 使用DataFormatter读取用户看到的文本,避免联系方式被当作数值转成科学计数法。
String phone = dataFormatter.formatCellValue(cell);
if (StrUtil.isNotBlank(phone)) {
excelList.get(i).setLineContactPhone(phone.trim());
}
}
}
}
/**
* 提取新线路导入模板“移动端缩略图”列中的内嵌图片。
*
* @param excelFile Excel文件
* @param extName 文件扩展名
* @return key为导入数据行下标、value为图片内容的映射
* @throws Exception Excel读取失败时抛出异常
*/
private Map<Integer, TheRapyLineImportImageMode> extractLineImportImages(File excelFile, String extName) throws Exception {
if ("xlsx".equalsIgnoreCase(extName)) {
return extractXlsxLineImportImages(excelFile);
}
return extractXlsLineImportImages(excelFile);
}
/**
* 解析xlsx模板中的内嵌图片,按图片左上角锚点匹配到“移动端缩略图”列。
*
* @param excelFile xlsx文件
* @return 图片映射
* @throws Exception Excel读取失败时抛出异常
*/
private Map<Integer, TheRapyLineImportImageMode> extractXlsxLineImportImages(File excelFile) throws Exception {
Map<Integer, TheRapyLineImportImageMode> imageMap = new HashMap<>();
try (InputStream inputStream = new FileInputStream(excelFile);
XSSFWorkbook workbook = new XSSFWorkbook(inputStream)) {
XSSFSheet sheet = workbook.getSheetAt(0);
XSSFDrawing drawing = sheet.getDrawingPatriarch();
if (drawing == null) {
return imageMap;
}
for (XSSFShape shape : drawing.getShapes()) {
if (!(shape instanceof XSSFPicture)) {
continue;
}
XSSFPicture picture = (XSSFPicture) shape;
if (!(picture.getAnchor() instanceof XSSFClientAnchor)) {
continue;
}
XSSFClientAnchor anchor = (XSSFClientAnchor) picture.getAnchor();
XSSFPictureData pictureData = picture.getPictureData();
addLineImportImage(imageMap, anchor.getRow1(), anchor.getCol1(), anchor.getCol2(), pictureData.suggestFileExtension(), pictureData.getData());
}
}
return imageMap;
}
/**
* 解析xls模板中的内嵌图片,按图片左上角锚点匹配到“移动端缩略图”列。
*
* @param excelFile xls文件
* @return 图片映射
* @throws Exception Excel读取失败时抛出异常
*/
private Map<Integer, TheRapyLineImportImageMode> extractXlsLineImportImages(File excelFile) throws Exception {
Map<Integer, TheRapyLineImportImageMode> imageMap = new HashMap<>();
try (InputStream inputStream = new FileInputStream(excelFile);
HSSFWorkbook workbook = new HSSFWorkbook(inputStream)) {
HSSFSheet sheet = workbook.getSheetAt(0);
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
if (drawing == null) {
return imageMap;
}
for (HSSFShape shape : drawing.getChildren()) {
if (!(shape instanceof HSSFPicture)) {
continue;
}
HSSFPicture picture = (HSSFPicture) shape;
if (!(picture.getAnchor() instanceof HSSFClientAnchor)) {
continue;
}
HSSFClientAnchor anchor = (HSSFClientAnchor) picture.getAnchor();
HSSFPictureData pictureData = picture.getPictureData();
addLineImportImage(imageMap, anchor.getRow1(), anchor.getCol1(), anchor.getCol2(), pictureData.suggestFileExtension(), pictureData.getData());
}
}
return imageMap;
}
/**
* 将匹配到缩略图列的图片加入映射,重复图片只保留同一行第一张。
*
* @param imageMap 图片映射
* @param rowIndex 图片左上角锚点行下标
* @param colIndex 图片左上角锚点列下标
* @param endColIndex 图片右下角锚点列下标
* @param extension 图片扩展名
* @param data 图片二进制内容
*/
private void addLineImportImage(Map<Integer, TheRapyLineImportImageMode> imageMap, int rowIndex, int colIndex, int endColIndex, String extension, byte[] data) {
int imageEndColIndex = Math.max(colIndex, endColIndex);
boolean coverThumbnailColumn = colIndex <= LINE_IMPORT_THUMBNAIL_COLUMN_INDEX && imageEndColIndex >= LINE_IMPORT_THUMBNAIL_COLUMN_INDEX;
if (rowIndex < LINE_IMPORT_HEADER_ROWS || !coverThumbnailColumn || data == null || data.length == 0) {
return;
}
int dataIndex = rowIndex - LINE_IMPORT_HEADER_ROWS;
TheRapyLineImportImageMode imageMode = new TheRapyLineImportImageMode();
imageMode.setRowIndex(dataIndex);
imageMode.setExtension(extension);
imageMode.setFileName("line-thumbnail-" + (dataIndex + 1) + "." + StrUtil.blankToDefault(extension, "png"));
imageMode.setData(data);
imageMap.putIfAbsent(dataIndex, imageMode);
}
/**
* 构建与页面线路类型一致的Excel下拉选项。
*
* @return 线路类型下拉选项
*/
private String[] buildRegionalNatureExcelOptions() {
if (!TherapyContext.hasAnyRoles(new String[]{"sysadmin", "A06"})) {
return new String[]{"省内线路_省内"};
}
return new String[]{"省内线路_省内", "省外线路_省外"};
}
/**
* 构建与页面组织形式一致的Excel下拉选项。
*
* @return 组织形式下拉选项
*/
private String[] buildSignUpModeExcelOptions() {
List<String> options = new ArrayList<>();
if (TherapyContext.hasAnyRoles(new String[]{"sysadmin", "A06", "H04"})) {
options.add("分工会组织_1");
}
if (TherapyContext.hasAnyRoles(new String[]{"sysadmin", "A06"})) {
options.add("校工会组织_2");
}
return options.toArray(new String[0]);
}
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.line")
public void exportTemplate(HttpServletResponse response) {
try {
//查旅行社,转数组
List<TheRapyRecuperationTravelAgency> travelAgencys = dao.query(TheRapyRecuperationTravelAgency.class, Cnd.NEW().desc("serialNumber"));
List<String> excelTravelAgencys = travelAgencys.stream().map(v -> v.getTravelAgencyName() + "_" + v.getId()).collect(Collectors.toList());
String[] excelTravelAgencyArrs = excelTravelAgencys.toArray(new String[excelTravelAgencys.size()]);
//查标段,转数组
List<TheRapyRecuperationLot> lots = dao.query(TheRapyRecuperationLot.class, Cnd.NEW().asc("id"));
List<String> excelLots = lots.stream().map(v -> v.getLotName() + "_" + v.getId()).collect(Collectors.toList());
String[] excelLotArrs = excelLots.toArray(new String[excelLots.size()]);
TherapyDownload.excelResponse(response, "线路导入模版.xls");
Class<TheRapyTravelLineExcelMode> excelModeClass = TheRapyTravelLineExcelMode.class;
Field[] excelModeClassDeclaredFields = excelModeClass.getDeclaredFields();
//字段过滤
List<Field> needAddReplaceFields = Arrays.stream(excelModeClassDeclaredFields).filter(v -> List.of("travelAgencyId", "lotId", "regionalNature").contains(v.getName())).collect(Collectors.toList());
//循环TheRapyTravelLineExcelMode需要下拉数据的字段
for (Field field : needAddReplaceFields) {
Excel excelAnnotation = field.getAnnotation(Excel.class);
if (Lang.isNotEmpty(excelAnnotation)) {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelAnnotation);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map e = (Map) memberValues.get(invocationHandler);
e.put("addressList", true);
if (field.getName().equals("travelAgencyId")) {
e.put("replace", excelTravelAgencyArrs);
} else if (field.getName().equals("lotId")) {
e.put("replace", excelLotArrs);
} else if (field.getName().equals("regionalNature")) {
e.put("replace", new String[]{"省内_省内", "省外_省外"});
}
}
}
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook sheets = ExcelExportUtil.exportExcel(exportParams, TheRapyTravelLineExcelMode.class, new ArrayList<>());
ServletOutputStream outputStream = response.getOutputStream();
sheets.write(outputStream);
outputStream.close();
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
@@ -0,0 +1,395 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.basicManage;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.sys.models.Sys_office_template;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.PageUtil;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyTravelAgencyExcelMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationTravelAgencyService;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.nutz.trans.Trans;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import java.math.BigDecimal;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.http.HttpServletResponse;
/**
* 疗休养旅行社管理
*
* @author jug
* @date 2022/05/31
*/
@IocBean
@At("/platform/inclusiveTherapyV3/travelAgency")
@Ok("json:full")
@Slf4j
public class TheRapyRecuperationTravelAgencyController {
@Inject
private TheRapyRecuperationTravelAgencyService travelAgencyService;
@Inject
private Dao dao;
@Inject
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/basicManage/travelAgency.html")
@SaCheckPermission("inclusiveTherapyV3.travelAgency")
public void index() {
}
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.travelAgency")
public void downloadTemplate(HttpServletResponse response) throws IOException {
String templateCode = "inclusive_therapy_v3_travel_agency_import";
try (InputStream in = sysOfficeTemplateUtil.getTemplate(templateCode)) {
Sys_office_template template = dao.fetch(Sys_office_template.class, Cnd.where("templateCode", "=", templateCode));
TherapyDownload.excelResponse(response, template.getTemplateName());
if (template.getTemplateName().toLowerCase(java.util.Locale.ROOT).endsWith(".xls")) {
response.setContentType("application/vnd.ms-excel");
}
in.transferTo(response.getOutputStream());
}
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object pageData(PageForm pageForm, Integer year, String keywords) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
if (StrUtil.isNotBlank(keywords)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("contact", keywords);
seg.orLike("travelAgencyName", keywords);
seg.orLike("serialNumber", keywords);
cnd.and(seg);
}
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.asc("serialNumber * 1");
}
return travelAgencyService.pageData(pageForm, cnd);
}
/**
* 提交
*
* @param travelAgency 旅行社
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object doSubmit(@Param("travelAgency") TheRapyRecuperationTravelAgency travelAgency) {
if (StrUtil.isBlank(travelAgency.getId())) {
if (travelAgencyService.count(Cnd.where("serialNumber", "=", travelAgency.getSerialNumber())) > 0) {
return Result.error("编号已存在");
}
travelAgencyService.addTravelAgency(travelAgency);
} else {
if (travelAgencyService.count(Cnd.where("serialNumber", "=", travelAgency.getSerialNumber()).and("id", "!=", travelAgency.getId())) > 0) {
return Result.error("编号已存在");
}
travelAgencyService.editTravelAgency(travelAgency);
}
return null;
}
/**
* 开启或关闭旅行社
*
* @param id 旅行社id
* @return {@link Object}
*/
@At("/openClosedTravelAgency/?")
@POST
@ViReturn
@SaCheckLogin
public Object openClosedTravelAgency(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
travelAgencyService.openTravelAgency(id);
return null;
}
/**
* 删除旅行社
*
* @param id 旅行社id
* @return {@link Object}
*/
@At("/deleteTravelAgency/?")
@POST
@ViReturn
@SaCheckLogin
public Object deleteTravelAgency(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
travelAgencyService.deleteTravelAgency(id);
return null;
}
/**
* 查询旅行社
*
* @param year 年度
* @return {@link Object}
*/
@At("/selectTravelAgency")
@ViReturn
@SaCheckLogin
public Object selectTravelAgency(Integer year) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
return travelAgencyService.selectAllTravelAgencyByYear(cnd);
}
/**
* 年度区间查询旅行社
*
* @param startYear 开始一年
* @param endYear 结束一年
* @return {@link Object}
*/
@At("/selectTravelAgencyByYears")
@ViReturn
@SaCheckLogin
public Object selectTravelAgencyByYears(Integer startYear, Integer endYear, Integer year) {
Cnd cnd = Cnd.NEW();
if(startYear != null && endYear != null) {
cnd.andEX("year", ">=", startYear);
cnd.andEX("year", "<=", endYear);
}else {
cnd.andEX("year", "=", year);
}
return travelAgencyService.selectAllTravelAgencyByYear(cnd);
}
/**
* 根据旅行社id查线路
*
* @param agencyId 代理id
* @return {@link Object}
*/
@At("/selectLineByAgencyId")
@ViReturn
@SaCheckLogin
public Object selectLineByAgencyId(String agencyId) {
Sql sql = Sqls.create("""
SELECT id,lineName FROM `inclusive_therapy_v3_line` WHERE travelAgencyId=@travelAgencyId
""").setParam("travelAgencyId", agencyId);
return travelAgencyService.listMap(sql);
}
/**
* 旅行社导入
*
* @param file
* @return
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.travelAgency")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Object travelAgencyImport(TempFile file) {
if (Lang.isEmpty(file)) {
return Result.error("上传的文件不能为空");
}
String extName = FileUtil.extName(file.getFile());
if (!List.of("xls", "xlsx").contains(extName.toLowerCase())) {
return Result.error("请上传xls,xlsx文件");
}
List<TheRapyTravelAgencyExcelMode> excelList = new ArrayList<>();
List<Integer> excelRowNumbers = new ArrayList<>();
try (Workbook workbook = WorkbookFactory.create(file.getFile())) {
Sheet sheet = workbook.getSheetAt(0);
Row header = sheet.getRow(0);
if (header == null) return Result.error("第一行必须是模板表头");
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
Map<String, Integer> headers = new java.util.LinkedHashMap<>();
for (Cell cell : header) {
String name = formatter.formatCellValue(cell).trim().replace("(可填)", "").replace("(可填)", "");
if ("编号".equals(name)) name = "排序编号";
if ("是否启用".equals(name)) name = "是否启用(是/否)";
if (StrUtil.isBlank(name)) continue;
if (headers.putIfAbsent(name, cell.getColumnIndex()) != null) return Result.error("模板表头重复:" + name);
}
for (String name : List.of("年度", "排序编号", "旅行社名称", "是否自由组团(是/否)", "旅行社联系人", "联系电话")) {
if (!headers.containsKey(name)) return Result.error("模板缺少必填列:" + name);
}
for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row dataRow = sheet.getRow(rowIndex);
if (dataRow == null) continue;
Map<String, String> values = new java.util.HashMap<>();
for (Map.Entry<String, Integer> column : headers.entrySet()) {
Cell cell = dataRow.getCell(column.getValue());
String value = formatter.formatCellValue(cell, evaluator).trim();
if (cell != null && ("年度".equals(column.getKey()) || "最多承担人数".equals(column.getKey()))) {
CellValue evaluated = evaluator.evaluate(cell);
if (evaluated != null && evaluated.getCellType() == CellType.NUMERIC) {
value = BigDecimal.valueOf(evaluated.getNumberValue()).toPlainString();
}
}
values.put(column.getKey(), value);
}
if (values.values().stream().allMatch(StrUtil::isBlank)) continue;
TheRapyTravelAgencyExcelMode travel = new TheRapyTravelAgencyExcelMode();
try {
if (StrUtil.isNotBlank(values.get("年度"))) {
travel.setYear(new BigDecimal(values.get("年度")).intValueExact());
}
} catch (NumberFormatException | ArithmeticException e) {
return Result.error("第" + (rowIndex + 1) + "行:年度须填写4位整数");
}
try {
if (StrUtil.isNotBlank(values.get("最多承担人数"))) {
travel.setMaxUndertakeNumber(new BigDecimal(values.get("最多承担人数")).intValueExact());
}
} catch (NumberFormatException | ArithmeticException e) {
return Result.error("第" + (rowIndex + 1) + "行:最多承担人数须填写有效整数");
}
travel.setSerialNumber(values.get("排序编号"));
travel.setTravelAgencyName(values.get("旅行社名称"));
travel.setSignUpTravelAgency(values.get("是否自由组团(是/否)"));
travel.setContact(values.get("旅行社联系人"));
travel.setContactMobileNumber(values.get("联系电话"));
travel.setEmail(values.get("邮箱"));
travel.setOfficialWebsite(values.get("官网"));
travel.setNote(values.get("备注"));
travel.setIsDisabled(values.get("是否启用(是/否)"));
excelList.add(travel);
excelRowNumbers.add(rowIndex + 1);
}
} catch (Exception e) {
log.error("读取旅行社导入文件失败", e);
return Result.error("读取失败,请使用新模板;年度和最多承担人数须填写整数");
}
if (Lang.isEmpty(excelList)) {
return Result.error("读取不到数据,请检查excel文件格式");
}
List<TheRapyRecuperationTravelAgency> list = new ArrayList<>();
Map<String, Integer> importedNumbers = new java.util.HashMap<>();
for (int index = 0; index < excelList.size(); index++) {
TheRapyTravelAgencyExcelMode travel = excelList.get(index);
String row = "第" + excelRowNumbers.get(index) + "行:";
travel.setSerialNumber(StrUtil.trim(travel.getSerialNumber()));
travel.setTravelAgencyName(StrUtil.trim(travel.getTravelAgencyName()));
travel.setContact(StrUtil.trim(travel.getContact()));
travel.setContactMobileNumber(StrUtil.trim(travel.getContactMobileNumber()));
travel.setSignUpTravelAgency(StrUtil.trim(travel.getSignUpTravelAgency()));
travel.setIsDisabled(StrUtil.trim(travel.getIsDisabled()));
travel.setEmail(StrUtil.trim(travel.getEmail()));
travel.setOfficialWebsite(StrUtil.trim(travel.getOfficialWebsite()));
if (travel.getYear() == null || travel.getYear() < 1000 || travel.getYear() > 9999) {
return Result.error(row + "年度须填写4位整数");
}
if (StrUtil.isBlank(travel.getSerialNumber()) || StrUtil.isBlank(travel.getTravelAgencyName())
|| StrUtil.isBlank(travel.getContact()) || StrUtil.isBlank(travel.getContactMobileNumber())) {
return Result.error(row + "编号、旅行社名称、旅行社联系人和联系电话不能为空");
}
if (!List.of("是", "否").contains(travel.getSignUpTravelAgency() == null ? "" : travel.getSignUpTravelAgency())) {
return Result.error(row + "是否自由组团须填写是或否");
}
if (StrUtil.isBlank(travel.getIsDisabled())) travel.setIsDisabled("是");
if (!List.of("是", "否").contains(travel.getIsDisabled())) return Result.error(row + "是否启用须填写是或否");
if (!travel.getContactMobileNumber().matches("^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$")) {
return Result.error(row + "联系电话格式不正确");
}
if (travel.getSerialNumber().length() > 50 || travel.getTravelAgencyName().length() > 50
|| travel.getContact().length() > 10 || StrUtil.length(travel.getEmail()) > 50
|| StrUtil.length(travel.getOfficialWebsite()) > 100 || StrUtil.length(travel.getNote()) > 100) {
return Result.error(row + "字段长度超限:编号/名称/邮箱最多50字,联系人10字,官网/备注100字");
}
if (StrUtil.isNotBlank(travel.getEmail()) && !cn.hutool.core.lang.Validator.isEmail(travel.getEmail())) {
return Result.error(row + "邮箱格式不正确");
}
if (StrUtil.isNotBlank(travel.getOfficialWebsite()) && !cn.hutool.core.lang.Validator.isUrl(travel.getOfficialWebsite())) {
return Result.error(row + "官网须填写完整网址");
}
if (travel.getMaxUndertakeNumber() != null && travel.getMaxUndertakeNumber() < 0) {
return Result.error(row + "最多承担人数不能小于0");
}
Integer previousRow = importedNumbers.putIfAbsent(travel.getSerialNumber(), excelRowNumbers.get(index));
if (previousRow != null) return Result.error(row + "编号与第" + previousRow + "行重复");
List<TheRapyRecuperationTravelAgency> existing = dao.query(TheRapyRecuperationTravelAgency.class,
Cnd.where("serialNumber", "=", travel.getSerialNumber()));
if (existing.size() > 1) return Result.error(row + "数据库中该编号对应多条旅行社记录");
TheRapyRecuperationTravelAgency agency = existing.isEmpty() ? new TheRapyRecuperationTravelAgency() : existing.get(0);
agency.setDisabled("否".equals(travel.getIsDisabled()));
agency.setSignUpTravelAgency("是".equals(travel.getSignUpTravelAgency()));
agency.setContact(travel.getContact());
agency.setTravelAgencyName(travel.getTravelAgencyName());
agency.setSerialNumber(travel.getSerialNumber());
agency.setEmail(travel.getEmail());
agency.setMaxUndertakeNumber(travel.getMaxUndertakeNumber());
agency.setContactMobileNumber(travel.getContactMobileNumber());
agency.setNote(travel.getNote());
agency.setYear(travel.getYear());
agency.setOfficialWebsite(travel.getOfficialWebsite());
list.add(agency);
}
try {
Trans.exec(() -> dao.insertOrUpdate(list));
} catch (Exception e) {
log.error("导入旅行社失败", e);
return Result.error("导入旅行社失败");
}
return Result.success("成功导入" + list.size() + "条旅行社");
}
}
@@ -0,0 +1,74 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.mobile;
import cn.dev33.satoken.annotation.SaCheckLogin;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @Author JyuHsin
* @Date 2022/6/2
* @Description 疗休养页面跳转controller
*/
@IocBean
@At("/platform/inclusiveTherapyV3/mobile")
@Ok("json:full")
public class MobileTheRapyRecuperationEnrollController {
/**
* 手机端 首页
*/
@At("/index")
@Ok("beetl:/platform/zhghh5/staffbenefit/therapyRecuperation/index.html")
@SaCheckLogin
public void index() {
}
/**
* 手机端 线路列表页面
*/
@At("/mobileLineListPage")
@Ok("beetl:/platform/zhghh5/staffbenefit/therapyRecuperation/lineList.html")
@SaCheckLogin
public void mobileLinePage() {
}
/**
* 手机端 线路详情页面
*/
@At("/lineInfo")
@Ok("beetl:/platform/zhghh5/staffbenefit/therapyRecuperation/lineInfo.html")
@SaCheckLogin
public void lineInfo() {
}
/**
* 手机端 基地详情页面
*/
@At("/baseInfo")
@Ok("beetl:/platform/zhghh5/staffbenefit/therapyRecuperation/baseManagement.html")
@SaCheckLogin
public void baseInfo() {
}
/**
* 手机端 我的疗休养页面
*/
@At("/myRecuperation")
@Ok("beetl:/platform/zhghh5/staffbenefit/therapyRecuperation/myRecuperation.html")
@SaCheckLogin
public void myRecuperation() {
}
@At("/userSignInfo")
@Ok("beetl:/platform/zhghh5/staffbenefit/therapyRecuperation/userSignInfo.html")
@SaCheckLogin
public void userSignInfo() {
}
}
@@ -0,0 +1,501 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.sys.models.Sys_config;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyUser;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationType;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationBaseManagement;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationCommonService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationTravelAgencyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.web.commons.base.Globals;
import cn.dev33.satoken.annotation.SaCheckLogin;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
* @FileName io.v.nutz.therapyRecuperation.controller.process.TheRapyRecuperationEnroll
* @Description: 疗休养报名报名
* @Author zxc
* @Date 2022/5/31:16:58
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/line/enroll")
@Ok("json:full")
public class TheRapyRecuperationEnrollController {
/**
* 单应用部署下按选择线路时段加锁,避免同一条线路最后一个名额被并发请求同时校验通过。
*/
private static final Map<String, ReentrantLock> LINE_SIGN_UP_LOCKS = new ConcurrentHashMap<>();
@Inject
private Dao dao;
@Inject
private TheRapyRecuperationEnrollService enrollService;
@Inject
private TheRapyRecuperationTravelAgencyService travelAgencyService;
@Inject
private TheRapyRecuperationCommonService commonService;
/**
* 线路的value集合 [0,1]
*/
static List<Integer> lineValues = new ArrayList<>() {{
add(TheRapyRecuperationType.provinceInLine.getValue());
add(TheRapyRecuperationType.provinceOutLine.getValue());
}};
static List<Integer> travelAgencies = new ArrayList<>() {{
add(TheRapyRecuperationType.provinceInTravelAgency.getValue());
}};
// static List<Integer> schoolFreeValues = new ArrayList<>() {{
// add(TheRapyRecuperationType.schoolFree.getValue());
// }};
@Inject
private TheRapyRecuperationLineService lineService;
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @param unionId 选择的工会id
* @param theRapyRecuperationType 线路类型 见下枚举类
* @param lineKeyword 移动端线路名称搜索关键字
* @param signUpStatus 报名状态筛选,0 全部、1 报名中、2 报名已结束
* @return {@link Object}
* @see com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationType
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object pageData(PageForm pageForm, Integer year, String unionId, int theRapyRecuperationType, Integer lineUnionType, String lineKeyword, Integer signUpStatus) {
return enrollService.enrollPageData(pageForm, year, unionId, theRapyRecuperationType, lineUnionType, lineKeyword, signUpStatus);
}
@At
@POST
@ViReturn
@SaCheckLogin
public Object getSelectLineById(String lineId, String usId, String unionId, int theRapyRecuperationType, Integer lineUnionType, Integer signUpStatus) {
return enrollService.getSelectLineById(lineId, usId, unionId, theRapyRecuperationType, lineUnionType, signUpStatus);
}
@At
@POST
@ViReturn
@SaCheckLogin
public Object openSignUser(String usId, String travelId, String searchKeyWord) {
return enrollService.openSignUser(usId, travelId, searchKeyWord);
}
//获取设置了公开线路的分工会
@At
@ViReturn
@SaCheckLogin
public Object getTheRapyUnions(Integer year, int theRapyRecuperationType) {
return enrollService.getTheRapyUnions(year, theRapyRecuperationType);
}
/**
* 线路报名及修改
*
* @param enrollInfo 登记信息
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object doSignUpForLine(@Param("enroll") TheRapyRecuperationEnroll enrollInfo) {
if (StrUtil.isBlank(enrollInfo.getId())) {
if (StrUtil.isBlank(enrollInfo.getTakePartInLineId())) {
return Result.error("请选择线路");
}
ReentrantLock lock = LINE_SIGN_UP_LOCKS.computeIfAbsent(enrollInfo.getTakePartInLineId(), key -> new ReentrantLock());
boolean locked = false;
try {
locked = lock.tryLock(10, TimeUnit.SECONDS);
if (!locked) {
return Result.error("当前线路报名人数较多,请稍后重试");
}
Map<Boolean, String> validResult = validLineSignUpInfo((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
if (validResult.containsKey(false)) {
return Result.error(validResult.get(false));
}
enrollService.doSignUpForLine(enrollInfo);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return Result.error("当前线路报名处理中,请稍后重试");
} finally {
if (locked) {
lock.unlock();
}
}
return null;
}
Map<Boolean, String> validResult = validLineSignUpInfo((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
if (validResult.containsKey(false)) {
return Result.error(validResult.get(false));
}
enrollService.updateSignUpLine(enrollInfo);
return null;
}
/**
* 按当前系统疗休养版本执行线路报名校验。
*
* @param loginName 当前登录人工号
* @param enrollInfo 报名信息,新增时必须包含takePartInLineId,编辑时包含报名记录id
* @return 校验结果,包含false时表示不可继续保存,value为前端提示文案
*/
private Map<Boolean, String> validLineSignUpInfo(String loginName, TheRapyRecuperationEnroll enrollInfo) {
Sys_config config = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "staffTherapyRecuperationVersion"));
Map<Boolean, String> validResult = new HashMap<>();
if ("zjxu".equals(config.getConfigValue())) {
validResult = enrollService.validSignUpInfoForZJXU(loginName, enrollInfo);
} else if ("zjiet".equals(config.getConfigValue())) {
validResult = enrollService.validSignUpInfo(loginName, enrollInfo);
} else if ("zjnu".equals(config.getConfigValue())) {
validResult = enrollService.validSignUpInfoForZJNU(loginName, enrollInfo);
}
return validResult;
}
/**
* 报名参加旅行社
*
* @param enrollInfo 登记信息
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object doSignUpForTravelAgency(@Param("enroll") TheRapyRecuperationEnroll enrollInfo) {
Sys_config config = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "staffTherapyRecuperationVersion"));
Map<Boolean, String> resultMap = new HashMap<>();
if("zjxu".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfoForZJXU((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
} else if("zjiet".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfo((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
} else if("zjnu".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfoForZJNU((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
}
if (resultMap.containsKey(false)) {
return Result.error(resultMap.get(false));
}
if (StrUtil.isBlank(enrollInfo.getId())) {
enrollService.doSignUpForTravelAgency(enrollInfo);
} else {
enrollService.updateSignUpTravelAgency(enrollInfo);
}
return null;
}
/**
* 报名参加酒店
*
* @param enrollInfo 登记信息
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object doSignUpForBaseManagement(@Param("enroll") TheRapyRecuperationEnroll enrollInfo) {
Sys_config config = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "staffTherapyRecuperationVersion"));
Map<Boolean, String> resultMap = new HashMap<>();
if("zjxu".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfoForZJXU((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
} else {
resultMap = enrollService.validSignUpInfo((String) TherapyContext.getPrincipalProperty("loginname"), enrollInfo);
}
if (resultMap.containsKey(false)) {
return Result.error(resultMap.get(false));
}
if (StrUtil.isBlank(enrollInfo.getId())) {
enrollService.doSignUpForHotel(enrollInfo);
} else {
enrollService.updateSignUpHotel(enrollInfo);
}
return null;
}
@At("/findSignUpInfoById/?")
@POST
@ViReturn
@SaCheckLogin
public Object findSignUpInfoById(String id) {
return enrollService.findSignUpInfoById(id);
}
/**
* 我报名的页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @param theRapyRecuperationType rapy恢复类型
* @param auditStateId 审核状态
* @param signUpStateId 报名状态 全部0 已报名1 已参加2 未参加3
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object mySignUpPageData(PageForm pageForm, Integer year, int theRapyRecuperationType, Integer auditStateId, int signUpStateId) {
Cnd cnd = Cnd.NEW();
cnd.and("e.loginName", "=", TherapyContext.getPrincipalProperty("loginname"));
switch (signUpStateId) {
case 1 -> cnd.and("1", "=", 1);
case 2 -> cnd.and("e.isTakePartIn", "=", 1);
default -> {
cnd.and("e.isTakePartIn", "=", 0);
}
}
return enrollService.mySignUpPageData(pageForm, cnd, theRapyRecuperationType, year);
}
@At
@POST
@ViReturn
@SaCheckLogin
public Object getType() {
List<TheRapyRecuperationLine> inList = dao.query(TheRapyRecuperationLine.class, Cnd.where("regionalNature", "=", "省内"));
List<String> inIds = inList.stream().map(TheRapyRecuperationLine::getId).collect(Collectors.toList());
List<TheRapyRecuperationLineUnionSelect> inSelectList = dao.query(TheRapyRecuperationLineUnionSelect.class, Cnd.where("lineId", "in", inIds));
List<String> inSelectIds = inSelectList.stream().map(TheRapyRecuperationLineUnionSelect::getId).collect(Collectors.toList());
List<TheRapyRecuperationLine> outList = dao.query(TheRapyRecuperationLine.class, Cnd.where("regionalNature", "=", "省外"));
List<String> outIds = outList.stream().map(TheRapyRecuperationLine::getId).collect(Collectors.toList());
List<TheRapyRecuperationLineUnionSelect> outSelectList = dao.query(TheRapyRecuperationLineUnionSelect.class, Cnd.where("lineId", "in", outIds));
List<String> outSelectIds = outSelectList.stream().map(TheRapyRecuperationLineUnionSelect::getId).collect(Collectors.toList());
//是否报省内
int inCount = dao.count("inclusive_therapy_v3_enroll", Cnd.where("loginName", "=", TherapyContext.getPrincipalProperty("loginname"))
.and("takePartInLineId", "in", inSelectIds).and("isNormal", "=", true));
if (inCount > 0) {
return 0;
}
//是否报省外
int outCount = dao.count("inclusive_therapy_v3_enroll", Cnd.where("loginName", "=", TherapyContext.getPrincipalProperty("loginname"))
.and("takePartInLineId", "in", outSelectIds).and("isNormal", "=", true));
if (outCount > 0) {
return 1;
}
//是否报旅行社
int travelCount = dao.count("inclusive_therapy_v3_enroll", Cnd.where("loginName", "=", TherapyContext.getPrincipalProperty("loginname"))
.and("takePartInLineId", "is", null).and("takePartInTravelAgencyId", "is not", null));
if (travelCount > 0) {
return 2;
}
return 0;
}
/**
* 验证是否能报名及修改
*
* @param enrollInfo 信息
* @return {@link Object}
*/
@At("/validSignUpInfo")
@POST
@ViReturn
@SaCheckLogin
public Object validSignUpInfo(@Param("enroll") TheRapyRecuperationEnroll enrollInfo) {
if (StrUtil.isBlank(enrollInfo.getTakePartInBaseManagementId())
&& StrUtil.isBlank(enrollInfo.getTakePartInTravelAgencyId())
&& StrUtil.isBlank(enrollInfo.getTakePartInLineId())) {
return Result.error("线路信息不能为空");
}
if (StrUtil.isBlank(enrollInfo.getLoginName())){
enrollInfo.setLoginName(TherapyContext.getPrincipalProperty("loginname").toString());
}
Sys_config config = dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "staffTherapyRecuperationVersion"));
Map<Boolean, String> resultMap = new HashMap<>();
if("zjxu".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfoForZJXU(enrollInfo.getLoginName(), enrollInfo);
} else if("zjiet".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfo(enrollInfo.getLoginName(), enrollInfo);
} else if("zjnu".equals(config.getConfigValue())) {
resultMap = enrollService.validSignUpInfoForZJNU(enrollInfo.getLoginName(), enrollInfo);
}
if (resultMap.containsKey(false)) {
return Result.error(resultMap.get(false));
}
if (resultMap.containsKey(true) && "当前线路所指定的旅行社可报名人数剩余1人,是否继续报名".equals(resultMap.get(true))) {
return Result.success(resultMap.get(true));
}
return Result.success();
}
/**
* 删除我的报名信息
*
* @param id id
* @return {@link Object}
*/
@At("/doDeleteMyEnrollInfoById/?")
@POST
@ViReturn
@SaCheckLogin
public Object doDeleteMyEnrollInfoById(String id) {
enrollService.deleteMyEnrollInfoById(id);
return null;
}
/**
* 删除我的报名信息
*
* @param id id
* @return {@link Object}
*/
@At("/doModify/?")
@POST
@ViReturn
@SaCheckLogin
public Object doModify(String id) {
enrollService.update(Chain.make("isNormal",false).add("delFlag", true),Cnd.where("id","=",id));
return null;
}
/**
* 能取消吗
*
* @param id id
* @return {@link Object}
*/
@At("/canDelete/?")
@POST
@ViReturn
@SaCheckLogin
public Object canDelete(String id) {
String errorMsg = enrollService.validateCanDeleteMyEnrollInfo(id);
if (StrUtil.isNotBlank(errorMsg)) {
return Result.error(errorMsg);
}
return null;
}
/**
* 反馈内容
*
* @param id id
* @param evaluationForTravelAgency 对旅行社的评价(几星)
* @param evaluationForLine 对线路的评价(几星)
* @param evaluationForJourney 对旅途的评价(几星)
* @param feedbackContent 反馈内容
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object doFeedBack(String id, String evaluationForTravelAgency, String evaluationForLine,
String evaluationForJourney, String feedbackContent) {
Chain chain = Chain.make("evaluationForTravelAgency", evaluationForTravelAgency);
chain.add("evaluationForLine", evaluationForLine);
chain.add("evaluationForJourney", evaluationForJourney);
chain.add("feedbackContent", feedbackContent);
dao.update(TheRapyRecuperationEnroll.class, chain, Cnd.where("id", "=", id));
return null;
}
/**
* 获取报名人数
*
* @param lineId 线路id
* @param unionId 工会
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckLogin
public Object getSignUpUserNum(String lineId, String unionId) {
TheRapyRecuperationEnroll enroll = dao.fetch(TheRapyRecuperationEnroll.class, Cnd.where("takePartInUnionId", "=", unionId).and("takePartInLineId", "=", lineId).and("stateId", "=", TheRapyRecuperationState.PASS));
dao.fetchLinks(enroll, "companionList");
Sql sql = Sqls.create("""
select
(select count(1) from inclusive_therapy_v3_enroll where isNormal=true and takePartInUnionId = @unionId AND takePartInLineId = @lineId AND stateId = @signUpSuccessCode) as signUpUserNum,
(select count(1) from inclusive_therapy_v3_enroll_companion where trreId in (select id from inclusive_therapy_v3_enroll where isNormal=true and takePartInUnionId = @unionId AND takePartInLineId = @lineId AND stateId = @signUpSuccessCode)) as signUpUserFamilyNum
""");
sql.setParam("signUpSuccessCode", TheRapyRecuperationState.PASS);
sql.setParam("lineId", lineId);
sql.setParam("unionId", unionId);
Object result = Daos.query(dao, sql.toString(), Sqls.callback.map());
return result;
}
/**
* 手机端线路介绍所有信息
*
* @param usId 行id
* @param usUnionId 我们工会id
* @return {@link Object}
*/
@At("/selectLineAllInfo")
@GET
@ViReturn
@SaCheckLogin
public Object selectLineAllInfo(@Param("usId") String usId,
@Param("usUnionId") String usUnionId,
@Param("year") String year) {
Assert.notBlank(usId);
return enrollService.selectLineAllInfo(usId, usUnionId, year);
}
@At
@ViReturn
@SaCheckLogin
public Object getSchoolTime() {
TherapyUser sysUser = dao.fetch(TherapyUser.class, TherapyContext.getUserId());
if(StrUtil.isNotBlank(sysUser.getSchoolTime())) {
DateTime schoolDate = DateUtil.parse(sysUser.getSchoolTime());
DateTime time = DateUtil.parse(DateUtil.thisYear() + "-07-01");
int compareResult = DateUtil.compare(schoolDate, time);
return compareResult >= 0 ? sysUser.getSchoolTime() : null;
} else {
return null;
}
}
}
@@ -0,0 +1,166 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollJoinUserImportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process.TheRapyRecuperationEnrollJoinUserImport
* @Description: 导入参加人员
* @Author zxc
* @Date 2022/6/14:09:16
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/joinUserImport")
@Ok("json:full")
@Slf4j
public class TheRapyRecuperationEnrollJoinUserImportController {
@Inject
private Dao dao;
@Inject
private TheRapyRecuperationEnrollJoinUserImportService joinUserImportService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/joinUserImport.html")
@SaCheckPermission("inclusiveTherapyV3.joinUser.import")
public void index() {
}
@At
@SaCheckPermission("inclusiveTherapyV3.joinUser.import")
@ViReturn
public Object selectLineAndTravelAgencyList(Integer year, String keyword) {
return joinUserImportService.selectLineAndTravelAgencyList(year, keyword);
}
@At
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@SaCheckPermission("inclusiveTherapyV3.joinUser.import")
public Object readExcel(@Param("file") TempFile tempFile, @Param("lineId") String lineId, @Param("travelAgencyId") String travelAgencyId) {
try {
Assert.notNull(tempFile);
File file = tempFile.getFile();
String extName = FileUtil.extName(file);
if (!List.of("XLSX", "XLS").contains(extName.toUpperCase())) {
return Result.error("请上传excel文件");
}
if (StrUtil.isBlank(lineId) && StrUtil.isBlank(travelAgencyId)) {
return Result.error("参数错误");
}
ImportParams importParams = new ImportParams();
List<TheRapyRecuperationEnroll> list = ExcelImportUtil.importExcel(file, TheRapyRecuperationEnroll.class, importParams);
if (Lang.isEmpty(list)) {
return Result.error("excel无数据");
}
List<TheRapyRecuperationEnroll> matchList = new ArrayList<>();
Dao ext = Daos.ext(dao, FieldFilter.create(TheRapyRecuperationEnroll.class, "id|loginName|userName|sex|unionName|signingUptime"));
for (TheRapyRecuperationEnroll enroll : list) {
Cnd cnd = Cnd.NEW();
cnd.andEX("takePartInLineId", "=", lineId);
cnd.andEX("takePartInTravelAgencyId", "=", travelAgencyId);
cnd.and("loginName", "=", enroll.getLoginName());
TheRapyRecuperationEnroll oneEnroll = ext.fetch(TheRapyRecuperationEnroll.class, cnd);
if (Lang.isNotEmpty(oneEnroll)) {
oneEnroll.setTakePartInTime(enroll.getTakePartInTime());
matchList.add(oneEnroll);
}
}
return Result.success(Map.of("excelRows", list, "matchList", matchList));
} catch (Exception e) {
log.error(e.getMessage());
return Result.error(e.getMessage());
}
}
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.joinUser.import")
public Object selectLineOrTravelAgency(Integer year) {
return joinUserImportService.selectLineOrTravelAgency(year);
}
/**
* 导入用户
*
* @param enrolls 招收
* @return {@link Object}
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.joinUser.import")
public Object doImportTakePartInUsers(@Param("enroll") TheRapyRecuperationEnroll[] enrolls) {
for (TheRapyRecuperationEnroll enroll : enrolls) {
enroll.setTakePartIn(true);
}
dao.updateIgnoreNull(enrolls);
return null;
}
/**
* 下载模板
*
* @param response 响应
*/
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.joinUser.import")
public void downloadTemplate(HttpServletResponse response) {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
List<TheRapyRecuperationEnroll> exampleList = new ArrayList<>();
exampleList.add(new TheRapyRecuperationEnroll().setLoginName("2000").setUserName("张三").setTakePartInTime(new Date()));
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, TheRapyRecuperationEnroll.class, exampleList);
try {
TherapyDownload.excelResponse(response, "参加人员.xlsx");
workbook.write(response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,18 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process.TheRapyRecuperationExamineController
* @Description: 疗休养报名审核
* @Author zxc
* @Date 2022/6/1:18:16
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/line/UnionSelect")
@Ok("json:full")
public class TheRapyRecuperationExamineController {
}
@@ -0,0 +1,207 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import cn.hutool.core.lang.Assert;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyMessage;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyUser;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationSignUpMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineAdjustmentService;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineAdjustment
* @Description: 线路及人员调整
* @Author zxc
* @Date 2022/6/10:10:00
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/lineAdjustment")
@Ok("json:full")
@Slf4j
public class TheRapyRecuperationLineAdjustmentController {
@Inject
private Dao dao;
@Inject
private TherapyMessage msgApi;
@Inject
private TheRapyRecuperationLineAdjustmentService adjustmentService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/lineAdjustment.html")
@SaCheckPermission("inclusiveTherapyV3.line.adjustment")
public void index() {
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @return {@link Object}
*/
@At
@POST
@Ok("json:full")
@ViReturn
@SaCheckRole(value = {"sysadmin", "A06", "H04", "SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN", "BRANCH_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN"}, mode = SaMode.OR)
public Object pageData(PageForm pageForm,
Integer year,
String lineId,
String unionId,
String keywords,
String regionalNature,
String lotId) {
return adjustmentService.pageData(pageForm, year, lineId, unionId, keywords, regionalNature, lotId);
}
/**
* 查询分工会报名模式线路
*
* @param year 年度
* @return {@link Object}
*/
@At("/findUnionSignUpModeLineList")
@POST
@Ok("json:full")
@ViReturn
@SaCheckLogin
public Object findUnionSignUpModeLineList(Integer year) {
Sql sql = Sqls.create("""
select id,lineName from inclusive_therapy_v3_line
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("signUpMode", "=", TheRapyRecuperationSignUpMode.UNION.getValue());
cnd.andEX("year", "=", year);
sql.setCondition(cnd);
return adjustmentService.listMap(sql);
}
/**
* 查询分工会模式报名的用户
*
* @param lineId lineId
* @return {@link Object}
*/
@At
@POST
@Ok("json:full")
@SaCheckLogin
public Object findUnionSignUpModeUserList(@Param("lineId") String lineId, @Param("unionId") String unionId) {
try {
Assert.notBlank(lineId);
return Result.success().addData(adjustmentService.findUnionSignUpModeUserList(lineId, unionId));
} catch (Exception e) {
log.error(e.getMessage());
return Result.error(e.getMessage());
}
}
/**
* 调整用户
*
* @param lineId 线路id
* @param loginName 登录名
* @return {@link Object}
*/
@At
@POST
@Ok("json:full")
@SaCheckLogin
public Object adjustmentUser(String lineId, @Param("loginNames") String[] loginName) {
try {
Assert.notBlank(lineId);
Assert.notNull(loginName);
Chain chain = Chain.makeSpecial("isNormal", "isNormal ^ 1");
Cnd cnd = Cnd.where("takePartInLineId", "=", lineId);
cnd.and("loginName", "in", loginName);
dao.update(TheRapyRecuperationEnroll.class, chain, cnd);
return Result.success();
} catch (Exception e) {
log.error(e.getMessage());
return Result.error(e.getMessage());
}
}
@At
@POST
@Ok("json:full")
@SaCheckLogin
public Object smsAlerts(String lineId,@Param("loginNames") String[] loginName){
try {
Sql sql = Sqls.create("""
SELECT
rlus.id,
rlus.unionId,
rlus.lineId,
rlus.selectUserId,
DATE_FORMAT( rlus.playStartTime, '%Y-%m-%d' ) AS playStartTime,
DATE_FORMAT( rlus.playEndTime, '%Y-%m-%d' ) AS playEndTime,
rl.lineName,
rl.regionalNature,
lot.lotName
FROM
`inclusive_therapy_v3_line_union_select` rlus
LEFT JOIN `inclusive_therapy_v3_line` rl ON rlus.lineId = rl.id
LEFT JOIN `inclusive_therapy_v3_lot` lot ON rl.lotId = lot.id
WHERE
rlus.id = @id
""").setParam("id",lineId);
NutMap map = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map());
String lineName = map.getString("lineName");
String lotName = map.getString("lotName");
String regionalNature = map.getString("regionalNature");
String playStartTime = map.getString("playStartTime");
String playEndTime = map.getString("playEndTime");
List<TherapyUser> userList = dao.query(TherapyUser.class, Cnd.where("loginname", "in", loginName));
Map<String, String> usernameMap = userList.stream().collect(Collectors.toMap(TherapyUser::getLoginname, TherapyUser::getUsername));
if (Lang.isNotEmpty(loginName)){
Arrays.stream(loginName).forEach(v->{
String username = usernameMap.get(v);
String content = "%s老师您好,您报名的%s【%s-%s】(%s至%s)线路未达到成团标准,现已解散,请您选择其他线路进行报名!"
.formatted(username,lineName,lotName,regionalNature,playStartTime,playEndTime);
//msgApi.sendWxMsg(content,v);
});
}
return Result.success();
} catch (Exception e){
e.printStackTrace();
return Result.error();
}
}
}
@@ -0,0 +1,128 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import cn.hutool.core.lang.Assert;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationCluster;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationClusterMember;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineClusterService;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process.TheRapyRecuperationLineClusterController
* @Description: TODO
* @Author zxc
* @Date 2022/6/17:08:52
* @Version V1.0
**/
@IocBean
@At("/platform/inclusiveTherapyV3/lineCluster")
@Ok("json:full")
public class TheRapyRecuperationLineClusterController {
@Inject
private TheRapyRecuperationLineClusterService clusterService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/lineCluster.html")
@SaCheckPermission("inclusiveTherapyV3.lineCluster")
public void index() {
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @param keywords 关键字
* @return {@link Object}
*/
@At
@ViReturn
@POST
@SaCheckLogin
@SaCheckPermission("inclusiveTherapyV3.lineCluster")
public Object pageData(PageForm pageForm, Integer year, String keywords, String unionId) {
Pagination pagination = clusterService.pageData(pageForm, year, unionId, keywords);
return pagination;
}
/**
* 查询组团信息
*
* @param lineId 线路id
* @param usUnionId 归属工会id
* @return {@link Object}
*/
@At
@ViReturn
@POST
@SaCheckLogin
public Object findClusterInfo(@Param("lineId") String lineId, @Param("usUnionId") String usUnionId) {
Assert.notBlank(lineId);
Assert.notBlank(usUnionId);
return clusterService.findClusterInfo(lineId, usUnionId);
}
/**
* 设置组团成员
*
* @param clusters 集群
* @return {@link Object}
*/
@At
@ViReturn
@POST
@SaCheckLogin
@SLog(tag = "疗休养", msg = "设置组团人员", param = true, result = true)
public Object setClusterMembers(@Param("clusters") String clusters, @Param("lineId") String lineId) {
NutMap nutMap = Json.fromJson(NutMap.class, clusters);
List<TheRapyRecuperationCluster> clusterList = new ArrayList<>();
nutMap.forEach((k, v) -> {
if (!"unSelectedUsers".equals(k)) {
TheRapyRecuperationCluster t = Lang.map2Object((Map<?, ?>) v, TheRapyRecuperationCluster.class);
t.setLineId(lineId);
clusterList.add(t);
if (Lang.isNotEmpty(t.getMembers())) {
for (TheRapyRecuperationClusterMember member : t.getMembers()) {
member.setLineId(lineId);
}
}
}
});
clusterService.setClusterMembers(clusterList, lineId);
return null;
}
@At("/selectClusterInfo/?")
@ViReturn
@POST
@SaCheckLogin
public Object selectClusterInfo(String lineId) {
List<TheRapyRecuperationCluster> clusters = clusterService.query(Cnd.where("lineId", "=", lineId));
clusterService.fetchLinks(clusters, null);
return clusters;
}
}
@@ -0,0 +1,461 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
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 cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollBed;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollChangeRecord;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollCompanion;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLot;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.LineSelectionOverviewTimeSlotVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.LineSelectionOverviewVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineUnionSelectService;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 管理员查看全部分工会已选择线路。
*/
@IocBean
@At("/platform/inclusiveTherapyV3/lineSelectionOverview")
@Ok("json:full")
public class TheRapyRecuperationLineSelectionOverviewController {
@Inject
private Dao dao;
@Inject
private TheRapyRecuperationLineUnionSelectService lineUnionSelectService;
/**
* 管理员查看分工会已选择线路页面。
*/
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/lineSelectionOverview.html")
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
public void index() {
}
/**
* 查询管理员查看线路选择情况列表。
*
* @param pageForm 分页参数,包含 pageNumber、pageSize、pageOrderName、pageOrderBy
* @param year 年度;为空时默认当前年度
* @param keywords 线路名称或旅行社名称关键字
* @param unionId 分工会 ID;为空时查询全部分工会
* @param lotId 时间标段 ID;为空时查询全部时间标段
* @param travelAgencyId 旅行社 ID;为空时查询全部旅行社
* @param regionalNature 线路类型;传“全部”或空时查询全部类型
* @return 分页后的已选择线路 VO,list 字段为 {@link LineSelectionOverviewVo}
*/
@At
@POST
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
public Object pageData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "keywords") String keywords,
@Param(value = "unionId") String unionId,
@Param(value = "lotId") String lotId,
@Param(value = "travelAgencyId") String travelAgencyId,
@Param(value = "regionalNature") String regionalNature) {
Sql listSql = buildSelectionOverviewSql(pageForm, year, keywords, unionId, lotId, travelAgencyId, regionalNature);
Pagination pagination = lineUnionSelectService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), listSql);
List<NutMap> rowList = pagination.getList();
List<LineSelectionOverviewVo> voList = new ArrayList<>();
for (NutMap row : rowList) {
voList.add(new LineSelectionOverviewVo()
.setLineId(row.getString("lineId"))
.setLineUnionSelectId(row.getString("lineUnionSelectId"))
.setLineUnionSelectIds(row.getString("lineUnionSelectIds"))
.setYear(row.getInt("year"))
.setSerialNumber(row.getInt("serialNumber"))
.setLineName(row.getString("lineName"))
.setRegionalNature(row.getString("regionalNature"))
.setLotName(row.getString("lotName"))
.setPlayTimes(row.getString("playTimes"))
.setSignUpTimes(row.getString("signUpTimes"))
.setAdjustSignUpEndTime(row.getString("adjustSignUpEndTime"))
.setSignUpMode(row.getInt("signUpMode"))
.setUnionId(row.getString("unionId"))
.setUnionName(row.getString("unionName"))
.setIsOpen(toBoolean(row.get("isOpen"))));
}
pagination.setList(voList);
return pagination;
}
/**
* 导出管理员查看线路选择情况列表。
*
* @param pageForm 排序参数,包含 pageOrderName、pageOrderBy;导出不使用分页参数
* @param year 年度;为空时默认当前年度
* @param keywords 线路名称或旅行社名称关键字
* @param unionId 分工会 ID;为空时导出全部分工会
* @param lotId 时间标段 ID;为空时导出全部时间标段
* @param travelAgencyId 旅行社 ID;为空时导出全部旅行社
* @param regionalNature 线路类型;传“全部”或空时导出全部类型
* @param response HTTP 响应对象,方法直接写出 xlsx 文件,无 JSON 返回
*/
@At
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
public void doExportExcel(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "keywords") String keywords,
@Param(value = "unionId") String unionId,
@Param(value = "lotId") String lotId,
@Param(value = "travelAgencyId") String travelAgencyId,
@Param(value = "regionalNature") String regionalNature,
HttpServletResponse response) throws IOException {
Sql listSql = buildSelectionOverviewSql(pageForm, year, keywords, unionId, lotId, travelAgencyId, regionalNature);
List<NutMap> list = queryMapList(listSql);
ArrayList<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("选择工会", "unionName", 25));
exportEntities.add(new ExcelExportEntity("线路名称", "lineName", 35));
exportEntities.add(new ExcelExportEntity("线路类型", "regionalNature", 15));
exportEntities.add(new ExcelExportEntity("报名时间", "signUpTimes", 30));
exportEntities.add(new ExcelExportEntity("出行时间", "playTimes", 40));
TherapyDownload.excelResponse(response, "线路选择情况.xlsx");
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
workbook.write(response.getOutputStream());
workbook.close();
}
/**
* 查询某个分工会已选择线路的出行时间段。
*
* @param lineId 线路 ID,对应 inclusive_therapy_v3_line.id
* @param unionId 分工会 ID,对应 sys_union.id
* @param year 年度;为空时默认当前年度
* @return 出行时间段 VO 列表,元素为 {@link LineSelectionOverviewTimeSlotVo}
*/
@At
@POST
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
public Object timeSlots(@Param("lineId") String lineId,
@Param("unionId") String unionId,
@Param(value = "year") Integer year) {
Assert.notBlank(lineId, "请选择线路");
Assert.notBlank(unionId, "请选择分工会");
Sql sql = Sqls.create("""
SELECT
us.id,
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.adjustSignUpEndTime,
us.playStartTime,
us.playEndTime,
us.travelAgencyId,
ta.travelAgencyName,
us.contact,
us.contactPhone,
us.principal,
us.principalContact,
us.trafficTools,
us.estimatedCost,
us.estimatedFamilyNumbers,
us.maxPeopleNumber,
us.enable
FROM
inclusive_therapy_v3_line_union_select us
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = us.travelAgencyId
WHERE
us.lineId = @lineId
AND us.unionId = @unionId
AND us.signUpMode = 1
AND YEAR(us.selectTime) = @year
ORDER BY
us.playStartTime ASC
""");
sql.setParam("lineId", lineId);
sql.setParam("unionId", unionId);
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
List<NutMap> rowList = queryMapList(sql);
List<LineSelectionOverviewTimeSlotVo> voList = new ArrayList<>();
for (NutMap row : rowList) {
voList.add(new LineSelectionOverviewTimeSlotVo()
.setId(row.getString("id"))
.setSignUpStartTime(toDate(row.get("signUpStartTime")))
.setSignUpEndTime(toDate(row.get("signUpEndTime")))
.setChangeEndTime(toDate(row.get("changeEndTime")))
.setAdjustSignUpEndTime(toDate(row.get("adjustSignUpEndTime")))
.setPlayStartTime(toDate(row.get("playStartTime")))
.setPlayEndTime(toDate(row.get("playEndTime")))
.setTravelAgencyId(row.getString("travelAgencyId"))
.setTravelAgencyName(row.getString("travelAgencyName"))
.setContact(row.getString("contact"))
.setContactPhone(row.getString("contactPhone"))
.setPrincipal(row.getString("principal"))
.setPrincipalContact(row.getString("principalContact"))
.setTrafficTools(row.getString("trafficTools"))
.setEstimatedCost(row.getString("estimatedCost"))
.setEstimatedFamilyNumbers(row.getInt("estimatedFamilyNumbers"))
.setMaxPeopleNumber(row.getInt("maxPeopleNumber"))
.setEnable(toBoolean(row.get("enable"))));
}
return voList;
}
/**
* 管理员修改某个分工会已选择线路的出行时间段。
*
* @param lineUnionSelects 出行时间段数组,包含报名时间、出行时间、旅行社、联系人、人数和启用状态等字段
* @param lineId 线路 ID,对应 inclusive_therapy_v3_line.id
* @param unionId 分工会 ID,对应 sys_union.id
* @param year 年度;为空时默认当前年度
* @return ViReturn 统一包装结果,成功时 data 为空
*/
@At
@POST
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
@Aop(TransAop.READ_COMMITTED)
public Object saveTimeSlots(@Param("lineUnionSelects") TheRapyRecuperationLineUnionSelect[] lineUnionSelects,
@Param("lineId") String lineId,
@Param("unionId") String unionId,
@Param(value = "year") Integer year) {
Assert.notBlank(lineId, "请选择线路");
Assert.notBlank(unionId, "请选择分工会");
lineUnionSelectService.adminSaveLineTimes(lineUnionSelects, lineId, unionId, year);
return null;
}
/**
* 管理员取消分工会已选择线路。
*
* @param lineId 线路 ID,对应 inclusive_therapy_v3_line.id
* @param unionId 分工会 ID,对应 sys_union.id
* @param year 年度;为空时默认当前年度
* @return ViReturn 统一包装结果,成功时 data 为空
*/
@At
@POST
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
@Aop(TransAop.READ_COMMITTED)
public Object cancelLine(@Param("lineId") String lineId,
@Param("unionId") String unionId,
@Param(value = "year") Integer year) {
Assert.notBlank(lineId, "请选择线路");
Assert.notBlank(unionId, "请选择分工会");
Integer queryYear = year == null ? DateUtil.thisYear() : year;
List<TheRapyRecuperationLineUnionSelect> unionSelects = lineUnionSelectService.query(Cnd.where("lineId", "=", lineId)
.and("unionId", "=", unionId)
.and("signUpMode", "=", 1)
.and("YEAR(selectTime)", "=", queryYear));
if (Lang.isEmpty(unionSelects)) {
throw Lang.makeThrow("未找到该分工会选择的线路");
}
// 取消线路会清理该分工会该线路下所有选择时段,以及这些时段关联的报名、床位、同伴和变更记录。
List<String> selectIds = unionSelects.stream()
.map(TheRapyRecuperationLineUnionSelect::getId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
List<TheRapyRecuperationEnroll> enrolls = lineUnionSelectService.dao()
.query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds));
List<String> enrollIds = enrolls.stream()
.map(TheRapyRecuperationEnroll::getId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
List<String> bedIds = enrolls.stream()
.map(TheRapyRecuperationEnroll::getBedInfoId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
if (Lang.isNotEmpty(enrollIds)) {
List<TheRapyRecuperationEnrollCompanion> companions = lineUnionSelectService.dao()
.query(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIds));
List<String> companionBedIds = companions.stream()
.map(TheRapyRecuperationEnrollCompanion::getBedInfoId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
lineUnionSelectService.dao().clear(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIds));
lineUnionSelectService.dao().clear(TheRapyRecuperationEnrollChangeRecord.class, Cnd.where("enrollId", "in", enrollIds));
if (Lang.isNotEmpty(companionBedIds)) {
lineUnionSelectService.dao().clear(TheRapyRecuperationEnrollBed.class, Cnd.where("id", "in", companionBedIds));
}
lineUnionSelectService.dao().clear(TheRapyRecuperationEnroll.class, Cnd.where("id", "in", enrollIds));
}
if (Lang.isNotEmpty(bedIds)) {
lineUnionSelectService.dao().clear(TheRapyRecuperationEnrollBed.class, Cnd.where("id", "in", bedIds));
}
lineUnionSelectService.clear(Cnd.where("id", "in", selectIds));
return null;
}
/**
* 查询旅行社下拉选项。
*
* @param year 年度;为空时默认当前年度
* @return 旅行社实体列表,前端使用 id 和 travelAgencyName
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
public Object travelAgencyOptions(@Param(value = "year") Integer year) {
// 旅行社按年度维护,管理员查看页切换年度时下拉框只展示该年度可选旅行社。
return dao.query(TheRapyRecuperationTravelAgency.class,
Cnd.where("year", "=", year == null ? DateUtil.thisYear() : year).asc("serialNumber"));
}
/**
* 查询时间标段下拉选项。
*
* @return 当前基础设置中的时间标段实体列表,前端使用 id 和 lotName
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.lineSelectionOverview")
public Object lotOptions() {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
return Optional.ofNullable(config)
.map(TheRapyRecuperationConfig::getLots)
.orElseGet(ArrayList::new);
}
private Sql buildSelectionOverviewSql(PageForm pageForm, Integer year, String keywords, String unionId, String lotId,
String travelAgencyId, String regionalNature) {
Sql listSql = Sqls.create("""
SELECT
line.id AS lineId,
us.id AS lineUnionSelectId,
us.id AS lineUnionSelectIds,
line.year,
line.serialNumber,
line.lineName,
line.regionalNature,
lot.lotName,
IF(us.playStartTime IS NULL OR us.playEndTime IS NULL,
NULL,
CONCAT(DATE_FORMAT(us.playStartTime, '%Y-%m-%d %H:%i'), '至', DATE_FORMAT(us.playEndTime, '%Y-%m-%d %H:%i'), IFNULL(CONCAT('(', ta.travelAgencyName, ')'), ''))
) AS playTimes,
IF(us.signUpStartTime IS NULL OR us.signUpEndTime IS NULL,
NULL,
CONCAT(DATE_FORMAT(us.signUpStartTime, '%Y-%m-%d %H:%i'), '至', DATE_FORMAT(us.signUpEndTime, '%Y-%m-%d %H:%i'))
) AS signUpTimes,
DATE_FORMAT(us.adjustSignUpEndTime, '%Y-%m-%d %H:%i') AS adjustSignUpEndTime,
us.signUpMode,
us.unionId,
selectUnion.unionname AS unionName,
us.isOpen
FROM
inclusive_therapy_v3_line_union_select us
LEFT JOIN inclusive_therapy_v3_line line ON line.id = us.lineId
LEFT JOIN inclusive_therapy_v3_union selectUnion ON selectUnion.id = us.unionId
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = us.travelAgencyId
LEFT JOIN inclusive_therapy_v3_lot lot ON lot.id = line.lotId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("us.signUpMode", "=", 1);
cnd.and("YEAR(us.selectTime)", "=", year == null ? DateUtil.thisYear() : year);
cnd.and("line.isDisabled", "=", 0);
cnd.andEX("us.unionId", "=", unionId);
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("us.travelAgencyId", "=", travelAgencyId);
if (StrUtil.isNotBlank(regionalNature) && !"全部".equals(regionalNature)) {
cnd.and("line.regionalNature", "=", regionalNature);
}
if (StrUtil.isNotBlank(keywords)) {
cnd.and(Cnd.exps("line.lineName", "like", "%" + keywords + "%")
.or("ta.travelAgencyName", "like", "%" + keywords + "%"));
}
addPageOrder(cnd, pageForm);
listSql.setCondition(cnd);
return listSql;
}
private void addPageOrder(Cnd cnd, PageForm pageForm) {
if (pageForm == null) {
addDefaultOrder(cnd);
return;
}
String orderName = pageForm.getPageOrderName();
String orderBy = pageForm.getPageOrderBy();
if (StrUtil.isNotBlank(orderName) && StrUtil.isNotBlank(orderBy)) {
String direction = "ascending".equals(orderBy) ? "asc" : "desc";
switch (orderName) {
case "lineName" -> cnd.orderBy("line.lineName", direction);
case "regionalNature" -> cnd.orderBy("line.regionalNature", direction);
case "lotName" -> cnd.orderBy("lot.lotName", direction);
case "playTime" -> cnd.orderBy("us.playStartTime", direction);
case "signUpTimes" -> cnd.orderBy("us.signUpStartTime", direction);
case "adjustSignUpEndTime" -> cnd.orderBy("us.adjustSignUpEndTime", direction);
case "signUpMode" -> cnd.orderBy("us.signUpMode", direction);
case "unionName" -> cnd.orderBy("selectUnion.unionname", direction);
case "isOpen" -> cnd.orderBy("us.isOpen", direction);
default -> addDefaultOrder(cnd);
}
} else {
addDefaultOrder(cnd);
}
}
private void addDefaultOrder(Cnd cnd) {
// 一条出行记录对应一条线路选择记录,默认先按年度、线路编号,再按出行开始时间排序。
cnd.desc("line.year").asc("line.serialNumber").asc("us.playStartTime").asc("selectUnion.unionname");
}
private List<NutMap> queryMapList(Sql sql) {
return (List<NutMap>) Daos.query(dao, sql.toString(), Sqls.callback.maps());
}
private Date toDate(Object value) {
return value instanceof Date ? (Date) value : null;
}
private Boolean toBoolean(Object value) {
if (value instanceof Boolean) {
return (Boolean) value;
}
if (value instanceof Number) {
return ((Number) value).intValue() == 1;
}
return value != null && Boolean.parseBoolean(value.toString());
}
}
@@ -0,0 +1,447 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationProvinceType;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.*;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.UnionLineSelectLimitVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineUnionSelectService;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
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.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import java.util.*;
import java.util.stream.Collectors;
/**
* 疗休养工会选择表
*
* @author jug
* @date 2023/06/26
*/
@IocBean
@At(value = {"/platform/inclusiveTherapyV3/lineFghSelect", "/platform/inclusiveTherapyV3/lineXghSelect", "/platform/inclusiveTherapyV3/lineUnionSelect"})
@Ok("json:full")
@Slf4j
public class TheRapyRecuperationLineUnionSelectController {
@Inject
private TherapyContext vi;
@Inject
private Dao dao;
@Inject
private TheRapyRecuperationLineUnionSelectService unionSelectService;
@At("")
@Ok("re")
// @Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/lineUnionSelect.html")
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public String index(@Param("mode") Integer mode) {
return "beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/lineUnionSelect.html";
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public Object pageData(PageForm pageForm, Integer year, String keywords, int selectStatus, String unionId,
String lotId, String travelAgencyId, Integer mode, String regionalNature) {
TheRapyRecuperationConfig config = unionSelectService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
Integer queryMode = mode == null ? 1 : mode;
Cnd cnd = Cnd.NEW();
cnd.andEX("line.lotId", "=", lotId);
addTravelAgencyCondition(cnd, travelAgencyId);
if (!"全部".equals(regionalNature)) {
cnd.andEX("line.regionalNature", "=", regionalNature);
}
// 按页面入口 mode 区分已选择线路:mode=1 查当前分工会选择,mode=2 查校工会选择。
Sql hasSelectLineSql;
if (Integer.valueOf(1).equals(queryMode)) {
SqlExpressionGroup lineScope = new SqlExpressionGroup();
if (!"全部".equals(regionalNature)) {
lineScope.or(Cnd.exps("line.createUnionId", "=", TherapyContext.getUnionId()).and("line.regionalNature", "=", regionalNature));
} else {
lineScope.or("line.createUnionId", "=", TherapyContext.getUnionId());
}
lineScope.or("line.createMode", "=", 2);
cnd.and(lineScope);
hasSelectLineSql = Sqls.createf("""
select lineId from inclusive_therapy_v3_line_union_select where unionId = '%s' AND signUpMode = %s AND year(selectTime) = %s
""", TherapyContext.getUnionId(), queryMode, year == null ? DateUtil.thisYear() : year);
} else {
hasSelectLineSql = Sqls.createf("""
select lineId from inclusive_therapy_v3_line_union_select where signUpMode = %s AND year(selectTime) = %s
""", queryMode, year == null ? DateUtil.thisYear() : year);
}
/*hasSelectLineSql = Sqls.createf("""
select lineId from inclusive_therapy_v3_line_union_select where unionId = '%s'
""", Vi.getUnionId());*/
switch (selectStatus) {
//查询未选择的线路
case -1 -> {
cnd.and("line.id", "not in", hasSelectLineSql);
cnd.and("line.year", "in", year == null ? Lang.array(config.getProvinceStartYear(), config.getProvinceStartYear() + 1) : year);
}
case 0 -> {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("us.signUpMode", "is", null);
seg.or("us.signUpMode", "=", mode);
cnd.and(seg);
}
/*case 0 -> {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or(Cnd.exps("line.id", "not in", hasSelectLineSql).and("line.createMode", "=", TheRapyRecuperationLineCreateMode.SCHOOL.getValue()));
seg.or("line.id", "in", hasSelectLineSql);
cnd.and(seg);
}*/
//查询已选择的线路
case 1 -> {
cnd.and("line.id", "in", hasSelectLineSql);
cnd.and("us.signUpMode", "=", queryMode);
cnd.and("year(us.selectTime)", "=", year == null ? DateUtil.thisYear() : year);
}
}
cnd.and("line.isDisabled", "=", 0);
if (StrUtil.isNotBlank(keywords)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("line.lineName", keywords);
cnd.and(seg);
}
if (StrUtil.isAllNotEmpty(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), pageForm.getPageOrderBy().replace("ending", ""));
} else {
cnd.asc("createUnionId").desc("year").asc("serialNumber");
}
return unionSelectService.pageData(pageForm, cnd, year, queryMode);
}
/**
* 查询当前登录人所属分工会本年度线路选择数量要求和已选择数量。
*
* @param year 年度,页面年度筛选值;为空时按当前年度统计
* @param mode 选择线路页面类型,1 表示分工会选择线路,2 表示校工会选择线路
* @return 分工会线路选择数量提示 VO
*/
@At
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public Object getUnionLineSelectLimit(Integer year, Integer mode) {
String unionId = TherapyContext.getUnionId();
Integer queryYear = year == null ? DateUtil.thisYear() : year;
Integer queryMode = mode == null ? 1 : mode;
UnionLineSelectLimitVo vo = new UnionLineSelectLimitVo()
.setMinProvinceOutNumber(0)
.setMinProvinceInNumber(0)
.setSelectedProvinceOutNumber(0)
.setSelectedProvinceInNumber(0);
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
List<NutMap> unionLineNumberConfigs = Optional.ofNullable(config)
.map(TheRapyRecuperationConfig::getUnionLineNumberConfigs)
.orElse(Collections.emptyList());
for (NutMap lineNumberConfig : unionLineNumberConfigs) {
if (Objects.equals(unionId, lineNumberConfig.getString("unionId"))) {
vo.setMinProvinceOutNumber(Optional.ofNullable(lineNumberConfig.getInt("minProvinceOutNumber")).orElse(0));
vo.setMinProvinceInNumber(Optional.ofNullable(lineNumberConfig.getInt("minProvinceInNumber")).orElse(0));
break;
}
}
Sql selectedSql = Sqls.create("""
SELECT
line.regionalNature,
COUNT(us.id) AS selectedNumber
FROM
inclusive_therapy_v3_line_union_select us
LEFT JOIN inclusive_therapy_v3_line line ON line.id = us.lineId
WHERE
us.unionId = @unionId
AND us.signUpMode = @mode
AND YEAR(us.selectTime) = @year
GROUP BY
line.regionalNature
""");
selectedSql.setParam("unionId", unionId);
selectedSql.setParam("mode", queryMode);
selectedSql.setParam("year", queryYear);
List<NutMap> selectedList = (List<NutMap>) Daos.query(dao, selectedSql.toString(), Sqls.callback.maps());
for (NutMap selected : selectedList) {
if (Objects.equals(TheRapyRecuperationProvinceType.provinceOut.getValue(), selected.getString("regionalNature"))) {
vo.setSelectedProvinceOutNumber(Optional.ofNullable(selected.getInt("selectedNumber")).orElse(0));
} else if (Objects.equals(TheRapyRecuperationProvinceType.provinceIn.getValue(), selected.getString("regionalNature"))) {
vo.setSelectedProvinceInNumber(Optional.ofNullable(selected.getInt("selectedNumber")).orElse(0));
}
}
return vo;
}
/**
* 分工会选择线路
*
* @param us 分工会选择线路信息
* @return {@link Object}
*/
@At("/selectLine")
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
@Aop(TransAop.READ_COMMITTED)
public Object selectLine(TheRapyRecuperationLineUnionSelect us) {
unionSelectService.validateLineSelectTime(us.getMode());
unionSelectService.selectLine(us);
return null;
}
/**
* 分工会选择线路时间
*
* @param lineUnionSelects 分工会选择线路
* @return {@link Object}
*/
@At("/selectLineTimes")
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
@Aop(TransAop.READ_COMMITTED)
public Object selectLineTimes(@Param("lineUnionSelects") TheRapyRecuperationLineUnionSelect[] lineUnionSelects) {
unionSelectService.selectLineTimes(lineUnionSelects);
return null;
}
@At
@POST
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public Object selectLineInfo(@Param("lineId") String lineId, @Param("unionId") String unionId, @Param("mode") Integer mode, @Param("year") Integer year) {
try {
Assert.notBlank(lineId);
Assert.notNull(mode);
unionId = StrUtil.emptyToNull(TherapyContext.getUnionId());
return Result.success(unionSelectService.selectLineInfo(lineId, unionId, mode, year));
} catch (Exception e) {
log.error(e.getMessage());
return Result.error(e.getMessage());
}
}
/**
* 查询某个分工会设置的线路时间信息
*
* @param lineId 行id
* @param usUnionId 我们工会id
* @return {@link Object}
*/
@At
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public Object findUsLineInfo(String lineId, String usUnionId) {
return unionSelectService.findUsLineInfo(lineId, usUnionId);
}
@At("/deSelect")
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
@SLog(tag = "疗休养", msg = "取消选择线路", param = true, result = true)
@Aop(TransAop.READ_COMMITTED)
public Object deSelect(@Param("lineId") String lineId, @Param("unionId") String unionId, @Param("mode") Integer mode) {
try {
unionSelectService.validateLineSelectTime(mode);
Assert.notBlank(lineId);
Assert.notBlank(unionId);
// Cnd enrollCnd = Cnd.where("takePartInUnionId", "=", unionId);
// enrollCnd.and("takePartInLineId", "=", lineId);
Cnd enrollCnd = Cnd.where("unionId", "=", unionId);
enrollCnd.and("lineId", "=", lineId);
List<TheRapyRecuperationLineUnionSelect> unionSelects = unionSelectService.query(enrollCnd);
List<String> list = unionSelects.stream().map(TheRapyRecuperationLineUnionSelect::getId).collect(Collectors.toList());
List<TheRapyRecuperationEnroll> enrolls = unionSelectService.dao().query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "in", list));
List<String> enrollIdList = enrolls.stream().map(TheRapyRecuperationEnroll::getId).collect(Collectors.toList());
List<String> bedIdList = enrolls.stream().map(TheRapyRecuperationEnroll::getBedInfoId).collect(Collectors.toList());
//同伴信息
List<TheRapyRecuperationEnrollCompanion> companions = unionSelectService.dao().query(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIdList));
List<String> comBedIdList = companions.stream().map(TheRapyRecuperationEnrollCompanion::getBedInfoId).collect(Collectors.toList());
//删除报名记录
unionSelectService.dao().clear(TheRapyRecuperationEnroll.class, Cnd.where("id", "in", enrollIdList));
//删除床位记录
unionSelectService.dao().clear(TheRapyRecuperationEnrollBed.class, Cnd.where("id", "in", bedIdList));
//删除同伴信息
unionSelectService.dao().clear(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIdList));
//删除变更记录
unionSelectService.dao().clear(TheRapyRecuperationEnrollChangeRecord.class, Cnd.where("enrollId", "in", enrollIdList));
//删除同伴床位信息
unionSelectService.dao().clear(TheRapyRecuperationEnrollBed.class, Cnd.where("id", "in", comBedIdList));
unionSelectService.clear(enrollCnd);
return Result.success();
} catch (Exception e) {
return Result.error(e.getMessage());
}
// unionSelectService.deSelect(usId);
}
/**
* 旅行社
*
* @return {@link Object}
*/
@At
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public Object getTravelAgencyOptions(Integer year) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
cnd.asc("serialNumber");
List<TheRapyRecuperationTravelAgency> travelAgencies = unionSelectService.dao().query(TheRapyRecuperationTravelAgency.class, cnd);
return travelAgencies;
}
/**
* 按旅行社筛选线路,兼容未选择线路的主表旅行社和已选择线路的出行时间段旅行社。
*
* @param cnd 当前页面查询条件
* @param travelAgencyId 旅行社 ID,为空时不增加过滤条件
*/
private void addTravelAgencyCondition(Cnd cnd, String travelAgencyId) {
if (StrUtil.isBlank(travelAgencyId)) {
return;
}
SqlExpressionGroup travelAgencyGroup = new SqlExpressionGroup();
travelAgencyGroup.or("us.travelAgencyId", "=", travelAgencyId);
travelAgencyGroup.or("line.travelAgencyId", "=", travelAgencyId);
cnd.and(travelAgencyGroup);
}
/**
* 是否公开分工会选择线路
*
* @param id 分工会选择线路id
* @return {@link Object}
*/
@At("/isOpenUnionLine/?")
@POST
@ViReturn
@SaCheckLogin
public Object isOpenUnionLine(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
dao.update(TheRapyRecuperationLineUnionSelect.class, Chain.makeSpecial("isOpen", "isOpen ^ 1"), Cnd.where("id", "=", id));
return null;
}
@At("/getLineConfig/?")
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
public Object getLineConfig(String id) {
Sql sql = Sqls.create("select lotId, travelAgencyId from inclusive_therapy_v3_line where id = @lineId");
sql.setParam("lineId", id);
NutMap lineInfo = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map());
String lotId = lineInfo != null ? lineInfo.getString("lotId") : null;
String travelAgencyId = lineInfo != null ? lineInfo.getString("travelAgencyId") : null;
TheRapyRecuperationLot lotInfo = dao.fetch(TheRapyRecuperationLot.class, lotId);
Integer cost = Optional.ofNullable(lotInfo).map(v -> v.getActivityCost()).orElse(0);
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
Integer groupNumber = Optional.ofNullable(config).map(TheRapyRecuperationConfig::getGroupNumber).orElse(0);
Integer outsideQuota = Optional.ofNullable(config).map(TheRapyRecuperationConfig::getOutsideQuota).orElse(0);
return Result.success(Map.of("cost", cost, "groupNumber", groupNumber, "outsideQuota", outsideQuota, "travelAgencyId", travelAgencyId));
}
/**
* 一键统赋时间,针对于已选择的线路
*
* @param lineIds 线路Id数组
* @param lineUnionSelects 出行时段
* @return {@link Object}
*/
@At("/setGiveLineTimes")
@POST
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "普惠疗休养", tag = "分工会/校工会选择线路", msg = "一键统赋时间,针对于已选择的线路", param = true, result = true)
public Object setGiveLineTimes(@Param("lineIds") String[] lineIds, @Param("lineUnionSelects") TheRapyRecuperationLineUnionSelect[] lineUnionSelects) {
if (Lang.isNotEmpty(lineUnionSelects) && Lang.isNotEmpty(lineIds)) {
TheRapyRecuperationLineUnionSelect lineUnionSelect = lineUnionSelects[0];
Chain chain = Chain.make("enable", 1);
if (lineUnionSelect.getSignUpStartTime() != null)
chain.add("signUpStartTime", lineUnionSelect.getSignUpStartTime());
if (lineUnionSelect.getSignUpEndTime() != null)
chain.add("signUpEndTime", lineUnionSelect.getSignUpEndTime());
if (lineUnionSelect.getChangeEndTime() != null)
chain.add("changeEndTime", lineUnionSelect.getChangeEndTime());
if (lineUnionSelect.getPlayStartTime() != null)
chain.add("playStartTime", lineUnionSelect.getPlayStartTime());
if (lineUnionSelect.getPlayEndTime() != null) chain.add("playEndTime", lineUnionSelect.getPlayEndTime());
if (lineUnionSelect.getAdjustSignUpEndTime() != null) chain.add("adjustSignUpEndTime", lineUnionSelect.getAdjustSignUpEndTime());
dao.update(TheRapyRecuperationLineUnionSelect.class, chain, Cnd.where("id", "in", lineIds));
}
return null;
}
@At
@ViReturn
@SaCheckPermission(value = {"inclusiveTherapyV3.lineFghSelect", "inclusiveTherapyV3.lineXghSelect"}, mode = SaMode.OR)
@SLog(type = "普惠疗休养", tag = "分工会/校工会选择线路", msg = "是否开放对外报名", param = true, result = true)
public Object doEditOpen(String id) {
dao.update(TheRapyRecuperationLineUnionSelect.class, Chain.makeSpecial("isOpen", "isOpen ^ 1"), Cnd.where("id", "=", id));
return null;
}
}
@@ -0,0 +1,153 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.process;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.base.service.BaseService;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
import java.util.Map;
/**
* 查询统计
*
* @author zhf
* @date 2022/06/15
*/
@IocBean
@At("/platform/inclusiveTherapyV3/query/statics")
@Ok("json:full")
public class TheRapyRecuperationStatisticsController {
@Inject("refer:staffTherapyDataService")
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/process/queryStatics.html")
@SaCheckPermission("inclusiveTherapyV3.queryStatics")
public void index() {
}
@At
@ViReturn
@SaCheckLogin
public Object getLineBar(String regionalNature, Integer year) {
Sql sql = Sqls.create("""
SELECT
line.lineName,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll WHERE isNormal=true and line.id = takePartInLineId ) AS enrollNum,
(
SELECT
COUNT( 1 )
FROM
inclusive_therapy_v3_enroll_companion com
LEFT JOIN inclusive_therapy_v3_enroll enroll ON enroll.id = com.trreId
WHERE
line.id = enroll.takePartInLineId
AND com.loginName IS NULL
) AS companionNum
FROM
`inclusive_therapy_v3_line` line
where line.regionalNature=@regionalNature and line.year=@year
ORDER BY
signUpStartTime DESC
""").setParam("regionalNature", regionalNature).setParam("year", year);
return baseService.listMap(sql);
}
@At
@ViReturn
@SaCheckLogin
public Object getSnSwNum(Integer year) {
Sql sql = Sqls.create("""
SELECT
COUNT( 1 ) AS enrollNum,
(
SELECT
COUNT( 1 )
FROM
inclusive_therapy_v3_enroll_companion com
LEFT JOIN inclusive_therapy_v3_enroll enroll ON enroll.id = com.trreId
WHERE
line.id = enroll.takePartInLineId
AND com.loginName IS NULL
) AS companionNum
FROM
inclusive_therapy_v3_enroll enroll
LEFT JOIN inclusive_therapy_v3_line line ON line.id = enroll.takePartInLineId
$condition
""");
Cnd cndSn = Cnd.NEW();
sql.setCondition(cndSn);
cndSn.and("line.regionalNature", "=", "省内");
cndSn.and("line.year", "=", year);
List<NutMap> sn = baseService.listMap(sql);
Cnd cndSw = Cnd.NEW();
sql.setCondition(cndSw);
cndSw.and("line.regionalNature", "=", "省内");
cndSw.and("line.year", "=", year);
List<NutMap> sw = baseService.listMap(sql);
NutMap snMap = sn.get(0);
NutMap swMap = sw.get(0);
int snEnrollNum = Strings.isNotBlank(snMap.getString("enrollNum")) ? snMap.getInt("enrollNum") : 0;
int snCompanionNum = Strings.isNotBlank(snMap.getString("companionNum")) ? snMap.getInt("companionNum") : 0;
int swEnrollNum = Strings.isNotBlank(swMap.getString("enrollNum")) ? swMap.getInt("enrollNum") : 0;
int swCompanionNum = Strings.isNotBlank(swMap.getString("companionNum")) ? swMap.getInt("companionNum") : 0;
return Map.of("snNum", (snCompanionNum + snEnrollNum), "swNum", (swEnrollNum + snCompanionNum));
}
@At
@ViReturn
@SaCheckLogin
public Object getTravelAgencyRating(Integer year) {
Sql sql = Sqls.create("""
SELECT
agency.travelAgencyName,
( SELECT AVG( evaluationForTravelAgency ) FROM inclusive_therapy_v3_enroll where isNormal=true and agency.id=takePartInTravelAgencyId) AS avg
FROM
`inclusive_therapy_v3_travel_agency` agency
WHERE
agency.`year` = @year
""").setParam("year", year);
List list = baseService.listMap(sql);
return list;
}
@At
@ViReturn
@SaCheckLogin
public Object getLineRating(Integer year) {
Sql sql = Sqls.create("""
SELECT
line.lineName,
( SELECT AVG( evaluationForLine ) FROM inclusive_therapy_v3_enroll where isNormal=true and line.id=takePartInLineId) AS avg
FROM
`inclusive_therapy_v3_line` line
WHERE
line.`year` = @year
""").setParam("year", year);
List list = baseService.listMap(sql);
return list;
}
}
@@ -0,0 +1,501 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.statistics;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyMessage;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyUnion;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationProvinceType;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.*;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.UnionLineNumberStatisticsVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.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.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @version 1.0
* @Author zzr
* @name:TheRapyRecuperationStatisticsController
* @Date 2024/6/3 17:32
* @注释 查看报名情况
*/
@IocBean
@At("/platform/inclusiveTherapyV3/statistics")
@Ok("json:full")
@Slf4j
public class TheRapyRecuperationLineStatisticsController {
@Inject
private TheRapyRecuperationEnrollService enrollService;
@Inject
private TherapyMessage msgApi;
@Inject
private Dao dao;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/statistics/lineStatistics.html")
@SaCheckPermission("inclusiveTherapyV3.statistics")
public void index() {
}
@At("/unionLineNumberStatistics")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/statistics/unionLineNumberStatistics.html")
@SaCheckPermission("inclusiveTherapyV3.unionLineNumberStatistics")
public void unionLineNumberStatistics() {
}
/**
* 查询基础设置中各分工会配置的线路最低数量,以及当前年度已选择的省内、省外出行时间段数量。
*
* @param unionId 分工会 ID;为空时查询基础设置中所有已配置分工会
* @return 分工会线路数量统计 VO 列表,finished 表示省内、省外均达到最低数量要求
*/
@At("/unionLineNumberStatistics/pageData")
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.unionLineNumberStatistics")
public Object unionLineNumberStatisticsPageData(@Param(value = "unionId") String unionId) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
List<NutMap> lineNumberConfigs = Optional.ofNullable(config)
.map(TheRapyRecuperationConfig::getUnionLineNumberConfigs)
.orElse(Collections.emptyList());
if (Strings.isNotBlank(unionId)) {
lineNumberConfigs = lineNumberConfigs.stream()
.filter(item -> unionId.equals(item.getString("unionId")))
.collect(Collectors.toList());
}
if (lineNumberConfigs.isEmpty()) {
return new ArrayList<>();
}
List<String> unionIds = lineNumberConfigs.stream()
.map(item -> item.getString("unionId"))
.filter(Strings::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (unionIds.isEmpty()) {
return new ArrayList<>();
}
Map<String, String> unionNameMap = dao.query(TherapyUnion.class, Cnd.where("id", "in", unionIds))
.stream()
.collect(Collectors.toMap(TherapyUnion::getId, TherapyUnion::getUnionname));
Sql selectedSql = Sqls.create("""
SELECT
us.unionId,
line.regionalNature,
COUNT(us.id) AS selectedNumber
FROM
inclusive_therapy_v3_line_union_select us
LEFT JOIN inclusive_therapy_v3_line line ON line.id = us.lineId
WHERE
us.signUpMode = 1
AND YEAR(us.selectTime) = @year
GROUP BY
us.unionId,
line.regionalNature
""");
selectedSql.setParam("year", DateUtil.thisYear());
List<NutMap> selectedList = (List<NutMap>) enrollService.listMap(selectedSql);
Map<String, Integer> selectedNumberMap = new HashMap<>();
for (NutMap selected : selectedList) {
selectedNumberMap.put(selected.getString("unionId") + "#" + selected.getString("regionalNature"),
Optional.ofNullable(selected.getInt("selectedNumber")).orElse(0));
}
List<UnionLineNumberStatisticsVo> resultList = new ArrayList<>();
for (NutMap lineNumberConfig : lineNumberConfigs) {
String rowUnionId = lineNumberConfig.getString("unionId");
Integer provinceOutNumber = Optional.ofNullable(lineNumberConfig.getInt("minProvinceOutNumber")).orElse(0);
Integer provinceInNumber = Optional.ofNullable(lineNumberConfig.getInt("minProvinceInNumber")).orElse(0);
Integer selectedProvinceOutNumber = selectedNumberMap.getOrDefault(rowUnionId + "#" + TheRapyRecuperationProvinceType.provinceOut.getValue(), 0);
Integer selectedProvinceInNumber = selectedNumberMap.getOrDefault(rowUnionId + "#" + TheRapyRecuperationProvinceType.provinceIn.getValue(), 0);
boolean finished = selectedProvinceOutNumber >= provinceOutNumber && selectedProvinceInNumber >= provinceInNumber;
// 配置来源于基础设置 JSON,统计结果按当前年度分工会已选择出行时间段数量合并展示。
resultList.add(new UnionLineNumberStatisticsVo()
.setUnionId(rowUnionId)
.setUnionName(unionNameMap.getOrDefault(rowUnionId, ""))
.setProvinceOutNumber(provinceOutNumber)
.setProvinceInNumber(provinceInNumber)
.setSelectedProvinceOutNumber(selectedProvinceOutNumber)
.setSelectedProvinceInNumber(selectedProvinceInNumber)
.setFinished(finished));
}
return resultList;
}
/**
* 统计线路报名情况列表。
*
* @param pageForm 分页参数,包含 pageNumber、pageSize、排序字段等表格通用参数
* @param startYear 选择线路年度开始年份,按 lineu.selectTime 年份过滤
* @param endYear 选择线路年度结束年份,按 lineu.selectTime 年份过滤
* @param unionId 分工会 ID,管理员可传;普通分工会账号按当前登录人分工会过滤
* @param takePartInLineId 线路 ID,对应 inclusive_therapy_v3_line.id
* @param lotId 标段 ID,对应 inclusive_therapy_v3_lot.id
* @param signUpMode 报名模式,1 分工会组织,2 校工会组织
* @param selectId 线路选择记录 ID,保留给旧入口按具体出行时间段精确筛选
* @param playMonth 出行年月,格式 yyyy-MM,按 lineu.playStartTime 所属年月筛选
* @param regionalNature 线路类型,省内或省外
* @param travelAgencyId 旅行社 ID,同时匹配线路选择记录和线路主表上的旅行社字段
* @return 分页数据,data.list 为线路统计行,data.totalCount 为总条数
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.statistics")
public Object pageData(PageForm pageForm,
@Param(value = "startYear") Integer startYear,
@Param(value = "endYear") Integer endYear,
@Param(value = "unionId") String unionId,
@Param("takePartInLineId") String takePartInLineId,
@Param(value = "lotId") String lotId,
@Param(value = "signUpMode") String signUpMode,
@Param(value = "selectId") String selectId,
@Param(value = "playMonth") String playMonth,
@Param(value = "regionalNature") String regionalNature,
@Param(value = "travelAgencyId") String travelAgencyId) {
Sql sql = Sqls.create("""
SELECT
line.id,
line.lineName,
line.regionalNature,
lineu.lineId,
lineu.id as lineUId,
lineu.signUpMode,
lineu.minimumGroupSize,
lineu.estimatedFamilyNumbers,
YEAR(lineu.selectTime) as `year`,
CONCAT(DATE_FORMAT(lineu.playStartTime,'%m月%d日'),'-',DATE_FORMAT(lineu.playEndTime,'%m月%d日')) AS linePlayTime,
CONCAT(DATE_FORMAT(lineu.signUpStartTime,'%m月%d日'),'-',DATE_FORMAT(lineu.signUpEndTime,'%m月%d日')) AS signUpTime,
DATE_FORMAT(lineu.adjustSignUpEndTime, '%Y-%m-%d %H:%i') AS adjustSignUpEndTime,
lineu.playStartTime as playStartTime1,
lineu.playEndTime as playEndTime2,
IFNULL(usTa.travelAgencyName, lineTa.travelAgencyName) AS travelAgencyName,
IFNULL(usTa.contact, lineTa.contact) AS contact,
IFNULL(usTa.contactMobileNumber, lineTa.contactMobileNumber) AS contactMobileNumber,
enrollStats.usUnionId,
if(lineu.signUpMode = 2, '校工会', un.unionname) as unionname,
lot.lotName,
lot.lotValue,
enrollStats.familyNumber,
IFNULL(enrollStats.lineNum, 0) lineNum,
IFNULL(enrollStats.signUpUserFamilyNum, 0) as signUpUserFamilyNum,
IFNULL(enrollStats.adultFamilyNum, 0) as adultFamilyNum
FROM
inclusive_therapy_v3_line_union_select lineu
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
LEFT JOIN inclusive_therapy_v3_lot lot ON lot.id = line.lotId
LEFT JOIN inclusive_therapy_v3_travel_agency usTa ON lineu.travelAgencyId = usTa.id
LEFT JOIN inclusive_therapy_v3_travel_agency lineTa ON line.travelAgencyId = lineTa.id
LEFT JOIN inclusive_therapy_v3_union un ON un.id = lineu.unionId
LEFT JOIN (
SELECT
e.takePartInLineId,
MAX(e.takePartInUnionId) AS usUnionId,
MAX(e.familyNumber) AS familyNumber,
COUNT(DISTINCT e.id) AS lineNum,
COUNT(c.id) AS signUpUserFamilyNum,
SUM(CASE WHEN c.age >= 18 THEN 1 ELSE 0 END) AS adultFamilyNum
FROM
inclusive_therapy_v3_enroll e
LEFT JOIN inclusive_therapy_v3_enroll_companion c ON c.trreId = e.id
WHERE
e.stateId = 2750
AND e.isNormal = TRUE
$unionCnd
GROUP BY
e.takePartInLineId
) enrollStats ON enrollStats.takePartInLineId = lineu.id
$condition
ORDER BY line.serialNumber ASC, lineu.playStartTime ASC
""");
Sql countSql = Sqls.create("""
SELECT
COUNT(1)
FROM
inclusive_therapy_v3_line_union_select lineu
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
LEFT JOIN inclusive_therapy_v3_lot lot ON lot.id = line.lotId
$condition
""");
Cnd cnd = Cnd.NEW();
if (startYear != null) {
cnd.and("lineu.selectTime", ">=", startYear + "-01-01 00:00:00");
}
if (endYear != null) {
cnd.and("lineu.selectTime", "<", (endYear + 1) + "-01-01 00:00:00");
}
cnd.andEX("lineu.signUpMode", "=", signUpMode);
sql.setVar("unionCnd", "");
if (!TherapyContext.hasAnyRoles("sysadmin,H06")) {
String unionCndSql = "and (e.selfUnionId='%s' or e.takePartInUnionId = '%s')".formatted(TherapyContext.getUnionId(), TherapyContext.getUnionId());
sql.setVar("unionCnd", unionCndSql);
cnd.and("lineu.unionId", "=", TherapyContext.getUnionId());
} else {
if (Strings.isNotBlank(unionId)) {
cnd.and("lineu.unionId", "=", unionId);
}
}
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("line.id", "=", takePartInLineId);
cnd.andEX("lineu.id", "=", selectId);
// 出行年月筛选按出行开始时间归属月份统计,跨月线路归入开始月份。
if (Strings.isNotBlank(playMonth)) {
String playMonthStart = playMonth + "-01 00:00:00";
String playMonthEnd = DateUtil.offsetMonth(DateUtil.parse(playMonth + "-01", "yyyy-MM-dd"), 1).toDateStr() + " 00:00:00";
cnd.and("lineu.playStartTime", ">=", playMonthStart);
cnd.and("lineu.playStartTime", "<", playMonthEnd);
}
cnd.andEX("line.regionalNature", "=", regionalNature);
addTravelAgencyCondition(cnd, travelAgencyId);
sql.setCondition(cnd);
countSql.setCondition(cnd);
return enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql, countSql);
}
/**
* 统计页按旅行社过滤线路选择记录。
* 旅行社可能保存在线路选择记录或线路主表,两个字段任一命中都应纳入统计结果。
*
* @param cnd 当前统计查询条件
* @param travelAgencyId 旅行社 ID,为空时不增加过滤条件
*/
private void addTravelAgencyCondition(Cnd cnd, String travelAgencyId) {
if (StrUtil.isBlank(travelAgencyId)) {
return;
}
SqlExpressionGroup travelAgencyGroup = new SqlExpressionGroup();
travelAgencyGroup.or("lineu.travelAgencyId", "=", travelAgencyId);
travelAgencyGroup.or("line.travelAgencyId", "=", travelAgencyId);
cnd.and(travelAgencyGroup);
}
/**
* 根据线路查询报名详情
*
* @param searchKeyword
* @param unionId
* @param unitId
* @return
*/
@At
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.statistics")
public Object getUserDateByLine(PageForm pageForm,
@Param(value = "takePartLineId") String takePartLineId,
@Param(value = "searchKeyword") String searchKeyword,
@Param(value = "unionId") String unionId,
@Param(value = "unitId") String unitId) {
Sql sql = Sqls.create("""
SELECT
enroll.*,
line.lineName,
line.id as lineId,
line.regionalNature,
'教职工' userNature,
state.stateColor,
state.stateName,
CONCAT(DATE_FORMAT(rs.playStartTime,'%m月%d日'),'-',DATE_FORMAT(rs.playEndTime,'%m月%d日')) AS linePlayTime,
IF
( enroll.takePartInUnionId != enroll.selfUnionId, TRUE, FALSE ) isTransferIn,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) isFamily,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id ) num
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN `inclusive_therapy_v3_line_union_select` rs ON rs.id = enroll.takePartInLineId
LEFT JOIN `inclusive_therapy_v3_line` line on line.id=rs.lineId
LEFT JOIN inclusive_therapy_v3_audit_state state ON state.stateId = enroll.stateId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("enroll.takePartInLineId", "=", takePartLineId);
cnd.and("enroll.stateId", "=", 2750);
cnd.andEX("enroll.selfUnionId", "=", unionId);
cnd.andEX("enroll.selfUnitId", "=", unitId);
cnd.and("enroll.takePartInLineId", "is not", null);
cnd.andEX("enroll.isNormal", "=", true);
if (StrUtil.isNotBlank(searchKeyword)) {
cnd.and(Cnd.exps("enroll.loginName", "like", "%" + searchKeyword + "%").or("enroll.userName", "like", "%" + searchKeyword + "%"));
}
cnd.desc("enroll.signingUptime");
cnd.desc("enroll.unitName");
sql.setCondition(cnd);
return enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@At
@ViReturn
@SaCheckLogin
public Object sendSuccess(String id) {
TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId());
if (DateUtil.compare(new Date(), unionSelect.getSignUpEndTime()) < 0) {
return Result.error("报名还未结束,不能发送");
}
//找出报名人员
List<TheRapyRecuperationEnroll> enrolls = dao.query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "=", id)
.and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
//发短信
enrolls.forEach(item -> {
String content = "%s老师,您好!您报名的%s线路,出行时间为%s,达到成团条件,请准时参加疗休养活动。".formatted(
item.getUserName(),
line.getLineName(),
DateUtil.format(unionSelect.getPlayStartTime(), "yyyy-MM-dd")
);
List list = List.of(Map.of("type", "User", "userId", item.getLoginName(), "name", item.getUserName()));
msgApi.sendMsg(content, list, "疗休养", " IntelligenceMode", TherapyMessage.sendMode.normal.name());
});
return null;
}
@At
@ViReturn
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
public Object sendFail(String id) {
TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId());
if (DateUtil.compare(new Date(), unionSelect.getSignUpEndTime()) < 0) {
return Result.error("报名还未结束,不能发送");
}
//找出报名人员
List<TheRapyRecuperationEnroll> enrolls = dao.query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "=", id)
.and("isNormal", "=", true).and("delFlag", "=", false).and("year(signingUptime)", "=", DateUtil.thisYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
//发短信
enrolls.forEach(item -> {
String content = "%s老师,您好!您报名的%s线路,出行时间为%s,因报名人数不足未达到成团条件,请尽快进入疗休养管理系统重新选择线路,7月份线路报名截止时间延长至7月4日晚上24点,谢谢!".formatted(
item.getUserName(),
line.getLineName(),
DateUtil.format(unionSelect.getPlayStartTime(), "yyyy-MM-dd")
);
List list = List.of(Map.of("type", "User", "userId", item.getLoginName(), "name", item.getUserName()));
msgApi.sendMsg(content, list, "疗休养", " IntelligenceMode", TherapyMessage.sendMode.normal.name());
});
// 未成团通知统一保留报名数据,只将报名标记为非正常且已删除,便于后续调剂和历史追溯。
List<String> idList = enrolls.stream().map(TheRapyRecuperationEnroll::getId).collect(Collectors.toList());
dao.update(TheRapyRecuperationEnroll.class, Chain.make("isNormal", false).add("delFlag", true), Cnd.where("id", "in", idList));
return null;
}
/**
* 补发 2026 年已删除报名记录的未成团通知。
* 仅 superadmin 可操作,避免普通统计人员误触发批量补发。
*
* @return 补发触发数量,前端展示给操作人确认
*/
@At("/resendFailNotice")
@ViReturn
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
public Object resendFailNotice() {
Object loginName = TherapyContext.getPrincipalProperty("loginname");
if (!"superadmin".equals(Strings.sNull(loginName))) {
return Result.error("仅 superadmin 可操作");
}
int count = enrollService.resendDeletedFailNotice(2026);
return Result.success("已触发补发未成团通知" + count + "条");
}
/**
* 手动发送所选线路的成团邮件给旅行社。
* 参数 lineUnionSelectIds 为统计页勾选的线路选择记录 ID 数组;返回值为统一 Result,msg 中说明实际发送邮件的旅行社数量。
*
* @param lineUnionSelectIds 线路选择记录 ID,对应 inclusive_therapy_v3_line_union_select.id
* @return Result,code=0 表示触发完成,msg 展示发送结果
*/
@At("/sendGroupMail")
@ViReturn
@SaCheckLogin
public Object sendGroupMail(@Param("lineUnionSelectIds") String[] lineUnionSelectIds) {
Object loginName = TherapyContext.getPrincipalProperty("loginname");
if (!"superadmin".equals(Strings.sNull(loginName))) {
return Result.error("仅 superadmin 可操作");
}
if (Lang.isEmpty(lineUnionSelectIds)) {
return Result.error("请选择需要发送成团邮件的线路");
}
int count = enrollService.sendTakePartInUserByLineMail(Arrays.asList(lineUnionSelectIds));
return Result.success("已发送成团邮件" + count + "封");
}
/**
* 统计页一键统赋勾选线路的报名、出行和调剂时间。
*
* @param lineUnionSelectIds 统计页勾选的线路选择记录 ID,对应 inclusive_therapy_v3_line_union_select.id
* @param lineUnionSelects 统赋时间表单数组,当前只取第一项作为批量更新模板
* @return 空数据,前端根据统一返回包装判断是否成功
*/
@At("/setGiveLineTimes")
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.statistics")
@Aop(TransAop.READ_COMMITTED)
public Object setGiveLineTimes(@Param("lineUnionSelectIds") String[] lineUnionSelectIds,
@Param("lineUnionSelects") TheRapyRecuperationLineUnionSelect[] lineUnionSelects) {
if (Lang.isEmpty(lineUnionSelectIds) || Lang.isEmpty(lineUnionSelects)) {
return null;
}
TheRapyRecuperationLineUnionSelect lineUnionSelect = lineUnionSelects[0];
Chain chain = Chain.make("enable", Boolean.TRUE.equals(lineUnionSelect.getEnable()));
if (lineUnionSelect.getSignUpStartTime() != null) {
chain.add("signUpStartTime", lineUnionSelect.getSignUpStartTime());
}
if (lineUnionSelect.getSignUpEndTime() != null) {
chain.add("signUpEndTime", lineUnionSelect.getSignUpEndTime());
}
if (lineUnionSelect.getChangeEndTime() != null) {
chain.add("changeEndTime", lineUnionSelect.getChangeEndTime());
}
if (lineUnionSelect.getPlayStartTime() != null) {
chain.add("playStartTime", lineUnionSelect.getPlayStartTime());
}
if (lineUnionSelect.getPlayEndTime() != null) {
chain.add("playEndTime", lineUnionSelect.getPlayEndTime());
}
if (lineUnionSelect.getAdjustSignUpEndTime() != null) {
chain.add("adjustSignUpEndTime", lineUnionSelect.getAdjustSignUpEndTime());
}
dao.update(TheRapyRecuperationLineUnionSelect.class, chain, Cnd.where("id", "in", lineUnionSelectIds));
return null;
}
}
@@ -0,0 +1,177 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.statistics;
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 cn.hutool.core.date.DateUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.TravelAgencyMonthlyEnrollStatisticsVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.UnionEnrollStatisticsVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import org.apache.poi.ss.usermodel.Workbook;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 旅行社月度报名统计。
*/
@IocBean
@At("/platform/inclusiveTherapyV3/travelAgencyMonthlyStatistics")
@Ok("json:full")
public class TheRapyRecuperationTravelAgencyMonthlyStatisticsController {
@Inject
private TheRapyRecuperationEnrollService enrollService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/statistics/travelAgencyMonthlyStatistics.html")
@SaCheckPermission("inclusiveTherapyV3.travelAgencyMonthlyStatistics")
public void index() {
}
/**
* 查询指定年度各旅行社每月报名数量。
* 参数 year 为统计年度,前端年度选择器传 yyyy;为空时默认当前年度。
* 返回值为 List<TravelAgencyMonthlyEnrollStatisticsVo>,每项包含旅行社、月份和报名数量。
*
* @param year 统计年度
* @return 旅行社月度报名数量统计列表
*/
@At("/getChartData")
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.travelAgencyMonthlyStatistics")
public Object getChartData(@Param(value = "year") Integer year) {
Integer queryYear = year == null ? DateUtil.thisYear() : year;
return enrollService.getTravelAgencyMonthlyEnrollStatistics(queryYear);
}
/**
* 查询指定年度二级工会出去疗休养人数。
* 参数 year 为统计年度,前端年度选择器传 yyyy;为空时默认当前年度。
* 返回值为 List<UnionEnrollStatisticsVo>,每项包含二级工会、月份和有效报名人数。
*
* @param year 统计年度
* @return 二级工会月度出行人数统计列表
*/
@At("/getUnionChartData")
@ViReturn
@SaCheckPermission("inclusiveTherapyV3.travelAgencyMonthlyStatistics")
public Object getUnionChartData(@Param(value = "year") Integer year) {
Integer queryYear = year == null ? DateUtil.thisYear() : year;
List<UnionEnrollStatisticsVo> list = enrollService.getUnionEnrollStatistics(queryYear);
return list;
}
/**
* 导出当前年度旅行社月度报名统计。
* 参数 year 为统计年度;为空时默认当前年度。
* 返回 xlsx 文件,列为年度、旅行社和动态月份数量列。
*
* @param year 统计年度
* @param response HTTP 响应对象,方法直接写出 Excel 文件
*/
@At("/doExportExcel")
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.travelAgencyMonthlyStatistics")
public void doExportExcel(@Param(value = "year") Integer year,
HttpServletResponse response) throws IOException {
Integer queryYear = year == null ? DateUtil.thisYear() : year;
NutMap exportData = enrollService.getTravelAgencyMonthlyEnrollExportData(queryYear);
List<Integer> months = getExportMonths(exportData);
List<NutMap> list = getExportRows(exportData);
ArrayList<ExcelExportEntity> exportEntities = buildMonthExportEntities("旅行社", "travelAgencyName", months);
TherapyDownload.excelResponse(response, queryYear + "旅行社月度报名统计.xlsx");
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
workbook.write(response.getOutputStream());
workbook.close();
}
/**
* 导出当前年度二级工会出去疗休养人数统计。
* 参数 year 为统计年度;为空时默认当前年度。
* 返回 xlsx 文件,列为年度、二级工会和动态月份数量列。
*
* @param year 统计年度
* @param response HTTP 响应对象,方法直接写出 Excel 文件
*/
@At("/doExportUnionExcel")
@Ok("void")
@SaCheckPermission("inclusiveTherapyV3.travelAgencyMonthlyStatistics")
public void doExportUnionExcel(@Param(value = "year") Integer year,
HttpServletResponse response) throws IOException {
Integer queryYear = year == null ? DateUtil.thisYear() : year;
NutMap exportData = enrollService.getUnionEnrollExportData(queryYear);
List<Integer> months = getExportMonths(exportData);
List<NutMap> list = getExportRows(exportData);
ArrayList<ExcelExportEntity> exportEntities = buildMonthExportEntities("二级工会", "unionName", months);
TherapyDownload.excelResponse(response, queryYear + "二级工会月度疗休养出行人数统计.xlsx");
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
workbook.write(response.getOutputStream());
workbook.close();
}
/**
* 根据有数据的月份生成横向月份导出列。
* 固定列为年度和统计对象名称,动态列为 7月、8月 等,字段名为 month_7、month_8。
*
* @param nameTitle 统计对象列标题,例如旅行社、二级工会
* @param nameField 统计对象列字段,例如 travelAgencyName、unionName
* @param months 有数据的月份数字列表,按月份升序生成列
* @return Excel 导出列定义
*/
private ArrayList<ExcelExportEntity> buildMonthExportEntities(String nameTitle, String nameField, List<Integer> months) {
ArrayList<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("年度", "year", 15));
exportEntities.add(new ExcelExportEntity(nameTitle, nameField, 35));
months.forEach(month ->{
ExcelExportEntity entity = new ExcelExportEntity(month + "月", "month_" + month, 15);
entity.setType(10);
exportEntities.add(entity);
} );
return exportEntities;
}
/**
* 从 service 返回的导出数据中读取动态月份列表。
* months 字段为 List<Integer>,用于按实际有数据的月份生成 Excel 列。
*
* @param exportData service 构建的导出数据
* @return 有数据的月份数字列表
*/
@SuppressWarnings("unchecked")
private List<Integer> getExportMonths(NutMap exportData) {
return (List<Integer>) exportData.get("months");
}
/**
* 从 service 返回的导出数据中读取 Excel 行数据。
* rows 字段为 List<NutMap>,每行包含年度、统计对象名称以及 month_月份 数量字段。
*
* @param exportData service 构建的导出数据
* @return Excel 行数据
*/
@SuppressWarnings("unchecked")
private List<NutMap> getExportRows(NutMap exportData) {
return (List<NutMap>) exportData.get("rows");
}
}
@@ -0,0 +1,152 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.theRapyConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.ViReturn;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationBaseManagement;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLot;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.trans.Trans;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* rapy休养配置控制器
*
* @author zhf
* @date 2022/06/01
*/
@IocBean
@At("/platform/inclusiveTherapyV3/TheRapyConfig")
@Ok("json:full")
public class TheRapyRecuperationConfigController {
@Inject
private Dao dao;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/therapyRecuperation/theRapyConfig/TheRapyConfig.html")
@SaCheckPermission("inclusiveTherapyV3.TheRapyConfig")
public void index() {
}
/**
* 保存疗休养配置。
*
* @param config 配置主体,包含基本配置、服务须知以及标段列表等页面表单字段
* @param lotDeleteList 需要删除的标段 ID 数组,后台会按 ID 清理标段数据
* @param unionLineNumberConfigs 分工会线路数量配置 JSON 数组,元素包含 unionId、minProvinceOutNumber、minProvinceInNumber
* @return ViReturn 统一包装的 JSON 结果,保存成功时 data 为空
*/
@At
@ViReturn
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
public Object operation(TheRapyRecuperationConfig config, String[] lotDeleteList, String unionLineNumberConfigs, String lots) {
if (Strings.isNotBlank(lots)) {
config.setLots(Json.fromJsonAsList(TheRapyRecuperationLot.class, lots));
}
if (config.getLots() == null) {
config.setLots(new ArrayList<>());
}
// unionLineNumberConfigs 为前端分工会线路数量配置 JSON 数组,返回保存后的配置对象仍由 findOne 接口按实体结构回显。
config.setUnionLineNumberConfigs(Strings.isBlank(unionLineNumberConfigs)
? new ArrayList<>()
: Json.fromJsonAsList(NutMap.class, unionLineNumberConfigs));
if (Strings.isNotBlank(config.getId())) {
if (Lang.isNotEmpty(lotDeleteList)) {
dao.clear(TheRapyRecuperationLot.class, Cnd.where("id", "in", lotDeleteList));
}
dao.updateWith(config, "lots");
List<TheRapyRecuperationLot> collect = config.getLots().stream().filter(v -> v.getConfigId() == null).collect(Collectors.toList());
for (TheRapyRecuperationLot obj : collect) {
obj.setConfigId(config.getId());
}
if (!collect.isEmpty()) {
dao.insert(collect);
}
} else {
dao.insertWith(config, "lots");
}
return null;
}
@At
@ViReturn
@SaCheckLogin
public Object findOne() {
return dao.fetchLinks(dao.fetch(TheRapyRecuperationConfig.class), "lots",Cnd.NEW().desc("lotValue"));
}
/**
* 查使用该标段的线路和目的地
* @param lotId
* @return
*/
@At
@ViReturn
@SaCheckLogin
public Object getLotsById(String lotId){
List<String> lineNames = new ArrayList<>();
List<String> baseNames = new ArrayList<>();
Map<String, List<String>> map = new HashMap<>();
List<TheRapyRecuperationLine> lineList = dao.query(TheRapyRecuperationLine.class, Cnd.where("lotId", "=", lotId));
if (!CollectionUtils.isEmpty(lineList)){
lineList.forEach(v-> lineNames.add(v.getLineName()));
map.put("line",lineNames);
}
List<TheRapyRecuperationBaseManagement> managementList = dao.query(TheRapyRecuperationBaseManagement.class, Cnd.where("lotId", "=", lotId));
if (!CollectionUtils.isEmpty(managementList)){
managementList.forEach(v-> baseNames.add(v.getBaseName()));
map.put("base",baseNames);
}
return map;
}
/**
* 强制删除标段时长,会删除已绑定的线路和目的地
* @param lotId
* @return
*/
@At
@ViReturn
@SaCheckLogin
public Object deleteLotById(String lotId){
Trans.exec(()->{
dao.clear(TheRapyRecuperationLot.class, Cnd.where("id","=",lotId));
List<TheRapyRecuperationLine> lineList = dao.query(TheRapyRecuperationLine.class, Cnd.where("lotId", "=", lotId));
if (!CollectionUtils.isEmpty(lineList)) {
lineList.forEach(v -> v.setLotId(null));
dao.update(lineList);
}
List<TheRapyRecuperationBaseManagement> managementList = dao.query(TheRapyRecuperationBaseManagement.class, Cnd.where("lotId", "=", lotId));
if (!CollectionUtils.isEmpty(managementList)) {
managementList.forEach(v -> v.setLotId(null));
dao.update(managementList);
}
});
return null;
}
}
@@ -0,0 +1,145 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.job;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyEmail;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.common.TherapyRecuperationCommon;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author: JyuHsin
* @Date: 2024/6/14 10:41
* @Version: v1.0.0
* @Description: 给旅游社发送线路成团的名单,每天早上八点执行,查询报名结束时间为前一天的线路
**/
@IocBean(name = "staffTherapySendTakePartInUserByLineJob")
public class SendTakePartInUserByLineJob implements Job {
@Inject
private TherapyEmail emailUtil;
@Inject
private TheRapyRecuperationEnrollService enrollService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//获取昨天
String yesterday = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
//先查询符合条件的线路
List<TheRapyRecuperationLineUnionSelect> unionSelects =
enrollService.dao().query(TheRapyRecuperationLineUnionSelect.class, Cnd.where("Date(signUpEndTime)", "=", yesterday).and("enable", "=", true));
List<String> selectIdList = unionSelects.stream().map(TheRapyRecuperationLineUnionSelect::getId).collect(Collectors.toList());
Map<String, TheRapyRecuperationLineUnionSelect> selectMap = unionSelects.stream().collect(Collectors.toMap(TheRapyRecuperationLineUnionSelect::getId, o -> o));
//在查询这些线路的报名人员
Sql sql = Sqls.create("""
SELECT
e.*,
concat(l.lineName, ifnull(concat('【', ta.travelAgencyName, '】'), ''), ifnull(concat('-', su.unionname), '')) as lineName,
ta.id as travelId,
ta.travelAgencyName,
concat(s.playStartTime, '至' , s.playEndTime) as playTime,
(select count(1) from inclusive_therapy_v3_enroll_companion ec where ec.trreId = e.id and ec.age >= 18) as companionCount,
(select GROUP_CONCAT(ec.userName, '(', ec.idcard, '、', ec.mobile, ')') from inclusive_therapy_v3_enroll_companion ec where ec.trreId = e.id) as companionInfo,
u.schoolTime
FROM
inclusive_therapy_v3_enroll e
LEFT JOIN `inclusive_therapy_v3_user` u on e.loginName = u.loginname
LEFT JOIN inclusive_therapy_v3_line_union_select s ON e.takePartInLineId = s.id
left join inclusive_therapy_v3_line l on l.id = s.lineId
left join inclusive_therapy_v3_travel_agency ta on ta.id = s.travelAgencyId
left join inclusive_therapy_v3_union su on su.id = s.unionId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("takePartInLineId", "in", selectIdList);
cnd.and("isNormal", "=", true);
cnd.and("stateId", "=", TheRapyRecuperationState.PASS);
cnd.and("year(signingUptime)", "=", DateUtil.thisYear());
cnd.asc("l.serialNumber").asc("s.playStartTime").asc("e.signingUptime");
sql.setCondition(cnd);
List<NutMap> enrolls = enrollService.listMap(sql);
if (Lang.isNotEmpty(enrolls)) {
enrolls.forEach(item -> {
String remark = TherapyRecuperationCommon.getRemarkBySchoolTime(item.getString("schoolTime"));
item.put("remark", remark);
});
}
//按照选择线路id分组,便于判断是否成团
Map<String, List<NutMap>> enrollGroup = enrolls.stream().collect(Collectors.groupingBy(o -> o.getString("takePartInLineId")));
// 成团人数口径与统计页保持一致:报名教职工本人 + 18 岁及以上家属人数。
List<NutMap> enrollList = enrollGroup.entrySet().stream()
.filter(entry -> selectMap.containsKey(entry.getKey()) && (entry.getValue().size() + entry.getValue().stream().mapToInt(o -> o.getInt("companionCount")).sum()) >= selectMap.get(entry.getKey()).getEstimatedFamilyNumbers())
.flatMap(entry -> entry.getValue().stream())
.collect(Collectors.toList());
//按旅行社分组
Map<String, List<NutMap>> enrollsMap = enrollList.stream().collect(Collectors.groupingBy(o -> o.getString("travelId")));
List<TheRapyRecuperationTravelAgency> travelAgencyList = enrollService.dao().query(TheRapyRecuperationTravelAgency.class, Cnd.NEW());
for (TheRapyRecuperationTravelAgency item : travelAgencyList) {
String email = item.getEmail();
if (StrUtil.isBlank(email)) continue;
List<NutMap> userList = enrollsMap.get(item.getId());
if (Lang.isEmpty(userList)) continue;
List<ExcelExportEntity> entityList = new ArrayList<>();
entityList.add(new ExcelExportEntity("姓名", "userName", 20));
entityList.add(new ExcelExportEntity("身份证号", "idCard", 20));
entityList.add(new ExcelExportEntity("联系电话", "mobile", 20));
entityList.add(new ExcelExportEntity("所属工会", "unionName", 20));
entityList.add(new ExcelExportEntity("报名线路", "lineName", 50));
entityList.add(new ExcelExportEntity("出行时间", "playTime", 50));
ExcelExportEntity entity = new ExcelExportEntity("家属信息", "companionInfo", 50);
entity.setWrap(true);
entityList.add(entity);
entityList.add(new ExcelExportEntity("旅行社名称", "travelAgencyName", 50));
entityList.add(new ExcelExportEntity("备注", "remark", 30));
File xls = new File("C:/temp/" + item.getTravelAgencyName() + "疗休养线路出行人员名单.xls");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(xls);
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, userList);
workbook.write(fileOutputStream);
fileOutputStream.close();
emailUtil.send(email, item.getTravelAgencyName() + "疗休养线路出行人员名单", false, xls);
if (xls.exists()) {
xls.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@@ -0,0 +1,113 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.job;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyEmail;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.common.TherapyRecuperationCommon;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @version 1.0
* @Author zzr
* @name:SendTakePartInUserByTravelJob
* @Date 2024/5/27 10:05
* @注释
*/
@IocBean(name = "staffTherapySendTakePartInUserByTravelJob")
public class SendTakePartInUserByTravelJob implements Job {
@Inject
private TherapyEmail emailUtil;
@Inject
private TheRapyRecuperationEnrollService enrollService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Sql sql = Sqls.create("""
SELECT
te.*,
travel.email,
travel.travelAgencyName,
u.schoolTime
FROM
`inclusive_therapy_v3_enroll` te
LEFT JOIN `inclusive_therapy_v3_user` u on te.loginName = u.loginname
LEFT JOIN `inclusive_therapy_v3_travel_agency` travel ON travel.id = te.takePartInTravelAgencyId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("te.isNormal","=",1);
cnd.and("te.stateId","=",2750);
cnd.and("te.signingUptime",">=", DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd HH:mm:ss"));
cnd.and("te.signingUptime","<=", DateUtil.now());
cnd.and("te.takePartInTravelAgencyId","is not",null);
cnd.and("te.takePartInTravelAgencyId","!=","");
cnd.groupBy("te.loginName");
sql.setCondition(cnd);
List<NutMap> nutMaps = enrollService.listMap(sql);
if (Lang.isNotEmpty(nutMaps)) {
nutMaps.forEach(item -> {
String remark = TherapyRecuperationCommon.getRemarkBySchoolTime(item.getString("schoolTime"));
item.put("remark", remark);
});
Map<String, List<NutMap>> enrollsMap = nutMaps.stream().collect(Collectors.groupingBy(v -> v.getString("takePartInTravelAgencyId")));
List<TheRapyRecuperationTravelAgency> travelAgencyList = enrollService.dao().query(TheRapyRecuperationTravelAgency.class, Cnd.NEW());
for (TheRapyRecuperationTravelAgency item : travelAgencyList) {
String email = item.getEmail();
if (StrUtil.isBlank(email)) continue;
List<NutMap> userList = enrollsMap.get(item.getId());
if (Lang.isEmpty(userList)) continue;
List<ExcelExportEntity> entityList = new ArrayList<>();
entityList.add(new ExcelExportEntity("姓名", "userName", 20));
entityList.add(new ExcelExportEntity("身份证号", "idCard", 20));
entityList.add(new ExcelExportEntity("联系电话", "mobile", 20));
entityList.add(new ExcelExportEntity("所属工会", "unionName", 20));
entityList.add(new ExcelExportEntity("旅行社名称", "travelAgencyName", 50));
entityList.add(new ExcelExportEntity("备注", "remark", 30));
File xls = new File("C:/temp/"+item.getTravelAgencyName()+"疗休养自由组团出行人员名单.xls");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(xls);
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, userList);
workbook.write(fileOutputStream);
fileOutputStream.close();
emailUtil.send(email, item.getTravelAgencyName() + "疗休养自由组团出行人员名单", false, xls);
if (xls.exists()) {
xls.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
@@ -0,0 +1,59 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
/**
* 疗休养线路新导入模板,字段与PC端线路管理新增页面保持一致。
*/
@Data
public class TheRapyLineImportExcelMode {
@Excel(name = "年度")
private Integer year;
@Excel(name = "排序号")
private Integer serialNumber;
@Excel(name = "线路名称")
private String lineName;
@Excel(name = "时间标段")
private String lotId;
@Excel(name = "线路类型")
private String regionalNature;
@Excel(name = "旅行社名称")
private String travelAgencyName;
@Excel(name = "交通工具")
private String trafficTools;
@Excel(name = "最少成团人数包括家属")
private Integer estimatedFamilyNumbers;
@Excel(name = "预计费用(元/人次)")
private String estimatedCost;
@Excel(name = "家属报名")
private String familySignUp;
@Excel(name = "组织形式")
private String signUpMode;
@Excel(name = "联系人")
private String lineContact;
@Excel(name = "联系方式", width = 20)
private String lineContactPhone;
@Excel(name = "线路内容")
private String content;
@Excel(name = "是否启用")
private String isEnabled;
@Excel(name = "移动端缩略图", width = 20)
private String files;
}
@@ -0,0 +1,30 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode;
import lombok.Data;
/**
* 线路导入模板内嵌图片数据,承载“移动端缩略图”列解析出的图片内容。
*/
@Data
public class TheRapyLineImportImageMode {
/**
* Excel数据行下标,从0开始,对应导入明细集合下标。
*/
private Integer rowIndex;
/**
* 导入图片原始文件名,用于写入sys_file.filename。
*/
private String fileName;
/**
* 图片扩展名,用于生成FTP文件名与校验图片类型。
*/
private String extension;
/**
* 图片二进制内容,后续在service层统一上传并保存文件记录。
*/
private byte[] data;
}
@@ -0,0 +1,22 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import java.util.Date;
@Data
public class TheRapyRecuperationEnrollExcelMode {
@Excel(name = "工号")
private String loginName;
@Excel(name = "姓名")
private String userName;
@Excel(name = "参加时间")
private Date takePartInTime;
@Excel(name = "标段时间")
private String lotId;
}
@@ -0,0 +1,42 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
@Data
public class TheRapyTravelAgencyExcelMode {
@Excel(name = "年度")
private Integer year;
@Excel(name = "排序编号")
private String serialNumber;
@Excel(name = "旅行社名称")
private String travelAgencyName;
@Excel(name = "是否自由组团(是/否)")
private String signUpTravelAgency;
@Excel(name = "旅行社联系人")
private String contact;
@Excel(name = "联系电话")
private String contactMobileNumber;
@Excel(name = "邮箱")
private String email;
@Excel(name = "最多承担人数")
private Integer maxUndertakeNumber;
@Excel(name = "官网")
private String officialWebsite;
@Excel(name = "备注")
private String note;
@Excel(name = "是否启用(是/否)")
private String isDisabled;
}
@@ -0,0 +1,69 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
@Data
public class TheRapyTravelLineExcelMode {
@Excel(name = "年度")
private Integer year;
@Excel(name = "排序编号")
private Integer serialNumber;
@Excel(name = "线路名称")
private String lineName;
@Excel(name = "旅行社名称")
private String travelAgencyId;
@Excel(name = "活动范围")
private String regionalNature;
@Excel(name = "最少参与教工")
private Integer minimumGroupSize;
// @Excel(name = "创建模式(分工会/校工会)")
// private String createMode;
//
// @Excel(name = "报名模式(分工会/自由)")
// private String signUpMode;
//
// @Excel(name = "联系人")
// private String lineContact;
//
// @Excel(name = "联系方式")
// private String lineContactPhone;
//
// @Excel(name = "报名开始时间")
// private Date signUpStartTime;
//
// @Excel(name = "报名截止时间")
// private Date signUpEndTime;
//
// @Excel(name = "变更截止时间")
// private Date changeEndTime;
//
// @Excel(name = "出行开始时间")
// private Date playStartTime;
//
// @Excel(name = "出行结束时间")
// private Date playEndTime;
@Excel(name = "时间标段")
private String lotId;
@Excel(name = "预计费用")
private String estimatedCost;
// @Excel(name = "交通工具")
// private String trafficTools;
@Excel(name = "详细信息")
private String content;
@Excel(name = "是否启用(是/否)")
private String isDisabled;
}
@@ -0,0 +1,158 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.budwk.app.sys.models.Sys_file;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationBaseManagement
* @Description: TODO
* @Author zzr
* @Date 2023/6/5
* @Version V1.0
**/
@Data
@Table("inclusive_therapy_v3_base_management")
@Accessors(chain = true)
public class TheRapyRecuperationBaseManagement {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.INT)
@Comment("年度")
@Excel(name = "年度")
private Integer year;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("排序编号")
@Excel(name = "排序编号")
private String sortNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("基地名称")
@Excel(name = "目的地名称")
private String baseName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("旅行社Id")
@Excel(name = "所属旅行社")
private String travelAgencyId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("区域")
@Excel(name = "活动范围(省内/省外)")
private String regionalNature;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("标段Id")
@Excel(name = "时间标段")
private String lotId;
@Column
@ColDefine(customType = "text")
@Comment("疗休养详情")
@Excel(name = "详细信息")
private String content;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否禁用")
@Excel(name = "是否启用(是/否)")
private Boolean isDisabled;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("哪个分工会创建的")
private String createUnionId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名开始时间")
@Excel(name = "报名开始时间")
private Date signUpStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名截至时间")
@Excel(name = "报名截至时间")
private Date signUpEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("变更截至时间")
@Excel(name = "变更截至时间")
private Date changeEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("活动开始时间")
@Excel(name = "活动开始时间")
private Date activityStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("活动结束时间")
@Excel(name = "活动结束时间")
private Date activityEndTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("预计费用")
@Excel(name = "预计费用")
private String estimatedCost;
@Column
@ColDefine(type = ColType.MYSQL_JSON)
@Comment("缩略图")
private List<Sys_file> files;
@Column
@ColDefine(type = ColType.INT)
@Comment("创建模式(1.校工会 2.分工会)")
@Excel(name = "组织形式(分工会/校工会)")
private int createMode;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("基地联系人")
@Excel(name = "目的地联系人")
private String baseContactPerson;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("基地联系人电话")
@Excel(name = "联系电话")
private String baseContactNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("操作人")
private String opBy;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("操作时间")
private String opAt;
@One(field = "travelAgencyId")
private TheRapyRecuperationTravelAgency travelAgency;
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationCluster
* @Description: TODO
* @Author zxc
* @Date 2022/6/17:09:30
* @Version V1.0
**/
@Data
@Table("inclusive_therapy_v3_cluster")
@Accessors(chain = true)
public class TheRapyRecuperationCluster {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("线路id")
private String lineId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("团名")
private String clusterName;
@Many(field = "clusterId")
private List<TheRapyRecuperationClusterMember> members;
}
@@ -0,0 +1,60 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationClusterMember
* @Description: TODO
* @Author zxc
* @Date 2022/6/17:09:30
* @Version V1.0
**/
@Data
@Table("inclusive_therapy_v3_cluster_member")
@Accessors(chain = true)
public class TheRapyRecuperationClusterMember {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("线路id")
private String lineId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("团Id")
private String clusterId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("工号")
private String loginName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("姓名")
private String userName;
@Column
@ColDefine(type = ColType.CHAR, width = 1)
@Comment("性别")
private String sex;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("工会")
private String unionName;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否领队")
private Boolean isLeader;
}
@@ -0,0 +1,164 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
@Data
@Table("inclusive_therapy_v3_config")
@Accessors(chain = true)
public class TheRapyRecuperationConfig {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 30)
@Comment("配置名称")
private String configName;
@Column
@ColDefine(type = ColType.INT, width = 32)
@Comment("参加人员范围")
private Integer activityGroupId;
/**
* 报名开始时间,用于基础设置页面控制全局报名开放区间。
*/
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名开始时间")
private Date signUpStartTime;
/**
* 报名结束时间,用于基础设置页面控制全局报名截止区间。
*/
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名结束时间")
private Date signUpEndTime;
/**
* 选择线路开始时间,用于控制分工会/校工会选择线路开放区间。
*/
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("选择线路开始时间")
private Date lineSelectStartTime;
/**
* 选择线路结束时间,用于控制分工会/校工会选择线路截止区间。
*/
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("选择线路结束时间")
private Date lineSelectEndTime;
@Column
@ColDefine(type = ColType.INT)
@Comment("省外名额分配")
private Integer outsideQuota;
@Column
@ColDefine(type = ColType.FLOAT, width = 3, precision = 2)
@Comment("省外名额分配比例")
private Double outsideQuotaProportion;
@Column
@ColDefine(type = ColType.INT)
@Comment("省外几年去一次")
private Integer outsideNumber;
@Column
@ColDefine(type = ColType.INT)
@Comment("每年旅行频率")
private Integer travelFrequency;
@Column
@ColDefine(type = ColType.INT)
@Comment("组团人数")
private Integer groupNumber;
@Column
@ColDefine(type = ColType.INT)
@Comment("不可取消修改天数")
private Integer modifyDays;
@Column
@ColDefine(type = ColType.INT)
@Comment("可以修改几次")
private Integer modifyNumber;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("省内线路是否审核")
@Default(value = "0")
private Boolean isSnLine;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("省外线路是否审核")
@Default(value = "0")
private Boolean isSwLine;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("旅行社是否审核")
@Default(value = "0")
private Boolean travelAudit;
@Column
@ColDefine(type = ColType.MYSQL_JSON)
@Comment("标段")
private List<NutMap> modifyBd;
/**
* 分工会线路数量配置。
* 每个元素保存一个分工会的最低线路选择要求:
* unionId 为分工会 ID,minProvinceOutNumber 为最少省外线路数量,
* minProvinceInNumber 为最少省内线路数量。
*/
@Column
@ColDefine(type = ColType.MYSQL_JSON)
@Comment("分工会线路数量配置")
private List<NutMap> unionLineNumberConfigs;
@Many(field = "configId")
private List<TheRapyRecuperationLot> lots;
@Column
@ColDefine(type = ColType.INT)
@Comment("全批次最多教职工报名人数")
private Integer allLineSignUpNumber;
@Column
@ColDefine(customType = "longtext")
@Comment("疗休养服务须知")
private String notice;
@Column
@ColDefine(type = ColType.INT)
@Comment("省内起始年份")
private Integer provinceStartYear;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("床位信息")
@Default(value = "0")
private Boolean bedInfo;
@Column
@ColDefine(type = ColType.INT)
@Comment("家属信息")
@Default(value = "0")
private Integer familyInfo;
}
@@ -0,0 +1,207 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.LegacyBaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll
* @Description: 疗休养报名登记表
* @Author zxc
* @Date 2022/5/31:16:58
* @Version V1.0
**/
@EqualsAndHashCode(callSuper = true)
@Data
@Table("inclusive_therapy_v3_enroll")
@Accessors(chain = true)
public class TheRapyRecuperationEnroll extends LegacyBaseModel {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("工号")
@Excel(name = "工号")
private String loginName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("姓名")
@Excel(name = "姓名")
private String userName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1)
@Comment("性别")
private String sex;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("本人单位")
private String unitName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("本人分工会")
private String unionName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("本人单位")
private String selfUnitId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("本人分工会Id")
private String selfUnionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("参加的分工会")
private String takePartInUnionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("参加线路")
private String takePartInLineId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("参加旅行社")
private String takePartInTravelAgencyId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("参加酒店")
private String takePartInBaseManagementId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名时间")
private Date signingUptime;
@Column
@ColDefine(type = ColType.DATE)
@Comment("参加时间")
@Excel(name = "参加时间", format = "yyyy-MM-dd")
private Date takePartInTime;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否参加")
private boolean isTakePartIn;
@Column
@ColDefine(type = ColType.INT)
@Comment("审核状态")
private Integer stateId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("本人分工会审核Id")
private String selfUnionAuditId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("床位信息id")
private String bedInfoId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("参加的线路分工会审核Id")
private String joinLineUnionAuditId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 18)
@Comment("身份证号")
private String idCard;
@Column
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("手机号")
private String mobile;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否正常(true正常 false该报名记录已被管理员废弃)")
private boolean isNormal;
/**
* 同伴信息
*/
@Many(field = "trreId")
private List<TheRapyRecuperationEnrollCompanion> companionList;
/**
* 酒店信息
*/
@One(field = "takePartInBaseManagementId")
private TheRapyRecuperationBaseManagement managementInfo;
/**
* 线路信息
*/
// @One(field = "takePartInLineId")
private TheRapyRecuperationLine lineInfo;
private String lineId;
/**
* 床位信息
*/
@One(field = "bedInfoId")
private TheRapyRecuperationEnrollBed bedInfo;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("对旅行社的评价(几星)")
private String evaluationForTravelAgency;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("对线路的评价(几星)")
private String evaluationForLine;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("对旅途的评价(几星)")
private String evaluationForJourney;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("反馈内容")
private String feedbackContent;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("标段时间")
private String lotId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("校工会审核Id")
private String schoolUnionAuditId;
@Column
@ColDefine(type = ColType.INT)
@Comment("家属数量")
private Integer familyNumber;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否报销")
private Boolean isReimbursement;
private String firstLetter;
}
@@ -0,0 +1,48 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.LegacyBaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollBed
* @Description: 报名拼床信息
* @Author zxc
* @Date 2022/6/2:14:44
* @Version V1.0
**/
@EqualsAndHashCode(callSuper = true)
@Data
@Table("inclusive_therapy_v3_enroll_bed")
@Accessors(chain = true)
public class TheRapyRecuperationEnrollBed extends LegacyBaseModel {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("床型")
private String bedType;
@Column
@ColDefine(type = ColType.INT)
@Comment("床位数")
private Integer bedNum;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("一起睡吗 搞基")
private boolean isSleepTogether;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("意向拼房人")
private String otherSleepUser;
}
@@ -0,0 +1,37 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollChangeRecord
* @Description: 疗休养登记变更记录表
* @Author zxc
* @Date 2022/5/31:17:10
* @Version V1.0
**/
@Data
@Table("inclusive_therapy_v3_enroll_change_record")
@Accessors(chain = true)
public class TheRapyRecuperationEnrollChangeRecord {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("变更记录id")
private String enrollId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("变更时间")
private Date changeTime;
}
@@ -0,0 +1,79 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.LegacyBaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollFamily
* @Description: TODO
* @Author zxc
* @Date 2022/5/31:17:07
* @Version V1.0
**/
@EqualsAndHashCode(callSuper = true)
@Data
@Table("inclusive_therapy_v3_enroll_companion")
@Accessors(chain = true)
public class TheRapyRecuperationEnrollCompanion extends LegacyBaseModel {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("报名记录表Id")
private String trreId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("工号")
private String loginName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("姓名")
private String userName;
@Column
@ColDefine(type = ColType.CHAR, width = 1)
@Comment("性别")
private String sex;
@Column
@ColDefine(type = ColType.INT)
@Comment("年龄")
private Integer age;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("关系")
private String relation;
@Column
@ColDefine(type = ColType.VARCHAR, width = 18)
@Comment("身份证号")
private String idCard;
@Column
@ColDefine(type = ColType.VARCHAR, width = 18)
@Comment("手机号")
private String mobile;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("床位信息id")
private String bedInfoId;
/**
* 床位信息
*/
@One(field = "bedInfoId")
private TheRapyRecuperationEnrollBed bedInfo;
}
@@ -0,0 +1,160 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.LegacyBaseModel;
import com.budwk.app.sys.models.Sys_file;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine
* @Description: 疗休养线路管理
* @Author zxc
* @Date 2022/5/31:09:13
* @Version V1.0
**/
@EqualsAndHashCode(callSuper = true)
@Data
@Table("inclusive_therapy_v3_line")
@Accessors(chain = true)
public class TheRapyRecuperationLine extends LegacyBaseModel {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.INT)
@Comment("编号")
private Integer serialNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("线路名称")
private String lineName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("旅行社Id")
private String travelAgencyId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("区域性质")
private String regionalNature;
@Column
@ColDefine(type = ColType.INT)
@Comment("游玩天数")
private Integer playNumberOfDays;
@Column
@ColDefine(customType = "text")
@Comment("疗休养内容")
private String content;
@Column
@ColDefine(type = ColType.INT)
@Comment("最少参与教工")
private Integer minimumGroupSize;
@Column
@ColDefine(type = ColType.INT)
@Comment("年度")
private Integer year;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否禁用")
private boolean isDisabled;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("哪个分工会创建的")
private String createUnionId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名开始时间")
private Date signUpStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名截至时间")
private Date signUpEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("变更截至时间")
private Date changeEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("游玩开始时间")
private Date playStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("游玩结束时间")
private Date playEndTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("交通工具")
private String trafficTools;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("预计费用")
private String estimatedCost;
@Column
@ColDefine(type = ColType.INT)
@Comment("成团人数包括家属")
private Integer estimatedFamilyNumbers;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("缩略图")
private String files;
@Column
@ColDefine(type = ColType.INT)
@Comment("报名模式(1.分工会 2.自由)")
private Integer signUpMode;
@Column
@ColDefine(type = ColType.INT)
@Comment("创建模式(1.分工会 2.校工会)")
private int createMode;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("标段")
private String lotId;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("联系人")
private String lineContact;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("联系电话")
private String lineContactPhone;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否家属报名")
private Boolean isFamilySignUp;
@One(field = "travelAgencyId")
private TheRapyRecuperationTravelAgency travelAgency;
}
@@ -0,0 +1,158 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.LegacyBaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
/**
* 疗休养线工会选择
*
* @author jug
* @date 2023/06/26
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Table("inclusive_therapy_v3_line_union_select")
@Accessors(chain = true)
public class TheRapyRecuperationLineUnionSelect extends LegacyBaseModel {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("分工会id")
private String unionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("线路id")
private String lineId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("选择时间")
private Date selectTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("选择用户")
private String selectUserId;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名开始时间")
private Date signUpStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("报名截至时间")
private Date signUpEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("变更截至时间")
private Date changeEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("调剂报名截止时间")
private Date adjustSignUpEndTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("游玩开始时间")
private Date playStartTime;
@Column
@ColDefine(type = ColType.DATETIME)
@Comment("游玩结束时间")
private Date playEndTime;
/**
* 线路信息
*/
@One(field = "lineId")
private TheRapyRecuperationLine lineInfo;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("联系人")
private String contact;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("联系电话")
private String contactPhone;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("负责人")
private String principal;
@Column
@ColDefine(type = ColType.VARCHAR)
@Comment("联系方式")
private String principalContact;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否公开")
private Boolean isOpen;
@Column
@ColDefine(type = ColType.INT)
@Comment("最少参与教工")
private Integer minimumGroupSize;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("交通工具")
private String trafficTools;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("预计费用")
private String estimatedCost;
@Column
@ColDefine(type = ColType.INT)
@Comment("成团人数包括家属")
private Integer estimatedFamilyNumbers;
@Column
@ColDefine(type = ColType.INT)
@Comment("最多人数")
private Integer maxPeopleNumber;
@Column
@ColDefine(type = ColType.INT)
@Comment("报名模式、组织形式(1.分工会 2.校工会)")
private Integer signUpMode;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否启用")
private Boolean enable;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("旅行社id")
private String travelAgencyId;
/**
* 页面提交的选择线路模式,仅用于接收请求参数,不持久化到数据库。
* 1 表示分工会选择线路,2 表示校工会选择线路。
*/
private Integer mode;
}
@@ -0,0 +1,47 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import lombok.Data;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLot
* @Description: TODO
* @Author zzr
* @Date 2023/6/6
* @Version V1.0
**/
@Table("inclusive_therapy_v3_lot")
@Data
@Accessors(chain = true)
public class TheRapyRecuperationLot {
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("标段")
private String lotName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("标段值")
private String lotValue;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("费用")
private Integer activityCost;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("配置ID")
private String configId;
}
@@ -0,0 +1,94 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.LegacyBaseModel;
import com.budwk.app.sys.models.Sys_file;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency
* @Description: 疗休养旅行社管理
* @Author zxc
* @Date 2022/5/31:14:39
* @Version V1.0
**/
@EqualsAndHashCode(callSuper = true)
@Data
@Table("inclusive_therapy_v3_travel_agency")
@Accessors(chain = true)
public class TheRapyRecuperationTravelAgency extends LegacyBaseModel {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("旅行社编号")
private String serialNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("旅行社名称")
private String travelAgencyName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("旅行社联系人")
private String contact;
@Column
@ColDefine(type = ColType.VARCHAR, width = 11)
@Comment("旅行社联系人手机")
private String contactMobileNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("旅行社邮箱")
private String email;
/**
* 旅行社最多承担出行人数,移动端线路报名时按该旅行社承担的所有线路合并校验。
*/
@Column
@ColDefine(type = ColType.INT)
@Comment("最多承担人数")
private Integer maxUndertakeNumber;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("旅行社官网")
private String officialWebsite;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("备注")
private String note;
@Column
@ColDefine(type = ColType.INT)
@Comment("年度")
private Integer year;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否禁用")
private boolean isDisabled;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("缩略图")
private String files;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否自由组团")
private Boolean signUpTravelAgency;
}
@@ -0,0 +1,105 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 管理员查看分工会已选择线路的出行时间段。
*/
@Data
@Accessors(chain = true)
public class LineSelectionOverviewTimeSlotVo {
/**
* 分工会选择线路记录 ID。
*/
private String id;
/**
* 报名开始时间。
*/
private Date signUpStartTime;
/**
* 报名结束时间。
*/
private Date signUpEndTime;
/**
* 变更截止时间。
*/
private Date changeEndTime;
/**
* 调剂报名截止时间。
*/
private Date adjustSignUpEndTime;
/**
* 出行开始时间。
*/
private Date playStartTime;
/**
* 出行结束时间。
*/
private Date playEndTime;
/**
* 旅行社名称。
*/
private String travelAgencyName;
/**
* 旅行社 ID。
*/
private String travelAgencyId;
/**
* 联系人。
*/
private String contact;
/**
* 联系电话。
*/
private String contactPhone;
/**
* 联络人。
*/
private String principal;
/**
* 联络人联系方式。
*/
private String principalContact;
/**
* 交通工具。
*/
private String trafficTools;
/**
* 预计费用。
*/
private String estimatedCost;
/**
* 最少成团人数,包含家属。
*/
private Integer estimatedFamilyNumbers;
/**
* 最多人数,为 0 时不限制。
*/
private Integer maxPeopleNumber;
/**
* 是否启用。
*/
private Boolean enable;
}
@@ -0,0 +1,87 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 管理员查看分工会已选择线路列表。
*/
@Data
@Accessors(chain = true)
public class LineSelectionOverviewVo {
/**
* 线路 ID,对应 inclusive_therapy_v3_line.id。
*/
private String lineId;
/**
* 分工会选择线路记录 ID,用于定位该线路已选择状态。
*/
private String lineUnionSelectId;
/**
* 当前列表行对应的分工会选择线路记录 ID,保留该字段用于兼容前端提交参数。
*/
private String lineUnionSelectIds;
/**
* 年度。
*/
private Integer year;
/**
* 线路序号。
*/
private Integer serialNumber;
/**
* 线路名称。
*/
private String lineName;
/**
* 线路类型,例如省内、省外。
*/
private String regionalNature;
/**
* 时间标段名称。
*/
private String lotName;
/**
* 出行时间段,多个时间段用逗号连接。
*/
private String playTimes;
/**
* 报名时间段,多个时间段用逗号连接。
*/
private String signUpTimes;
/**
* 调剂报名截止时间。
*/
private String adjustSignUpEndTime;
/**
* 组织形式,1 表示分工会,2 表示校工会。
*/
private Integer signUpMode;
/**
* 选择线路的分工会 ID。
*/
private String unionId;
/**
* 选择线路的分工会名称。
*/
private String unionName;
/**
* 是否开放对外报名。
*/
private Boolean isOpen;
}
@@ -0,0 +1,42 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 旅行社月度报名数量统计。
*/
@Data
@Accessors(chain = true)
public class TravelAgencyMonthlyEnrollStatisticsVo {
/**
* 旅行社 ID,对应 inclusive_therapy_v3_travel_agency.id。
*/
private String travelAgencyId;
/**
* 旅行社名称,用于图表分组展示。
*/
private String travelAgencyName;
/**
* 统计年度。
*/
private Integer year;
/**
* 月份数字,取值范围 1-12。
*/
private Integer month;
/**
* 月份展示名称,例如 1月、2月。
*/
private String monthName;
/**
* 当前旅行社在该月份的有效报名数量。
*/
private Integer enrollNumber;
}
@@ -0,0 +1,42 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 二级工会疗休养出行人数统计。
*/
@Data
@Accessors(chain = true)
public class UnionEnrollStatisticsVo {
/**
* 二级工会 ID,对应报名人的本人分工会 selfUnionId。
*/
private String unionId;
/**
* 二级工会名称,用于图表横轴展示。
*/
private String unionName;
/**
* 统计年度。
*/
private Integer year;
/**
* 月份数字,取值范围 1-12。
*/
private Integer month;
/**
* 月份展示名称,例如 1月、2月。
*/
private String monthName;
/**
* 当前二级工会在该月份的有效报名人数。
*/
private Integer enrollNumber;
}
@@ -0,0 +1,47 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 分工会线路数量配置与当前年度选择数量统计。
*/
@Data
@Accessors(chain = true)
public class UnionLineNumberStatisticsVo {
/**
* 分工会 ID,对应 sys_union.id。
*/
private String unionId;
/**
* 分工会名称,对应 sys_union.unionname。
*/
private String unionName;
/**
* 基础设置中配置的最低省外线路数量。
*/
private Integer provinceOutNumber;
/**
* 基础设置中配置的最低省内线路数量。
*/
private Integer provinceInNumber;
/**
* 当前年度该分工会已选择的省外线路数量。
*/
private Integer selectedProvinceOutNumber;
/**
* 当前年度该分工会已选择的省内线路数量。
*/
private Integer selectedProvinceInNumber;
/**
* 是否同时满足省外、省内最低选择数量要求。
*/
private Boolean finished;
}
@@ -0,0 +1,32 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 分工会选择线路数量提示信息。
*/
@Data
@Accessors(chain = true)
public class UnionLineSelectLimitVo {
/**
* 当前登录人所属分工会在基础设置中配置的最少省外线路选择数量。
*/
private Integer minProvinceOutNumber;
/**
* 当前登录人所属分工会在基础设置中配置的最少省内线路选择数量。
*/
private Integer minProvinceInNumber;
/**
* 当前登录人所属分工会本年度已选择的省外线路数量。
*/
private Integer selectedProvinceOutNumber;
/**
* 当前登录人所属分工会本年度已选择的省内线路数量。
*/
private Integer selectedProvinceInNumber;
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyAudit;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import org.nutz.lang.util.NutMap;
import java.util.List;
public interface TheRapyRecuperationAuditService extends TherapyService<TherapyAudit> {
/**
* 根据分工会查询线路
*
* @param
* @param unionId
* @param regionalNature 是否省内省外 可为空
* @param year 可为空
* @return
*/
List<NutMap> getXlByUnion(Integer state, String unionId, String regionalNature, String year,String endYear, Integer signUpMode, String agencyId);
/**
*
* @param id
* @return
*/
NutMap findOne(String id);
/**
* 校工会审核
* @param stateId
* @param loginName
* @param adjustment
* @param takePartInLineId
*/
void schoolAudit(Integer stateId, String loginName,Boolean adjustment, String takePartInLineId);
}
@@ -0,0 +1,17 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationType;
public interface TheRapyRecuperationCommonService extends TherapyService {
/**
* 可以报名吗
*
* @param loginName 用户名
* @return boolean
*/
boolean canSignUp(String loginName, TheRapyRecuperationType theRapyRecuperationType);
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
public interface TheRapyRecuperationEnrollJoinUserImportService extends TherapyService {
List<?> selectLineAndTravelAgencyList(Integer year, String keyword);
Map<String, List<NutMap>> selectLineOrTravelAgency(Integer year);
}
@@ -0,0 +1,229 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyUnion;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.TravelAgencyMonthlyEnrollStatisticsVo;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.vo.UnionEnrollStatisticsVo;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
/**
* 疗休养报名service
*
* @author jug
* @date 2022/06/01
*/
public interface TheRapyRecuperationEnrollService extends TherapyService<TheRapyRecuperationEnroll> {
/**
* 报名页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @param unionId 工会 ID
* @param trrt 疗休养线路类型
* @param lineUnionType 线路筛选类型,1 本分工会、2 其他分工会、3 校工会、4 全部
* @param lineKeyword 移动端线路名称搜索关键字
* @param signUpStatus 报名状态筛选,0 全部、1 报名中、2 报名已结束
* @return {@link Pagination}
*/
Pagination enrollPageData(PageForm pageForm, Integer year, String unionId, int trrt, Integer lineUnionType, String lineKeyword, Integer signUpStatus);
List<NutMap> getSelectLineById(String lineId, String usId, String unionId, int trrt, Integer lineUnionType, Integer signUpStatus);
Object openSignUser(String usId, String travelId, String searchKeyWord);
/**
* 线路报名
*
* @param enrollInfo 登记信息
*/
void doSignUpForLine(TheRapyRecuperationEnroll enrollInfo);
/**
* 校工会代选线路报名。
*
* @param enrollInfo 包含被报名人工号和线路选择表id的报名信息
*/
void doProxySignUpForLine(TheRapyRecuperationEnroll enrollInfo);
/**
* 变更报名
*
* @param enrollInfo 登记信息
*/
void updateSignUpLine(TheRapyRecuperationEnroll enrollInfo);
/**
* 报名旅行社
*
* @param enrollInfo 登记信息
*/
void doSignUpForTravelAgency(TheRapyRecuperationEnroll enrollInfo);
/**
* 报名酒店
*
* @param enrollInfo 登记信息
*/
void doSignUpForHotel(TheRapyRecuperationEnroll enrollInfo);
void updateSignUpHotel(TheRapyRecuperationEnroll enrollInfo);
/**
* 变更报名旅行社
*
* @param enrollInfo 登记信息
*/
void updateSignUpTravelAgency(TheRapyRecuperationEnroll enrollInfo);
/**
* 验证报名登记信息
*
* @param enrollInfo 登记信息
* @param loginName 用户名
* @return {@link Map}<{@link Boolean}, {@link String}>
*/
Map<Boolean, String> validSignUpInfo(String loginName, TheRapyRecuperationEnroll enrollInfo);
Map<Boolean, String> validSignUpInfoForZJXU(String loginName, TheRapyRecuperationEnroll enrollInfo);
Map<Boolean, String> validSignUpInfoForZJNU(String loginName, TheRapyRecuperationEnroll enrollInfo);
/**
* 校工会代选线路报名校验,不校验旅行社最多承担人数。
*
* @param loginName 被报名人工号
* @param enrollInfo 报名信息
* @return {@link Map}<{@link Boolean}, {@link String}>
*/
Map<Boolean, String> validProxySignUpInfoForLine(String loginName, TheRapyRecuperationEnroll enrollInfo);
/**
* 校工会代选线路人员搜索。
*
* @param keyword 姓名或工号关键字
* @return 人员下拉列表
*/
List<NutMap> searchProxySignUpUsers(String keyword);
/**
* 校工会代选线路查询,返回校工会和分工会已选择的线路时间段。
*
* @param year 主页面选择年份
* @return 线路时间段下拉列表
*/
List<NutMap> getProxySignUpLines(Integer year);
/**
* 补发指定年度已标记删除的未成团通知。
*
* @param year 报名年度,按 signingUptime 所在年份筛选
* @return 实际触发消息发送的报名记录数量
*/
int resendDeletedFailNotice(Integer year);
/**
* 手动发送所选线路的成团邮件给旅行社。
*
* @param lineUnionSelectIds 统计页勾选的线路选择记录 ID,对应 inclusive_therapy_v3_line_union_select.id
* @return 实际发送邮件的旅行社数量
*/
int sendTakePartInUserByLineMail(List<String> lineUnionSelectIds);
/**
* 校验线路指定旅行社最多承担人数。
*
* @param enrollInfo 报名信息
* @return {@link Map}<{@link Boolean}, {@link String}>
*/
Map<Boolean, String> validTravelAgencyMaxUndertakeNumber(TheRapyRecuperationEnroll enrollInfo);
/**
* 我报名的页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
Pagination mySignUpPageData(PageForm pageForm, Cnd cnd, int trrt, Integer year);
/**
* 找到报名信息通过id
*
* @param id id
* @return {@link TheRapyRecuperationEnroll}
*/
TheRapyRecuperationEnroll findSignUpInfoById(String id);
/**
* 删除我的报名信息
*
* @param id id
*/
void deleteMyEnrollInfoById(String id);
/**
* 校验我的疗休养报名是否允许取消。
*
* @param id 报名记录id
* @return 为空表示允许取消;非空表示不允许取消的提示文案
*/
String validateCanDeleteMyEnrollInfo(String id);
/**
* 手机端线路介绍所有信息
*
* @param usId usId
* @param usUnionId usUnionId
* @return {@link NutMap}
*/
NutMap selectLineAllInfo(String usId, String usUnionId, String year);
List<TherapyUnion> getTheRapyUnions(Integer year, int theRapyRecuperationType);
/**
* 按旅行社统计指定年度每个月的有效报名数量。
*
* @param year 统计年度,为空时使用当前年度
* @return 旅行社月度报名数量 VO 列表,只返回有报名数据的月份
*/
List<TravelAgencyMonthlyEnrollStatisticsVo> getTravelAgencyMonthlyEnrollStatistics(Integer year);
/**
* 构建旅行社月度统计导出数据。
* 参数 year 为统计年度;返回 NutMap,其中 months 为有数据的月份数字列表,rows 为按旅行社横向展开后的导出行。
*
* @param year 统计年度,为空时使用当前年度
* @return 导出数据,包含动态月份列和行数据
*/
NutMap getTravelAgencyMonthlyEnrollExportData(Integer year);
/**
* 按报名人本人二级工会和报名月份统计指定年度有效报名人数。
*
* @param year 统计年度,为空时使用当前年度
* @return 二级工会月度出行人数 VO 列表,只返回有报名数据的月份
*/
List<UnionEnrollStatisticsVo> getUnionEnrollStatistics(Integer year);
/**
* 构建二级工会月度出行人数导出数据。
* 参数 year 为统计年度;返回 NutMap,其中 months 为有数据的月份数字列表,rows 为按二级工会横向展开后的导出行。
*
* @param year 统计年度,为空时使用当前年度
* @return 导出数据,包含动态月份列和行数据
*/
NutMap getUnionEnrollExportData(Integer year);
}
@@ -0,0 +1,16 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import java.util.List;
public interface TheRapyRecuperationLineAdjustmentService extends TherapyService {
Pagination pageData(PageForm pageForm, Integer year, String lineId, String unionId, String keywords, String regionalNature, String lotId);
List findUnionSignUpModeUserList(String lineId, String unionId);
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationCluster;
import java.util.List;
public interface TheRapyRecuperationLineClusterService extends TherapyService<TheRapyRecuperationCluster> {
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @param unionId 工会id
* @param keywords 关键字
* @return {@link Pagination}
*/
Pagination pageData(PageForm pageForm, Integer year, String unionId, String keywords);
/**
* 查询组团信息
*
* @param lineId 线路id
* @param lineId 归属工会id
* @return {@link Object}
*/
Object findClusterInfo(String lineId, String usUnionId);
/**
* 设置组团成员
*
* @param clusters 集群
* @param lineId 行id
*/
void setClusterMembers(List<TheRapyRecuperationCluster> clusters, String lineId);
}
@@ -0,0 +1,107 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyLineImportExcelMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyLineImportImageMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineService
* @Description: 疗休养线路管理service
* @Author zxc
* @Date 2022/5/31:09:45
* @Version V1.0
**/
public interface TheRapyRecuperationLineService extends TherapyService<TheRapyRecuperationLine> {
/**
* 删除线路
*
* @param lineId 线路id
*/
void deleteLine(String lineId);
/**
* 添加线路
*
* @param line 线路
*/
void addLine(TheRapyRecuperationLine line);
/**
* 编辑线路
*
* @param line 线路
*/
void editLine(TheRapyRecuperationLine line);
/**
* 开启或关闭线路
*
* @param lineId 线路id
*/
void openClosedLine(String lineId);
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
Pagination pageData(PageForm pageForm, Cnd cnd);
/**
* 查询线路详细信息
*
* @param lineId 行id
* @return {@link TheRapyRecuperationLine}
*/
TheRapyRecuperationLine selectLineInfoById(String lineId);
/**
* 根据分工会选择的线路id查询所该线路报名的人
*
* @param pageForm 页面形式
* @param lineId 行id
* @return {@link List}<{@link NutMap}>
*/
Pagination selectLineUser(PageForm pageForm, String lineId, String unionId);
/**
* 清除线路详细信息
*
* @param lineId 线路id
*/
void deleteLineInfoCache(String lineId);
/**
* 查看各个分工会设置的时间信息
*
* @param lineId 线路id
* @return {@link List}<{@link NutMap}>
*/
List<NutMap> viewUnionSelectTimeInfo(String lineId);
/**
* 按PC端线路管理页面字段导入线路。
*
* @param excelList 线路导入模板数据
* @param imageMap 移动端缩略图列的内嵌图片,key为导入数据行下标
* @return 导入成功数量
*/
int importLineByPageFields(List<TheRapyLineImportExcelMode> excelList, Map<Integer, TheRapyLineImportImageMode> imageMap);
}
@@ -0,0 +1,108 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* 分工会选择线路
*
* @author jug
* @date 2022/06/01
*/
public interface TheRapyRecuperationLineUnionSelectService extends TherapyService<TheRapyRecuperationLineUnionSelect> {
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @param year 年度
* @param mode 页面模式,1 表示分工会选择线路,2 表示校工会选择线路
* @return {@link Pagination}
*/
Pagination pageData(PageForm pageForm, Cnd cnd, Integer year, Integer mode);
/**
* 选择线路
*
* @param us 分工会选择线路信息
*/
void selectLine(TheRapyRecuperationLineUnionSelect us);
/**
* 保存分工会或校工会选择线路的出行时段。
*
* @param lineUnionSelects 出行时段列表,mode 用于区分分工会和校工会页面
*/
void selectLineTimes(TheRapyRecuperationLineUnionSelect[] lineUnionSelects);
/**
* 管理员维护指定分工会已选择线路的全部出行时间段信息。
*
* @param lineUnionSelects 出行时间段列表,每项包含时间、旅行社、联系人、人数和启用状态等字段
* @param lineId 线路 ID,用于限定只能修改当前线路的时间段
* @param unionId 分工会 ID,用于限定只能修改当前分工会选择的时间段
* @param year 年度,用于限定当前页面筛选年度下的选择记录
*/
void adminSaveLineTimes(TheRapyRecuperationLineUnionSelect[] lineUnionSelects, String lineId, String unionId, Integer year);
/**
* 已经选择的线路ids
*
* @param year 选择年份
* @param mode 页面模式,1 表示分工会选择线路,2 表示校工会选择线路
* @return {@link List}<{@link String}>
*/
List<String> getHasSelectLineIds(Integer year, Integer mode);
/**
* 设置的活动时间信息
*
* @param lineId 行id
* @return {@link Object}
*/
Object selectLineInfo(String lineId, String unionId,Integer mode, Integer year);
/**
* 设置线路时间信息
*
* @param unionSelect 联盟选择
*/
void setLineInfo(TheRapyRecuperationLineUnionSelect unionSelect);
/**
* 查询某个分工会设置的线路时间信息
*
* @param lineId 行id
* @param usUnionId 我们工会id
* @return {@link NutMap}
*/
TheRapyRecuperationLineUnionSelect findUsLineInfo(String lineId, String usUnionId);
/**
* 分工会取消选择线路
*
* @param usId union_select 主键id
*/
void deSelect(String usId);
/**
* 校验当前页面模式是否允许选择、修改或取消选择线路。
* mode=2 表示校工会选择线路,不受基础设置选择线路时间控制;
* 其他模式在基础设置已配置完整开始/结束时间时,当前时间必须落在配置范围内。
*
* @param mode 选择线路页面类型,1 表示分工会选择线路,2 表示校工会选择线路
*/
void validateLineSelectTime(Integer mode);
}
@@ -0,0 +1,79 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyService;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* 疗休养旅行社
*
* @author jug
* @date 2022/05/31
*/
public interface TheRapyRecuperationTravelAgencyService extends TherapyService<TheRapyRecuperationTravelAgency> {
/**
* 删除旅行社
*
* @param travelAgencyId 旅行社 ID
*/
void deleteTravelAgency(String travelAgencyId);
/**
* 添加旅行社
*
* @param travelAgency 旅行社
*/
void addTravelAgency(TheRapyRecuperationTravelAgency travelAgency);
/**
* 编辑旅行社
*
* @param travelAgency 旅行社
*/
void editTravelAgency(TheRapyRecuperationTravelAgency travelAgency);
/**
* 开启或关闭旅行社
*
* @param travelAgencyId 旅行社id
*/
void openTravelAgency(String travelAgencyId);
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
Pagination pageData(PageForm pageForm, Cnd cnd);
/**
* 查询旅行社
*
* @param cnd cnd
* @return {@link List}<{@link TheRapyRecuperationTravelAgency}>
*/
List<TheRapyRecuperationTravelAgency> selectAllTravelAgencyByYear(Cnd cnd);
/**
* 根据旅行社id查询所该旅行社报名的人,只查报旅行社的人跟线路没关系
*
* @param pageForm 页面形式
* @param id 旅行社id
* @return {@link List}<{@link NutMap}>
*/
Pagination selectAgencyUser(PageForm pageForm,String id);
}
@@ -0,0 +1,13 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.baseManage;
import org.nutz.lang.util.NutMap;
/**
* @Author JyuHsin
* @Date 2023/6/7
* @Description
*/
public interface TheRapyRecuperationBaseManagerService {
NutMap selectBaseAllInfo(String id);
}
@@ -0,0 +1,169 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyMessage;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyAudit;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyUser;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollBed;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollCompanion;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationAuditService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationAuditServiceImpl extends TherapyServiceImpl<TherapyAudit> implements TheRapyRecuperationAuditService {
public TheRapyRecuperationAuditServiceImpl(Dao dao) {
super(dao);
}
@Inject
private TherapyMessage msgApi;
@Override
public List<NutMap> getXlByUnion(Integer state, String unionId, String regionalNature, String year,String endYear, Integer signUpMode, String agencyId) {
Sql sql = Sqls.create("""
SELECT
line.*,
lineu.id as selectId,
un.unionname,
DATE_FORMAT(lineu.playStartTime,'%Y-%m-%d') as playStartTime1
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_line_union_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
LEFT JOIN inclusive_therapy_v3_union un ON un.id = enroll.takePartInUnionId
$condition
""");
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(unionId)) {
cnd.and(Cnd.exps("enroll.takePartInUnionId", "=", unionId).or("enroll.selfUnionId", "=", unionId));
}
if (state != null && (state == 3 || state == 1)) {
cnd.and("enroll.takePartInUnionId", "=", TherapyContext.getUnionId());
}
if (state != null && state == 2) {
cnd.and("enroll.selfUnionId", "=", TherapyContext.getUnionId());
cnd.and("enroll.takePartInUnionId", "!=", TherapyContext.getUnionId());
}
cnd.andEX("lineu.signUpMode", "=", signUpMode);
cnd.andEX("line.regionalNature", "=", regionalNature);
addLineTravelAgencyCondition(cnd, agencyId);
if (StrUtil.isNotBlank(endYear)){
cnd.andEX("YEAR(enroll.signingUptime)", ">=", year);
cnd.andEX("YEAR(enroll.signingUptime)", "<=", endYear);
} else {
cnd.andEX("YEAR(enroll.signingUptime)", "=", year);
}
cnd.and("enroll.takePartInLineId", "is not", null);
cnd.and("enroll.takePartInLineId", "!=", "");
cnd.and("enroll.stateId", "=", TheRapyRecuperationState.PASS);
cnd.groupBy("line.id");
cnd.having(Cnd.where("playStartTime1", "is not", null));
cnd.asc("un.unionname").asc("lineu.lineId").asc("lineu.playStartTime");
sql.setCondition(cnd);
return listMap(sql);
}
/**
* 线路下拉按旅行社过滤。
* 线路选择记录和线路主表都可能保存旅行社,因此同时匹配两处字段。
*
* @param cnd 当前线路下拉查询条件
* @param travelAgencyId 旅行社 ID,为空时不增加过滤条件
*/
private void addLineTravelAgencyCondition(Cnd cnd, String travelAgencyId) {
if (StrUtil.isBlank(travelAgencyId)) {
return;
}
SqlExpressionGroup travelAgencyGroup = new SqlExpressionGroup();
travelAgencyGroup.or("lineu.travelAgencyId", "=", travelAgencyId);
travelAgencyGroup.or("line.travelAgencyId", "=", travelAgencyId);
cnd.and(travelAgencyGroup);
}
@Override
public NutMap findOne(String id) {
Sql sql = Sqls.create("""
SELECT
lxs.travelAgencyName,
ta.travelAgencyName as joinTravelAgencyName,
enroll.*,
line.lineName,
if(enroll.takePartInUnionId!=enroll.selfUnionId,true,false) isTransferIn,
(SELECT COUNT(1) FROM inclusive_therapy_v3_enroll_companion WHERE trreId=enroll.id and relation='亲属') isFamily
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_line_union_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
LEFT JOIN inclusive_therapy_v3_travel_agency lxs ON lxs.id = lineu.travelAgencyId
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = enroll.takePartInTravelAgencyId
where enroll.id=@id
""").setParam("id", id);
NutMap fetch = fetch(sql);
NutMap map = NutMap.NEW();
if (fetch == null) {
return map.addv("viewData", NutMap.NEW());
}
if (Strings.isNotBlank(fetch.getString("selfUnionAuditId"))) {
TherapyAudit selfUnionAudit = dao().fetch(TherapyAudit.class, fetch.getString("selfUnionAuditId"));
fetch.setv("selfUnionAudit", selfUnionAudit);
}
if (Strings.isNotBlank(fetch.getString("joinLineUnionAuditId"))) {
TherapyAudit joinLineUnionAudit = dao().fetch(TherapyAudit.class, fetch.getString("joinLineUnionAuditId"));
fetch.setv("joinLineUnionAudit", joinLineUnionAudit);
}
if (Strings.isNotBlank(fetch.getString("schoolUnionAuditId"))) {
TherapyAudit schoolUnionAudit = dao().fetch(TherapyAudit.class, fetch.getString("schoolUnionAuditId"));
fetch.setv("schoolUnionAudit", schoolUnionAudit);
}
if (Strings.isNotBlank(fetch.getString("bedInfoId"))) {
TheRapyRecuperationEnrollBed bedInfo = dao().fetch(TheRapyRecuperationEnrollBed.class, fetch.getString("bedInfoId"));
fetch.setv("bedInfo", bedInfo);
}
List<TheRapyRecuperationEnrollCompanion> companionList = dao().query(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "=", id));
companionList.forEach(v -> {
if (Strings.isNotBlank(v.getBedInfoId())) {
v.setBedInfo(dao().fetch(TheRapyRecuperationEnrollBed.class, v.getBedInfoId()));
}
});
map.addv("viewData", fetch.setv("companionList", companionList));
return map;
}
@Override
public void schoolAudit(Integer stateId, String loginName, Boolean adjustment, String takePartInLineId) {
TherapyUser user = dao().fetch(TherapyUser.class, Cnd.where("loginname", "=", loginName));
TheRapyRecuperationLineUnionSelect unionSelect = dao().fetch(TheRapyRecuperationLineUnionSelect.class, Cnd.where("id", "=", takePartInLineId));
TheRapyRecuperationLine theRapyRecuperationLine = dao().fetch(TheRapyRecuperationLine.class, Cnd.where("id", "=", unionSelect.getLineId()));
String content = "【智慧工会】%s老师您好,您报名的%s线路因报名人数不足已取消,请尽快进入智慧工会重新选择线路。"
.formatted(user.getUsername(),theRapyRecuperationLine.getLineName());
List list = List.of(Map.of("type", "User", "userId", user.getLoginname(), "name", user.getUsername()));
if (stateId.equals(TheRapyRecuperationState.PASS)) {
content = "【智慧工会】%s老师您好,您报名的%s线路已组团成功,请按约定出行。"
.formatted(user.getUsername(), theRapyRecuperationLine.getLineName());
}
//msgApi.sendMsg(content, list, "疗休养", " IntelligenceMode", MsgApi.sendMode.normal.name());
}
}
@@ -0,0 +1,66 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationType;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationCommonService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationCommonServiceImpl
* @Description: TODO
* @Author zxc
* @Date 2022/6/6:10:46
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationCommonServiceImpl extends TherapyServiceImpl implements TheRapyRecuperationCommonService {
public TheRapyRecuperationCommonServiceImpl(Dao dao) {
super(dao);
}
@Override
public boolean canSignUp(String loginName, TheRapyRecuperationType trrt) {
TheRapyRecuperationConfig config = dao().fetch(TheRapyRecuperationConfig.class);
//每年旅行频率
Integer travelFrequency = config.getTravelFrequency();
//省外几年去一次
Integer outsideNumber = config.getOutsideNumber();
//今年是否参加了? 旅游频率限制
Cnd cnd = Cnd.NEW();
cnd.and("loginName", "=", loginName);
cnd.and("YEAR(takePartInTime)", "=", DateUtil.thisYear());
cnd.and("isTakePartIn", "=", 1);
int joinCount = dao().count(TheRapyRecuperationEnroll.class, cnd);
if (joinCount == travelFrequency) {
return false;
}
//省外 outsideNumber 年内是否去过
if (trrt.getValue() == TheRapyRecuperationType.provinceOutLine.getValue()) {
Cnd lineCnd = cnd.clone();
lineCnd.and("takePartInLineId", "IS NOT", null);
lineCnd.and(new SqlExpressionGroup().andBetween("YEAR(takePartInTime)", DateUtil.thisYear() - 1, DateUtil.thisYear() - outsideNumber));
int lineJoinCount = dao().count(TheRapyRecuperationEnroll.class, lineCnd);
return lineJoinCount <= 0;
}
return false;
}
}
@@ -0,0 +1,79 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationEnrollJoinUserImportService;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationEnrollJoinUserImportServiceImpl
* @Description: TODO
* @Author zxc
* @Date 2022/6/14:09:57
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationEnrollJoinUserImportServiceImpl extends TherapyServiceImpl implements TheRapyRecuperationEnrollJoinUserImportService {
public TheRapyRecuperationEnrollJoinUserImportServiceImpl(Dao dao) {
super(dao);
}
@Override
public List<?> selectLineAndTravelAgencyList(Integer year, String keyword) {
Sql sql = Sqls.create("""
SELECT
id,
lineName AS label,
'线路' AS `type`
FROM
inclusive_therapy_v3_line
UNION ALL
SELECT
id,
travelAgencyName AS label,
'旅行社' AS `type`
FROM
inclusive_therapy_v3_travel_agency
""");
return listMap(sql);
}
@Override
public Map<String, List<NutMap>> selectLineOrTravelAgency(Integer year) {
Sql lineSql = Sqls.create("""
SELECT
id,
lineName AS label
FROM
inclusive_therapy_v3_line
WHERE
`year` = @year
AND createUnionId = @unionId
UNION
SELECT
line.id,
line.lineName AS label
FROM
inclusive_therapy_v3_line_union_select lus
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lus.lineId\s
WHERE
line.`year` = @year
AND lus.unionId = @unionId
""");
lineSql.setParam("year", year);
lineSql.setParam("unionId", TherapyContext.getUnionId());
Sql travelSql = Sqls.create("SELECT id,travelAgencyName AS label FROM inclusive_therapy_v3_travel_agency where year = @year");
travelSql.setParam("year", year);
return Map.of("lines", listMap(lineSql), "travels", listMap(travelSql));
}
}
@@ -0,0 +1,140 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineAdjustmentService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationLineAdjustmentServiceImpl
* @Description: TODO
* @Author zxc
* @Date 2022/6/10:10:04
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationLineAdjustmentServiceImpl extends TherapyServiceImpl implements TheRapyRecuperationLineAdjustmentService {
public TheRapyRecuperationLineAdjustmentServiceImpl(Dao dao) {
super(dao);
}
@Override
public Pagination pageData(PageForm pageForm, Integer year, String lineId, String unionId, String keywords, String regionalNature, String lotId) {
Sql sql = Sqls.create("""
SELECT
line.id,
line.serialNumber,
line.lineName,
line.regionalNature,
us.minimumGroupSize,
line.`year`,
line.isDisabled,
line.playNumberOfDays,
line.createUnionId,
line.signUpStartTime,
line.signUpEndTime,
line.changeEndTime,
line.signUpMode,
line.createMode,
us.id as usId,
us.playStartTime,
us.playEndTime,
line.files AS fileId,
create_gh.unionname AS createUnionName,
ta.travelAgencyName,
us.unionId,
select_gh.unionname AS selectUnionName,
(select count(1) from inclusive_therapy_v3_enroll where if(us.signUpMode = 1, takePartInUnionId = us.unionId, 1=1) AND takePartInLineId = us.id and isNormal=true) as signUpUserNum,
(select count(1) from inclusive_therapy_v3_enroll_companion where trreId in (select id from inclusive_therapy_v3_enroll where if(us.signUpMode = 1, takePartInUnionId = us.unionId, 1=1) AND takePartInLineId = us.id and isNormal=true)) as signUpUserFamilyNum,
(select ifnull(sum(familyNumber),0) from inclusive_therapy_v3_enroll where takePartInLineId = us.id and if(us.signUpMode = 1, takePartInUnionId = us.unionId, 1=1) and isNormal = true and stateId not in (2715,2725,2735) and YEAR(signingUptime)=@year) as familyNumber
FROM
inclusive_therapy_v3_line_union_select us
LEFT JOIN inclusive_therapy_v3_line line ON line.id = us.lineId
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = line.travelAgencyId
LEFT JOIN inclusive_therapy_v3_union create_gh ON create_gh.id = line.createUnionid
LEFT JOIN inclusive_therapy_v3_union select_gh ON select_gh.id = us.unionId
$condition
""");
sql.setParam("signUpSuccessCode", TheRapyRecuperationState.PASS);
sql.setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("line.regionalNature","=",regionalNature);
cnd.andEX("line.lotId", "=", lotId);
//cnd.and("line.signUpMode", "=", TheRapyRecuperationSignUpMode.UNION.getValue());
cnd.and("us.playStartTime", "is not", null);
//cnd.andEX("line.year", "=", year);
cnd.andEX("line.id", "=", lineId);
if (TherapyContext.hasAnyRoles("sysadmin,A06")) {
cnd.andEX("us.unionId", "=", unionId);
cnd.andEX("us.signUpMode", "=", Strings.isNotBlank(unionId) ? 1 : 2);
} else {
cnd.and("us.unionId", "=", TherapyContext.getUnionId());
cnd.and("us.signUpMode", "=", 1);
}
if (StrUtil.isNotBlank(keywords)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("line.lineName", keywords);
seg.orLike("line.serialNumber", keywords);
cnd.and(seg);
}
if (TherapyContext.isNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), pageForm.getPageOrderBy());
}
cnd.and("year(selectTime)", "=", year);
sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@Override
public List findUnionSignUpModeUserList(String lineId, String unionId) {
Sql sql = Sqls.create("""
SELECT
e.id,
e.loginName,
e.userName,
e.sex,
e.unitName,
e.unionName,
e.signingUptime,
e.isNormal,
count(c.id) as companionCount,
e.familyNumber
FROM
inclusive_therapy_v3_enroll e
LEFT JOIN inclusive_therapy_v3_enroll_companion c ON c.trreId = e.id
left join inclusive_therapy_v3_line_union_select us on e.takePartInLineId = us.id
WHERE
e.takePartInLineId = @lineId
and if(us.signUpMode = 1, e.takePartInUnionId = @unionId, 1=1)
GROUP BY e.id
""");
// AND (e.stateId = @passStateCode or e.stateId is null)
sql.setParam("lineId", lineId);
sql.setParam("unionId", unionId);
sql.setParam("passStateCode", TheRapyRecuperationState.PASS);
List<NutMap> list = listMap(sql);
for (NutMap rowMap : list) {
Sql companionSql = Sqls.create("select loginName,userName,sex,relation,idCard from inclusive_therapy_v3_enroll_companion where trreId=@trreId");
companionSql.setParam("trreId", rowMap.getString("id"));
List companionList = listMap(companionSql);
rowMap.setv("companionList", companionList);
}
return list;
}
}
@@ -0,0 +1,262 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationCluster;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationClusterMember;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineClusterService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationLineClusterServiceImpl
* @Description: 组团
* @Author zxc
* @Date 2022/6/17:09:04
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationLineClusterServiceImpl extends TherapyServiceImpl<TheRapyRecuperationCluster> implements TheRapyRecuperationLineClusterService {
public TheRapyRecuperationLineClusterServiceImpl(Dao dao) {
super(dao);
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param year 年度
* @param unionId 工会id
* @param keywords 关键字
* @return {@link Pagination}
*/
@Override
public Pagination pageData(PageForm pageForm, Integer year, String unionId, String keywords) {
// Sql sql = Sqls.create("""
// SELECT
// line.id,
// line.serialNumber,
// line.lineName,
// line.regionalNature,
// line.minimumGroupSize,
// line.`year`,
// line.isDisabled,
// line.playNumberOfDays,
// line.createUnionId,
// line.signUpStartTime,
// line.signUpEndTime,
// line.changeEndTime,
// line.createMode,
// line.signUpMode,
// gh.unionname AS ascriptionUnionName,
// gh.id AS ascriptionUnionId,
// u.username AS createUserName,
// ta.travelAgencyName,
// ( SELECT count( 1 ) FROM inclusive_therapy_v3_enroll WHERE takePartInUnionId = us.unionId AND takePartInLineId = line.id AND stateId = 2750 ) AS signUpUserNum,
// (
// SELECT
// count( 1 )\s
// FROM
// inclusive_therapy_v3_enroll_companion\s
// WHERE
// trreId IN ( SELECT id FROM inclusive_therapy_v3_enroll WHERE takePartInUnionId = us.unionId AND takePartInLineId = line.id AND stateId = 2750 )) AS signUpUserFamilyNum\s
// FROM
// inclusive_therapy_v3_line_union_select us
// LEFT JOIN inclusive_therapy_v3_line line ON line.id = us.lineId
// LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = line.travelAgencyId
// LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = us.unionId
// LEFT JOIN inclusive_therapy_v3_user u ON u.id = line.opBy
// $usCnd
// UNION ALL
// (SELECT
// line.id,
// line.serialNumber,
// line.lineName,
// line.regionalNature,
// line.minimumGroupSize,
// line.`year`,
// line.isDisabled,
// line.playNumberOfDays,
// line.createUnionId,
// line.signUpStartTime,
// line.signUpEndTime,
// line.changeEndTime,
// line.createMode,
// line.signUpMode,
// gh.unionname AS ascriptionUnionName,
// gh.id AS ascriptionUnionId,
// u.username AS createUserName,
// ta.travelAgencyName,
// ( SELECT count( 1 ) FROM inclusive_therapy_v3_enroll WHERE takePartInUnionId = line.createUnionId AND takePartInLineId = line.id AND stateId = 2750 ) AS signUpUserNum,
// (
// SELECT
// count( 1 )
// FROM
// inclusive_therapy_v3_enroll_companion
// WHERE
// trreId IN ( SELECT id FROM inclusive_therapy_v3_enroll WHERE takePartInUnionId = line.createUnionId AND takePartInLineId = line.id AND stateId = 2750 )) AS signUpUserFamilyNum
// FROM
// inclusive_therapy_v3_line line
// LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = line.travelAgencyId
// LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = line.createUnionid
// LEFT JOIN inclusive_therapy_v3_user u ON u.id = line.opBy
// $lineCnd)
// """);
// Cnd lineCnd = Cnd.NEW();
// //如果是超管 前端传工会id 就不查自由模式的线路 只查线路归属分工会的线路
// //如果是分工会管理员 不查不查自由模式的线路 由校工会去组团
// if (ShiroUtil.hasAnyRoles("sysadmin,A06")) {
// if (StrUtil.isNotBlank(unionId)) {
// sql.setVar("lineCnd", Cnd.where("1", "!=", "1"));
// } else {
// lineCnd.andEX("line.year", "=", year);
// lineCnd.andEX("line.createMode", "=", TheRapyRecuperationLineCreateMode.SCHOOL.getValue());
// lineCnd.andEX("line.signUpMode", "=", TheRapyRecuperationSignUpMode.FREE.getValue());
// lineCnd.and(Cnd.likeEX("line.lineName", keywords));
// sql.setVar("lineCnd", lineCnd);
// }
// } else {
// sql.setVar("lineCnd", Cnd.where("1", "!=", "1"));
// }
//
// Cnd usCnd = Cnd.NEW();
// usCnd.andEX("line.year", "=", year);
// usCnd.andEX("line.signUpMode", "=", TheRapyRecuperationSignUpMode.UNION.getValue());
// usCnd.and(Cnd.likeEX("line.lineName", keywords));
// usCnd.andEX("us.unionId", "=", unionId);
//
// //如果只是分工会管理员 us表只查询自己选择的线路
// if (!ShiroUtil.hasRole("sysadmin")) {
// usCnd.andEX("us.unionId", "=", Vi.getUnionId());
// }
//
// sql.setVar("usCnd", usCnd);
Sql sql = Sqls.create("""
SELECT
line.id,
line.serialNumber,
line.lineName,
line.regionalNature,
line.minimumGroupSize,
line.`year`,
line.isDisabled,
line.createUnionId,
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.playStartTime,
us.playEndTime,
line.createMode,
line.signUpMode,
gh.unionname AS ascriptionUnionName,
gh.id AS ascriptionUnionId,
u.username AS createUserName,
ta.travelAgencyName,
( SELECT count( 1 ) FROM inclusive_therapy_v3_enroll $summaryCnd ) AS signUpUserNum,
( SELECT count( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId IN ( SELECT id FROM inclusive_therapy_v3_enroll $summaryCnd )) AS signUpUserFamilyNum
FROM
inclusive_therapy_v3_line_union_select us
LEFT JOIN inclusive_therapy_v3_line line ON line.id = us.lineId
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = line.travelAgencyId
LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = us.unionId
LEFT JOIN inclusive_therapy_v3_user u ON u.id = line.opBy
$condition
""");
Cnd cnd = Cnd.NEW();
Cnd summaryCnd = Cnd.NEW();
summaryCnd.and("isNormal", "=", true);
summaryCnd.and("takePartInLineId", "=", "us.id");
summaryCnd.and("stateId", "=", TheRapyRecuperationState.PASS);
//如果是超级管理和校工会管理员,查看校工会线路
if (TherapyContext.hasAnyRoles("sysadmin,A06")) {
cnd.andEX("us.unionId", "=", unionId);
cnd.andEX("us.signUpMode", "=", Strings.isNotBlank(unionId) ? 1 : 2);
}else{
summaryCnd.and("takePartInUnionId", "=", "us.unionId");
cnd.andEX("us.signUpMode", "=", 1);
cnd.andEX("us.unionId", "=", TherapyContext.getUnionId());
}
cnd.andEX("line.year", "=", year);
cnd.and(Cnd.likeEX("line.lineName", keywords));
sql.setVar("summaryCnd", summaryCnd);
cnd.asc("line.serialNumber");
sql.setCondition(cnd);
return list(pageForm, sql);
}
/**
* 查询组团信息
*
* @param lineId 线路id
* @param lineId 归属工会id
* @return {@link Object}
*/
@Override
public Object findClusterInfo(String lineId, String usUnionId) {
NutMap resMap = NutMap.NEW();
Sql sql = Sqls.create("""
select
loginName,
userName,
sex,
unionName,
(select count(*) from inclusive_therapy_v3_enroll_companion c where c.trreId = e.id) as companionCount
from
inclusive_therapy_v3_enroll e
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("takePartInLineId", "=", lineId);
cnd.and("takePartInUnionId", "=", usUnionId);
cnd.and("isNormal", "=", 1);
cnd.and(Cnd.exps("stateId", "is", null).or("stateId", "=", TheRapyRecuperationState.PASS));
cnd.and("loginName", "not in", Sqls.create("select loginName from inclusive_therapy_v3_cluster_member where lineId = @lineId AND loginName is not null").setParam("lineId", lineId));
sql.setCondition(cnd);
List<NutMap> unSelectedUsers = listMap(sql);
resMap.put("unSelectedUsers", Map.of("clusterName", "线路未分配人员", "members", unSelectedUsers));
List<TheRapyRecuperationCluster> clusters = dao().query(TheRapyRecuperationCluster.class, Cnd.where("lineId", "=", lineId));
dao().fetchLinks(clusters, null);
if (Lang.isNotEmpty(clusters)) {
Map<String, TheRapyRecuperationCluster> clusterMap = clusters.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));
resMap.putAll(clusterMap);
}
return resMap;
}
/**
* 设置组团成员
*
* @param clusters 集群
* @param lineId 行id
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void setClusterMembers(List<TheRapyRecuperationCluster> clusters, String lineId) {
dao().clear(TheRapyRecuperationCluster.class, Cnd.where("lineId", "=", lineId));
dao().clear(TheRapyRecuperationClusterMember.class, Cnd.where("lineId", "=", lineId));
for (TheRapyRecuperationCluster cluster : clusters) {
insertWith(cluster, "members");
}
}
}
@@ -0,0 +1,662 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationLineCreateMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationProvinceType;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationSignUpMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.constant.TheRapyRecuperationState;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyLineImportExcelMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.mode.TheRapyLineImportImageMode;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnrollCompanion;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLine;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLot;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineService;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import org.nutz.aop.interceptor.ioc.TransAop;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.sys.enums.SysFileEngineTypeEnum;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.plugins.wkcache.annotation.CacheRemove;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationLineServiceImpl
* @Description: TODO
* @Author zxc
* @Date 2022/5/31:09:47
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationLineServiceImpl extends TherapyServiceImpl<TheRapyRecuperationLine> implements TheRapyRecuperationLineService {
/**
* 线路导入缩略图允许的图片类型,与系统通用上传图片类型保持一致。
*/
private static final List<String> LINE_IMPORT_IMAGE_TYPES = List.of("JPG", "JPEG", "PNG", "BMP", "SVG");
@Inject
private SysFileService sysFileService;
public TheRapyRecuperationLineServiceImpl(Dao dao) {
super(dao);
}
/**
* 删除线路 同时删除分工会选择线路数据
*
* @param lineId 线路id
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void deleteLine(String lineId) {
delete(lineId);
dao().clear(TheRapyRecuperationLineUnionSelect.class, Cnd.where("lineId", "=", lineId));
deleteLineInfoCache(lineId);
}
/**
* 添加线路 如果添加人是分工会管理员 同时添加到分工会选择线路表
*
* @param line 线路
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void addLine(TheRapyRecuperationLine line) {
boolean hasSchoolAdminRole = com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.hasAnyRoles(List.of("sysadmin", "A06"));
if (hasSchoolAdminRole) {
line.setCreateUnionId(null);
line.setCreateMode(TheRapyRecuperationLineCreateMode.SCHOOL.getValue());
insert(line);
} else if (com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.hasRole("H04")) {
line.setCreateUnionId(TherapyContext.getUnionId());
line.setCreateMode(TheRapyRecuperationLineCreateMode.UNION.getValue());
insert(line);
/*if (line.getSignUpMode() == TheRapyRecuperationSignUpMode.UNION.getValue()) {
TheRapyRecuperationLineUnionSelect unionSelect = new TheRapyRecuperationLineUnionSelect();
unionSelect.setUnionId(line.getCreateUnionId());
unionSelect.setLineId(line.getId());
unionSelect.setSelectTime(new Date());
unionSelect.setSelectUserId((String) com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.getPrincipalProperty("id"));
unionSelect.setSignUpStartTime(line.getSignUpStartTime());
unionSelect.setSignUpEndTime(line.getSignUpEndTime());
unionSelect.setChangeEndTime(line.getChangeEndTime());
unionSelect.setPlayStartTime(line.getPlayStartTime());
unionSelect.setPlayEndTime(line.getPlayEndTime());
insert(unionSelect);
}*/
}
}
/**
* 编辑线路
*
* @param line 线路
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void editLine(TheRapyRecuperationLine line) {
update(line);
/*if (line.getSignUpMode() == TheRapyRecuperationSignUpMode.UNION.getValue()) {
TheRapyRecuperationLineUnionSelect unionSelect = dao().fetch(TheRapyRecuperationLineUnionSelect.class, Cnd.where("lineId", "=", line.getId()));
if (unionSelect != null) {
unionSelect.setSignUpStartTime(line.getSignUpStartTime());
unionSelect.setSignUpEndTime(line.getSignUpEndTime());
unionSelect.setChangeEndTime(line.getChangeEndTime());
unionSelect.setPlayStartTime(line.getPlayStartTime());
unionSelect.setPlayEndTime(line.getPlayEndTime());
updateIgnoreNull(unionSelect);
} else {
TheRapyRecuperationLineUnionSelect insertUnionSelect = new TheRapyRecuperationLineUnionSelect();
insertUnionSelect.setUnionId(line.getCreateUnionId());
insertUnionSelect.setLineId(line.getId());
insertUnionSelect.setSelectTime(new Date());
insertUnionSelect.setSelectUserId((String) com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.getPrincipalProperty("id"));
insertUnionSelect.setSignUpStartTime(line.getSignUpStartTime());
insertUnionSelect.setSignUpEndTime(line.getSignUpEndTime());
insertUnionSelect.setChangeEndTime(line.getChangeEndTime());
insertUnionSelect.setPlayStartTime(line.getPlayStartTime());
insertUnionSelect.setPlayEndTime(line.getPlayEndTime());
insert(insertUnionSelect);
}
}
deleteLineInfoCache(line.getId());*/
}
/**
* 开启或关闭线路
*
* @param lineId 线路id
*/
/**
* 按PC端线路管理页面字段导入线路,并复用新增线路的保存逻辑补齐创建模式与创建工会。
*
* @param excelList 线路导入模板数据
* @param imageMap 移动端缩略图列的内嵌图片,key为导入数据行下标
* @return 导入成功数量
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public int importLineByPageFields(List<TheRapyLineImportExcelMode> excelList, Map<Integer, TheRapyLineImportImageMode> imageMap) {
if (excelList == null || excelList.isEmpty()) {
throw new IllegalArgumentException("导入数据不能为空");
}
Map<Integer, TheRapyLineImportImageMode> safeImageMap = imageMap == null ? Collections.emptyMap() : imageMap;
Set<Integer> serialNumberSet = new HashSet<>();
int successCount = 0;
for (int i = 0; i < excelList.size(); i++) {
TheRapyLineImportExcelMode mode = excelList.get(i);
if (isBlankLine(mode)) {
continue;
}
int rowNumber = i + 2;
// 页面新增线路必填项在导入时同样需要校验,避免生成不可维护的线路数据。
validImportRequired(mode, rowNumber);
if (!serialNumberSet.add(mode.getSerialNumber())) {
throw new IllegalArgumentException("第" + rowNumber + "行排序号在导入文件中重复");
}
if (count(Cnd.where("serialNumber", "=", mode.getSerialNumber())) > 0) {
throw new IllegalArgumentException("第" + rowNumber + "行排序号已存在");
}
// 移动端缩略图如果是Excel内嵌图片,优先保存图片并使用生成的filepath覆盖单元格文本。
TheRapyRecuperationLine line = buildLineByImportMode(mode, safeImageMap.get(i), rowNumber);
addLine(line);
successCount++;
}
if (successCount == 0) {
throw new IllegalArgumentException("导入数据不能为空");
}
return successCount;
}
/**
* 判断模板行是否为空行,空行不会参与校验和保存。
*
* @param mode 模板行数据
* @return true表示空行
*/
private boolean isBlankLine(TheRapyLineImportExcelMode mode) {
return mode == null
|| (mode.getYear() == null
&& mode.getSerialNumber() == null
&& StrUtil.isBlank(mode.getLineName())
&& StrUtil.isBlank(mode.getLotId())
&& StrUtil.isBlank(mode.getRegionalNature())
&& StrUtil.isBlank(mode.getTrafficTools())
&& mode.getEstimatedFamilyNumbers() == null
&& StrUtil.isBlank(mode.getEstimatedCost())
&& StrUtil.isBlank(mode.getSignUpMode())
&& StrUtil.isBlank(mode.getLineContact())
&& StrUtil.isBlank(mode.getLineContactPhone())
&& StrUtil.isBlank(mode.getContent())
&& StrUtil.isBlank(mode.getIsEnabled())
&& StrUtil.isBlank(mode.getTravelAgencyName())
&& StrUtil.isBlank(mode.getFamilySignUp())
&& StrUtil.isBlank(mode.getFiles()));
}
/**
* 校验线路管理页面中要求填写的核心字段。
*
* @param mode 模板行数据
* @param rowNumber Excel行号
*/
private void validImportRequired(TheRapyLineImportExcelMode mode, int rowNumber) {
if (StrUtil.isBlank(mode.getTravelAgencyName())) {
throw new IllegalArgumentException("第" + rowNumber + "行旅行社名称不能为空");
}
if (!StrUtil.equalsAny(StrUtil.trim(mode.getFamilySignUp()), "是", "否")) {
throw new IllegalArgumentException("第" + rowNumber + "行家属报名必填,请填写是或否");
}
if (mode.getYear() == null) {
throw new IllegalArgumentException("第" + rowNumber + "行年度不能为空");
}
if (mode.getSerialNumber() == null) {
throw new IllegalArgumentException("第" + rowNumber + "行排序号不能为空");
}
if (StrUtil.isBlank(mode.getLineName())) {
throw new IllegalArgumentException("第" + rowNumber + "行线路名称不能为空");
}
if (StrUtil.isBlank(mode.getLotId())) {
throw new IllegalArgumentException("第" + rowNumber + "行时间标段不能为空");
}
if (StrUtil.isBlank(mode.getRegionalNature())) {
throw new IllegalArgumentException("第" + rowNumber + "行线路类型不能为空");
}
if (StrUtil.isBlank(mode.getSignUpMode())) {
throw new IllegalArgumentException("第" + rowNumber + "行组织形式不能为空");
}
}
/**
* 将Excel模板行转换成线路实体,字段与PC端线路管理页面保存字段保持一致。
*
* @param mode 模板行数据
* @param imageMode 移动端缩略图内嵌图片
* @param rowNumber Excel行号
* @return 线路实体
*/
private TheRapyRecuperationLine buildLineByImportMode(TheRapyLineImportExcelMode mode, TheRapyLineImportImageMode imageMode, int rowNumber) {
List<TheRapyRecuperationTravelAgency> agencies = dao().query(TheRapyRecuperationTravelAgency.class,
Cnd.where("year", "=", mode.getYear()).and("travelAgencyName", "=", StrUtil.trim(mode.getTravelAgencyName())));
if (agencies.isEmpty()) {
throw new IllegalArgumentException("第" + rowNumber + "行旅行社名称在该年度不存在");
}
if (agencies.size() > 1) {
throw new IllegalArgumentException("第" + rowNumber + "行旅行社名称在该年度存在重名,无法确定旅行社");
}
TheRapyRecuperationLine line = new TheRapyRecuperationLine();
line.setTravelAgencyId(agencies.get(0).getId());
line.setIsFamilySignUp("是".equals(StrUtil.trim(mode.getFamilySignUp())));
line.setYear(mode.getYear());
line.setSerialNumber(mode.getSerialNumber());
line.setLineName(mode.getLineName());
line.setLotId(parseLotId(mode.getLotId(), rowNumber));
line.setRegionalNature(parseRegionalNature(mode.getRegionalNature(), rowNumber));
line.setTrafficTools(mode.getTrafficTools());
line.setMinimumGroupSize(1);
line.setPlayNumberOfDays(1);
line.setEstimatedFamilyNumbers(mode.getEstimatedFamilyNumbers());
line.setEstimatedCost(mode.getEstimatedCost());
line.setSignUpMode(parseSignUpMode(mode.getSignUpMode(), rowNumber));
line.setLineContact(mode.getLineContact());
line.setLineContactPhone(mode.getLineContactPhone() == null ? null : mode.getLineContactPhone().trim());
line.setContent(mode.getContent());
// 页面保存时是否启用为开关默认值,导入未填写时同样按“启用”处理。
line.setDisabled(StrUtil.isBlank(mode.getIsEnabled()) ? false : parseIsDisabled(mode.getIsEnabled(), rowNumber));
String importImagePath = saveLineImportImage(imageMode, rowNumber);
line.setFiles(StrUtil.isNotBlank(importImagePath) ? importImagePath : mode.getFiles());
return line;
}
/**
* 将Excel时间标段下拉显示值转换为线路表实际保存的标段ID。
*
* @param lotValue Excel中读取到的标段显示名、标段ID或“显示名_ID”
* @param rowNumber Excel行号
* @return 时间标段ID
*/
private String parseLotId(String lotValue, int rowNumber) {
String value = StrUtil.trim(lotValue);
if (StrUtil.isBlank(value)) {
throw new IllegalArgumentException("第" + rowNumber + "行时间标段不能为空");
}
// EasyPoi的replace可能导入后台值,也可能导入显示名;先兼容“显示名_ID”格式。
String replaceValue = parseExcelReplaceValue(value);
TheRapyRecuperationLot lot = dao().fetch(TheRapyRecuperationLot.class, replaceValue);
if (lot == null) {
lot = dao().fetch(TheRapyRecuperationLot.class, Cnd.where("lotName", "=", value));
}
if (lot == null) {
lot = dao().fetch(TheRapyRecuperationLot.class, Cnd.where("lotName", "=", replaceValue));
}
if (lot == null) {
lot = dao().fetch(TheRapyRecuperationLot.class, Cnd.where("lotValue", "=", value));
}
if (lot == null) {
throw new IllegalArgumentException("第" + rowNumber + "行时间标段不正确");
}
return lot.getId();
}
/**
* 拆解EasyPoi下拉替换值,兼容“显示名_后台值”和纯显示名两种导入结果。
*
* @param value Excel单元格读取值
* @return 后台值或原始显示名
*/
private String parseExcelReplaceValue(String value) {
if (StrUtil.isBlank(value)) {
return value;
}
int splitIndex = value.lastIndexOf("_");
if (splitIndex >= 0 && splitIndex < value.length() - 1) {
return value.substring(splitIndex + 1);
}
return value;
}
/**
* 将Excel线路类型下拉显示值转换为页面实际保存的省内/省外值。
*
* @param regionalNature Excel中读取到的线路类型显示名或后台值
* @param rowNumber Excel行号
* @return 线路类型后台值
*/
private String parseRegionalNature(String regionalNature, int rowNumber) {
String value = StrUtil.trim(regionalNature);
if (StrUtil.isBlank(value)) {
throw new IllegalArgumentException("第" + rowNumber + "行线路类型不能为空");
}
String replaceValue = parseExcelReplaceValue(value);
if (StrUtil.equalsAny(value, TheRapyRecuperationProvinceType.provinceIn.getValue(), "省内线路", "provinceIn")
|| StrUtil.equalsAny(replaceValue, TheRapyRecuperationProvinceType.provinceIn.getValue(), "省内线路", "provinceIn")) {
return TheRapyRecuperationProvinceType.provinceIn.getValue();
}
if (StrUtil.equalsAny(value, TheRapyRecuperationProvinceType.provinceOut.getValue(), "省外线路", "provinceOut")
|| StrUtil.equalsAny(replaceValue, TheRapyRecuperationProvinceType.provinceOut.getValue(), "省外线路", "provinceOut")) {
return TheRapyRecuperationProvinceType.provinceOut.getValue();
}
throw new IllegalArgumentException("第" + rowNumber + "行线路类型不正确");
}
/**
* 保存线路导入中的移动端缩略图,并返回与页面上传组件一致的文件路径。
*
* @param imageMode Excel中提取出的内嵌图片数据
* @param rowNumber Excel行号
* @return 上传后的文件路径,为空表示该行没有内嵌图片
*/
private String saveLineImportImage(TheRapyLineImportImageMode imageMode, int rowNumber) {
if (imageMode == null || imageMode.getData() == null || imageMode.getData().length == 0) {
return null;
}
String suffix = normalizeLineImportImageSuffix(imageMode.getExtension(), rowNumber);
byte[] uploadBytes = compressLineImportImage(imageMode.getData(), suffix);
String name = StrUtil.isBlank(imageMode.getFileName()) ? "line-thumbnail." + suffix.toLowerCase() : imageMode.getFileName();
return sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), name, uploadBytes);
}
/**
* 校验并标准化导入图片后缀。
*
* @param extension 图片后缀
* @param rowNumber Excel行号
* @return 标准化后的大写图片后缀
*/
private String normalizeLineImportImageSuffix(String extension, int rowNumber) {
String suffix = StrUtil.blankToDefault(extension, "png").toUpperCase();
if (!LINE_IMPORT_IMAGE_TYPES.contains(suffix)) {
throw new IllegalArgumentException("第" + rowNumber + "行移动端缩略图仅支持jpg、jpeg、png、bmp、svg图片");
}
return suffix;
}
/**
* 按系统通用上传规则压缩导入图片,无法读取的图片直接返回原始字节。
*
* @param imageBytes 图片原始字节
* @param suffix 图片后缀
* @return 待上传的图片字节
*/
private byte[] compressLineImportImage(byte[] imageBytes, String suffix) {
if ("SVG".equalsIgnoreCase(suffix)) {
return imageBytes;
}
try {
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageBytes));
if (bufferedImage == null) {
return imageBytes;
}
int size = calculateLineImportImageSize(bufferedImage.getWidth(), bufferedImage.getHeight());
BufferedImage asBufferedImage = new BufferedImage(Math.max(1, bufferedImage.getWidth() / size),
Math.max(1, bufferedImage.getHeight() / size), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = asBufferedImage.createGraphics();
try {
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics.drawImage(bufferedImage, 0, 0, asBufferedImage.getWidth(), asBufferedImage.getHeight(), null);
} finally {
graphics.dispose();
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
boolean writeResult = ImageIO.write(asBufferedImage, suffix.toLowerCase(), output);
return writeResult && output.size() > 0 ? output.toByteArray() : imageBytes;
} catch (Exception e) {
return imageBytes;
}
}
/**
* 计算图片压缩比例,保持与系统通用上传压缩规则一致。
*
* @param srcWidth 原图宽度
* @param srcHeight 原图高度
* @return 压缩比例
*/
private int calculateLineImportImageSize(int srcWidth, int srcHeight) {
srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;
int longSide = Math.max(srcWidth, srcHeight);
int shortSide = Math.min(srcWidth, srcHeight);
float scale = ((float) shortSide / longSide);
if (scale <= 1 && scale > 0.5625) {
if (longSide < 1664) {
return 1;
} else if (longSide < 4990) {
return 2;
} else if (longSide > 4990 && longSide < 10240) {
return 4;
} else {
return longSide / 1280;
}
} else if (scale <= 0.5625 && scale > 0.5) {
return longSide / 1280 == 0 ? 1 : longSide / 1280;
} else {
return (int) Math.ceil(longSide / (1280.0 / scale));
}
}
/**
* 将页面组织形式下拉值转换为报名模式编码。
*
* @param signUpMode 组织形式文本或编码
* @param rowNumber Excel行号
* @return 报名模式编码
*/
private Integer parseSignUpMode(String signUpMode, int rowNumber) {
String value = StrUtil.trim(signUpMode);
String replaceValue = parseExcelReplaceValue(value);
if (StrUtil.equalsAny(value, "1", "分工会", "分工会组织")
|| StrUtil.equalsAny(replaceValue, "1", "分工会", "分工会组织")) {
return TheRapyRecuperationSignUpMode.UNION.getValue();
}
if (StrUtil.equalsAny(value, "2", "自由", "校工会", "校工会组织")
|| StrUtil.equalsAny(replaceValue, "2", "自由", "校工会", "校工会组织")) {
return TheRapyRecuperationSignUpMode.FREE.getValue();
}
throw new IllegalArgumentException("第" + rowNumber + "行组织形式不正确");
}
/**
* 将页面是否启用下拉值转换为线路禁用状态。
*
* @param isEnabled 是否启用文本
* @param rowNumber Excel行号
* @return true表示禁用,false表示启用
*/
private boolean parseIsDisabled(String isEnabled, int rowNumber) {
String value = StrUtil.trim(isEnabled);
String replaceValue = parseExcelReplaceValue(value);
if (StrUtil.equalsAny(value, "是", "启用", "true")
|| StrUtil.equalsAny(replaceValue, "是", "启用", "true")) {
return false;
}
if (StrUtil.equalsAny(value, "否", "禁用", "false")
|| StrUtil.equalsAny(replaceValue, "否", "禁用", "false")) {
return true;
}
throw new IllegalArgumentException("第" + rowNumber + "行是否启用不正确");
}
@Override
public void openClosedLine(String lineId) {
//位运算 取反
update(Chain.makeSpecial("isDisabled", "isDisabled ^ 1"), Cnd.where("id", "=", lineId));
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
@Override
public Pagination pageData(PageForm pageForm, Cnd cnd) {
Sql sql = Sqls.create("""
SELECT
line.id,
line.serialNumber,
line.lineName,
line.regionalNature,
line.minimumGroupSize,
line.year,
line.isDisabled,
line.playNumberOfDays,
line.createUnionId,
line.signUpMode,
line.createMode,
line.files AS fileId,
ifnull(gh.unionname, '校工会') AS createUnionName,
u.username AS createUserName,
ta.travelAgencyName,
ta.contact,
ta.contactMobileNumber,
ta.officialWebsite,
line.lotId,
lot.lotName AS lotName,
lot.lotValue AS lotValue
FROM
inclusive_therapy_v3_line line
LEFT JOIN inclusive_therapy_v3_travel_agency ta ON ta.id = line.travelAgencyId
LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = line.createUnionid
LEFT JOIN inclusive_therapy_v3_user u ON u.id = line.opBy
LEFT JOIN inclusive_therapy_v3_lot lot on lot.id = line.lotId
$condition
""");
sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
/**
* 查询线路详细信息
*
* @param lineId 线路id
* @return {@link String}
*/
@Override
public TheRapyRecuperationLine selectLineInfoById(String lineId) {
return fetchLinks(fetch(lineId), "travelAgency");
}
/**
* 根据分工会选择的线路id查询所该线路报名的人
*
* @param pageForm 页面形式
* @param lineId 行id
* @return {@link List}<{@link NutMap}>
*/
@Override
public Pagination selectLineUser(PageForm pageForm, String lineId, String unionId) {
Sql sql = Sqls.create("""
SELECT
line.lineName,
enroll.id,
enroll.loginName,
enroll.userName,
enroll.unionName,
enroll.unitName,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id) isFamily
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_line_union_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
WHERE
enroll.takePartInLineId = @takePartInLineId
and enroll.stateId=@stateId
$unionCnd
""").setParam("takePartInLineId", lineId).setParam("stateId", TheRapyRecuperationState.PASS);
if (StrUtil.isNotBlank(unionId) && !TherapyContext.hasAnyRoles("sysadmin")) {
sql.setVar("unionCnd", "and (enroll.takePartInUnionId='%s' or enroll.selfUnionId='%s')".formatted(unionId, unionId));
//sql.setVar("unionCnd", "and enroll.selfUnionId='%s'".formatted(unionId));
}
Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> list = pagination.getList();
list.forEach(v -> {
List<TheRapyRecuperationEnrollCompanion> companionList = dao().query(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "=", v.getString("id")));
for (TheRapyRecuperationEnrollCompanion enrollCompanion : companionList) {
dao().fetchLinks(enrollCompanion, "bedInfo");
}
v.setv("companionList", companionList);
});
return pagination;
}
/**
* 清除线路详细信息
*
* @param lineId 线路id
*/
@Override
@CacheRemove(cacheKey = "${args[0]}_selectLineInfoById")
public void deleteLineInfoCache(String lineId) {
}
/**
* 查看各个分工会设置的时间信息
*
* @param lineId 线路id
* @return {@link List}<{@link NutMap}>
*/
@Override
public List<NutMap> viewUnionSelectTimeInfo(String lineId) {
Sql sql = Sqls.create("""
SELECT
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.playStartTime,
us.playEndTime,
gh.unionname AS selectUnionName
FROM
`inclusive_therapy_v3_line_union_select` us
LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = us.unionId
WHERE us.lineId = @lineId
""");
return listMap(sql);
}
}
@@ -0,0 +1,476 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationLineUnionSelectService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationLineUnionSelectServiceImpl
* @Description: 分工会选择线路
* @Author zxc
* @Date 2022/6/1:10:18
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationLineUnionSelectServiceImpl extends TherapyServiceImpl<TheRapyRecuperationLineUnionSelect>
implements TheRapyRecuperationLineUnionSelectService {
public TheRapyRecuperationLineUnionSelectServiceImpl(Dao dao) {
super(dao);
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @param year 年度
* @param mode 页面模式,1 表示分工会选择线路,2 表示校工会选择线路
* @return {@link Pagination}
*/
@Override
public Pagination pageData(PageForm pageForm, Cnd cnd, Integer year, Integer mode) {
Sql sql = Sqls.create("""
select
line.id,
line.serialNumber,
line.lineName,
line.regionalNature,
line.minimumGroupSize,
line.year,
line.isDisabled,
line.playNumberOfDays,
line.createUnionId,
GROUP_CONCAT(us.playStartTime,'至',us.playEndTime,ifnull(concat('(', usTa.travelAgencyName, ')'), '') order by us.playStartTime) as playTimes,
us.signUpStartTime,
us.signUpEndTime,
us.playStartTime,
us.playEndTime,
us.changeEndTime,
us.isOpen,
IFNULL(us.signUpMode, line.signUpMode) AS signUpMode,
line.createMode,
gh.unionname AS createUnionName,
u.username AS createUserName,
IFNULL(usTa.travelAgencyName, lineTa.travelAgencyName) AS travelAgencyName,
IFNULL(usTa.contact, lineTa.contact) AS contact,
IFNULL(usTa.contactMobileNumber, lineTa.contactMobileNumber) AS contactMobileNumber,
IFNULL(usTa.officialWebsite, lineTa.officialWebsite) AS officialWebsite,
lot.lotName,
us.unionId as usUnionId,
us.id as usId,
usUnion.unionname as belongUnionName,
(SELECT COUNT(*) FROM inclusive_therapy_v3_enroll WHERE takePartInLineId=us.id and isNormal=true) applyCount
from
inclusive_therapy_v3_line line
LEFT JOIN inclusive_therapy_v3_union gh ON gh.id = line.createUnionid
LEFT JOIN inclusive_therapy_v3_user u ON u.id = line.opBy
LEFT JOIN inclusive_therapy_v3_line_union_select us on us.lineId = line.id AND year(selectTime) = @year AND us.signUpMode = @mode $us
LEFT JOIN inclusive_therapy_v3_travel_agency usTa on usTa.id = us.travelAgencyId
LEFT JOIN inclusive_therapy_v3_travel_agency lineTa on lineTa.id = line.travelAgencyId
LEFT JOIN inclusive_therapy_v3_union usUnion on usUnion.id = us.unionId
LEFT JOIN inclusive_therapy_v3_lot lot on lot.id = line.lotId
$condition
""");
if (Integer.valueOf(1).equals(mode)) {
sql.setVar("us", "AND us.unionId = '%s'".formatted(TherapyContext.getUnionId()));
}
//sql.setParam("unionId", Vi.getUnionId());
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
sql.setParam("mode", mode == null ? 1 : mode);
/*SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("line.createUnionId", "=", Vi.getUnionId());
seg.or("line.createMode", "=", TheRapyRecuperationLineCreateMode.SCHOOL.getValue());
cnd.and(seg);*/
cnd.groupBy("line.id");
sql.setCondition(cnd);
Pagination pagination = list(pageForm, sql);
List<NutMap> list = pagination.getList();
List<String> hasSelectLineIds = getHasSelectLineIds(year, mode);
for (NutMap m : list) {
m.setv("isSelect", hasSelectLineIds.contains(m.getString("id")));
}
return pagination;
}
/**
* 选择线路
*
* @param us 分工会选择线路信息
*/
@Override
public void selectLine(TheRapyRecuperationLineUnionSelect us) {
us.setUnionId(TherapyContext.getUnionId());
us.setSelectTime(new Date());
us.setSelectUserId((String) com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext.getPrincipalProperty("id"));
if (StrUtil.isBlank(us.getId())) {
insert(us);
} else {
updateIgnoreNull(us);
}
insertOrUpdate(us);
}
/**
* 保存分工会或校工会选择线路的出行时段。
*
* @param lineUnionSelects 出行时段列表,mode 用于区分分工会和校工会页面
*/
@Override
public void selectLineTimes(TheRapyRecuperationLineUnionSelect[] lineUnionSelects) {
if (Lang.isEmpty(lineUnionSelects)) {
return;
}
TheRapyRecuperationLineUnionSelect lineUnionSelect = lineUnionSelects[0];
validateLineSelectTime(lineUnionSelect.getMode());
if (StrUtil.isBlank(lineUnionSelect.getLineId())) {
throw Lang.makeThrow("请选择有效的线路");
}
if (lineUnionSelect.getMode() == null) {
throw Lang.makeThrow("请选择有效的选择线路页面");
}
// 组织形式必须以页面入口 mode 为准,避免同时拥有分工会和校工会角色时保存成错误类型。
int signUpMode = lineUnionSelect.getMode();
if (!List.of(1, 2).contains(signUpMode)) {
throw Lang.makeThrow("请选择有效的选择线路页面");
}
// 清理旧时段时按当前线路、当前工会、当前年份和当前组织形式匹配,避免历史出行时段残留到代选线路下拉。
List<TheRapyRecuperationLineUnionSelect> oldUnionSelects = query(Cnd.where("unionId", "=", TherapyContext.getUnionId())
.and("lineId", "=", lineUnionSelect.getLineId())
.and("signUpMode", "=", signUpMode)
.and("YEAR(selectTime)", "=", DateUtil.thisYear()));
TheRapyRecuperationLineUnionSelect oldLineUnionSelect = dao().fetch(TheRapyRecuperationLineUnionSelect.class, Cnd.where("id", "=", lineUnionSelect.getId()));
for (TheRapyRecuperationLineUnionSelect unionSelect : lineUnionSelects) {
unionSelect.setSelectTime(new Date());
unionSelect.setSelectUserId(TherapyContext.getPlatformUid());
unionSelect.setUnionId(TherapyContext.getUnionId());
unionSelect.setIsOpen(Lang.isNotEmpty(oldLineUnionSelect) ? oldLineUnionSelect.getIsOpen() : true);
unionSelect.setSignUpMode(signUpMode);
}
dao().insertOrUpdate(lineUnionSelects);
List<String> newIds = Arrays.stream(lineUnionSelects).map(TheRapyRecuperationLineUnionSelect::getId).collect(Collectors.toList());
List<String> deleteIds = oldUnionSelects.stream().map(TheRapyRecuperationLineUnionSelect::getId).filter(v -> !newIds.contains(v)).collect(Collectors.toList());
if (Lang.isNotEmpty(deleteIds)) {
clear(Cnd.where("id", "in", deleteIds));
}
}
/**
* 已经选择的线路ids
*
* @param year 选择年份
* @param mode 页面模式,1 表示分工会选择线路,2 表示校工会选择线路
* @return {@link List}<{@link String}>
*/
@Override
public List<String> getHasSelectLineIds(Integer year, Integer mode) {
Sql sql = Sqls.create("""
select lineId from inclusive_therapy_v3_line_union_select
where signUpMode = @mode
$userCnd
$unionCnd
and year(selectTime) = @year
""");
sql.setParam("mode", mode == null ? 1 : mode);
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
sql.setVar("userCnd", "");
sql.setVar("unionCnd", "");
if (Integer.valueOf(1).equals(mode == null ? 1 : mode)) {
sql.setVar("unionCnd", "and unionId = @unionId");
sql.setParam("unionId", TherapyContext.getUnionId());
}
List<NutMap> lineIdsMap = (List<NutMap>) Daos.query(dao(), sql.toString(), Sqls.callback.maps());
return lineIdsMap.stream().map(v -> v.getString("lineId")).collect(Collectors.toList());
}
/**
* 设置的活动时间信息
*
* @param lineId 行id
* @return {@link Object}
*/
@Override
public Object selectLineInfo(String lineId, String unionId, Integer mode, Integer year) {
Sql sql;
sql = Sqls.create("""
select
us.id,
lineId,
signUpStartTime,
signUpEndTime,
changeEndTime,
adjustSignUpEndTime,
playStartTime,
playEndTime,
us.contact,
us.contactPhone,
us.principal,
us.principalContact,
minimumGroupSize,
trafficTools,
estimatedCost,
estimatedFamilyNumbers,
maxPeopleNumber,
us.travelAgencyId,
signUpMode,
enable,
ta.travelAgencyName
from
inclusive_therapy_v3_line_union_select us
left join inclusive_therapy_v3_travel_agency ta on ta.id = us.travelAgencyId
where unionId = @unionId
and lineId = @lineId
and signUpMode = @mode
and year(selectTime) = @year
ORDER BY signUpStartTime,playStartTime ASC
""");
sql.setParam("unionId", unionId);
sql.setParam("lineId", lineId);
sql.setParam("mode", mode);
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
return listMap(sql);
// TheRapyRecuperationLine line = dao().fetch(TheRapyRecuperationLine.class, lineId);
// if (line.getSignUpMode() == TheRapyRecuperationSignUpMode.UNION.getValue()) {
// sql = Sqls.create("""
// select
// id,
// lineId,
// signUpStartTime,
// signUpEndTime,
// changeEndTime,
// playStartTime,
// playEndTime,
// contact,
// contactPhone
// from
// inclusive_therapy_v3_line_union_select
// where unionId = @unionId
// and lineId = @lineId
// ORDER BY signUpStartTime ASC
// """);
// sql.setParam("unionId", unionId);
// sql.setParam("lineId", lineId);
// return listMap(sql);
// } else {
// sql = Sqls.create("""
// select
// id,
// signUpStartTime,
// signUpEndTime,
// changeEndTime,
// playStartTime,
// playEndTime
// from
// inclusive_therapy_v3_line
// where id = @lineId
// """);
// sql.setParam("lineId", lineId);
// return listMap(sql);
// }
}
/**
* 设置线路时间信息
*
* @param unionSelect 联盟选择
*/
@Override
public void setLineInfo(TheRapyRecuperationLineUnionSelect unionSelect) {
dao().updateIgnoreNull(unionSelect);
}
/**
* 查询某个分工会设置的线路时间信息
*
* @param lineId 行id
* @param usUnionId 我们工会id
* @return {@link NutMap}
*/
@Override
public TheRapyRecuperationLineUnionSelect findUsLineInfo(String lineId, String usUnionId) {
return dao().fetch(TheRapyRecuperationLineUnionSelect.class,
Cnd.where("lineId", "=", lineId)
.and("unionId", "=", usUnionId));
}
/**
* 分工会取消选择线路
*
* @param usId union_select 主键id
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void deSelect(String usId) {
TheRapyRecuperationLineUnionSelect lineUnionSelect = fetch(usId);
Cnd enrollCnd = Cnd.where("takePartInUnionId", "=", lineUnionSelect.getUnionId());
enrollCnd.and("takePartInLineId", "=", lineUnionSelect.getLineId());
dao().clear(TheRapyRecuperationEnroll.class, enrollCnd);
delete(usId);
}
/**
* 选择线路时间由基础设置统一控制;校工会选择线路 mode=2 按业务要求不受该时间限制。
*
* @param mode 选择线路页面类型,1 表示分工会选择线路,2 表示校工会选择线路
*/
@Override
public void validateLineSelectTime(Integer mode) {
if (Integer.valueOf(2).equals(mode)) {
return;
}
TheRapyRecuperationConfig config = dao().fetch(TheRapyRecuperationConfig.class);
if (config == null || config.getLineSelectStartTime() == null || config.getLineSelectEndTime() == null) {
return;
}
Date now = new Date();
if (DateUtil.compare(now, config.getLineSelectStartTime()) < 0) {
throw Lang.makeThrow("选择线路还未开始");
}
if (DateUtil.compare(now, config.getLineSelectEndTime()) > 0) {
throw Lang.makeThrow("选择线路已结束");
}
}
/**
* 管理员保存指定分工会已选择线路的全部时间段信息。
*
* @param lineUnionSelects 出行时间段列表,每项包含报名时间、出行时间、旅行社、联系人、人数和启用状态等字段
* @param lineId 线路 ID,只允许保存该线路下的时间段
* @param unionId 分工会 ID,只允许保存该分工会选择的时间段
* @param year 年度,按选择记录 selectTime 所属年份定位数据
*/
@Override
public void adminSaveLineTimes(TheRapyRecuperationLineUnionSelect[] lineUnionSelects, String lineId, String unionId, Integer year) {
if (Lang.isEmpty(lineUnionSelects)) {
throw Lang.makeThrow("请至少保留一个出行时间段");
}
Integer queryYear = year == null ? DateUtil.thisYear() : year;
List<TheRapyRecuperationLineUnionSelect> oldUnionSelects = query(Cnd.where("lineId", "=", lineId)
.and("unionId", "=", unionId)
.and("signUpMode", "=", 1)
.and("YEAR(selectTime)", "=", queryYear));
Map<String, TheRapyRecuperationLineUnionSelect> oldSelectMap = oldUnionSelects.stream()
.filter(v -> StrUtil.isNotBlank(v.getId()))
.collect(Collectors.toMap(TheRapyRecuperationLineUnionSelect::getId, v -> v));
Date newSelectTime = DateUtil.parse(queryYear + "-01-01 00:00:00");
for (TheRapyRecuperationLineUnionSelect unionSelect : lineUnionSelects) {
validateAdminLineTime(unionSelect);
if (StrUtil.isNotBlank(unionSelect.getId()) && !oldSelectMap.containsKey(unionSelect.getId())) {
throw Lang.makeThrow("出行时间段不存在或不属于当前线路");
}
unionSelect.setLineId(lineId);
unionSelect.setUnionId(unionId);
unionSelect.setSignUpMode(1);
unionSelect.setSelectTime(StrUtil.isNotBlank(unionSelect.getId()) && oldSelectMap.containsKey(unionSelect.getId())
? oldSelectMap.get(unionSelect.getId()).getSelectTime()
: newSelectTime);
if (StrUtil.isNotBlank(unionSelect.getId()) && oldSelectMap.containsKey(unionSelect.getId())) {
TheRapyRecuperationLineUnionSelect oldSelect = oldSelectMap.get(unionSelect.getId());
unionSelect.setIsOpen(oldSelect.getIsOpen());
unionSelect.setMinimumGroupSize(oldSelect.getMinimumGroupSize());
}
if (unionSelect.getIsOpen() == null) {
unionSelect.setIsOpen(true);
}
if (unionSelect.getEnable() == null) {
unionSelect.setEnable(true);
}
}
dao().insertOrUpdate(lineUnionSelects);
List<String> newIds = Arrays.stream(lineUnionSelects)
.map(TheRapyRecuperationLineUnionSelect::getId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
List<String> deleteIds = oldUnionSelects.stream()
.map(TheRapyRecuperationLineUnionSelect::getId)
.filter(v -> !newIds.contains(v))
.collect(Collectors.toList());
if (Lang.isNotEmpty(deleteIds)) {
long enrollCount = dao().count(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "in", deleteIds));
if (enrollCount > 0) {
throw Lang.makeThrow("已存在报名记录的出行时间段不能删除");
}
clear(Cnd.where("id", "in", deleteIds));
}
}
/**
* 管理员维护出行时间段时校验关键字段,避免保存不完整时间或无法联系的旅行社信息。
*/
private void validateAdminLineTime(TheRapyRecuperationLineUnionSelect unionSelect) {
if (unionSelect.getSignUpStartTime() == null) {
throw Lang.makeThrow("请选择报名开始时间");
}
if (unionSelect.getSignUpEndTime() == null) {
throw Lang.makeThrow("请选择报名结束时间");
}
if (DateUtil.compare(unionSelect.getSignUpEndTime(), unionSelect.getSignUpStartTime()) <= 0) {
throw Lang.makeThrow("报名结束时间必须大于报名开始时间");
}
if (unionSelect.getChangeEndTime() == null) {
throw Lang.makeThrow("请选择变更截至时间");
}
if (unionSelect.getPlayStartTime() == null) {
throw Lang.makeThrow("请选择出行开始时间");
}
if (unionSelect.getPlayEndTime() == null) {
throw Lang.makeThrow("请选择出行结束时间");
}
if (DateUtil.compare(unionSelect.getPlayEndTime(), unionSelect.getPlayStartTime()) <= 0) {
throw Lang.makeThrow("出行结束时间必须大于出行开始时间");
}
if (StrUtil.isBlank(unionSelect.getTravelAgencyId())) {
throw Lang.makeThrow("请选择旅行社");
}
if (StrUtil.isBlank(unionSelect.getContact())) {
throw Lang.makeThrow("请填写联系人");
}
if (StrUtil.isBlank(unionSelect.getContactPhone())) {
throw Lang.makeThrow("请填写联系电话");
}
if (StrUtil.isBlank(unionSelect.getPrincipal())) {
throw Lang.makeThrow("请填写负责人");
}
if (StrUtil.isBlank(unionSelect.getPrincipalContact())) {
throw Lang.makeThrow("请填写负责人联系方式");
}
}
}
@@ -0,0 +1,124 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.TheRapyRecuperationTravelAgencyService;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.List;
/**
* @FileName com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.TheRapyRecuperationTravelAgencyServiceImpl
* @Description: 疗休养旅行社
* @Author zxc
* @Date 2022/5/31:14:46
* @Version V1.0
**/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationTravelAgencyServiceImpl extends TherapyServiceImpl<TheRapyRecuperationTravelAgency> implements TheRapyRecuperationTravelAgencyService {
public TheRapyRecuperationTravelAgencyServiceImpl(Dao dao) {
super(dao);
}
/**
* 删除旅行社
*
* @param travelAgencyId 旅行社 ID
*/
@Override
public void deleteTravelAgency(String travelAgencyId) {
delete(travelAgencyId);
}
/**
* 添加旅行社
*
* @param travelAgency 旅行社
*/
@Override
public void addTravelAgency(TheRapyRecuperationTravelAgency travelAgency) {
insert(travelAgency);
}
/**
* 编辑旅行社
*
* @param travelAgency 旅行社
*/
@Override
public void editTravelAgency(TheRapyRecuperationTravelAgency travelAgency) {
update(travelAgency);
}
/**
* 开启或关闭旅行社
*
* @param travelAgencyId 旅行社id
*/
@Override
public void openTravelAgency(String travelAgencyId) {
//位运算 取反
update(Chain.makeSpecial("isDisabled", "isDisabled ^ 1"), Cnd.where("id", "=", travelAgencyId));
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
@Override
public Pagination pageData(PageForm pageForm, Cnd cnd) {
Sql sql = Sqls.create("""
select
*,
files as fileId
from
inclusive_therapy_v3_travel_agency $condition
""");
sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
/**
* 查询旅行社
*
* @param cnd cnd
* @return {@link List}<{@link TheRapyRecuperationTravelAgency}>
*/
@Override
public List<TheRapyRecuperationTravelAgency> selectAllTravelAgencyByYear(Cnd cnd) {
return dao().query(TheRapyRecuperationTravelAgency.class, cnd);
}
@Override
public Pagination selectAgencyUser(PageForm pageForm, String id) {
Sql sql = Sqls.create("""
SELECT
agency.travelAgencyName,
enroll.id,
enroll.loginName,
enroll.userName,
enroll.unionName,
enroll.unitName,
( SELECT COUNT( 1 ) FROM inclusive_therapy_v3_enroll_companion WHERE trreId = enroll.id AND relation = '亲属' ) isFamily
FROM
`inclusive_therapy_v3_enroll` enroll
LEFT JOIN inclusive_therapy_v3_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
WHERE
enroll.takePartInTravelAgencyId = @takePartInTravelAgencyId
and enroll.selfUnionId = @unionId
""").setParam("takePartInTravelAgencyId", id).setParam("unionId", TherapyContext.getUnionId());
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
}
@@ -0,0 +1,68 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.impl.baseManage;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyServiceImpl;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyContext;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.model.TheRapyRecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.service.baseManage.TheRapyRecuperationBaseManagerService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
/**
* @Author JyuHsin
* @Date 2023/6/7
* @Description
*/
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationBaseManagerServiceImpl extends TherapyServiceImpl implements TheRapyRecuperationBaseManagerService {
public TheRapyRecuperationBaseManagerServiceImpl(Dao dao) {
super(dao);
}
@Override
public NutMap selectBaseAllInfo(String id) {
Sql sql = Sqls.create("""
select
b.*,
l.lotName,
(select COUNT(1) FROM inclusive_therapy_v3_enroll en WHERE isNormal=true AND en.loginName=@loginname and YEAR(en.signingUptime)=@year ) isNormal,
(select COUNT(1) FROM inclusive_therapy_v3_enroll en WHERE isNormal=false AND en.loginName=@loginname and YEAR(en.signingUptime)=@year) isNormalFalse
from
inclusive_therapy_v3_base_management b
left join inclusive_therapy_v3_lot l on l.id = b.lotId
$condition
""");
sql.setParam("loginname", TherapyContext.getPrincipalProperty("loginname"));
sql.setParam("year", DateUtil.thisYear());
Cnd cnd = Cnd.NEW();
cnd.and("b.id", "=", id);
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.map());
dao().execute(sql);
NutMap nutMap = (NutMap) sql.getResult();
useConfigSignUpTime(nutMap);
return nutMap;
}
/**
* 手机端目的地详情报名时间统一使用基础设置中的报名时间。
*
* @param nutMap 目的地详情返回数据
*/
private void useConfigSignUpTime(NutMap nutMap) {
if (nutMap == null) {
return;
}
TheRapyRecuperationConfig config = dao().fetch(TheRapyRecuperationConfig.class);
if (config == null) {
return;
}
nutMap.setv("signUpStartTime", config.getSignUpStartTime());
nutMap.setv("signUpEndTime", config.getSignUpEndTime());
}
}
@@ -0,0 +1,20 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class LegacyBaseModel extends BaseModel {
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = @EL("$me.createdByUid()"))
private String opBy;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String opAt;
}
@@ -0,0 +1,7 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
public class PageUtil {
public static String getOrder(String value) {
return "descending".equals(value) ? "desc" : "asc";
}
}
@@ -0,0 +1,7 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SelectEnum {}
@@ -0,0 +1,29 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("inclusive_therapy_v3_audit")
public class TherapyAudit extends LegacyBaseModel {
@Name
@PrevInsert(uu32 = true)
private String id;
@Column
private String auditor;
@Column
private Boolean auditPass;
@Column
private Date auditTime;
@Column
@ColDefine(type = ColType.TEXT)
private String auditOpinion;
@Column
private String username;
@Column
private String loginname;
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
@Data
@Table("inclusive_therapy_v3_audit_state")
public class TherapyAuditState {
@Id(auto = false)
private Integer stateId;
@Column
private String stateName;
@Column
private String stateColor;
}
@@ -0,0 +1,110 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import cn.dev33.satoken.stp.StpUtil;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.mvc.Mvcs;
import java.util.Arrays;
import java.util.Collection;
@IocBean
public class TherapyContext {
public static boolean isEmbeddedPage() {
return "1".equals(Mvcs.getReq().getParameter("therapyEmbedded"));
}
public static String getEmbeddedPageUrl() {
String query = Mvcs.getReq().getQueryString();
return Mvcs.getReq().getRequestURI() + (Strings.isBlank(query) ? "?" : "?" + query + "&") + "therapyEmbedded=1";
}
public static String getUserId() {
return SecurityUtil.getUserId();
}
public static String getPlatformUid() {
return getUserId();
}
public static String getPlatformLoginname() {
return SecurityUtil.getUserLoginname();
}
public static String getUnionId() {
String unionId = SecurityUtil.getUnionId();
if (Strings.isNotBlank(unionId)) return unionId;
TherapyUser user = Mvcs.getIoc().get(Dao.class).fetch(TherapyUser.class, getUserId());
return user == null ? "" : Strings.sNull(user.getUnionid());
}
public static boolean hasRole(String role) {
if (StpUtil.hasRole(role)) return true;
switch (role) {
case "sysadmin": return StpUtil.hasRole("SYSADMIN") || StpUtil.hasRole("superadmin");
case "A06": return StpUtil.hasRole("SCHOOL_UNION_ADMIN") || StpUtil.hasRole("SCHOOL_UNION_WELFARE_ADMIN");
case "H03": return StpUtil.hasRole("BRANCH_UNION_CHAIRMAN");
case "H04": return StpUtil.hasRole("BRANCH_UNION_ADMIN") || StpUtil.hasRole("BRANCH_UNION_CHAIRMAN");
case "H06": return StpUtil.hasRole("SCHOOL_UNION_WELFARE_ADMIN");
case "SchoolUnionMemberAdmin": return StpUtil.hasRole("SCHOOL_UNION_MEMBER_ADMIN");
default: return false;
}
}
public static boolean hasAnyRoles(String roles) {
return hasAnyRoles(Arrays.asList(roles.split(",")));
}
public static boolean hasAnyRoles(String[] roles) {
return hasAnyRoles(Arrays.asList(roles));
}
public static boolean hasAnyRoles(Collection<String> roles) {
return roles.stream().map(String::trim).anyMatch(TherapyContext::hasRole);
}
public static boolean isNotBlank(String... values) {
return Arrays.stream(values).allMatch(Strings::isNotBlank);
}
public static String getRoleCodesJson() {
SysUserService userService = Mvcs.getIoc().get(SysUserService.class, "sysUserServiceImpl");
java.util.List<String> roles = new java.util.ArrayList<>(userService.getRoleCodeList(userService.fetch(getUserId())));
for (String role : Arrays.asList("sysadmin", "A06", "H03", "H04", "H06", "SchoolUnionMemberAdmin")) {
if (hasRole(role) && !roles.contains(role)) roles.add(role);
}
return org.nutz.json.Json.toJson(roles, org.nutz.json.JsonFormat.compact());
}
public static TherapyUser getUser() {
Dao dao = Mvcs.getIoc().get(Dao.class);
TherapyUser user = dao.fetch(TherapyUser.class, getUserId());
return user == null ? null : dao.fetchLinks(user, "^(unit|union)$");
}
public static TherapyUser getPrincipal() {
return getUser();
}
public static Object getPrincipalProperty(String property) {
switch (property) {
case "id": return getUserId();
case "loginname": return SecurityUtil.getUserLoginname();
case "username": return SecurityUtil.getUserUsername();
case "unionid": return getUnionId();
default:
TherapyUser user = getUser();
if (user == null) return null;
switch (property) {
case "unit": return user.getUnit();
case "union": return user.getUnion();
case "mobile": return user.getMobile();
case "idcard": return user.getIdcard();
default: throw new IllegalArgumentException(property);
}
}
}
}
@@ -0,0 +1,11 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
@IocBean(name = "staffTherapyDataService", args = {"refer:dao"})
public class TherapyDataService extends TherapyServiceImpl<TherapyAudit> {
public TherapyDataService(Dao dao) {
super(dao);
}
}
@@ -0,0 +1,13 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class TherapyDownload {
public static void excelResponse(HttpServletResponse response, String name) {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" +
URLEncoder.encode(name, StandardCharsets.UTF_8).replace("+", "%20"));
}
}
@@ -0,0 +1,117 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import com.budwk.app.web.commons.base.Globals;
import com.budwk.app.sys.models.Sys_config;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.ioc.impl.PropertiesProxy;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;
import java.util.UUID;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
@IocBean
public class TherapyEmail {
@Inject
private PropertiesProxy conf;
@Inject
private Dao dao;
public void send(String email, String content, boolean html, File... files) {
String host = setting("host");
String from = setting("from");
String user = setting("user");
String password = setting("password");
if (host == null || from == null || user == null || password == null) {
throw new IllegalStateException("普惠疗休养邮件发送配置不完整");
}
String portSetting = setting("port");
int port = portSetting == null ? 465 : Integer.parseInt(portSetting);
String[] recipients = email.split("[,;]");
checkAddress(from);
for (String recipient : recipients) checkAddress(recipient.trim());
// Use the JDK TLS client so the migrated mail feature needs no additional dependencies.
try (Socket transport = new Socket()) {
transport.connect(new InetSocketAddress(host, port), 30000);
try (SSLSocket socket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(transport, host, port, true)) {
socket.setSoTimeout(30000);
javax.net.ssl.SSLParameters parameters = socket.getSSLParameters();
parameters.setEndpointIdentificationAlgorithm("HTTPS");
socket.setSSLParameters(parameters);
socket.startHandshake();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.US_ASCII));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.US_ASCII));
expect(in, 220);
command(out, in, "EHLO localhost", 250);
command(out, in, "AUTH LOGIN", 334);
command(out, in, encoded(user), 334);
command(out, in, encoded(password), 235);
command(out, in, "MAIL FROM:<" + from + ">", 250);
for (String recipient : recipients) command(out, in, "RCPT TO:<" + recipient.trim() + ">", 250, 251);
command(out, in, "DATA", 354);
String boundary = "therapy_" + UUID.randomUUID().toString().replace("-", "");
out.write("From: " + from + "\r\nTo: " + String.join(",", recipients) + "\r\n");
out.write("Subject: =?UTF-8?B?" + encoded(Globals.AppName + "疗休养管理系统") + "?=\r\n");
out.write("MIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"" + boundary + "\"\r\n\r\n");
out.write("--" + boundary + "\r\nContent-Type: text/" + (html ? "html" : "plain") + "; charset=UTF-8\r\n");
out.write("Content-Transfer-Encoding: base64\r\n\r\n");
writeBody(out, content.getBytes(StandardCharsets.UTF_8));
for (File file : files) {
out.write("--" + boundary + "\r\nContent-Type: application/octet-stream\r\n");
out.write("Content-Disposition: attachment; filename=\"=?UTF-8?B?" + encoded(file.getName()) + "?=\"\r\n");
out.write("Content-Transfer-Encoding: base64\r\n\r\n");
writeBody(out, Files.readAllBytes(file.toPath()));
}
out.write("--" + boundary + "--\r\n.\r\n");
out.flush();
expect(in, 250);
command(out, in, "QUIT", 221);
}
} catch (IOException e) {
throw new IllegalStateException("疗休养名单邮件发送失败", e);
}
}
private String setting(String name) {
String key = "staffTherapy.mail." + name;
String value = conf.get(key);
if (value != null && !value.isBlank()) return value;
Sys_config config = dao.fetch(Sys_config.class, key);
return config == null || config.getConfigValue() == null || config.getConfigValue().isBlank() ? null : config.getConfigValue();
}
private static void checkAddress(String address) {
if (!address.matches("[^\\s<>@]+@[^\\s<>@]+")) throw new IllegalArgumentException("邮件地址格式错误");
}
private static String encoded(String text) {
return Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8));
}
private static void writeBody(BufferedWriter out, byte[] bytes) throws IOException {
out.write(Base64.getMimeEncoder(76, new byte[]{13, 10}).encodeToString(bytes));
out.write("\r\n");
}
private static void command(BufferedWriter out, BufferedReader in, String value, int... codes) throws IOException {
out.write(value + "\r\n");
out.flush();
expect(in, codes);
}
private static void expect(BufferedReader in, int... codes) throws IOException {
String response;
do {
response = in.readLine();
if (response == null || response.length() < 3) throw new IOException("SMTP connection closed");
} while (response.length() > 3 && response.charAt(3) == '-');
for (int code : codes) if (response.startsWith(String.valueOf(code))) return;
throw new IOException("SMTP request rejected");
}
}
@@ -0,0 +1,28 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageSendService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.*;
@IocBean
public class TherapyMessage {
public enum sendMode { normal }
@Inject
private Dao dao;
@Inject
private GlobalMessageSendService globalMessageSendService;
public void sendMsg(String content, List<? extends Map> receivers, String title, String mode, String sendMode) {
Set<String> ids = new LinkedHashSet<>();
for (Map receiver : receivers) {
String loginname = String.valueOf(receiver.get("userId"));
Sys_user user = dao.fetch(Sys_user.class, Cnd.where("loginname", "=", loginname));
if (user != null) ids.add(user.getId());
}
if (!ids.isEmpty()) globalMessageSendService.sendMessage(title, content, new ArrayList<>(ids));
}
}
@@ -0,0 +1,43 @@
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support;
import com.budwk.app.base.result.Result;
import org.nutz.aop.MethodInterceptor;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.aop.config.AopConfigration;
import org.nutz.ioc.aop.config.InterceptorPair;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import java.util.Collections;
import java.util.List;
@IocBean(name = "$aop_staffTherapyReturn")
public class TherapyReturnConfiguration implements AopConfigration {
private static final Log log = Logs.get();
@Override
public List<InterceptorPair> getInterceptorPairList(Ioc ioc, Class<?> type) {
if (!type.getName().startsWith("com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.")) {
return Collections.emptyList();
}
MethodInterceptor interceptor = chain -> {
cn.dev33.satoken.stp.StpUtil.checkLogin();
ViReturn annotation = chain.getCallingMethod().getAnnotation(ViReturn.class);
if (annotation == null) {
chain.doChain();
return;
}
try {
chain.doChain();
Object value = chain.getReturn();
chain.setReturnValue(value instanceof Result ? value : Result.success(annotation.successMsg(), value));
} catch (Exception e) {
log.error(e);
chain.setReturnValue(Result.error(e.getMessage() == null ? annotation.errorMsg() : e.getMessage()));
}
};
return Collections.singletonList(new InterceptorPair(interceptor,
method -> method.isAnnotationPresent(org.nutz.mvc.annotation.At.class)));
}
}

Some files were not shown because too many files have changed in this diff Show More