This commit is contained in:
=
2026-06-03 10:33:41 +08:00
parent 41b370692e
commit 66f87fa3bc
51 changed files with 1368 additions and 270 deletions
@@ -1,6 +1,7 @@
package io.v.nutz.zhgh.therapyRecuperation.controller.audit;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.date.DateUtil;
import io.v.nutz.base.annontation.ViReturn;
import io.v.nutz.base.model.Audit;
@@ -12,6 +13,7 @@ import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnroll;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationAuditService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.aop.interceptor.ioc.TransAop;
@@ -56,6 +58,9 @@ public class TheRapyRecuperationTravelAuditController {
@Inject
private Dao dao;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/audit/TheRapyTravelAudit.html")
@RequiresPermissions("theRapyRecuperation.TheRapyTravelAudit")
@@ -138,7 +143,7 @@ public class TheRapyRecuperationTravelAuditController {
@ViReturn
@RequiresAuthentication
public Object getApplyNumAudit(String agencyId, String isAudit, Integer year) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(year == null ? DateUtil.thisYear() : year);
String unionId = Vi.getUnionId();
Sql sql = Sqls.create("""
SELECT
@@ -23,6 +23,7 @@ import io.v.nutz.sys.models.User;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.baseManage.TheRapyRecuperationBaseManagerService;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.Logical;
@@ -75,6 +76,9 @@ public class TheRapyRecuperationBaseManagerController {
@Inject
private TheRapyRecuperationBaseManagerService theRapyRecuperationBaseManagerService;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/baseManage/baseManagement.html")
@RequiresPermissions("theRapyRecuperation.TheBaseManagement")
@@ -217,6 +221,29 @@ public class TheRapyRecuperationBaseManagerController {
return null;//deleteBase
}
/**
* 复制上一年度目的地到目标年度。
*
* @param sourceYear 来源年度
* @param targetYear 目标年度
* @return 复制结果
*/
@At("/copyLastYearBase")
@POST
@ViReturn
@RequiresRoles(value = {"sysadmin", "A06", "H04"}, logical = Logical.OR)
public Object copyLastYearBase(Integer sourceYear, Integer targetYear) {
Assert.notNull(sourceYear, "请选择来源年度");
Assert.notNull(targetYear, "请选择目标年度");
if (sourceYear.equals(targetYear)) {
return Result.error("来源年度和目标年度不能相同");
}
if (sourceYear > targetYear) {
return Result.error("来源年度不能大于目标年度");
}
return theRapyRecuperationBaseManagerService.copyLastYearBase(sourceYear, targetYear);
}
/**
* 删除线路
*
@@ -288,17 +315,16 @@ public class TheRapyRecuperationBaseManagerController {
return Result.error("参数错误");
}
// 手机端日历使用最新提交配置,保持活动时间和页面展示一致。
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.where("latestConfig", "=", true));
if (config == null) {
return Result.error("未找到最新疗休养配置,请联系管理员");
}
//获取线路对应的标段
// 手机端日历使用当前目的地年度对应配置,保持活动时间和页面展示一致。
TheRapyRecuperationBaseManagement management = dao.fetch(TheRapyRecuperationBaseManagement.class, id);
TheRapyRecuperationConfig config = configService.requireByYear(management.getYear());
if (config == null) {
return Result.error("未找到对应年度疗休养配置,请联系管理员");
}
//TheRapyRecuperationLot lot = dao.fetch(TheRapyRecuperationLot.class, management.getLotId());
//获取当年的节假日
List<SysHoliday> holidayList = dao.query(SysHoliday.class, Cnd.where("year(day)", "=", DateUtil.thisYear()).asc("day"));
List<SysHoliday> holidayList = dao.query(SysHoliday.class, Cnd.where("year(day)", "=", management.getYear()).asc("day"));
List<String> holidays = holidayList.stream().map(SysHoliday::getDay).collect(Collectors.toList());
//按月份分组
Map<Integer, List<SysHoliday>> listMap = holidayList.stream().collect(Collectors.groupingBy(o -> DateUtil.month(DateUtil.parse(o.getDay()))));
@@ -145,6 +145,29 @@ public class TheRapyRecuperationLineController {
return null;
}
/**
* 复制校工会组织线路到目标年度。
*
* @param sourceYear 来源年度
* @param targetYear 目标年度
* @return 复制结果
*/
@At("/copySchoolUnionLines")
@POST
@ViReturn
@RequiresRoles(value = {"sysadmin", "SchoolUnionAdmin"}, logical = Logical.OR)
public Object copySchoolUnionLines(Integer sourceYear, Integer targetYear) {
Assert.notNull(sourceYear, "请选择来源年度");
Assert.notNull(targetYear, "请选择目标年度");
if (sourceYear.equals(targetYear)) {
return Result.error("来源年度和目标年度不能相同");
}
if (sourceYear > targetYear) {
return Result.error("来源年度不能大于目标年度");
}
return lineService.copySchoolUnionLines(sourceYear, targetYear);
}
/**
* 开启或关闭线路
*
@@ -271,7 +294,7 @@ public class TheRapyRecuperationLineController {
@ViReturn
@RequiresPermissions("theRapyRecuperation.line")
public Object getTravelAgencyOptions() {
List<TheRapyRecuperationTravelAgency> travelAgencies = lineService.dao().query(TheRapyRecuperationTravelAgency.class, Cnd.NEW().asc("serialNumber"));
List<TheRapyRecuperationTravelAgency> travelAgencies = lineService.dao().query(TheRapyRecuperationTravelAgency.class, Cnd.NEW().desc("year").asc("serialNumber"));
return travelAgencies;
}
@@ -87,7 +87,7 @@ public class TheRapyRecuperationTravelAgencyController {
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.asc("serialNumber");
cnd.desc("year").asc("serialNumber");
}
return travelAgencyService.pageData(pageForm, cnd);
}
@@ -164,7 +164,7 @@ public class TheRapyRecuperationTravelAgencyController {
@RequiresAuthentication
public Object selectTravelAgency(Integer year) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
cnd.asc("serialNumber");
return travelAgencyService.selectAllTravelAgencyByYear(cnd);
}
@@ -181,8 +181,7 @@ public class TheRapyRecuperationTravelAgencyController {
@RequiresAuthentication
public Object selectTravelAgencyByYears(Integer startYear, Integer endYear) {
Cnd cnd = Cnd.NEW();
cnd.andEX("year", ">=", startYear);
cnd.andEX("year", "<=", endYear);
cnd.asc("serialNumber");
return travelAgencyService.selectAllTravelAgencyByYear(cnd);
}
@@ -11,6 +11,7 @@ import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationType;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationCommonService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationLineService;
@@ -51,6 +52,9 @@ public class TheRapyRecuperationEnrollController {
@Inject
private TheRapyRecuperationTravelAgencyService travelAgencyService;
@Inject
private TheRapyRecuperationConfigService configService;
@Inject
private TheRapyRecuperationCommonService commonService;
@@ -337,7 +341,8 @@ public class TheRapyRecuperationEnrollController {
return Result.error("当前报名已经成团不能取消");
}
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
Integer configYear = enroll.getSigningUptime() == null ? DateUtil.thisYear() : DateUtil.year(enroll.getSigningUptime());
TheRapyRecuperationConfig config = configService.requireByYear(configYear);
Date changeEndTime = null;
if (StrUtil.isNotBlank(enroll.getTakePartInLineId())) {
@@ -14,6 +14,7 @@ import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.activity.models.ActivityUserScope;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationSignUpMode;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationLineUnionSelectService;
import io.v.nutz.web.commons.slog.annotation.SLog;
import lombok.extern.slf4j.Slf4j;
@@ -65,6 +66,8 @@ public class TheRapyRecuperationLineUnionSelectController {
private Dao dao;
@Inject
private TheRapyRecuperationLineUnionSelectService unionSelectService;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("re")
@@ -100,6 +103,8 @@ public class TheRapyRecuperationLineUnionSelectController {
//当前登录用户已选择的线路id
Sql hasSelectLineSql = null;
boolean isSchoolAdmin = ShiroUtil.hasAnyRoles("sysadmin, SchoolUnionAdmin");
if(mode == 1) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.or("line.openChoose", "=", true);
@@ -114,14 +119,23 @@ public class TheRapyRecuperationLineUnionSelectController {
select lineId from the_rapy_recuperation_line_union_select where year(selectTime) = %s and signUpMode = %s
""", year, TheRapyRecuperationSignUpMode.FREE.getValue());
} else if(mode == 3) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.or("line.openChoose", "=", true);
group.or(Cnd.exps("line.openChoose", "=", false).and("line.opBy", "=", ShiroUtil.getUserId()));
cnd.and(group);
//管理员查看个人组织线路时不按创建人收窄,普通用户仍只能查看公开或自己创建的线路。
if (!isSchoolAdmin) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.or("line.openChoose", "=", true);
group.or(Cnd.exps("line.openChoose", "=", false).and("line.opBy", "=", ShiroUtil.getUserId()));
cnd.and(group);
}
//个人
hasSelectLineSql = Sqls.createf("""
if (isSchoolAdmin) {
hasSelectLineSql = Sqls.createf("""
select lineId from the_rapy_recuperation_line_union_select where year(selectTime) = %s and signUpMode = %s
""", year, TheRapyRecuperationSignUpMode.PERSONAL.getValue());
} else {
hasSelectLineSql = Sqls.createf("""
select lineId from the_rapy_recuperation_line_union_select where selectUserId = '%s' and year(selectTime) = %s and signUpMode = %s
""", ShiroUtil.getUserId(), year, TheRapyRecuperationSignUpMode.PERSONAL.getValue());
}
}
switch (selectStatus) {
@@ -340,12 +354,10 @@ public class TheRapyRecuperationLineUnionSelectController {
@ViReturn
@RequiresPermissions(value = {"theRapyRecuperation.lineFghSelect", "theRapyRecuperation.lineXghSelect", "theRapyRecuperation.linePersonalSelect"}, logical = Logical.OR)
public Object getLineConfig(String id) {
Sql sql = Sqls.create("select lotId from the_rapy_recuperation_line where id = @lineId");
sql.setParam("lineId", id);
String lotId = (String) Daos.query(dao, sql.toString(), Sqls.callback.str());
TheRapyRecuperationLot lotInfo = dao.fetch(TheRapyRecuperationLot.class, lotId);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, id);
TheRapyRecuperationLot lotInfo = dao.fetch(TheRapyRecuperationLot.class, line.getLotId());
Integer cost = Optional.ofNullable(lotInfo).map(v -> v.getActivityCost()).orElse(0);
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(line.getYear());
Integer groupNumber = Optional.ofNullable(config).map(TheRapyRecuperationConfig::getGroupNumber).orElse(0);
return Result.success(Map.of("cost", cost, "groupNumber", groupNumber));
@@ -400,7 +412,7 @@ public class TheRapyRecuperationLineUnionSelectController {
@At
@ViReturn
@RequiresPermissions(value = {"theRapyRecuperation.lineFghSelect", "theRapyRecuperation.lineXghSelect", "theRapyRecuperation.linePersonalSelect"}, logical = Logical.OR)
public Object queryJoinUser(String keyWord){
public Object queryJoinUser(String keyWord, Integer year){
Sql sql = Sqls.create("""
select
id,
@@ -422,7 +434,7 @@ public class TheRapyRecuperationLineUnionSelectController {
cnd.and(seg);
}
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(year == null ? DateUtil.thisYear() : year);
cnd.and(new Static("id in (select userId from activity_user_scope where groupId = '%s')".formatted(config.getActivityGroupId())));
@@ -19,6 +19,7 @@ import io.v.nutz.sys.models.Sys_user;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationTravelAgencyService;
import io.v.nutz.web.commons.base.Globals;
import io.v.nutz.web.commons.slog.annotation.SLog;
@@ -65,6 +66,9 @@ public class TheRapyRecuperationUnionQueryController {
@Inject
private TheRapyRecuperationTravelAgencyService agencyService;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/process/TheRapyQuery.html")
@@ -421,7 +425,7 @@ public class TheRapyRecuperationUnionQueryController {
baseService.dao().fetchLinks(v, "bedInfo");
});
TheRapyRecuperationConfig config = baseService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(year == null ? DateUtil.thisYear() : year);
List<NutMap> arrayList = new ArrayList<>();
enrollList.forEach(v -> {
@@ -578,7 +582,7 @@ public class TheRapyRecuperationUnionQueryController {
cnd1.andEX("enroll.isNormal", "= ", true);
cnd1.andEX("enroll.stateId", "= ", TheRapyRecuperationState.PASS);
TheRapyRecuperationConfig config = baseService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(year == null ? DateUtil.thisYear() : year);
Sql sql2 = null;
if (config.getFamilyInfo() == 2) {
@@ -17,6 +17,7 @@ import io.v.nutz.base.query.PageForm;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.mode.TheRapyRecuperationEnrollExcelMode;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
@@ -59,6 +60,9 @@ public class TheRapyRecuperationUserQueryController {
@Inject
private BaseService baseService;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/process/TheRapyUserQuery.html")
@@ -93,8 +97,8 @@ public class TheRapyRecuperationUserQueryController {
$condition
""");
cnd.andEX("enroll.selfUnionId", "=", Vi.getUnionId());
cnd.andEX("lxs.`year`", ">=", startYear);
cnd.andEX("lxs.`year`", "<=", endYear);
cnd.andEX("YEAR(enroll.signingUptime)", ">=", startYear);
cnd.andEX("YEAR(enroll.signingUptime)", "<=", endYear);
cnd.andEX("enroll.takePartInTravelAgencyId", "=", agencyId);
cnd.andEX("enroll.isTakePartIn", "=", isTakePartIn);
} else {
@@ -245,12 +249,18 @@ public class TheRapyRecuperationUserQueryController {
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLoginName())) || excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getUserName()))) {
return Result.error("工号和姓名不能为空");
}
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLotId())) || excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getTakePartInTime().toString()))) {
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLotId())) || excelList.stream().anyMatch(v -> v.getTakePartInTime() == null)) {
return Result.error("标段时间和参加时间不能为空");
}
// 按 Excel 每行参加时间所属年度匹配报名数据,避免跨年度导入时查错报名记录。
List<Integer> importYears = excelList.stream()
.map(v -> DateUtil.year(v.getTakePartInTime()))
.distinct()
.collect(Collectors.toList());
//报名的数据
List<TheRapyRecuperationEnroll> enrollList = baseService.dao().query(TheRapyRecuperationEnroll.class, Cnd.where("YEAR(signingUptime)", "=", DateUtil.thisYear()));
Map<String, TheRapyRecuperationEnroll> enrollMap = enrollList.stream().collect(Collectors.toMap(v -> v.getLoginName(), v -> v));
List<TheRapyRecuperationEnroll> enrollList = baseService.dao().query(TheRapyRecuperationEnroll.class, Cnd.where("YEAR(signingUptime)", "in", importYears));
Map<String, TheRapyRecuperationEnroll> enrollMap = enrollList.stream()
.collect(Collectors.toMap(v -> v.getLoginName() + "_" + DateUtil.year(v.getSigningUptime()), v -> v, (oldValue, newValue) -> oldValue));
//时间标段数据
List<TheRapyRecuperationLot> lots = baseService.dao().query(TheRapyRecuperationLot.class, Cnd.NEW());
//修改信息
@@ -258,11 +268,12 @@ public class TheRapyRecuperationUserQueryController {
//错误信息返回
List<String> errorInfos = new ArrayList<>();
excelList.forEach(v -> {
TheRapyRecuperationEnroll enrollInfo = enrollMap.get(v.getLoginName());
int takePartInYear = DateUtil.year(v.getTakePartInTime());
TheRapyRecuperationEnroll enrollInfo = enrollMap.get(v.getLoginName() + "_" + takePartInYear);
if (enrollInfo == null) {
errorInfos.add(v.getLoginName());
} else if (lots.stream().noneMatch(l -> l.getLotName().equals(v.getLotId()))) {
// errorInfos.add("工号" + v.getLoginName() + "的报名信息错误(时间标段有误)");
errorInfos.add("工号" + v.getLoginName() + "的报名信息错误(时间标段有误)");
} else {
List<TheRapyRecuperationLot> collect = lots.stream().filter(l -> l.getLotName().equals(v.getLotId())).collect(Collectors.toList());
TheRapyRecuperationEnroll enroll = new TheRapyRecuperationEnroll();
@@ -270,6 +281,8 @@ public class TheRapyRecuperationUserQueryController {
enroll.setTakePartInTime(v.getTakePartInTime());
enroll.setLotId(collect.get(0).getId());
enroll.setTakePartIn(true);
// 导入参加人员只更新参加信息,保持报名记录为正常状态,避免被列表的 isNormal=true 条件过滤掉。
enroll.setNormal(true);
updateEnrollList.add(enroll);
}
});
@@ -284,12 +297,11 @@ public class TheRapyRecuperationUserQueryController {
}
return Result.error(str + "的人员导入失败");
}
return Result.success("导入成功,共更新" + updateEnrollList.size() + "人,年度:" + importYears.stream().map(String::valueOf).collect(Collectors.joining("")));
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("导入参加人员失败");
}
return null;
}
@@ -425,7 +437,7 @@ public class TheRapyRecuperationUserQueryController {
List<NutMap> list = baseService.listMap(sql);
List<TheRapyRecuperationEnroll> enrollList = Lang.collection2list(list, TheRapyRecuperationEnroll.class);
TheRapyRecuperationConfig config = baseService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(startYear == null ? DateUtil.thisYear() : startYear);
enrollList.forEach(v -> {
baseService.dao().fetchLinks(v, "companionList");
@@ -16,6 +16,7 @@ import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnrollBed;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnrollCompanion;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -55,6 +56,8 @@ public class TheRapyRecuperationBranchUnionUserQueryController {
private BaseService baseService;
@Inject
private TheRapyRecuperationEnrollService enrollService;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/branchUnionUserQuery/index.html")
@@ -372,7 +375,7 @@ public class TheRapyRecuperationBranchUnionUserQueryController {
});
// 配置
TheRapyRecuperationConfig config = baseService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(year);
List<ExcelExportEntity> excelEntities = new ArrayList<>();
excelEntities.add(new ExcelExportEntity("姓名", "userName", 20));
@@ -10,7 +10,6 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
@@ -106,10 +105,8 @@ public class TheRapyRecuperationLineQueryController {
}
}
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())){
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("u.username", pageForm.getSearchKeyword());
group.orLike("u.loginname", pageForm.getSearchKeyword());
cnd.and(group);
// 线路查询页关键字只用于线路名称模糊查询。
cnd.and(Cnd.likeEX("line.lineName", pageForm.getSearchKeyword().trim()));
}
cnd.andEX("line.lotId", "=", lotId);
@@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.base.service.BaseService;
@@ -15,6 +16,7 @@ import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnrollBed;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnrollCompanion;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -31,10 +33,14 @@ 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.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
@@ -55,6 +61,8 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
private BaseService baseService;
@Inject
private TheRapyRecuperationEnrollService enrollService;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/schoolUnionUserQuery/index.html")
@@ -279,6 +287,63 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
return Result.success(list);
}
/**
* 参加人员补录使用的线路列表,直接读取已选择线路,避免无报名记录的线路无法选择。
*
* @param year 年度
* @param unionId 分工会id
* @param regionalNature 区域
* @return 线路列表
*/
@At
@RequiresPermissions("theRapyRecuperation.schoolUnionUserQuery")
public Result supplementLineList(Integer year, String unionId, String regionalNature) {
Sql sql = Sqls.create("""
SELECT
t2.id AS takePartInLineId,
t3.lineName,
t4.unionname AS unionName
FROM
the_rapy_recuperation_line_union_select t2
LEFT JOIN the_rapy_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("t3.stateId", "=", 4);
cnd.andEX("YEAR(t2.selectTime)", "=", year);
cnd.andEX("t2.unionId", "=", unionId);
cnd.andEX("t3.regionalNature", "=", regionalNature);
cnd.desc("t3.lineName");
sql.setCondition(cnd);
return Result.success(enrollService.listMap(sql));
}
/**
* 参加人员补录,给实际已报名但系统内不存在报名记录的人员补建疗休养报名记录。
*
* @param takePartInLineId 选择的线路
* @param file 导入文件
* @return 补录结果
*/
@At
@RequiresPermissions("theRapyRecuperation.schoolUnionUserQuery")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@Aop(TransAop.READ_COMMITTED)
public Result supplementImport(String takePartInLineId, TempFile file) {
if (StrUtil.isBlank(takePartInLineId)) {
return Result.error("请选择补录线路");
}
if (Lang.isEmpty(file)) {
return Result.error("上传的文件不能为空");
}
String extName = FileUtil.extName(file.getFile());
if (!List.of("xls", "xlsx").contains(extName.toLowerCase())) {
return Result.error("请上传xls,xlsx文件");
}
return enrollService.supplementEnrollImport(takePartInLineId, file.getFile());
}
@At
@Ok("void")
@RequiresPermissions("theRapyRecuperation.schoolUnionUserQuery")
@@ -378,7 +443,7 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
});
// 配置
TheRapyRecuperationConfig config = baseService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig config = configService.requireByYear(year);
List<ExcelExportEntity> excelEntities = new ArrayList<>();
excelEntities.add(new ExcelExportEntity("姓名", "userName", 20));
@@ -422,8 +487,9 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
@At
@Ok("void")
@RequiresPermissions("theRapyRecuperation.schoolUnionUserQuery")
public void noSignExport(HttpServletResponse response) {
TheRapyRecuperationConfig config = baseService.dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
public void noSignExport(Integer year, HttpServletResponse response) {
Integer configYear = year == null ? DateUtil.thisYear() : year;
TheRapyRecuperationConfig config = configService.requireByYear(configYear);
Sql sql = Sqls.create("""
select
u.username as userName,
@@ -440,7 +506,7 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
""");
Cnd cnd = Cnd.NEW();
cnd.and("us.groupId", "=", config.getActivityGroupId());
cnd.and(new Static(" u.loginname not in (select loginName from the_rapy_recuperation_enroll where year(signingUptime) = '%s' and isNormal = true)".formatted(DateUtil.thisYear())));
cnd.and(new Static(" u.loginname not in (select loginName from the_rapy_recuperation_enroll where year(signingUptime) = '%s' and isNormal = true)".formatted(configYear)));
cnd.asc("unitcode");
sql.setCondition(cnd);
List<NutMap> listMap = enrollService.listMap(sql);
@@ -18,6 +18,7 @@ import io.v.nutz.web.commons.base.Globals;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
@@ -72,6 +73,8 @@ public class TheRapyRecuperationLineFragmentController {
private Dao dao;
@Inject
private OfficeTemplateUtil officeTemplateUtil;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/statistics/fragment.html")
@@ -223,13 +226,14 @@ public class TheRapyRecuperationLineFragmentController {
@Aop(TransAop.READ_COMMITTED)
@RequiresPermissions("theRapyRecuperation.fragment")
public Object sendSuccess(String baseId, Boolean type, String specificTime, Integer playDay) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationBaseManagement configManagement = dao.fetch(TheRapyRecuperationBaseManagement.class, baseId);
TheRapyRecuperationConfig config = configService.requireByYear(configManagement.getYear());
if (DateUtil.compare(new Date(), config.getFragmentEndTime()) < 0) {
return Result.error("报名还未结束");
}
TheRapyRecuperationBaseManagement management = dao.fetch(TheRapyRecuperationBaseManagement.class, baseId);
TheRapyRecuperationBaseManagement management = configManagement;
//找出报名人员
List<TheRapyRecuperationEnroll> enrolls = dao.query(
@@ -237,7 +241,7 @@ public class TheRapyRecuperationLineFragmentController {
Cnd.where("takePartInBaseManagementId", "=", baseId)
.and("specificTime", "=", specificTime)
.and("playDay", "=", playDay)
.and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear())
.and("isNormal", "=", true).and("year(signingUptime)", "=", management.getYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
if (enrolls.size() < config.getFragmentCount()) {
@@ -268,13 +272,14 @@ public class TheRapyRecuperationLineFragmentController {
@RequiresPermissions("theRapyRecuperation.fragment")
public Object sendFail(String baseId, Boolean type, String specificTime, Integer playDay) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationBaseManagement configManagement = dao.fetch(TheRapyRecuperationBaseManagement.class, baseId);
TheRapyRecuperationConfig config = configService.requireByYear(configManagement.getYear());
if (DateUtil.compare(new Date(), config.getFragmentEndTime()) < 0) {
return Result.error("报名还未结束");
}
TheRapyRecuperationBaseManagement management = dao.fetch(TheRapyRecuperationBaseManagement.class, baseId);
TheRapyRecuperationBaseManagement management = configManagement;
//找出报名人员
List<TheRapyRecuperationEnroll> enrolls = dao.query(
@@ -282,7 +287,7 @@ public class TheRapyRecuperationLineFragmentController {
Cnd.where("takePartInBaseManagementId", "=", baseId)
.and("specificTime", "=", specificTime)
.and("playDay", "=", playDay)
.and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear())
.and("isNormal", "=", true).and("year(signingUptime)", "=", management.getYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
//发短信
@@ -313,7 +318,8 @@ public class TheRapyRecuperationLineFragmentController {
@Aop(TransAop.READ_COMMITTED)
@RequiresPermissions("theRapyRecuperation.fragment")
public Object oneKeyGroupSuccess(String travelAgencyId, String baseId, String playStart, String playEnd, Boolean type) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationBaseManagement currentManagement = StrUtil.isBlank(baseId) ? null : dao.fetch(TheRapyRecuperationBaseManagement.class, baseId);
TheRapyRecuperationConfig config = configService.requireByYear(currentManagement == null ? DateUtil.thisYear() : currentManagement.getYear());
Integer fragmentCount = config.getFragmentCount();
if (DateUtil.compare(new Date(), config.getFragmentEndTime()) < 0) {
@@ -451,7 +457,8 @@ public class TheRapyRecuperationLineFragmentController {
response.setHeader("content-disposition", "attachment;filename="
+ URLEncoder.encode("分段疗休养成团表.zip", StandardCharsets.UTF_8));
TheRapyRecuperationConfig rapyConfig = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationBaseManagement currentManagement = StrUtil.isBlank(baseManagementId) ? null : dao.fetch(TheRapyRecuperationBaseManagement.class, baseManagementId);
TheRapyRecuperationConfig rapyConfig = configService.requireByYear(currentManagement == null ? DateUtil.thisYear() : currentManagement.getYear());
Integer fragmentCount = rapyConfig.getFragmentCount();
Sql sql = Sqls.create("""
SELECT
@@ -19,6 +19,7 @@ import io.v.nutz.web.commons.base.Globals;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
@@ -74,6 +75,8 @@ public class TheRapyRecuperationLineStatisticsController {
private Dao dao;
@Inject
private OfficeTemplateUtil officeTemplateUtil;
@Inject
private TheRapyRecuperationConfigService configService;
@At("")
@Ok("beetl:/platform/theRapyRecuperation/statistics/lineStatistics.html")
@@ -216,15 +219,14 @@ public class TheRapyRecuperationLineStatisticsController {
@RequiresAuthentication
@Aop(TransAop.READ_COMMITTED)
public Object sendSuccess(String id, Boolean type) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId());
TheRapyRecuperationConfig config = configService.requireByYear(line.getYear());
if (DateUtil.compare(new Date(), config.getImplodeEndTime()) < 0) {
return Result.error("报名还未结束");
}
TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId());
unionSelect.setGroupSuccess(true);
unionSelect.setGroupTime(DateUtil.now());
/*switch (unionSelect.getSignUpMode()) {
@@ -239,12 +241,12 @@ public class TheRapyRecuperationLineStatisticsController {
List<TheRapyRecuperationEnroll> enrolls = dao.query(
TheRapyRecuperationEnroll.class,
Cnd.where("takePartInLineId", "=", id)
.and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear())
.and("isNormal", "=", true).and("year(signingUptime)", "=", line.getYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
Integer count = line.getGroupType() == 1 ? config.getConventionalCount() : config.getBoutiqueCount();
if(enrolls.size() < count) {
return Result.error("报名人数为%s人,未达到%s人的成团条件".formatted(enrolls.size(), config.getFragmentCount()));
return Result.error("报名人数为%s人,未达到%s人的成团条件".formatted(enrolls.size(), count));
}
enrolls.forEach(item -> {
@@ -287,15 +289,14 @@ public class TheRapyRecuperationLineStatisticsController {
@RequiresAuthentication
@Aop(TransAop.READ_COMMITTED)
public Object sendFail(String id, Boolean type) {
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId());
TheRapyRecuperationConfig config = configService.requireByYear(line.getYear());
if (DateUtil.compare(new Date(), config.getImplodeEndTime()) < 0) {
return Result.error("报名还未结束");
}
TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id);
TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId());
unionSelect.setGroupSuccess(false);
unionSelect.setGroupTime(null);
dao.update(unionSelect);
@@ -304,7 +305,7 @@ public class TheRapyRecuperationLineStatisticsController {
List<TheRapyRecuperationEnroll> enrolls = dao.query(
TheRapyRecuperationEnroll.class,
Cnd.where("takePartInLineId", "=", id)
.and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear())
.and("isNormal", "=", true).and("year(signingUptime)", "=", line.getYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
//发短信
@@ -17,6 +17,14 @@ public interface TheRapyRecuperationConfigService extends ViService<TheRapyRecup
*/
TheRapyRecuperationConfig findByYear(Integer configYear);
/**
* 按指定年度获取业务配置,年度为空或配置不存在时直接报错,不使用旧配置或最新配置兜底。
*
* @param configYear 配置年度
* @return 指定年度配置
*/
TheRapyRecuperationConfig requireByYear(Integer configYear);
/**
* 保存年度基础配置,已存在配置时更新,不存在时新增。
*
@@ -1,6 +1,7 @@
package io.v.nutz.zhgh.therapyRecuperation.service;
import cn.wizzer.framework.page.Pagination;
import cn.wizzer.framework.base.Result;
import io.v.nutz.base.query.PageForm;
import io.v.nutz.base.service.ViService;
import io.v.nutz.sys.models.Sys_union;
@@ -8,6 +9,7 @@ import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnroll;
import org.nutz.dao.Cnd;
import org.nutz.lang.util.NutMap;
import java.io.File;
import java.util.List;
import java.util.Map;
@@ -110,4 +112,13 @@ public interface TheRapyRecuperationEnrollService extends ViService<TheRapyRecup
NutMap selectLineAllInfo(String usId, String usUnionId);
List<Sys_union> getTheRapyUnions(Integer year);
/**
* 补录实际已报名但系统不存在报名记录的参加人员。
*
* @param takePartInLineId 选择的线路工会记录id
* @param file 导入的 Excel 文件
* @return 补录结果
*/
Result supplementEnrollImport(String takePartInLineId, File file);
}
@@ -93,4 +93,13 @@ public interface TheRapyRecuperationLineService extends ViService<TheRapyRecuper
* @return {@link List}<{@link NutMap}>
*/
List<NutMap> viewUnionSelectTimeInfo(String lineId);
/**
* 复制校工会组织线路到目标年度,只复制线路基础信息,不复制报名、选择记录和审核记录。
*
* @param sourceYear 来源年度
* @param targetYear 目标年度
* @return 复制结果,包含来源数量、复制数量和跳过数量
*/
NutMap copySchoolUnionLines(Integer sourceYear, Integer targetYear);
}
@@ -10,4 +10,13 @@ import org.nutz.lang.util.NutMap;
public interface TheRapyRecuperationBaseManagerService {
NutMap selectBaseAllInfo(String id);
/**
* 复制上一年度目的地到目标年度,只复制目的地基础信息,不复制报名数据。
*
* @param sourceYear 来源年度
* @param targetYear 目标年度
* @return 复制结果,包含来源数量、复制数量和跳过数量
*/
NutMap copyLastYearBase(Integer sourceYear, Integer targetYear);
}
@@ -5,10 +5,12 @@ import io.v.nutz.base.service.impl.ViServiceImpl;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationType;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnroll;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationCommonService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
/**
@@ -21,6 +23,9 @@ import org.nutz.ioc.loader.annotation.IocBean;
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationCommonServiceImpl extends ViServiceImpl implements TheRapyRecuperationCommonService {
@Inject
private TheRapyRecuperationConfigService configService;
public TheRapyRecuperationCommonServiceImpl(Dao dao) {
super(dao);
}
@@ -29,7 +34,7 @@ public class TheRapyRecuperationCommonServiceImpl extends ViServiceImpl implemen
@Override
public boolean canSignUp(String loginName, TheRapyRecuperationType trrt) {
TheRapyRecuperationConfig config = dao().fetch(TheRapyRecuperationConfig.class);
TheRapyRecuperationConfig config = configService.requireByYear(DateUtil.getYear());
//每年旅行频率
Integer travelFrequency = config.getTravelFrequency();
@@ -64,6 +64,18 @@ public class TheRapyRecuperationConfigServiceImpl extends ViServiceImpl<TheRapyR
return dao().fetchLinks(config, "lots", Cnd.NEW().desc("lotValue"));
}
@Override
public TheRapyRecuperationConfig requireByYear(Integer configYear) {
if (configYear == null) {
throw new IllegalArgumentException("请选择疗休养年度");
}
TheRapyRecuperationConfig config = fetch(Cnd.where("configYear", "=", configYear));
if (config == null) {
throw new IllegalArgumentException(configYear + "年度疗休养配置不存在,请先维护年度配置");
}
return dao().fetchLinks(config, "lots", Cnd.NEW().desc("lotValue"));
}
/**
* 其他业务页面不传年度时,只使用最新提交的基础配置。
*
@@ -37,7 +37,7 @@ public class TheRapyRecuperationEnrollJoinUserImportServiceImpl extends ViServic
UNION ALL
SELECT
id,
travelAgencyName AS label,
CONCAT(travelAgencyName, IF(serialNumber IS NULL OR serialNumber = '', '', CONCAT('(', serialNumber, ')'))) AS label,
'旅行社' AS `type`
FROM
the_rapy_recuperation_travel_agency
@@ -71,8 +71,16 @@ public class TheRapyRecuperationEnrollJoinUserImportServiceImpl extends ViServic
lineSql.setParam("year", year);
lineSql.setParam("unionId", Vi.getUnionId());
Sql travelSql = Sqls.create("SELECT id,travelAgencyName AS label FROM the_rapy_recuperation_travel_agency where year = @year");
travelSql.setParam("year", year);
Sql travelSql = Sqls.create("""
SELECT
id,
CONCAT(travelAgencyName, IF(serialNumber IS NULL OR serialNumber = '', '', CONCAT('(', serialNumber, ')'))) AS label
FROM
the_rapy_recuperation_travel_agency
WHERE
isDisabled = false
ORDER BY serialNumber
""");
return Map.of("lines", listMap(lineSql), "travels", listMap(travelSql));
}
@@ -1,8 +1,11 @@
package io.v.nutz.zhgh.therapyRecuperation.service.impl;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.wizzer.framework.base.Result;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.wizzer.framework.page.Pagination;
import io.v.nutz.web.commons.utils.ShiroUtil;
@@ -16,7 +19,9 @@ import io.v.nutz.sys.models.Sys_union;
import io.v.nutz.sys.models.Sys_user;
import io.v.nutz.sys.models.User;
import io.v.nutz.zhgh.therapyRecuperation.constant.*;
import io.v.nutz.zhgh.therapyRecuperation.mode.TheRapyRecuperationEnrollExcelMode;
import io.v.nutz.zhgh.therapyRecuperation.model.*;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationEnrollService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationLineService;
import org.nutz.aop.interceptor.ioc.TransAop;
@@ -33,6 +38,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.io.File;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
@@ -55,6 +61,9 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
@Inject
private MsgApi msgApi;
@Inject
private TheRapyRecuperationConfigService configService;
public TheRapyRecuperationEnrollServiceImpl(Dao dao) {
super(dao);
}
@@ -385,7 +394,7 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
}
//2023-06-07 省内外线路是否需要审核配置 根据配置来赋报名表的审核状态值☞
TheRapyRecuperationConfig recuperationConfig = dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig recuperationConfig = configService.requireByYear(lineInfo.getYear());
Boolean isSnLine = recuperationConfig.getIsSnLine();
Boolean isSwLine = recuperationConfig.getIsSwLine();
@@ -435,7 +444,7 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
TheRapyRecuperationLineUnionSelect lineUnionSelect = dao().fetch(TheRapyRecuperationLineUnionSelect.class, enrollInfo.getTakePartInLineId());
TheRapyRecuperationLine lineInfo = dao().fetch(TheRapyRecuperationLine.class, lineUnionSelect.getLineId());
TheRapyRecuperationConfig recuperationConfig = dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
TheRapyRecuperationConfig recuperationConfig = configService.requireByYear(lineInfo.getYear());
if (lineUnionSelect.getSignUpMode() == TheRapyRecuperationSignUpMode.FREE.getValue()) {
enrollInfo.setTakePartInUnionId(null);
@@ -544,10 +553,10 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
@Override
public Map<Boolean, String> validSignUpInfo(String loginName, TheRapyRecuperationEnroll enrollInfo) {
// 配置信息只取当前最新配置,避免报名校验和页面展示使用不同年度配置。
TheRapyRecuperationConfig config = fetchLatestConfig();
// 配置信息按报名对象所属年度读取,避免报名校验和页面展示使用不同年度配置。
TheRapyRecuperationConfig config = fetchConfigByEnroll(enrollInfo);
if (config == null) {
return Map.of(false, "未找到最新疗休养配置,请联系管理员");
return Map.of(false, "未找到对应年度疗休养配置,请联系管理员");
}
if (StrUtil.isNotBlank(loginName) && loginName.startsWith("2025")) {
@@ -563,7 +572,7 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
}
//判断报名时间
Map<Boolean, String> validTime = this.validSignTime(enrollInfo);
Map<Boolean, String> validTime = this.validSignTime(enrollInfo, config);
if (validTime != null && validTime.containsKey(false)) {
return validTime;
}
@@ -657,7 +666,7 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
return Map.of(false, "近三年内您已参加过省外线路,不能再次报名");
}
//获取今年的所有线路
List<TheRapyRecuperationLine> lineList = dao().query(TheRapyRecuperationLine.class, Cnd.where("year", "=", DateUtil.thisYear())
List<TheRapyRecuperationLine> lineList = dao().query(TheRapyRecuperationLine.class, Cnd.where("year", "=", lineInfo.getYear())
.and("isDisabled", "=", false));
List<String> lineIds = lineList.stream().map(TheRapyRecuperationLine::getId).collect(Collectors.toList());
//获取这些线路在选择表中的选择id,因为报名表存的是选择id
@@ -665,7 +674,7 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
List<String> selectIds = selectList.stream().map(TheRapyRecuperationLineUnionSelect::getId).collect(Collectors.toList());
//获取这些省外线路的总报名人数
List<TheRapyRecuperationEnroll> enrollList = dao().query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "in", selectIds)
.and("isNormal", "=", true).and("signingUptime", "=", DateUtil.thisYear())
.and("isNormal", "=", true).and("YEAR(signingUptime)", "=", lineInfo.getYear())
.and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL)));
//活动范围总人数
List<ActivityUserScope> userScopes = dao().query(ActivityUserScope.class, Cnd.where("groupId", "=", config.getActivityGroupId()));
@@ -713,10 +722,9 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
}
}
public Map<Boolean, String> validSignTime(TheRapyRecuperationEnroll currentEnroll) {
TheRapyRecuperationConfig config = fetchLatestConfig();
public Map<Boolean, String> validSignTime(TheRapyRecuperationEnroll currentEnroll, TheRapyRecuperationConfig config) {
if (config == null) {
return Map.of(false, "未找到最新疗休养配置,请联系管理员");
return Map.of(false, "未找到对应年度疗休养配置,请联系管理员");
}
DateTime signUpStartTime = null;
DateTime signUpEndTime = null;
@@ -737,12 +745,39 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
}
/**
* 获取最新提交的疗休养配置。
* 获取报名对象所属年度的疗休养配置。
*
* @return 最新疗休养配置
* @return 对应年度疗休养配置
*/
private TheRapyRecuperationConfig fetchLatestConfig() {
return dao().fetch(TheRapyRecuperationConfig.class, Cnd.where("latestConfig", "=", true));
private TheRapyRecuperationConfig fetchConfigByEnroll(TheRapyRecuperationEnroll currentEnroll) {
Integer year = fetchEnrollYear(currentEnroll);
// Load config by the year of the selected line or base management.
return configService.requireByYear(year);
}
private Integer fetchEnrollYear(TheRapyRecuperationEnroll currentEnroll) {
if (currentEnroll == null) {
return DateUtil.thisYear();
}
if (StrUtil.isNotBlank(currentEnroll.getTakePartInLineId())) {
TheRapyRecuperationLineUnionSelect lineUnionSelect = dao().fetch(TheRapyRecuperationLineUnionSelect.class, currentEnroll.getTakePartInLineId());
if (lineUnionSelect != null && StrUtil.isNotBlank(lineUnionSelect.getLineId())) {
TheRapyRecuperationLine line = dao().fetch(TheRapyRecuperationLine.class, lineUnionSelect.getLineId());
if (line != null && line.getYear() != null) {
return line.getYear();
}
}
if (lineUnionSelect != null && lineUnionSelect.getSelectTime() != null) {
return DateUtil.year(lineUnionSelect.getSelectTime());
}
}
if (StrUtil.isNotBlank(currentEnroll.getTakePartInBaseManagementId())) {
TheRapyRecuperationBaseManagement baseManagement = dao().fetch(TheRapyRecuperationBaseManagement.class, currentEnroll.getTakePartInBaseManagementId());
if (baseManagement != null && baseManagement.getYear() != null) {
return baseManagement.getYear();
}
}
return DateUtil.thisYear();
}
public Map<Boolean, String> validBaseManagementCount(String loginName, TheRapyRecuperationEnroll currentEnroll) {
@@ -1036,7 +1071,7 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
""");
cnd.and("e.takePartInTravelAgencyId", "is not", null);
cnd.and("e.isNormal", "=", true);
cnd.andEX("ta.year", "=", year);
cnd.andEX("year(e.signingUptime)", "=", year);
taSql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), taSql);
}
@@ -1099,6 +1134,126 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
// RCSCloudAPI.sendTplSms("81d48e1811144270b838b321575c7199", user.getMobile(), "@1@=" + user.getUsername() + "||@2@=取消||@3@=" + lineInfo.getLineName(), "");
}
@Override
@Aop(TransAop.READ_COMMITTED)
public Result supplementEnrollImport(String takePartInLineId, File file) {
if (StrUtil.isBlank(takePartInLineId)) {
return Result.error("请选择补录线路");
}
TheRapyRecuperationLineUnionSelect lineUnionSelect = dao().fetch(TheRapyRecuperationLineUnionSelect.class, takePartInLineId);
if (lineUnionSelect == null) {
return Result.error("选择的线路不存在");
}
TheRapyRecuperationLine lineInfo = dao().fetch(TheRapyRecuperationLine.class, lineUnionSelect.getLineId());
if (lineInfo == null) {
return Result.error("选择的线路信息不存在");
}
List<TheRapyRecuperationEnrollExcelMode> excelList;
try {
excelList = ExcelImportUtil.importExcel(file, TheRapyRecuperationEnrollExcelMode.class, new ImportParams());
} catch (Exception e) {
return Result.error("读取不到数据,请检查excel文件格式");
}
if (Lang.isEmpty(excelList)) {
return Result.error("读取不到数据,请检查excel文件格式");
}
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLoginName()))
|| excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getUserName()))) {
return Result.error("工号和姓名不能为空");
}
if (excelList.stream().anyMatch(v -> StrUtil.isBlank(v.getLotId()))
|| excelList.stream().anyMatch(v -> v.getTakePartInTime() == null)) {
return Result.error("标段时间和参加时间不能为空");
}
List<String> loginNames = excelList.stream()
.map(v -> StrUtil.trim(v.getLoginName()))
.distinct()
.collect(Collectors.toList());
List<Integer> importYears = excelList.stream()
.map(v -> DateUtil.year(v.getTakePartInTime()))
.distinct()
.collect(Collectors.toList());
Map<String, User> userMap = dao().query(User.class, Cnd.where("loginname", "in", loginNames))
.stream()
.collect(Collectors.toMap(User::getLoginname, v -> v, (oldValue, newValue) -> oldValue));
Map<String, TheRapyRecuperationEnroll> existEnrollMap = dao().query(TheRapyRecuperationEnroll.class, Cnd.where("loginName", "in", loginNames)
.and("YEAR(signingUptime)", "in", importYears))
.stream()
.collect(Collectors.toMap(v -> v.getLoginName() + "_" + DateUtil.year(v.getSigningUptime()), v -> v, (oldValue, newValue) -> oldValue));
TheRapyRecuperationConfig lineConfig = configService.requireByYear(lineInfo.getYear());
// 补录标段必须限定在所选线路年度配置内,避免不同年度同名标段匹配错。
Map<String, TheRapyRecuperationLot> lotMap = dao().query(TheRapyRecuperationLot.class, Cnd.where("configId", "=", lineConfig.getId()))
.stream()
.collect(Collectors.toMap(TheRapyRecuperationLot::getLotName, v -> v, (oldValue, newValue) -> oldValue));
List<TheRapyRecuperationEnroll> supplementList = new ArrayList<>();
List<String> existInfos = new ArrayList<>();
List<String> errorInfos = new ArrayList<>();
Set<String> supplementKeys = new HashSet<>();
for (TheRapyRecuperationEnrollExcelMode excel : excelList) {
String loginName = StrUtil.trim(excel.getLoginName());
int takePartInYear = DateUtil.year(excel.getTakePartInTime());
String enrollKey = loginName + "_" + takePartInYear;
if (existEnrollMap.containsKey(enrollKey) || supplementKeys.contains(enrollKey)) {
existInfos.add(loginName);
continue;
}
User user = userMap.get(loginName);
if (user == null) {
errorInfos.add("工号" + loginName + "的系统用户不存在");
continue;
}
TheRapyRecuperationLot lot = lotMap.get(excel.getLotId());
if (lot == null) {
errorInfos.add("工号" + loginName + "的标段时间不存在");
continue;
}
if (StrUtil.isNotBlank(lineInfo.getLotId()) && !lineInfo.getLotId().equals(lot.getId())) {
errorInfos.add("工号" + loginName + "的标段时间与所选线路不一致");
continue;
}
TheRapyRecuperationEnroll enroll = new TheRapyRecuperationEnroll();
enroll.setLoginName(loginName);
enroll.setUserName(user.getUsername());
enroll.setSex(user.getSex());
enroll.setUnitName(user.getUnitname());
enroll.setUnionName(user.getUnionname());
enroll.setSelfUnitId(user.getUnitid());
enroll.setSelfUnionId(user.getUnionid());
enroll.setIdCard(user.getIdcard());
enroll.setMobile(user.getMobile());
enroll.setTakePartInLineId(lineUnionSelect.getId());
enroll.setTakePartInUnionId(lineUnionSelect.getSignUpMode() != null
&& lineUnionSelect.getSignUpMode() == TheRapyRecuperationSignUpMode.FREE.getValue() ? null : lineUnionSelect.getUnionId());
enroll.setTakePartInTravelAgencyId(lineInfo.getTravelAgencyId());
// 补录无法取得原始报名时间,使用参加时间所属年度年初作为报名年度依据。
enroll.setSigningUptime(DateUtil.beginOfYear(excel.getTakePartInTime()));
enroll.setTakePartInTime(excel.getTakePartInTime());
enroll.setLotId(lot.getId());
enroll.setStateId(TheRapyRecuperationState.PASS);
enroll.setTakePartIn(true);
enroll.setNormal(true);
supplementKeys.add(enrollKey);
supplementList.add(enroll);
}
if (Lang.isNotEmpty(supplementList)) {
dao().insert(supplementList);
}
if (Lang.isEmpty(supplementList) && Lang.isNotEmpty(errorInfos) && Lang.isEmpty(existInfos)) {
return Result.error("补录失败:" + String.join("", errorInfos));
}
String msg = "补录成功" + supplementList.size() + "人,已存在" + existInfos.size() + "";
if (Lang.isNotEmpty(errorInfos)) {
msg += ",失败" + errorInfos.size() + "人:" + String.join("", errorInfos);
}
return Result.success(msg);
}
/**
* 手机端线路介绍所有信息
*
@@ -9,10 +9,13 @@ import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationLineCreateMode;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationSignUpMode;
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnroll;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationEnrollCompanion;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLine;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLineUnionSelect;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLot;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationLineService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
@@ -21,6 +24,7 @@ import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.plugins.wkcache.annotation.CacheRemove;
@@ -38,6 +42,9 @@ import java.util.List;
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationLineServiceImpl extends ViServiceImpl<TheRapyRecuperationLine> implements TheRapyRecuperationLineService {
@Inject
private TheRapyRecuperationConfigService configService;
public TheRapyRecuperationLineServiceImpl(Dao dao) {
super(dao);
}
@@ -238,4 +245,148 @@ public class TheRapyRecuperationLineServiceImpl extends ViServiceImpl<TheRapyRec
""");
return listMap(sql);
}
/**
* 复制校工会组织线路到目标年度,编号从当前最大编号后递增,避免复用历史线路编号。
* 复制时只生成新的线路基础数据,不复制分工会选择记录、报名记录和审核记录,防止新年度业务挂到旧流程。
*
* @param sourceYear 来源年度
* @param targetYear 目标年度
* @return 复制结果,包含来源数量、复制数量和跳过数量
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public NutMap copySchoolUnionLines(Integer sourceYear, Integer targetYear) {
List<TheRapyRecuperationLine> sourceLines = query(Cnd.where("year", "=", sourceYear)
.and("signUpMode", "=", TheRapyRecuperationSignUpMode.FREE.getValue())
.asc("serialNumber"));
int nextSerialNumber = getNextSerialNumber();
int copyCount = 0;
int skipCount = 0;
for (TheRapyRecuperationLine sourceLine : sourceLines) {
String targetLotId = getLatestLotIdBySourceLotId(sourceLine.getLotId(), targetYear);
if (StrUtil.isBlank(targetLotId)) {
skipCount++;
continue;
}
if (existsTargetSchoolUnionLine(sourceLine, targetYear, targetLotId)) {
skipCount++;
continue;
}
TheRapyRecuperationLine copyLine = buildCopyLine(sourceLine, targetYear, nextSerialNumber++, targetLotId);
insert(copyLine);
copyCount++;
}
return new NutMap()
.setv("sourceYear", sourceYear)
.setv("targetYear", targetYear)
.setv("sourceCount", sourceLines.size())
.setv("copyCount", copyCount)
.setv("skipCount", skipCount);
}
/**
* 目标年度中已存在同名、同旅行社、同标段、同区域性质的校工会组织线路时,不再重复复制。
*
* @param sourceLine 来源线路
* @param targetYear 目标年度
* @param targetLotId 最新配置中匹配到的目标标段id
* @return 是否已存在目标年度线路
*/
private boolean existsTargetSchoolUnionLine(TheRapyRecuperationLine sourceLine, Integer targetYear, String targetLotId) {
return count(Cnd.where("year", "=", targetYear)
.and("signUpMode", "=", TheRapyRecuperationSignUpMode.FREE.getValue())
.and("lineName", "=", sourceLine.getLineName())
.and("travelAgencyId", "=", sourceLine.getTravelAgencyId())
.and("lotId", "=", targetLotId)
.and("regionalNature", "=", sourceLine.getRegionalNature())) > 0;
}
/**
* 组装新年度线路基础信息,清空主键和审核记录,确保新年度线路拥有独立编号和独立业务流程。
*
* @param sourceLine 来源线路
* @param targetYear 目标年度
* @param nextSerialNumber 新线路编号
* @param targetLotId 最新配置中匹配到的目标标段id
* @return 新年度线路
*/
private TheRapyRecuperationLine buildCopyLine(TheRapyRecuperationLine sourceLine, Integer targetYear, int nextSerialNumber, String targetLotId) {
TheRapyRecuperationLine copyLine = new TheRapyRecuperationLine();
copyLine.setSerialNumber(nextSerialNumber);
copyLine.setLineName(sourceLine.getLineName());
copyLine.setTravelAgencyId(sourceLine.getTravelAgencyId());
copyLine.setRegionalNature(sourceLine.getRegionalNature());
copyLine.setPlayNumberOfDays(sourceLine.getPlayNumberOfDays());
copyLine.setContent(sourceLine.getContent());
copyLine.setMinimumGroupSize(sourceLine.getMinimumGroupSize());
copyLine.setYear(targetYear);
copyLine.setDisabled(sourceLine.isDisabled());
copyLine.setCreateUnionId(sourceLine.getCreateUnionId());
copyLine.setSignUpStartTime(copyDate(sourceLine.getSignUpStartTime()));
copyLine.setSignUpEndTime(copyDate(sourceLine.getSignUpEndTime()));
copyLine.setChangeEndTime(copyDate(sourceLine.getChangeEndTime()));
copyLine.setPlayStartTime(copyDate(sourceLine.getPlayStartTime()));
copyLine.setPlayEndTime(copyDate(sourceLine.getPlayEndTime()));
copyLine.setTrafficTools(sourceLine.getTrafficTools());
copyLine.setEstimatedCost(sourceLine.getEstimatedCost());
copyLine.setEstimatedFamilyNumbers(sourceLine.getEstimatedFamilyNumbers());
copyLine.setMaxGroupSize(sourceLine.getMaxGroupSize());
copyLine.setFiles(sourceLine.getFiles());
copyLine.setSignUpMode(TheRapyRecuperationSignUpMode.FREE.getValue());
copyLine.setCreateMode(TheRapyRecuperationLineCreateMode.SCHOOL.getValue());
copyLine.setLotId(targetLotId);
copyLine.setLineContact(sourceLine.getLineContact());
copyLine.setLineContactPhone(sourceLine.getLineContactPhone());
copyLine.setTravelAgencyPlace(sourceLine.getTravelAgencyPlace());
copyLine.setOpenChoose(sourceLine.getOpenChoose());
copyLine.setSpecialLine(sourceLine.getSpecialLine());
copyLine.setTogetherLine(sourceLine.getTogetherLine());
copyLine.setGroupType(sourceLine.getGroupType());
// 线路表审核状态使用 1、2、3、4,来源为空时默认按审核通过处理。
copyLine.setStateId(sourceLine.getStateId() == null ? 4 : sourceLine.getStateId());
copyLine.setSchoolAuditId(null);
return copyLine;
}
/**
* 沿用线路时,按来源标段的出行天数匹配最新配置标段,避免新年度线路继续使用旧配置标段。
*
* @param sourceLotId 来源线路标段id
* @return 最新配置中相同出行天数的标段id,无法匹配时返回空
*/
private String getLatestLotIdBySourceLotId(String sourceLotId, Integer targetYear) {
if (StrUtil.isBlank(sourceLotId)) {
return null;
}
TheRapyRecuperationLot sourceLot = dao().fetch(TheRapyRecuperationLot.class, sourceLotId);
if (sourceLot == null || StrUtil.isBlank(sourceLot.getLotValue())) {
return null;
}
// Match the copied lot against the target year's config.
TheRapyRecuperationConfig targetConfig = configService.requireByYear(targetYear);
if (StrUtil.isBlank(targetConfig.getId())) {
return null;
}
TheRapyRecuperationLot targetLot = dao().fetch(TheRapyRecuperationLot.class, Cnd.where("configId", "=", targetConfig.getId())
.and("lotValue", "=", sourceLot.getLotValue()));
return targetLot == null ? null : targetLot.getId();
}
/**
* 查询当前线路最大编号,并返回下一位可用编号。
*
* @return 下一位线路编号
*/
private int getNextSerialNumber() {
Sql sql = Sqls.fetchInt("SELECT max(serialNumber * 1) FROM the_rapy_recuperation_line");
dao().execute(sql);
return sql.getInt() + 1;
}
private Date copyDate(Date date) {
return date == null ? null : new Date(date.getTime());
}
}
@@ -98,7 +98,12 @@ public class TheRapyRecuperationLineUnionSelectServiceImpl extends ViServiceImpl
""");
//sql.setVar("us", "AND us.selectUserId = '%s'".formatted(ShiroUtil.getPlatformUid()));
sql.setParam("year", year == null ? DateUtil.thisYear() : year);
cnd.groupBy("line.id");
//管理员查看个人组织线路时,同一线路可能被不同人员选择,需要按选择人拆分展示。
if (mode == 3 && ShiroUtil.hasAnyRoles("sysadmin, SchoolUnionAdmin")) {
cnd.groupBy("line.id, us.selectUserId");
} else {
cnd.groupBy("line.id");
}
sql.setCondition(cnd);
Pagination pagination = list(pageForm, sql);
List<NutMap> list = pagination.getList();
@@ -152,7 +157,8 @@ public class TheRapyRecuperationLineUnionSelectServiceImpl extends ViServiceImpl
List<User> userList = dao().query(User.class, Cnd.where("unitId", "=", "100414"));
List<String> idListByUnit = userList.stream().map(User::getId).toList();
cnd.and("selectUserId", "in", Stream.concat(list.stream(), idListByUnit.stream()).toList());
} else {
} else if (!(mode == 3 && ShiroUtil.hasAnyRoles("sysadmin, SchoolUnionAdmin"))) {
//管理员查看个人组织线路时,需要标记所有人员已选择的线路,普通用户仍只标记自己的选择。
cnd.and("selectUserId", "=", ShiroUtil.getUserId());
}
sql.setCondition(cnd);
@@ -1,16 +1,29 @@
package io.v.nutz.zhgh.therapyRecuperation.service.impl.baseManage;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import io.v.nutz.base.service.impl.BaseServiceImpl;
import io.v.nutz.base.utils.Vi;
import io.v.nutz.web.commons.utils.ShiroUtil;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationBaseManagement;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLot;
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
import io.v.nutz.zhgh.therapyRecuperation.service.baseManage.TheRapyRecuperationBaseManagerService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* @Author JyuHsin
* @Date 2023/6/7
@@ -19,6 +32,9 @@ import org.nutz.lang.util.NutMap;
@IocBean(args = {"refer:dao"})
public class TheRapyRecuperationBaseManagerServiceImpl extends BaseServiceImpl implements TheRapyRecuperationBaseManagerService {
@Inject
private TheRapyRecuperationConfigService configService;
public TheRapyRecuperationBaseManagerServiceImpl(Dao dao) {
super(dao);
}
@@ -46,4 +62,142 @@ public class TheRapyRecuperationBaseManagerServiceImpl extends BaseServiceImpl i
NutMap nutMap = (NutMap) sql.getResult();
return nutMap;
}
/**
* 复制上一年度目的地到目标年度,排序号从当前最大排序号后递增,避免复用历史目的地排序号。
* 复制时只生成目的地基础数据,不复制报名记录,防止目标年度业务挂到旧年度报名数据。
*
* @param sourceYear 来源年度
* @param targetYear 目标年度
* @return 复制结果,包含来源数量、复制数量和跳过数量
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public NutMap copyLastYearBase(Integer sourceYear, Integer targetYear) {
Cnd sourceCnd = (Cnd) Cnd.where("year", "=", sourceYear).asc("sortNumber");
if (!ShiroUtil.hasAnyRoles("sysadmin,A06") && ShiroUtil.hasRole("H04")) {
sourceCnd.and("createUnionId", "=", Vi.getUnionId());
}
List<TheRapyRecuperationBaseManagement> sourceBases = dao().query(TheRapyRecuperationBaseManagement.class, sourceCnd);
int nextSortNumber = getNextSortNumber();
int copyCount = 0;
int skipCount = 0;
for (TheRapyRecuperationBaseManagement sourceBase : sourceBases) {
String targetLotId = getLatestLotIdBySourceLotId(sourceBase.getLotId(), targetYear);
if (StrUtil.isNotBlank(sourceBase.getLotId()) && StrUtil.isBlank(targetLotId)) {
skipCount++;
continue;
}
if (existsTargetBase(sourceBase, targetYear, targetLotId)) {
skipCount++;
continue;
}
TheRapyRecuperationBaseManagement copyBase = buildCopyBase(sourceBase, targetYear, nextSortNumber++, targetLotId);
dao().insert(copyBase);
copyCount++;
}
return new NutMap()
.setv("sourceYear", sourceYear)
.setv("targetYear", targetYear)
.setv("sourceCount", sourceBases.size())
.setv("copyCount", copyCount)
.setv("skipCount", skipCount);
}
/**
* 目标年度存在同名、同旅行社、同地点、同区域、同标段的目的地时,不再重复复制。
*
* @param sourceBase 来源目的地
* @param targetYear 目标年度
* @param targetLotId 最新配置中匹配到的目标标段id
* @return 是否已存在目标年度目的地
*/
private boolean existsTargetBase(TheRapyRecuperationBaseManagement sourceBase, Integer targetYear, String targetLotId) {
return dao().count(TheRapyRecuperationBaseManagement.class, Cnd.where("year", "=", targetYear)
.and("baseName", "=", sourceBase.getBaseName())
.and("travelAgencyId", "=", sourceBase.getTravelAgencyId())
.and("travelAgencyPlace", "=", sourceBase.getTravelAgencyPlace())
.and("regionalNature", "=", sourceBase.getRegionalNature())
.and("lotId", "=", targetLotId)) > 0;
}
/**
* 组装目标年度目的地基础信息,清空主键并设置新的排序号。
*
* @param sourceBase 来源目的地
* @param targetYear 目标年度
* @param nextSortNumber 新排序号
* @param targetLotId 最新配置中匹配到的目标标段id
* @return 目标年度目的地
*/
private TheRapyRecuperationBaseManagement buildCopyBase(TheRapyRecuperationBaseManagement sourceBase, Integer targetYear, int nextSortNumber, String targetLotId) {
TheRapyRecuperationBaseManagement copyBase = new TheRapyRecuperationBaseManagement();
copyBase.setYear(targetYear);
copyBase.setSortNumber(nextSortNumber);
copyBase.setBaseName(sourceBase.getBaseName());
copyBase.setTravelAgencyId(sourceBase.getTravelAgencyId());
copyBase.setRegionalNature(sourceBase.getRegionalNature());
copyBase.setLotId(targetLotId);
copyBase.setContent(sourceBase.getContent());
copyBase.setIsDisabled(sourceBase.getIsDisabled());
copyBase.setCreateUnionId(sourceBase.getCreateUnionId());
copyBase.setSignUpStartTime(copyDate(sourceBase.getSignUpStartTime()));
copyBase.setSignUpEndTime(copyDate(sourceBase.getSignUpEndTime()));
copyBase.setChangeEndTime(copyDate(sourceBase.getChangeEndTime()));
copyBase.setActivityStartTime(copyDate(sourceBase.getActivityStartTime()));
copyBase.setActivityEndTime(copyDate(sourceBase.getActivityEndTime()));
copyBase.setEstimatedCost(sourceBase.getEstimatedCost());
copyBase.setFiles(sourceBase.getFiles());
copyBase.setCreateMode(sourceBase.getCreateMode());
copyBase.setBaseContactPerson(sourceBase.getBaseContactPerson());
copyBase.setBaseContactNumber(sourceBase.getBaseContactNumber());
copyBase.setOpBy((String) ShiroUtil.getPrincipalProperty("id"));
copyBase.setOpAt(String.valueOf(new Date().getTime()));
copyBase.setWeekCheckIn(sourceBase.getWeekCheckIn());
copyBase.setAllowDay(sourceBase.getAllowDay());
copyBase.setMaxSignCount(sourceBase.getMaxSignCount());
copyBase.setTravelAgencyPlace(sourceBase.getTravelAgencyPlace());
return copyBase;
}
/**
* 沿用目的地时,来源存在标段才按出行天数匹配最新配置;来源为空时保持为空,兼容当前目的地使用 allowDay 的数据。
*
* @param sourceLotId 来源目的地标段id
* @return 最新配置中相同出行天数的标段id,无法匹配时返回空
*/
private String getLatestLotIdBySourceLotId(String sourceLotId, Integer targetYear) {
if (StrUtil.isBlank(sourceLotId)) {
return sourceLotId;
}
TheRapyRecuperationLot sourceLot = dao().fetch(TheRapyRecuperationLot.class, sourceLotId);
if (sourceLot == null || StrUtil.isBlank(sourceLot.getLotValue())) {
return null;
}
// Match the copied lot against the target year's config.
TheRapyRecuperationConfig targetConfig = configService.requireByYear(targetYear);
if (StrUtil.isBlank(targetConfig.getId())) {
return null;
}
TheRapyRecuperationLot targetLot = dao().fetch(TheRapyRecuperationLot.class, Cnd.where("configId", "=", targetConfig.getId())
.and("lotValue", "=", sourceLot.getLotValue()));
return targetLot == null ? null : targetLot.getId();
}
/**
* 查询当前目的地最大排序号,并返回下一位可用排序号。
*
* @return 下一位排序号
*/
private int getNextSortNumber() {
Object sortNumber = dao().func2(TheRapyRecuperationBaseManagement.class, "max", "sortNumber");
sortNumber = Objects.requireNonNullElse(sortNumber, 0);
return Integer.parseInt(sortNumber.toString()) + 1;
}
private Date copyDate(Date date) {
return date == null ? null : new Date(date.getTime());
}
}
@@ -877,9 +877,11 @@ layout("/mobile/platform.html"){
this.userList = data
}
},
async getConfigData() {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.configData = resp.data
async getConfigData(year) {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.baseData.year || new Date().getFullYear().toString()
})
this.$set(this, 'configData', resp.data)
},
async toResult(loginname) {
const res = await $.post('/platform/theRapyRecuperation/line/enroll/validSignUpInfo', {
@@ -953,7 +955,6 @@ layout("/mobile/platform.html"){
},
},
async created() {
await this.getConfigData()
this.id = getQueryString('id') ? getQueryString('id') : ''
this.enrollId = getQueryString('enrollId') ? getQueryString('enrollId') : ''
this.index = getQueryString('index') ? getQueryString('index') : ''
@@ -963,6 +964,7 @@ layout("/mobile/platform.html"){
await this.findSignUpInfoById()
}
await this.getData()
await this.getConfigData(this.baseData.year)
try {
const parser = new DOMParser();
@@ -752,9 +752,11 @@ layout("/mobile/platform.html"){
this.$forceUpdate()
}
},
async getConfigData() {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.configData = resp.data
async getConfigData(year) {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.lineData.year || new Date().getFullYear().toString()
})
this.$set(this, 'configData', resp.data)
},
handleClick(event, classArray = [], imagesArray = []) {
if(event == null) {
@@ -802,7 +804,6 @@ layout("/mobile/platform.html"){
async created() {
this.id = getQueryString('id') ? getQueryString('id') : ''
this.index = getQueryString('index') ? getQueryString('index') : ''
await this.getConfigData()
//编辑传出来的参数
this.fromUrlByMy = getQueryString('fromUrlByMy') ? getQueryString('fromUrlByMy') : ''
this.enrollId = getQueryString('enrollId') ? getQueryString('enrollId') : ''
@@ -811,6 +812,7 @@ layout("/mobile/platform.html"){
await this.findSignUpInfoById()
}
await this.getData()
await this.getConfigData(this.lineData.year)
this.isLoad = true
try {
const parser = new DOMParser();
@@ -439,7 +439,7 @@ layout("/mobile/platform.html"){
<van-popup v-model="travelPicker" position="bottom">
<van-picker
show-toolbar
value-key="travelAgencyName"
value-key="travelAgencyLabel"
:columns="travelOptions"
@cancel="travelPicker = false"
@confirm="(value, index) => {pageForm.travelName=value.travelAgencyName;pageForm.travelId=value.id;travelPicker=false}"
@@ -565,6 +565,7 @@ layout("/mobile/platform.html"){
this.unionPop = true
},
doSearch() {
this.getModifyConfig(this.pageForm.year)
this.loading = true
this.finished = false
this.getData()
@@ -656,15 +657,22 @@ layout("/mobile/platform.html"){
})
return resp.data
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year || new Date().getFullYear().toString()
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async getTravelAgencyOptions() {
const {data} = await $.get('/platform/theRapyRecuperation/line/getTravelAgencyOptions')
this.travelOptions = data
this.travelOptions = data.map(v => {
return {
...v,
travelAgencyLabel: v.travelAgencyName + (v.serialNumber ? '(' + v.serialNumber + ')' : '')
}
})
},
},
mounted() {
@@ -675,7 +683,7 @@ layout("/mobile/platform.html"){
},
async created() {
this.createYear()
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.year)
this.chooseButton = await getEnumOptions('TheRapyRecuperationType')
this.chooseButton = this.chooseButton.filter(o => o.value !== 2)
const unions = await this.getTheRapyUnions()
@@ -683,6 +683,7 @@ layout("/mobile/platform.html"){
return true;
},
doSearch() {
this.getConfigData(this.pageForm.year);
this.loading = true;
this.finished = false;
this.getData();
@@ -833,11 +834,12 @@ layout("/mobile/platform.html"){
this.yearArray.push({value: i, text: i + "年"});
}
},
async getConfigData() {
async getConfigData(year) {
const resp = await $.get(
"/platform/theRapyRecuperation/TheRapyConfig/findOne",
{year: year || this.pageForm.year || new Date().getFullYear().toString()}
);
this.configData = resp.data;
this.$set(this, "configData", resp.data);
},
},
async created() {
@@ -850,7 +852,7 @@ layout("/mobile/platform.html"){
this.chooseButton = this.chooseButton.filter(
(o) => o.value !== 2,
);
await this.getConfigData();
await this.getConfigData(this.pageForm.year);
this.onLoad();
},
mounted() {
@@ -940,14 +940,17 @@ layout("/layouts/platform.html"){
},
async doSearch() {
this.pageForm.pageNumber = 1;
await this.getModifyConfig(this.pageForm.year)
this.pageData();
await this.getApplyNumAudit()
this.takePartInLines = await this.getXlByUnion()
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async getUnionSelectLine() {
@@ -962,7 +965,7 @@ layout("/layouts/platform.html"){
},
async created() {
await this.getBmUserUnion()
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.year)
this.takePartInLines = await this.getXlByUnion()
await this.doSearch()
await this.getUnionSelectLine()
@@ -111,7 +111,7 @@ layout("/layouts/platform.html"){
style="width: 80%">
<el-option v-for="item in agencyLists"
:key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id">
</el-option>
</el-select>
@@ -416,7 +416,7 @@ layout("/layouts/platform.html"){
style="width: 100%">
<el-option v-for="item in agencyLists"
:key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id">
</el-option>
</el-select>
@@ -499,10 +499,7 @@ layout("/layouts/platform.html"){
},
methods: {
async getAgencyList() {
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgencyByYears", {
startYear: this.pageForm.startYear,
endYear: this.pageForm.endYear
})
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgency")
this.agencyLists = data
},
dropdownCommand(command) {
@@ -781,20 +778,23 @@ layout("/layouts/platform.html"){
},
async doSearch() {
this.pageForm.pageNumber = 1;
await this.getModifyConfig(this.pageForm.year)
this.pageData();
await this.getApplyNumAudit()
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
},
async created() {
await this.getBmUserUnion()
await this.getAgencyList()
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.year)
await this.doSearch()
}
})
@@ -935,14 +935,17 @@ layout("/layouts/platform.html"){
// },
async doSearch() {
this.pageForm.pageNumber = 1;
await this.getModifyConfig(this.pageForm.year)
this.pageData();
//await this.getApplyNumAudit()
this.takePartInLines = await this.getXlByUnion()
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async getUnionSelectLine() {
@@ -957,7 +960,7 @@ layout("/layouts/platform.html"){
},
async created() {
await this.getBmUserUnion()
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.year)
this.takePartInLines = await this.getXlByUnion()
await this.doSearch()
await this.getLineSignNumber()
@@ -35,7 +35,7 @@ layout("/layouts/platform.html"){
v-model="pageForm.travelAgencyId"
@change="doSearch">
<el-option :key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyList"
></el-option>
@@ -62,9 +62,13 @@ layout("/layouts/platform.html"){
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="目的地列表">
<template #func>
<el-button @click="openCopyBase"
size="medium"
type="primary">沿用目的地</el-button>
<el-button @click="openImport" size="medium" type="primary">导入目的地
</el-button>
<el-button @click="openAdd" size="medium" type="primary">新建目的地</el-button>
</template>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
@@ -150,7 +154,7 @@ layout("/layouts/platform.html"){
<el-select clearable filterable style="width: 100%" @change="travelChange"
v-model="formData.travelAgencyId" placeholder="请选择旅行社名称">
<el-option :key="item.id"
:label="item.travelAgencyName+'('+ item.year +'年)'"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyList"
></el-option>
@@ -423,6 +427,38 @@ layout("/layouts/platform.html"){
</span>
</el-dialog>
<el-dialog
title="沿用目的地"
:visible.sync="copyBaseVisible"
:close-on-click-modal="false"
width="420px"
>
<el-form :model="copyBaseForm" :rules="copyBaseRules" ref="copyBaseForm" label-width="110px">
<el-form-item label="来源年度" prop="sourceYear">
<el-date-picker
v-model="copyBaseForm.sourceYear"
type="year"
placeholder="请选择来源年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="目标年度" prop="targetYear">
<el-date-picker
v-model="copyBaseForm.targetYear"
type="year"
placeholder="请选择目标年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeCopyBaseDialog" :disabled="copyBaseLoading">取消</el-button>
<el-button type="primary" @click="doCopyBase" :loading="copyBaseLoading">确定</el-button>
</span>
</el-dialog>
<template #view>
<base-info ref="viewBaseInfo"></base-info>
</template>
@@ -564,12 +600,27 @@ layout("/layouts/platform.html"){
importVisible: false,
importLoading: false,
importData: {},
copyBaseVisible: false,
copyBaseLoading: false,
copyBaseForm: {
sourceYear: (new Date().getFullYear() - 1).toString(),
targetYear: new Date().getFullYear().toString()
},
copyBaseRules: {
sourceYear: [{required: true, message: '请选择来源年度', trigger: ['change', 'blur']}],
targetYear: [{required: true, message: '请选择目标年度', trigger: ['change', 'blur']}]
},
}
},
methods: {
travelChange(val) {
this.$set(this.formData,'travelAgencyPlace','')
const travel = this.travelAgencyList.find(o => o.id === val)
if (!travel) {
this.$set(this.formData,'baseContactPerson', null)
this.$set(this.formData,'baseContactNumber', null)
return
}
this.$set(this.formData,'baseContactPerson', travel.contact)
this.$set(this.formData,'baseContactNumber', travel.contactMobileNumber)
},
@@ -593,8 +644,47 @@ layout("/layouts/platform.html"){
await this.pageData();
},
async selectTravelAgencyList() {
const resp = await $.post('/platform/theRapyRecuperation/travelAgency/selectTravelAgency', {year: this.formData.year})
this.travelAgencyList = resp.data
const resp = await $.post('/platform/theRapyRecuperation/travelAgency/selectTravelAgency')
this.$set(this, 'travelAgencyList', resp.data)
},
openCopyBase() {
this.$set(this.copyBaseForm, 'sourceYear', (new Date().getFullYear() - 1).toString())
this.$set(this.copyBaseForm, 'targetYear', new Date().getFullYear().toString())
this.$set(this, 'copyBaseVisible', true)
this.$nextTick(() => {
if (this.$refs.copyBaseForm) {
this.$refs.copyBaseForm.clearValidate()
}
})
},
closeCopyBaseDialog() {
if (this.copyBaseLoading) return
this.$set(this, 'copyBaseVisible', false)
},
async doCopyBase() {
const valid = await this.$refs.copyBaseForm.validate()
if (!valid) return
if (this.copyBaseForm.sourceYear === this.copyBaseForm.targetYear) {
this.notifyWarning('来源年度和目标年度不能相同')
return
}
const confirm = await this.$confirm('确定沿用来源年度的目的地到目标年度吗?沿用后将生成新的排序编号。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm !== 'confirm') return
this.$set(this, 'copyBaseLoading', true)
const resp = await $.post(loc() + '/copyLastYearBase', this.copyBaseForm)
this.$set(this, 'copyBaseLoading', false)
if (resp.code === 0) {
const result = resp.data || {}
this.notifySuccess('沿用完成,来源目的地' + (result.sourceCount || 0) + '条,新增' + (result.copyCount || 0) + '条,跳过' + (result.skipCount || 0) + '条')
this.$set(this, 'copyBaseVisible', false)
this.pageData()
} else {
this.notifyWarning(resp.msg)
}
},
async openAdd() {
this.$refs.guava.edit()
@@ -615,6 +705,8 @@ layout("/layouts/platform.html"){
const data = resp.data
data.year = data.year.toString()
this.formData = {...data}
await this.selectTravelAgencyList()
await this.getModifyBd(data.year)
this.formData.weekIn = this.formData.weekCheckIn && this.formData.weekCheckIn.length > 0 ? 2 : 1
this.initLineContentEditor(data.content)
} else {
@@ -667,9 +759,10 @@ layout("/layouts/platform.html"){
this.notifyWarning(resp.msg)
}
},
yearChange() {
this.formData.travelAgencyId = null
this.selectTravelAgencyList()
async yearChange() {
this.$set(this.formData, 'lotId', null)
this.$set(this.formData, 'estimatedCost', null)
await this.getModifyBd(this.formData.year)
},
async openView(id) {
this.$refs.guava.view()
@@ -685,14 +778,16 @@ layout("/layouts/platform.html"){
this.formData = obj;
},
async initPageData() {
await this.getModifyBd();
await this.getModifyBd(this.pageForm.year);
this.unionOptions = await getUnions(null)
await this.selectTravelAgencyList()
},
async getModifyBd() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyBd(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.formData.year || this.pageForm.year
})
if (res.code === 0) {
this.modifyBdList = res.data.lots
this.$set(this, 'modifyBdList', res.data.lots)
// this.modifyBdList.forEach((v, i) => {
// v.id = JSON.stringify(v.id)
// })
@@ -55,7 +55,7 @@ layout("/layouts/platform.html"){
style="width: 100%"
v-model="pageForm.travelAgencyId">
<el-option :key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyOptions"></el-option>
</el-select>
@@ -127,6 +127,10 @@ layout("/layouts/platform.html"){
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="线路列表">
<template #func>
<el-button v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('SchoolUnionAdmin')}"
@click="openCopySchoolUnionLine"
size="medium"
type="primary">沿用校工会线路</el-button>
<el-button @click="openAdd" size="medium" type="primary">新建线路</el-button>
</template>
</table-tool>
@@ -224,7 +228,7 @@ layout("/layouts/platform.html"){
<el-select clearable filterable style="width: 100%" v-model="formData.travelAgencyId"
placeholder="请选择旅行社" @change="travelChange">
<el-option :key="item.id"
:label="item.travelAgencyName+'('+ item.year +'年)'"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyList"
></el-option>
@@ -502,6 +506,38 @@ layout("/layouts/platform.html"){
</span>
</el-dialog>
<el-dialog
title="沿用校工会线路"
:visible.sync="copyLineVisible"
:close-on-click-modal="false"
width="420px"
>
<el-form :model="copyLineForm" :rules="copyLineRules" ref="copyLineForm" label-width="110px">
<el-form-item label="来源年度" prop="sourceYear">
<el-date-picker
v-model="copyLineForm.sourceYear"
type="year"
placeholder="请选择来源年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="目标年度" prop="targetYear">
<el-date-picker
v-model="copyLineForm.targetYear"
type="year"
placeholder="请选择目标年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeCopyLineDialog" :disabled="copyLineLoading">取消</el-button>
<el-button type="primary" @click="doCopySchoolUnionLine" :loading="copyLineLoading">确定</el-button>
</span>
</el-dialog>
</guava>
</div>
@@ -658,6 +694,16 @@ layout("/layouts/platform.html"){
importVisible: false,
importLoading: false,
importData: {},
copyLineVisible: false,
copyLineLoading: false,
copyLineForm: {
sourceYear: moment().add(-1, 'year').format('YYYY'),
targetYear: moment().format('YYYY')
},
copyLineRules: {
sourceYear: [{required: true, message: '请选择来源年度', trigger: ['change', 'blur']}],
targetYear: [{required: true, message: '请选择目标年度', trigger: ['change', 'blur']}]
},
modifyConfig: {}
}
@@ -666,6 +712,11 @@ layout("/layouts/platform.html"){
travelChange(val) {
const travel = this.travelAgencyList.find(o => o.id === val)
this.$set(this.formData,'travelAgencyPlace','')
if (!travel) {
this.$set(this.formData, 'lineContact', null)
this.$set(this.formData, 'lineContactPhone', null)
return
}
this.$set(this.formData, 'lineContact', travel.contact)
this.$set(this.formData, 'lineContactPhone', travel.contactMobileNumber)
},
@@ -706,6 +757,45 @@ layout("/layouts/platform.html"){
return resp.data
}
},
openCopySchoolUnionLine() {
this.$set(this.copyLineForm, 'sourceYear', moment().add(-1, 'year').format('YYYY'))
this.$set(this.copyLineForm, 'targetYear', moment().format('YYYY'))
this.$set(this, 'copyLineVisible', true)
this.$nextTick(() => {
if (this.$refs.copyLineForm) {
this.$refs.copyLineForm.clearValidate()
}
})
},
closeCopyLineDialog() {
if (this.copyLineLoading) return
this.$set(this, 'copyLineVisible', false)
},
async doCopySchoolUnionLine() {
const valid = await this.$refs.copyLineForm.validate()
if (!valid) return
if (this.copyLineForm.sourceYear === this.copyLineForm.targetYear) {
this.notifyWarning('来源年度和目标年度不能相同')
return
}
const confirm = await this.$confirm('确定复制来源年度的校工会组织线路到目标年度吗?复制后将生成新的线路编号。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm !== 'confirm') return
this.$set(this, 'copyLineLoading', true)
const resp = await $.post(loc() + '/copySchoolUnionLines', this.copyLineForm)
this.$set(this, 'copyLineLoading', false)
if (resp.code === 0) {
const result = resp.data || {}
this.notifySuccess('复制完成,来源线路' + (result.sourceCount || 0) + '条,新增' + (result.copyCount || 0) + '条,跳过' + (result.skipCount || 0) + '条')
this.$set(this, 'copyLineVisible', false)
this.pageData()
} else {
this.notifyWarning(resp.msg)
}
},
async openAdd() {
if(!this.validLineTime()) {
this.$alert('抱歉,当前时间不能操作线路', '温馨提示', {
@@ -797,12 +887,15 @@ layout("/layouts/platform.html"){
this.$refs.viewLineInfo.openView(id)
},
async selectTravelAgencyList() {
const resp = await $.post('/platform/theRapyRecuperation/travelAgency/selectTravelAgency', {year: this.formData.year})
this.travelAgencyList = resp.data
const resp = await $.post('/platform/theRapyRecuperation/travelAgency/selectTravelAgency')
this.$set(this, 'travelAgencyList', resp.data || [])
},
yearChange() {
this.formData.travelAgencyId = null
this.selectTravelAgencyList()
async yearChange() {
this.$set(this.formData, 'lotId', null)
this.$set(this.formData, 'estimatedCost', null)
await this.getConfig(this.formData.year)
await this.getLotList(this.formData.year)
await this.getModifyConfig(this.formData.year)
},
signUpModeName(val) {
const d = this.signUpModeList.find(v => v.value === val)
@@ -833,10 +926,11 @@ layout("/layouts/platform.html"){
this.notifyWarning(resp.msg)
}
},
async getConfig() {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getConfig(year) {
const params = year ? {year: year} : {}
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne', params)
if (resp.code === 0) {
this.config = resp.data
this.$set(this, 'config', resp.data || {})
} else {
this.notifyWarning(resp.msg)
}
@@ -845,9 +939,10 @@ layout("/layouts/platform.html"){
const {data} = await $.get(loc() + '/getTravelAgencyOptions')
this.travelAgencyOptions = data
},
async getLotList() {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.lotList = data.lots
async getLotList(year) {
const params = year ? {year: year} : {}
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', params)
this.$set(this, 'lotList', (data || {}).lots || [])
},
openImport() {
this.importData = {
@@ -890,10 +985,11 @@ layout("/layouts/platform.html"){
}
}
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const params = year ? {year: year} : {}
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', params)
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data || {})
}
},
async getNumber() {
@@ -47,7 +47,7 @@ layout("/layouts/platform.html"){
style="width: 100%"
v-model="pageForm.travelAgencyId">
<el-option :key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyOptions"></el-option>
</el-select>
@@ -235,24 +235,28 @@ layout("/layouts/platform.html"){
}
}
},
async getLotList() {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.lotList = data.lots
async getLotList(year) {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear || new Date().getFullYear().toString()
})
this.$set(this, 'lotList', data.lots)
},
async getTravelAgencyOptions() {
const {data} = await $.get('/platform/theRapyRecuperation/line/getTravelAgencyOptions')
this.travelAgencyOptions = data
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear || new Date().getFullYear().toString()
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async initPageData() {
await this.getLotList()
await this.getLotList(this.pageForm.startYear)
await this.getTravelAgencyOptions()
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.startYear)
},
},
async created() {
@@ -333,7 +333,7 @@ layout("/layouts/platform.html"){
},
pageForm: {
keywords: null,
year: new Date().getFullYear() + ""
year: null
},
//旅行社导入
importVisible: false,
@@ -126,7 +126,7 @@ const editForm = {
this.year = year
this.visible = true
this.getUnionSelectLine()
await this.getModifyConfig()
await this.getModifyConfig(this.year)
const {code, msg, data} = await $.get("/platform/theRapyRecuperation/branchUnionUserQuery/findOne", {id})
if (code === 0) {
this.formData = data
@@ -141,10 +141,12 @@ const editForm = {
}
},
async getModifyConfig() {
const {code, data, msg} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const {code, data, msg} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.year
})
if (code === 0) {
this.config = data
this.$set(this, 'config', data)
} else {
this.$message.error(msg)
}
@@ -85,6 +85,7 @@ layout("/layouts/platform.html"){
type="year"
placeholder="选择年度"
value-format="yyyy"
@change="getConfig(pageForm.year);getLines()"
style="width: 100%">
</el-date-picker>
</el-form-item>
@@ -411,10 +412,12 @@ layout("/layouts/platform.html"){
this.$refs.setUpRef.onOpen(selection)
},
getConfig() {
$.post('/platform/theRapyRecuperation/TheRapyConfig/findOne').then((res) => {
getConfig(year) {
$.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
}).then((res) => {
if (res.code === 0) {
this.config = res.data
this.$set(this, 'config', res.data)
}
})
},
@@ -444,7 +447,7 @@ layout("/layouts/platform.html"){
async created() {
this.getLines()
this.doSearch()
this.getConfig()
this.getConfig(this.pageForm.year)
}
})
</script>
@@ -51,21 +51,42 @@ const setUpPart = {
visible: false,
config: {},
tableData: [],
year: null,
lotId: null,
takePartInTime: null
}
},
methods: {
onOpen(selection) {
this.visible = true
this.tableData = JSON.parse(JSON.stringify(selection))
this.getModifyConfig()
this.$set(this, 'visible', true)
this.$set(this, 'year', this.getSelectionYear(selection))
this.$set(this, 'tableData', JSON.parse(JSON.stringify(selection)))
this.getModifyConfig(this.year)
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
getSelectionYear(selection) {
if (!selection || selection.length === 0) {
return null
}
const row = selection[0]
if (row.year) {
return row.year
}
if (row.signingUptime) {
return row.signingUptime.toString().substring(0, 4)
}
if (row.takePartInTime) {
return row.takePartInTime.toString().substring(0, 4)
}
return null
},
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.year
})
if (res.code === 0) {
this.config = res.data
this.$set(this, 'config', res.data)
}
},
@@ -368,10 +368,12 @@ layout("/layouts/platform.html"){
await this.getLinePlayTimeByLineId(val);
await this.doSearch()
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async playChange() {
@@ -380,7 +382,7 @@ layout("/layouts/platform.html"){
},
async created() {
this.unions = await getUnions()
await this.getModifyConfig();
await this.getModifyConfig(this.pageForm.startYear);
await this.getUnionSelectLine();
this.pageData()
}
@@ -390,4 +392,4 @@ layout("/layouts/platform.html"){
<!--#
}
#-->
#-->
@@ -355,10 +355,12 @@ layout("/layouts/platform.html"){
await this.getLinePlayTimeByLineId(val);
await this.doSearch()
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async playChange() {
@@ -366,7 +368,7 @@ layout("/layouts/platform.html"){
},
},
async created() {
await this.getModifyConfig();
await this.getModifyConfig(this.pageForm.startYear);
await this.getUnionSelectLine();
this.pageData()
}
@@ -376,4 +378,4 @@ layout("/layouts/platform.html"){
<!--#
}
#-->
#-->
@@ -355,10 +355,12 @@ layout("/layouts/platform.html"){
await this.getLinePlayTimeByLineId(val);
await this.doSearch()
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async playChange() {
@@ -366,7 +368,7 @@ layout("/layouts/platform.html"){
},
},
async created() {
await this.getModifyConfig();
await this.getModifyConfig(this.pageForm.startYear);
await this.getUnionSelectLine();
this.pageData()
}
@@ -376,4 +378,4 @@ layout("/layouts/platform.html"){
<!--#
}
#-->
#-->
@@ -44,7 +44,7 @@ layout("/layouts/platform.html"){
type="year"
value-format="yyyy"
placeholder="选择年"
style="width: 38%" @change="getUnionSelectLine(); doSearch()">
style="width: 38%" @change="getModifyConfig(pageForm.startYear);getUnionSelectLine(); doSearch()">
</el-date-picker>
<span></span>
<el-date-picker
@@ -90,16 +90,11 @@ layout("/layouts/platform.html"){
<el-col class="query-row-content">
<el-row>
<el-col :span="8">
<span>线&emsp;&emsp;路:</span>
<el-select v-model="pageForm.takePartInLineId" filterable clearable
placeholder="请选择线路"
style="width: 80%" @change="doSearch">
<el-option v-for="item in lineList"
:key="item.id"
:label="item.lineName + '-' + item.regionalNature + '【' + item.lotName + '】' + '' + item.signUpMode + ''"
:value="item.lineId">
</el-option>
</el-select>
<span>线路名称</span>
<el-input placeholder="请输入线路名称" v-model="pageForm.searchKeyword"
style="width: 80%" clearable>
<el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
</el-input>
</el-col>
<el-col :span="8">
<span>&emsp;&emsp;段:</span>
@@ -113,12 +108,18 @@ layout("/layouts/platform.html"){
</el-option>
</el-select>
</el-col>
<el-col :span="8">
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
<el-input placeholder="请输入发起人姓名/工号" v-model="pageForm.searchKeyword"
style="width: 80%" clearable>
<el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
</el-input>
<span>线&emsp;&emsp;</span>
<el-select v-model="pageForm.takePartInLineId" filterable clearable
placeholder="请选择线路"
style="width: 80%" @change="doSearch">
<el-option v-for="item in lineList"
:key="item.id"
:label="item.lineName + '-' + item.regionalNature + '【' + item.lotName + '】' + '' + item.signUpMode + ''"
:value="item.lineId">
</el-option>
</el-select>
</el-col>
</el-row>
</el-col>
@@ -146,7 +147,7 @@ layout("/layouts/platform.html"){
<el-select clearable filterable style="width: 80%" v-model="pageForm.travelAgencyId"
placeholder="请选择旅行社" @change="doSearch();$set(pageForm,'travelAgencyPlace','')">
<el-option :key="item.id"
:label="item.travelAgencyName+'('+ item.year +'年)'"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyList"
></el-option>
@@ -304,23 +305,22 @@ layout("/layouts/platform.html"){
this.lineList = resp.data
}
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async selectTravelAgencyList() {
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgencyByYears", {
startYear: this.pageForm.startYear,
endYear: this.pageForm.endYear
})
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgency")
this.travelAgencyList = data
},
},
async created() {
this.unions = await getUnions()
await this.getModifyConfig();
await this.getModifyConfig(this.pageForm.startYear);
await this.getUnionSelectLine();
await this.selectTravelAgencyList();
this.pageData();
@@ -45,7 +45,7 @@ layout("/layouts/platform.html"){
type="year"
value-format="yyyy"
placeholder="选择年"
style="width: 80%" @change="pageData();getApplyNumAudit()">
style="width: 80%" @change="getModifyConfig(pageForm.year);pageData();getApplyNumAudit()">
</el-date-picker>
</el-col>
<el-col :span="12" v-if="pageForm.lb==='ry'||pageForm.lb===''">
@@ -172,7 +172,7 @@ layout("/layouts/platform.html"){
style="width: 80%" @change="pageData()">
<el-option v-for="item in agencyLists"
:key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id">
</el-option>
</el-select>
@@ -1393,9 +1393,7 @@ layout("/layouts/platform.html"){
this.takePartInLines = data
},
async getAgencyList() {
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgency", {
year: this.pageForm.year
})
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgency")
this.agencyLists = data
},
async getJdList() {
@@ -1495,10 +1493,12 @@ layout("/layouts/platform.html"){
]
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
openImport() {
@@ -1543,7 +1543,7 @@ layout("/layouts/platform.html"){
},
},
async created() {
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.year)
this.signUpModeList = await getEnumOptions('TheRapyRecuperationSignUpMode')
this.unionOptions = await getUnions()
await this.getApplyNumAudit()
@@ -47,7 +47,7 @@ layout("/layouts/platform.html"){
type="year"
value-format="yyyy"
placeholder="选择年"
style="width: 38%" @change="doSearch">
style="width: 38%" @change="getModifyConfig(pageForm.startYear);doSearch()">
</el-date-picker>
<span></span>
<el-date-picker
@@ -172,7 +172,7 @@ layout("/layouts/platform.html"){
style="width: 80%" @change="doSearch()">
<el-option v-for="item in agencyLists"
:key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id">
</el-option>
</el-select>
@@ -912,10 +912,7 @@ layout("/layouts/platform.html"){
return data
},
async getAgencyList() {
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgencyByYears", {
startYear: this.pageForm.startYear,
endYear: this.pageForm.endYear
})
const {data} = await $.post("/platform/theRapyRecuperation/travelAgency/selectTravelAgency")
this.agencyLists = data
},
async flushUnits() {
@@ -948,10 +945,12 @@ layout("/layouts/platform.html"){
})
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
openImport() {
@@ -1003,7 +1002,7 @@ layout("/layouts/platform.html"){
},
},
async created() {
await this.getModifyConfig()
await this.getModifyConfig(this.pageForm.startYear)
await this.getAgencyList()
await this.getUnionSelectLine();
this.unionOptions = await getUnions(null)
@@ -285,9 +285,11 @@ layout("/layouts/platform.html"){
}
},
methods: {
async getLotList() {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.lotList = data.lots
async getLotList(year) {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
this.$set(this, 'lotList', data.lots)
},
getRowClassName({row, rowIndex}) {
if (row.companionCount === 0) {
@@ -427,19 +429,21 @@ layout("/layouts/platform.html"){
this.notifyWarning(resp.msg)
}
},
async getConfigData() {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.configData = resp.data
async getConfigData(year) {
const resp = await $.get('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
this.$set(this, 'configData', resp.data)
},
},
async created() {
await this.getConfigData()
await this.getConfigData(this.pageForm.year)
this.createModeList = await getEnumOptions('TheRapyRecuperationLineCreateMode')
this.signUpModeList = await getEnumOptions('TheRapyRecuperationSignUpMode')
this.regionalNatureList = await getEnumOptions('TheRapyRecuperationProvinceType')
this.unionOptions = await getUnions(null)
await this.findUnionSignUpModeLineList()
this.lotList = this.getLotList()
await this.getLotList(this.pageForm.year)
await this.pageData()
}
})
@@ -54,7 +54,7 @@ layout("/layouts/platform.html"){
style="width: 100%"
v-model="pageForm.travelAgencyId">
<el-option :key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id"
v-for="item in travelAgencyOptions"></el-option>
</el-select>
@@ -892,7 +892,7 @@ layout("/layouts/platform.html"){
})
},
queryJoinUser(val) {
$.post('/platform/theRapyRecuperation/linePersonalSelect/queryJoinUser', {keyWord: val}).then(res => {
$.post('/platform/theRapyRecuperation/linePersonalSelect/queryJoinUser', {keyWord: val, year: this.pageForm.year}).then(res => {
if (res.code === 0) {
this.canChooseUserList = res.data
}
@@ -936,10 +936,11 @@ layout("/layouts/platform.html"){
}
this.userDialogVisible = false
},
doSearch() {
async doSearch() {
this.tableData = []
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
await this.getLotList(this.pageForm.year)
this.pageData()
},
pageOrder(column) {
@@ -1071,9 +1072,11 @@ layout("/layouts/platform.html"){
const {data} = await $.get(loc() + '/getTravelAgencyOptions')
this.travelAgencyOptions = data
},
async getLotList() {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
this.lotList = data.lots
async getLotList(year) {
const {data} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
})
this.$set(this, 'lotList', data.lots)
},
async getLineConfig(lineId) {
const {data} = await $.post(loc() + '/getLineConfig/' + lineId)
@@ -1150,6 +1153,8 @@ layout("/layouts/platform.html"){
},
async created() {
this.$set(this.pageForm, 'mode', GetQueryString('mode'))
//页面初始化默认当前年度,避免筛选框为空但后端按当前年度查询造成选择情况显示不直观。
this.$set(this.pageForm, 'year', String(new Date().getFullYear()))
await this.initTableColumns()
this.pageData()
this.createModeList = await getEnumOptions('TheRapyRecuperationLineCreateMode')
@@ -1157,7 +1162,7 @@ layout("/layouts/platform.html"){
this.regionalNatureList.push(...await getEnumOptions('TheRapyRecuperationProvinceType'))
this.unionOptions = await getUnions(null)
this.travelAgencyOptions = this.getTravelAgencyOptions()
this.lotList = this.getLotList()
await this.getLotList(this.pageForm.year)
}
})
@@ -126,7 +126,7 @@ const editForm = {
this.year = year
this.visible = true
this.getUnionSelectLine()
await this.getModifyConfig()
await this.getModifyConfig(this.year)
const {code, msg, data} = await $.get("/platform/theRapyRecuperation/schoolUnionUserQuery/findOne", {id})
if (code === 0) {
this.formData = data
@@ -141,10 +141,12 @@ const editForm = {
}
},
async getModifyConfig() {
const {code, data, msg} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const {code, data, msg} = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.year
})
if (code === 0) {
this.config = data
this.$set(this, 'config', data)
} else {
this.$message.error(msg)
}
@@ -85,6 +85,7 @@ layout("/layouts/platform.html"){
type="year"
placeholder="选择年度"
value-format="yyyy"
@change="getConfig(pageForm.year);getLines()"
style="width: 100%">
</el-date-picker>
</el-form-item>
@@ -173,6 +174,8 @@ layout("/layouts/platform.html"){
<!-- </el-button>-->
<el-button icon="el-icon-upload" @click="openImport" size="small" type="primary">参加人员导入
</el-button>
<el-button icon="el-icon-upload2" @click="openSupplementImport" size="small" type="primary">参加人员补录
</el-button>
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
导出未报名人员
</el-button>
@@ -326,6 +329,57 @@ layout("/layouts/platform.html"){
<el-button type="primary" @click="doImport" :loading="importLoading">确定</el-button>
</span>
</el-dialog>
<el-dialog
title="参加人员补录"
:visible.sync="supplementVisible"
:close-on-click-modal="false"
width="50%">
<el-timeline>
<el-timeline-item timestamp="选择线路" placement="top">
<el-card>
<el-form label-width="90px">
<el-form-item label="线路">
<el-select v-model="supplementData.takePartInLineId" placeholder="请选择线路" filterable clearable
style="width: 100%">
<el-option
v-for="item in supplementLines"
:key="item.takePartInLineId"
:label="item.lineName + '' + item.unionName"
:value="item.takePartInLineId">
</el-option>
</el-select>
</el-form-item>
</el-form>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="上传文件" placement="top">
<el-card>
<el-form>
<el-upload
name="file"
ref="supplementUpload"
:on-remove="handleSupplementFileRemove"
:on-change="handleSupplementFileChange"
:auto-upload="false"
:limit="1"
:file-list="supplementData.fileList">
<el-button size="medium" type="" icon="el-icon-upload" style="width: 200px">选择文件
</el-button>
<div class="el-upload__tip" slot="tip" style="color: #F56C6C">
只能上传 xls/xlsx 文件,补录会给系统内不存在报名记录的人员新增报名记录
</div>
</el-upload>
</el-form>
</el-card>
</el-timeline-item>
</el-timeline>
<span slot="footer" class="dialog-footer">
<el-button @click="supplementVisibleClose" :disabled="supplementLoading">取 消</el-button>
<el-button type="primary" @click="doSupplementImport" :loading="supplementLoading">确定</el-button>
</span>
</el-dialog>
</div>
<script>
@@ -372,6 +426,13 @@ layout("/layouts/platform.html"){
importLoading: false,
importData: {
fileList: []
},
supplementVisible: false,
supplementLoading: false,
supplementLines: [],
supplementData: {
takePartInLineId: '',
fileList: []
}
}
},
@@ -470,6 +531,7 @@ layout("/layouts/platform.html"){
success: (resp) => {
if (resp.code === 0) {
this.importVisible = false
this.$message.success(resp.msg || resp.data || '导入成功')
this.doSearch()
} else {
this.$message.warning(resp.msg)
@@ -486,8 +548,74 @@ layout("/layouts/platform.html"){
this.importVisible = false
this.doSearch()
},
openSupplementImport() {
this.$set(this.supplementData, 'takePartInLineId', this.pageForm.takePartInLineId || '')
this.$set(this.supplementData, 'fileList', [])
this.getSupplementLines()
this.$set(this, 'supplementVisible', true)
},
handleSupplementFileRemove(file, fileList) {
this.$set(this.supplementData, 'fileList', this.fileHandleRemove(file, fileList))
},
handleSupplementFileChange(file, fileList) {
this.$set(this.supplementData, 'fileList', this.fileHandleChange(file, fileList, {type: ['xls', 'xlsx']}))
},
doSupplementImport() {
if (!this.supplementData.takePartInLineId) {
this.$message.warning('请选择线路')
return
}
if (this.supplementData.fileList.length === 0) {
this.$message.warning('请选择文件!')
return
}
const data = new FormData()
this.supplementData.fileList.forEach((val) => {
data.append('file', val.raw, val.raw.name)
})
data.append('takePartInLineId', this.supplementData.takePartInLineId)
this.$set(this, 'supplementLoading', true)
$.ajax({
url: '/platform/theRapyRecuperation/schoolUnionUserQuery/supplementImport',
type: 'post',
data: data,
processData: false,
contentType: false,
success: (resp) => {
if (resp.code === 0) {
this.$set(this, 'supplementVisible', false)
this.$message.success(resp.msg || resp.data || '补录成功')
this.doSearch()
} else {
this.$message.warning(resp.msg)
}
this.$set(this, 'supplementLoading', false)
},
error: () => {
this.$message.warning('补录失败')
this.$set(this, 'supplementLoading', false)
}
})
},
supplementVisibleClose() {
this.$set(this, 'supplementVisible', false)
this.doSearch()
},
getSupplementLines() {
$.post('/platform/theRapyRecuperation/schoolUnionUserQuery/supplementLineList', {
year: this.pageForm.year,
unionId: this.pageForm.unionId,
regionalNature: this.pageForm.regionalNature
}).then(res => {
if (res.code === 0) {
this.$set(this, 'supplementLines', res.data || [])
} else {
this.$message.error(res.msg)
}
})
},
noSignExport() {
window.open('/platform/theRapyRecuperation/schoolUnionUserQuery/noSignExport')
window.open('/platform/theRapyRecuperation/schoolUnionUserQuery/noSignExport?year=' + this.pageForm.year)
},
doExport() {
const {year, userName, loginName, unionId, signUpMode, regionalNature, takePartInLineId, lotId} = this.pageForm
@@ -513,10 +641,12 @@ layout("/layouts/platform.html"){
this.$refs.setUpRef.onOpen(selection)
},
getConfig() {
$.post('/platform/theRapyRecuperation/TheRapyConfig/findOne').then((res) => {
getConfig(year) {
$.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.year
}).then((res) => {
if (res.code === 0) {
this.config = res.data
this.$set(this, 'config', res.data)
}
})
},
@@ -543,6 +673,7 @@ layout("/layouts/platform.html"){
},
doSearch(){
this.getConfig(this.pageForm.year)
this.getLines()
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
@@ -551,7 +682,6 @@ layout("/layouts/platform.html"){
},
async created() {
this.doSearch()
this.getConfig()
this.unionOptions = await getUnions()
}
})
@@ -51,21 +51,42 @@ const setUpPart = {
visible: false,
config: {},
tableData: [],
year: null,
lotId: null,
takePartInTime: null
}
},
methods: {
onOpen(selection) {
this.visible = true
this.tableData = JSON.parse(JSON.stringify(selection))
this.getModifyConfig()
this.$set(this, 'visible', true)
this.$set(this, 'year', this.getSelectionYear(selection))
this.$set(this, 'tableData', JSON.parse(JSON.stringify(selection)))
this.getModifyConfig(this.year)
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
getSelectionYear(selection) {
if (!selection || selection.length === 0) {
return null
}
const row = selection[0]
if (row.year) {
return row.year
}
if (row.signingUptime) {
return row.signingUptime.toString().substring(0, 4)
}
if (row.takePartInTime) {
return row.takePartInTime.toString().substring(0, 4)
}
return null
},
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.year
})
if (res.code === 0) {
this.config = res.data
this.$set(this, 'config', res.data)
}
},
@@ -104,7 +104,7 @@ layout("/layouts/platform.html"){
<el-option
v-for="item in travelAgencyList"
:key="item.id"
:label="item.travelAgencyName"
:label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')"
:value="item.id">
</el-option>
</el-select>
@@ -44,7 +44,7 @@ layout("/layouts/platform.html"){
type="year"
value-format="yyyy"
placeholder="选择年"
style="width: 38%" @change="getUnionSelectLine(); doSearch()">
style="width: 38%" @change="getModifyConfig(pageForm.startYear);getUnionSelectLine(); doSearch()">
</el-date-picker>
<span></span>
<el-date-picker
@@ -549,10 +549,12 @@ layout("/layouts/platform.html"){
this.lineList = resp.data
}
},
async getModifyConfig() {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne')
async getModifyConfig(year) {
const res = await $.post('/platform/theRapyRecuperation/TheRapyConfig/findOne', {
year: year || this.pageForm.startYear
})
if (res.code === 0) {
this.modifyConfig = res.data
this.$set(this, 'modifyConfig', res.data)
}
},
async flushUnits() {
@@ -582,7 +584,7 @@ layout("/layouts/platform.html"){
},
async created() {
this.unions = await getUnions()
await this.getModifyConfig();
await this.getModifyConfig(this.pageForm.startYear);
await this.getUnionSelectLine();
this.pageData();
this.flushUnits();