diff --git a/src/main/java/io/v/nutz/zhgh/staffmanage/sourcechange/service/impl/SourceChangeManageServiceImpl.java b/src/main/java/io/v/nutz/zhgh/staffmanage/sourcechange/service/impl/SourceChangeManageServiceImpl.java index 2a42cc6..fbd9326 100644 --- a/src/main/java/io/v/nutz/zhgh/staffmanage/sourcechange/service/impl/SourceChangeManageServiceImpl.java +++ b/src/main/java/io/v/nutz/zhgh/staffmanage/sourcechange/service/impl/SourceChangeManageServiceImpl.java @@ -81,6 +81,9 @@ public class SourceChangeManageServiceImpl extends BaseServiceImpl travelEntities = new ArrayList<>(commonEntities); travelEntities.add(new ExcelExportEntity("酒店名称", "baseName", 20)); + travelEntities.add(new ExcelExportEntity("预出行时间", "specificTime", 20)); commonEntities.add(new ExcelExportEntity("备注", "remark", 30)); diff --git a/src/main/java/io/v/nutz/zhgh/therapyRecuperation/controller/statistics/TheRapyRecuperationLineStatisticsController.java b/src/main/java/io/v/nutz/zhgh/therapyRecuperation/controller/statistics/TheRapyRecuperationLineStatisticsController.java new file mode 100644 index 0000000..a89488b --- /dev/null +++ b/src/main/java/io/v/nutz/zhgh/therapyRecuperation/controller/statistics/TheRapyRecuperationLineStatisticsController.java @@ -0,0 +1,254 @@ +package io.v.nutz.zhgh.therapyRecuperation.controller.statistics; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import cn.wizzer.framework.base.Result; +import io.v.nutz.base.annontation.ViReturn; +import io.v.nutz.base.query.PageForm; +import io.v.nutz.base.utils.MsgApi; +import io.v.nutz.base.utils.Vi; +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.TheRapyRecuperationEnrollService; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.annotation.RequiresAuthentication; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; +import org.nutz.lang.Strings; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @version 1.0 + * @Author zzr + * @name:TheRapyRecuperationStatisticsController + * @Date 2024/6/3 17:32 + * @注释 查看报名情况 + */ +@IocBean +@At("/platform/theRapyRecuperation/statistics") +@Ok("json:full") +@Slf4j +public class TheRapyRecuperationLineStatisticsController { + + @Inject + private TheRapyRecuperationEnrollService enrollService; + + @Inject + private MsgApi msgApi; + + @Inject + private Dao dao; + + @At("") + @Ok("beetl:/platform/theRapyRecuperation/statistics/lineStatistics.html") + @RequiresPermissions("theRapyRecuperation.statistics") + public void index() { + } + + @At + @ViReturn + @RequiresPermissions("theRapyRecuperation.statistics") + public Object pageData(PageForm pageForm, + @Param(value = "startYear", required = false) Integer startYear, + @Param(value = "endYear", required = false) Integer endYear, + @Param(value = "unionId", required = false) String unionId, + @Param("takePartInLineId") String takePartInLineId, + @Param(value = "lotId", required = false) String lotId, + @Param(value = "signUpMode", required = false) String signUpMode, + @Param(value = "selectId",required = false) String selectId, + @Param(value = "regionalNature", required = false) String regionalNature) { + Sql sql = Sqls.create(""" + SELECT + line.id, + line.lineName, + line.regionalNature, + lineu.lineId, + lineu.id as lineUId, + lineu.signUpMode, + lineu.minimumGroupSize, + lineu.estimatedFamilyNumbers, + YEAR(lineu.selectTime) as `year`, + CONCAT(DATE_FORMAT(lineu.playStartTime,'%m月%d日'),'-',DATE_FORMAT(lineu.playEndTime,'%m月%d日')) AS linePlayTime, + lineu.playStartTime as playStartTime1, + lineu.playEndTime as playEndTime2, + lxs.travelAgencyName, + lxs.contact, + lxs.contactMobileNumber, + enroll.takePartInUnionId AS usUnionId, + if(lineu.signUpMode = 2, '校工会', un.unionname) as unionname, + lot.lotName, + lot.lotValue, + enroll.familyNumber, + ( SELECT COUNT( 1 ) FROM the_rapy_recuperation_enroll WHERE takePartInLineId = lineu.id and stateId=2750 and isNormal = true $unionCnd) lineNum, + (select count(1) from the_rapy_recuperation_enroll_companion where trreId in (select id from the_rapy_recuperation_enroll where stateId=2750 and takePartInLineId = lineu.id and isNormal = true $unionCnd)) as signUpUserFamilyNum + FROM + `the_rapy_recuperation_enroll` enroll + LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id=enroll.takePartInLineId + LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId + LEFT JOIN the_rapy_recuperation_lot lot ON lot.id = line.lotId + LEFT JOIN the_rapy_recuperation_travel_agency lxs ON line.travelAgencyId = lxs.id + LEFT JOIN sys_union un ON un.id = lineu.unionId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("YEAR(lineu.selectTime)", ">=", startYear); + cnd.andEX("YEAR(lineu.selectTime)", "<=", endYear); + cnd.andEX("lineu.signUpMode","=",signUpMode); + if (!ShiroUtil.hasAnyRoles("sysadmin,H06")){ + String unionCndSql = "and (selfUnionId='%s' or takePartInUnionId = '%s')".formatted(Vi.getUnionId(), Vi.getUnionId()); + sql.setVar("unionCnd", unionCndSql); + cnd.and("lineu.unionId", "=", Vi.getUnionId()); + } else { + if (Strings.isNotBlank(unionId)) { + cnd.and("lineu.unionId", "=", unionId); + } + } + + cnd.andEX("line.lotId", "=", lotId); + cnd.andEX("line.id", "=", takePartInLineId); + cnd.andEX("lineu.id", "=", selectId); + cnd.andEX("line.regionalNature", "=", regionalNature); + cnd.groupBy("enroll.takePartInLineId"); + cnd.asc("line.serialNumber").asc("lineu.playStartTime"); + sql.setCondition(cnd); + return enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + + /** + * 根据线路查询报名详情 + * @param searchKeyword + * @param unionId + * @param unitId + * @return + */ + @At + @ViReturn + @RequiresPermissions("theRapyRecuperation.statistics") + public Object getUserDateByLine(PageForm pageForm, + @Param(value = "takePartLineId",required = false) String takePartLineId, + @Param(value = "searchKeyword", required = false) String searchKeyword, + @Param(value = "unionId", required = false) String unionId, + @Param(value = "unitId", required = false) String unitId) { + Sql sql = Sqls.create(""" + SELECT + enroll.*, + line.lineName, + line.id as lineId, + line.regionalNature, + '教职工' userNature, + state.stateColor, + state.stateName, + CONCAT(DATE_FORMAT(rs.playStartTime,'%m月%d日'),'-',DATE_FORMAT(rs.playEndTime,'%m月%d日')) AS linePlayTime, + IF + ( enroll.takePartInUnionId != enroll.selfUnionId, TRUE, FALSE ) isTransferIn, + ( SELECT COUNT( 1 ) FROM the_rapy_recuperation_enroll_companion WHERE trreId = enroll.id ) isFamily, + ( SELECT COUNT( 1 ) FROM the_rapy_recuperation_enroll_companion WHERE trreId = enroll.id ) num + FROM + `the_rapy_recuperation_enroll` enroll + LEFT JOIN `the_rapy_recuperation_line_union_select` rs ON rs.id = enroll.takePartInLineId + LEFT JOIN `the_rapy_recuperation_line` line on line.id=rs.lineId + LEFT JOIN audit_state state ON state.stateId = enroll.stateId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("enroll.takePartInLineId","=",takePartLineId); + cnd.and("enroll.stateId","=",2750); + cnd.andEX("enroll.selfUnionId", "=", unionId); + cnd.andEX("enroll.selfUnitId", "=", unitId); + cnd.and("enroll.takePartInLineId", "is not", null); + cnd.andEX("enroll.isNormal", "=", true); + if (StrUtil.isNotBlank(searchKeyword)){ + cnd.and(Cnd.exps("enroll.loginName","like","%"+searchKeyword+"%").or("enroll.userName","like","%"+searchKeyword+"%")); + } + cnd.desc("enroll.signingUptime"); + cnd.desc("enroll.unitName"); + sql.setCondition(cnd); + return enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @At + @ViReturn + @RequiresAuthentication + public Object sendSuccess(String id) { + + TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id); + TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId()); + if (DateUtil.compare(new Date(), unionSelect.getSignUpEndTime()) < 0) { + return Result.error("报名还未结束,不能发送"); + } + //找出报名人员 + List enrolls = dao.query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "=", id) + .and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear()) + .and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL))); + + //发短信 + enrolls.forEach(item -> { + String content = "%s老师,您好!您报名的%s线路,出行时间为%s,达到成团条件,请准时参加疗休养活动。".formatted( + item.getUserName(), + line.getLineName(), + DateUtil.format(unionSelect.getPlayStartTime(), "yyyy-MM-dd") + ); + List list = List.of(Map.of("type", "User", "userId", item.getLoginName(), "name", item.getUserName())); +// msgApi.sendMsg(content, list, "疗休养", " IntelligenceMode", MsgApi.sendMode.normal.name()); + }); + return null; + } + + @At + @ViReturn + @RequiresAuthentication + @Aop(TransAop.READ_COMMITTED) + public Object sendFail(String id, Boolean type) { + + TheRapyRecuperationLineUnionSelect unionSelect = dao.fetch(TheRapyRecuperationLineUnionSelect.class, id); + TheRapyRecuperationLine line = dao.fetch(TheRapyRecuperationLine.class, unionSelect.getLineId()); + if (DateUtil.compare(new Date(), unionSelect.getSignUpEndTime()) < 0) { + return Result.error("报名还未结束,不能发送"); + } + //找出报名人员 + List enrolls = dao.query(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "=", id) + .and("isNormal", "=", true).and("year(signingUptime)", "=", DateUtil.thisYear()) + .and("stateId", "not in", Lang.array(TheRapyRecuperationState.UNITFAIL, TheRapyRecuperationState.LINEUNITFAIL, TheRapyRecuperationState.SCHOOLFAIL))); + + //发短信 + enrolls.forEach(item -> { + String content = "%s老师,您好!您报名的%s线路,出行时间为%s,因报名人数不足未达到成团条件,请尽快进入疗休养管理系统重新选择线路。".formatted( + item.getUserName(), + line.getLineName(), + DateUtil.format(unionSelect.getPlayStartTime(), "yyyy-MM-dd") + ); + List list = List.of(Map.of("type", "User", "userId", item.getLoginName(), "name", item.getUserName())); +// msgApi.sendMsg(content, list, "疗休养", " IntelligenceMode", MsgApi.sendMode.normal.name()); + }); + + if(!type) { + List enrollIds = enrolls.stream().map(TheRapyRecuperationEnroll::getId).collect(Collectors.toList()); + List bedIds = enrolls.stream().map(TheRapyRecuperationEnroll::getBedInfo).collect(Collectors.toList()); + dao.clear(TheRapyRecuperationEnroll.class, Cnd.where("takePartInLineId", "=", id)); + dao.clear(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", enrollIds)); + dao.clear(TheRapyRecuperationEnrollBed.class, Cnd.where("id", "in", bedIds)); + } else { + List idList = enrolls.stream().map(TheRapyRecuperationEnroll::getId).collect(Collectors.toList()); + dao.update(TheRapyRecuperationEnroll.class, Chain.make("isNormal", false), Cnd.where("id", "in", idList)); + } + return null; + } +} diff --git a/src/main/java/io/v/nutz/zhgh/therapyRecuperation/service/impl/TheRapyRecuperationEnrollServiceImpl.java b/src/main/java/io/v/nutz/zhgh/therapyRecuperation/service/impl/TheRapyRecuperationEnrollServiceImpl.java index a5f9c41..e46fb65 100644 --- a/src/main/java/io/v/nutz/zhgh/therapyRecuperation/service/impl/TheRapyRecuperationEnrollServiceImpl.java +++ b/src/main/java/io/v/nutz/zhgh/therapyRecuperation/service/impl/TheRapyRecuperationEnrollServiceImpl.java @@ -1063,36 +1063,34 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl list = numSql.getList(String.class); + // 这就是所有的报名线路 int enrollNum = list.size(); if (Lang.isNotEmpty(list)) { int i = dao().count(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "in", list)); enrollNum = enrollNum + i; } + // 去判断当前报名的记录,名额有没有超出限制,包含家属 List companionList = enrollInfo.getCompanionList(); - int applyNum = StrUtil.isNotBlank(enrollInfo.getId()) ? 0 : 1; - - if (StrUtil.isNotBlank(enrollInfo.getEditOther())) { - applyNum = applyNum + 1; - } - - // 电脑有的特殊情况,在我的里面修改报名信息,可以直接修改多个时间段的信息,那就要判断数据库报名的Id和,修改的线路的Id是不是一致的 + // 报名人数,默认为1,也就是当前的报名记录 + int applyNum = 1; + // 先查询这个人,有没有报名记录;有报名记录,并且报名的线路和当前选择的线路是一样的话,扣减掉数据库存储的报名记录和携带家属人数 TheRapyRecuperationEnroll enroll = dao().fetch(TheRapyRecuperationEnroll.class, Cnd.where("id", "=", enrollInfo.getId())); - if (Lang.isNotEmpty(enroll) && !Objects.equals(enroll.getTakePartInLineId(), enrollInfo.getTakePartInLineId())) { - applyNum = applyNum + 1; + if (Lang.isNotEmpty(enroll) && Objects.equals(enroll.getTakePartInLineId(), enrollInfo.getTakePartInLineId())) { + // 这就是家属人数,那就要用enrollNum减掉家属人数和本人 + int counted = dao().count(TheRapyRecuperationEnrollCompanion.class, Cnd.where("trreId", "=", enroll.getId())); + enrollNum = enrollNum - counted - 1; } + applyNum = applyNum + (Lang.isEmpty(companionList) ? 0 : companionList.size()); - if (Lang.isNotEmpty(companionList)) { - applyNum = applyNum + companionList.size(); - } if ((applyNum + enrollNum) > maxApplyNum) { - int canApplyNum = maxApplyNum - enrollNum; - if (canApplyNum == 0) { + int canApplyNum = maxApplyNum - (applyNum + enrollNum); + if ((canApplyNum - 1) == 0) { return Map.of(false, "此线路报名人数已满,请选择其他线路报名"); } else { - return Map.of(false, "此线路剩余可报名人数为:【" + canApplyNum + "人】,本人及家属超过名额限制,请减少随行人或选择其他线路报名"); + return Map.of(false, "本人及家属超过名额限制,请减少随行人或选择其他线路报名"); } } diff --git a/src/main/java/io/v/nutz/zhgh/welfare/controller/statistics/WelfareSingleController.java b/src/main/java/io/v/nutz/zhgh/welfare/controller/statistics/WelfareSingleController.java index a0371cf..b27c881 100644 --- a/src/main/java/io/v/nutz/zhgh/welfare/controller/statistics/WelfareSingleController.java +++ b/src/main/java/io/v/nutz/zhgh/welfare/controller/statistics/WelfareSingleController.java @@ -29,6 +29,7 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.boot.starter.ftp.FtpService; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; @@ -48,10 +49,7 @@ import org.nutz.mvc.annotation.Param; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; -import java.io.BufferedOutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; @@ -68,16 +66,16 @@ import java.util.zip.ZipOutputStream; @Slf4j public class WelfareSingleController { - @Inject - private WelfareSingleService welfareSingleService; - - @Inject - private MsgApi msgApi; - @Inject private Dao dao; @Inject + private MsgApi msgApi; + @Inject + private FtpService ftpService; + @Inject private OfficeTemplateUtil officeTemplateUtil; + @Inject + private WelfareSingleService welfareSingleService; @At("") @Ok("beetl:/platform/welfare/statistics/single.html") @@ -803,7 +801,8 @@ public class WelfareSingleController { IF(LOCATE('undefined',wpus.receiveAddress)>0,NULL,wpus.receiveAddress) as receiveAddress, wpus.selectNum, wpso.optionName, - wpus.selectSpecs + wpus.selectSpecs, + wpus.userSign FROM welfare_project_user_selection wpus left join user u on u.id = wpus.selectUserId @@ -843,6 +842,21 @@ public class WelfareSingleController { v.put("address", addressMap.get("收货地址")); v.put("phone", addressMap.get("联系方式")); } + + if (StrUtil.isNotBlank(v.getString("userSign"))) { + try { + ByteArrayOutputStream signOs = new ByteArrayOutputStream(); + ftpService.download(v.getString("userSign"), signOs); + byte[] imageBytes = signOs.toByteArray(); + if (Lang.isNotEmpty(imageBytes)) { + v.setv("qzBytes", imageBytes); + } else { + v.setv("qzBytes", null); + } + } catch (Exception e) { + e.printStackTrace(); + } + } }); Map> optionGroupData = list.stream().collect(Collectors.groupingBy(v -> v.getString("optionName"))); @@ -864,6 +878,15 @@ public class WelfareSingleController { exportEntities.add(new ExcelExportEntity("收货人", "recipient", 15)); exportEntities.add(new ExcelExportEntity("联系方式", "phone", 20)); exportEntities.add(new ExcelExportEntity("收货地址", "address", 60)); + ExcelExportEntity excelExportEntity = new ExcelExportEntity(); + excelExportEntity.setName("签字"); + excelExportEntity.setKey("qzBytes"); + excelExportEntity.setHeight(12); + excelExportEntity.setWidth(20); + excelExportEntity.setType(2); + excelExportEntity.setExportImageType(2); + exportEntities.add(excelExportEntity); + Workbook workbook = new XSSFWorkbook(); optionGroupData.forEach((k, v) -> { @@ -876,7 +899,7 @@ public class WelfareSingleController { }); try (ServletOutputStream outputStream = response.getOutputStream()) { - ViTool.excelResponse(response, projectName + ".xlsx"); + ViTool.excelResponse(response, projectName + ".xls"); workbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/resources/static/components/plugins/OpenQRCode.vue b/src/main/resources/static/components/plugins/OpenQRCode.vue index 6838257..5e6f27a 100644 --- a/src/main/resources/static/components/plugins/OpenQRCode.vue +++ b/src/main/resources/static/components/plugins/OpenQRCode.vue @@ -1,68 +1,71 @@ diff --git a/src/main/resources/views/mobile/home.html b/src/main/resources/views/mobile/home.html index cf44926..79a5402 100644 --- a/src/main/resources/views/mobile/home.html +++ b/src/main/resources/views/mobile/home.html @@ -216,7 +216,7 @@ layout("/mobile/platform.html"){
- +
@@ -257,7 +257,7 @@ layout("/mobile/platform.html"){ {{clickMenu.moduleName}}