This commit is contained in:
@jyuhsin
2025-08-20 08:42:54 +08:00
parent 0b07ce45d0
commit b34a1945fc
76 changed files with 6696 additions and 156 deletions
@@ -154,6 +154,7 @@ public class FamilyActivityStatisticsController {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
ts.*, ts.*,
CONCAT(DATE_FORMAT(ac.courseStartTime, '%H:%i:%s'),'至',DATE_FORMAT(ac.courseEndTime, '%H:%i:%s')) AS courseTime,
u.username, u.username,
u.loginname, u.loginname,
u.sex, u.sex,
@@ -162,6 +163,7 @@ public class FamilyActivityStatisticsController {
tsc.courseName tsc.courseName
FROM FROM
family_user ts family_user ts
left join family_activity_course ac on ts.activityCourseId = ac.id
left join `vw_user` u on u.id = ts. userId left join `vw_user` u on u.id = ts. userId
left join family_course tsc on tsc.id = ts.courseId left join family_course tsc on tsc.id = ts.courseId
WHERE WHERE
@@ -183,7 +185,8 @@ public class FamilyActivityStatisticsController {
Map.of("name", "单位", "key", "unitName"), Map.of("name", "单位", "key", "unitName"),
Map.of("name", "分工会", "key", "unionName"), Map.of("name", "分工会", "key", "unionName"),
Map.of("name", "性别", "key", "sex"), Map.of("name", "性别", "key", "sex"),
Map.of("name", "手机号", "key", "newMobile") Map.of("name", "手机号", "key", "newMobile"),
Map.of("name", "报名时段", "key", "courseTime")
); );
List<ExcelExportEntity> excelCommonExportEntity = basicEntity.stream().map(entity -> { List<ExcelExportEntity> excelCommonExportEntity = basicEntity.stream().map(entity -> {
@@ -71,6 +71,11 @@ public class FamilyUser implements Serializable {
@Comment("报名时间") @Comment("报名时间")
private Date signUpTime; private Date signUpTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("活动课程时段id")
private String activityCourseId;
@Column @Column
@ColDefine(type = ColType.MYSQL_JSON) @ColDefine(type = ColType.MYSQL_JSON)
@Comment("手机端报名字段和值") @Comment("手机端报名字段和值")
@@ -13,6 +13,8 @@ import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.family.models.*; import com.budwk.app.zhgh.activity.family.models.*;
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService; import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService; import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpActivityCourse;
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpUserCourse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.async.Async; import org.nutz.aop.interceptor.async.Async;
import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.aop.interceptor.ioc.TransAop;
@@ -273,7 +275,22 @@ public class FamilyActivityServiceImpl extends BaseServiceImpl<FamilyActivity> i
familyUser.setSignUpTime(new Date()); familyUser.setSignUpTime(new Date());
dao().insert(familyUser); dao().insert(familyUser);
asyncInsertUserCourse(familyUser.getActivityId(), familyUser.getCourseId(), userId);
if (StrUtil.isNotBlank(familyUser.getActivityCourseId())) {
TrainSignUpActivityCourse fetch = dao().fetch(TrainSignUpActivityCourse.class, familyUser.getActivityCourseId());
TrainSignUpUserCourse userCourse = new TrainSignUpUserCourse();
userCourse.setActivityId(familyUser.getActivityId());
userCourse.setCourseId(familyUser.getCourseId());
userCourse.setUserId(familyUser.getUserId());
userCourse.setCourseStartTime(fetch.getCourseStartTime());
userCourse.setCourseEndTime(fetch.getCourseEndTime());
userCourse.setAttend(false);
userCourse.setAttendTime(null);
userCourse.setActivityCourseId(fetch.getId());
dao().insert(userCourse);
} else {
asyncInsertUserCourse(familyUser.getActivityId(), familyUser.getCourseId(), userId);
}
} }
@Async @Async
@@ -143,7 +143,7 @@ public class FamilyActivityStatisticsServiceImpl extends BaseServiceImpl<FamilyU
u.unitname, u.unitname,
u.unionname, u.unionname,
u.sex, u.sex,
u.mobile, ifnull(tsuu.mobile, u.mobile) as mobile,
tsuu.signUpTime, tsuu.signUpTime,
tsuu.state tsuu.state
FROM FROM
@@ -35,7 +35,7 @@ public class FamilyUserServiceImpl extends BaseServiceImpl<FamilyBlackList> impl
u.id AS userId, u.id AS userId,
u.username, u.username,
u.loginname, u.loginname,
u.mobile, ifnull(tsuu.mobile, u.mobile) as mobile,
u.unitname, u.unitname,
u.unionname, u.unionname,
tsuc.courseName, tsuc.courseName,
@@ -1,12 +1,17 @@
package com.budwk.app.zhgh.activity.planSummary.controller; package com.budwk.app.zhgh.activity.planSummary.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm; import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.models.Sys_union; import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicSettings; import com.budwk.app.zhgh.activity.basic.models.ActivityBasicSettings;
@@ -21,13 +26,23 @@ import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang; import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** /**
* @ClassName YearPlanController * @ClassName YearPlanController
@@ -139,4 +154,66 @@ public class YearPlanController {
List<SysClub> list = dao.query(SysClub.class, cnd); List<SysClub> list = dao.query(SysClub.class, cnd);
return Result.success(list); return Result.success(list);
} }
@At
@Ok("void")
@SaCheckPermission("planSummary.yearPlan.manage")
public void downloadFiles(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "tissueIdByUnion") String tissueIdByUnion,
@Param(value = "tissueIdByClub") String tissueIdByClub,
@Param(value = "planName") String planName,
HttpServletResponse response) throws IOException {
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(yp.planTime)", "=", year);
cnd.andEX("yp.tissueId", "=", tissueIdByUnion);
cnd.andEX("yp.tissueId", "=", tissueIdByClub);
cnd.and(Cnd.likeEX("yp.planName", planName));
List<NutMap> listMap = yearPlanService.queryData(cnd);
List<String> urlList = new ArrayList<>();
for (NutMap map : listMap) {
if(StrUtil.isNotBlank(map.getString("files"))) {
List<JSONObject> files = Json.fromJsonAsList(JSONObject.class, map.getString("files"));
ArrayList<String> list = files.stream().map(o -> o.getStr("url")).collect(Collectors.toCollection(ArrayList::new));
urlList.addAll(list);
}
}
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode("文件汇总.zip"));
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
for (String url : urlList) {
String fileId = extractFileId(url);
if(StrUtil.isNotBlank(fileId)) {
Sys_file file = dao.fetch(Sys_file.class, fileId);
byte[] bytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
if(bytes == null || bytes.length == 0){
continue;
}
String entryName = file.getName();
zos.putNextEntry(new ZipEntry(entryName));
zos.write(bytes);
zos.closeEntry();
}
}
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "生成ZIP文件失败");
e.printStackTrace();
}
}
public static String extractFileId(String url) {
if (url == null) return null;
Pattern pattern = Pattern.compile("[?&]id=([^&]*)");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
} }
@@ -2,13 +2,18 @@ package com.budwk.app.zhgh.activity.planSummary.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm; import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_dict; import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.models.Sys_union; import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.budwk.app.sys.views.View_user; import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -26,13 +31,22 @@ import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang; import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/** /**
* @ClassName YearSummaryController * @ClassName YearSummaryController
@@ -119,4 +133,68 @@ public class YearSummaryController {
yearSummaryService.delete(id); yearSummaryService.delete(id);
return Result.success(); return Result.success();
} }
@At
@Ok("void")
@SaCheckPermission("planSummary.yearPlan.manage")
public void downloadFiles(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "tissueIdByUnion") String tissueIdByUnion,
@Param(value = "tissueIdByClub") String tissueIdByClub,
@Param(value = "summaryType") String summaryType,
@Param(value = "summaryFrom") String summaryFrom,
HttpServletResponse response) throws IOException {
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(ys.cTime)", "=", year);
cnd.andEX("ys.tissueId", "=", tissueIdByUnion);
cnd.andEX("ys.tissueId", "=", tissueIdByClub);
cnd.andEX("ys.summaryType", "=", summaryType);
cnd.andEX("ys.summaryFrom", "=", summaryFrom);
List<NutMap> listMap = yearSummaryService.queryData(cnd);
List<String> urlList = new ArrayList<>();
for (NutMap map : listMap) {
if(StrUtil.isNotBlank(map.getString("files"))) {
List<JSONObject> files = Json.fromJsonAsList(JSONObject.class, map.getString("files"));
ArrayList<String> list = files.stream().map(o -> o.getStr("url")).collect(Collectors.toCollection(ArrayList::new));
urlList.addAll(list);
}
}
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode("文件汇总.zip"));
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
for (String url : urlList) {
String fileId = extractFileId(url);
if(StrUtil.isNotBlank(fileId)) {
Sys_file file = dao.fetch(Sys_file.class, fileId);
byte[] bytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
if(bytes == null || bytes.length == 0){
continue;
}
String entryName = file.getName();
zos.putNextEntry(new ZipEntry(entryName));
zos.write(bytes);
zos.closeEntry();
}
}
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "生成ZIP文件失败");
e.printStackTrace();
}
}
public static String extractFileId(String url) {
if (url == null) return null;
Pattern pattern = Pattern.compile("[?&]id=([^&]*)");
Matcher matcher = pattern.matcher(url);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
} }
@@ -1,5 +1,6 @@
package com.budwk.app.zhgh.activity.planSummary.model; package com.budwk.app.zhgh.activity.planSummary.model;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel; import com.budwk.app.base.model.BaseModel;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -7,6 +8,8 @@ import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*; import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert; import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.List;
/** /**
* @ClassName Plan * @ClassName Plan
* @Author JyuHsin * @Author JyuHsin
@@ -66,4 +69,9 @@ public class YearPlan extends BaseModel {
@Comment("活动类型") @Comment("活动类型")
@ColDefine(type = ColType.VARCHAR, width = 32) @ColDefine(type = ColType.VARCHAR, width = 32)
private String activityType; private String activityType;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
} }
@@ -5,6 +5,9 @@ import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService; import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.planSummary.model.YearPlan; import com.budwk.app.zhgh.activity.planSummary.model.YearPlan;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/** /**
* @ClassName YearPlanService * @ClassName YearPlanService
@@ -16,4 +19,6 @@ import org.nutz.dao.Cnd;
public interface YearPlanService extends BaseService<YearPlan> { public interface YearPlanService extends BaseService<YearPlan> {
Pagination pageData(PageForm pageForm, Cnd cnd); Pagination pageData(PageForm pageForm, Cnd cnd);
List<NutMap> queryData(Cnd cnd);
} }
@@ -5,6 +5,9 @@ import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService; import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.planSummary.model.YearSummary; import com.budwk.app.zhgh.activity.planSummary.model.YearSummary;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/** /**
* @ClassName YearSummaryService * @ClassName YearSummaryService
@@ -16,4 +19,6 @@ import org.nutz.dao.Cnd;
public interface YearSummaryService extends BaseService<YearSummary> { public interface YearSummaryService extends BaseService<YearSummary> {
Pagination pageData(PageForm pageForm, Cnd cnd); Pagination pageData(PageForm pageForm, Cnd cnd);
List<NutMap> queryData(Cnd cnd);
} }
@@ -20,6 +20,7 @@ import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings; import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.List; import java.util.List;
@@ -43,6 +44,17 @@ public class YearPlanServiceImpl extends BaseServiceImpl<YearPlan> implements Ye
@Override @Override
public Pagination pageData(PageForm pageForm, Cnd cnd) { public Pagination pageData(PageForm pageForm, Cnd cnd) {
Sql sql = buildSql(cnd);
return this.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@Override
public List<NutMap> queryData(Cnd cnd) {
Sql sql = buildSql(cnd);
return this.listMap(sql);
}
private Sql buildSql(Cnd cnd) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
yp.*, yp.*,
@@ -68,6 +80,6 @@ public class YearPlanServiceImpl extends BaseServiceImpl<YearPlan> implements Ye
} }
cnd.desc("yp.planTime"); cnd.desc("yp.planTime");
sql.setCondition(cnd); sql.setCondition(cnd);
return this.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return sql;
} }
} }
@@ -19,6 +19,7 @@ import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.List; import java.util.List;
@@ -42,6 +43,17 @@ public class YearSummaryServiceImpl extends BaseServiceImpl<YearSummary> impleme
@Override @Override
public Pagination pageData(PageForm pageForm, Cnd cnd) { public Pagination pageData(PageForm pageForm, Cnd cnd) {
Sql sql = buildSql(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@Override
public List<NutMap> queryData(Cnd cnd) {
Sql sql = buildSql(cnd);
return this.listMap(sql);
}
private Sql buildSql(Cnd cnd) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
ys.*, ys.*,
@@ -66,6 +78,6 @@ public class YearSummaryServiceImpl extends BaseServiceImpl<YearSummary> impleme
} }
cnd.desc("ys.cTime"); cnd.desc("ys.cTime");
sql.setCondition(cnd); sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return sql;
} }
} }
@@ -15,6 +15,7 @@ import com.budwk.app.zhgh.activity.family.models.FamilyCourse;
import com.budwk.app.zhgh.activity.family.models.FamilyUser; import com.budwk.app.zhgh.activity.family.models.FamilyUser;
import com.budwk.app.zhgh.activity.trainSignUp.models.*; import com.budwk.app.zhgh.activity.trainSignUp.models.*;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService; import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityService;
import com.budwk.app.zhgh.activity.trainSignUp.service.TrainSignUpActivityStatisticsService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Chain; import org.nutz.dao.Chain;
@@ -53,6 +54,8 @@ public class MTrainSignUpActivityController {
private TrainSignUpActivityService trainSignUpActivityService; private TrainSignUpActivityService trainSignUpActivityService;
@Inject @Inject
private RedisService redisService; private RedisService redisService;
@Inject
private TrainSignUpActivityStatisticsService statisticsService;
@At("/trainList") @At("/trainList")
@Ok("beetl:/platform/zhghh5/activity/trainSignUp/trainList/index.html") @Ok("beetl:/platform/zhghh5/activity/trainSignUp/trainList/index.html")
@@ -152,16 +152,16 @@ public class TrainSignUpActivityStatisticsController {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
ts.*, ts.*,
CONCAT(DATE_FORMAT(ac.courseStartTime, '%H:%i:%s'),'至',DATE_FORMAT(ac.courseEndTime, '%H:%i:%s')) AS courseTime,
u.username, u.username,
u.loginname, u.loginname,
u.unitname,
u.unionname,
u.sex, u.sex,
u.mobile, ifnull(ts.mobile, u.mobile) as mobile,
u.birthday, u.birthday,
tsc.courseName tsc.courseName
FROM FROM
train_sign_up_user ts train_sign_up_user ts
left join train_sign_up_activity_course ac on ts.activityCourseId = ac.id
left join `vw_user` u on u.id = ts. userId left join `vw_user` u on u.id = ts. userId
left join train_sign_up_course tsc on tsc.id = ts.courseId left join train_sign_up_course tsc on tsc.id = ts.courseId
WHERE WHERE
@@ -180,11 +180,12 @@ public class TrainSignUpActivityStatisticsController {
List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>(); List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>();
excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20)); excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20));
excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20)); excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20));
excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitname", 20)); excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionname", 20)); excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20));
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20)); excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
excelCommonExportEntity.add(new ExcelExportEntity("手机号", "mobile", 20)); excelCommonExportEntity.add(new ExcelExportEntity("手机号", "mobile", 20));
excelCommonExportEntity.add(new ExcelExportEntity("生日", "birthday", 20)); excelCommonExportEntity.add(new ExcelExportEntity("生日", "birthday", 20));
excelCommonExportEntity.add(new ExcelExportEntity("报名时段", "courseTime", 20));
for (TrainSignUpCourse c : courseList) { for (TrainSignUpCourse c : courseList) {
String k = c.getCourseName(); String k = c.getCourseName();
@@ -132,6 +132,5 @@ public class TrainSignUpActivity extends BaseModel implements Serializable, SysH
sysHomeActivity.setEnable(!this.isDisabled()); sysHomeActivity.setEnable(!this.isDisabled());
sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName()); sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName());
return sysHomeActivity; return sysHomeActivity;
} }
} }
@@ -70,6 +70,11 @@ public class TrainSignUpUser implements Serializable {
@Comment("报名时间") @Comment("报名时间")
private Date signUpTime; private Date signUpTime;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("活动课程时段id")
private String activityCourseId;
@Column @Column
@ColDefine(type = ColType.MYSQL_JSON) @ColDefine(type = ColType.MYSQL_JSON)
@Comment("手机端报名字段和值") @Comment("手机端报名字段和值")
@@ -278,7 +278,22 @@ public class TrainSignUpActivityServiceImpl extends BaseServiceImpl<TrainSignUpA
trainSignUpUser.setSignUpTime(new Date()); trainSignUpUser.setSignUpTime(new Date());
dao().insert(trainSignUpUser); dao().insert(trainSignUpUser);
asyncInsertUserCourse(trainSignUpUser.getActivityId(), trainSignUpUser.getCourseId(), userId);
if (StrUtil.isNotBlank(trainSignUpUser.getActivityCourseId())) {
TrainSignUpActivityCourse fetch = dao().fetch(TrainSignUpActivityCourse.class, trainSignUpUser.getActivityCourseId());
TrainSignUpUserCourse userCourse = new TrainSignUpUserCourse();
userCourse.setActivityId(trainSignUpUser.getActivityId());
userCourse.setCourseId(trainSignUpUser.getCourseId());
userCourse.setUserId(trainSignUpUser.getUserId());
userCourse.setCourseStartTime(fetch.getCourseStartTime());
userCourse.setCourseEndTime(fetch.getCourseEndTime());
userCourse.setAttend(false);
userCourse.setAttendTime(null);
userCourse.setActivityCourseId(fetch.getId());
dao().insert(userCourse);
} else {
asyncInsertUserCourse(trainSignUpUser.getActivityId(), trainSignUpUser.getCourseId(), trainSignUpUser.getUserId());
}
} }
@Async @Async
@@ -18,6 +18,7 @@ import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang; import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
@@ -90,7 +91,8 @@ public class TrainSignUpActivityStatisticsServiceImpl extends BaseServiceImpl<Tr
tsuu.unitName, tsuu.unitName,
ifnull(tsuu.mobile, u.mobile) as mobile, ifnull(tsuu.mobile, u.mobile) as mobile,
tsuu.signUpTime, tsuu.signUpTime,
tsuu.state tsuu.state,
tsuu.mobileColumnsValue
FROM FROM
train_sign_up_user tsuu train_sign_up_user tsuu
LEFT JOIN `vw_user` u ON u.id = tsuu.userId LEFT JOIN `vw_user` u ON u.id = tsuu.userId
@@ -100,7 +102,16 @@ public class TrainSignUpActivityStatisticsServiceImpl extends BaseServiceImpl<Tr
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.andEX("tsuu.courseId", "=", courseId); cnd.andEX("tsuu.courseId", "=", courseId);
sql.setCondition(cnd); sql.setCondition(cnd);
return listMap(sql); List<NutMap> list = listMap(sql);
list.forEach(o -> {
List<NutMap> mobileColumnsValue = Json.fromJsonAsList(NutMap.class, o.getString("mobileColumnsValue"));
if(Lang.isNotEmpty(mobileColumnsValue)) {
mobileColumnsValue.forEach(m -> {
o.put(m.getString("columnCode"), m.getString("columnValue"));
});
}
});
return list;
} }
@Override @Override
@@ -125,7 +136,7 @@ public class TrainSignUpActivityStatisticsServiceImpl extends BaseServiceImpl<Tr
u.unitname, u.unitname,
u.unionname, u.unionname,
u.sex, u.sex,
u.mobile, ifnull(tsuu.mobile, u.mobile) as mobile,
tsuu.signUpTime, tsuu.signUpTime,
tsuu.state tsuu.state
FROM FROM
@@ -35,7 +35,7 @@ public class TrainSignUpUserServiceImpl extends BaseServiceImpl<TrainSignUpBlack
u.id AS userId, u.id AS userId,
u.username, u.username,
u.loginname, u.loginname,
u.mobile, ifnull(tsuu.mobile, u.mobile) as mobile,
u.unitname, u.unitname,
u.unionname, u.unionname,
tsuc.courseName, tsuc.courseName,
@@ -9,6 +9,7 @@ import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil; import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.DateUtil; import com.budwk.app.base.utils.DateUtil;
import com.budwk.app.base.utils.SysOfficeTemplateUtil; import com.budwk.app.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicSettings;
import com.budwk.app.zhgh.dayofficework.clothing.service.ClothingService; import com.budwk.app.zhgh.dayofficework.clothing.service.ClothingService;
import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.Configure;
@@ -143,6 +144,9 @@ public class ClothingRecordController {
Configure config = Configure.builder().bind("buys", policy).build(); Configure config = Configure.builder().bind("buys", policy).build();
clothes.put("buys", buyUserList); clothes.put("buys", buyUserList);
ActivityBasicSettings basicSettings = clothingService.dao().fetch(ActivityBasicSettings.class, Cnd.where(ActivityBasicSettings::getCode, "=", projectId));
clothes.put("projectName", basicSettings.getName());
ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream();
XWPFTemplate template = XWPFTemplate.compile(officeTemplateUtil.getTemplate("clothes"), config); XWPFTemplate template = XWPFTemplate.compile(officeTemplateUtil.getTemplate("clothes"), config);
template.render(clothes).writeAndClose(os); template.render(clothes).writeAndClose(os);
@@ -1,6 +1,8 @@
package com.budwk.app.zhgh.staffbenefit.legal.controller; package com.budwk.app.zhgh.staffbenefit.legal.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
@@ -51,7 +53,7 @@ public class LegalAppointmentSetController {
@At @At
@ApiOperation("查询时间段内的预约信息") @ApiOperation("查询时间段内的预约信息")
@SaCheckPermission("legal.appointmentSet") @SaCheckLogin
public Result queryAppointmentInfo(Long startTimeTs, Long endTimeTs) { public Result queryAppointmentInfo(Long startTimeTs, Long endTimeTs) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
@@ -136,6 +138,9 @@ public class LegalAppointmentSetController {
@ApiOperation("查询咨询师") @ApiOperation("查询咨询师")
@SaCheckPermission("legal.appointmentSet") @SaCheckPermission("legal.appointmentSet")
public Result queryDoctorUser(String keyWord, long startTimeTs, long endTimeTs) { public Result queryDoctorUser(String keyWord, long startTimeTs, long endTimeTs) {
if(StrUtil.isBlank(keyWord)) {
keyWord = "";
}
//先查询该时间段没时间的咨询师 //先查询该时间段没时间的咨询师
Sql doctorSql = Sqls.create(""" Sql doctorSql = Sqls.create("""
SELECT SELECT
@@ -1,7 +1,9 @@
package com.budwk.app.zhgh.staffbenefit.psychology.controller; package com.budwk.app.zhgh.staffbenefit.psychology.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
@@ -55,7 +57,7 @@ public class PsychologyAppointmentSetController {
@At @At
@ApiOperation("查询时间段内的预约信息") @ApiOperation("查询时间段内的预约信息")
@SaCheckPermission("psychology.appointmentSet") @SaCheckLogin
public Result queryAppointmentInfo(Long startTimeTs, Long endTimeTs) { public Result queryAppointmentInfo(Long startTimeTs, Long endTimeTs) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
@@ -140,6 +142,9 @@ public class PsychologyAppointmentSetController {
@ApiOperation("查询咨询师") @ApiOperation("查询咨询师")
@SaCheckPermission("psychology.appointmentSet") @SaCheckPermission("psychology.appointmentSet")
public Result queryDoctorUser(String keyWord, long startTimeTs, long endTimeTs) { public Result queryDoctorUser(String keyWord, long startTimeTs, long endTimeTs) {
if(StrUtil.isBlank(keyWord)) {
keyWord = "";
}
//先查询该时间段没时间的咨询师 //先查询该时间段没时间的咨询师
Sql doctorSql = Sqls.create(""" Sql doctorSql = Sqls.create("""
SELECT SELECT
@@ -0,0 +1,70 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.constant;
import com.budwk.app.base.annotation.DictEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
/**
* @FileName io.v.nutz.zhgh.Recuperation.constant.RecuperationType
* @Description: 疗休养分类
* @Author zxc
* @Date 2022/6/2:14:02
* @Version V1.0
**/
@AllArgsConstructor
@Getter
@DictEnum(key = "RecuperationProvinceType", name = "疗休养分类")
public enum RecuperationType {
/**
* 省内线路
*/
provinceInLine("省内线路", 0, RecuperationProvinceType.provinceIn.getValue(), "/assets/mobile/img/Recuperation/in.png"),
/**
* 省外线路
*/
provinceOutLine("省外线路", 1, RecuperationProvinceType.provinceOut.getValue(), "/assets/mobile/img/Recuperation/out.png"),
/**
* 省内旅行社
*/
provinceInTravelAgency("旅行社", 2, RecuperationProvinceType.provinceIn.getValue(), "/assets/mobile/img/Recuperation/lxs.png"),
/**
* 酒店
*/
provinceInHotel("分段疗休养", 3, RecuperationProvinceType.provinceIn.getValue(), "/assets/mobile/img/Recuperation/lxs.png");
/**
* 学校自由组织
*/
// schoolFree("学校自由报名", 3, RecuperationProvinceType.provinceIn.getValue(), "/assets/mobile/img/Recuperation/lxs.png");
private final String label;
private final int value;
private final String regionType;
/**
* 缓存状态map k->value v->RecuperationProvinceType.value
*/
public static Map<Integer, String> typeMap = new HashMap<>();
/**
* 缓存状态map k->value v->RecuperationProvinceType
*/
public static Map<Integer, RecuperationType> objMap = new HashMap<>();
static {
RecuperationType[] values = RecuperationType.values();
for (RecuperationType t : values) {
typeMap.put(t.getValue(), t.getRegionType());
objMap.put(t.getValue(), t);
}
}
private final String imgUrl;
}
@@ -0,0 +1,372 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.recuperation.constant.RecuperationState;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLine;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLineSelect;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLot;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.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.Param;
import java.util.*;
import java.util.stream.Collectors;
/**
* @ClassName RecuperationAnnualAnalysisController
* @Author JyuHsin
* @Date 2025/8/18 15:24
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean
@At("/platform/recuperation/annualAnalysis")
@Api("疗休养年度分析")
@Ok("json:full")
public class RecuperationAnnualAnalysisController {
@Inject
private Dao dao;
@Inject
private RecuperationLineService lineService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/recuperation/annualAnalysis/index.html")
@SaCheckLogin
public void index() {
}
@At
@ApiOperation("获取年度出行人数、线路数、省内、省外、校工会组织线路数、校省内、校省外线路数")
@SaCheckPermission("recuperation.annualAnalysis")
public Result getNumData(@Param(value = "year") Integer year,
@Param(value = "lineType") String lineType) {
// 获取选择线路表的id,后面发现了,报名表里有线路id不在线路表的情况,这类人员要排除掉
Sql selectIdSql = Sqls.create("select id from recuperation_line_select");
selectIdSql.setCallback(Sqls.callback.strList());
dao.execute(selectIdSql);
List<String> selectIdList = selectIdSql.getList(String.class);
// 获取今年报名的所有人数,还要确保报名线路是属于上面选择线路的id
Sql sql = Sqls.create("""
SELECT
takePartInLineId
FROM
`recuperation_enroll`
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(signingUptime)", "=", year);
cnd.andEX("isNormal", "=", true);
cnd.andEX("stateId", "=", RecuperationState.PASS);
cnd.andEX("takePartInLineId", "in", selectIdList);
sql.setCallback(Sqls.callback.strList());
dao.execute(sql);
// 今年的报名记录
List<String> enrollTakePartLineIdList = sql.getList(String.class);
List<String> takePartInLineIdList = enrollTakePartLineIdList.stream().distinct().collect(Collectors.toList());
// 今年报名的线路
List<RecuperationLineSelect> selectLineList = dao.query(RecuperationLineSelect.class, Cnd.where("id", "in", takePartInLineIdList));
// 找出选择的线路详情,用于区分省内还是省外
List<String> lineIdList = selectLineList.stream().map(RecuperationLineSelect::getLineId).distinct().collect(Collectors.toList());
List<RecuperationLine> lineList = dao.query(RecuperationLine.class, Cnd.where("id", "in", lineIdList));
// 如果不是全部,按搜索条件查询省内还是省外
if (StrUtil.isNotBlank(lineType) && !"全部".equals(lineType)) {
lineList = lineList.stream().filter(line -> line.getRegionalNature().equals(lineType)).toList();
List<String> lineTypeIdList = lineList.stream().map(RecuperationLine::getId).toList();
selectLineList = selectLineList.stream().filter(v -> lineTypeIdList.contains(v.getLineId())).toList();
}
// 省内线路
List<RecuperationLine> inLineList = lineList.stream().filter(line -> "省内".equals(line.getRegionalNature())).toList();
Set<String> inLineIds = inLineList.stream().map(RecuperationLine::getId).collect(Collectors.toSet());
// 选择省内的线路
List<String> selectInLineIds = selectLineList.stream().filter(v -> inLineIds.contains(v.getLineId()))
.map(RecuperationLineSelect::getId).toList();
// 省外线路
List<RecuperationLine> outLineList = lineList.stream().filter(line -> "省外".equals(line.getRegionalNature())).toList();
Set<String> outLineIds = outLineList.stream().map(RecuperationLine::getId).collect(Collectors.toSet());
// 选择省外的线路
List<String> selectOutLineIds = selectLineList.stream().filter(v -> outLineIds.contains(v.getLineId()))
.map(RecuperationLineSelect::getId).toList();
// 返回前端的数据展示
NutMap nutMap = NutMap.NEW();
// 总出行人数
int allNum = enrollTakePartLineIdList.size();
// 省内出行人数
int provinceNum = (int) enrollTakePartLineIdList.stream().filter(selectInLineIds::contains).count();
// 省外出行人数
int outProvinceNum = (int) enrollTakePartLineIdList.stream().filter(selectOutLineIds::contains).count();
nutMap.addv("allNum", allNum).addv("provinceNum", provinceNum).addv("outProvinceNum", outProvinceNum);
// 总线路数
int lineNum = selectLineList.size();
// 总省内
int inLineNum = selectInLineIds.size();
// 总省外
int outLineNum = selectOutLineIds.size();
nutMap.addv("lineNum", lineNum).addv("inLineNum", inLineNum).addv("outLineNum", outLineNum);
// 校工会组织线路
List<RecuperationLineSelect> schoolSelectLineList = selectLineList.stream().filter(v -> v.getSignUpMode() == 2).toList();
int schoolUnionLineNum = schoolSelectLineList.size();
// 校省内
int schoolInLineNum = (int) schoolSelectLineList.stream().filter(s -> inLineIds.contains(s.getLineId())).count();
// 校省外
int schoolOutLineNum = (int) schoolSelectLineList.stream().filter(s -> outLineIds.contains(s.getLineId())).count();
nutMap.addv("schoolUnionLineNum", schoolUnionLineNum).addv("schoolInLineNum", schoolInLineNum).addv("schoolOutLineNum", schoolOutLineNum);
// 分工会组织线路
List<RecuperationLineSelect> unionSelectLineList = selectLineList.stream().filter(v -> v.getSignUpMode() == 1).toList();
int unionLineNum = unionSelectLineList.size();
// 分省内
int unionInLineNum = (int) unionSelectLineList.stream().filter(s -> inLineIds.contains(s.getLineId())).count();
// 分省外
int unionOutLineNum = (int) unionSelectLineList.stream().filter(s -> outLineIds.contains(s.getLineId())).count();
nutMap.addv("unionLineNum", unionLineNum).addv("unionInLineNum", unionInLineNum).addv("unionOutLineNum", unionOutLineNum);
return Result.success(nutMap);
}
@At
@ApiOperation("出行时间标段统计")
@SaCheckPermission("recuperation.annualAnalysis")
public Result getLotNum(@Param(value = "year") Integer year,
@Param(value = "lineType") String lineType) {
if (year == null) {
year = DateUtil.thisYear();
}
List<RecuperationLot> lotList = dao.query(RecuperationLot.class, Cnd.NEW().asc("lotValue"));
Sql sql = Sqls.create("""
SELECT
enroll.*,
line.lotId AS lineLotId
FROM
recuperation_enroll enroll
LEFT JOIN recuperation_line_select us ON us.id = enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = us.lineId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(signingUpTime)", "=", year);
cnd.and("enroll.isNormal", "=", true);
cnd.and("enroll.stateId", "=", RecuperationState.PASS);
if (StrUtil.isNotBlank(lineType) && !"全部".equals(lineType)) {
cnd.andEX("line.regionalNature", "=", lineType);
}
sql.setCondition(cnd);
List<NutMap> list = lineService.listMap(sql);
List<NutMap> resultMap = new ArrayList<>();
lotList.forEach(item -> {
NutMap map = NutMap.NEW();
int value = list.stream().filter(v -> item.getId().equals(v.getString("lineLotId"))).toList().size();
map.put("label", item.getLotName());
map.put("value", value);
resultMap.add(map);
});
return Result.success().addData(resultMap);
}
@At
@ApiOperation("出行年龄分布统计")
@SaCheckPermission("recuperation.annualAnalysis")
public Result getAgeNum(@Param(value = "year") Integer year,
@Param(value = "lineType") String lineType) {
if (year == null) {
year = DateUtil.thisYear();
}
Map<String, Integer> result = new HashMap<>();
result.put("35岁以下", 0);
result.put("35至45岁", 0);
result.put("45岁以上", 0);
Sql sql = Sqls.create("""
SELECT
enroll.idCard
FROM
recuperation_enroll enroll
LEFT JOIN recuperation_line_select us ON us.id = enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = us.lineId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(signingUpTime)", "=", year);
cnd.and("enroll.isNormal", "=", true);
cnd.and("enroll.stateId", "=", RecuperationState.PASS);
cnd.and("enroll.idCard", "is not", null);
cnd.groupBy("enroll.idCard");
if (StrUtil.isNotBlank(lineType) && !"全部".equals(lineType)) {
cnd.andEX("line.regionalNature", "=", lineType);
}
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.strList());
dao.execute(sql);
List<String> idCardList = sql.getList(String.class);
for (String idCard : idCardList) {
if (StrUtil.isBlank(idCard)) {
continue;
}
int birthYear = getBirthYearFromIdCard(idCard);
if (birthYear == 0) {
continue;
}
int age = year - birthYear;
if (age < 35) {
result.put("35岁以下", result.get("35岁以下") + 1);
} else if (age <= 45) {
result.put("35至45岁", result.get("35至45岁") + 1);
} else {
result.put("45岁以上", result.get("45岁以上") + 1);
}
}
List<NutMap> list = new ArrayList<>();
result.forEach((k, v) -> {
NutMap map = NutMap.NEW();
map.put("label", k);
map.put("value", v);
list.add(map);
});
return Result.success(list);
}
private static int getBirthYearFromIdCard(String idCard) {
String birthYearStr;
if (idCard.length() == 18) {
// 18位身份证号,直接取第7到第10位作为出生年份
birthYearStr = idCard.substring(6, 10);
} else if (idCard.length() == 15) {
// 15位身份证号,取第7到第8位作为出生年份的后两位 15位身份证号均为19xx年
birthYearStr = "19" + idCard.substring(6, 8);
} else {
return 0;
}
return Integer.parseInt(birthYearStr);
}
@At
@ApiOperation("获取线路出行人数和年龄统计数据")
@SaCheckPermission("recuperation.annualAnalysis")
public Result getLineTravelAndAgeData(@Param(value = "year") Integer year,
@Param(value = "lineType") String lineType) {
Sql sql = Sqls.create("""
SELECT
us.id,
CONCAT(line.lineName,'(',DATE_FORMAT(us.playStartTime,'%m月%d'),'至',DATE_FORMAT(us.playEndTime,'%m月%d'),')') AS lineName,
su.name as unionName,
lot.lotName,
COUNT(enroll.id) AS takePartInLineNum,
SUM(CASE
WHEN @year - (CASE
WHEN LENGTH(enroll.idCard) = 18 THEN CAST(SUBSTR(enroll.idCard, 7, 4) AS UNSIGNED)
WHEN LENGTH(enroll.idCard) = 15 THEN 1900 + CAST(SUBSTR(enroll.idCard, 7, 2) AS UNSIGNED)
ELSE NULL
END) < 35 THEN 1 ELSE 0 END) AS underThirtyFive,
SUM(CASE
WHEN @year - (CASE
WHEN LENGTH(enroll.idCard) = 18 THEN CAST(SUBSTR(enroll.idCard, 7, 4) AS UNSIGNED)
WHEN LENGTH(enroll.idCard) = 15 THEN 1900 + CAST(SUBSTR(enroll.idCard, 7, 2) AS UNSIGNED)
ELSE NULL
END) BETWEEN 35 AND 45 THEN 1 ELSE 0 END) AS thirtyFiveToFortyFive,
SUM(CASE
WHEN @year - (CASE
WHEN LENGTH(enroll.idCard) = 18 THEN CAST(SUBSTR(enroll.idCard, 7, 4) AS UNSIGNED)
WHEN LENGTH(enroll.idCard) = 15 THEN 1900 + CAST(SUBSTR(enroll.idCard, 7, 2) AS UNSIGNED)
ELSE NULL
END) > 45 THEN 1 ELSE 0 END) AS aboveFortyFive
FROM
recuperation_line_select us
LEFT JOIN recuperation_line line ON us.lineId = line.id
LEFT JOIN recuperation_enroll enroll ON enroll.takePartInLineId = us.id
LEFT JOIN recuperation_lot lot ON lot.id = line.lotId
LEFT JOIN sys_union su ON su.id = us.unionId
$condition
""").setParam("year", year == null ? DateUtil.thisYear() : year);
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(us.selectTime)", "=", year);
cnd.and("enroll.isNormal", "=", true);
cnd.and("us.`enable`", "=", true);
cnd.groupBy("us.id");
if (StrUtil.isNotBlank(lineType) && !"全部".equals(lineType)) {
cnd.andEX("line.regionalNature", "=", lineType);
}
sql.setCondition(cnd);
List<NutMap> list = lineService.listMap(sql);
NutMap result = NutMap.NEW();
// 柱状图
List<NutMap> uvData = list.stream().map(v -> {
NutMap map = NutMap.NEW();
map.put("lineName", v.getString("lineName"));
map.put("value", v.getInt("takePartInLineNum"));
return map;
}).sorted(Comparator.comparing(v -> v.getString("lineName"))).collect(Collectors.toCollection(ArrayList::new));
// 折线图
List<NutMap> underThirtyFiveList = list.stream().map(v -> {
NutMap map = NutMap.NEW();
map.put("lineName", v.getString("lineName"));
map.put("count", v.getInt("underThirtyFive"));
map.put("name", "35岁以下");
return map;
}).collect(Collectors.toCollection(ArrayList::new));
List<NutMap> thirtyFiveToFortyFiveList = list.stream().map(v -> {
NutMap map = NutMap.NEW();
map.put("lineName", v.getString("lineName"));
map.put("count", v.getInt("thirtyFiveToFortyFive"));
map.put("name", "35至45岁");
return map;
}).collect(Collectors.toCollection(ArrayList::new));
List<NutMap> aboveFortyFiveList = list.stream().map(v -> {
NutMap map = NutMap.NEW();
map.put("lineName", v.getString("lineName"));
map.put("count", v.getInt("aboveFortyFive"));
map.put("name", "45岁以上");
return map;
}).collect(Collectors.toCollection(ArrayList::new));
underThirtyFiveList.addAll(thirtyFiveToFortyFiveList);
underThirtyFiveList.addAll(aboveFortyFiveList);
List<NutMap> collect = underThirtyFiveList.stream().sorted(Comparator.comparing(v -> v.getString("lineName"))).collect(Collectors.toList());
result.put("uvData", uvData);
result.put("transformData", collect);
return Result.success(result);
}
}
@@ -0,0 +1,416 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.controller;
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.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationState;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollBed;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
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.json.Json;
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 javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName RecuperationBranchUnionUserQueryController
* @Author JyuHsin
* @Date 2025/8/19 15:24
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean
@At("/platform/recuperation/branchUnionUserQuery")
@Api("疗休养分工会查询")
@Ok("json:full")
public class RecuperationBranchUnionUserQueryController {
@Inject
private Dao dao;
@Inject
private RecuperationEnrollService enrollService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/index.html")
@SaCheckLogin
public void index() {}
/**
* 分工会人员信息查询
*
* @param pageForm 分页
* @param year 年度
* @param userName 姓名
* @param loginName 登录名
* @param signUpMode 报名方式(1分工会 2校工会 3个人)
* @param unionId
* @param takePartInLineId 线路id
* @param lotId 标段id
* @param regionalNature 区域性质 省内 省外
* @return
*/
@At
@ApiOperation("分页查询")
@SaCheckPermission("recuperation.branchUnionUserQuery")
public Result pageData(PageForm pageForm,
Integer year,
String userName,
String loginName,
String signUpMode,
String unionId,
String takePartInLineId,
String lotId,
String regionalNature) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
line.regionalNature,
line.lineName,
agency.travelAgencyName,
ma.baseName,
enroll.*,
lineu.lineId,
lineu.playStartTime,
lineu.playEndTime,
( SELECT COUNT( 1 ) FROM recuperation_enroll_companion WHERE trreId = enroll.id ) isFamily
$lotSql
FROM
`recuperation_enroll` enroll
LEFT JOIN recuperation_line_select lineu ON lineu.id=enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId
LEFT JOIN recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
LEFT JOIN recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
$condition
""");
if (Strings.isNotBlank(pageForm.getSearchKeyword()) && Strings.isNotBlank(pageForm.getSearchName())) {
cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword()));
}
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), "ascending".equalsIgnoreCase(pageForm.getPageOrderBy()) ? "ASC" : "DESC");
}
// 年度
cnd.andEX("YEAR ( enroll.signingUptime )", "=", year);
if (StrUtil.isNotBlank(userName)) {
cnd.where().andLike("enroll.userName", loginName);
}
if (StrUtil.isNotBlank(loginName)) {
cnd.where().andLike("enroll.loginName", userName);
}
// 线路
cnd.andEX("enroll.takePartInLineId", "=", takePartInLineId);
// 标段
if (StrUtil.isNotBlank(lotId)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("line.lotId", "=", lotId);
seg.or("ma.lotId", "=", lotId);
cnd.and(seg);
}
// 区域
cnd.andEX("line.regionalNature", "=", regionalNature);
// 分工会只查本分工会的人员
cnd.and("enroll.selfUnionId", "=", SecurityUtil.getUnionId());
// 报名模式
if (StrUtil.isNotBlank(signUpMode)) {
if ("1".equals(signUpMode)) {
cnd.andEX("line.signUpMode", "=", 2);
} else if ("2".equals(signUpMode)) {
cnd.andEX("lineu.unionId", "=", SecurityUtil.getUnionId());
cnd.andEX("line.signUpMode", "=", 1);
} else if ("3".equals(signUpMode)) {
cnd.andEX("lineu.unionId", "!=", SecurityUtil.getUnionId());
cnd.andEX("line.signUpMode", "=", 1);
} else if ("4".equals(signUpMode)) {
cnd.andEX("line.signUpMode", "=", 3);
}
}
cnd.desc("enroll.stateId");
cnd.andEX("enroll.stateId", "=", RecuperationState.PASS);
cnd.andEX("enroll.isNormal", "=", true);
sql.setCondition(cnd);
Pagination pagination = enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> list = pagination.getList();
list.forEach(v -> {
List<RecuperationEnrollCompanion> companionList = dao.query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", v.getString("id")));
for (RecuperationEnrollCompanion enrollCompanion : companionList) {
enrollService.fetchLinks(enrollCompanion, "bedInfo");
}
v.setv("companionList", companionList);
});
return Result.success(pagination);
}
/**
* 设置出行人员
*
* @return
*/
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("设置出行人员")
@SaCheckPermission("recuperation.branchUnionUserQuery")
@SLog(type = "recuperation", tag = "设置出行人员", msg = "设置出行人员")
public Result setUpParticipants(@Param("data") String data) {
List<NutMap> list = Json.fromJsonAsList(NutMap.class, data);
for (NutMap map : list) {
Chain chain = Chain.make("lotId", map.getString("lotId")).add("takePartInTime", map.getString("takePartInTime")).add("isTakePartIn", true);
dao.update(RecuperationEnroll.class, chain, Cnd.where("id", "=", map.getString("id")));
}
return Result.success();
}
/**
* 删除报名信息
*/
@At
@ApiOperation("删除报名信息")
@SaCheckPermission("recuperation.baseManagement")
@SLog(type = "recuperation", tag = "删除报名信息", msg = "删除报名信息")
public Result deleteMyEnrollInfoById(String id) {
enrollService.deleteMyEnrollInfoById(id);
return Result.success();
}
/**
* 编辑查询详细信息
*/
@At
@ApiOperation("编辑查询详细信息")
@SaCheckPermission("recuperation.branchUnionUserQuery")
public Result findOne(String id) {
Sql sql = Sqls.create("""
SELECT
lxs.travelAgencyName,
enroll.*,
line.lineName,
if(enroll.takePartInUnionId!=enroll.selfUnionId,true,false) isTransferIn,
(SELECT COUNT(1) FROM recuperation_enroll_companion WHERE trreId=enroll.id and relation='亲属') isFamily
FROM
`recuperation_enroll` enroll
LEFT JOIN recuperation_line_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId
LEFT JOIN recuperation_travel_agency lxs ON lxs.id = line.travelAgencyId
where enroll.id=@id
""");
sql.setParam("id", id);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap data = (NutMap) sql.getResult();
List<RecuperationEnrollCompanion> companionList = dao.query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", id));
companionList.forEach(v -> {
v.setBedInfo(dao.fetch(RecuperationEnrollBed.class, v.getBedInfoId()));
});
data.put("companionList", companionList);
return Result.success(data);
}
/**
* 获取线路
*
* @param year 年度
* @param signUpMode 报名模式
* @param regionalNature 区域
* @return
*/
@At
@ApiOperation("获取线路")
@SaCheckPermission("recuperation.branchUnionUserQuery")
public Result listLine(Integer year, String signUpMode, String regionalNature) {
Sql sql = Sqls.create("""
SELECT
t1.takePartInLineId,
t3.lineName,
t4.name as unionName
FROM
recuperation_enroll t1
LEFT JOIN recuperation_line_select t2 ON t2.id = t1.takePartInLineId
LEFT JOIN recuperation_line t3 ON t3.id = t2.lineId
LEFT JOIN sys_union t4 ON t4.id = t2.unionId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.selfUnionId", "=", SecurityUtil.getUnionId());
cnd.andEX("YEAR(t2.selectTime)", "=", year);
cnd.andEX("t3.regionalNature", "=", regionalNature);
if ("1".equals(signUpMode)) {
cnd.andEX("t3.signUpMode", "=", 2);
} else if ("2".equals(signUpMode)) {
cnd.andEX("t2.unionId", "=", SecurityUtil.getUnionId());
cnd.and("t3.signUpMode", "=", 1);
} else if ("3".equals(signUpMode)) {
cnd.andEX("t2.unionId", "!=", SecurityUtil.getUnionId());
cnd.and("t3.signUpMode", "=", 1);
} else if ("4".equals(signUpMode)) {
cnd.andEX("t3.signUpMode", "=", 3);
}
cnd.groupBy("t1.takePartInLineId");
sql.setCondition(cnd);
List<NutMap> list = enrollService.listMap(sql);
return Result.success(list);
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("recuperation.branchUnionUserQuery")
public void exportXlsx(Integer year,
String userName,
String loginName,
String signUpMode,
String unionId,
String takePartInLineId,
String lotId,
String regionalNature,
HttpServletResponse response) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
line.regionalNature,
line.lineName,
agency.travelAgencyName,
ma.baseName,
enroll.*,
lineu.lineId,
lineu.playStartTime,
lineu.playEndTime,
( SELECT COUNT( 1 ) FROM recuperation_enroll_companion WHERE trreId = enroll.id ) isFamily
$lotSql
FROM
`recuperation_enroll` enroll
LEFT JOIN recuperation_line_select lineu ON lineu.id=enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId
LEFT JOIN recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
LEFT JOIN recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
$condition
""");
// 年度
cnd.andEX("YEAR ( enroll.signingUptime )", "=", year);
if (StrUtil.isNotBlank(userName)) {
cnd.where().andLike("enroll.userName", userName);
}
if (StrUtil.isNotBlank(loginName)) {
cnd.where().andLike("enroll.loginName", loginName);
}
// 线路
cnd.andEX("enroll.takePartInLineId", "=", takePartInLineId);
// 标段
if (StrUtil.isNotBlank(lotId)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("line.lotId", "=", lotId);
seg.or("ma.lotId", "=", lotId);
cnd.and(seg);
}
// 区域
cnd.andEX("line.regionalNature", "=", regionalNature);
// 分工会只查本分工会的人员
cnd.and("enroll.selfUnionId", "=", SecurityUtil.getUnionId());
// 报名模式
if (StrUtil.isNotBlank(signUpMode)) {
if ("1".equals(signUpMode)) {
cnd.andEX("line.signUpMode", "=", 2);
} else if ("2".equals(signUpMode)) {
cnd.andEX("lineu.unionId", "=", SecurityUtil.getUnionId());
cnd.andEX("line.signUpMode", "=", 1);
} else if ("3".equals(signUpMode)) {
cnd.andEX("lineu.unionId", "!=", SecurityUtil.getUnionId());
cnd.andEX("line.signUpMode", "=", 1);
} else if ("4".equals(signUpMode)) {
cnd.andEX("line.signUpMode", "=", 3);
}
}
cnd.desc("enroll.stateId");
cnd.andEX("enroll.stateId", "=", RecuperationState.PASS);
cnd.andEX("enroll.isNormal", "=", true);
sql.setCondition(cnd);
List<NutMap> list = enrollService.listMap(sql);
list.forEach(v -> {
List<RecuperationEnrollCompanion> companionList = dao.query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", v.getString("id")));
for (RecuperationEnrollCompanion enrollCompanion : companionList) {
enrollService.fetchLinks(enrollCompanion, "bedInfo");
}
v.setv("companionList", companionList);
});
// 配置
RecuperationConfig config = dao.fetch(RecuperationConfig.class, Cnd.NEW());
List<ExcelExportEntity> excelEntities = new ArrayList<>();
excelEntities.add(new ExcelExportEntity("姓名", "userName", 20));
excelEntities.add(new ExcelExportEntity("工号", "loginName", 20));
excelEntities.add(new ExcelExportEntity("性别", "sex", 20));
excelEntities.add(new ExcelExportEntity("单位", "unitName", 20));
excelEntities.add(new ExcelExportEntity("工会", "unionName", 20));
excelEntities.add(new ExcelExportEntity("身份证号", "idCard", 30));
excelEntities.add(new ExcelExportEntity("手机号", "mobile", 20));
if (config.getFamilyInfo() == 2) {
excelEntities.add(new ExcelExportEntity("与本人关系", "relation", 10));
excelEntities.add(new ExcelExportEntity("床型", "bedType", 10));
excelEntities.add(new ExcelExportEntity("床位数", "bedNum", 10));
excelEntities.add(new ExcelExportEntity("意向拼房人", "otherSleepUser", 10));
} else {
excelEntities.add(new ExcelExportEntity("携带家属数", "familyNumber", 10));
}
excelEntities.add(new ExcelExportEntity("备注", "bz", 20));
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + new String(("报名人员.xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
try {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelEntities, list);
workbook.write(response.getOutputStream());
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,23 +1,36 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.controller; package com.budwk.app.zhgh.staffbenefit.recuperation.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm; import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; 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.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param; import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/** /**
* @ClassName RecuperationEvaluateStatisticsController * @ClassName RecuperationEvaluateStatisticsController
* @Author JyuHsin * @Author JyuHsin
@@ -34,11 +47,14 @@ public class RecuperationEvaluateStatisticsController {
@Inject @Inject
private Dao dao; private Dao dao;
@Inject
private RecuperationEnrollService enrollService;
@At("") @At("")
@Ok("beetl:/platform/zhgh/staffbenefit/recuperation/statistics/index.html") @Ok("beetl:/platform/zhgh/staffbenefit/recuperation/statistics/index.html")
@SaCheckLogin @SaCheckLogin
public void index() {} public void index() {
}
@At @At
@ApiOperation("分页查询") @ApiOperation("分页查询")
@@ -51,35 +67,38 @@ public class RecuperationEvaluateStatisticsController {
@Param(value = "userState") String userState, @Param(value = "userState") String userState,
@Param(value = "evaluateScore") String evaluateScore) { @Param(value = "evaluateScore") String evaluateScore) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
we.evaluateText, we.evaluateText,
we.evaluateScore, we.evaluateScore,
we.userName, we.userName,
we.loginName, we.loginName,
u.unionname, u.unionname as unionName,
u.unitname, u.unitname as unitName,
u.userState, u.userState,
u.personType, u.personType,
line.lineName, line.lineName,
us.playStartTime us.playStartTime
FROM FROM
`recuperation_evaluate` we `recuperation_evaluate` we
LEFT JOIN `vw_user` u ON u.id = we.userId LEFT JOIN `vw_user` u ON u.id = we.userId
LEFT JOIN recuperation_enroll en ON en.takePartInLineId = we.lineId LEFT JOIN recuperation_enroll en ON en.takePartInLineId = we.lineId
LEFT JOIN recuperation_line_union_select us ON us.id = en.takePartInLineId LEFT JOIN recuperation_line_select us ON us.id = en.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = us.lineId LEFT JOIN recuperation_line line ON line.id = us.lineId
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchName()) && StrUtil.isNotBlank(pageForm.getSearchKeyword())) { if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword())); SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("u.userName", pageForm.getSearchKeyword());
seg.orLike("u.loginName", pageForm.getSearchKeyword());
cnd.and(seg);
} }
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) { if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), "ascending".equals(pageForm.getPageOrderBy()) ? "asc" : "desc"); cnd.orderBy(pageForm.getPageOrderName(), "ascending".equals(pageForm.getPageOrderBy()) ? "asc" : "desc");
} else { } else {
cnd.desc("we.evaluateScore"); cnd.desc("we.evaluateScore");
} }
if(StrUtil.isNotBlank(lineId)) { if (StrUtil.isNotBlank(lineId)) {
cnd.andEX("we.lineId", "in", lineId.split(",")); cnd.andEX("we.lineId", "in", lineId.split(","));
} }
cnd.andEX("u.unionid", "=", unionId); cnd.andEX("u.unionid", "=", unionId);
@@ -89,7 +108,93 @@ public class RecuperationEvaluateStatisticsController {
cnd.andEX("we.evaluateScore", "=", evaluateScore); cnd.andEX("we.evaluateScore", "=", evaluateScore);
cnd.groupBy("we.lineId"); cnd.groupBy("we.lineId");
sql.setCondition(cnd); sql.setCondition(cnd);
//enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); Pagination pagination = enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(); return Result.success(pagination);
}
@At
@ApiOperation("获取线路列表")
@SaCheckPermission("recuperation.statistics")
public Result lineList(Integer year) {
Sql sql = Sqls.create("""
SELECT
GROUP_CONCAT(us.id) as id,
line.lineName,
if(us.signUpMode = 2, '校工会', un.name) as unionName
FROM
recuperation_line_select us
LEFT JOIN recuperation_line line ON us.lineId = line.id
LEFT JOIN sys_union un ON un.id = us.unionId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("year(us.selectTime)", "=", year);
cnd.groupBy("lineId, unionid");
sql.setCondition(cnd);
return Result.success(enrollService.listMap(sql));
}
@At
@ApiOperation("导出评价统计")
@SaCheckPermission("recuperation.statistics")
public void exportEvaluate(String lineId,
String unionId,
String unitId,
String evaluateScore,
String searchKeyword,
String searchName,
HttpServletResponse response) {
Sql sql = Sqls.create("""
SELECT
we.evaluateText,
we.evaluateScore,
we.userName,
we.loginName,
u.unionname,
u.unitname,
u.userState,
u.personType,
line.lineName,
us.playStartTime
FROM
`recuperation_evaluate` we
LEFT JOIN `vw_user` u ON u.id = we.userId
LEFT JOIN recuperation_enroll en ON en.takePartInLineId = we.lineId
LEFT JOIN recuperation_line_select us ON us.id = en.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = us.lineId
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(searchName) && StrUtil.isNotBlank(searchKeyword)) {
cnd.and(Cnd.likeEX(searchName, searchKeyword));
}
if (StrUtil.isNotBlank(lineId)) {
cnd.andEX("we.lineId", "in", lineId.split(","));
}
cnd.andEX("u.unionid", "=", unionId);
cnd.andEX("u.unitid", "=", unitId);
cnd.andEX("we.evaluateScore", "=", evaluateScore);
cnd.groupBy("we.lineId");
sql.setCondition(cnd);
List<NutMap> listMap = enrollService.listMap(sql);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("线路", "lineName", 20));
entities.add(new ExcelExportEntity("出行时间", "playStartTime", 20));
entities.add(new ExcelExportEntity("工号", "loginName", 20));
entities.add(new ExcelExportEntity("姓名", "userName", 20));
entities.add(new ExcelExportEntity("所属单位", "unitname", 20));
entities.add(new ExcelExportEntity("所属工会", "unionname", 20));
entities.add(new ExcelExportEntity("在职状态", "userState", 20));
entities.add(new ExcelExportEntity("人员类型", "personType", 20));
entities.add(new ExcelExportEntity("评分", "evaluateScore", 20));
entities.add(new ExcelExportEntity("评价", "evaluateText", 40));
try {
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entities, listMap);
CommonDownloadUtil.download("评价人员名单.xlsx", workbook, response);
} catch (Exception ignored) {
}
} }
} }
@@ -0,0 +1,357 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLineSelect;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLot;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationTravelAgency;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineSelectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.*;
import java.util.stream.Collectors;
/**
* @ClassName RecuperationLineSelectController
* @Author JyuHsin
* @Date 2025/8/18 15:53
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean
@At("/platform/recuperation/lineSelect")
@Api("疗休养选择线路")
@Ok("json:full")
public class RecuperationLineSelectController {
@Inject
private Dao dao;
@Inject
private RecuperationLineSelectService lineSelectService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/recuperation/lineSelect/index.html")
@SaCheckLogin
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
public Result pageData(PageForm pageForm,
@Param("year") Integer year,
@Param("keywords") String keywords,
@Param("selectStatus") int selectStatus,
@Param("unionId") String unionId,
@Param("lotId") String lotId,
@Param("travelAgencyId") String travelAgencyId,
@Param("mode") Integer mode,
@Param("regionalNature") String regionalNature) {
RecuperationConfig config = lineSelectService.dao().fetch(RecuperationConfig.class, Cnd.NEW());
Cnd cnd = Cnd.NEW();
cnd.andEX("line.lotId", "=", lotId);
cnd.andEX("line.travelAgencyId", "=", travelAgencyId);
if (!"全部".equals(regionalNature)) {
cnd.andEX("line.regionalNature", "=", regionalNature);
}
//当前登录用户已选择的线路id
Sql hasSelectLineSql;
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and(Cnd.exps("line.createUnionId", "=", SecurityUtil.getUnionId()).or("createMode", "=", 2));
hasSelectLineSql = Sqls.createf("""
select lineId from recuperation_line_select where selectUserId = '%s' AND unionId = '%s' AND year(selectTime) = %s
""", SecurityUtil.getUserId(), SecurityUtil.getUnionId(), year == null ? DateUtil.thisYear() : year);
} else {
hasSelectLineSql = Sqls.createf("""
select lineId from recuperation_line_select where year(selectTime) = %s
""", year == null ? DateUtil.thisYear() : year);
}
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", "=", RecuperationLineCreateMode.SCHOOL.getValue()));
seg.or("line.id", "in", hasSelectLineSql);
cnd.and(seg);
}*/
//查询已选择的线路
case 1 -> {
cnd.and("line.id", "in", hasSelectLineSql);
cnd.and("us.signUpMode", "=", mode);
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);
seg.orLike("ta.travelAgencyName", 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");
}
Pagination pagination = lineSelectService.pageData(pageForm, cnd, year);
return Result.success(pagination);
}
/**
* 选择线路
*
* @param us 选择线路信息
* @return {@link Result}
*/
@At("/selectLine")
@ApiOperation("选择线路")
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
@SLog(type = "recuperation", tag = "选择线路", msg = "选择线路")
public Result selectLine(RecuperationLineSelect us) {
lineSelectService.selectLine(us);
return Result.success();
}
/**
* 选择线路时间
*
* @param lineSelects 选择线路
* @return {@link Object}
*/
@At("/selectLineTimes")
@ApiOperation("选择线路时间")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
@SLog(type = "recuperation", tag = "选择线路时间", msg = "选择线路时间")
public Result selectLineTimes(@Param("lineSelects") RecuperationLineSelect[] lineSelects) {
if (Lang.isNotEmpty(lineSelects)) {
RecuperationLineSelect lineUnionSelect = lineSelects[0];
List<RecuperationLineSelect> oldUnionSelects = lineSelectService.query(Cnd.where("unionId", "=", SecurityUtil.getUnionId()).and("lineId", "=", lineUnionSelect.getUnionId()));
//组织形式
int signUpMode = AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_ADMIN.name(), RoleConstant.BRANCH_UNION_CHAIRMAN.name()) ? 1 : 2;
RecuperationLineSelect recuperationLineSelect = dao.fetch(RecuperationLineSelect.class, Cnd.where("id", "=", lineUnionSelect.getId()));
for (RecuperationLineSelect lineSelect : lineSelects) {
lineSelect.setSelectTime(new Date());
lineSelect.setSelectUserId(SecurityUtil.getUserId());
lineSelect.setUnionId(SecurityUtil.getUnionId());
lineSelect.setIsOpen(Lang.isNotEmpty(recuperationLineSelect) ? recuperationLineSelect.getIsOpen() : false);
lineSelect.setDelFlag(signUpMode == 2);
lineSelect.setSignUpMode(signUpMode);
}
//新增或修改
dao.insertOrUpdate(lineSelects);
List<String> newIds = Arrays.stream(lineSelects).map(RecuperationLineSelect::getId).toList();
//删除
List<String> deleteIds = oldUnionSelects.stream().map(RecuperationLineSelect::getId).filter(v -> !newIds.contains(v)).toList();
lineSelectService.clear(Cnd.where("id", "in", deleteIds));
}
return Result.success();
}
@At
@ApiOperation("查询线路信息")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
public Result 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(SecurityUtil.getUnionId());
if (mode == 1 && !AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_ADMIN.name(), RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
return Result.error("您没有分工会角色权限!");
} else if (mode == 2 && !AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_ADMIN.name())) {
return Result.error("您没有校工会角色权限!");
}
return Result.success(lineSelectService.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
@ApiOperation("查询某个分工会设置的线路时间信息")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
public Result findUsLineInfo(String lineId, String usUnionId) {
RecuperationLineSelect lineSelect = lineSelectService.findUsLineInfo(lineId, usUnionId);
return Result.success(lineSelect);
}
@At("/deSelect")
@ApiOperation("取消选择线路")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
@SLog(tag = "recuperation", msg = "取消选择线路", param = true, result = true)
public Result deSelect(@Param("lineId") String lineId, @Param("unionId") String unionId) {
try {
Assert.notBlank(lineId);
Assert.notBlank(unionId);
Cnd enrollCnd = Cnd.where("unionId", "=", unionId);
enrollCnd.and("lineId", "=", lineId);
lineSelectService.clear(enrollCnd);
return Result.success();
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
/**
* 旅行社
*
* @return {@link Object}
*/
@At
@ApiOperation("查询旅行社信息")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
public Result getTravelAgencyOptions() {
List<RecuperationTravelAgency> travelAgencies = lineSelectService.dao().query(RecuperationTravelAgency.class, Cnd.NEW().asc("serialNumber"));
return Result.success(travelAgencies);
}
/**
* 是否公开分工会选择线路
*
* @param id 分工会选择线路id
* @return {@link Object}
*/
@At("/isOpenUnionLine/?")
@ApiOperation("是否公开分工会选择线路")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
@SLog(tag = "recuperation", msg = "公开分工会选择线路", param = true, result = true)
public Result isOpenUnionLine(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
dao.update(RecuperationLineSelect.class, Chain.makeSpecial("isOpen", "isOpen ^ 1"), Cnd.where("id", "=", id));
return Result.success();
}
@At("/getLineConfig/?")
@ApiOperation("获取线路配置信息")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
public Result getLineConfig(String id) {
Sql sql = Sqls.create("select lotId from recuperation_line where id = @lineId");
sql.setParam("lineId", id);
String lotId = (String) Daos.query(dao, sql.toString(), Sqls.callback.str());
RecuperationLot lotInfo = dao.fetch(RecuperationLot.class, lotId);
Integer cost = Optional.ofNullable(lotInfo).map(RecuperationLot::getActivityCost).orElse(0);
RecuperationConfig config = dao.fetch(RecuperationConfig.class, Cnd.NEW());
Integer groupNumber = Optional.ofNullable(config).map(RecuperationConfig::getGroupNumber).orElse(0);
return Result.success(Map.of("cost", cost, "groupNumber", groupNumber));
}
/**
* 一键统赋时间,针对于已选择的线路
*
* @param lineIds 线路Id数组
* @param lineSelects 出行时段
* @return {@link Object}
*/
@At("/setGiveLineTimes")
@ApiOperation("一键统赋时间,针对于已选择的线路")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
@SLog(type = "普惠疗休养", tag = "分工会/校工会选择线路", msg = "一键统赋时间,针对于已选择的线路", param = true, result = true)
public Result setGiveLineTimes(@Param("lineIds") String[] lineIds,
@Param("lineUnionSelects") RecuperationLineSelect[] lineSelects,
@Param(value = "year") Integer year) {
if (Lang.isNotEmpty(lineSelects) && Lang.isNotEmpty(lineIds)) {
RecuperationLineSelect lineUnionSelect = lineSelects[0];
Cnd cnd = Cnd.NEW();
cnd.and("unionId", "=", SecurityUtil.getUnionId());
cnd.and("selectUserId", "=", SecurityUtil.getUserId());
cnd.and("YEAR(selectTime)", "=", year == null ? DateUtil.thisYear() : year);
List<RecuperationLineSelect> unionSelectList = dao.query(RecuperationLineSelect.class, cnd);
List<String> selectIdList = unionSelectList.stream().map(RecuperationLineSelect::getId).collect(Collectors.toList());
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());
dao.update(RecuperationLineSelect.class, chain, Cnd.where("id", "in", selectIdList));
}
return Result.success();
}
@At
@ApiOperation("是否开放对外报名")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR)
@SLog(type = "普惠疗休养", tag = "分工会/校工会选择线路", msg = "是否开放对外报名", param = true, result = true)
public Result doEditOpen(String id) {
dao.update(RecuperationLineSelect.class, Chain.makeSpecial("isOpen", "isOpen ^ 1"), Cnd.where("id", "=", id));
return Result.success();
}
}
@@ -0,0 +1,463 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.controller;
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.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationState;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationConfig;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollBed;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
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.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.json.Json;
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 javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName RecuperationSchoolUnionUserQueryController
* @Author JyuHsin
* @Date 2025/8/19 15:34
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean
@At("/platform/recuperation/schoolUnionUserQuery")
@Api("疗休养校工会查询")
@Ok("json:full")
public class RecuperationSchoolUnionUserQueryController {
@Inject
private Dao dao;
@Inject
private RecuperationEnrollService enrollService;
@At("")
@Ok("beetl:/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html")
@SaCheckLogin
public void index() {}
/**
* 校工会人员信息查询
*
* @param pageForm 分页
* @param year 年度
* @param userName 姓名
* @param loginName 登录名
* @param signUpMode 报名方式(1分工会 2校工会 3个人)
* @param unionId 分工会id
* @param takePartInLineId 线路id
* @param lotId 标段id
* @param regionalNature 区域性质 省内 省外
* @return
*/
@At
@ApiOperation("分页查询")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
public Result pageData(PageForm pageForm,
Integer year,
String userName,
String loginName,
String signUpMode,
String unionId,
String takePartInLineId,
String lotId,
String regionalNature) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
line.regionalNature,
line.lineName,
agency.travelAgencyName,
ma.baseName,
enroll.*,
lineu.lineId,
lineu.playStartTime,
lineu.playEndTime,
( SELECT COUNT( 1 ) FROM recuperation_enroll_companion WHERE trreId = enroll.id ) isFamily
$lotSql
FROM
`recuperation_enroll` enroll
LEFT JOIN recuperation_line_select lineu ON lineu.id=enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId
LEFT JOIN recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
LEFT JOIN recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
$condition
""");
if (Strings.isNotBlank(pageForm.getSearchKeyword()) && Strings.isNotBlank(pageForm.getSearchName())) {
cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword()));
}
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), "ascending".equalsIgnoreCase(pageForm.getPageOrderBy()) ? "ASC" : "DESC");
}
cnd.and("enroll.takePartInLineId", "is not", null);
// 年度
cnd.andEX("YEAR ( enroll.signingUptime )", "=", year);
if (StrUtil.isNotBlank(userName)) {
cnd.where().andLike("enroll.userName", userName);
}
if (StrUtil.isNotBlank(loginName)) {
cnd.where().andLike("enroll.loginName", loginName);
}
// 线路
cnd.andEX("enroll.takePartInLineId", "=", takePartInLineId);
// 标段
if (StrUtil.isNotBlank(lotId)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("line.lotId", "=", lotId);
seg.or("ma.lotId", "=", lotId);
cnd.and(seg);
}
// 区域
cnd.andEX("line.regionalNature", "=", regionalNature);
// 校工会可查询指定分工会
cnd.andEX("enroll.selfUnionId", "=", unionId);
// // 报名模式
// if (StrUtil.isNotBlank(signUpMode)) {
// if (signUpMode.equals("1")) {
// cnd.andEX("line.signUpMode", "=", 2);
// } else if (signUpMode.equals("2")) {
// cnd.andEX("lineu.unionId", "=", Vi.getUnionId());
// cnd.andEX("line.signUpMode", "=", 1);
// } else if (signUpMode.equals("3")) {
// cnd.andEX("lineu.unionId", "!=", Vi.getUnionId());
// cnd.andEX("line.signUpMode", "=", 1);
// } else if (signUpMode.equals("4")) {
// cnd.andEX("line.signUpMode", "=", 3);
// }
// }
cnd.desc("enroll.stateId");
cnd.andEX("enroll.stateId", "=", RecuperationState.PASS);
cnd.andEX("enroll.isNormal", "=", true);
sql.setCondition(cnd);
Pagination pagination = enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> list = pagination.getList();
list.forEach(v -> {
List<RecuperationEnrollCompanion> companionList = dao.query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", v.getString("id")));
for (RecuperationEnrollCompanion enrollCompanion : companionList) {
enrollService.fetchLinks(enrollCompanion, "bedInfo");
}
v.setv("companionList", companionList);
});
return Result.success(pagination);
}
/**
* 设置出行人员
*
* @return
*/
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("设置出行人员")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
@SLog(type = "recuperation", tag = "设置出行人员", msg = "设置出行人员")
public Result setUpParticipants(@Param("data") String data) {
List<NutMap> list = Json.fromJsonAsList(NutMap.class, data);
for (NutMap map : list) {
Chain chain = Chain.make("lotId", map.getString("lotId")).add("takePartInTime", map.getString("takePartInTime")).add("isTakePartIn", true);
dao.update(RecuperationEnroll.class, chain, Cnd.where("id", "=", map.getString("id")));
}
return Result.success();
}
/**
* 删除报名信息
*/
@At
@ApiOperation("删除报名信息")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
@SLog(type = "recuperation", tag = "删除报名信息", msg = "删除报名信息")
public Result deleteMyEnrollInfoById(String id) {
enrollService.deleteMyEnrollInfoById(id);
return Result.success();
}
/**
* 编辑查询详细信息
*/
@At
@ApiOperation("编辑查询详细信息")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
public Result findOne(String id) {
Sql sql = Sqls.create("""
SELECT
lxs.travelAgencyName,
enroll.*,
line.lineName,
if(enroll.takePartInUnionId!=enroll.selfUnionId,true,false) isTransferIn,
(SELECT COUNT(1) FROM recuperation_enroll_companion WHERE trreId=enroll.id and relation='亲属') isFamily
FROM
`recuperation_enroll` enroll
LEFT JOIN recuperation_line_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId
LEFT JOIN recuperation_travel_agency lxs ON lxs.id = line.travelAgencyId
where enroll.id=@id
""");
sql.setParam("id", id);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap data = (NutMap) sql.getResult();
List<RecuperationEnrollCompanion> companionList = dao.query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", id));
companionList.forEach(v -> {
v.setBedInfo(dao.fetch(RecuperationEnrollBed.class, v.getBedInfoId()));
});
data.put("companionList", companionList);
return Result.success(data);
}
/**
* 获取线路
*
* @param year 年度
* @param signUpMode 报名模式
* @param unionId 分工会id
* @param regionalNature 区域
* @return
*/
@At
@ApiOperation("获取线路")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
public Result listLine(Integer year, String signUpMode, String unionId, String regionalNature) {
Sql sql = Sqls.create("""
SELECT
t1.takePartInLineId,
t3.lineName,
t4.name as unionName
FROM
recuperation_enroll t1
LEFT JOIN recuperation_line_select t2 ON t2.id = t1.takePartInLineId
LEFT JOIN recuperation_line t3 ON t3.id = t2.lineId
LEFT JOIN sys_union t4 ON t4.id = t2.unionId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("t1.selfUnionId", "=", unionId);
cnd.andEX("YEAR(t2.selectTime)", "=", year);
cnd.andEX("t3.regionalNature", "=", regionalNature);
cnd.groupBy("t1.takePartInLineId");
sql.setCondition(cnd);
List<NutMap> list = enrollService.listMap(sql);
return Result.success(list);
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
public void exportXlsx(Integer year,
String userName,
String loginName,
String signUpMode,
String unionId,
String takePartInLineId,
String lotId,
String regionalNature,
HttpServletResponse response) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
line.regionalNature,
line.lineName,
agency.travelAgencyName,
ma.baseName,
enroll.*,
lineu.lineId,
lineu.playStartTime,
lineu.playEndTime,
( SELECT COUNT( 1 ) FROM recuperation_enroll_companion WHERE trreId = enroll.id ) isFamily
$lotSql
FROM
`recuperation_enroll` enroll
LEFT JOIN recuperation_line_select lineu ON lineu.id=enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId
LEFT JOIN recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
LEFT JOIN recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
$condition
""");
cnd.and("enroll.takePartInLineId", "is not", null);
// 年度
cnd.andEX("YEAR ( enroll.signingUptime )", "=", year);
if (StrUtil.isNotBlank(userName)) {
cnd.where().andLike("enroll.userName", userName);
}
if (StrUtil.isNotBlank(loginName)) {
cnd.where().andLike("enroll.loginName", loginName);
}
// 线路
cnd.andEX("enroll.takePartInLineId", "=", takePartInLineId);
// 标段
if (StrUtil.isNotBlank(lotId)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("line.lotId", "=", lotId);
seg.or("ma.lotId", "=", lotId);
cnd.and(seg);
}
// 区域
cnd.andEX("line.regionalNature", "=", regionalNature);
// 校工会可查询指定分工会
cnd.andEX("enroll.selfUnionId", "=", unionId);
// // 报名模式
// if (StrUtil.isNotBlank(signUpMode)) {
// if (signUpMode.equals("1")) {
// cnd.andEX("line.signUpMode", "=", 2);
// } else if (signUpMode.equals("2")) {
// cnd.andEX("lineu.unionId", "=", Vi.getUnionId());
// cnd.andEX("line.signUpMode", "=", 1);
// } else if (signUpMode.equals("3")) {
// cnd.andEX("lineu.unionId", "!=", Vi.getUnionId());
// cnd.andEX("line.signUpMode", "=", 1);
// } else if (signUpMode.equals("4")) {
// cnd.andEX("line.signUpMode", "=", 3);
// }
// }
cnd.desc("enroll.stateId");
cnd.andEX("enroll.stateId", "=", RecuperationState.PASS);
cnd.andEX("enroll.isNormal", "=", true);
sql.setCondition(cnd);
List<NutMap> list = enrollService.listMap(sql);
list.forEach(v -> {
List<RecuperationEnrollCompanion> companionList = dao.query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", v.getString("id")));
for (RecuperationEnrollCompanion enrollCompanion : companionList) {
enrollService.fetchLinks(enrollCompanion, "bedInfo");
}
v.setv("companionList", companionList);
});
// 配置
RecuperationConfig config = dao.fetch(RecuperationConfig.class, Cnd.NEW());
List<ExcelExportEntity> excelEntities = new ArrayList<>();
excelEntities.add(new ExcelExportEntity("姓名", "userName", 20));
excelEntities.add(new ExcelExportEntity("工号", "loginName", 20));
excelEntities.add(new ExcelExportEntity("性别", "sex", 20));
excelEntities.add(new ExcelExportEntity("单位", "unitName", 20));
excelEntities.add(new ExcelExportEntity("工会", "unionName", 20));
excelEntities.add(new ExcelExportEntity("身份证号", "idCard", 30));
excelEntities.add(new ExcelExportEntity("手机号", "mobile", 20));
if (config.getFamilyInfo() == 2) {
excelEntities.add(new ExcelExportEntity("与本人关系", "relation", 10));
excelEntities.add(new ExcelExportEntity("床型", "bedType", 10));
excelEntities.add(new ExcelExportEntity("床位数", "bedNum", 10));
excelEntities.add(new ExcelExportEntity("意向拼房人", "otherSleepUser", 10));
} else {
excelEntities.add(new ExcelExportEntity("携带家属数", "familyNumber", 10));
}
excelEntities.add(new ExcelExportEntity("备注", "bz", 20));
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + new String(("报名人员.xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
try {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelEntities, list);
workbook.write(response.getOutputStream());
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@At
@Ok("void")
@ApiOperation("导出未报名人员")
@SaCheckPermission("recuperation.schoolUnionUserQuery")
public void noSignExport(HttpServletResponse response) {
RecuperationConfig config = dao.fetch(RecuperationConfig.class, Cnd.NEW());
Sql sql = Sqls.create("""
select
u.username as userName,
u.loginname as loginName,
u.sex,
u.mobile,
u.unitname as unitName,
u.name as unionName,
u.remark
from
activity_user_scope us
left join vw_user u on u.id = us.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("us.groupId", "=", config.getActivityGroupId());
cnd.and(new Static(" u.loginname not in (select loginName from recuperation_enroll where year(signingUptime) = '%s' and isNormal = true)".formatted(DateUtil.thisYear())));
cnd.asc("unitcode");
sql.setCondition(cnd);
List<NutMap> listMap = enrollService.listMap(sql);
for (int i = 0; i < listMap.size(); i++) {
listMap.get(i).put("index", i + 1);
}
List<ExcelExportEntity> excelEntities = new ArrayList<>();
excelEntities.add(new ExcelExportEntity("序号", "index", 10));
excelEntities.add(new ExcelExportEntity("姓名", "userName", 10));
excelEntities.add(new ExcelExportEntity("工号", "loginName", 20));
excelEntities.add(new ExcelExportEntity("性别", "sex", 10));
excelEntities.add(new ExcelExportEntity("联系方式", "mobile", 20));
excelEntities.add(new ExcelExportEntity("所属单位", "unitName", 20));
excelEntities.add(new ExcelExportEntity("所属工会", "unionName", 20));
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + new String((DateUtil.thisYear() + "未报名人员.xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
try {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelEntities, listMap);
workbook.write(response.getOutputStream());
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,36 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
/**
* @ClassName RecuperationEnrollChangeRecord
* @Author JyuHsin
* @Date 2025/8/19 15:48
* @Version 1.0
* @Description TODO
*/
@Data
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("疗休养登记变更记录表")
public class RecuperationEnrollChangeRecord {
@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,61 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.model;
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;
import java.io.Serializable;
import java.util.Date;
/**
* @author NINGMEI
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("recuperation_evaluate")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("疗休养评价统计表")
public class RecuperationEvaluate extends BaseModel implements Serializable {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("参加线路id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String lineId;
@Column
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userName;
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String loginName;
@Column
@Comment("评分")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String evaluateScore;
@Column
@Comment("评价内容")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String evaluateText;
@Column
@Comment("评价时间")
@ColDefine(type = ColType.DATETIME)
private Date applyDate;
}
@@ -17,10 +17,10 @@ import java.util.Date;
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Table("recuperation_line_union_select") @Table("recuperation_line_select")
@TableMeta("{'mysql-charset':'utf8mb4'}") @TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("疗休养线路") @Comment("疗休养线路")
public class RecuperationLineUnionSelect extends BaseModel { public class RecuperationLineSelect extends BaseModel {
@Name @Name
@Comment("id") @Comment("id")
@@ -0,0 +1,114 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName RecuperationEnrollService
* @Author JyuHsin
* @Date 2025/8/18 14:56
* @Version 1.0
* @Description TODO
*/
public interface RecuperationEnrollService extends BaseService<RecuperationEnroll> {
/**
* 报名页面数据
*
* @param pageForm 分页参数
* @param trrt trrt
* @return {@link Pagination}
*/
Pagination enrollPageData(PageForm pageForm, Integer year, String unionId, int trrt, Integer lineUnionType);
List<NutMap> getSelectLineById(String lineId, String unionId, int trrt, Integer lineUnionType);
/**
* 线路报名
*
* @param enrollInfo 登记信息
*/
void doSignUpForLine(RecuperationEnroll enrollInfo);
/**
* 变更报名
*
* @param enrollInfo 登记信息
*/
void updateSignUpLine(RecuperationEnroll enrollInfo);
/**
* 报名旅行社
*
* @param enrollInfo 登记信息
*/
void doSignUpForTravelAgency(RecuperationEnroll enrollInfo);
/**
* 报名酒店
*
* @param enrollInfo 登记信息
*/
void doSignUpForHotel(RecuperationEnroll enrollInfo);
void updateSignUpHotel(RecuperationEnroll enrollInfo);
/**
* 变更报名旅行社
*
* @param enrollInfo 登记信息
*/
void updateSignUpTravelAgency(RecuperationEnroll enrollInfo);
/**
* 验证报名登记信息
*
* @param enrollInfo 登记信息
* @param loginName 用户名
* @return {@link Map}<{@link Boolean}, {@link String}>
*/
Map<Boolean, String> validSignUpInfo(String loginName, RecuperationEnroll 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 RecuperationEnroll}
*/
RecuperationEnroll findSignUpInfoById(String id);
/**
* 删除我的报名信息
*
* @param id id
*/
void deleteMyEnrollInfoById(String id);
/**
* 手机端线路介绍所有信息
*
* @param usId usId
* @param usUnionId usUnionId
* @return {@link NutMap}
*/
NutMap selectLineAllInfo(String usId, String usUnionId);
List<Sys_union> getUnions(Integer year);
}
@@ -0,0 +1,70 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLineSelect;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.util.List;
/**
* @ClassName RecuperationLineUnionSelectService
* @Author JyuHsin
* @Date 2025/8/18 15:54
* @Version 1.0
* @Description TODO
*/
public interface RecuperationLineSelectService extends BaseService<RecuperationLineSelect> {
/**
* 页面数据
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
Pagination pageData(PageForm pageForm, Cnd cnd, Integer year);
/**
* 选择线路
* @param us 分工会选择线路信息
*/
void selectLine(RecuperationLineSelect us);
/**
* 已经选择的线路ids
*
* @return {@link List}<{@link String}>
*/
List<String> getHasSelectLineIds();
/**
* 设置的活动时间信息
*
* @param lineId 行id
* @return {@link Object}
*/
Object selectLineInfo(String lineId, String unionId,Integer mode, Integer year);
/**
* 设置线路时间信息
* @param lineSelect 联盟选择
*/
void setLineInfo(RecuperationLineSelect lineSelect);
/**
* 查询某个分工会设置的线路时间信息
* @param lineId 行id
* @param usUnionId 我们工会id
* @return {@link NutMap}
*/
RecuperationLineSelect findUsLineInfo(String lineId, String usUnionId);
/**
* 分工会取消选择线路
*
* @param usId union_select 主键id
*/
void deSelect(String usId);
}
@@ -0,0 +1,934 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.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.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.staffbenefit.recuperation.constant.*;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.*;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineService;
import lombok.extern.slf4j.Slf4j;
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.entity.Record;
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 java.time.LocalDate;
import java.time.Period;
import java.util.*;
import java.util.stream.Collectors;
/**
* @ClassName RecuperationEnrollServiceImpl
* @Author JyuHsin
* @Date 2025/8/18 14:56
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean(args = {"refer:dao"})
public class RecuperationEnrollServiceImpl extends BaseServiceImpl<RecuperationEnroll> implements RecuperationEnrollService {
@Inject
private RecuperationLineService lineService;
public RecuperationEnrollServiceImpl(Dao dao) {
super(dao);
}
static Map<String, RecuperationType> regionTypeLineMap = new HashMap<>() {{
put(RecuperationType.provinceOutLine.getRegionType(), RecuperationType.provinceOutLine);
put(RecuperationType.provinceInLine.getRegionType(), RecuperationType.provinceInLine);
}};
@Override
public Pagination enrollPageData(PageForm pageForm, Integer year, String unionId, int trrt, Integer lineUnionType) {
Cnd cnd = Cnd.NEW();
if (List.of(RecuperationType.provinceInLine.getValue(), RecuperationType.provinceOutLine.getValue()).contains(trrt)) {
Sql lineSql = Sqls.create("""
SELECT
us.id as usId,
line.id as lineId,
line.serialNumber,
line.lineName,
line.regionalNature,
us.minimumGroupSize,
line.`year`,
us.enable,
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.playStartTime,
us.playEndTime,
us.signUpMode,
us.estimatedFamilyNumbers,
line.file AS fileId,
usgh.name AS usUnionName,
usgh.id AS takePartInUnionId,
u.username AS createUserName,
ta.travelAgencyName,
ta.contact,
ta.contactMobileNumber,
lot.lotName,
lot.lotValue,
lot.activityCost as lotActivityCost,
count(us.id) as playCount,
(select count(1) from recuperation_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 signUpUserNum,
(select count(1) from recuperation_enroll_companion where trreId in (select id from recuperation_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 signUpUserFamilyNum,
(select ifnull(sum(familyNumber),0) from recuperation_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
`recuperation_line_select` us
LEFT JOIN recuperation_line line ON line.id = us.lineId
LEFT JOIN recuperation_lot lot on lot.id = line.lotId
LEFT JOIN sys_union usgh ON usgh.id = us.unionId
LEFT JOIN sys_user u ON u.id = line.opBy
LEFT JOIN recuperation_travel_agency ta ON ta.id = line.travelAgencyId
$lineCnd
group by lineId
ORDER BY lotValue desc, us.lineId, playStartTime ASC
""").setParam("year", DateUtil.thisYear());
Cnd lineCnd = Cnd.NEW();
lineCnd.and("line.isDisabled", "=", false);
lineCnd.and("us.enable", "=", true);
lineCnd.and("line.regionalNature", "=", RecuperationType.typeMap.get(trrt));
lineCnd.andEX("year(us.selectTime)", "=", year != null ? year : DateUtil.thisYear());
//本公会
if (lineUnionType == 1) {
lineCnd.and("us.signUpMode", "=", RecuperationSignUpMode.UNION.getValue());
// lineCnd.and("us.isOpen", "=", true);
lineCnd.and("us.unionId", "=", unionId);
} else if (lineUnionType == 2) {
lineCnd.and("us.signUpMode", "=", RecuperationSignUpMode.UNION.getValue());
lineCnd.and("us.isOpen", "=", true);
lineCnd.and("us.unionId", "=", unionId);
} else if (lineUnionType == 3) {
//校工会
lineCnd.and("us.signUpMode", "=", RecuperationSignUpMode.FREE.getValue());
}
lineSql.setVar("lineCnd", lineCnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), lineSql);
} else if (RecuperationType.provinceInTravelAgency.getValue() == trrt) {
cnd.andEX("year", "=", year != null ? year : DateUtil.thisYear());
cnd.and("isDisabled", "=", false);
Sql taSql = Sqls.create("""
select
*,
file as fileId
from
recuperation_travel_agency $condition
""");
taSql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), taSql);
} else if (RecuperationType.provinceInHotel.getValue() == trrt) {
cnd.andEX("b.year", "=", year != null ? year : DateUtil.thisYear());
cnd.and("b.isDisabled", "=", false);
Sql taSql = Sqls.create("""
select
b.*,
b.file as fileId,
l.lotName,
t.travelAgencyName
from
recuperation_base_management b
left join recuperation_lot l on l.id = b.lotId
left join recuperation_travel_agency t on t.id = b.travelAgencyId
$condition
""");
cnd.asc("sortNumber");
taSql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), taSql);
}
return new Pagination();
}
@Override
public List<NutMap> getSelectLineById(String lineId, String unionId, int trrt, Integer lineUnionType) {
Sql lineSql = Sqls.create("""
SELECT
us.id as usId,
line.id as lineId,
line.serialNumber,
line.lineName,
line.regionalNature,
us.minimumGroupSize,
line.`year`,
us.enable,
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.playStartTime,
us.playEndTime,
us.signUpMode,
us.estimatedFamilyNumbers,
line.files,
line.file AS fileId,
usgh.name AS usUnionName,
usgh.id AS takePartInUnionId,
u.username AS createUserName,
ta.travelAgencyName,
us.contact,
us.contactPhone,
lot.lotName,
lot.lotValue,
lot.activityCost as lotActivityCost,
(select count(1) from recuperation_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 signUpUserNum,
(select count(1) from recuperation_enroll_companion where trreId in (select id from recuperation_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 signUpUserFamilyNum,
(select ifnull(sum(familyNumber),0) from recuperation_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
`recuperation_line_select` us
LEFT JOIN recuperation_line line ON line.id = us.lineId
LEFT JOIN recuperation_lot lot on lot.id = line.lotId
LEFT JOIN sys_union usgh ON usgh.id = us.unionId
LEFT JOIN sys_user u ON u.id = line.opBy
LEFT JOIN recuperation_travel_agency ta ON ta.id = line.travelAgencyId
$lineCnd
ORDER BY us.lineId, playStartTime ASC
""").setParam("lineId", lineId).setParam("year", DateUtil.thisYear());
Cnd lineCnd = Cnd.NEW();
lineCnd.and("lineId", "=", lineId);
lineCnd.and("us.enable", "=", true);
lineCnd.and("year(us.selectTime)", "=", DateUtil.thisYear());
lineCnd.and("line.regionalNature", "=", RecuperationType.typeMap.get(trrt));
//本公会
if (lineUnionType == 1) {
lineCnd.and("us.signUpMode", "=", RecuperationSignUpMode.UNION.getValue());
// lineCnd.and("us.isOpen", "=", true);
lineCnd.and("us.unionId", "=", unionId);
} else if (lineUnionType == 2) {
lineCnd.and("us.signUpMode", "=", RecuperationSignUpMode.UNION.getValue());
lineCnd.and("us.isOpen", "=", true);
lineCnd.and("us.unionId", "=", unionId);
} else if (lineUnionType == 3) {
//校工会
lineCnd.and("us.signUpMode", "=", RecuperationSignUpMode.FREE.getValue());
}
lineSql.setVar("lineCnd", lineCnd);
return (List<NutMap>) Daos.query(dao(), lineSql.toString(), Sqls.callback.maps());
}
/**
* 线路报名
*
* @param enrollInfo 登记信息
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void doSignUpForLine(RecuperationEnroll enrollInfo) {
RecuperationLineSelect lineUnionSelect = dao().fetch(RecuperationLineSelect.class, enrollInfo.getTakePartInLineId());
RecuperationLine lineInfo = dao().fetch(RecuperationLine.class, lineUnionSelect.getLineId());
Sys_user user = dao().fetch(Sys_user.class, SecurityUtil.getUserId());
enrollInfo.setLoginName(user.getLoginname());
enrollInfo.setUserName(user.getUsername());
enrollInfo.setSex(user.getSex());
enrollInfo.setUnitName(user.getUnit().getName());
enrollInfo.setUnionName(SecurityUtil.getUnionId());
enrollInfo.setSelfUnionId(user.getUnion().getId());
enrollInfo.setSelfUnitId(SecurityUtil.getUnitId());
enrollInfo.setSigningUptime(new Date());
enrollInfo.setTakePartIn(false);
enrollInfo.setNormal(true);
if (lineUnionSelect.getSignUpMode() == RecuperationSignUpMode.FREE.getValue()) {
enrollInfo.setTakePartInUnionId(null);
}
//2023-06-07 省内外线路是否需要审核配置 根据配置来赋报名表的审核状态值☞
RecuperationConfig recuperationConfig = dao().fetch(RecuperationConfig.class, Cnd.NEW());
Boolean isSnLine = recuperationConfig.getIsSnLine();
Boolean isSwLine = recuperationConfig.getIsSwLine();
Boolean flag = null;
if (lineInfo.getRegionalNature().equals(RecuperationProvinceType.provinceOut.getValue())) {
flag = isSwLine;
} else if (lineInfo.getRegionalNature().equals(RecuperationProvinceType.provinceIn.getValue())) {
flag = isSnLine;
}
if (Boolean.TRUE.equals(flag)) {
if (lineUnionSelect.getSignUpMode() == 1) {
if (StrUtil.isNotBlank(enrollInfo.getTakePartInUnionId()) && !enrollInfo.getTakePartInUnionId().equals(enrollInfo.getSelfUnionId())) {
enrollInfo.setStateId(RecuperationState.LINEUNIT);
} else {
enrollInfo.setStateId(RecuperationState.UNIT);
}
} else {
enrollInfo.setStateId(RecuperationState.SCHOOL);
}
} else {
enrollInfo.setStateId(RecuperationState.PASS);
}
if (recuperationConfig.getBedInfo() || recuperationConfig.getFamilyInfo() == 2) {
for (RecuperationEnrollCompanion RecuperationEnrollCompanion : enrollInfo.getCompanionList()) {
insertLinks(RecuperationEnrollCompanion, "bedInfo");
}
insertWith(enrollInfo, "companionList|bedInfo");
} else {
insert(enrollInfo);
}
//String content = "【智慧工会】%s老师您好,您已成功报名%s疗休养线路".formatted(user.getUsername(), lineInfo.getLineName());
//msgApi.sendMsg(content, user.getMobile(), MsgApi.DING_DING_TEMPLATE_ID);
//发短信
// RCSCloudAPI.sendTplSms("81d48e1811144270b838b321575c7199", user.getMobile(), "@1@=" + user.getUsername() + "||@2@=报名||@3@=" + lineInfo.getLineName(), "");
}
/**
* 变更报名
*
* @param enrollInfo 登记信息
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void updateSignUpLine(RecuperationEnroll enrollInfo) {
RecuperationLineSelect lineUnionSelect = dao().fetch(RecuperationLineSelect.class, enrollInfo.getTakePartInLineId());
RecuperationConfig recuperationConfig = dao().fetch(RecuperationConfig.class, Cnd.NEW());
if (lineUnionSelect.getSignUpMode() == RecuperationSignUpMode.FREE.getValue()) {
enrollInfo.setTakePartInUnionId(null);
}
if (recuperationConfig.getBedInfo() || recuperationConfig.getFamilyInfo() == 2) {
dao().clearLinks(enrollInfo, "companionList");
dao().delete(RecuperationEnrollBed.class, enrollInfo.getBedInfoId());
dao().insertLinks(enrollInfo, "companionList|bedInfo");
}
update(enrollInfo);
//插入变更记录
RecuperationEnrollChangeRecord changeRecord = new RecuperationEnrollChangeRecord();
changeRecord.setEnrollId(enrollInfo.getId());
changeRecord.setChangeTime(new Date());
insert(changeRecord);
//发短信
//String content = "【智慧工会】%s老师您好,您的疗休养线路已成功修改为%s".formatted(user.getUsername(), lineInfo.getLineName());
//msgApi.sendMsg(content, user.getMobile(), MsgApi.DING_DING_TEMPLATE_ID);
// RCSCloudAPI.sendTplSms("81d48e1811144270b838b321575c7199", user.getMobile(), "@1@=" + user.getUsername() + "||@2@=修改||@3@=" + lineInfo.getLineName(), "");
}
/**
* 报名旅行社
*
* @param enrollInfo 登记信息
*/
@Override
public void doSignUpForTravelAgency(RecuperationEnroll enrollInfo) {
Sys_user user = dao().fetch(Sys_user.class, SecurityUtil.getUserId());
enrollInfo.setLoginName(user.getLoginname());
enrollInfo.setUserName(user.getUsername());
enrollInfo.setSex(user.getSex());
enrollInfo.setUnitName(user.getUnit().getName());
enrollInfo.setUnionName(user.getUnion().getName());
enrollInfo.setSelfUnionId(user.getUnion().getId());
enrollInfo.setSelfUnitId(user.getUnitId());
enrollInfo.setSigningUptime(new Date());
enrollInfo.setTakePartIn(false);
enrollInfo.setNormal(true);
insert(enrollInfo);
}
/**
* 报名酒店
*
* @param enrollInfo 登记信息
*/
@Override
public void doSignUpForHotel(RecuperationEnroll enrollInfo) {
Sys_user user = dao().fetch(Sys_user.class, SecurityUtil.getUserId());
enrollInfo.setLoginName(user.getLoginname());
enrollInfo.setUserName(user.getUsername());
enrollInfo.setSex(user.getSex());
enrollInfo.setUnitName(user.getUnit().getName());
enrollInfo.setUnionName(user.getUnion().getName());
enrollInfo.setSelfUnionId(user.getUnion().getId());
enrollInfo.setSelfUnitId(user.getUnitId());
enrollInfo.setSigningUptime(new Date());
enrollInfo.setTakePartIn(false);
enrollInfo.setNormal(true);
enrollInfo.setStateId(RecuperationState.PASS);
for (RecuperationEnrollCompanion RecuperationEnrollCompanion : enrollInfo.getCompanionList()) {
insertLinks(RecuperationEnrollCompanion, "bedInfo");
}
insertWith(enrollInfo, "companionList|bedInfo");
}
/**
* 变更报名
*
* @param enrollInfo 登记信息
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void updateSignUpHotel(RecuperationEnroll enrollInfo) {
dao().clearLinks(enrollInfo, "companionList");
dao().delete(RecuperationEnrollBed.class, enrollInfo.getBedInfoId());
dao().insertLinks(enrollInfo, "companionList|bedInfo");
update(enrollInfo);
//插入变更记录
RecuperationEnrollChangeRecord changeRecord = new RecuperationEnrollChangeRecord();
changeRecord.setEnrollId(enrollInfo.getId());
changeRecord.setChangeTime(new Date());
insert(changeRecord);
}
/**
* 变更报名旅行社
*
* @param enrollInfo 登记信息
*/
@Override
public void updateSignUpTravelAgency(RecuperationEnroll enrollInfo) {
updateIgnoreNull(enrollInfo);
}
/**
* 验证报名登记信息
*
* @param enrollInfo 登记信息
* @param loginName 用户名
* @return {@link Map}<{@link Boolean}, {@link String}>
*/
@Override
public Map<Boolean, String> validSignUpInfo(String loginName, RecuperationEnroll enrollInfo) {
//配置信息
RecuperationConfig config = dao().fetch(RecuperationConfig.class);
Sys_user user = dao().fetch(Sys_user.class, Cnd.where("loginname", "=", loginName));
//判断是否在报名范围内
int count = dao().count("activity_user_scope", Cnd.NEW().and("groupId", "=", config.getActivityGroupId())
.and("userId", "=", user.getId() ));
if (count == 0) {
return Map.of(false, "抱歉,您不在报名范围内!");
}
//每年旅行频率
Integer travelFrequency = config.getTravelFrequency();
//省外几年去一次
Integer outsideNumber = config.getOutsideNumber();
//可以修改几次
Integer modifyNumber = config.getModifyNumber();
//省外最多报名人数
Integer allLineSignUpNumber = config.getAllLineSignUpNumber();
//省内起始年份
Integer provinceStartYear = config.getProvinceStartYear();
//活动范围
Integer activityGroupId = config.getActivityGroupId();
//线路信息
RecuperationLineSelect lineUnionSelect = dao().fetch(RecuperationLineSelect.class, enrollInfo.getTakePartInLineId());
RecuperationLine lineInfo = dao().fetch(RecuperationLine.class, lineUnionSelect.getLineId());
Date signUpStartTime = lineUnionSelect.getSignUpStartTime();
Date signUpEndTime = lineUnionSelect.getSignUpEndTime();
Date changeEndTime = lineUnionSelect.getChangeEndTime();
//线路人数,省外线路最多报名数
// Integer estimatedFamilyNumbers = lineUnionSelect.getEstimatedFamilyNumbers();
Integer estimatedFamilyNumbers = config.getOutsideQuota();
if (DateUtil.compare(new Date(), signUpStartTime) < 0) {
return Map.of(false, "报名未开始,请耐心等待");
}
if (DateUtil.compare(new Date(), changeEndTime) > 0 && enrollInfo.isNormal()) {
return Map.of(false, "报名时间已过,抱歉不能报名");
}
RecuperationType trrt = regionTypeLineMap.get(lineInfo.getRegionalNature());
if (StrUtil.isBlank(enrollInfo.getId()) && StrUtil.isNotBlank(enrollInfo.getTakePartInLineId())) {
//2025-05-20 临时增加的代码
Record tempRecord = dao().fetch("recuperation_temp", Cnd.where("loginname", "=", loginName));
if(tempRecord != null) {
if(tempRecord.getInt("flag") != trrt.getValue()) {
return Map.of(false, "您只能报名" + tempRecord.getString("type") + "线路");
}
}
//获取标段中的最大费用
List<RecuperationLot> lotList = dao().query(RecuperationLot.class, Cnd.NEW());
//最大费用
OptionalInt optionalInt = lotList.stream().mapToInt(RecuperationLot::getActivityCost).max();
int maxCost = optionalInt.isPresent() ? optionalInt.getAsInt() : 0;
//获取当前报名线路对应的标段的费用
Integer currentLineCost = dao().fetch(RecuperationLot.class, lineInfo.getLotId()).getActivityCost();
//省外线路判断报名人数
if (trrt.getValue() == RecuperationType.provinceOutLine.getValue() && estimatedFamilyNumbers != null) {
Map<Boolean, String> map = validSignCount(enrollInfo, config, estimatedFamilyNumbers, "add");
if(map != null) {
return map;
}
}
//获取起始年份到当前时间,是否报名
Sql sql = Sqls.create("""
SELECT
r.*,
l.regionalNature,
(select activityCost from recuperation_lot where id = l.lotId) as activityCost
FROM
recuperation_enroll r
LEFT JOIN recuperation_line_select us on us.id = r.takePartInLineId
LEFT JOIN recuperation_line l ON l.id = us.lineId
$condition
""");
Sql twoYearInSql = sql;
Sql threeYearOutSql = sql;
Sql twoYearOutSql = sql;
Sql nowYearSql = sql;
Cnd commonCnd = Cnd.NEW();
commonCnd.and("r.takePartInLineId", "is not", null);
commonCnd.and("loginName", "=", SecurityUtil.getUserLoginname());
commonCnd.and("r.isNormal", "=", true);
commonCnd.and("stateId", "not in", Lang.array(RecuperationState.UNITFAIL, RecuperationState.LINEUNITFAIL, RecuperationState.SCHOOLFAIL));
commonCnd.and("signingUptime", "<=", DateUtil.now());
//两年参加省内
Cnd twoYearInCnd = commonCnd.clone();
twoYearInCnd.and("signingUptime", ">=", provinceStartYear + "-01-01");
twoYearInCnd.and("regionalNature", "=", "省内");
twoYearInCnd.and("isTakePartIn", "=", true);
twoYearInSql.setCondition(twoYearInCnd);
List<NutMap> twoYearInMapList = listMap(twoYearInSql);
//今年是否报名,不管省内省外
Cnd nowYearCnd = commonCnd.clone();
nowYearCnd.and("signingUptime", ">=", DateUtil.thisYear() + "-01-01");
nowYearSql.setCondition(nowYearCnd);
List<NutMap> nowYearMapList = listMap(nowYearSql);
//两年参加省外
Cnd twoYearOutCnd = commonCnd.clone();
twoYearOutCnd.and("signingUptime", ">=", provinceStartYear + "-01-01");
twoYearOutCnd.and("regionalNature", "=", "省外");
twoYearOutCnd.and("isTakePartIn", "=", true);
twoYearOutSql.setCondition(twoYearOutCnd);
List<NutMap> twoYearOutMapList = listMap(twoYearOutSql);
//三年参加省外
Cnd threeYearOutCnd = commonCnd.clone();
threeYearOutCnd.and("signingUptime", ">=", (DateUtil.thisYear() - 3) + "-01-01");
threeYearOutCnd.and("regionalNature", "=", "省外");
threeYearOutCnd.and("isTakePartIn", "=", true);
threeYearOutSql.setCondition(threeYearOutCnd);
List<NutMap> threeYearOutMapList = listMap(threeYearOutSql);
//今年是否报名,不管报省内还是省外
if (nowYearMapList.size() > 0) {
NutMap nowYearMap = nowYearMapList.get(0);
//判断当前报名的线路是否和今年第一次报名的线路重复
if (nowYearMap.getString("takePartInLineId").equals(lineUnionSelect.getId())) {
return Map.of(false, "您已报名过当前线路,请选择其他线路");
}
//获取第一次报名线路对应的标段的费用
int lastLineCost = nowYearMap.getInt("activityCost");
if ((lastLineCost + currentLineCost) > maxCost) {
return Map.of(false, "您已报名过省内或省外线路");
}
}
//省内线路判断
if (trrt.getValue() == RecuperationType.provinceInLine.getValue()) {
if (twoYearInMapList.size() == 0 && threeYearOutMapList.size() == 0) {
return Map.of(true, "验证成功");
}
//查询两年内有没有参加过省外
if (twoYearOutMapList.size() > 0) {
return Map.of(false, "您近两年已参加过省外线路,不能报名省内线路");
}
if (twoYearInMapList.size() > 0) {
int hasCost = twoYearInMapList.get(0).getInt("activityCost");
if ((hasCost + currentLineCost) > maxCost) {
return Map.of(false, "您已参加过省内线路");
}
}
}
//省外线路判断
if (trrt.getValue() == RecuperationType.provinceOutLine.getValue()) {
//两年内参加过省内
if (twoYearInMapList.size() > 0) {
return Map.of(false, "您近两年已参加过省内线路,不能报名省外线路");
}
//三年内有没有参加过省外
if (threeYearOutMapList.size() > 0) {
return Map.of(false, "近三年内您已参加过省外线路,不能再次报名");
}
//获取今年的所有线路
List<RecuperationLine> lineList = dao().query(RecuperationLine.class, Cnd.where("year", "=", DateUtil.thisYear())
.and("isDisabled", "=", false));
List<String> lineIds = lineList.stream().map(RecuperationLine::getId).collect(Collectors.toList());
//获取这些线路在选择表中的选择id,因为报名表存的是选择id
List<RecuperationLineSelect> selectList = dao().query(RecuperationLineSelect.class, Cnd.where("lineId", "in", lineIds));
List<String> selectIds = selectList.stream().map(RecuperationLineSelect::getId).collect(Collectors.toList());
//获取这些省外线路的总报名人数
List<RecuperationEnroll> enrollList = dao().query(RecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds)
.and("isNormal", "=", true).and("signingUptime", "=", DateUtil.thisYear())
.and("stateId", "not in", Lang.array(RecuperationState.UNITFAIL, RecuperationState.LINEUNITFAIL, RecuperationState.SCHOOLFAIL)));
//活动范围总人数
List<ActivityUserScope> userScopes = dao().query(ActivityUserScope.class, Cnd.where("groupId", "=", activityGroupId));
int result = (int) Math.floor((double) userScopes.size() / 3);
if (enrollList.size() >= result) {
return Map.of(false, "已报人数超过三分之一,不能报名");
}
}
}
//变更操作
if (StrUtil.isNotBlank(enrollInfo.getId())) {
if (trrt.getValue() == RecuperationType.provinceOutLine.getValue() && estimatedFamilyNumbers != null) {
Map<Boolean, String> map = validSignCount(enrollInfo, config, estimatedFamilyNumbers, "edit");
if(map != null) {
return map;
}
}
int changeCount = dao().count(RecuperationEnrollChangeRecord.class, Cnd.where("enrollId", "=", enrollInfo.getId()));
if (changeCount >= modifyNumber) {
return Map.of(false, "只能变更" + changeCount + "次!");
}
if (DateUtil.compare(new Date(), changeEndTime) > 0) {
return Map.of(false, "超过变更截至时间,无法变更!");
} else {
return Map.of(true, "验证成功");
}
}
return Map.of(true, "验证成功");
}
public Map<Boolean, String> validSignCount(RecuperationEnroll enrollInfo, RecuperationConfig config, int estimatedFamilyNumbers, String type) {
int hasSignNumber = 0;//已经报名的人数
int currentSignNumber = 1;//当前报名人数,1表示自己,下面的if是加家属人数
Cnd cnd = Cnd.where("takePartInLineId", "=", enrollInfo.getTakePartInLineId())
.and("stateId", "in", Lang.array(RecuperationState.UNIT, RecuperationState.LINEUNIT, RecuperationState.SCHOOL, RecuperationState.PASS))
.and("isNormal", "=", true);
//如果是修改,排除自己的报名记录
if("edit".equals(type)) {
cnd.and("loginName", "!=", SecurityUtil.getUserLoginname());
}
List<RecuperationEnroll> enrolls = dao().query(RecuperationEnroll.class, cnd);
//1表示在配置页面的家属配置的是数量,2是家属的List
/*if (config.getFamilyInfo() == 1) {
currentSignNumber += enrollInfo.getFamilyNumber() != null ? enrollInfo.getFamilyNumber() : 0;
int sum = enrolls.stream().mapToInt(RecuperationEnroll::getFamilyNumber).sum();
hasSignNumber = enrolls.size() + sum;
} else {
currentSignNumber += enrollInfo.getCompanionList() != null ? enrollInfo.getCompanionList().size() : 0;
List<String> list = enrolls.stream().map(RecuperationEnroll::getId).collect(Collectors.toList());
List<RecuperationEnrollCompanion> companions = dao().query(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", list));
hasSignNumber = enrolls.size() + companions.size();
}*/
//省外报名限制,不包含家属
// hasSignNumber += currentSignNumber + enrolls.size();
if (( currentSignNumber + enrolls.size()) > estimatedFamilyNumbers) {
return Map.of(false, "报名人数已满");
} else {
return null;
}
}
//判断一年报几次
public Map<Boolean, String> validCountOneYear(String loginName, int travelFrequency) {
Cnd cnd = Cnd.NEW();
cnd.and("loginName", "=", loginName);
cnd.and("YEAR(signingUptime)", "=", DateUtil.thisYear());
int joinCount = dao().count(RecuperationEnroll.class, cnd);
if (joinCount >= travelFrequency) {
List<RecuperationLine> inList = dao().query(RecuperationLine.class, Cnd.where("regionalNature", "=", "省内"));
List<RecuperationLine> outList = dao().query(RecuperationLine.class, Cnd.where("regionalNature", "=", "省外"));
//是否选择省外
int inCount = dao().count("recuperation_enroll", Cnd.where("loginName", "=", SecurityUtil.getUserLoginname())
.and("takePartInLineId", "in", inList.stream().map(RecuperationLine::getId).collect(Collectors.toList()))
.and("isNormal", "=", true)
.and("YEAR(signingUptime)", "=", DateUtil.thisYear()));
//是否报省外
int outCount = dao().count("recuperation_enroll", Cnd.where("loginName", "=", SecurityUtil.getUserLoginname())
.and("takePartInLineId", "in", outList.stream().map(RecuperationLine::getId).collect(Collectors.toList()))
.and("isNormal", "=", true)
.and("YEAR(signingUptime)", "=", DateUtil.thisYear()));
//是否报旅行社
int travelCount = dao().count("recuperation_enroll", Cnd.where("loginName", "=", SecurityUtil.getUserLoginname())
.and("takePartInLineId", "is", null).and("isNormal", "=", true)
.and("takePartInTravelAgencyId", "is not", null)
.and("YEAR(signingUptime)", "=", DateUtil.thisYear()));
//是否报酒店
int hotelCount = dao().count("recuperation_enroll", Cnd.where("loginName", "=", SecurityUtil.getUserLoginname())
.and("takePartInLineId", "is", null).and("isNormal", "=", true)
.and("takePartInBaseManagementId", "is not", null)
.and("YEAR(signingUptime)", "=", DateUtil.thisYear()));
String str = "";
if (inCount > 0) {
str = "省内线路";
} else if (outCount > 0) {
str = "省外线路";
} else if (travelCount > 0) {
str = "旅行社";
} else if (hotelCount > 0) {
str = "酒店";
}
return Map.of(false, "一年只能报" + travelFrequency + "次,您已报" + str + ",请先在我的疗休养中删除,方可报名!");
}
return Map.of(true, "成功");
}
public int getCountByOutLine(RecuperationType trrt, String loginName, int outsideNumber) {
//省外 outsideNumber 年内是否去过
if (trrt.getValue() == RecuperationType.provinceOutLine.getValue()) {
Sql lineJoinSql = Sqls.create("""
SELECT
count(*)
FROM
recuperation_enroll ren
LEFT JOIN recuperation_line rl on ren.takePartInLineId = rl.id
$condition
""");
Cnd lineCnd = Cnd.NEW();
lineCnd.and("loginName", "=", loginName);
lineCnd.and("isNormal", "=", true);
lineCnd.and("takePartInLineId", "IS NOT", null);
lineCnd.and("YEAR ( signingUptime )", ">=", DateUtil.thisYear() - outsideNumber);
lineCnd.and("YEAR ( signingUptime )", "<=", DateUtil.thisYear() - 1);
lineCnd.and("regionalNature", "=", RecuperationType.provinceOutLine.getValue());
lineJoinSql.setCondition(lineCnd);
//lineCnd.and(new SqlExpressionGroup().andBetween("YEAR(signingUptime)", io.v.nutz.base.utils.DateUtil.getYear() - 1, io.v.nutz.base.utils.DateUtil.getYear() - outsideNumber));
return lineService.count(lineJoinSql);
}
return 0;
}
/**
* 我报名的页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
@Override
public Pagination mySignUpPageData(PageForm pageForm, Cnd cnd, int trrt, Integer year) {
if (List.of(
RecuperationType.provinceInLine.getValue(),
RecuperationType.provinceOutLine.getValue()
).contains(trrt)) {
return this.getDataByInLineAndOutLine(pageForm, cnd, trrt, year);
} else if (trrt == RecuperationType.provinceInTravelAgency.getValue()) {
return this.getDataByInTravelAgency(pageForm, cnd, trrt, year);
} else if (trrt == RecuperationType.provinceInHotel.getValue()) {
return this.getDataByInHotel(pageForm, cnd, trrt, year);
}
return null;
}
public Pagination getDataByInLineAndOutLine(PageForm pageForm, Cnd cnd, int trrt, Integer year) {
Sql lineSql = Sqls.create("""
SELECT
e.*,
line.serialNumber,
line.lineName,
line.regionalNature,
line.YEAR,
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.playStartTime,
us.playEndTime,
us.signUpMode,
line.file AS fileId,
gh.name AS signUpUnionName,
ta.travelAgencyName,
ta.contact,
ta.contactMobileNumber,
ta.officialWebsite,
GROUP_CONCAT(ec.userName) as companionUserNames,
l.lotName
FROM
recuperation_enroll e
LEFT JOIN sys_union gh ON gh.id = e.takePartInUnionId
LEFT JOIN recuperation_line_select us on us.id = e.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = us.lineId
LEFT JOIN recuperation_travel_agency ta ON ta.id = line.travelAgencyId
left join recuperation_enroll_companion ec on ec.trreId = e.id
left join recuperation_lot l on l.id = line.lotId
$condition
GROUP BY e.id
""");
cnd.and("line.regionalNature", "=", RecuperationType.typeMap.get(trrt));
cnd.and("e.isNormal", "=", true);
cnd.andEX("year(e.signingUptime)", "=", year);
lineSql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), lineSql);
}
public Pagination getDataByInTravelAgency(PageForm pageForm, Cnd cnd, int trrt, Integer year) {
Sql taSql = Sqls.create("""
SELECT
e.*,
ta.travelAgencyName,
ta.contact,
ta.contactMobileNumber,
ta.officialWebsite,
ta.file AS fileId
FROM
recuperation_enroll e
LEFT JOIN recuperation_travel_agency ta ON ta.id = e.takePartInTravelAgencyId
$condition
""");
cnd.and("e.takePartInTravelAgencyId", "is not", null);
cnd.and("e.isNormal", "=", true);
cnd.andEX("ta.year", "=", year);
taSql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), taSql);
}
public Pagination getDataByInHotel(PageForm pageForm, Cnd cnd, int trrt, Integer year) {
Sql taSql = Sqls.create("""
SELECT
e.*,
ta.baseName,
ta.baseContactPerson,
ta.baseContactNumber,
ta.file AS fileId,
l.lotName,
ta.regionalNature,
t.travelAgencyName,
ta.changeEndTime
FROM
recuperation_enroll e
LEFT JOIN recuperation_base_management ta ON ta.id = e.takePartInBaseManagementId
LEFT JOIN recuperation_lot l on l.id = ta.lotId
LEFT JOIN recuperation_travel_agency t on t.id = ta.travelAgencyId
$condition
""");
cnd.and("e.takePartInBaseManagementId", "is not", null);
cnd.and("e.isNormal", "=", true);
cnd.andEX("ta.year", "=", year);
taSql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), taSql);
}
/**
* 找到报名信息通过id
*
* @param id id
* @return {@link RecuperationEnroll}
*/
@Override
public RecuperationEnroll findSignUpInfoById(String id) {
RecuperationEnroll enroll = fetch(id);
return fetchLinks(enroll, "companionList|bedInfo");
}
/**
* 删除我的报名信息
*
* @param id id
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void deleteMyEnrollInfoById(String id) {
RecuperationEnroll enrollInfo = fetch(id);
RecuperationLineSelect lineUnionSelect = dao().fetch(RecuperationLineSelect.class, enrollInfo.getTakePartInLineId());
dao().clearLinks(enrollInfo, "companionList|bedInfo");
delete(id);
dao().clear(RecuperationEnrollChangeRecord.class, Cnd.where("enrollId", "=", id));
//发短信
//String content = "【智慧工会】%s老师您好,您报名的%s疗休养线路已取消成功".formatted(user.getUsername(), lineInfo.getLineName());
//msgApi.sendMsg(content, user.getMobile(), MsgApi.DING_DING_TEMPLATE_ID);
// RCSCloudAPI.sendTplSms("81d48e1811144270b838b321575c7199", user.getMobile(), "@1@=" + user.getUsername() + "||@2@=取消||@3@=" + lineInfo.getLineName(), "");
}
/**
* 手机端线路介绍所有信息
*
* @param usId usId
* @param usUnionId usUnionId
* @return {@link NutMap}
*/
@Override
public NutMap selectLineAllInfo(String usId, String usUnionId) {
Sql usLineSql = Sqls.create("""
SELECT
us.id as usId,
line.id as lineId,
line.lineName,
line.regionalNature,
us.playStartTime,
us.playEndTime,
us.signUpStartTime,
us.signUpEndTime,
us.changeEndTime,
us.minimumGroupSize,
us.estimatedFamilyNumbers,
line.content,
l.lotName,
(select COUNT(1) FROM recuperation_enroll en WHERE isNormal=true AND en.loginName=@loginname and YEAR(en.signingUptime)=@year) isNormal,
(select COUNT(1) FROM recuperation_enroll en WHERE isNormal=false AND en.loginName=@loginname and YEAR(en.signingUptime)=@year) isNormalFalse,
(select count(1) from recuperation_enroll where takePartInLineId = us.id and if(us.signUpMode = 1, takePartInUnionId = us.unionId, 1=1) and isNormal = true and YEAR(signingUptime)=@year) as signUpUserNum,
(select count(1) from recuperation_enroll_companion where trreId in (select id from recuperation_enroll where takePartInLineId = us.id and if(us.signUpMode = 1, takePartInUnionId = us.unionId, 1=1) and isNormal = true and YEAR(signingUptime)=@year)) as signUpUserFamilyNum,
(select ifnull(sum(familyNumber),0) from recuperation_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,
ta.travelAgencyName,
ta.contactMobileNumber
FROM
`recuperation_line_select` us
LEFT JOIN recuperation_line line ON line.id = us.lineId
LEFT JOIN recuperation_travel_agency ta on ta.id = line.travelAgencyId
LEFT JOIN recuperation_lot l on l.id = line.lotId
WHERE if(us.signUpMode = 1, us.unionId = @usUnionId, 1=1) AND us.id = @id
""");
usLineSql.setParam("loginname", SecurityUtil.getUserLoginname());
usLineSql.setParam("year", DateUtil.thisYear());
usLineSql.setParam("usUnionId", usUnionId);
usLineSql.setParam("id", usId);
usLineSql.setCallback(Sqls.callback.map());
this.dao().execute(usLineSql);
return usLineSql.getObject(NutMap.class);
}
@Override
public List<Sys_union> getUnions(Integer year) {
//查询某个年份公开线路了的工会
List<RecuperationLineSelect> openList = dao().query(RecuperationLineSelect.class, Cnd.where("isOpen", "=", true)
.and("signUpMode", "=", 1).and("year(selectTime)", "=", DateUtil.thisYear()).and("unionId", "!=", SecurityUtil.getUnionId()));
// List<RecuperationLineSelect> openList = dao().query(RecuperationLineSelect.class,
// Cnd.where("signUpMode", "=", 1).and("year(selectTime)", "=", DateUtil.thisYear()));
if (Lang.isNotEmpty(openList)) {
List<String> unionIds = openList.stream().map(RecuperationLineSelect::getUnionId).distinct().collect(Collectors.toList());
return dao().query(Sys_union.class, Cnd.where("id", "in", unionIds));
}
return new ArrayList<>();
}
}
@@ -0,0 +1,271 @@
package com.budwk.app.zhgh.staffbenefit.recuperation.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLineSelect;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineSelectService;
import lombok.extern.slf4j.Slf4j;
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.util.NutMap;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName RecuperationLineSelectServiceImpl
* @Author JyuHsin
* @Date 2025/8/18 15:55
* @Version 1.0
* @Description TODO
*/
@Slf4j
@IocBean(args = {"refer:dao"})
public class RecuperationLineSelectServiceImpl extends BaseServiceImpl<RecuperationLineSelect> implements RecuperationLineSelectService {
public RecuperationLineSelectServiceImpl(Dao dao) {
super(dao);
}
/**
* 页面数据
*
* @param pageForm 分页参数
* @param cnd cnd
* @return {@link Pagination}
*/
@Override
public Pagination pageData(PageForm pageForm, Cnd cnd, Integer year) {
Sql sql = Sqls.create("""
select
line.id,
line.serialNumber,
line.lineName,
line.regionalNature,
line.minimumGroupSize,
line.year,
line.isDisabled,
line.createUnionId,
GROUP_CONCAT(us.playStartTime,'至',us.playEndTime) as playTimes,
us.signUpStartTime,
us.signUpEndTime,
us.playStartTime,
us.playEndTime,
us.changeEndTime,
us.isOpen,
us.signUpMode,
line.createMode,
gh.name AS createUnionName,
u.username AS createUserName,
ta.travelAgencyName,
ta.contact,
ta.contactMobileNumber,
ta.officialWebsite,
lot.lotName,
us.unionId as usUnionId,
us.id as usId,
usUnion.name as belongUnionName,
(SELECT COUNT(*) FROM recuperation_enroll WHERE takePartInLineId=line.id AND takePartInUnionId=@unionId) applyCount
from
recuperation_line line
LEFT JOIN recuperation_travel_agency ta on ta.id = line.travelAgencyId
LEFT JOIN sys_union gh ON gh.id = line.createUnionid
LEFT JOIN sys_user u ON u.id = line.createdBy
LEFT JOIN recuperation_line_select us on us.lineId = line.id and year(selectTime) = @year $us
LEFT JOIN sys_union usUnion on usUnion.id = us.unionId
LEFT JOIN recuperation_lot lot on lot.id = line.lotId
$condition
""");
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
sql.setVar("us", "AND us.unionId = '%s' AND us.selectUserId = '%s'".formatted(SecurityUtil.getUnionId(), SecurityUtil.getUserId()));
}
//sql.setParam("unionId", Vi.getUnionId());
//sql.setParam("userId", ShiroUtil.getPrincipalProperty("id"));
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
/*SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("line.createUnionId", "=", Vi.getUnionId());
seg.or("line.createMode", "=", RecuperationLineCreateMode.SCHOOL.getValue());
cnd.and(seg);*/
cnd.groupBy("line.id");
sql.setCondition(cnd);
Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> list = pagination.getList();
List<String> hasSelectLineIds = getHasSelectLineIds();
for (NutMap m : list) {
m.setv("isSelect", hasSelectLineIds.contains(m.getString("id")));
}
return pagination;
}
/**
* 选择线路
*
* @param us 分工会选择线路信息
*/
@Override
public void selectLine(RecuperationLineSelect us) {
us.setUnionId(SecurityUtil.getUnionId());
us.setSelectTime(new Date());
us.setSelectUserId(SecurityUtil.getUserId());
if (StrUtil.isBlank(us.getId())) {
insert(us);
} else {
updateIgnoreNull(us);
}
insertOrUpdate(us);
}
/**
* 已经选择的线路ids
*
* @return {@link List}<{@link String}>
*/
@Override
public List<String> getHasSelectLineIds() {
Sql sql = Sqls.create("""
select lineId from recuperation_line_select
where selectUserId = @userId
""");
sql.setParam("userId", SecurityUtil.getUserId());
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
id,
lineId,
signUpStartTime,
signUpEndTime,
changeEndTime,
playStartTime,
playEndTime,
contact,
contactPhone,
minimumGroupSize,
trafficTools,
estimatedCost,
estimatedFamilyNumbers,
signUpMode,
enable
from
recuperation_line_select
where unionId = @unionId
and lineId = @lineId
and signUpMode = @mode
and year(selectTime) = @year
ORDER BY signUpStartTime ASC
""");
sql.setParam("unionId", unionId);
sql.setParam("lineId", lineId);
sql.setParam("mode", mode);
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
return listMap(sql);
// RecuperationLine line = dao().fetch(RecuperationLine.class, lineId);
// if (line.getSignUpMode() == RecuperationSignUpMode.UNION.getValue()) {
// sql = Sqls.create("""
// select
// id,
// lineId,
// signUpStartTime,
// signUpEndTime,
// changeEndTime,
// playStartTime,
// playEndTime,
// contact,
// contactPhone
// from
// recuperation_line_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
// recuperation_line
// where id = @lineId
// """);
// sql.setParam("lineId", lineId);
// return listMap(sql);
// }
}
/**
* 设置线路时间信息
*
* @param unionSelect 联盟选择
*/
@Override
public void setLineInfo(RecuperationLineSelect unionSelect) {
dao().updateIgnoreNull(unionSelect);
}
/**
* 查询某个分工会设置的线路时间信息
*
* @param lineId 行id
* @param usUnionId 我们工会id
* @return {@link NutMap}
*/
@Override
public RecuperationLineSelect findUsLineInfo(String lineId, String usUnionId) {
return dao().fetch(RecuperationLineSelect.class,
Cnd.where("lineId", "=", lineId)
.and("unionId", "=", usUnionId));
}
/**
* 分工会取消选择线路
*
* @param usId union_select 主键id
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public void deSelect(String usId) {
RecuperationLineSelect lineUnionSelect = fetch(usId);
Cnd enrollCnd = Cnd.where("takePartInUnionId", "=", lineUnionSelect.getUnionId());
enrollCnd.and("takePartInLineId", "=", lineUnionSelect.getLineId());
dao().clear(RecuperationEnroll.class, enrollCnd);
delete(usId);
}
}
@@ -8,12 +8,11 @@ import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationLineCreateMode; import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationLineCreateMode;
import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationSignUpMode;
import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationState; import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationState;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLine; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLine;
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLineUnionSelect; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationLineSelect;
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineService; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Chain; import org.nutz.dao.Chain;
@@ -26,7 +25,6 @@ import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
import org.nutz.plugins.wkcache.annotation.CacheRemove; import org.nutz.plugins.wkcache.annotation.CacheRemove;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -47,18 +45,18 @@ public class RecuperationLineServiceImpl extends BaseServiceImpl<RecuperationLin
@Override @Override
public void deleteLine(String lineId) { public void deleteLine(String lineId) {
List<RecuperationLineUnionSelect> unionSelectList = dao().query(RecuperationLineUnionSelect.class, Cnd.where("lineId", "=", lineId)); List<RecuperationLineSelect> unionSelectList = dao().query(RecuperationLineSelect.class, Cnd.where("lineId", "=", lineId));
if (Lang.isNotEmpty(unionSelectList)) { if (Lang.isNotEmpty(unionSelectList)) {
List<String> selectIds = unionSelectList.stream().map(RecuperationLineUnionSelect::getId).collect(Collectors.toList()); List<String> selectIds = unionSelectList.stream().map(RecuperationLineSelect::getId).collect(Collectors.toList());
List<RecuperationEnroll> enrollList = dao().query(RecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds)); List<RecuperationEnroll> enrollList = dao().query(RecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds));
if (Lang.isNotEmpty(enrollList)){ if (Lang.isNotEmpty(enrollList)) {
List<String> enrollIds = enrollList.stream().map(RecuperationEnroll::getId).collect(Collectors.toList()); List<String> enrollIds = enrollList.stream().map(RecuperationEnroll::getId).collect(Collectors.toList());
dao().clear(RecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIds)); dao().clear(RecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIds));
} }
dao().clear(RecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds)); dao().clear(RecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds));
} }
delete(lineId); delete(lineId);
dao().clear(RecuperationLineUnionSelect.class, Cnd.where("lineId", "=", lineId)); dao().clear(RecuperationLineSelect.class, Cnd.where("lineId", "=", lineId));
deleteLineInfoCache(lineId); deleteLineInfoCache(lineId);
} }
@@ -91,33 +89,33 @@ public class RecuperationLineServiceImpl extends BaseServiceImpl<RecuperationLin
@Override @Override
public Pagination pageData(PageForm pageForm, Cnd cnd) { public Pagination pageData(PageForm pageForm, Cnd cnd) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
line.id, line.id,
line.serialNumber, line.serialNumber,
line.lineName, line.lineName,
line.regionalNature, line.regionalNature,
line.minimumGroupSize, line.minimumGroupSize,
line.year, line.year,
line.isDisabled, line.isDisabled,
line.createUnionId, line.createUnionId,
line.signUpMode, line.signUpMode,
line.createMode, line.createMode,
line.file AS fileId, line.file AS fileId,
gh.name AS createUnionName, gh.name AS createUnionName,
u.username AS createUserName, u.username AS createUserName,
ta.travelAgencyName, ta.travelAgencyName,
ta.contact, ta.contact,
ta.contactMobileNumber, ta.contactMobileNumber,
ta.officialWebsite, ta.officialWebsite,
lot.lotName lot.lotName
FROM FROM
recuperation_line line recuperation_line line
LEFT JOIN recuperation_travel_agency ta ON ta.id = line.travelAgencyId LEFT JOIN recuperation_travel_agency ta ON ta.id = line.travelAgencyId
LEFT JOIN sys_union gh ON gh.id = line.createUnionid LEFT JOIN sys_union gh ON gh.id = line.createUnionid
LEFT JOIN sys_user u ON u.id = line.createdBy LEFT JOIN sys_user u ON u.id = line.createdBy
LEFT JOIN recuperation_lot lot on lot.id = line.lotId LEFT JOIN recuperation_lot lot on lot.id = line.lotId
$condition $condition
"""); """);
sql.setCondition(cnd); sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
} }
@@ -130,24 +128,24 @@ public class RecuperationLineServiceImpl extends BaseServiceImpl<RecuperationLin
@Override @Override
public Pagination selectLineUser(PageForm pageForm, String lineId, String unionId) { public Pagination selectLineUser(PageForm pageForm, String lineId, String unionId) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
line.lineName, line.lineName,
enroll.id, enroll.id,
enroll.loginName, enroll.loginName,
enroll.userName, enroll.userName,
enroll.unionName, enroll.unionName,
enroll.unitName, enroll.unitName,
enroll.familyNumber, enroll.familyNumber,
( SELECT COUNT( 1 ) FROM recuperation_enroll_companion WHERE trreId = enroll.id) isFamily ( SELECT COUNT( 1 ) FROM recuperation_enroll_companion WHERE trreId = enroll.id) isFamily
FROM FROM
`recuperation_enroll` enroll `recuperation_enroll` enroll
LEFT JOIN recuperation_line_union_select lineu ON lineu.id = enroll.takePartInLineId LEFT JOIN recuperation_line_select lineu ON lineu.id = enroll.takePartInLineId
LEFT JOIN recuperation_line line ON line.id = lineu.lineId LEFT JOIN recuperation_line line ON line.id = lineu.lineId
WHERE WHERE
lineu.id = @takePartInLineId lineu.id = @takePartInLineId
and enroll.stateId=@stateId and enroll.stateId=@stateId
$unionCnd $unionCnd
""").setParam("takePartInLineId", lineId).setParam("stateId", RecuperationState.PASS); """).setParam("takePartInLineId", lineId).setParam("stateId", RecuperationState.PASS);
if (StrUtil.isNotBlank(unionId) && !AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { if (StrUtil.isNotBlank(unionId) && !AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
sql.setVar("unionCnd", "and enroll.selfUnionId='%s'".formatted(unionId)); sql.setVar("unionCnd", "and enroll.selfUnionId='%s'".formatted(unionId));
} }
@@ -172,18 +170,18 @@ public class RecuperationLineServiceImpl extends BaseServiceImpl<RecuperationLin
@Override @Override
public List<NutMap> viewUnionSelectTimeInfo(String lineId) { public List<NutMap> viewUnionSelectTimeInfo(String lineId) {
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
us.signUpStartTime, us.signUpStartTime,
us.signUpEndTime, us.signUpEndTime,
us.changeEndTime, us.changeEndTime,
us.playStartTime, us.playStartTime,
us.playEndTime, us.playEndTime,
gh.name AS selectUnionName gh.name AS selectUnionName
FROM FROM
`recuperation_line_union_select` us `recuperation_line_select` us
LEFT JOIN sys_union gh ON gh.id = us.unionId LEFT JOIN sys_union gh ON gh.id = us.unionId
WHERE us.lineId = @lineId WHERE us.lineId = @lineId
"""); """);
return listMap(sql); return listMap(sql);
} }
} }
@@ -88,7 +88,7 @@ layout("/layouts/platform.html"){
activityType: "2" activityType: "2"
}, },
tableColumns: [ tableColumns: [
{ label: "活动名称", prop: "activityName", width: 800}, { label: "活动名称", prop: "activityName", width: 600},
{ label: "活动性质", prop: "trainType"}, { label: "活动性质", prop: "trainType"},
{ label: "报名时间", prop: "activitySignUpStartTime"}, { label: "报名时间", prop: "activitySignUpStartTime"},
{ label: "活动时间", prop: "activityStartTime"}, { label: "活动时间", prop: "activityStartTime"},
@@ -3,7 +3,7 @@ const signForm = {
<div> <div>
<el-dialog :close-on-click-modal="false" :visible.sync="signDialog" title="信息填写" width="50%" <el-dialog :close-on-click-modal="false" :visible.sync="signDialog" title="信息填写" width="50%"
append-to-body> append-to-body>
<el-form :model="formData" ref="form" label-width="80px"> <el-form :model="formData" ref="form" label-width="120px">
<div class="left-span-label">个人信息</div> <div class="left-span-label">个人信息</div>
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
@@ -64,9 +64,9 @@ layout("/layouts/platform.html"){
{{ $moment(createdAt).format('YYYY-MM-DD HH:mm:ss') }} {{ $moment(createdAt).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
<template v-slot="{ row }" v-else-if="column.prop === 'activityTime'"> <template v-slot="{ row }" v-else-if="column.prop === 'activityTime'">
<span>{{ $moment(row.activityStartTime).format('MM/DD') }}</span> <span>{{ $moment(row.activityStartTime).format('YYYY/MM/DD') }}</span>
<span></span> <span></span>
<span>{{ $moment(row.activityEndTime).format('MM/DD') }}</span> <span>{{ $moment(row.activityEndTime).format('YYYY/MM/DD') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="150px"> <el-table-column label="操作" width="150px">
@@ -135,7 +135,7 @@ layout("/layouts/platform.html"){
year: new Date().getFullYear() + '' year: new Date().getFullYear() + ''
}, },
tableColumns: [ tableColumns: [
{ label: "活动名称", prop: "activityName", width: 800 }, { label: "活动名称", prop: "activityName", width: 600 },
{ label: "活动时间", prop: "activityTime" }, { label: "活动时间", prop: "activityTime" },
{ label: "是否开启", prop: "isDisabled", width: 100 }, { label: "是否开启", prop: "isDisabled", width: 100 },
{ label: "创建时间", prop: "createdAt" } { label: "创建时间", prop: "createdAt" }
@@ -16,9 +16,10 @@ layout("/layouts/platform.html"){
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度:"> <search-item label="年度:">
<el-date-picker <el-date-picker
placeholder="选择年度" placeholder="选择年度"
type="year" type="year"
style="width: 100%" style="width: 100%"
@change="yearChange"
v-model="pageForm.year" v-model="pageForm.year"
value-format="yyyy" value-format="yyyy"
></el-date-picker> ></el-date-picker>
@@ -12,11 +12,12 @@ layout("/layouts/platform.html"){
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度:"> <search-item label="年度:">
<el-date-picker <el-date-picker
placeholder="选择年度" placeholder="选择年度"
type="year" type="year"
style="width: 100%" style="width: 100%"
v-model="pageForm.year" @change="yearChange"
value-format="yyyy" v-model="pageForm.year"
value-format="yyyy"
></el-date-picker> ></el-date-picker>
</search-item> </search-item>
<search-item label="活动名称:"> <search-item label="活动名称:">
@@ -69,7 +70,7 @@ layout("/layouts/platform.html"){
</el-card> </el-card>
<template #view> <template #view>
<user-info ref="userInfoRef"></user-info> <user-info ref="userInfoRef" @refresh="doSearch"></user-info>
</template> </template>
</guava> </guava>
@@ -152,16 +152,16 @@ const userInfo = {
background: "rgba(0, 0, 0, 0.7)" background: "rgba(0, 0, 0, 0.7)"
}) })
const resp = await this.$axios.post(loc() + "/adjust", { const resp = await this.$axios.post(loc() + "/adjust", {
activityId: this.pageForm.activityId, activityId: this.activity.id,
oldCourseId: this.registerCourse.id, oldCourseId: this.registerCourse.id,
newCourseId: this.afterAdjustCourse, newCourseId: this.afterAdjustCourse,
userId: this.userInfo.userId userId: this.userInfo.userId
}) })
if (resp.code === 0) { if (resp.code === 0) {
this.$message.success(resp.msg) this.$message.success(resp.msg)
this.$refs.guava.index()
this.adjustDialogVisible = false this.adjustDialogVisible = false
this.doSearch() await this.registerSearch()
this.$emit("refresh", null)
} else { } else {
this.$message.warning(resp.msg) this.$message.warning(resp.msg)
} }
@@ -184,7 +184,7 @@ const userInfo = {
}) })
.then(async () => { .then(async () => {
const resp = await this.$axios.post(loc() + "/deleteSignUser", { const resp = await this.$axios.post(loc() + "/deleteSignUser", {
activityId: this.pageForm.activityId, activityId: this.activity.id,
courseId: this.registerCourse.id, courseId: this.registerCourse.id,
userId: o.userId userId: o.userId
}) })
@@ -79,8 +79,8 @@ layout("/layouts/platform.html"){
<el-table-column prop="username" label="姓名"></el-table-column> <el-table-column prop="username" label="姓名"></el-table-column>
<el-table-column prop="loginname" label="工号"></el-table-column> <el-table-column prop="loginname" label="工号"></el-table-column>
<el-table-column prop="mobile" label="联系方式"></el-table-column> <el-table-column prop="mobile" label="联系方式"></el-table-column>
<el-table-column prop="unitname" label="单位"></el-table-column> <el-table-column prop="unitName" label="单位"></el-table-column>
<el-table-column prop="unionname" label="工会"></el-table-column> <el-table-column prop="unionName" label="工会"></el-table-column>
<el-table-column prop="signUpTime" label="报名时间"></el-table-column> <el-table-column prop="signUpTime" label="报名时间"></el-table-column>
</el-table> </el-table>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@@ -1,7 +1,7 @@
const basicForm = { const basicForm = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<div> <div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="110px" label-position="left"> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="120px" label-position="left">
<el-form-item prop="planType" label="计划类型"> <el-form-item prop="planType" label="计划类型">
<el-select v-model="formData.planType" placeholder="请选择计划类型" filterable clearable <el-select v-model="formData.planType" placeholder="请选择计划类型" filterable clearable
style="width: 100%"> style="width: 100%">
@@ -68,6 +68,12 @@ const basicForm = {
<el-form-item prop="content" label="计划内容" class="is-required"> <el-form-item prop="content" label="计划内容" class="is-required">
<text-editor v-model="formData.content"></text-editor> <text-editor v-model="formData.content"></text-editor>
</el-form-item> </el-form-item>
<el-form-item prop="content" label="附件上传">
<file-upload :upload_number="5" :value.sync="formData.files"
upload_result_type="url"
complete_result upload_mode="drag"
upload_result_category="array"></file-upload>
</el-form-item>
</el-form> </el-form>
<el-row class="mt10" justify="end" type="flex"> <el-row class="mt10" justify="end" type="flex">
<el-button @click="$emit('refresh')">取消</el-button> <el-button @click="$emit('refresh')">取消</el-button>
@@ -120,6 +126,7 @@ const basicForm = {
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(async () => { }).then(async () => {
this.formData.files = JSON.stringify(this.formData.files)
const resp = await this.$axios.post("/platform/yearPlan/manage/onSubmit", this.formData) const resp = await this.$axios.post("/platform/yearPlan/manage/onSubmit", this.formData)
if (resp.code === 0) { if (resp.code === 0) {
this.$message.success(resp.msg) this.$message.success(resp.msg)
@@ -57,6 +57,10 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt20"> <el-card shadow="never" class="mt20">
<table-tool label="年度计划"> <table-tool label="年度计划">
<el-button type="primary" size="small" @click="onDownLoad">
<i class="el-icon-download"></i>
下载全部附件
</el-button>
<el-button type="primary" size="small" @click="onAdd"> <el-button type="primary" size="small" @click="onAdd">
<i class="ti-plus"></i> <i class="ti-plus"></i>
新增计划 新增计划
@@ -133,6 +137,9 @@ layout("/layouts/platform.html"){
} }
}, },
methods: { methods: {
onDownLoad() {
this.$downLoad(loc() + '/downloadFiles', this.pageForm)
},
refresh() { refresh() {
this.doSearch() this.doSearch()
this.$refs.guava.index() this.$refs.guava.index()
@@ -1,7 +1,7 @@
const basicForm = { const basicForm = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<div> <div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="110px" label-position="left"> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="120px" label-position="left">
<el-form-item label="上传人" prop="userName"> <el-form-item label="上传人" prop="userName">
<el-input maxlength="50" placeholder="请填写上传人" :value="$store.state.user.username" <el-input maxlength="50" placeholder="请填写上传人" :value="$store.state.user.username"
type="text"></el-input> type="text"></el-input>
@@ -54,6 +54,10 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt20"> <el-card shadow="never" class="mt20">
<table-tool label="年度总结"> <table-tool label="年度总结">
<el-button type="primary" size="small" @click="onDownLoad">
<i class="el-icon-download"></i>
下载全部附件
</el-button>
<el-button type="primary" size="small" @click="onAdd"> <el-button type="primary" size="small" @click="onAdd">
<i class="ti-plus"></i> <i class="ti-plus"></i>
新增计划 新增计划
@@ -129,6 +133,9 @@ layout("/layouts/platform.html"){
} }
}, },
methods: { methods: {
onDownLoad() {
this.$downLoad(loc() + '/downloadFiles', this.pageForm)
},
refresh() { refresh() {
this.doSearch() this.doSearch()
this.$refs.guava.index() this.$refs.guava.index()
@@ -88,7 +88,7 @@ layout("/layouts/platform.html"){
activityType: "2" activityType: "2"
}, },
tableColumns: [ tableColumns: [
{ label: "活动名称", prop: "activityName", width: 800}, { label: "活动名称", prop: "activityName", width: 600},
{ label: "活动性质", prop: "trainType"}, { label: "活动性质", prop: "trainType"},
{ label: "报名时间", prop: "activitySignUpStartTime"}, { label: "报名时间", prop: "activitySignUpStartTime"},
{ label: "活动时间", prop: "activityStartTime"}, { label: "活动时间", prop: "activityStartTime"},
@@ -2,7 +2,7 @@ const signForm = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<div> <div>
<el-dialog :close-on-click-modal="false" :visible.sync="signDialog" title="信息填写" width="50%" append-to-body> <el-dialog :close-on-click-modal="false" :visible.sync="signDialog" title="信息填写" width="50%" append-to-body>
<el-form :model="formData" ref="form" label-width="80px"> <el-form :model="formData" ref="form" label-width="120px">
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="姓名" prop="username"> <el-form-item label="姓名" prop="username">
@@ -155,7 +155,7 @@ const signForm = {
this.$refs["form"].validate(async (valid) => { this.$refs["form"].validate(async (valid) => {
if (valid) { if (valid) {
if (this.courseRow.courseIsLimitApply) { if (this.courseRow.courseIsLimitApply) {
const resp = await $.post('/platform/mobile/trainSignUpActivity/validateSourceSignUp', {activityCourseId: this.formData.activityCourseId}) const resp = await this.$axios.post('/platform/mobile/trainSignUpActivity/validateSourceSignUp', {activityCourseId: this.formData.activityCourseId})
if (resp.code !== 0) { if (resp.code !== 0) {
this.$message.warning(res.msg) this.$message.warning(res.msg)
return return
@@ -64,9 +64,9 @@ layout("/layouts/platform.html"){
{{ $moment(createdAt).format('YYYY-MM-DD HH:mm:ss') }} {{ $moment(createdAt).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
<template v-slot="{ row }" v-else-if="column.prop === 'activityTime'"> <template v-slot="{ row }" v-else-if="column.prop === 'activityTime'">
<span>{{ $moment(row.activityStartTime).format('MM/DD') }}</span> <span>{{ $moment(row.activityStartTime).format('YYYY/MM/DD') }}</span>
<span></span> <span></span>
<span>{{ $moment(row.activityEndTime).format('MM/DD') }}</span> <span>{{ $moment(row.activityEndTime).format('YYYY/MM/DD') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="150px"> <el-table-column label="操作" width="150px">
@@ -135,7 +135,7 @@ layout("/layouts/platform.html"){
year: new Date().getFullYear() + '' year: new Date().getFullYear() + ''
}, },
tableColumns: [ tableColumns: [
{ label: "活动名称", prop: "activityName", width: 800 }, { label: "活动名称", prop: "activityName", width: 600 },
{ label: "活动时间", prop: "activityTime" }, { label: "活动时间", prop: "activityTime" },
{ label: "是否开启", prop: "isDisabled", width: 100 }, { label: "是否开启", prop: "isDisabled", width: 100 },
{ label: "创建时间", prop: "createdAt" } { label: "创建时间", prop: "createdAt" }
@@ -16,9 +16,10 @@ layout("/layouts/platform.html"){
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度:"> <search-item label="年度:">
<el-date-picker <el-date-picker
placeholder="选择年度" placeholder="选择年度"
type="year" type="year"
style="width: 100%" style="width: 100%"
@change="yearChange"
v-model="pageForm.year" v-model="pageForm.year"
value-format="yyyy" value-format="yyyy"
></el-date-picker> ></el-date-picker>
@@ -12,9 +12,10 @@ layout("/layouts/platform.html"){
<search @search="doSearch"> <search @search="doSearch">
<search-item label="年度:"> <search-item label="年度:">
<el-date-picker <el-date-picker
placeholder="选择年度" placeholder="选择年度"
type="year" type="year"
style="width: 100%" style="width: 100%"
@change="yearChange"
v-model="pageForm.year" v-model="pageForm.year"
value-format="yyyy" value-format="yyyy"
></el-date-picker> ></el-date-picker>
@@ -69,7 +70,7 @@ layout("/layouts/platform.html"){
</el-card> </el-card>
<template #view> <template #view>
<user-info ref="userInfoRef"></user-info> <user-info ref="userInfoRef" @refresh="doSearch"></user-info>
</template> </template>
</guava> </guava>
@@ -152,20 +152,20 @@ const userInfo = {
background: "rgba(0, 0, 0, 0.7)" background: "rgba(0, 0, 0, 0.7)"
}) })
const resp = await this.$axios.post(loc() + "/adjust", { const resp = await this.$axios.post(loc() + "/adjust", {
activityId: this.pageForm.activityId, activityId: this.activity.id,
oldCourseId: this.registerCourse.id, oldCourseId: this.registerCourse.id,
newCourseId: this.afterAdjustCourse, newCourseId: this.afterAdjustCourse,
userId: this.userInfo.userId userId: this.userInfo.userId
}) })
loading.close()
if (resp.code === 0) { if (resp.code === 0) {
this.$message.success(resp.msg) this.$message.success(resp.msg)
this.$refs.guava.index()
this.adjustDialogVisible = false this.adjustDialogVisible = false
this.doSearch() await this.registerSearch()
this.$emit("refresh", null)
} else { } else {
this.$message.warning(resp.msg) this.$message.warning(resp.msg)
} }
loading.close()
}) })
.catch(() => {}) .catch(() => {})
}, },
@@ -184,14 +184,14 @@ const userInfo = {
}) })
.then(async () => { .then(async () => {
const resp = await this.$axios.post(loc() + "/deleteSignUser", { const resp = await this.$axios.post(loc() + "/deleteSignUser", {
activityId: this.pageForm.activityId, activityId: this.activity.id,
courseId: this.registerCourse.id, courseId: this.registerCourse.id,
userId: o.userId userId: o.userId
}) })
if (resp.code === 0) { if (resp.code === 0) {
this.$message.success(resp.msg) this.$message.success(resp.msg)
await this.registerSearch() await this.registerSearch()
this.doSearch() this.$emit("refresh", null)
} else { } else {
this.$message.warning(resp.msg) this.$message.warning(resp.msg)
} }
@@ -79,8 +79,8 @@ layout("/layouts/platform.html"){
<el-table-column prop="username" label="姓名"></el-table-column> <el-table-column prop="username" label="姓名"></el-table-column>
<el-table-column prop="loginname" label="工号"></el-table-column> <el-table-column prop="loginname" label="工号"></el-table-column>
<el-table-column prop="mobile" label="联系方式"></el-table-column> <el-table-column prop="mobile" label="联系方式"></el-table-column>
<el-table-column prop="unitname" label="单位"></el-table-column> <el-table-column prop="unitName" label="单位"></el-table-column>
<el-table-column prop="unionname" label="工会"></el-table-column> <el-table-column prop="unionName" label="工会"></el-table-column>
<el-table-column prop="signUpTime" label="报名时间"></el-table-column> <el-table-column prop="signUpTime" label="报名时间"></el-table-column>
</el-table> </el-table>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@@ -119,6 +119,9 @@ const addForm = {
}) })
}, },
}, },
created() {
this.queryDoctorUser(null)
},
style: /*language=CSS*/ ` style: /*language=CSS*/ `
` `
@@ -8,6 +8,7 @@ const basicForm = {
v-model="formData.userId" v-model="formData.userId"
filterable filterable
remote remote
:disabled="formData.id !== '' && formData.id !== null && formData.id !== undefined"
reserve-keyword reserve-keyword
placeholder="请输入关键词" placeholder="请输入关键词"
:remote-method="selectQueryUser" :remote-method="selectQueryUser"
@@ -101,7 +101,7 @@ layout("/layouts/platform.html"){
{prop: 'userName', label: '姓名'}, {prop: 'userName', label: '姓名'},
{prop: 'sex', label: '性别'}, {prop: 'sex', label: '性别'},
{prop: 'unitName', label: '单位'}, {prop: 'unitName', label: '单位'},
{prop: 'jobTitle', label: '职称'}, {prop: 'technicalTitle', label: '职称'},
{prop: 'mobile', label: '联系电话'}, {prop: 'mobile', label: '联系电话'},
{prop: 'avatar', label: '头像'} {prop: 'avatar', label: '头像'}
], ],
@@ -42,6 +42,10 @@ const info = {
}, },
}, },
style: /*language=CSS*/ ` style: /*language=CSS*/ `
.el-descriptions-item__label {
width: 200px;
min-width: 200px;
max-width: 200px;
}
` `
} }
@@ -119,6 +119,9 @@ const addForm = {
}) })
}, },
}, },
created() {
this.queryDoctorUser(null)
},
style: /*language=CSS*/ ` style: /*language=CSS*/ `
` `
@@ -8,6 +8,7 @@ const basicForm = {
v-model="formData.userId" v-model="formData.userId"
filterable filterable
remote remote
:disabled="formData.id !== '' && formData.id !== null && formData.id !== undefined"
reserve-keyword reserve-keyword
placeholder="请输入关键词" placeholder="请输入关键词"
:remote-method="selectQueryUser" :remote-method="selectQueryUser"
@@ -101,7 +101,7 @@ layout("/layouts/platform.html"){
{prop: 'userName', label: '姓名'}, {prop: 'userName', label: '姓名'},
{prop: 'sex', label: '性别'}, {prop: 'sex', label: '性别'},
{prop: 'unitName', label: '单位'}, {prop: 'unitName', label: '单位'},
{prop: 'jobTitle', label: '职称'}, {prop: 'technicalTitle', label: '职称'},
{prop: 'mobile', label: '联系电话'}, {prop: 'mobile', label: '联系电话'},
{prop: 'avatar', label: '头像'} {prop: 'avatar', label: '头像'}
], ],
@@ -42,6 +42,10 @@ const info = {
}, },
}, },
style: /*language=CSS*/ ` style: /*language=CSS*/ `
.el-descriptions-item__label {
width: 200px;
min-width: 200px;
max-width: 200px;
}
` `
} }
@@ -0,0 +1,353 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.top_block {
width: 100%;
padding: 20px 80px;
border-bottom: 10px solid rgb(240, 240, 240);
}
.top_title {
font-size: 18px;
height: 30px;
line-height: 30px;
margin-bottom: 5px;
}
.top_num {
font-size: 26px;
color: #808492;
}
.two_num {
margin-top: 8px;
font-size: 18px;
color: #808492;
}
.cut-off-line {
width: 1px;
height: 70%;
position: absolute;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background-color: rgb(230, 230, 230);
}
.chartTitle {
font-size: 14px;
color: #808492;
margin-bottom: 20px;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
placeholder="请选择年度"
type="year"
@change="doSearch"
style="width: 100%"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="线路类型:">
<el-select v-model="pageForm.lineType" placeholder="请选择线路类型" clearable style="width: 100%" @change="doSearch">
<el-option v-for="item in regionalNatureList" :key="item.value" :label="item.label" :value="item.value">{{item.label}}</el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt20">
<div class="top_block">
<el-row :gutter="20">
<el-col :span="4" style="position: relative">
<div class="top_title">总人数</div>
<div class="top_num">{{numData.allNum || '0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div class="top_title">省内人数</div>
<div class="top_num">{{numData.provinceNum || '0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div class="top_title">省外人数</div>
<div class="top_num">{{numData.outProvinceNum || '0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div style="display: flex;justify-content: space-between;">
<div class="top_title">总线路数</div>
<div style="margin-top: 2px;font-size: 18px;color: #1867b0">共{{numData.lineNum || '0'}}条</div>
</div>
<div class="two_num">省内{{numData.inLineNum || '0'}} | 省外{{numData.outLineNum || '0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4" style="position: relative">
<div style="display: flex;justify-content: space-between;">
<div class="top_title">校工会组织</div>
<div style="margin-top: 2px;font-size: 18px;color: #1867b0">共{{numData.schoolUnionLineNum || '0'}}条</div>
</div>
<div class="two_num">省内{{numData.schoolInLineNum || '0'}} | 省外{{numData.schoolOutLineNum || '0'}}</div>
<div class="cut-off-line"></div>
</el-col>
<el-col :span="4">
<div style="display: flex;justify-content: space-between;">
<div class="top_title">分工会组织</div>
<div style="margin-top: 2px;font-size: 18px;color: #1867b0">共{{numData.unionLineNum || '0'}}条</div>
</div>
<div class="two_num">省内{{numData.unionInLineNum || '0'}} | 省外{{numData.unionOutLineNum || '0'}}</div>
</el-col>
</el-row>
</div>
<el-row :gutter="20" style="padding: 30px 0;border-bottom: 10px solid rgb(240, 240, 240)">
<el-col :span="12" v-loading="lotLoading">
<div class="chartTitle">时间标段统计</div>
<div id="lotChart" style="width: 100%;height: 300px"></div>
</el-col>
<el-col :span="12" v-loading="ageLoading">
<div class="chartTitle">年龄分布统计</div>
<div id="ageChart" style="width: 100%;height: 300px"></div>
</el-col>
</el-row>
<el-row style="padding: 30px 0;border-bottom: 10px solid rgb(240, 240, 240)">
<el-col :span="24" style="padding: 0 20px" v-loading="lineTravelOrAgeLoading">
<div class="chartTitle">线路人数及年龄统计</div>
<div id="lineTravelChart"></div>
</el-col>
</el-row>
</el-card>
</template>
</guava>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {},
data() {
return {
pageForm: {
year: new Date().getFullYear().toString(),
},
numData: {
allNum: '',
provinceNum: '',
outProvinceNum: '',
allLineNum: '',
schoolLineNum: '',
branchLineNum: ''
},
regionalNatureList: [{label:'全部线路',name:'provinceAll',ordinal:0,provinceIn:'provinceIn',provinceOut:'provinceOut',value:'全部'}],
lotLoading: false,
ageLoading: false,
lineTravelOrAgeLoading: false,
isLineTravel: false,
lineTravelOrAgeTip: '出行线路年龄统计',
dualAxisChartInstance: null,
}
},
methods: {
async getNumData(){
const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getNumData', this.pageForm)
if (resp.code === 0) {
this.numData = resp.data
}
},
async getLotNumData(){
this.lotLoading = true
const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getLotNum', this.pageForm)
if (resp.code === 0) {
let {data} = resp
document.getElementById("lotChart").innerHTML = ''
const config = {
isStack: true,
"legend": {
"position": "top-right",
"flipPage": false
},
autoFit: true,
title: {
visible: true,
text: '出行时间标段统计详情',
},
description: {
visible: true,
text: '人',
},
xField: 'label',
yField: 'value',
stackField: 'type',
color: ["#5B8FF9", "#5AD8A6"],
"xAxis": {
label: {
formatter: (v) => {
if (data.length > 30 && v.length > 3) {
return v.substr(0, 2) + '...'
} else if (data.length > 20 && v.length > 4) {
return v.substr(0, 3) + '...'
} else if (data.length > 10 && v.length > 6) {
return v.substr(0, 5) + '...'
}
return v
}
}
},
"yAxis": {},
meta: {
label: {
alias: '标段时长',
},
value: {
alias: '人数',
}
},
connectedArea: {
visible: true,
triggerOn: false,
},
}
const plot = new G2Plot.Column(document.getElementById("lotChart"), {
data,
...config,
});
plot.render();
this.lotLoading = false
}
},
async getAgeData(){
this.ageLoading = true
const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getAgeNum', this.pageForm)
if (resp.code === 0) {
let {data} = resp
document.getElementById("ageChart").innerHTML = ''
const config = {
"legend": {
"flipPage": false
},
"label": {
"type": "spider",
"offset": 50
},
"width": $('#ageChart').width(),
"height": $('#ageChart').height(),
"forceFit": false,
"radius": 1,
"colorField": "label",
"angleField": "value",
meta: {
label: {
alias: '年龄结构',
},
value: {
alias: '人数',
}
},
}
const plot = new G2Plot.Pie(document.getElementById("ageChart"), {
data,
...config,
});
plot.render();
this.ageLoading = false
}
},
async getLineTravelData(){
if (this.dualAxisChartInstance) {
this.dualAxisChartInstance.destroy(); // 如果已有实例,先销毁
}
const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getLineTravelAndAgeData', this.pageForm)
if (resp.code === 0) {
let {data} = resp
document.getElementById("lineTravelChart").innerHTML = ''
const dualAxes = new G2Plot.DualAxes('lineTravelChart', {
data: [data.uvData, data.transformData],
xField: 'lineName',
yField: ['value', 'count'],
meta: {
value: {
alias: '出行人数',
},
count: {
alias: '年龄段人数',
}
},
yAxis: [
{
min: 0, // 设置Y轴最小值为0
max: null, // 自动计算最大值
title: {
text: '出行人数',
},
},
{
position: 'right',
min: 0,
max: null,
title: {
text: '年龄段人数',
},
},
],
geometryOptions: [
{
geometry: 'column',
columnWidthRatio: 0.4,
color: '#5B8FF9', // 设置柱状图颜色
},
{
geometry: 'line',
seriesField: 'name',
color: ['#5AD8A6', '#E8684A', '#FF9D4D'], // 设置线的颜色
},
],
tooltip: {
shared: true, // 共享提示框
},
});
dualAxes.render();
}
},
doLineTravelOrAgeSwitch(){
this.isLineTravel = !this.isLineTravel
this.lineTravelOrAgeTip = this.isLineTravel ? '出行线路年龄统计' : '出行线路人数统计'
},
async initData(){
await this.getNumData()
await this.getLotNumData()
await this.getAgeData()
await this.getLineTravelData()
},
async getEnumOptions(enumName) {
const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: enumName })
return resp.data
},
},
async created() {
this.regionalNatureList.push(...await this.getEnumOptions('RecuperationProvinceType'))
this.initData()
}
})
</script>
<!--#
}
#-->
@@ -90,8 +90,8 @@ layout("/layouts/platform.html"){
> >
<template v-slot="{ row }" v-if="column.prop === 'isDisabled'"> <template v-slot="{ row }" v-if="column.prop === 'isDisabled'">
<el-switch <el-switch
:active-value="true" :active-value="false"
:inactive-value="false" :inactive-value="true"
@change="(val)=>{baseStatusChange(row.id)}" @change="(val)=>{baseStatusChange(row.id)}"
active-color="#13ce66" active-color="#13ce66"
inactive-color="#ff4949" inactive-color="#ff4949"
@@ -0,0 +1,193 @@
const editForm = {
template: /*language=HTML*/ `
<el-dialog title="编辑" :visible.sync="visible" top="50px">
<el-form :model="formData" label-width="120px" :formRules="formRules" ref="formRef"
style="margin-right: 40px">
<el-row>
<el-col span="12">
<el-form-item prop="loginName" label="工号">
<el-input v-model="formData.loginName" readonly></el-input>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="userName" label="姓名">
<el-input v-model="formData.userName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col span="12">
<el-form-item prop="userName" label="手机号">
<el-input v-model="formData.mobile" readonly></el-input>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="userName" label="身份证号">
<el-input v-model="formData.idCard" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col span="12">
<el-form-item prop="unionName" label="工会">
<el-input v-model="formData.unionName" readonly></el-input>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="unitName" label="单位">
<el-input v-model="formData.unitName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="prop" :label="labelName">
<template v-if="config.familyInfo == 2">
<el-collapse v-model="activeNames">
<el-collapse-item title="点击可展开详细信息" name="1">
<el-card shadow="never">
<el-table :data="formData.companionList">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="身份证号" prop="idCard"></el-table-column>
<el-table-column label="年龄" prop="age"></el-table-column>
<el-table-column label="床型" prop="bedType">
<template v-slot="{row}">
{{ row.bedInfo.bedType }}
</template>
</el-table-column>
<el-table-column label="床位" prop="bedNum">
<template v-slot="{row}">
{{ row.bedInfo.bedNum }}
</template>
</el-table-column>
<el-table-column label="意向拼床人" prop="otherSleepUser">
<template v-slot="{row}">
{{ row.bedInfo.otherSleepUser ?
row.bedInfo.otherSleepUser : '暂无' }}
</template>
</el-table-column>
<el-table-column label="关系" prop="relation"></el-table-column>
</el-table>
</el-card>
</el-collapse-item>
</el-collapse>
</template>
<template v-else>
<el-input v-model="formData.bedType" readonly></el-input>
</template>
</el-form-item>
<el-form-item prop="travelLine" :label="lineLabelName">
<el-select v-model="formData.takePartInLineId" filterable clearable
placeholder="请选择线路"
@change="validateLine"
style="width: 100%">
<el-option v-for="item in unionSelectLines"
:key="item.id"
:label="item.lineName + '-' + item.regionalNature + '【' + item.lotName + '】' + '' + item.playStartTime + '至' + item.playEndTime + '' + '' + item.signUpMode + ''"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item prop="specificTime" label="出行时间" v-if="pageForm.state==='3'">-->
<!-- <el-select v-model="formData.specificTime" filterable clearable-->
<!-- placeholder="请选择出行时间"-->
<!-- style="width: 100%">-->
<!-- <el-option v-for="item in editSpecificTimes"-->
<!-- :key="item"-->
<!-- :label="item"-->
<!-- :value="item">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="onSubmit">确 定</el-button>
</div>
</template>
</el-dialog>
`,
data() {
return {
visible: false,
year: null,
config: {},
formData: {},
formRules: {},
labelName: null,
lineLabelName: '线路',
unionSelectLines: [],
activeNames: []
}
},
methods: {
async onOpen(id, year) {
this.year = year
this.visible = true
await this.getUnionSelectLine()
await this.getModifyConfig()
const {code, msg, data} = await this.$axios.get("/platform/recuperation/branchUnionUserQuery/findOne", {id})
if (code === 0) {
this.formData = data
if (this.config.familyInfo === 2) {
this.labelName = "家属信息"
} else {
this.editFormData.bedType = data.familyNumber
this.labelName = "家属数量"
}
} else {
this.$message.error(msg)
}
},
async getModifyConfig() {
const {code, data, msg} = await this.$axios.post('/platform/recuperation/config/findOne')
if (code === 0) {
this.config = data
} else {
this.$message.error(msg)
}
},
async getUnionSelectLine() {
const resp = await this.$axios.post('/platform/recuperation/user/query/getUnionSelectLine', {
year: this.year,
signUpMode: 1,
})
if (resp.code === 0) {
this.unionSelectLines = resp.data
}
},
async validateLine() {
const resp = await $.post('/platform/recuperation/line/enroll/validSignUpInfo'
, {enroll: JSON.stringify(this.editFormData)})
if (resp.code !== 0) {
this.$message.warning(resp.msg)
this.formData.takePartInLineId = ''
}
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm('您确定要修改报名信息吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
if (!this.formData.takePartInLineId && !this.formData.takePartInBaseManagementId) {
this.$message.warning('请选择线路')
return
}
const {code,msg} = await $.post('/platform/recuperation/user/query/doEdit', this.formData)
if (code === 0) {
this.$message.success(msg)
this.visible = false
this.$emit('refresh')
} else {
this.$message.error(msg)
}
}).catch()
}
})
}
}
};
@@ -0,0 +1,377 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.filter-container {
margin-bottom: 10px;
border-radius: 4px;
}
.filter-container .el-form {
padding: 10px 15px;
}
.form-row {
display: flex;
gap: 20px;
margin-bottom: 22px;
flex-wrap: wrap;
}
.form-row .el-form-item {
flex: 1;
min-width: 240px;
margin-bottom: 0;
}
.flex-grow-1 {
flex: 1;
}
.route-line {
display: flex;
align-items: center;
margin-bottom: 22px;
}
.route-line-title {
width: 90px;
text-align: right;
padding-right: 12px;
color: #606266;
font-size: 14px;
line-height: 40px;
}
.route-line-content {
flex: 1;
}
.route-radio-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.route-radio-group .el-radio {
margin-right: 0;
margin-bottom: 10px;
}
.button-container {
display: flex;
justify-content: center;
padding-top: 15px;
border-top: 1px dashed #ebeef5;
}
.button-container .el-button {
padding-left: 25px;
padding-right: 25px;
margin: 0 15px;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never" class="filter-container">
<el-form :model="pageForm" ref="pageFormRef" label-width="90px" size="medium">
<div class="form-row">
<el-form-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
placeholder="选择年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="pageForm.userName" placeholder="请输入姓名" clearable
prefix-icon="el-icon-user"></el-input>
</el-form-item>
<el-form-item label="工号">
<el-input v-model="pageForm.loginName" placeholder="请输入工号" clearable
prefix-icon="el-icon-postcard"></el-input>
</el-form-item>
</div>
<div class="route-line">
<div class="route-line-title">报名线路</div>
<div class="route-line-content">
<el-radio-group v-model="pageForm.signUpMode" class="route-radio-group" size="small"
@change="signUpModeChange">
<el-radio :label="1" border>校工会线路</el-radio>
<el-radio :label="2" border>本分工会线路本工会人员</el-radio>
<el-radio :label="3" border>其他工会线路本工会人员</el-radio>
<el-radio :label="4" border>个人组织线路</el-radio>
</el-radio-group>
</div>
</div>
<div class="route-line">
<div class="route-line-title">区域</div>
<div class="route-line-content">
<el-radio-group @change="doSearch"
size="small"
v-model="pageForm.regionalNature">
<el-radio label="" border>全部</el-radio>
<el-radio label="省内" border>省内</el-radio>
<el-radio label="省外" border>省外</el-radio>
</el-radio-group>
</div>
</div>
<div class="form-row">
<el-form-item label="线路选择">
<el-select v-model="pageForm.takePartInLineId" placeholder="请选择线路" clearable
style="width: 100%">
<el-option
v-for="item in takePartInLines"
:key="item.takePartInLineId"
:label="item.lineName+''+item.unionName+''"
:value="item.takePartInLineId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="标段">
<el-select v-model="pageForm.lotId" placeholder="请选择标段" clearable style="width: 100%">
<el-option
v-for="item in config.lots"
:key="item.id"
:label="item.lotName"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item class="flex-grow-1">
<!-- 占位,保持布局平衡 -->
</el-form-item>
</div>
<div class="button-container">
<el-button type="primary" icon="el-icon-search" round @click="doSearch">查询</el-button>
<el-button icon="el-icon-refresh" round @click="resetQuery">重置</el-button>
</div>
</el-form>
</el-card>
<el-card shadow="never">
<table-tool label="人员列表" ref="table_tool">
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="doExport">
导出
</el-button>
<el-button icon="el-icon-s-promotion" size="small" type="primary"
@click="openSetUpPart"
>设置参加人员
</el-button>
</table-tool>
<el-table :data="tableData" row-key="id" style="width: 100%" ref="tableRef">
<el-table-column reserve-selection type="selection" width="55"></el-table-column>
<el-table-column align="center" header-align="center" type="index" label="序号" :index="indexMethod"
width="80px"></el-table-column>
<el-table-column
align="center"
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
:label="column.label"
:prop="column.prop"
:key="column.prop"
:sortable="column.sortable"
>
<template v-slot="{row}" v-if="column.prop=='isFamily'">
<el-link v-if="!row.familyNumber" type="primary" @click="openUser(row)">
{{row.isFamily?'携带':'未携带'}}{{row.isFamily}}
</el-link>
<el-link v-else type="primary">
{{row.familyNumber?'携带':'未携带'}}{{row.familyNumber}}
</el-link>
</template>
<template v-slot="{row}" v-else-if="column.prop=='times'">
<div v-if="row.playStartTime">{{row.playStartTime}}</div>
<div v-else>{{row.playStartTime1}}</div>
</template>
<template v-slot="{row}" v-else-if="column.prop=='isTakePartIn'">
{{row.isTakePartIn?'已参加':'未参加'}}
</template>
<template v-slot="{row}" v-else-if="column.prop=='stateId'">
<span v-if="row.stateId">
</span>
<sapn v-else style="color: #67C23A">暂无</sapn>
</template>
<template v-slot="{row}" v-else-if="column.prop=='lineOrMaName'">
{{row.lineName?row.lineName:row.baseName?row.baseName:row.travelAgencyName}}
</template>
</el-table-column>
<el-table-column v-if="pageForm.state=='1'||pageForm.state=='3'" align="center"
prop="lotName"
show-overflow-tooltip
header-align="center"
label="标段"
sortable>
<template v-slot="{row}">
{{row.lotName}}
</template>
</el-table-column>
<el-table-column label="操作" width="250px">
<template v-slot="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button @click="onDelete(row)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
<el-dialog title="查看报名信息" :visible.sync="viewVisible" top="50px">
<enroll-info ref="viewEnrollInfoRef"></enroll-info>
</el-dialog>
<set-up-part ref="setUpRef"></set-up-part>
<edit-form ref="editRef" @refresh="doSearch"></edit-form>
</div>
<script>
<!--#include('setUpPart.js'){}#-->
<!--#include('editForm.js'){}#-->
<!--#include('../line/info.js'){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
'line-info': info,
'set-up-part': setUpPart,
'edit-form': editForm
},
data() {
return {
pageForm: {
year: new Date().getFullYear().toString(),
loginName: '',
userName: '',
takePartInLineId: '',
unionId: '',
signUpMode: 1,
lotId: '',
regionalNature: ''
},
takePartInLines: [],
tableColumns: [
{prop: 'loginName', label: '工号'},
{prop: 'userName', label: '姓名'},
{prop: 'unitName', label: '所属单位', sortable: true},
{prop: 'unionName', label: '所属工会', sortable: true},
{prop: 'lineOrMaName', label: '线路'},
{prop: 'times', label: '出行时间'},
{prop: 'isFamily', label: '是否携带家属'},
{prop: 'isTakePartIn', label: '是否参加'}
],
viewVisible: false,
unionOptions: [],
config: {}
}
},
methods: {
signUpModeChange(val) {
this.pageForm.takePartInLineId = ''
this.getLines()
this.doSearch()
},
resetQuery() {
this.pageForm = {
year: new Date().getFullYear().toString(),
loginName: '',
userName: '',
takePartInLineId: '',
unionId: '',
signUpMode: 1,
lotId: '',
regionalNature: '',
pageNumber: 1,
pageSize: 10,
totalCount: 0,
}
this.doSearch()
},
openView(row) {
this.viewVisible = true
this.$nextTick(() => {
this.$refs.viewEnrollInfoRef.openView(row.id)
})
},
openEdit(row) {
this.$refs.editRef.onOpen(row.id)
},
onDelete(row) {
this.$confirm("您确定要删除【<span style='color: red'>" + row.userName + "</span>】的信息吗?", '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning'
}).then(async () => {
const {code, msg} = await this.$axios.post('/platform/recuperation/branchUnionUserQuery/deleteMyEnrollInfoById', {
id: row.id
})
if (code === 0) {
this.doSearch()
this.$message.success(msg)
} else {
this.$message.warning(msg)
}
})
},
doExport() {
const {year, userName, loginName, unionId, signUpMode, regionalNature, takePartInLineId, lotId} = this.pageForm
window.open('/platform/recuperation/schoolUnionUserQuery/exportXlsx?year=' +
year
+ '&userName=' + userName
+ '&loginName=' + loginName
+ '&unionId=' + unionId
+ '&signUpMode=' + signUpMode
+ '&regionalNature=' + regionalNature
+ '&takePartInLineId=' + takePartInLineId
+ '&lotId=' + lotId)
},
openSetUpPart() {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.error('请选择要设置的人员')
return
}
this.$refs.setUpRef.onOpen(selection)
},
getConfig() {
this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => {
if (res.code === 0) {
this.config = res.data
}
})
},
getLines() {
this.$axios.post('/platform/recuperation/branchUnionUserQuery/listLine', {
year: this.pageForm.year,
signUpMode: this.pageForm.signUpMode,
regionalNature: this.pageForm.regionalNature
}).then(res => {
if (res.code === 0) {
this.takePartInLines = res.data
} else {
this.$message.warning(res.msg)
}
})
},
doSearch(){
this.getLines()
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.pageData()
}
},
async created() {
this.doSearch()
this.getConfig()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,136 @@
const setUpPart = {
template: /*language=HTML*/ `
<el-dialog :visible.sync="visible" title="设置参加人员" top="50px">
<el-row class="text-primary p20">
选择标段/参加时间(设置前请先勾选需要设置的用户)
</el-row>
<el-row type="flex" style="column-gap: 10px">
<el-select v-model="lotId" filterable clearable
placeholder="请选择标段"
style="width: 100%"
@change="lotChange">
<el-option v-for="item in config.lots"
:key="item.id"
:label="item.lotName"
:value="item.id">
</el-option>
</el-select>
<el-date-picker
v-model="takePartInTime"
type="date"
style="width: 100%"
@change="takePartInTimeChange"
value-format="yyyy-MM-dd"
placeholder="请选择参加时间">
</el-date-picker>
</el-row>
<el-row class="mt10">
<el-table :data="tableData" border ref="tableRef" row-key="id">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" label="序号" width="80"></el-table-column>
<el-table-column prop="loginName" label="一卡通号"></el-table-column>
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="unitName" label="单位"></el-table-column>
<el-table-column prop="unionName" label="工会"></el-table-column>
<el-table-column prop="signingUptime" label="报名时间"></el-table-column>
<el-table-column prop="takePartInTime" label="参加时间"></el-table-column>
<el-table-column prop="lotName" label="标段"></el-table-column>
</el-table>
</el-row>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</el-dialog>
`,
data() {
return {
visible: false,
config: {},
tableData: [],
lotId: null,
takePartInTime: null
}
},
methods: {
onOpen(selection) {
this.visible = true
this.tableData = JSON.parse(JSON.stringify(selection))
this.getModifyConfig()
},
async getModifyConfig() {
const res = await $.post('/platform/recuperation/config/findOne')
if (res.code === 0) {
this.config = res.data
}
},
lotChange(val) {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.error('请选择要设置的人员')
this.lotId = null
return
}
if (!val) {
this.$refs.tableRef.clearSelection()
return
}
const lot = this.config.lots.find(v => v.id === val)
this.tableData.map((v, index) => {
this.$set(this.tableData[index], "lotId", val)
this.$set(this.tableData[index], "lotName", lot.lotName)
})
},
takePartInTimeChange(val) {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.error('请选择要设置的人员')
this.takePartInTime = null
return
}
if (!val) {
this.$refs.tableRef.clearSelection()
return
}
this.tableData.map((v, index) => {
this.$set(this.tableData[index], "takePartInTime", val)
})
},
onSubmit() {
// 检查哪几条数据填写不完整
this.tableData.forEach((v, index) => {
if (!v.lotId || !v.takePartInTime) {
this.$message.error('第' + (index + 1) + '行数据填写不完整')
return
}
})
const data = this.tableData.map((v, index) => {
return{
lotId: v.lotId,
takePartInTime: v.takePartInTime,
id: v.id
}
})
this.$confirm('确定要提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async res => {
const {
code,
msg
} = await $.post("/platform/recuperation/branchUnionUserQuery/setUpParticipants", {data: JSON.stringify(data)})
if (code === 0) {
this.$message.success(msg)
this.$refs.tableRef.clearSelection()
this.visible = false
} else {
this.$message.error(msg)
}
})
}
}
};
@@ -109,8 +109,8 @@ layout("/layouts/platform.html"){
> >
<template v-slot="{ row }" v-if="column.prop === 'isDisabled'"> <template v-slot="{ row }" v-if="column.prop === 'isDisabled'">
<el-switch <el-switch
:active-value="true" :active-value="false"
:inactive-value="false" :inactive-value="true"
@change="(val)=>{lineStatusChange(row.id)}" @change="(val)=>{lineStatusChange(row.id)}"
active-color="#13ce66" active-color="#13ce66"
inactive-color="#ff4949" inactive-color="#ff4949"
@@ -189,6 +189,14 @@ layout("/layouts/platform.html"){
} }
}, },
methods: { methods: {
async lineStatusChange(id) {
const resp = await this.$axios.post(loc() + '/openClosedLine/' + id)
if (resp.code === 0) {
this.$message.success(resp.msg)
} else {
this.$message.warning(resp.msg)
}
},
async getEnumOptions(enumName) { async getEnumOptions(enumName) {
const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: enumName }) const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: enumName })
return resp.data return resp.data
@@ -0,0 +1,237 @@
const batchSelect = {
template: /*language=HTML*/ `
<div>
<el-dialog :close-on-click-modal="false" :visible.sync="setLineTimeDialog" title="统赋出行时间段信息" width="80%">
<el-form :model="formData" :rules="rules" label-width="0" ref="form" size="small">
<div v-for="(row,$index) in formData.times" :key="row.id" class="panel panel-default mt20"
style="border: none">
<div class="panel-heading"
style="background: #fafafa;border:1px solid #ebeef5;border-bottom: none;display: flex;align-items: center;justify-content: space-between">
<h3 class="panel-title">
出行时间段
</h3>
</div>
<el-row class="playPeriod">
<el-descriptions border :column="3" class="playPeriodTable">
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
报名开始时间
</template>
<el-form-item :prop="'times.' + $index + '.signUpStartTime'"
:rules="{required:true,message:'请选择报名开始时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择报名开始时间"
v-model="row.signUpStartTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
报名结束时间
</template>
<el-form-item :prop="'times.' + $index + '.signUpEndTime'"
:rules="{required:true,message:'请选择报名结束时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择报名结束时间"
@change="doSetChangeTime($index,row.signUpEndTime)"
v-model="row.signUpEndTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
变更截至时间
</template>
<el-form-item :prop="'times.' + $index + '.changeEndTime'"
:rules="{required:true,message:'请选择变更截至时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择变更截至时间"
v-model="row.changeEndTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
出行开始时间
</template>
<el-form-item :prop="'times.' + $index + '.playStartTime'"
:rules="{required:true,message:'请选择出行开始时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择出行开始时间"
v-model="row.playStartTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
出行结束时间
</template>
<el-form-item :prop="'times.' + $index + '.playEndTime'"
:rules="{required:true,message:'请选择出行结束时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择出行结束时间"
v-model="row.playEndTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-row>
</div>
<el-alert closable show-icon style="margin:10px 0"
title="温馨提醒:变更时间应该大于报名截至时间,小于出行时间。"
type="warning"></el-alert>
</el-form>
<el-row justify="end" type="flex">
<el-button @click="setLineTimeDialog = false">取 消</el-button>
<el-button @click="onSelect" type="primary">提 交</el-button>
</el-row>
</el-dialog>
</div>
`,
props: {
},
data() {
const validateGiveSignUpEndTime = (rule, value, callback) => {
if (!value) {
callback(new Error('请选择报名截至时间'))
}
if (this.formData.signUpStartTime) {
if (Date.parse(value) <= Date.parse(this.formData.signUpStartTime)) {
callback(new Error('报名截至时间必须大于报名开始时间'))
}
}
callback()
}
const validateGiveChangeEndTime = (rule, value, callback) => {
if (!value) {
callback(new Error('请选择变更截至时间'))
}
if (this.formData.signUpEndTime) {
if (Date.parse(value) <= Date.parse(this.formData.signUpEndTime)) {
callback(new Error('变更截至时间必须大于报名截至时间'))
}
}
callback()
}
const validateGivePlayEndTime = (rule, value, callback) => {
if (!value) {
callback(new Error('请选择出行结束时间'))
}
if (this.formData.playStartTime) {
if (Date.parse(value) <= Date.parse(this.formData.playStartTime)) {
callback(new Error('出行结束时间必须大于出行开始时间'))
}
}
callback()
}
return {
setLineTimeDialog: false,
rules: {
signUpStartTime: [{required: false, message: '请选择报名开始时间', trigger: ['change', 'blur']}],
signUpEndTime: [{required: false, validator: validateGiveSignUpEndTime, trigger: ['change', 'blur']}],
changeEndTime: [{required: false, validator: validateGiveChangeEndTime, trigger: ['change', 'blur']}],
playStartTime: [{required: false, message: '请选择出行开始时间', trigger: ['change', 'blur']}],
playEndTime: [{required: false, validator: validateGivePlayEndTime, trigger: ['change', 'blur']}],
},
formData: {
times: []
},
multipleSelection: [],
year: null,
}
},
methods: {
doSetChangeTime(index, value){
this.$set(this.formData.times[index], "changeEndTime", value)
},
async onOpen(multipleSelection, year) {
if (!multipleSelection || multipleSelection.length === 0) {
this.$message.warning('请在线路列表中勾选您想要统赋时间的线路');
return
}
this.multipleSelection = multipleSelection
this.year = year
this.formData = {
times: [{
signUpStartTime: '',
signUpEndTime: '',
changeEndTime: '',
playStartTime: '',
playEndTime: '',
}]
}
this.setLineTimeDialog = true
},
async onSelect() {
const valid = await this.$refs['form'].validate()
if (!valid) return
const confirm = await this.$confirm('请再次确认,是否为选择线路统赋时间?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm !== 'confirm') return
const lineIds = this.multipleSelection.map(v => v.id)
const fmtData = this.formData.times.map(v => {
return {
...v,
signUpMode: this.formData.signUpMode,
mode: GetQueryString('mode')
}
})
const resp = await this.$axios.post(loc() + '/setGiveLineTimes', {
lineIds: JSON.stringify(lineIds),
lineUnionSelects: JSON.stringify(fmtData),
year: this.year
})
if (resp.code === 0) {
this.setLineTimeDialog = false
this.$message.success(resp.msg)
} else {
this.$message.warning(resp.msg)
}
},
},
async created() {
},
style: /*language=CSS*/ `
.panel-heading {
border-color: #eeeff8;
border-top-left-radius: 0;
border-top-right-radius: 0;
padding: 10px 15px;
}
.panel-title {
font-weight: bold;
color: #777;
height: 16px;
line-height: 16px;
}
.text-right {
text-align: right;
margin-top: 20px;
}
`
}
@@ -0,0 +1,312 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.playPeriod .el-form-item {
margin-bottom: 0 !important;
}
.el-button--text {
padding: 0 20px;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
placeholder="请选择年度"
type="year"
@change="doSearch"
style="width: 100%"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="线路:">
<el-select @change="doSearch"
clearable
filterable
style="width: 100%"
placeholder="请选择线路"
v-model="pageForm.travelAgencyId">
<el-option :key="item.id"
:label="item.travelAgencyName"
:value="item.id"
v-for="item in travelAgencyOptions"></el-option>
</el-select>
</search-item>
<search-item label="线路类型:">
<el-select v-model="pageForm.regionalNature" placeholder="请选择线路类型" filterable clearable
@change="doSearch" :disabled="pageForm.mode == 1">
<el-option v-for="item in regionalNatureList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</search-item>
<search-item label="线路名称:">
<el-input @keyup.enter.native="doSearch" clearable clearable
placeholder="请输入线路名称"
style="width: 100%"
v-model="pageForm.keywords">
</el-input>
</search-item>
<search-item v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])" label="所属工会:">
<el-select @change="doSearch" v-model="pageForm.unionId" placeholder="请选择所属工会" filterable clearable>
<el-option v-for="item in unionList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="时间标段:">
<el-select @change="doSearch" clearable filterable
style="width: 100%" placeholder="请选择时间标段"
v-model="pageForm.lotId">
<el-option :key="item.id"
:label="item.lotName"
:value="item.id"
v-for="item in lotList"
></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt20">
<table-tool label="线路列表(温馨提示:如查询条件的年度为空时,已选择默认查询当年选择的线路)">
<el-button @click="showGiveTimes" type="primary"
size="small" style="margin-right: 10px">
一键统赋时间
</el-button>
<el-radio-group @change="doSearch" size="small" v-model="pageForm.selectStatus">
<el-radio-button :label="1">已选择</el-radio-button>
<el-radio-button :label="-1">可选择</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize" ref="table"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" reserve-selection width="55"
:selectable="(row)=>{return row.isDisabled==true || !(row.usId==null || row.usId == '')}"></el-table-column>
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
:show-overflow-tooltip="column.prop!=='playTime'"
v-if="pageForm.mode != 2 || (pageForm.mode == 2 && column.prop !== 'isOpen')"
v-for="column in tableColumns"
>
<template v-slot="{row:{signUpMode}}" v-if="column.prop==='signUpMode'">
{{ signUpModeList.find(v => v.value === signUpMode)?.label || '' }}
</template>
<template v-slot="{row:{createMode}}" v-else-if="column.prop==='createMode'">
{{ createModeList.find(v => v.value === createMode)?.label || '' }}
</template>
<template v-slot="{ row }" v-else-if="column.prop==='belongUnionName'">
{{ pageForm.mode == 2 && pageForm.selectStatus == 1 ? '校工会' : row.belongUnionName }}
</template>
<template v-slot="{ row }" v-else-if="column.prop==='playTime'">
<template v-if="row.playTimes">
<el-tooltip placement="top">
<div slot="content">
<div v-for="(t,ti) in row.playTimes.split(',')" :key="t"
:class="[ti==row.playTimes.split(',').length-1?'':'mb10']">
{{t}}
</div>
</div>
<div style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis">
{{row.playTimes}}
</div>
</el-tooltip>
</template>
<el-button v-else @click="openSetLineTime(row)" type="text">
选择并设置出行时间段
</el-button>
</template>
<template v-slot="{row}" v-else-if="column.prop==='createUnionName'">
<span v-if="!row.isSelect">
{{row.createUnionName}}
</span>
<span v-else>{{row.belongUnionName}}</span>
</template>
<template v-slot="{row}" v-else-if="column.prop==='isOpen'">
<template v-if="row.usId">
<el-switch
@change="doEditOpen(row)"
v-model="row.isOpen"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</template>
<template v-else>
<span>暂未选择</span>
</template>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template v-slot="{ row }">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{action:openViewLineInfo,value:row}">
查看线路基本信息
</el-dropdown-item>
<el-dropdown-item :command="{action:openViewTimeSlot,value:row}" v-if="row.isSelect">
查看出行时间段
</el-dropdown-item>
<el-dropdown-item :command="{action:openSetLineTime,value:row}" v-if="!row.isSelect">
选择设置出行时间段
</el-dropdown-item>
<el-dropdown-item :command="{action:openSetLineTime,value:row}" v-if="row.isSelect">
修改出行时间段
</el-dropdown-item>
<el-dropdown-item :command="{action:cancelSelect,value:row}" v-if="row.isSelect">
取消选择
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #view>
<info ref="infoRef"></info>
</template>
</guava>
<select-line ref="selectRef" @refresh="refresh"></select-line>
<batch-select ref="batchSelectRef" @refresh="batchRefresh"></batch-select>
<time-info ref="timeInfoRef" :sign-mode-list="signUpModeList"></time-info>
</div>
<script>
<!--#include('../line/info.js'){}#-->
<!--#include('select.js'){}#-->
<!--#include('batchSelect.js'){}#-->
<!--#include('timeInfo.js'){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"info": info,
"select-line": select,
"batch-select": batchSelect,
"time-info": timeInfo,
},
data() {
return {
unionList: [],
tableColumns: [
{label: '线路名称', prop: 'lineName', sortable: true},
{label: '线路类型', prop: 'regionalNature', sortable: true},
{label: '时间标段', prop: 'lotName', sortable: true, sortProp: 'lotValue'},
{label: '出行时间', prop: 'playTime', sortable: 'custom', sortProp: 'playStartTime', width: 230},
{label: '承担旅行社', prop: 'travelAgencyName', sortable: true},
{label: '组织形式', prop: 'signUpMode', sortable: true},
{label: '选择工会', prop: 'belongUnionName', sortable: true},
{label: '是否开放对外报名', prop: 'isOpen', sortable: true},
],
pageForm: {
keywords: null,
selectStatus: -1,
unionId: null,
regionalNature: '省内'
},
travelAgencyOptions: [],
regionalNatureList: [{label:'全部线路',name:'provinceAll',ordinal:0,provinceIn:'provinceIn',provinceOut:'provinceOut',value:'全部'}],
lotList: [],
multipleSelection: [],
createModeList: [],
signUpModeList: [],
}
},
methods: {
async cancelSelect({applyCount, id: lineId, usUnionId: unionId}) {
const msg = applyCount > 0 ? '已经有教工选择本线路,请确认是否取消选择本线路,一旦取消将清空报名人员!!!' : '您确定要取消吗?'
const confirm = await this.$confirm(msg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm !== 'confirm') return
const resp = await this.$axios.post(loc() + '/deSelect', {lineId, unionId})
if (resp.code === 0) {
this.doSearch()
this.$message.success(resp.msg)
} else {
this.$message.warning(resp.msg)
}
},
refresh() {
this.doSearch()
},
batchRefresh() {
this.$refs.table.clearSelection()
this.doSearch()
},
openViewTimeSlot({id, usUnionId}) {
this.$refs.timeInfoRef.onOpen(id, usUnionId, this.pageForm.year)
},
openViewLineInfo(row) {
this.$refs.guava.view(() => {
this.$refs.infoRef.onOpen(row.id)
})
},
openSetLineTime({id, lineName, usUnionId, signUpMode}) {
this.$refs.selectRef.onOpen(id, lineName, usUnionId, signUpMode, this.pageForm.year)
},
handleSelectionChange(val) {
this.multipleSelection = val
},
showGiveTimes() {
this.$refs.batchSelectRef.onOpen(this.multipleSelection, this.pageForm.year)
},
pageData() {
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
async getTravelAgencyOptions() {
const {data} = await this.$axios.post(loc() + '/getTravelAgencyOptions')
this.travelAgencyOptions = data
},
async getEnumOptions(enumName) {
const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: enumName })
return resp.data
},
},
async created() {
this.$set(this.pageForm, 'mode', Number(GetQueryString('mode')))
if(this.pageForm.mode === 2) {
this.$set(this.pageForm, 'regionalNature', '全部')
}
this.unionList = await this.$businessTool.listUnion()
this.createModeList = await this.getEnumOptions('RecuperationLineCreateMode')
this.signUpModeList = await this.getEnumOptions('RecuperationSignUpMode')
this.regionalNatureList.push(...await this.getEnumOptions('RecuperationProvinceType'))
this.travelAgencyOptions = this.getTravelAgencyOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,337 @@
const select = {
template: /*language=HTML*/ `
<div>
<el-dialog :close-on-click-modal="false" :visible.sync="setLineTimeDialog" title="设置出行时间段信息" width="80%">
<el-form :model="formData" :rules="rules" label-width="0" ref="form" size="small">
<h4>{{formData.lineName}}</h4>
<div v-for="(row,$index) in formData.times" :key="row.id" class="panel panel-default mt20"
style="border: none">
<div class="panel-heading"
style="background: #fafafa;border:1px solid #ebeef5;border-bottom: none;display: flex;align-items: center;justify-content: space-between">
<h3 class="panel-title">
时间段{{$index+1}}
</h3>
<el-button icon="el-icon-circle-close" circle size="mini" type="danger"
@click="formData.times.splice($index,1)"></el-button>
</div>
<el-row class="playPeriod">
<el-descriptions border :column="3" class="playPeriodTable">
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
报名开始时间
</template>
<el-form-item :prop="'times.' + $index + '.signUpStartTime'"
:rules="{required:true,message:'请选择报名开始时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择报名开始时间"
v-model="row.signUpStartTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
报名结束时间
</template>
<el-form-item :prop="'times.' + $index + '.signUpEndTime'"
:rules="{required:true,message:'请选择报名结束时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择报名结束时间"
@change="doSetChangeTime($index,row.signUpEndTime)"
v-model="row.signUpEndTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
变更截至时间
</template>
<el-form-item :prop="'times.' + $index + '.changeEndTime'"
:rules="{required:true,message:'请选择变更截至时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择变更截至时间"
v-model="row.changeEndTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
出行开始时间
</template>
<el-form-item :prop="'times.' + $index + '.playStartTime'"
:rules="{required:true,message:'请选择出行开始时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择出行开始时间"
v-model="row.playStartTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
出行结束时间
</template>
<el-form-item :prop="'times.' + $index + '.playEndTime'"
:rules="{required:true,message:'请选择出行结束时间',trigger:['change','blur']}"
label-width="0">
<el-date-picker style="width: 100%"
type="datetime"
placeholder="请选择出行结束时间"
v-model="row.playEndTime"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
联系人
</template>
<el-form-item :prop="'times.' + $index + '.contact'"
:rules="{required:true,message:'请输入联系人',trigger:['change','blur']}"
label-width="0">
<el-input placeholder="请输入联系人" clearable maxlength="10" v-model="row.contact"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span class="text-danger">*</span>
联系方式
</template>
<el-form-item :prop="'times.' + $index + '.contactPhone'"
:rules="[
{ required: true, message: '手机号码不能为空', trigger: 'blur' },
{ pattern: /^1[34578]\\d{9}$/, message: '手机号码格式不正确', trigger: 'blur' }
]"
label-width="0">
<el-input placeholder="请输入联系方式" clearable maxlength="11" v-model="row.contactPhone"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="最少参与教工">
<el-form-item :prop="'times.' + $index + '.minimumGroupSize'"
:rules="[
{ required: true, message: '最少参与教工不能为空', trigger: 'blur' },
{ pattern: /^[0-9]*$/, message: '最少参与教工格式不正确', trigger: 'blur' }
]"
label-width="0">
<el-input placeholder="请输入最少参与教工" clearable v-model="row.minimumGroupSize"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="交通工具">
<el-form-item :prop="'times.' + $index + '.trafficTools'"
:rules="{required:false,message:'请输入交通工具',trigger:['change','blur']}"
label-width="0">
<el-input placeholder="请输入交通工具" clearable v-model="row.trafficTools"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="预计费用(元/人次)">
<el-form-item :prop="'times.' + $index + '.estimatedCost'"
:rules="{required:true,message:'请输入预计费用',trigger:['change','blur']}"
label-width="0">
<el-input placeholder="请输入预计费用" clearable v-model="row.estimatedCost"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="成团人数包括家属">
<el-form-item :prop="'times.' + $index + '.estimatedFamilyNumbers'"
:rules="[
{ required: false, message: '成团人数包括家属不能为空', trigger: 'blur' },
{ pattern: /^[0-9]*$/, message: '成团人数包括家属格式不正确', trigger: 'blur' }
]"
label-width="0">
<el-input clearable v-model="row.estimatedFamilyNumbers"
placeholder="省外线路人数上限,不限制请忽略"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="是否开启">
<el-form-item :prop="'times.' + $index + '.enable'"
label-width="0">
<el-switch
v-model="row.enable"
:active-value="true"
:inactive-value="false"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-row>
</div>
<div class="text-right">
<el-button
@click="formData.times.push({enable:true,minimumGroupSize:lineConfig.groupNumber,estimatedCost:lineConfig.cost})"
size="mini" type="primary">新增出行时间
</el-button>
</div>
<el-alert closable show-icon style="margin:10px 0"
title="温馨提醒:变更时间应该大于报名截至时间,小于出行时间。"
type="warning"></el-alert>
</el-form>
<el-row justify="end" type="flex">
<el-button @click="setLineTimeDialog = false">取 消</el-button>
<el-button @click="onSelect" type="primary">提 交</el-button>
</el-row>
</el-dialog>
</div>
`,
props: {
},
data() {
const validateSignUpEndTime = (rule, value, callback) => {
if (!value) {
callback(new Error('请选择报名截至时间'))
}
if (this.formData.signUpStartTime) {
if (Date.parse(value) <= Date.parse(this.formData.signUpStartTime)) {
callback(new Error('报名截至时间必须大于报名开始时间'))
}
}
callback()
}
const validateChangeEndTime = (rule, value, callback) => {
if (!value) {
callback(new Error('请选择变更截至时间'))
}
if (this.formData.signUpEndTime) {
if (Date.parse(value) <= Date.parse(this.formData.signUpEndTime)) {
callback(new Error('变更截至时间必须大于报名截至时间'))
}
}
callback()
}
const validatePlayEndTime = (rule, value, callback) => {
if (!value) {
callback(new Error('请选择出行结束时间'))
}
if (this.formData.playStartTime) {
if (Date.parse(value) <= Date.parse(this.formData.playStartTime)) {
callback(new Error('出行结束时间必须大于出行开始时间'))
}
}
callback()
}
return {
setLineTimeDialog: false,
rules: {
signUpStartTime: [{required: true, message: '请选择报名开始时间', trigger: ['change', 'blur']}],
signUpEndTime: [{required: true, validator: validateSignUpEndTime, trigger: ['change', 'blur']}],
changeEndTime: [{required: true, validator: validateChangeEndTime, trigger: ['change', 'blur']}],
playStartTime: [{required: true, message: '请选择出行开始时间', trigger: ['change', 'blur']}],
playEndTime: [{required: true, validator: validatePlayEndTime, trigger: ['change', 'blur']}],
},
formData: {
signUpStartTime: null,
signUpEndTime: null,
changeEndTime: null,
playStartTime: null,
playEndTime: null,
id: null,
lineId: null,
times: []
},
lineConfig: {},
}
},
methods: {
doSetChangeTime(index, value){
this.$set(this.formData.times[index], "changeEndTime", value)
},
async getLineConfig(lineId) {
const {data} = await this.$axios.post(loc() + '/getLineConfig/' + lineId)
this.lineConfig = data
},
async onOpen(id, lineName, usUnionId, signUpMode, year) {
await this.getLineConfig(id)
const resp = await this.$axios.post(loc() + '/selectLineInfo', {
lineId: id,
unionId: usUnionId,
mode: GetQueryString('mode'),
year: year
})
if (resp.code === 0 && resp.data) {
this.formData = {
times: []
}
if (resp.data && resp.data.length > 0) {
this.$set(this.formData, 'times', resp.data)
} else {
this.formData.times.push({
enable: true,
minimumGroupSize: this.lineConfig.groupNumber,
estimatedCost: this.lineConfig.cost
})
}
this.formData.lineId = id
this.formData.signUpMode = signUpMode
this.$set(this.formData, 'lineName', lineName)
this.setLineTimeDialog = true
} else {
this.$message.warning(resp.msg)
}
},
async onSelect() {
const valid = await this.$refs['form'].validate()
if (!valid) return
const confirm = await this.$confirm('请再次确认,是否选择此线路为疗休养线路?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm !== 'confirm') return
const fmtData = this.formData.times.map(v => {
return {
...v,
lineId: this.formData.lineId,
signUpMode: this.formData.signUpMode,
mode: GetQueryString('mode')
}
})
const resp = await this.$axios.post(loc() + '/selectLineTimes', {lineSelects: JSON.stringify(fmtData)})
if (resp.code === 0) {
this.setLineTimeDialog = false
this.$emit('refresh')
this.$message.success(resp.msg)
} else {
this.$message.warning(resp.msg)
}
},
},
async created() {
},
style: /*language=CSS*/ `
.panel-heading {
border-color: #eeeff8;
border-top-left-radius: 0;
border-top-right-radius: 0;
padding: 10px 15px;
}
.panel-title {
font-weight: bold;
color: #777;
height: 16px;
line-height: 16px;
}
.text-right {
text-align: right;
margin-top: 20px;
}
`
}
@@ -0,0 +1,115 @@
const timeInfo = {
template: /*language=HTML*/ `
<div>
<el-dialog :close-on-click-modal="false" :visible.sync="timeLotsDialogVisible" title="查看出行时间段信息" width="80%">
<div v-for="(row,$index) in timeLots" :key="row.id" class="panel panel-default mt20" style="border: none">
<div class="panel-heading"
style="background: #fafafa;border:1px solid #ebeef5;border-bottom: none;display: flex;align-items: center;justify-content: space-between">
<h3 class="panel-title">
时间段{{$index+1}}
</h3>
</div>
<el-row class="playPeriod">
<el-descriptions border :column="3" class="playPeriodTable">
<el-descriptions-item label="报名开始时间">
{{row.signUpStartTime}}
</el-descriptions-item>
<el-descriptions-item label="报名结束时间">
{{row.signUpEndTime}}
</el-descriptions-item>
<el-descriptions-item label="变更截至时间">
{{row.changeEndTime}}
</el-descriptions-item>
<el-descriptions-item label="出行开始时间">
{{row.playStartTime}}
</el-descriptions-item>
<el-descriptions-item label="出行结束时间">
{{row.playEndTime}}
</el-descriptions-item>
<el-descriptions-item label="联系人">
{{row.contact}}
</el-descriptions-item>
<el-descriptions-item label="联系方式">
{{row.contactPhone}}
</el-descriptions-item>
<el-descriptions-item label="最少参与教工">
{{row.minimumGroupSize}}
</el-descriptions-item>
<el-descriptions-item label="交通工具">
{{row.trafficTools}}
</el-descriptions-item>
<el-descriptions-item label="预计费用(元/人次)">
{{row.estimatedCost}}
</el-descriptions-item>
<el-descriptions-item label="成团人数包括家属">
{{row.estimatedFamilyNumbers}}
</el-descriptions-item>
<el-descriptions-item label="是否开启">
<el-switch
disabled
v-model="row.enable"
:active-value="true"
:inactive-value="false"
active-color="#13ce66"
inactive-color="#ff4949">
</el-switch>
</el-descriptions-item>
<el-descriptions-item label="组织形式">
{{ signModeList.find(v => v.value === row.signUpMode)?.label || '' }}
</el-descriptions-item>
</el-descriptions>
</el-row>
</div>
</el-dialog>
</div>
`,
props: {
signModeList: {
type: Array,
required: false
},
},
data() {
return {
timeLotsDialogVisible: false,
timeLots: [],
}
},
methods: {
async onOpen(id, usUnionId, year) {
const resp = await this.$axios.post(loc() + '/selectLineInfo', {
lineId: id,
unionId: usUnionId,
mode: GetQueryString('mode'),
year: year
})
if (resp.code === 0) {
this.timeLots = resp.data
this.timeLotsDialogVisible = true
} else {
this.$message.warning(resp.msg)
}
},
},
style: /*language=CSS*/ `
.panel-heading {
border-color: #eeeff8;
border-top-left-radius: 0;
border-top-right-radius: 0;
padding: 10px 15px;
}
.panel-title {
font-weight: bold;
color: #777;
height: 16px;
line-height: 16px;
}
.text-right {
text-align: right;
margin-top: 20px;
}
.el-dialog__body {
padding-top: 0;
}
`
}
@@ -0,0 +1,193 @@
const editForm = {
template: /*language=HTML*/ `
<el-dialog title="编辑" :visible.sync="visible" top="50px">
<el-form :model="formData" label-width="120px" :formRules="formRules" ref="formRef"
style="margin-right: 40px">
<el-row>
<el-col span="12">
<el-form-item prop="loginName" label="工号">
<el-input v-model="formData.loginName" readonly></el-input>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="userName" label="姓名">
<el-input v-model="formData.userName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col span="12">
<el-form-item prop="userName" label="手机号">
<el-input v-model="formData.mobile" readonly></el-input>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="userName" label="身份证号">
<el-input v-model="formData.idCard" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col span="12">
<el-form-item prop="unionName" label="工会">
<el-input v-model="formData.unionName" readonly></el-input>
</el-form-item>
</el-col>
<el-col span="12">
<el-form-item prop="unitName" label="单位">
<el-input v-model="formData.unitName" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item prop="prop" :label="labelName">
<template v-if="config.familyInfo == 2">
<el-collapse v-model="activeNames">
<el-collapse-item title="点击可展开详细信息" name="1">
<el-card shadow="never">
<el-table :data="formData.companionList">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="身份证号" prop="idCard"></el-table-column>
<el-table-column label="年龄" prop="age"></el-table-column>
<el-table-column label="床型" prop="bedType">
<template v-slot="{row}">
{{ row.bedInfo.bedType }}
</template>
</el-table-column>
<el-table-column label="床位" prop="bedNum">
<template v-slot="{row}">
{{ row.bedInfo.bedNum }}
</template>
</el-table-column>
<el-table-column label="意向拼床人" prop="otherSleepUser">
<template v-slot="{row}">
{{ row.bedInfo.otherSleepUser ?
row.bedInfo.otherSleepUser : '暂无' }}
</template>
</el-table-column>
<el-table-column label="关系" prop="relation"></el-table-column>
</el-table>
</el-card>
</el-collapse-item>
</el-collapse>
</template>
<template v-else>
<el-input v-model="formData.bedType" readonly></el-input>
</template>
</el-form-item>
<el-form-item prop="travelLine" :label="lineLabelName">
<el-select v-model="formData.takePartInLineId" filterable clearable
placeholder="请选择线路"
@change="validateLine"
style="width: 100%">
<el-option v-for="item in unionSelectLines"
:key="item.id"
:label="item.lineName + '-' + item.regionalNature + '【' + item.lotName + '】' + '' + item.playStartTime + '至' + item.playEndTime + '' + '' + item.signUpMode + ''"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item prop="specificTime" label="出行时间" v-if="pageForm.state==='3'">-->
<!-- <el-select v-model="formData.specificTime" filterable clearable-->
<!-- placeholder="请选择出行时间"-->
<!-- style="width: 100%">-->
<!-- <el-option v-for="item in editSpecificTimes"-->
<!-- :key="item"-->
<!-- :label="item"-->
<!-- :value="item">-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="onSubmit">确 定</el-button>
</div>
</template>
</el-dialog>
`,
data() {
return {
visible: false,
year: null,
config: {},
formData: {},
formRules: {},
labelName: null,
lineLabelName: '线路',
unionSelectLines: [],
activeNames: []
}
},
methods: {
async onOpen(id, year) {
this.year = year
this.visible = true
await this.getUnionSelectLine()
await this.getModifyConfig()
const {code, msg, data} = await this.$axios.get("/platform/recuperation/schoolUnionUserQuery/findOne", {id})
if (code === 0) {
this.formData = data
if (this.config.familyInfo === 2) {
this.labelName = "家属信息"
} else {
this.editFormData.bedType = data.familyNumber
this.labelName = "家属数量"
}
} else {
this.$message.error(msg)
}
},
async getModifyConfig() {
const {code, data, msg} = await this.$axios.post('/platform/recuperation/config/fetchOne')
if (code === 0) {
this.config = data
} else {
this.$message.error(msg)
}
},
async getUnionSelectLine() {
const resp = await this.$axios.post('/platform/recuperation/user/query/getUnionSelectLine', {
year: this.year,
signUpMode: 1,
})
if (resp.code === 0) {
this.unionSelectLines = resp.data
}
},
async validateLine() {
const resp = await this.$axios.post('/platform/recuperation/line/enroll/validSignUpInfo'
, {enroll: JSON.stringify(this.editFormData)})
if (resp.code !== 0) {
this.$message.warning(resp.msg)
this.formData.takePartInLineId = ''
}
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$confirm('您确定要修改报名信息吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
if (!this.formData.takePartInLineId && !this.formData.takePartInBaseManagementId) {
this.$message.warning('请选择线路')
return
}
const {code,msg} = await this.$axios.post('/platform/recuperation/user/query/doEdit', this.formData)
if (code === 0) {
this.$message.success(msg)
this.visible = false
this.$emit('refresh')
} else {
this.$message.error(msg)
}
}).catch()
}
})
}
}
};
@@ -0,0 +1,375 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.filter-container {
margin-bottom: 10px;
border-radius: 4px;
}
.filter-container .el-form {
padding: 10px 15px;
}
.form-row {
display: flex;
gap: 20px;
margin-bottom: 22px;
flex-wrap: wrap;
}
.form-row .el-form-item {
flex: 1;
min-width: 240px;
margin-bottom: 0;
}
.flex-grow-1 {
flex: 1;
}
.route-line {
display: flex;
align-items: center;
margin-bottom: 22px;
}
.route-line-title {
width: 90px;
text-align: right;
padding-right: 12px;
color: #606266;
font-size: 14px;
line-height: 40px;
}
.route-line-content {
flex: 1;
}
.route-radio-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.route-radio-group .el-radio {
margin-right: 0;
margin-bottom: 10px;
}
.button-container {
display: flex;
justify-content: center;
padding-top: 15px;
border-top: 1px dashed #ebeef5;
}
.button-container .el-button {
padding-left: 25px;
padding-right: 25px;
margin: 0 15px;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never" class="filter-container">
<el-form :model="pageForm" ref="pageFormRef" label-width="90px" size="medium">
<div class="form-row">
<el-form-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
placeholder="选择年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="pageForm.userName" placeholder="请输入姓名" clearable
prefix-icon="el-icon-user"></el-input>
</el-form-item>
<el-form-item label="工号">
<el-input v-model="pageForm.loginName" placeholder="请输入工号" clearable
prefix-icon="el-icon-postcard"></el-input>
</el-form-item>
</div>
<div class="form-row">
<el-form-item label="分工会">
<el-select v-model="pageForm.unionId"
@change="doSearch"
placeholder="请选择所属工会"
filterable
clearable
style="width: 100%">
<el-option
v-for="item in unionOptions"
:key="item.id"
:label="item.unionname"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</div>
<div class="route-line">
<div class="route-line-title">区域</div>
<div class="route-line-content">
<el-radio-group @change="doSearch"
size="small"
v-model="pageForm.regionalNature">
<el-radio label="" border>全部</el-radio>
<el-radio label="省内" border>省内</el-radio>
<el-radio label="省外" border>省外</el-radio>
</el-radio-group>
</div>
</div>
<div class="form-row">
<el-form-item label="线路选择">
<el-select v-model="pageForm.takePartInLineId" placeholder="请选择线路" clearable
style="width: 100%">
<el-option
v-for="item in takePartInLines"
:key="item.takePartInLineId"
:label="item.lineName+''+item.unionName+''"
:value="item.takePartInLineId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="标段">
<el-select v-model="pageForm.lotId" placeholder="请选择标段" clearable style="width: 100%">
<el-option
v-for="item in config.lots"
:key="item.id"
:label="item.lotName"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item class="flex-grow-1"></el-form-item>
</div>
<div class="button-container">
<el-button type="primary" icon="el-icon-search" round @click="doSearch">查询</el-button>
<el-button icon="el-icon-refresh" round @click="resetQuery">重置</el-button>
</div>
</el-form>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="人员列表" ref="table_tool">
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
导出未报名人员
</el-button>
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="doExport">
导出
</el-button>
<el-button icon="el-icon-s-promotion" size="small" type="primary"
@click="openSetUpPart"
>设置参加人员
</el-button>
</table-tool>
<el-table :data="tableData" row-key="id" style="width: 100%" ref="tableRef">
<el-table-column reserve-selection type="selection" width="55"></el-table-column>
<el-table-column align="center" header-align="center" type="index" label="序号" :index="indexMethod"
width="80px"></el-table-column>
<el-table-column
align="center"
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
:label="column.label"
:prop="column.prop"
:key="column.prop"
:sortable="column.sortable"
>
<template v-slot="{row}" v-if="column.prop=='isFamily'">
<el-link v-if="!row.familyNumber" type="primary" @click="openUser(row)">
{{row.isFamily?'携带':'未携带'}}{{row.isFamily}}
</el-link>
<el-link v-else type="primary">
{{row.familyNumber?'携带':'未携带'}}{{row.familyNumber}}
</el-link>
</template>
<template v-slot="{row}" v-else-if="column.prop=='times'">
<div v-if="row.playStartTime">{{row.playStartTime}}</div>
<div v-else>{{row.playStartTime1}}</div>
</template>
<template v-slot="{row}" v-else-if="column.prop=='isTakePartIn'">
{{row.isTakePartIn?'已参加':'未参加'}}
</template>
<template v-slot="{row}" v-else-if="column.prop=='stateId'">
<span v-if="row.stateId">
</span>
<sapn v-else style="color: #67C23A">暂无</sapn>
</template>
<template v-slot="{row}" v-else-if="column.prop=='lineOrMaName'">
{{row.lineName?row.lineName:row.baseName?row.baseName:row.travelAgencyName}}
</template>
</el-table-column>
<el-table-column v-if="pageForm.state=='1'||pageForm.state=='3'" align="center"
prop="lotName"
show-overflow-tooltip
header-align="center"
label="标段"
sortable>
<template v-slot="{row}">
{{row.lotName}}
</template>
</el-table-column>
<el-table-column label="操作" width="250px">
<template v-slot="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button @click="onDelete(row)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
<el-dialog title="查看报名信息" :visible.sync="viewVisible" top="50px">
<enroll-info ref="viewEnrollInfoRef"></enroll-info>
</el-dialog>
<set-up-part ref="setUpRef"></set-up-part>
<edit-form ref="editRef" @refresh="doSearch"></edit-form>
</div>
<script>
<!--#include('setUpPart.js'){}#-->
<!--#include('editForm.js'){}#-->
<!--#include('../line/info.js'){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
'line-info': info,
'set-up-part': setUpPart,
'edit-form': editForm
},
data() {
return {
pageForm: {
year: new Date().getFullYear().toString(),
loginName: '',
userName: '',
takePartInLineId: '',
unionId: '',
signUpMode: 1,
lotId: '',
regionalNature: ''
},
takePartInLines: [],
tableColumns: [
{prop: 'loginName', label: '工号'},
{prop: 'userName', label: '姓名'},
{prop: 'unitName', label: '所属单位', sortable: true},
{prop: 'unionName', label: '所属工会', sortable: true},
{prop: 'lineOrMaName', label: '线路'},
{prop: 'times', label: '出行时间'},
{prop: 'isFamily', label: '是否携带家属'},
{prop: 'isTakePartIn', label: '是否参加'}
],
viewVisible: false,
unionOptions: [],
config: {}
}
},
methods: {
resetQuery() {
this.pageForm = {
year: new Date().getFullYear().toString(),
loginName: '',
userName: '',
takePartInLineId: '',
unionId: '',
signUpMode: 1,
lotId: '',
regionalNature: '',
pageNumber: 1,
pageSize: 10,
totalCount: 0,
}
this.doSearch()
},
openView(row) {
this.viewVisible = true
this.$nextTick(() => {
this.$refs.viewEnrollInfoRef.openView(row.id)
})
},
openEdit(row) {
this.$refs.editRef.onOpen(row.id)
},
onDelete(row) {
this.$confirm("您确定要删除【<span style='color: red'>" + row.userName + "</span>】的信息吗?", '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning'
}).then(async () => {
const {code, msg} = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/deleteMyEnrollInfoById', {
id: row.id
})
if (code === 0) {
this.doSearch()
this.$message.success(msg)
} else {
this.$message.warning(msg)
}
})
},
noSignExport() {
window.open('/platform/recuperation/schoolUnionUserQuery/noSignExport')
},
doExport() {
const {year, userName, loginName, unionId, signUpMode, regionalNature, takePartInLineId, lotId} = this.pageForm
window.open('/platform/recuperation/schoolUnionUserQuery/exportXlsx?year=' +
year
+ '&userName=' + userName
+ '&loginName=' + loginName
+ '&unionId=' + unionId
+ '&signUpMode=' + signUpMode
+ '&regionalNature=' + regionalNature
+ '&takePartInLineId=' + takePartInLineId
+ '&lotId=' + lotId)
},
openSetUpPart() {
const selection = this.$refs.tableRef.selection
console.log(selection)
if (selection.length === 0) {
this.$message.error('请选择要设置的人员')
return
}
this.$refs.setUpRef.onOpen(selection)
},
getConfig() {
this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => {
if (res.code === 0) {
this.config = res.data
}
})
},
getLines() {
this.$axios.post('/platform/recuperation/schoolUnionUserQuery/listLine', {
year: this.pageForm.year,
unionId: this.pageForm.unionId,
signUpMode: this.pageForm.signUpMode,
regionalNature: this.pageForm.regionalNature
}).then(res => {
if (res.code === 0) {
this.takePartInLines = res.data
} else {
this.$message.warning(res.msg)
}
})
},
doSearch(){
this.getLines()
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.pageData()
}
},
async created() {
this.doSearch()
this.getConfig()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,139 @@
const setUpPart = {
template: /*language=HTML*/ `
<el-dialog :visible.sync="visible" title="设置参加人员" top="50px">
<el-row class="text-primary p20">
选择标段/参加时间(设置前请先勾选需要设置的用户)
</el-row>
<el-row type="flex" style="column-gap: 10px">
<el-select v-model="lotId" filterable clearable
placeholder="请选择标段"
style="width: 100%"
@change="lotChange">
<el-option v-for="item in config.lots"
:key="item.id"
:label="item.lotName"
:value="item.id">
</el-option>
</el-select>
<el-date-picker
v-model="takePartInTime"
type="date"
style="width: 100%"
@change="takePartInTimeChange"
value-format="yyyy-MM-dd"
placeholder="请选择参加时间">
</el-date-picker>
</el-row>
<el-row class="mt10">
<el-table :data="tableData" border ref="tableRef" row-key="id">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" label="序号" width="80"></el-table-column>
<el-table-column prop="loginName" label="一卡通号"></el-table-column>
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="unitName" label="单位"></el-table-column>
<el-table-column prop="unionName" label="工会"></el-table-column>
<el-table-column prop="signingUptime" label="报名时间"></el-table-column>
<el-table-column prop="takePartInTime" label="参加时间"></el-table-column>
<el-table-column prop="lotName" label="标段"></el-table-column>
</el-table>
</el-row>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</template>
</el-dialog>
`,
data() {
return {
visible: false,
config: {},
tableData: [],
lotId: null,
takePartInTime: null
}
},
methods: {
onOpen(selection) {
this.visible = true
this.tableData = JSON.parse(JSON.stringify(selection))
this.getModifyConfig()
},
async getModifyConfig() {
const res = await this.$axios.post('/platform/recuperation/config/fetchOne')
if (res.code === 0) {
this.config = res.data
}
},
// 标段改变
lotChange(val) {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.error('请选择要设置的人员')
this.lotId = null
return
}
if (!val) {
this.$refs.tableRef.clearSelection()
return
}
const lot = this.config.lots.find(v => v.id === val)
this.tableData.map((v, index) => {
this.$set(this.tableData[index], "lotId", val)
this.$set(this.tableData[index], "lotName", lot.lotName)
})
},
// 参加时间改变
takePartInTimeChange(val) {
const selection = this.$refs.tableRef.selection
if (selection.length === 0) {
this.$message.error('请选择要设置的人员')
this.takePartInTime = null
return
}
if (!val) {
this.$refs.tableRef.clearSelection()
return
}
this.tableData.map((v, index) => {
this.$set(this.tableData[index], "takePartInTime", val)
})
},
// 确定提交
onSubmit() {
// 检查哪几条数据填写不完整
this.tableData.forEach((v, index) => {
if (!v.lotId || !v.takePartInTime) {
this.$message.error('第' + (index + 1) + '行数据填写不完整')
return
}
})
const data = this.tableData.map((v, index) => {
return{
lotId: v.lotId,
takePartInTime: v.takePartInTime,
id: v.id
}
})
this.$confirm('确定要提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async res => {
const {
code,
msg
} = await this.$axios.post("/platform/recuperation/schoolUnionUserQuery/setUpParticipants", {data: JSON.stringify(data)})
if (code === 0) {
this.$message.success(msg)
this.$refs.tableRef.clearSelection()
this.visible = false
} else {
this.$message.error(msg)
}
})
}
}
};
@@ -0,0 +1,187 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
</style>
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度:">
<el-date-picker
placeholder="请选择年度"
type="year"
@change="yearChange"
style="width: 100%"
v-model="pageForm.year"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="线路:">
<el-select @change="doSearch" filterable
placeholder="请选择线路"
style="width: 100%;" clearable
v-model="pageForm.lineId">
<el-option :label="item.lineName + '' + item.unionName + ''" :value="item.id"
:key="value.id"
v-for="item in lineList"></el-option>
</el-select>
</search-item>
<search-item label="关键字:">
<el-input placeholder="请输入姓名或工号查询" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch"></el-input>
</search-item>
<search-item label="所属工会:">
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会" filterable clearable @change="doSearch">
<el-option v-for="item in unionList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位:">
<el-select v-model="pageForm.unitId" placeholder="请选择所属单位" filterable clearable @change="doSearch">
<el-option v-for="item in unitList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="评分:">
<el-select clearable filterable placeholder="请选择评分"
style="width: 100%" @change="doSearch"
v-model="pageForm.evaluateScore">
<el-option
:key="item.code"
:label="item.name"
:value="item.code"
v-for="item in evaluateScores">
</el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt20">
<table-tool label="评价名单">
<el-button type="primary" size="small" @click="exportEvaluate">
<i class="el-icon-download"></i>
导出名单
</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize">
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
</el-table-column>
<el-table-column label="操作" width="100">
<template v-slot="{ row }">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
<el-dialog
:close-on-click-modal="false"
:visible.sync="evaluateDialogVisible"
title="评分内容"
width="30%">
<el-form :model="formData" label-width="60px" ref="form">
<el-form-item :rules="[{ required: true, message: ''}]" label="评分">
<span>{{viewData.evaluateScore}}</span>
</el-form-item>
<el-form-item label="评价">
<span>{{viewData.evaluateText}}</span>
</el-form-item>
</el-form>
<span class="dialog-footer" slot="footer">
<el-button @click="evaluateDialogVisible = false" type="primary">关 闭</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {},
data() {
return {
unionList: [],
unitList: [],
lineList: [],
evaluateDialogVisible: false,
tableColumns: [
{prop: 'lineName', label: '线路'},
{prop: 'playStartTime', label: '出行时间'},
{prop: 'loginName', label: '工号'},
{prop: 'userName', label: '姓名'},
{prop: 'unitName', label: '所属单位'},
{prop: 'unionName', label: '所属工会'},
{prop: 'evaluateScore', label: '评分', sortable: true},
{prop: 'evaluateText', label: '评价'},
],
viewData: {},
evaluateScores: [
{name: "满意", code: "满意"},
{name: "一般", code: "一般"},
{name: "不满意", code: "不满意"},
],
pageForm: {
year: new Date().getFullYear().toString(),
},
}
},
methods: {
exportEvaluate() {
this.$downLoad(loc() + '/exportEvaluate', this.pageForm)
},
onView(row) {
this.viewData = {
lineId: row.id,
evaluateText: row.evaluateText,
evaluateScore: row.evaluateScore,
}
this.evaluateDialogVisible = true
},
async getLineList() {
const resp = await this.$axios.post(loc() + '/lineList', {year: this.pageForm.year})
this.lineList = resp.data
},
async yearChange() {
this.$set(this.pageForm, "lineId", null)
await this.getLineList()
this.doSearch()
},
pageData() {
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
},
async created() {
this.unionList = await this.$businessTool.listUnion()
this.unitList = await this.$businessTool.listUnit()
await this.getLineList()
this.pageData()
}
})
</script>
<!--#
}
#-->