From 15991eeb9c272fb2c0def33807366fda2382dff9 Mon Sep 17 00:00:00 2001 From: zhouhefeng Date: Thu, 3 Sep 2026 08:42:56 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E6=A4=8Dv3=E7=96=97=E4=BC=91=E5=85=BB?= =?UTF-8?q?=E5=88=B0=E8=BF=99=E4=B8=AA=E7=89=88=E6=9C=AC=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecuperationAuditController.java | 24 +- ...erationBranchUnionUserQueryController.java | 125 ++++- ...uperationEvaluateStatisticsController.java | 40 ++ ...uperationFlexibleGroupQueryController.java | 117 ++++ .../RecuperationJoinUserImportController.java | 5 +- .../RecuperationLineAdjustmentController.java | 20 +- .../RecuperationLineClusterController.java | 3 + .../RecuperationLineSelectController.java | 1 + .../RecuperationLineStatisticsController.java | 72 +++ ...rationProvinceFlexibleGroupController.java | 6 + ...erationSchoolUnionUserQueryController.java | 192 ++++++- .../param/RecuperationUserQueryPageForm.java | 34 ++ .../service/RecuperationAuditService.java | 6 +- .../service/RecuperationEnrollService.java | 60 ++ .../RecuperationLineAdjustmentService.java | 7 +- .../RecuperationLineStatisticsService.java | 17 + ...uperationProvinceFlexibleGroupService.java | 24 + .../impl/RecuperationAuditServiceImpl.java | 23 +- .../impl/RecuperationEnrollServiceImpl.java | 522 ++++++++++++++++++ ...RecuperationLineAdjustmentServiceImpl.java | 39 +- .../RecuperationLineClusterServiceImpl.java | 32 +- ...RecuperationLineStatisticsServiceImpl.java | 97 ++++ ...ationProvinceFlexibleGroupServiceImpl.java | 153 +++++ .../recuperation/annualAnalysis/index.html | 51 +- .../recuperation/audit/index.html | 72 ++- .../branchUnionUserQuery/editForm.js | 51 +- .../branchUnionUserQuery/index.html | 6 +- .../branchUnionUserQuery/setUpPart.js | 13 +- .../recuperation/common/enrollInfo.js | 33 +- .../recuperation/config/index.html | 245 +++++--- .../flexibleGroupQuery/index.html | 43 ++ .../recuperation/joinUserImport/index.html | 20 +- .../recuperation/lineAdjustment/index.html | 52 +- .../recuperation/lineCluster/index.html | 30 +- .../recuperation/lineSelect/batchSelect.js | 35 +- .../recuperation/lineSelect/index.html | 38 +- .../recuperation/lineSelect/select.js | 58 +- .../recuperation/lineSelect/timeInfo.js | 13 +- .../recuperation/lineStatistics/index.html | 26 + .../schoolUnionUserQuery/editForm.js | 72 +-- .../schoolUnionUserQuery/index.html | 310 +++++++++-- .../schoolUnionUserQuery/setUpPart.js | 30 +- .../recuperation/statistics/index.html | 198 +------ 43 files changed, 2436 insertions(+), 579 deletions(-) create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationFlexibleGroupQueryController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineStatisticsController.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/param/RecuperationUserQueryPageForm.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineStatisticsService.java create mode 100644 src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineStatisticsServiceImpl.java create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/recuperation/flexibleGroupQuery/index.html create mode 100644 src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineStatistics/index.html diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationAuditController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationAuditController.java index 6fb5634..7115268 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationAuditController.java @@ -8,10 +8,15 @@ import com.budwk.app.base.result.Result; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationAuditService; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.ioc.aop.Aop; +import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; /** * 旧版通用 audit 审核入口,不接入 wf。stage 支持 branch、lineUnion、school、travel, @@ -48,8 +53,9 @@ public class RecuperationAuditController { /** pageForm 为分页信息;stage 为审核环节;year 为年度;audited 表示已审/待审;keyword 为姓名或工号。 */ @At @SaCheckPermission("recuperation.audit") - public Result pageData(PageForm pageForm, String stage, Integer year, Boolean audited, String keyword) { - return Result.success(auditService.auditPage(pageForm, stage, year, audited, keyword)); + public Result pageData(PageForm pageForm, String stage, Integer year, Boolean audited, String keyword, + String unionId, String lineId, String agencyId) { + return Result.success(auditService.auditPage(pageForm, stage, year, audited, keyword, unionId, lineId, agencyId)); } @At @@ -60,6 +66,7 @@ public class RecuperationAuditController { /** id 为报名记录,pass 为是否通过,auditOpinion 为意见;返回 success=true 表示 audit 和报名状态已在同一事务更新。 */ @At + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.audit") public Result audit(String id, Boolean pass, String auditOpinion) { if (StrUtil.isBlank(id) || pass == null) return Result.error("审核参数不完整"); @@ -68,10 +75,23 @@ public class RecuperationAuditController { } @At + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.audit") public Result recall(String id) { if (StrUtil.isBlank(id)) return Result.error("参数错误"); auditService.recallAudit(id); return Result.success(); } + + /** ids 为逗号分隔的报名记录 ID;pass 为审核结果;auditOpinion 为统一意见。 */ + @At + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission("recuperation.audit") + public Result oneKeyAudit(String ids, Boolean pass, String auditOpinion) { + if (StrUtil.isBlank(ids) || pass == null) return Result.error("请选择需要审核的报名记录"); + List idList = Arrays.stream(ids.split(",")).map(String::trim) + .filter(StrUtil::isNotBlank).collect(Collectors.toList()); + auditService.auditEnrolls(idList, pass, auditOpinion); + return Result.success("审核完成"); + } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationBranchUnionUserQueryController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationBranchUnionUserQueryController.java index d48c9b3..40c073f 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationBranchUnionUserQueryController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationBranchUnionUserQueryController.java @@ -7,16 +7,19 @@ import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.util.StrUtil; +import cn.hutool.core.date.DateUtil; import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.CommonDownloadUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationState; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationConfig; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollBed; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion; +import com.budwk.app.zhgh.staffbenefit.recuperation.param.RecuperationUserQueryPageForm; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -40,9 +43,12 @@ import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; /** * @ClassName RecuperationBranchUnionUserQueryController @@ -64,9 +70,12 @@ public class RecuperationBranchUnionUserQueryController { private RecuperationEnrollService enrollService; @At("") - @Ok("beetl:/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/index.html") + @Ok("beetl:/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html") @SaCheckLogin - public void index() {} + public void index(HttpServletRequest request) { + request.setAttribute("queryBase", "/platform/recuperation/branchUnionUserQuery"); + request.setAttribute("schoolMode", false); + } /** * 分工会人员信息查询 @@ -85,7 +94,7 @@ public class RecuperationBranchUnionUserQueryController { @At @ApiOperation("分页查询") @SaCheckPermission("recuperation.branchUnionUserQuery") - public Result pageData(PageForm pageForm, + public Result legacyPageData(PageForm pageForm, Integer year, String userName, String loginName, @@ -180,6 +189,54 @@ public class RecuperationBranchUnionUserQueryController { return Result.success(pagination); } + /** + * 分工会 PC 人员综合查询。 + * + * @param query 年度范围、报名状态、报名类型、线路及分页参数;工会固定取当前登录人 + * @return Result.data 为 Pagination,list 是人员列表,totalCount 是总人数 + */ + @At + @ApiOperation("分工会人员综合查询") + @SaCheckPermission("recuperation.branchUnionUserQuery") + public Result pageData(@Param("..") RecuperationUserQueryPageForm query) { + return Result.success(enrollService.managementPageData(query, true)); + } + + /** + * 查询当前分工会三种报名类型的人数。 + * + * @param query 年度、报名日期和参加状态等查询参数 + * @return xlCount、lxsCount、jdCount 分别为线路、灵活组团、定点人数 + */ + @At + @ApiOperation("查询报名类型人数") + @SaCheckPermission("recuperation.branchUnionUserQuery") + public Result getCategoryCount(@Param("..") RecuperationUserQueryPageForm query) { + return Result.success(enrollService.managementCategoryCount(query, true)); + } + + /** 按当前分工会筛选条件提醒人员,loginNames 为空时提醒全部筛选结果。 */ + @At + @ApiOperation("提醒疗休养人员") + @SaCheckPermission("recuperation.branchUnionUserQuery") + public Result remindUsers(@Param("..") RecuperationUserQueryPageForm query, String loginNames, String content) { + List selected = StrUtil.isBlank(loginNames) ? new ArrayList<>() : Arrays.stream(loginNames.split(",")) + .map(String::trim).filter(StrUtil::isNotBlank).collect(Collectors.toList()); + NutMap result = enrollService.remindManagementUsers(query, true, selected, content); + return result.getInt("sendCount", 0) > 0 ? Result.success(result.getString("msg"), result) : Result.error(result.getString("msg")); + } + + /** 保留报名记录,将作废记录恢复为正常记录。 */ + @At + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("保留报名记录") + @SaCheckPermission("recuperation.branchUnionUserQuery") + @SLog(tag = "疗休养管理-分工会查询", msg = "保留报名记录") + public Result restoreEnroll(String id) { + enrollService.restoreEnroll(id); + return Result.success(); + } + /** * 设置出行人员 * @@ -244,6 +301,46 @@ public class RecuperationBranchUnionUserQueryController { return Result.success(data); } + /** + * 修改报名线路。enroll 包含报名记录 ID 和新的线路选择记录 ID,返回统一 Result。 + */ + @At + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("修改报名信息") + @SaCheckPermission("recuperation.branchUnionUserQuery") + @SLog(tag = "疗休养管理-分工会查询", msg = "修改报名信息") + public Result doEdit(RecuperationEnroll enroll) { + enroll.setNormal(true); + dao.updateIgnoreNull(enroll); + return Result.success(); + } + + /** + * 查询当前年度允许分工会调整的线路,返回线路选择记录、日期、标段和报名方式。 + */ + @At + @ApiOperation("获取分工会可选线路") + @SaCheckPermission("recuperation.branchUnionUserQuery") + public Result getUnionSelectLine() { + Sql sql = Sqls.create(""" + SELECT rlus.id, rlus.unionId, rlus.lineId, + DATE_FORMAT(rlus.playStartTime, '%Y-%m-%d') AS playStartTime, + DATE_FORMAT(rlus.playEndTime, '%Y-%m-%d') AS playEndTime, + rl.lineName, rl.regionalNature, + IF(rlus.signUpMode=1,'分工会','校工会') AS signUpMode, lot.lotName + FROM the_rapy_recuperation_line_union_select rlus + LEFT JOIN the_rapy_recuperation_line rl ON rlus.lineId=rl.id + LEFT JOIN the_rapy_recuperation_lot lot ON rl.lotId=lot.id + $condition + """); + Cnd cnd = Cnd.where("rlus.isOpen", "=", 1) + .and("rlus.unionId", "=", SecurityUtil.getUnionId()) + .and("YEAR(rlus.selectTime)", "=", DateUtil.thisYear()); + cnd.desc("lot.lotValue").desc("rl.lineName"); + sql.setCondition(cnd); + return Result.success(enrollService.listMap(sql)); + } + /** * 获取线路 * @@ -290,6 +387,28 @@ public class RecuperationBranchUnionUserQueryController { return Result.success(list); } + /** 按分工会页面当前筛选条件导出全部人员,Excel 使用 XSSF 格式。 */ + @At + @Ok("void") + @ApiOperation("导出人员综合查询") + @SaCheckPermission("recuperation.branchUnionUserQuery") + public void exportManagement(@Param("..") RecuperationUserQueryPageForm query, HttpServletResponse response) { + List columns = new ArrayList<>(); + columns.add(new ExcelExportEntity("工号", "loginName", 18)); + columns.add(new ExcelExportEntity("姓名", "userName", 14)); + columns.add(new ExcelExportEntity("所属单位", "unitName", 24)); + columns.add(new ExcelExportEntity("所属工会", "unionName", 20)); + columns.add(new ExcelExportEntity("报名状态", "signUpStatus", 14)); + columns.add(new ExcelExportEntity("报名类型", "signUpModeName", 14)); + columns.add(new ExcelExportEntity("线路/旅行社/定点", "targetName", 30)); + columns.add(new ExcelExportEntity("是否参加", "takePartInName", 14)); + columns.add(new ExcelExportEntity("报名时间", "signingUptime", 22)); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, columns, enrollService.managementList(query, true)); + CommonDownloadUtil.download("疗休养人员查询.xlsx", workbook, response); + } + @At @Ok("void") @ApiOperation("导出") diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationEvaluateStatisticsController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationEvaluateStatisticsController.java index 4f2290e..517dd69 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationEvaluateStatisticsController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationEvaluateStatisticsController.java @@ -134,6 +134,46 @@ public class RecuperationEvaluateStatisticsController { return Result.success(enrollService.listMap(sql)); } + /** year 为统计年度;data 返回旅行社综合评分和线路、灵活组团、定点方案评分。 */ + @At + @SaCheckPermission("recuperation.statistics") + public Result getSatisfactionRatingStatistics(Integer year) { + return Result.success(enrollService.satisfactionRatingStatistics(year)); + } + + /** year 为统计年度,typeName 可传全部、线路、灵活组团或定点;data 返回评价明细。 */ + @At + @SaCheckPermission("recuperation.statistics") + public Result getSatisfactionFeedbackDetails(Integer year, String typeName) { + return Result.success(enrollService.satisfactionFeedbackDetails(year, typeName)); + } + + @At + @Ok("void") + @SaCheckPermission("recuperation.statistics") + public void exportSatisfactionFeedbackDetails(Integer year, String typeName, HttpServletResponse response) { + List rows = enrollService.satisfactionFeedbackDetails(year, typeName); + for (int i = 0; i < rows.size(); i++) rows.get(i).setv("no", i + 1); + List columns = new ArrayList<>(); + columns.add(new ExcelExportEntity("序号", "no", 10)); + columns.add(new ExcelExportEntity("报名方式", "typeName", 12)); + columns.add(new ExcelExportEntity("方案名称", "schemeName", 24)); + columns.add(new ExcelExportEntity("旅行社", "travelAgencyName", 22)); + columns.add(new ExcelExportEntity("评价人", "userName", 14)); + columns.add(new ExcelExportEntity("所属单位", "unitName", 24)); + columns.add(new ExcelExportEntity("旅行社评分", "evaluationForTravelAgency", 14)); + columns.add(new ExcelExportEntity("住宿/酒店评分", "evaluationForAccommodation", 16)); + columns.add(new ExcelExportEntity("行程评分", "evaluationForJourney", 14)); + columns.add(new ExcelExportEntity("餐饮评分", "evaluationForDining", 14)); + columns.add(new ExcelExportEntity("交通评分", "evaluationForTransportation", 14)); + columns.add(new ExcelExportEntity("综合评分", "compositeScore", 14)); + columns.add(new ExcelExportEntity("评价建议", "feedbackContent", 45)); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, columns, rows); + CommonDownloadUtil.download("满意度评价明细.xlsx", workbook, response); + } + @At @Ok("void") @ApiOperation("导出评价统计") diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationFlexibleGroupQueryController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationFlexibleGroupQueryController.java new file mode 100644 index 0000000..d4afbad --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationFlexibleGroupQueryController.java @@ -0,0 +1,117 @@ +package com.budwk.app.zhgh.staffbenefit.recuperation.controller; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationProvinceFlexibleGroupService; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +/** PC 端省内灵活组团及报名人员查询。 */ +@IocBean +@At("/platform/recuperation/flexibleGroupQuery") +@Ok("json:full") +public class RecuperationFlexibleGroupQueryController { + + @Inject + private RecuperationProvinceFlexibleGroupService flexibleGroupService; + + @At("") + @Ok("beetl:/platform/zhgh/staffbenefit/recuperation/flexibleGroupQuery/index.html") + @SaCheckPermission("recuperation.flexibleGroupQuery") + public void index() { + } + + /** 查询年度区间、组团、旅行社和人员关键字;data 返回组团分页数据。 */ + @At + @SaCheckPermission("recuperation.flexibleGroupQuery") + public Result pageData(PageForm pageForm, Integer startYear, Integer endYear, String groupName, + String travelAgencyId, String searchKeyword) { + return Result.success(flexibleGroupService.queryPage(pageForm, startYear, endYear, groupName, travelAgencyId, searchKeyword)); + } + + /** groupId 为灵活组团 ID;data 返回按团长聚合的团列表。 */ + @At + @SaCheckLogin + public Result getGroupInfo(String groupId) { + return Result.success(flexibleGroupService.queryGroupInfo(groupId)); + } + + /** 团长参数指定某个团,noGroupLeader=true 查询未分团人员;data 返回人员分页数据。 */ + @At + @SaCheckLogin + public Result getSignUser(PageForm pageForm, String groupId, String groupLeaderUserId, + String groupLeaderLoginName, Boolean noGroupLeader) { + return Result.success(flexibleGroupService.querySignUsers(pageForm, groupId, groupLeaderUserId, groupLeaderLoginName, noGroupLeader)); + } + + @At + @SaCheckLogin + public Result getAllSignUser(PageForm pageForm, String groupId) { + return Result.success(flexibleGroupService.querySignUsers(pageForm, groupId, null, null, false)); + } + + @At + @SaCheckLogin + public Result selectTravelAgencyList(Integer startYear, Integer endYear) { + return Result.success(flexibleGroupService.queryTravelAgencyOptions(startYear, endYear)); + } + + @At + @SaCheckLogin + public Result selectFlexibleGroupList(Integer startYear, Integer endYear) { + return Result.success(flexibleGroupService.queryFlexibleGroupOptions(startYear, endYear)); + } + + /** id 为报名记录 ID;删除报名时同步删除家属明细。 */ + @At + @SaCheckPermission("recuperation.flexibleGroupQuery") + @Aop(TransAop.READ_COMMITTED) + public Result deleteJoinUser(String id) { + if (StrUtil.isBlank(id)) return Result.error("报名记录不能为空"); + flexibleGroupService.deleteJoinUser(id); + return Result.success(); + } + + /** 按当前页面筛选条件导出全部报名人员。 */ + @At + @Ok("void") + @SaCheckPermission("recuperation.flexibleGroupQuery") + public void doExport(Integer startYear, Integer endYear, String groupName, String travelAgencyId, + String searchKeyword, HttpServletResponse response) { + List columns = new ArrayList<>(); + columns.add(new ExcelExportEntity("序号", "no", 10)); + columns.add(new ExcelExportEntity("工号", "loginName", 18)); + columns.add(new ExcelExportEntity("姓名", "userName", 14)); + columns.add(new ExcelExportEntity("联系电话", "mobile", 18)); + columns.add(new ExcelExportEntity("身份证号", "idCard", 24)); + columns.add(new ExcelExportEntity("单位", "unitName", 24)); + columns.add(new ExcelExportEntity("工会", "unionName", 20)); + columns.add(new ExcelExportEntity("旅行社", "travelAgencyName", 22)); + columns.add(new ExcelExportEntity("报名时间", "signingUptime", 20)); + columns.add(new ExcelExportEntity("团长", "leaderName", 20)); + columns.add(new ExcelExportEntity("是否成团", "formedTeamState", 14)); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, columns, + flexibleGroupService.queryExportUsers(startYear, endYear, groupName, travelAgencyId, searchKeyword)); + CommonDownloadUtil.download("灵活组团报名人员名单.xlsx", workbook, response); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationJoinUserImportController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationJoinUserImportController.java index 8014868..d23ae6d 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationJoinUserImportController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationJoinUserImportController.java @@ -22,6 +22,8 @@ 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 org.nutz.ioc.aop.Aop; +import org.nutz.aop.interceptor.ioc.TransAop; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; @@ -44,7 +46,7 @@ public class RecuperationJoinUserImportController { @At @SaCheckPermission("recuperation.joinUserImport") - public Result options(Integer year, String keyword) { return Result.success(importService.selectLineAndTravelAgencyList(year, keyword)); } + public Result options(Integer year, String keyword) { return Result.success(importService.selectLineOrTravelAgency(year)); } /** file 为 xls/xlsx,lineId 与 travelAgencyId 二选一;data 返回 excelRows 和匹配到的 matchList。 */ @At @@ -64,6 +66,7 @@ public class RecuperationJoinUserImportController { /** enrolls 为已确认匹配的报名记录数组;返回 success=true 表示实际参加状态和日期已更新。 */ @At @SaCheckPermission("recuperation.joinUserImport") + @Aop(TransAop.READ_COMMITTED) public Result doImport(@Param("enrolls") RecuperationEnroll[] enrolls) { importService.markParticipated(enrolls == null ? List.of() : List.of(enrolls)); return Result.success(); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineAdjustmentController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineAdjustmentController.java index 311ba6f..51d539c 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineAdjustmentController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineAdjustmentController.java @@ -11,6 +11,8 @@ import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import org.nutz.ioc.aop.Aop; +import org.nutz.aop.interceptor.ioc.TransAop; /** 旧版报名人员调整接口。 */ @IocBean @@ -47,14 +49,26 @@ public class RecuperationLineAdjustmentController { return Result.success(adjustmentService.findUnionSignUpModeUserList(lineId, unionId)); } - /** lineId 为线路选择记录,loginNames 为需调入或调出的登录名数组;返回统一 Result。 */ + /** lineId 为线路选择记录,loginNames 为人员工号数组,normal 表示恢复正常或调出;返回统一 Result。 */ @At @SaCheckPermission("recuperation.lineAdjustment") - public Result adjustmentUsers(String lineId, @Param("loginNames") String[] loginNames) { + @Aop(TransAop.READ_COMMITTED) + public Result adjustmentUsers(String lineId, @Param("loginNames") String[] loginNames, boolean normal) { if (StrUtil.isBlank(lineId) || loginNames == null || loginNames.length == 0) { return Result.error("请选择需要调整的人员"); } - adjustmentService.adjustmentUsers(lineId, loginNames); + adjustmentService.adjustmentUsers(lineId, loginNames, normal); return Result.success(); } + + /** lineId 为线路选择记录,loginNames 为接收提醒的工号数组;返回消息中心发送结果。 */ + @At + @SaCheckPermission("recuperation.lineAdjustment") + public Result smsAlerts(String lineId, @Param("loginNames") String[] loginNames) { + if (StrUtil.isBlank(lineId) || loginNames == null || loginNames.length == 0) { + return Result.error("请选择需要提醒的人员"); + } + return adjustmentService.smsAlerts(lineId, loginNames) + ? Result.success("提醒发送成功") : Result.error("提醒发送失败,请检查消息中心配置"); + } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineClusterController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineClusterController.java index a256a6a..b1016b1 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineClusterController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineClusterController.java @@ -9,6 +9,8 @@ import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationCluster; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineClusterService; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.ioc.aop.Aop; +import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.json.Json; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; @@ -46,6 +48,7 @@ public class RecuperationLineClusterController { /** clusters 为组团及 members 的 JSON 数组,lineId 为线路选择记录;返回统一 Result。 */ @At + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.lineCluster") public Result setClusterMembers(@Param("clusters") String clusters, String lineId) { if (StrUtil.isBlank(lineId) || StrUtil.isBlank(clusters)) { diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineSelectController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineSelectController.java index 1e4f113..568ae52 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineSelectController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineSelectController.java @@ -162,6 +162,7 @@ public class RecuperationLineSelectController { */ @At("/selectLine") @ApiOperation("选择线路") + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission(value = {"recuperation.branchUnionSelect", "recuperation.schoolUnionSelect"}, mode = SaMode.OR) @SLog(tag = "疗休养管理-选择线路", msg = "选择线路") public Result selectLine(RecuperationLineSelect us) { diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineStatisticsController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineStatisticsController.java new file mode 100644 index 0000000..ff0e7ad --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationLineStatisticsController.java @@ -0,0 +1,72 @@ +package com.budwk.app.zhgh.staffbenefit.recuperation.controller; + +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService; +import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineStatisticsService; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** PC 端线路报名情况及成团通知。 */ +@IocBean +@At("/platform/recuperation/lineStatistics") +@Ok("json:full") +public class RecuperationLineStatisticsController { + @Inject private RecuperationLineStatisticsService statisticsService; + @Inject private RecuperationEnrollService enrollService; + + @At("") + @Ok("beetl:/platform/zhgh/staffbenefit/recuperation/lineStatistics/index.html") + @SaCheckPermission("recuperation.lineStatistics") + public void index() { } + + /** 按年度、工会、线路、标段、报名模式及出行批次查询线路报名统计。 */ + @At + @SaCheckPermission("recuperation.lineStatistics") + public Result pageData(PageForm pageForm, Integer startYear, Integer endYear, String unionId, String takePartInLineId, + String lotId, String signUpMode, String selectId, String regionalNature) { + return Result.success(statisticsService.pageData(pageForm, startYear, endYear, unionId, takePartInLineId, + lotId, signUpMode, selectId, regionalNature)); + } + + /** takePartLineId 为工会选线记录 ID;data 返回审核通过的正常报名人员分页数据。 */ + @At + @SaCheckPermission("recuperation.lineStatistics") + public Result getUserDateByLine(PageForm pageForm, String takePartLineId, String searchKeyword, String unionId, String unitId) { + return Result.success(statisticsService.userPage(pageForm, takePartLineId, searchKeyword, unionId, unitId)); + } + + @At + @SaCheckLogin + public Result getLineOptions(Integer startYear, Integer endYear, String signUpMode, String regionalNature) { + return Result.success(statisticsService.lineOptions(startYear, endYear, signUpMode, regionalNature)); + } + + @At + @SaCheckPermission("recuperation.lineStatistics") + public Result countSuccessNotice(String id) { return Result.success(enrollService.countLineGroupNoticeUsers(id, true)); } + + @At + @SaCheckPermission("recuperation.lineStatistics") + public Result countFailNotice(String id) { return Result.success(enrollService.countLineGroupNoticeUsers(id, false)); } + + /** id 为工会选线记录,content 为管理员确认后的通知正文。 */ + @At + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission("recuperation.lineStatistics") + public Result sendSuccess(String id, String content) { return Result.success(enrollService.sendLineGroupSuccessNotice(id, content)); } + + /** type=true 保留并调出报名记录,false 同步删除报名、家属及床位记录。 */ + @At + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission("recuperation.lineStatistics") + public Result sendFail(String id, Boolean type, String content) { + return Result.success(enrollService.sendLineGroupFailureNotice(id, Boolean.TRUE.equals(type), content)); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationProvinceFlexibleGroupController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationProvinceFlexibleGroupController.java index 049e34e..9dccf73 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationProvinceFlexibleGroupController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationProvinceFlexibleGroupController.java @@ -15,6 +15,8 @@ import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import org.nutz.ioc.aop.Aop; +import org.nutz.aop.interceptor.ioc.TransAop; /** * 旧版省内灵活组团入口。接口接收年度、组团名称、工会及旅行社筛选条件, @@ -55,6 +57,7 @@ public class RecuperationProvinceFlexibleGroupController { /** 保存新增或编辑数据;返回 Result,success=true 表示旧表写入成功。 */ @At + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.provinceFlexibleGroup") public Result onSubmit(RecuperationProvinceFlexibleGroup flexibleGroup) { if (flexibleGroup == null) { @@ -65,6 +68,7 @@ public class RecuperationProvinceFlexibleGroupController { } @At("/toggle/?") + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.provinceFlexibleGroup") public Result toggle(String id) { if (StrUtil.isBlank(id)) { @@ -75,6 +79,7 @@ public class RecuperationProvinceFlexibleGroupController { } @At("/delete/?") + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.provinceFlexibleGroup") public Result delete(String id) { if (StrUtil.isBlank(id)) { @@ -85,6 +90,7 @@ public class RecuperationProvinceFlexibleGroupController { } @At + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("recuperation.provinceFlexibleGroup") public Result batchAssignSignUpTimes(@Param("ids") String[] ids, RecuperationProvinceFlexibleGroup form) { flexibleGroupService.batchAssignSignUpTimes(ids, form.getSignUpStartTime(), form.getSignUpEndTime(), form.getChangeEndTime()); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationSchoolUnionUserQueryController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationSchoolUnionUserQueryController.java index 015ae56..49d4434 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationSchoolUnionUserQueryController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/controller/RecuperationSchoolUnionUserQueryController.java @@ -1,12 +1,15 @@ package com.budwk.app.zhgh.staffbenefit.recuperation.controller; import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.page.Pagination; @@ -20,6 +23,8 @@ import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationConfig; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollBed; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion; +import com.budwk.app.zhgh.staffbenefit.recuperation.mode.RecuperationEnrollExcelMode; +import com.budwk.app.zhgh.staffbenefit.recuperation.param.RecuperationUserQueryPageForm; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -42,11 +47,26 @@ import org.nutz.lang.util.NutMap; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import org.nutz.mvc.annotation.AdaptBy; +import org.nutz.mvc.upload.TempFile; +import org.nutz.mvc.upload.UploadAdaptor; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; +import java.io.ByteArrayOutputStream; +import java.io.BufferedOutputStream; +import java.net.URLEncoder; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * @ClassName RecuperationSchoolUnionUserQueryController @@ -72,7 +92,10 @@ public class RecuperationSchoolUnionUserQueryController { @At("") @Ok("beetl:/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html") @SaCheckLogin - public void index() {} + public void index(HttpServletRequest request) { + request.setAttribute("queryBase", "/platform/recuperation/schoolUnionUserQuery"); + request.setAttribute("schoolMode", true); + } /** * 校工会人员信息查询 @@ -91,7 +114,7 @@ public class RecuperationSchoolUnionUserQueryController { @At @ApiOperation("分页查询") @SaCheckPermission("recuperation.schoolUnionUserQuery") - public Result pageData(PageForm pageForm, + public Result legacyPageData(PageForm pageForm, Integer year, String userName, String loginName, @@ -188,6 +211,66 @@ public class RecuperationSchoolUnionUserQueryController { return Result.success(pagination); } + /** + * 校工会 PC 人员综合查询。 + * + * @param query 年度范围、报名状态、报名类型、工会、线路及分页参数 + * @return Result.data 为 Pagination,list 是人员列表,totalCount 是总人数 + */ + @At + @ApiOperation("校工会人员综合查询") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public Result pageData(@Param("..") RecuperationUserQueryPageForm query) { + return Result.success(enrollService.managementPageData(query, false)); + } + + /** + * 查询当前条件下三种报名类型的人数。 + * + * @param query 年度、分工会、报名日期和参加状态等查询参数 + * @return xlCount、lxsCount、jdCount 分别为线路、灵活组团、定点人数 + */ + @At + @ApiOperation("查询报名类型人数") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public Result getCategoryCount(@Param("..") RecuperationUserQueryPageForm query) { + return Result.success(enrollService.managementCategoryCount(query, false)); + } + + /** + * 按当前筛选条件提醒人员。 + * + * @param query 查询参数 + * @param loginNames 页面勾选工号,逗号分隔;为空时提醒筛选结果全部人员 + * @param content 提醒正文 + * @return sendCount 为实际接收人数,msg 为发送结果 + */ + @At + @ApiOperation("提醒疗休养人员") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public Result remindUsers(@Param("..") RecuperationUserQueryPageForm query, String loginNames, String content) { + List selected = StrUtil.isBlank(loginNames) ? new ArrayList<>() : Arrays.stream(loginNames.split(",")) + .map(String::trim).filter(StrUtil::isNotBlank).collect(Collectors.toList()); + NutMap result = enrollService.remindManagementUsers(query, false, selected, content); + return result.getInt("sendCount", 0) > 0 ? Result.success(result.getString("msg"), result) : Result.error(result.getString("msg")); + } + + /** + * 将作废报名恢复为正常报名。 + * + * @param id 报名记录 ID + * @return 操作结果 + */ + @At + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("保留报名记录") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + @SLog(tag = "疗休养管理-校工会查询", msg = "保留报名记录") + public Result restoreEnroll(String id) { + enrollService.restoreEnroll(id); + return Result.success(); + } + /** * 设置出行人员 * @@ -331,6 +414,111 @@ public class RecuperationSchoolUnionUserQueryController { return Result.success(listMap); } + /** + * 按页面当前条件导出全部人员。 + * + * @param query 查询参数,含报名、未报名、未成团状态及全部筛选项 + * @param response Excel 下载响应 + */ + @At + @Ok("void") + @ApiOperation("导出人员综合查询") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public void exportManagement(@Param("..") RecuperationUserQueryPageForm query, HttpServletResponse response) { + List columns = new ArrayList<>(); + columns.add(new ExcelExportEntity("工号", "loginName", 18)); + columns.add(new ExcelExportEntity("姓名", "userName", 14)); + columns.add(new ExcelExportEntity("所属单位", "unitName", 24)); + columns.add(new ExcelExportEntity("所属工会", "unionName", 20)); + columns.add(new ExcelExportEntity("报名状态", "signUpStatus", 14)); + columns.add(new ExcelExportEntity("报名类型", "signUpModeName", 14)); + columns.add(new ExcelExportEntity("线路/旅行社/定点", "targetName", 30)); + columns.add(new ExcelExportEntity("是否参加", "takePartInName", 14)); + columns.add(new ExcelExportEntity("报名时间", "signingUptime", 22)); + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, columns, enrollService.managementList(query, false)); + CommonDownloadUtil.download("疗休养人员查询.xlsx", workbook, response); + } + + /** 下载实际参加人员导入模板,模板字段为工号、姓名、参加时间和标段时间。 */ + @At + @Ok("void") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public void downloadImportTemplate(HttpServletResponse response) { + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, RecuperationEnrollExcelMode.class, new ArrayList<>()); + CommonDownloadUtil.download("参加人员导入模板.xlsx", workbook, response); + } + + /** file 为 xls/xlsx;按参加时间年度匹配省外线路报名并返回成功、失败及错误明细。 */ + @At + @AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"}) + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public Result enrollImport(@Param("file") TempFile file) { + if (file == null || !List.of("xls", "xlsx").contains(FileUtil.extName(file.getFile()).toLowerCase())) { + return Result.error("请上传xls、xlsx文件"); + } + try { + List rows = ExcelImportUtil.importExcel(file.getFile(), RecuperationEnrollExcelMode.class, new ImportParams()); + if (rows == null || rows.isEmpty()) return Result.error("读取不到数据,请检查Excel文件格式"); + NutMap result = enrollService.importParticipants(rows); + return Result.success("导入完成,成功" + result.getInt("successCount") + "人,失败" + result.getInt("errorCount") + "人", result); + } catch (Exception e) { + log.error("导入参加人员失败", e); + return Result.error("读取不到数据,请检查Excel文件格式"); + } + } + + /** 将当前筛选结果按线路、旅行社或定点分别生成 Excel 并打包下载。 */ + @At + @Ok("void") + @SaCheckPermission("recuperation.schoolUnionUserQuery") + public void exportZip(@Param("..") RecuperationUserQueryPageForm query, HttpServletResponse response) throws Exception { + List rows = enrollService.managementList(query, false); + Map> groups = rows.stream().collect(Collectors.groupingBy( + row -> StrUtil.blankToDefault(row.getString("signUpModeName"), "其他") + "/" + StrUtil.blankToDefault(row.getString("targetName"), "未命名"), + LinkedHashMap::new, Collectors.toList())); + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("疗休养报名人员名单.zip", StandardCharsets.UTF_8)); + Set entryNames = new HashSet<>(); + try (ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()))) { + for (Map.Entry> entry : groups.entrySet()) { + String entryName = cleanZipEntry(entry.getKey()) + ".xlsx"; + int suffix = 2; + while (!entryNames.add(entryName)) entryName = cleanZipEntry(entry.getKey()) + "_" + suffix++ + ".xlsx"; + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, managementExportColumns(), entry.getValue()); + ByteArrayOutputStream output = new ByteArrayOutputStream()) { + workbook.write(output); + zip.putNextEntry(new ZipEntry(entryName)); + zip.write(output.toByteArray()); + zip.closeEntry(); + } + } + } + } + + private List managementExportColumns() { + List columns = new ArrayList<>(); + columns.add(new ExcelExportEntity("工号", "loginName", 18)); + columns.add(new ExcelExportEntity("姓名", "userName", 14)); + columns.add(new ExcelExportEntity("单位", "unitName", 24)); + columns.add(new ExcelExportEntity("工会", "unionName", 20)); + columns.add(new ExcelExportEntity("报名类型", "signUpModeName", 14)); + columns.add(new ExcelExportEntity("线路/旅行社/定点", "targetName", 28)); + columns.add(new ExcelExportEntity("报名时间", "signingUptime", 22)); + columns.add(new ExcelExportEntity("联系电话", "mobile", 18)); + return columns; + } + + private String cleanZipEntry(String name) { + return name.replaceAll("[\\\\:*?\"<>|]", "_").replace("..", "_"); + } + @At @Ok("void") @ApiOperation("导出") diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/param/RecuperationUserQueryPageForm.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/param/RecuperationUserQueryPageForm.java new file mode 100644 index 0000000..40422b8 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/param/RecuperationUserQueryPageForm.java @@ -0,0 +1,34 @@ +package com.budwk.app.zhgh.staffbenefit.recuperation.param; + +import com.budwk.app.base.param.PageForm; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * PC 端疗休养人员查询参数。 + * + *

startYear、endYear 为报名年度范围;signUpStatus 为 0 未报名、1 已报名、2 未成团; + * state 为 1 线路、2 灵活组团、3 定点;其余字段分别用于工会、单位、线路、旅行社、 + * 定点、标段、区域、报名方式、参加状态和报名日期筛选。分页结果返回 Pagination, + * list 为人员数据,totalCount 为符合条件的总人数。

+ */ +@Data +@EqualsAndHashCode(callSuper = true) +public class RecuperationUserQueryPageForm extends PageForm { + private Integer startYear; + private Integer endYear; + private Integer signUpStatus; + private Integer state; + private Integer isTakePartIn; + private String unFormedType; + private String unionId; + private String unitId; + private String takePartInLineId; + private String agencyId; + private String lotId; + private String takePartInBaseManagementId; + private String signUpMode; + private String regionalNature; + private String signStartTime; + private String signEndTime; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationAuditService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationAuditService.java index 5c9cca8..76ca557 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationAuditService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationAuditService.java @@ -41,11 +41,15 @@ public interface RecuperationAuditService extends BaseService { void schoolAudit(Integer stateId, String loginName,Boolean adjustment, String takePartInLineId); /** 按审核环节分页查询旧版报名记录。 */ - Pagination auditPage(PageForm pageForm, String stage, Integer year, Boolean audited, String keyword); + Pagination auditPage(PageForm pageForm, String stage, Integer year, Boolean audited, String keyword, + String unionId, String lineId, String agencyId); /** 根据报名当前状态完成分工会、线路工会或校工会审核。 */ void auditEnroll(String id, boolean pass, String auditOpinion); /** 撤回最近一次审核,将报名恢复到对应待审核状态。 */ void recallAudit(String id); + + /** 批量审核报名记录,ids 为报名 ID,pass 为结果,auditOpinion 为统一审核意见。 */ + void auditEnrolls(List ids, boolean pass, String auditOpinion); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationEnrollService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationEnrollService.java index fb79e2b..6d04c55 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationEnrollService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationEnrollService.java @@ -5,6 +5,8 @@ import com.budwk.app.base.param.PageForm; import com.budwk.app.base.service.BaseService; import com.budwk.app.sys.models.Sys_union; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll; +import com.budwk.app.zhgh.staffbenefit.recuperation.param.RecuperationUserQueryPageForm; +import com.budwk.app.zhgh.staffbenefit.recuperation.mode.RecuperationEnrollExcelMode; import org.nutz.dao.Cnd; import org.nutz.lang.util.NutMap; @@ -119,4 +121,62 @@ public interface RecuperationEnrollService extends BaseService getUnions(Integer year); + + /** + * 查询 PC 管理端疗休养人员。 + * + * @param query 查询参数,包含年度范围、报名状态、报名类型、工会及线路等筛选项 + * @param currentUnionOnly true 时强制限定为当前登录人的分工会,false 时允许校工会选择分工会 + * @return 分页结果;list 为报名、未报名或未成团人员,totalCount 为总人数 + */ + Pagination managementPageData(RecuperationUserQueryPageForm query, boolean currentUnionOnly); + + /** 按 PC 查询条件返回全部人员,用于导出;字段与分页列表一致。 */ + List managementList(RecuperationUserQueryPageForm query, boolean currentUnionOnly); + + /** + * 统计当前筛选范围内线路、灵活组团和定点报名人数。 + * + * @param query 查询参数,年度、工会、报名日期和参加状态与列表口径一致 + * @param currentUnionOnly 是否强制限定当前分工会 + * @return xlCount、lxsCount、jdCount 分别表示线路、灵活组团和定点人数 + */ + NutMap managementCategoryCount(RecuperationUserQueryPageForm query, boolean currentUnionOnly); + + /** + * 按 PC 查询条件发送报名提醒。 + * + * @param query 查询条件 + * @param currentUnionOnly 是否限定当前分工会 + * @param selectedLoginNames 页面勾选工号;为空时提醒当前筛选结果全部人员 + * @param content 消息正文,为空时使用疗休养配置中的默认提醒内容 + * @return sendCount 为实际接收人数,msg 为发送结果 + */ + NutMap remindManagementUsers(RecuperationUserQueryPageForm query, boolean currentUnionOnly, + List selectedLoginNames, String content); + + /** + * 保留报名记录:将已作废记录恢复为正常记录。 + * + * @param id 报名记录 ID + */ + void restoreEnroll(String id); + + /** 预览线路成团或未成团通知人数及默认内容。 */ + NutMap countLineGroupNoticeUsers(String lineUnionSelectId, boolean success); + + /** 发送线路成团通知。 */ + NutMap sendLineGroupSuccessNotice(String lineUnionSelectId, String content); + + /** 发送未成团通知,并按 keepEnrollRecords 决定保留为调出记录或彻底删除。 */ + NutMap sendLineGroupFailureNotice(String lineUnionSelectId, boolean keepEnrollRecords, String content); + + /** 批量导入省外线路实际参加时间和标段,返回成功、失败及错误明细。 */ + NutMap importParticipants(List rows); + + /** 按年度统计旅行社及具体方案的满意度评分。 */ + NutMap satisfactionRatingStatistics(Integer year); + + /** 查询满意度评价明细,typeName 可传线路、灵活组团、定点或全部。 */ + List satisfactionFeedbackDetails(Integer year, String typeName); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineAdjustmentService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineAdjustmentService.java index d87d154..134ebba 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineAdjustmentService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineAdjustmentService.java @@ -17,7 +17,10 @@ public interface RecuperationLineAdjustmentService extends BaseService findLineOptions(Integer year); - /** 切换指定线路中报名人员的正常/调出状态。 */ - void adjustmentUsers(String lineId, String[] loginNames); + /** 将指定线路报名人员设置为正常或调出状态。 */ + void adjustmentUsers(String lineId, String[] loginNames, boolean normal); + + /** 向线路调整人员发送未成团提醒,返回是否全部发送成功。 */ + boolean smsAlerts(String lineId, String[] loginNames); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineStatisticsService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineStatisticsService.java new file mode 100644 index 0000000..2564703 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationLineStatisticsService.java @@ -0,0 +1,17 @@ +package com.budwk.app.zhgh.staffbenefit.recuperation.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** PC 端线路成团统计查询。 */ +public interface RecuperationLineStatisticsService { + Pagination pageData(PageForm pageForm, Integer startYear, Integer endYear, String unionId, + String lineId, String lotId, String signUpMode, String selectId, String regionalNature); + + Pagination userPage(PageForm pageForm, String lineSelectId, String searchKeyword, String unionId, String unitId); + + List lineOptions(Integer startYear, Integer endYear, String signUpMode, String regionalNature); +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationProvinceFlexibleGroupService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationProvinceFlexibleGroupService.java index a43d36b..7d21595 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationProvinceFlexibleGroupService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/RecuperationProvinceFlexibleGroupService.java @@ -93,4 +93,28 @@ public interface RecuperationProvinceFlexibleGroupService extends BaseService queryGroupInfo(String groupId); + + /** 查询灵活组团报名人员;团长参数为空时返回全部人员。 */ + Pagination querySignUsers(PageForm pageForm, String groupId, String groupLeaderUserId, + String groupLeaderLoginName, Boolean noGroupLeader); + + /** 查询年度区间内可用旅行社。 */ + List queryTravelAgencyOptions(Integer startYear, Integer endYear); + + /** 查询年度区间内的灵活组团选项。 */ + List queryFlexibleGroupOptions(Integer startYear, Integer endYear); + + /** 按查询条件导出灵活组团报名人员。 */ + List queryExportUsers(Integer startYear, Integer endYear, String groupName, + String travelAgencyId, String searchKeyword); + + /** 删除灵活组团中的一条报名及其家属信息。 */ + void deleteJoinUser(String id); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationAuditServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationAuditServiceImpl.java index 3cdb27f..4b3215e 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationAuditServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationAuditServiceImpl.java @@ -161,7 +161,8 @@ public class RecuperationAuditServiceImpl extends BaseServiceImpl impleme } @Override - public Pagination auditPage(PageForm pageForm, String stage, Integer year, Boolean audited, String keyword) { + public Pagination auditPage(PageForm pageForm, String stage, Integer year, Boolean audited, String keyword, + String unionId, String lineId, String agencyId) { Sql sql = Sqls.create(""" SELECT enroll.*, line.lineName, ta.travelAgencyName, self_union.name AS selfUnionName, @@ -181,10 +182,17 @@ public class RecuperationAuditServiceImpl extends BaseServiceImpl impleme cnd.and(Cnd.exps("enroll.userName", "like", "%" + keyword + "%") .or("enroll.loginName", "like", "%" + keyword + "%")); } - if ("school".equals(stage) || "travel".equals(stage)) { + cnd.andEX("enroll.selfUnionId", "=", unionId); + cnd.andEX("line.id", "=", lineId); + cnd.andEX("ta.id", "=", agencyId); + if ("travel".equals(stage)) { + // 旅行社报名沿用分工会审核状态:待审为 UNIT,审核后为 UNITFAIL 或 PASS。 + cnd.and("enroll.takePartInTravelAgencyId", "is not", null); + cnd.and("enroll.stateId", audited == null || !audited ? "=" : "in", + audited == null || !audited ? RecuperationState.UNIT : new Integer[]{RecuperationState.UNITFAIL, RecuperationState.PASS}); + } else if ("school".equals(stage)) { cnd.and("enroll.stateId", audited == null || !audited ? "=" : "in", audited == null || !audited ? RecuperationState.SCHOOL : new Integer[]{RecuperationState.SCHOOLFAIL, RecuperationState.PASS}); - if ("travel".equals(stage)) cnd.and("enroll.takePartInTravelAgencyId", "is not", null); } else if ("lineUnion".equals(stage)) { cnd.and("enroll.takePartInUnionId", "=", SecurityUtil.getUnionId()); cnd.and("enroll.stateId", audited == null || !audited ? "=" : "in", @@ -246,4 +254,13 @@ public class RecuperationAuditServiceImpl extends BaseServiceImpl impleme } dao().update(enroll, "^stateId|selfUnionAuditId|joinLineUnionAuditId|schoolUnionAuditId$"); } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void auditEnrolls(List ids, boolean pass, String auditOpinion) { + if (ids == null) return; + for (String id : ids) { + if (StrUtil.isNotBlank(id)) auditEnroll(id, pass, auditOpinion); + } + } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationEnrollServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationEnrollServiceImpl.java index fdeeb55..2ec9a3e 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationEnrollServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationEnrollServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.sms.SmsService; import com.budwk.app.base.service.BaseService; import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.sys.models.Sys_union; @@ -13,6 +14,8 @@ import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope; import com.budwk.app.zhgh.activity.basic.service.ActivityBasicScopeService; import com.budwk.app.zhgh.staffbenefit.recuperation.constant.*; import com.budwk.app.zhgh.staffbenefit.recuperation.model.*; +import com.budwk.app.zhgh.staffbenefit.recuperation.param.RecuperationUserQueryPageForm; +import com.budwk.app.zhgh.staffbenefit.recuperation.mode.RecuperationEnrollExcelMode; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationEnrollService; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationBaseManagerService; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineService; @@ -21,6 +24,7 @@ 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.util.cri.Static; import org.nutz.dao.entity.Record; import org.nutz.dao.sql.Sql; import org.nutz.dao.util.Daos; @@ -58,6 +62,8 @@ public class RecuperationEnrollServiceImpl extends BaseServiceImpl(); } + + /** + * PC 人员查询统一入口。报名、未报名和未成团共用同一参数对象,避免校工会与分工会页面 + * 各自维护不同的查询口径。 + */ + @Override + public Pagination managementPageData(RecuperationUserQueryPageForm query, boolean currentUnionOnly) { + int startYear = query.getStartYear() == null ? DateUtil.thisYear() : query.getStartYear(); + int endYear = query.getEndYear() == null ? startYear : query.getEndYear(); + if (startYear > endYear) { + int temp = startYear; + startYear = endYear; + endYear = temp; + } + String unionId = currentUnionOnly ? SecurityUtil.getUnionId() : query.getUnionId(); + if (Integer.valueOf(0).equals(query.getSignUpStatus())) { + return unSignManagementPage(query, startYear, endYear, unionId); + } + if (Integer.valueOf(2).equals(query.getSignUpStatus())) { + return unFormedManagementPage(query, startYear, endYear, unionId); + } + Sql sql = Sqls.create(""" + SELECT + enroll.*, + '已报名' AS signUpStatus, + CASE WHEN enroll.takePartInBaseManagementId IS NOT NULL AND enroll.takePartInBaseManagementId!='' THEN '定点' + WHEN enroll.takePartInTravelAgencyId IS NOT NULL AND enroll.takePartInTravelAgencyId!='' THEN '灵活组团' + ELSE '线路' END AS signUpModeName, + IF(enroll.isTakePartIn=true,'已参加','未参加') AS takePartInName, + line.regionalNature, + line.lineName, + agency.travelAgencyName, + ma.baseName, + COALESCE(ma.baseName, line.lineName, agency.travelAgencyName) AS targetName, + lineu.lineId, + lineu.signUpMode, + lineu.playStartTime, + lineu.playEndTime, + CASE WHEN enroll.lotId IN ('两天','三天','五天') THEN enroll.lotId + ELSE lot.lotName END AS lotName, + (SELECT COUNT(1) FROM the_rapy_recuperation_enroll_companion companion + WHERE companion.trreId = enroll.id) AS isFamily + 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 = IFNULL(NULLIF(enroll.lotId, ''), line.lotId) + LEFT JOIN the_rapy_recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId + LEFT JOIN the_rapy_recuperation_base_management ma ON ma.id = enroll.takePartInBaseManagementId + $condition + """); + Cnd cnd = Cnd.where("YEAR(enroll.signingUptime)", ">=", startYear) + .and("YEAR(enroll.signingUptime)", "<=", endYear) + .and("enroll.stateId", "=", RecuperationState.PASS) + .and("enroll.isNormal", "=", true); + appendManagementConditions(cnd, query, unionId); + if (Integer.valueOf(1).equals(query.getState())) { + cnd.and("enroll.takePartInLineId", "is not", null).and("enroll.takePartInLineId", "!=", ""); + } else if (Integer.valueOf(2).equals(query.getState())) { + cnd.and("enroll.takePartInTravelAgencyId", "is not", null).and("enroll.takePartInTravelAgencyId", "!=", ""); + } else if (Integer.valueOf(3).equals(query.getState())) { + cnd.and("enroll.takePartInBaseManagementId", "is not", null).and("enroll.takePartInBaseManagementId", "!=", ""); + } + cnd.desc("enroll.signingUptime").asc("enroll.unionName"); + sql.setCondition(cnd); + return listPageMap(query.getPageNumber(), query.getPageSize(), sql); + } + + @Override + public List managementList(RecuperationUserQueryPageForm query, boolean currentUnionOnly) { + int originalPage = query.getPageNumber() == null ? 1 : query.getPageNumber(); + int originalSize = query.getPageSize() == null ? 10 : query.getPageSize(); + query.setPageNumber(1); + query.setPageSize(200); + Pagination firstPage = managementPageData(query, currentUnionOnly); + List result = new ArrayList<>(); + appendManagementRows(firstPage, result); + for (int page = 2; page <= firstPage.getTotalPage(); page++) { + query.setPageNumber(page); + appendManagementRows(managementPageData(query, currentUnionOnly), result); + } + query.setPageNumber(originalPage); + query.setPageSize(originalSize); + return result; + } + + /** 将分页中的 Map 或实体统一转换为导出使用的 NutMap。 */ + private void appendManagementRows(Pagination page, List target) { + if (page == null || page.getList() == null) return; + for (Object item : page.getList()) { + target.add(item instanceof NutMap ? (NutMap) item : Lang.obj2nutmap(item)); + } + } + + /** 查询参加范围内没有有效报名记录的教职工。 */ + private Pagination unSignManagementPage(RecuperationUserQueryPageForm query, int startYear, int endYear, String unionId) { + RecuperationConfig config = dao().fetch(RecuperationConfig.class); + if (config == null || config.getActivityGroupId() == null) { + return new Pagination(query.getPageNumber(), query.getPageSize(), 0, new ArrayList<>()); + } + Sql sql = Sqls.create(""" + SELECT DISTINCT u.id, u.loginname AS loginName, u.username AS userName, u.sex, u.mobile, + u.unitname AS unitName, u.unionname AS unionName, u.unitid AS selfUnitId, + u.unionid AS selfUnionId, '未报名' AS signUpStatus + FROM vw_user u + $condition + """); + Cnd cnd = Cnd.where("u.id", "in", activityBasicScopeService.buildGroupUserIdSubSql(config.getActivityGroupId())) + .and(new Static("NOT EXISTS (SELECT 1 FROM the_rapy_recuperation_enroll enroll WHERE enroll.loginName=u.loginname " + + "AND YEAR(enroll.signingUptime)>=" + startYear + " AND YEAR(enroll.signingUptime)<=" + endYear + + " AND enroll.isNormal=true AND enroll.stateId NOT IN (2715,2725,2735))")); + if (StrUtil.isNotBlank(unionId)) { + cnd.and("u.unionid", "=", unionId); + } + appendSearchCondition(cnd, query, "u.loginname", "u.username"); + cnd.asc("u.unionname").asc("u.unitname").asc("u.loginname"); + sql.setCondition(cnd); + return listPageMap(query.getPageNumber(), query.getPageSize(), sql); + } + + /** 查询报名成功但没有达到旧版成团人数规则的线路或灵活组团人员。 */ + private Pagination unFormedManagementPage(RecuperationUserQueryPageForm query, int startYear, int endYear, String unionId) { + boolean flexible = "flexible".equals(query.getUnFormedType()); + String sqlText = flexible ? """ + SELECT * FROM ( + SELECT enroll.*, ta.travelAgencyName AS targetName, ta.id AS agencyId, '灵活组团' AS signUpModeName, + 3 AS groupThreshold, + (SELECT COUNT(DISTINCT sameLeader.loginName) FROM the_rapy_recuperation_enroll sameLeader + WHERE sameLeader.takePartInTravelAgencyId=enroll.takePartInTravelAgencyId + AND YEAR(sameLeader.signingUptime)=YEAR(enroll.signingUptime) AND sameLeader.isNormal=true + AND sameLeader.stateId=2750 AND IFNULL(sameLeader.groupLeaderLoginName,sameLeader.loginName)= + IFNULL(enroll.groupLeaderLoginName,enroll.loginName)) AS currentCount + FROM the_rapy_recuperation_enroll enroll + LEFT JOIN the_rapy_recuperation_travel_agency ta ON ta.id=enroll.takePartInTravelAgencyId + WHERE enroll.takePartInTravelAgencyId IS NOT NULL AND enroll.takePartInTravelAgencyId!='' + AND enroll.isNormal=true AND enroll.stateId=2750 + AND YEAR(enroll.signingUptime) BETWEEN @startYear AND @endYear + ) unformed $condition + """ : """ + SELECT * FROM ( + SELECT enroll.*, line.lineName AS targetName, line.regionalNature, lineu.playStartTime, + IFNULL((SELECT outsideQuota FROM the_rapy_recuperation_config LIMIT 1),0) AS groupThreshold, + ((SELECT COUNT(DISTINCT sameLine.loginName) FROM the_rapy_recuperation_enroll sameLine + WHERE sameLine.takePartInLineId=enroll.takePartInLineId AND sameLine.isNormal=true AND sameLine.stateId=2750) + + IFNULL((SELECT SUM(IFNULL(sameLine.familyNumber,0)) FROM the_rapy_recuperation_enroll sameLine + WHERE sameLine.takePartInLineId=enroll.takePartInLineId AND sameLine.isNormal=true AND sameLine.stateId=2750),0)) AS currentCount + 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 + WHERE enroll.takePartInLineId IS NOT NULL AND enroll.takePartInLineId!='' + AND enroll.isNormal=true AND enroll.stateId=2750 + AND YEAR(enroll.signingUptime) BETWEEN @startYear AND @endYear + ) unformed $condition + """; + Sql sql = Sqls.create(sqlText).setParam("startYear", startYear).setParam("endYear", endYear); + Cnd cnd = Cnd.where("unformed.groupThreshold", ">", 0) + .and(new Static("unformed.currentCount < unformed.groupThreshold")); + if (StrUtil.isNotBlank(unionId)) { + cnd.and("unformed.selfUnionId", "=", unionId); + } + if (StrUtil.isNotBlank(query.getAgencyId()) && flexible) { + cnd.and("unformed.agencyId", "=", query.getAgencyId()); + } + appendSearchCondition(cnd, query, "unformed.loginName", "unformed.userName"); + cnd.asc("unformed.unionName").asc("unformed.targetName").asc("unformed.signingUptime"); + sql.setCondition(cnd); + return listPageMap(query.getPageNumber(), query.getPageSize(), sql); + } + + /** 追加报名列表的公共筛选条件。 */ + private void appendManagementConditions(Cnd cnd, RecuperationUserQueryPageForm query, String unionId) { + cnd.andEX("enroll.selfUnionId", "=", unionId); + cnd.andEX("enroll.selfUnitId", "=", query.getUnitId()); + cnd.andEX("line.id", "=", query.getTakePartInLineId()); + cnd.andEX("enroll.takePartInTravelAgencyId", "=", query.getAgencyId()); + cnd.andEX("enroll.takePartInBaseManagementId", "=", query.getTakePartInBaseManagementId()); + cnd.andEX("line.regionalNature", "=", query.getRegionalNature()); + cnd.andEX("lineu.signUpMode", "=", query.getSignUpMode()); + cnd.andEX("enroll.isTakePartIn", "=", query.getIsTakePartIn()); + cnd.andEX("enroll.lotId", "=", query.getLotId()); + cnd.andEX("enroll.signingUptime", ">=", query.getSignStartTime()); + cnd.andEX("enroll.signingUptime", "<=", query.getSignEndTime()); + appendSearchCondition(cnd, query, "enroll.loginName", "enroll.userName"); + } + + /** 姓名和工号查询只能使用固定字段,禁止将页面字段名直接拼入 SQL。 */ + private void appendSearchCondition(Cnd cnd, RecuperationUserQueryPageForm query, String loginColumn, String userColumn) { + if (StrUtil.isBlank(query.getSearchKeyword())) { + return; + } + if ("loginName".equals(query.getSearchName())) { + cnd.and(Cnd.likeEX(loginColumn, query.getSearchKeyword())); + } else { + cnd.and(Cnd.likeEX(userColumn, query.getSearchKeyword())); + } + } + + @Override + public NutMap managementCategoryCount(RecuperationUserQueryPageForm query, boolean currentUnionOnly) { + String unionId = currentUnionOnly ? SecurityUtil.getUnionId() : query.getUnionId(); + int startYear = query.getStartYear() == null ? DateUtil.thisYear() : query.getStartYear(); + int endYear = query.getEndYear() == null ? startYear : query.getEndYear(); + int minYear = Math.min(startYear, endYear); + int maxYear = Math.max(startYear, endYear); + int lineCount = dao().count(RecuperationEnroll.class, buildManagementCountCnd(query, unionId, minYear, maxYear) + .and("takePartInLineId", "is not", null).and("takePartInLineId", "!=", "")); + int agencyCount = dao().count(RecuperationEnroll.class, buildManagementCountCnd(query, unionId, minYear, maxYear) + .and("takePartInTravelAgencyId", "is not", null).and("takePartInTravelAgencyId", "!=", "")); + int baseCount = dao().count(RecuperationEnroll.class, buildManagementCountCnd(query, unionId, minYear, maxYear) + .and("takePartInBaseManagementId", "is not", null).and("takePartInBaseManagementId", "!=", "")); + return NutMap.NEW().setv("xlCount", lineCount).setv("lxsCount", agencyCount).setv("jdCount", baseCount); + } + + @Override + public NutMap remindManagementUsers(RecuperationUserQueryPageForm query, boolean currentUnionOnly, + List selectedLoginNames, String content) { + RecuperationConfig config = dao().fetch(RecuperationConfig.class); + String sendContent = StrUtil.trim(content); + if (StrUtil.isBlank(sendContent) && config != null) { + sendContent = StrUtil.trim(config.getRemindContent()); + } + if (StrUtil.isBlank(sendContent)) { + return NutMap.NEW().setv("sendCount", 0).setv("msg", "提醒内容不能为空"); + } + Set selected = selectedLoginNames == null ? Collections.emptySet() : selectedLoginNames.stream() + .filter(StrUtil::isNotBlank).collect(Collectors.toSet()); + int originalPage = query.getPageNumber() == null ? 1 : query.getPageNumber(); + int originalSize = query.getPageSize() == null ? 10 : query.getPageSize(); + query.setPageNumber(1); + query.setPageSize(200); + Pagination firstPage = managementPageData(query, currentUnionOnly); + int totalPages = Math.max(1, (firstPage.getTotalCount() + 199) / 200); + LinkedHashSet loginNames = new LinkedHashSet<>(); + collectManagementLoginNames(firstPage, selected, loginNames); + for (int page = 2; page <= totalPages; page++) { + query.setPageNumber(page); + collectManagementLoginNames(managementPageData(query, currentUnionOnly), selected, loginNames); + } + query.setPageNumber(originalPage); + query.setPageSize(originalSize); + if (loginNames.isEmpty()) { + return NutMap.NEW().setv("sendCount", 0).setv("msg", "当前筛选条件下没有可提醒人员"); + } + boolean success = smsService.sendMsg("56", new ArrayList<>(loginNames), null, + "疗休养报名提醒", sendContent, null, "/platform/h5/recuperation"); + return NutMap.NEW().setv("sendCount", loginNames.size()) + .setv("msg", success ? "已发送提醒" + loginNames.size() + "人" : "消息发送失败,请检查消息中心配置"); + } + + /** 从分页结果中提取工号;页面勾选不为空时只保留勾选人员。 */ + private void collectManagementLoginNames(Pagination page, Set selected, Set result) { + if (page == null || page.getList() == null) { + return; + } + for (Object item : page.getList()) { + NutMap row = item instanceof NutMap ? (NutMap) item : Lang.obj2nutmap(item); + String loginName = row.getString("loginName"); + if (StrUtil.isNotBlank(loginName) && (selected.isEmpty() || selected.contains(loginName))) { + result.add(loginName); + } + } + } + + /** 构造分类数量统计的独立条件对象,避免三个统计相互污染。 */ + private Cnd buildManagementCountCnd(RecuperationUserQueryPageForm query, String unionId, int startYear, int endYear) { + return Cnd.where("YEAR(signingUptime)", ">=", startYear) + .and("YEAR(signingUptime)", "<=", endYear) + .and("stateId", "=", RecuperationState.PASS) + .and("isNormal", "=", true) + .andEX("selfUnionId", "=", unionId) + .andEX("isTakePartIn", "=", query.getIsTakePartIn()) + .andEX("signingUptime", ">=", query.getSignStartTime()) + .andEX("signingUptime", "<=", query.getSignEndTime()); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void restoreEnroll(String id) { + dao().update(RecuperationEnroll.class, org.nutz.dao.Chain.make("isNormal", true), Cnd.where("id", "=", id)); + } + + @Override + public NutMap countLineGroupNoticeUsers(String lineUnionSelectId, boolean success) { + NutMap notice = lineGroupNoticeInfo(lineUnionSelectId); + if (!notice.getBoolean("valid")) return lineNoticeResult(0, notice.getString("msg"), notice, success, null); + List enrolls = lineNoticeEnrolls(lineUnionSelectId); + long count = enrolls.stream().map(RecuperationEnroll::getLoginName).filter(StrUtil::isNotBlank).distinct().count(); + return lineNoticeResult((int) count, count == 0 ? "当前暂无需要发送通知的报名人员" : "当前将发送通知" + count + "人", notice, success, null); + } + + @Override + public NutMap sendLineGroupSuccessNotice(String lineUnionSelectId, String content) { + return sendLineGroupNotice(lineUnionSelectId, true, true, content); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public NutMap sendLineGroupFailureNotice(String lineUnionSelectId, boolean keepEnrollRecords, String content) { + return sendLineGroupNotice(lineUnionSelectId, false, keepEnrollRecords, content); + } + + /** 统一校验线路、发送消息,并在未成团时处理报名数据。 */ + private NutMap sendLineGroupNotice(String lineUnionSelectId, boolean success, boolean keepEnrollRecords, String content) { + NutMap notice = lineGroupNoticeInfo(lineUnionSelectId); + if (!notice.getBoolean("valid")) return lineNoticeResult(0, notice.getString("msg"), notice, success, content); + List enrolls = lineNoticeEnrolls(lineUnionSelectId); + List loginNames = enrolls.stream().map(RecuperationEnroll::getLoginName) + .filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList()); + if (loginNames.isEmpty()) return lineNoticeResult(0, "当前暂无需要发送通知的报名人员", notice, success, content); + String sendContent = StrUtil.blankToDefault(StrUtil.trim(content), defaultLineNoticeContent(notice, success)); + if (StrUtil.isBlank(sendContent)) return lineNoticeResult(0, "消息内容不能为空", notice, success, content); + String title = success ? "疗休养成团通知" : "疗休养未成团通知"; + if (!smsService.sendMsg("56", loginNames, null, title, sendContent, null, null)) { + return lineNoticeResult(0, "消息发送失败,请检查消息中心配置", notice, success, sendContent); + } + if (!success) handleLineGroupFailure(enrolls, keepEnrollRecords); + return lineNoticeResult(loginNames.size(), "已发送通知" + loginNames.size() + "人", notice, success, sendContent); + } + + private List lineNoticeEnrolls(String lineUnionSelectId) { + return dao().query(RecuperationEnroll.class, Cnd.where("takePartInLineId", "=", lineUnionSelectId) + .and("isNormal", "=", true).and("stateId", "not in", + Lang.array(RecuperationState.UNITFAIL, RecuperationState.LINEUNITFAIL, RecuperationState.SCHOOLFAIL))); + } + + private NutMap lineGroupNoticeInfo(String lineUnionSelectId) { + RecuperationLineSelect lineSelect = dao().fetch(RecuperationLineSelect.class, lineUnionSelectId); + if (lineSelect == null) return NutMap.NEW().setv("valid", false).setv("msg", "线路报名信息不存在"); + if (lineSelect.getSignUpEndTime() != null && new Date().before(lineSelect.getSignUpEndTime())) { + return NutMap.NEW().setv("valid", false).setv("msg", "报名还未结束,不能发送"); + } + RecuperationLine line = dao().fetch(RecuperationLine.class, lineSelect.getLineId()); + if (line == null) return NutMap.NEW().setv("valid", false).setv("msg", "线路信息不存在"); + return NutMap.NEW().setv("valid", true).setv("lineName", line.getLineName()) + .setv("playStartTime", lineSelect.getPlayStartTime() == null ? "" : DateUtil.formatDate(lineSelect.getPlayStartTime())); + } + + /** 未成团记录保留时转为调出;删除时同步清理家属和床位。 */ + private void handleLineGroupFailure(List enrolls, boolean keepEnrollRecords) { + List ids = enrolls.stream().map(RecuperationEnroll::getId).collect(Collectors.toList()); + if (keepEnrollRecords) { + dao().update(RecuperationEnroll.class, org.nutz.dao.Chain.make("isNormal", false), Cnd.where("id", "in", ids)); + return; + } + List bedIds = enrolls.stream().map(RecuperationEnroll::getBedInfoId).filter(StrUtil::isNotBlank).collect(Collectors.toList()); + dao().clear(RecuperationEnrollCompanion.class, Cnd.where("trreId", "in", ids)); + if (!bedIds.isEmpty()) dao().clear(RecuperationEnrollBed.class, Cnd.where("id", "in", bedIds)); + dao().clear(RecuperationEnroll.class, Cnd.where("id", "in", ids)); + } + + private String defaultLineNoticeContent(NutMap notice, boolean success) { + return success + ? "您好!您报名的" + notice.getString("lineName") + "线路,出行时间为" + notice.getString("playStartTime") + ",已达到成团条件,请准时参加疗休养活动。" + : "您好!您报名的" + notice.getString("lineName") + "线路,出行时间为" + notice.getString("playStartTime") + ",因报名人数不足未达到成团条件,请尽快进入疗休养管理系统重新选择线路。"; + } + + private NutMap lineNoticeResult(int sendCount, String msg, NutMap notice, boolean success, String content) { + return NutMap.NEW().setv("sendCount", sendCount).setv("msg", msg) + .setv("title", success ? "疗休养成团通知" : "疗休养未成团通知") + .setv("content", StrUtil.blankToDefault(StrUtil.trim(content), notice == null ? "" : defaultLineNoticeContent(notice, success))) + .setv("sendType", "56").setv("sendTypeName", "微信、钉钉"); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public NutMap importParticipants(List rows) { + List successList = new ArrayList<>(); + List errorList = new ArrayList<>(); + List lots = dao().query(RecuperationLot.class, Cnd.NEW()); + for (int i = 0; i < rows.size(); i++) { + RecuperationEnrollExcelMode row = rows.get(i); + NutMap result = NutMap.NEW().setv("no", i + 2).setv("loginName", StrUtil.trim(row.getLoginName())) + .setv("userName", row.getUserName()).setv("takePartInTime", row.getTakePartInTime() == null ? "" : DateUtil.formatDate(row.getTakePartInTime())) + .setv("lotName", row.getLotId()); + if (StrUtil.isBlank(row.getLoginName()) || StrUtil.isBlank(row.getUserName()) || row.getTakePartInTime() == null || StrUtil.isBlank(row.getLotId())) { + errorList.add(result.setv("errors", "工号、姓名、参加时间和标段时间均不能为空")); + continue; + } + int year = DateUtil.year(row.getTakePartInTime()); + RecuperationEnroll enroll = dao().fetch(RecuperationEnroll.class, Cnd.where("loginName", "=", StrUtil.trim(row.getLoginName())) + .and("YEAR(signingUptime)", "=", year).desc("signingUptime")); + if (enroll == null) { + errorList.add(result.setv("errors", "未找到参加时间所属年度报名记录(" + year + ")")); + continue; + } + String existsError = participantImportExistsError(enroll); + if (StrUtil.isNotBlank(existsError)) { + errorList.add(result.setv("errors", existsError)); + continue; + } + RecuperationLot lot = lots.stream().filter(item -> StrUtil.equals(item.getLotName(), row.getLotId())).findFirst().orElse(null); + if (lot == null) { + errorList.add(result.setv("errors", "标段时间不存在或名称不匹配")); + continue; + } + enroll.setTakePartInTime(row.getTakePartInTime()); + enroll.setLotId(lot.getId()); + enroll.setTakePartIn(true); + enroll.setNormal(true); + dao().updateIgnoreNull(enroll); + successList.add(result.setv("result", "导入成功").setv("errors", "")); + } + return NutMap.NEW().setv("totalCount", rows.size()).setv("successCount", successList.size()) + .setv("errorCount", errorList.size()).setv("successList", successList).setv("errorList", errorList); + } + + /** 导入参加信息只允许覆盖已有省外线路报名,避免误覆盖定点、灵活组团和省内线路。 */ + private String participantImportExistsError(RecuperationEnroll enroll) { + if (StrUtil.isNotBlank(enroll.getTakePartInBaseManagementId())) return "该年度已有定点报名记录,导入不会覆盖原报名"; + if (StrUtil.isNotBlank(enroll.getTakePartInTravelAgencyId())) return "该年度已有灵活组团报名记录,导入不会覆盖原报名"; + if (StrUtil.isBlank(enroll.getTakePartInLineId())) return "该年度报名记录未选择线路"; + Sql sql = Sqls.create("SELECT line.regionalNature FROM the_rapy_recuperation_line_union_select us LEFT JOIN the_rapy_recuperation_line line ON line.id=us.lineId WHERE us.id=@id"); + sql.setParam("id", enroll.getTakePartInLineId()).setCallback(Sqls.callback.map()); + dao().execute(sql); + NutMap line = sql.getObject(NutMap.class); + String regionalNature = line == null ? "" : line.getString("regionalNature"); + return "省外".equals(regionalNature) ? "" : "该年度已有" + StrUtil.blankToDefault(regionalNature, "") + "线路报名记录,导入不会覆盖原报名"; + } + + @Override + public NutMap satisfactionRatingStatistics(Integer year) { + int statisticYear = year == null ? DateUtil.thisYear() : year; + Sql agencySql = Sqls.create(""" + SELECT agency.travelAgencyName, + ROUND(AVG(CASE WHEN rating.evaluationForTravelAgency IS NOT NULL AND rating.evaluationForJourney IS NOT NULL + AND rating.evaluationForAccommodation IS NOT NULL AND rating.evaluationForDining IS NOT NULL + AND rating.evaluationForTransportation IS NOT NULL THEN + (rating.evaluationForTravelAgency+rating.evaluationForJourney+rating.evaluationForAccommodation+rating.evaluationForDining+rating.evaluationForTransportation)/5 END),1) AS avg, + COUNT(DISTINCT CASE WHEN rating.evaluationForTravelAgency IS NOT NULL AND rating.evaluationForJourney IS NOT NULL + AND rating.evaluationForAccommodation IS NOT NULL AND rating.evaluationForDining IS NOT NULL + AND rating.evaluationForTransportation IS NOT NULL THEN rating.loginName END) AS ratingCount + FROM the_rapy_recuperation_travel_agency agency + LEFT JOIN ($ratingSql) rating ON rating.travelAgencyId=agency.id + WHERE agency.year=@year + GROUP BY agency.id, agency.travelAgencyName + ORDER BY CASE WHEN avg IS NULL THEN 1 ELSE 0 END, avg DESC, ratingCount DESC, agency.travelAgencyName + """); + agencySql.setVar("ratingSql", satisfactionBaseSql()).setParam("year", statisticYear); + Sql schemeSql = Sqls.create(""" + SELECT rating.typeName, rating.schemeId, rating.schemeName, rating.travelAgencyName, + ROUND(AVG(rating.evaluationForTravelAgency),1) AS travelAgencyAvg, + COUNT(DISTINCT CASE WHEN rating.evaluationForTravelAgency IS NOT NULL THEN rating.loginName END) AS travelAgencyCount, + ROUND(AVG(rating.evaluationForJourney),1) AS journeyAvg, + COUNT(DISTINCT CASE WHEN rating.evaluationForJourney IS NOT NULL THEN rating.loginName END) AS journeyCount, + ROUND(AVG(rating.evaluationForAccommodation),1) AS accommodationAvg, + COUNT(DISTINCT CASE WHEN rating.evaluationForAccommodation IS NOT NULL THEN rating.loginName END) AS accommodationCount, + ROUND(AVG(rating.evaluationForDining),1) AS diningAvg, + COUNT(DISTINCT CASE WHEN rating.evaluationForDining IS NOT NULL THEN rating.loginName END) AS diningCount, + ROUND(AVG(rating.evaluationForTransportation),1) AS transportationAvg, + COUNT(DISTINCT CASE WHEN rating.evaluationForTransportation IS NOT NULL THEN rating.loginName END) AS transportationCount, + ROUND(AVG(CASE + WHEN rating.typeName='线路' AND rating.evaluationForTravelAgency IS NOT NULL AND rating.evaluationForJourney IS NOT NULL + AND rating.evaluationForAccommodation IS NOT NULL AND rating.evaluationForDining IS NOT NULL AND rating.evaluationForTransportation IS NOT NULL + THEN (rating.evaluationForTravelAgency+rating.evaluationForJourney+rating.evaluationForAccommodation+rating.evaluationForDining+rating.evaluationForTransportation)/5 + WHEN rating.typeName IN ('灵活组团','定点') AND rating.evaluationForTravelAgency IS NOT NULL AND rating.evaluationForAccommodation IS NOT NULL + THEN (rating.evaluationForTravelAgency+rating.evaluationForAccommodation)/2 END),1) AS compositeAvg, + COUNT(DISTINCT CASE + WHEN rating.typeName='线路' AND rating.evaluationForTravelAgency IS NOT NULL AND rating.evaluationForJourney IS NOT NULL + AND rating.evaluationForAccommodation IS NOT NULL AND rating.evaluationForDining IS NOT NULL AND rating.evaluationForTransportation IS NOT NULL THEN rating.loginName + WHEN rating.typeName IN ('灵活组团','定点') AND rating.evaluationForTravelAgency IS NOT NULL AND rating.evaluationForAccommodation IS NOT NULL THEN rating.loginName END) AS ratingCount + FROM ($ratingSql) rating + WHERE IFNULL(rating.schemeId,'')<>'' + GROUP BY rating.typeName, rating.schemeId, rating.schemeName, rating.travelAgencyName + ORDER BY FIELD(rating.typeName,'线路','灵活组团','定点'), rating.schemeName + """); + schemeSql.setVar("ratingSql", satisfactionBaseSql()).setParam("year", statisticYear); + return NutMap.NEW().setv("travelAgencyCompositeRatings", listMap(agencySql)) + .setv("schemeServiceRatings", listMap(schemeSql)); + } + + @Override + public List satisfactionFeedbackDetails(Integer year, String typeName) { + Sql sql = Sqls.create(""" + SELECT rating.*, + ROUND(CASE WHEN rating.typeName='线路' THEN + (rating.evaluationForTravelAgency+rating.evaluationForJourney+rating.evaluationForAccommodation+rating.evaluationForDining+rating.evaluationForTransportation)/5 + ELSE (rating.evaluationForTravelAgency+rating.evaluationForAccommodation)/2 END,1) AS compositeScore + FROM ($ratingSql) rating + WHERE rating.feedbackContent IS NOT NULL AND rating.feedbackContent<>'' + ORDER BY rating.signingUptime DESC + """); + sql.setVar("ratingSql", satisfactionBaseSql()).setParam("year", year == null ? DateUtil.thisYear() : year); + List list = listMap(sql); + if (StrUtil.isBlank(typeName) || "全部".equals(typeName)) return list; + return list.stream().filter(item -> typeName.equals(item.getString("typeName"))).collect(Collectors.toList()); + } + + /** 满意度统计与明细共用同一报名方式、方案和旅行社映射。 */ + private String satisfactionBaseSql() { + return """ + SELECT enroll.id, enroll.loginName, enroll.userName, enroll.unitName, enroll.signingUptime, enroll.feedbackContent, + enroll.evaluationForTravelAgency, enroll.evaluationForJourney, enroll.evaluationForAccommodation, + enroll.evaluationForDining, enroll.evaluationForTransportation, + CASE WHEN enroll.takePartInLineId IS NOT NULL THEN '线路' WHEN enroll.takePartInBaseManagementId IS NOT NULL THEN '定点' ELSE '灵活组团' END AS typeName, + CASE WHEN enroll.takePartInLineId IS NOT NULL THEN COALESCE(line.id,directLine.id) WHEN enroll.takePartInBaseManagementId IS NOT NULL THEN base.id ELSE COALESCE(flexible.id,enroll.takePartInTravelAgencyId) END AS schemeId, + CASE WHEN enroll.takePartInLineId IS NOT NULL THEN COALESCE(line.lineName,directLine.lineName) WHEN enroll.takePartInBaseManagementId IS NOT NULL THEN base.baseName ELSE COALESCE(flexible.groupName, directAgency.travelAgencyName) END AS schemeName, + COALESCE(selectAgency.id,lineAgency.id,directLineAgency.id,baseAgency.id,directAgency.id) AS travelAgencyId, + COALESCE(selectAgency.travelAgencyName,lineAgency.travelAgencyName,directLineAgency.travelAgencyName,baseAgency.travelAgencyName,directAgency.travelAgencyName) AS travelAgencyName + FROM the_rapy_recuperation_enroll enroll + LEFT JOIN the_rapy_recuperation_line_union_select lineSelect ON lineSelect.id=enroll.takePartInLineId + LEFT JOIN the_rapy_recuperation_line line ON line.id=lineSelect.lineId + LEFT JOIN the_rapy_recuperation_line directLine ON directLine.id=enroll.takePartInLineId + LEFT JOIN the_rapy_recuperation_base_management base ON base.id=enroll.takePartInBaseManagementId + LEFT JOIN the_rapy_recuperation_travel_agency selectAgency ON selectAgency.id=lineSelect.travelAgencyId + LEFT JOIN the_rapy_recuperation_travel_agency lineAgency ON lineAgency.id=line.travelAgencyId + LEFT JOIN the_rapy_recuperation_travel_agency directLineAgency ON directLineAgency.id=directLine.travelAgencyId + LEFT JOIN the_rapy_recuperation_travel_agency baseAgency ON baseAgency.id=base.travelAgencyId + LEFT JOIN the_rapy_recuperation_travel_agency directAgency ON directAgency.id=enroll.takePartInTravelAgencyId + LEFT JOIN the_rapy_recuperation_province_flexible_group flexible ON flexible.id=( + SELECT firstFlexible.id FROM the_rapy_recuperation_province_flexible_group firstFlexible + WHERE firstFlexible.travelAgencyId=enroll.takePartInTravelAgencyId + AND firstFlexible.year=YEAR(enroll.signingUptime) AND firstFlexible.isDisabled=false + ORDER BY firstFlexible.sortNumber, firstFlexible.id LIMIT 1 + ) + WHERE enroll.isNormal=true AND enroll.isTakePartIn=true AND YEAR(enroll.signingUptime)=@year + """; + } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineAdjustmentServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineAdjustmentServiceImpl.java index c68188f..ded5f79 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineAdjustmentServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineAdjustmentServiceImpl.java @@ -2,6 +2,7 @@ package com.budwk.app.zhgh.staffbenefit.recuperation.service.impl; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.sms.SmsService; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.service.impl.BaseServiceImpl; @@ -16,12 +17,14 @@ import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.aop.Aop; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.lang.Strings; import org.nutz.lang.util.NutMap; import java.util.List; +import java.util.Collections; /** * @FileName com.budwk.app.zhgh.staffbenefit.recuperation.service.impl.RecuperationLineAdjustmentServiceImpl @@ -33,6 +36,9 @@ import java.util.List; @IocBean(args = {"refer:dao"}) public class RecuperationLineAdjustmentServiceImpl extends BaseServiceImpl implements RecuperationLineAdjustmentService { + @Inject + private SmsService smsService; + public RecuperationLineAdjustmentServiceImpl(Dao dao) { super(dao); } @@ -159,8 +165,37 @@ public class RecuperationLineAdjustmentServiceImpl extends BaseServiceImpl users = dao().query(RecuperationEnroll.class, + Cnd.where("takePartInLineId", "=", lineId).and("loginName", "in", loginNames)); + boolean success = true; + for (RecuperationEnroll user : users) { + String content = String.format("%s老师您好,您报名的%s【%s-%s】(%s至%s)线路未达到成团标准,现已解散,请您选择其他线路进行报名!", + user.getUserName(), line.getString("lineName"), line.getString("lotName"), + line.getString("regionalNature"), line.getString("playStartTime"), line.getString("playEndTime")); + success = smsService.sendMsg("56", Collections.singletonList(user.getLoginName()), null, + "疗休养线路调整提醒", content, null, null) && success; + } + return success; } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineClusterServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineClusterServiceImpl.java index f616af1..27555c3 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineClusterServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationLineClusterServiceImpl.java @@ -149,7 +149,8 @@ public class RecuperationLineClusterServiceImpl extends BaseServiceImpl 1 OR enroll.takePartInUnionId = us.unionId)) AS signUpUserNum, + (SELECT count(1) + FROM the_rapy_recuperation_enroll_companion companion + WHERE companion.trreId IN ( + SELECT enroll.id + FROM the_rapy_recuperation_enroll enroll + WHERE enroll.takePartInLineId = us.id + AND enroll.isNormal = true + AND enroll.stateId = 2750 + AND (us.signUpMode <> 1 OR enroll.takePartInUnionId = us.unionId) + )) AS signUpUserFamilyNum FROM the_rapy_recuperation_line_union_select us LEFT JOIN the_rapy_recuperation_line line ON line.id = us.lineId @@ -179,22 +194,16 @@ public class RecuperationLineClusterServiceImpl extends BaseServiceImpl implements RecuperationLineStatisticsService { + public RecuperationLineStatisticsServiceImpl(Dao dao) { super(dao); } + + @Override + public Pagination pageData(PageForm pageForm, Integer startYear, Integer endYear, String unionId, + String lineId, String lotId, String signUpMode, String selectId, String regionalNature) { + Sql sql = Sqls.create(""" + SELECT line.id, line.lineName, line.regionalNature, lineu.id AS lineUId, lineu.signUpMode, + YEAR(lineu.selectTime) AS year, + CONCAT(DATE_FORMAT(lineu.playStartTime,'%m月%d日'),'-',DATE_FORMAT(lineu.playEndTime,'%m月%d日')) AS linePlayTime, + agency.travelAgencyName, agency.contact, agency.contactMobileNumber, + IF(lineu.signUpMode=2,'校工会',un.name) AS unionName, lot.lotName, + COALESCE((SELECT outsideQuota FROM the_rapy_recuperation_config LIMIT 1),0) AS minimumGroupSize, + COUNT(DISTINCT enroll.loginName) AS lineNum, + IF(COALESCE((SELECT familyInfo FROM the_rapy_recuperation_config LIMIT 1),1)=2, + (SELECT COUNT(1) FROM the_rapy_recuperation_enroll_companion c WHERE c.trreId IN + (SELECT e.id FROM the_rapy_recuperation_enroll e WHERE e.takePartInLineId=lineu.id AND e.stateId=2750 AND e.isNormal=true)), + COALESCE(SUM(enroll.familyNumber),0)) AS signUpUserFamilyNum + FROM the_rapy_recuperation_line_union_select lineu + 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 agency ON agency.id=lineu.travelAgencyId + LEFT JOIN sys_union un ON un.id=lineu.unionId + LEFT JOIN the_rapy_recuperation_enroll enroll ON enroll.takePartInLineId=lineu.id AND enroll.stateId=2750 AND enroll.isNormal=true + $condition + """); + Cnd cnd = Cnd.where("YEAR(lineu.selectTime)", ">=", startYear).and("YEAR(lineu.selectTime)", "<=", endYear); + cnd.andEX("lineu.signUpMode", "=", signUpMode).andEX("line.lotId", "=", lotId) + .andEX("line.id", "=", lineId).andEX("lineu.id", "=", selectId).andEX("line.regionalNature", "=", regionalNature); + if (AuthUtil.hasRoleOr("sysadmin", "H06", "A06")) cnd.andEX("lineu.unionId", "=", unionId); + else cnd.and("lineu.unionId", "=", SecurityUtil.getUnionId()); + cnd.groupBy("lineu.id", "line.id", "line.lineName", "line.regionalNature", "lineu.signUpMode", + "lineu.selectTime", "lineu.playStartTime", "lineu.playEndTime", "agency.travelAgencyName", + "agency.contact", "agency.contactMobileNumber", "un.name", "lot.lotName"); + cnd.asc("line.serialNumber").asc("lineu.playStartTime"); + sql.setCondition(cnd); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @Override + public Pagination userPage(PageForm pageForm, String lineSelectId, String searchKeyword, String unionId, String unitId) { + Sql sql = Sqls.create(""" + SELECT enroll.*, line.lineName, + CONCAT(DATE_FORMAT(lineu.playStartTime,'%m月%d日'),'-',DATE_FORMAT(lineu.playEndTime,'%m月%d日')) AS linePlayTime, + (SELECT COUNT(1) FROM the_rapy_recuperation_enroll_companion WHERE trreId=enroll.id) AS familyCount + 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 + $condition + """); + Cnd cnd = Cnd.where("enroll.takePartInLineId", "=", lineSelectId).and("enroll.stateId", "=", 2750).and("enroll.isNormal", "=", true); + cnd.andEX("enroll.selfUnionId", "=", unionId).andEX("enroll.selfUnitId", "=", unitId); + if (StrUtil.isNotBlank(searchKeyword)) cnd.and(Cnd.exps("enroll.loginName", "like", "%" + searchKeyword + "%").or("enroll.userName", "like", "%" + searchKeyword + "%")); + cnd.desc("enroll.signingUptime").desc("enroll.unitName"); + sql.setCondition(cnd); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @Override + public List lineOptions(Integer startYear, Integer endYear, String signUpMode, String regionalNature) { + Sql sql = Sqls.create(""" + SELECT DISTINCT line.id, line.lineName, line.regionalNature, lot.lotName, + IF(lineu.signUpMode=1,'分工会组织','校工会组织') AS signUpMode + FROM the_rapy_recuperation_line_union_select lineu + LEFT JOIN the_rapy_recuperation_line line ON line.id=lineu.lineId + LEFT JOIN the_rapy_recuperation_lot lot ON lot.id=line.lotId + $condition + """); + Cnd cnd = Cnd.where("YEAR(lineu.selectTime)", ">=", startYear).and("YEAR(lineu.selectTime)", "<=", endYear) + .andEX("lineu.signUpMode", "=", signUpMode).andEX("line.regionalNature", "=", regionalNature); + if (!AuthUtil.hasRoleOr("sysadmin", "H06", "A06")) cnd.and("lineu.unionId", "=", SecurityUtil.getUnionId()); + cnd.asc("line.serialNumber"); + sql.setCondition(cnd); + return listMap(sql); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationProvinceFlexibleGroupServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationProvinceFlexibleGroupServiceImpl.java index 62c4c77..6961996 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationProvinceFlexibleGroupServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/recuperation/service/impl/RecuperationProvinceFlexibleGroupServiceImpl.java @@ -8,6 +8,7 @@ import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.staffbenefit.recuperation.constant.RecuperationState; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll; +import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnrollCompanion; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationProvinceFlexibleGroup; import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationTravelAgency; import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationProvinceFlexibleGroupService; @@ -376,6 +377,158 @@ public class RecuperationProvinceFlexibleGroupServiceImpl extends BaseServiceImp delete(id); } + @Override + public Pagination queryPage(PageForm pageForm, Integer startYear, Integer endYear, String groupName, + String travelAgencyId, String searchKeyword) { + Sql sql = Sqls.create(""" + SELECT fg.id, fg.groupName, fg.year, ta.travelAgencyName, + COUNT(DISTINCT CASE WHEN enroll.groupLeaderUserId IS NOT NULL AND enroll.groupLeaderUserId <> '' + THEN enroll.groupLeaderUserId WHEN enroll.groupLeaderLoginName IS NOT NULL + AND enroll.groupLeaderLoginName <> '' THEN enroll.groupLeaderLoginName END) AS groupCount, + COUNT(DISTINCT enroll.loginName) AS signCount + FROM the_rapy_recuperation_province_flexible_group fg + LEFT JOIN the_rapy_recuperation_travel_agency ta ON ta.id = fg.travelAgencyId + LEFT JOIN the_rapy_recuperation_enroll enroll + ON enroll.takePartInTravelAgencyId = fg.travelAgencyId + AND YEAR(enroll.signingUptime) = fg.year + AND enroll.isNormal = true + AND (enroll.stateId IS NULL OR enroll.stateId NOT IN (2715,2725,2735)) + $condition + """); + Cnd cnd = Cnd.where("ta.signUpTravelAgency", "=", true); + cnd.andEX("fg.year", ">=", startYear).andEX("fg.year", "<=", endYear); + cnd.andEX("fg.travelAgencyId", "=", travelAgencyId); + cnd.and(Cnd.likeEX("fg.groupName", groupName)); + if (StrUtil.isNotBlank(searchKeyword)) { + cnd.and(Cnd.exps("enroll.userName", "like", "%" + searchKeyword + "%") + .or("enroll.loginName", "like", "%" + searchKeyword + "%")); + } + if (!AuthUtil.hasRoleOr("sysadmin", "A06") && AuthUtil.hasRoleOr("H04")) { + cnd.and("fg.createUnionId", "=", SecurityUtil.getUnionId()); + } + cnd.groupBy("fg.id", "fg.groupName", "fg.year", "ta.travelAgencyName"); + cnd.desc("fg.year").asc("fg.groupName"); + sql.setCondition(cnd); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @Override + public List queryGroupInfo(String groupId) { + Sql sql = Sqls.create(""" + SELECT enroll.groupLeaderUserId, enroll.groupLeaderUserName, enroll.groupLeaderLoginName, + MAX(CASE WHEN enroll.loginName = enroll.groupLeaderLoginName THEN enroll.groupLeaderPassword ELSE '' END) AS groupLeaderPassword, + COUNT(DISTINCT enroll.loginName) AS userCount + FROM the_rapy_recuperation_enroll enroll + WHERE enroll.takePartInTravelAgencyId = (SELECT travelAgencyId FROM the_rapy_recuperation_province_flexible_group WHERE id=@groupId) + AND YEAR(enroll.signingUptime) = (SELECT year FROM the_rapy_recuperation_province_flexible_group WHERE id=@groupId) + AND enroll.isNormal = true AND (enroll.stateId IS NULL OR enroll.stateId NOT IN (2715,2725,2735)) + GROUP BY enroll.groupLeaderUserId, enroll.groupLeaderUserName, enroll.groupLeaderLoginName + ORDER BY enroll.groupLeaderUserName, enroll.groupLeaderLoginName + """); + sql.setParam("groupId", groupId); + return listMap(sql); + } + + @Override + public Pagination querySignUsers(PageForm pageForm, String groupId, String groupLeaderUserId, + String groupLeaderLoginName, Boolean noGroupLeader) { + StringBuilder condition = new StringBuilder(); + if (isValidGroupLeaderParam(groupLeaderUserId)) { + condition.append(" AND enroll.groupLeaderUserId=@groupLeaderUserId"); + } else if (isValidGroupLeaderParam(groupLeaderLoginName)) { + condition.append(" AND enroll.groupLeaderLoginName=@groupLeaderLoginName"); + } else if (Boolean.TRUE.equals(noGroupLeader)) { + condition.append(" AND (enroll.groupLeaderUserId IS NULL OR enroll.groupLeaderUserId='')"); + } + String sqlText = """ + SELECT enroll.id, enroll.loginName, enroll.userName, + CASE WHEN enroll.loginName = enroll.groupLeaderLoginName THEN '团长' ELSE '队员' END AS identity, + enroll.unionName, enroll.unitName, enroll.sex, enroll.mobile, + (SELECT COUNT(1) FROM the_rapy_recuperation_enroll_companion WHERE trreId=enroll.id) AS isFamily + FROM the_rapy_recuperation_enroll enroll + WHERE enroll.takePartInTravelAgencyId=(SELECT travelAgencyId FROM the_rapy_recuperation_province_flexible_group WHERE id=@groupId) + AND YEAR(enroll.signingUptime)=(SELECT year FROM the_rapy_recuperation_province_flexible_group WHERE id=@groupId) + AND enroll.isNormal=true + AND (enroll.stateId IS NULL OR enroll.stateId NOT IN ($auditFailStates)) + $condition + ORDER BY CASE WHEN enroll.loginName=enroll.groupLeaderLoginName THEN 0 ELSE 1 END, enroll.signingUptime + """; + // 动态团长条件必须在创建 Sql 前拼入,确保 Nutz 能识别对应参数占位符。 + Sql sql = Sqls.create(sqlText.replace("$condition", condition.toString())) + .setParam("groupId", groupId) + .setParam("groupLeaderUserId", groupLeaderUserId) + .setParam("groupLeaderLoginName", groupLeaderLoginName) + .setVar("auditFailStates", RecuperationState.UNITFAIL + "," + RecuperationState.LINEUNITFAIL + "," + RecuperationState.SCHOOLFAIL); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + /** 过滤浏览器可能传入的 undefined/null 文本,避免错误命中团长条件。 */ + private boolean isValidGroupLeaderParam(String value) { + return StrUtil.isNotBlank(value) && !"undefined".equalsIgnoreCase(value) && !"null".equalsIgnoreCase(value); + } + + @Override + public List queryTravelAgencyOptions(Integer startYear, Integer endYear) { + Sql sql = Sqls.create(""" + SELECT DISTINCT ta.id, ta.travelAgencyName, ta.serialNumber + FROM the_rapy_recuperation_province_flexible_group fg + LEFT JOIN the_rapy_recuperation_travel_agency ta ON ta.id=fg.travelAgencyId + WHERE ta.id IS NOT NULL AND ta.isDisabled=false AND ta.signUpTravelAgency=true + AND fg.year>=@startYear AND fg.year<=@endYear + ORDER BY ta.serialNumber * 1, ta.travelAgencyName + """); + sql.setParam("startYear", startYear).setParam("endYear", endYear); + return listMap(sql); + } + + @Override + public List queryFlexibleGroupOptions(Integer startYear, Integer endYear) { + Sql sql = Sqls.create(""" + SELECT fg.id, fg.groupName FROM the_rapy_recuperation_province_flexible_group fg + LEFT JOIN the_rapy_recuperation_travel_agency ta ON ta.id=fg.travelAgencyId + WHERE ta.signUpTravelAgency=true AND fg.year>=@startYear AND fg.year<=@endYear ORDER BY fg.groupName + """); + sql.setParam("startYear", startYear).setParam("endYear", endYear); + return listMap(sql); + } + + @Override + public List queryExportUsers(Integer startYear, Integer endYear, String groupName, + String travelAgencyId, String searchKeyword) { + Sql sql = Sqls.create(""" + SELECT enroll.loginName, enroll.userName, enroll.mobile, enroll.idCard, enroll.unitName, enroll.unionName, + ta.travelAgencyName, DATE_FORMAT(enroll.signingUptime,'%Y-%m-%d %H:%i:%s') AS signingUptime, + CONCAT(IFNULL(enroll.groupLeaderUserName,''), IF(enroll.groupLeaderLoginName IS NULL OR enroll.groupLeaderLoginName='', '', CONCAT('(',enroll.groupLeaderLoginName,')'))) AS leaderName, + CASE WHEN (SELECT COUNT(DISTINCT sameLeader.loginName) FROM the_rapy_recuperation_enroll sameLeader + WHERE sameLeader.takePartInTravelAgencyId=enroll.takePartInTravelAgencyId + AND sameLeader.groupLeaderLoginName=enroll.groupLeaderLoginName AND sameLeader.isNormal=true + AND YEAR(sameLeader.signingUptime)=YEAR(enroll.signingUptime))>=3 THEN '已成团' ELSE '未成团' END AS formedTeamState + FROM the_rapy_recuperation_enroll enroll + LEFT JOIN the_rapy_recuperation_travel_agency ta ON ta.id=enroll.takePartInTravelAgencyId + LEFT JOIN the_rapy_recuperation_province_flexible_group fg ON fg.travelAgencyId=enroll.takePartInTravelAgencyId AND fg.year=YEAR(enroll.signingUptime) + $condition + """); + Cnd cnd = Cnd.where("fg.year", ">=", startYear).and("fg.year", "<=", endYear) + .and("enroll.isNormal", "=", true); + cnd.andEX("fg.travelAgencyId", "=", travelAgencyId).and(Cnd.likeEX("fg.groupName", groupName)); + if (StrUtil.isNotBlank(searchKeyword)) { + cnd.and(Cnd.exps("enroll.userName", "like", "%" + searchKeyword + "%").or("enroll.loginName", "like", "%" + searchKeyword + "%")); + } + if (!AuthUtil.hasRoleOr("sysadmin", "A06") && AuthUtil.hasRoleOr("H04")) cnd.and("fg.createUnionId", "=", SecurityUtil.getUnionId()); + cnd.asc("fg.year").asc("ta.serialNumber * 1").asc("enroll.groupLeaderUserName").asc("enroll.signingUptime"); + sql.setCondition(cnd); + List list = listMap(sql); + for (int i = 0; i < list.size(); i++) list.get(i).setv("no", i + 1); + return list; + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void deleteJoinUser(String id) { + dao().clear(RecuperationEnrollCompanion.class, Cnd.where("trreId", "=", id)); + dao().clear(RecuperationEnroll.class, Cnd.where("id", "=", id)); + } + /** * 查询旅行社编辑页中“是否灵活组团”为是且未禁用的旅行社。 * diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/annualAnalysis/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/annualAnalysis/index.html index 0a4cda7..f3a1529 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/annualAnalysis/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/annualAnalysis/index.html @@ -167,15 +167,16 @@ layout("/layouts/platform.html"){ } }, methods: { - async getNumData(){ - const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getNumData', this.pageForm) + getNumData(){ + return this.$axios.post('/platform/recuperation/annualAnalysis/getNumData', this.pageForm).then((resp) => { if (resp.code === 0) { - this.numData = resp.data + this.$set(this, 'numData', resp.data) } + }) }, - async getLotNumData(){ - this.lotLoading = true - const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getLotNum', this.pageForm) + getLotNumData(){ + this.$set(this, 'lotLoading', true) + return this.$axios.post('/platform/recuperation/annualAnalysis/getLotNum', this.pageForm).then((resp) => { if (resp.code === 0) { let {data} = resp document.getElementById("lotChart").innerHTML = '' @@ -231,12 +232,12 @@ layout("/layouts/platform.html"){ ...config, }); plot.render(); - this.lotLoading = false } + }).finally(() => { this.$set(this, 'lotLoading', false) }) }, - async getAgeData(){ - this.ageLoading = true - const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getAgeNum', this.pageForm) + getAgeData(){ + this.$set(this, 'ageLoading', true) + return this.$axios.post('/platform/recuperation/annualAnalysis/getAgeNum', this.pageForm).then((resp) => { if (resp.code === 0) { let {data} = resp document.getElementById("ageChart").innerHTML = '' @@ -268,14 +269,14 @@ layout("/layouts/platform.html"){ ...config, }); plot.render(); - this.ageLoading = false } + }).finally(() => { this.$set(this, 'ageLoading', false) }) }, - async getLineTravelData(){ + getLineTravelData(){ if (this.dualAxisChartInstance) { this.dualAxisChartInstance.destroy(); // 如果已有实例,先销毁 } - const resp = await this.$axios.post('/platform/recuperation/annualAnalysis/getLineTravelAndAgeData', this.pageForm) + return this.$axios.post('/platform/recuperation/annualAnalysis/getLineTravelAndAgeData', this.pageForm).then((resp) => { if (resp.code === 0) { let {data} = resp document.getElementById("lineTravelChart").innerHTML = '' @@ -326,24 +327,24 @@ layout("/layouts/platform.html"){ }); dualAxes.render(); } + }) }, doLineTravelOrAgeSwitch(){ - this.isLineTravel = !this.isLineTravel - this.lineTravelOrAgeTip = this.isLineTravel ? '出行线路年龄统计' : '出行线路人数统计' + this.$set(this, 'isLineTravel', !this.isLineTravel) + this.$set(this, 'lineTravelOrAgeTip', this.isLineTravel ? '出行线路年龄统计' : '出行线路人数统计') }, - async initData(){ - await this.getNumData() - await this.getLotNumData() - await this.getAgeData() - await this.getLineTravelData() + initData(){ + this.getNumData() + this.getLotNumData() + this.getAgeData() + this.getLineTravelData() }, - async getEnumOptions(enumName) { - const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: enumName }) - return resp.data + getEnumOptions(enumName) { + return this.$axios.post("/open/common/dictEnumOptions", { name: enumName }).then((resp) => resp.data || []) }, }, - async created() { - this.regionalNatureList.push(...await this.getEnumOptions('RecuperationProvinceType')) + created() { + this.getEnumOptions('RecuperationProvinceType').then((res) => this.$set(this, 'regionalNatureList', this.regionalNatureList.concat(res))) this.initData() } }) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/audit/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/audit/index.html index d2ee6ec..f67424e 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/audit/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/audit/index.html @@ -1,11 +1,73 @@
- - - {{viewData.loginName}}{{viewData.userName}}{{viewData.idCard}}{{viewData.mobile}}{{viewData.lineName}}{{viewData.travelAgencyName}} - + + + + + + + + + + + + + 一键通过 + 一键拒绝 + + + + + + + + + + + + + + + + + + + {{viewData.loginName}}{{viewData.userName}} + {{viewData.idCard}}{{viewData.mobile}} + {{viewData.unitName}}{{viewData.unionName}} + {{viewData.lineName}}{{viewData.travelAgencyName}} + + + + + + +
本次将{{auditForm.pass?'通过':'拒绝'}} {{auditCount}} 条报名记录。
+ + +
diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/editForm.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/editForm.js index 79a0551..6a180d9 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/editForm.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/editForm.js @@ -121,48 +121,51 @@ const editForm = { } }, methods: { - async onOpen(id, year) { - this.year = year - this.visible = true - await this.getUnionSelectLine() - await this.getModifyConfig() - const {code, msg, data} = await this.$axios.get("/platform/recuperation/branchUnionUserQuery/findOne", {id}) + onOpen(id, year) { + this.$set(this, 'year', year) + this.$set(this, 'visible', true) + Promise.all([this.getUnionSelectLine(),this.getModifyConfig()]).then(() => this.$axios.get("/platform/recuperation/branchUnionUserQuery/findOne", {id})).then((res) => { + const {code, msg, data} = res if (code === 0) { - this.formData = data + this.$set(this, 'formData', data) if (this.config.familyInfo === 2) { this.labelName = "家属信息" } else { - this.formData.bedType = data.familyNumber - this.labelName = "家属数量" + this.$set(this.formData, 'bedType', data.familyNumber) + this.$set(this, 'labelName', "家属数量") } } else { this.$message.error(msg) } + }) }, - async getModifyConfig() { - const {code, data, msg} = await this.$axios.post('/platform/recuperation/config/fetchOne') + getModifyConfig() { + return this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => { + const {code, data, msg} = res if (code === 0) { - this.config = data + this.$set(this, 'config', data) } else { this.$message.error(msg) } + }) }, - async getUnionSelectLine() { - const resp = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/getUnionSelectLine', { + getUnionSelectLine() { + return this.$axios.post('/platform/recuperation/schoolUnionUserQuery/getUnionSelectLine', { year: this.year, signUpMode: 1, - }) + }).then((resp) => { if (resp.code === 0) { - this.unionSelectLines = resp.data + this.$set(this, 'unionSelectLines', resp.data) } + }) }, - async validateLine() { - const resp = await this.$axios.post('/platform/recuperation/line/enroll/validSignUpInfo' - , {enroll: JSON.stringify(this.formData)}) + validateLine() { + this.$axios.post('/platform/recuperation/line/enroll/validSignUpInfo', {enroll: JSON.stringify(this.formData)}).then((resp) => { if (resp.code !== 0) { this.$message.warning(resp.msg) - this.formData.takePartInLineId = '' + this.$set(this.formData, 'takePartInLineId', '') } + }) }, onSubmit() { this.$refs.formRef.validate((valid) => { @@ -171,19 +174,21 @@ const editForm = { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' - }).then(async () => { + }).then(() => { if (!this.formData.takePartInLineId && !this.formData.takePartInBaseManagementId) { this.$message.warning('请选择线路') return } - const {code, msg} = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/doEdit', this.formData) + return this.$axios.post('/platform/recuperation/schoolUnionUserQuery/doEdit', this.formData).then((res) => { + const {code, msg} = res if (code === 0) { this.$message.success(msg) - this.visible = false + this.$set(this, 'visible', false) this.$emit('refresh') } else { this.$message.error(msg) } + }) }).catch() } }) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/index.html index 4d9ecdd..41891ba 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/index.html @@ -313,10 +313,10 @@ layout("/layouts/platform.html"){ cancelButtonText: '取消', dangerouslyUseHTMLString: true, type: 'warning' - }).then(async () => { - const {code, msg} = await this.$axios.post('/platform/recuperation/branchUnionUserQuery/deleteMyEnrollInfoById', { + }).then(() => this.$axios.post('/platform/recuperation/branchUnionUserQuery/deleteMyEnrollInfoById', { id: row.id - }) + })).then((res) => { + const {code, msg} = res if (code === 0) { this.doSearch() this.$message.success(msg) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/setUpPart.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/setUpPart.js index b3cdb07..4aefa44 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/setUpPart.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/branchUnionUserQuery/setUpPart.js @@ -61,11 +61,12 @@ const setUpPart = { this.tableData = JSON.parse(JSON.stringify(selection)) this.getModifyConfig() }, - async getModifyConfig() { - const res = await this.$axios.post('/platform/recuperation/config/fetchOne') + getModifyConfig() { + this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => { if (res.code === 0) { - this.config = res.data + this.$set(this, 'config', res.data) } + }) }, lotChange(val) { const selection = this.$refs.tableRef.selection @@ -119,12 +120,12 @@ const setUpPart = { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' - }).then(async res => { - const {code, msg} = await this.$axios.post("/platform/recuperation/branchUnionUserQuery/setUpParticipants", {data: JSON.stringify(data)}) + }).then(() => this.$axios.post("/platform/recuperation/branchUnionUserQuery/setUpParticipants", {data: JSON.stringify(data)})).then((res) => { + const {code, msg} = res if (code === 0) { this.$message.success(msg) this.$refs.tableRef.clearSelection() - this.visible = false + this.$set(this, 'visible', false) } else { this.$message.error(msg) } diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/common/enrollInfo.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/common/enrollInfo.js index 9ab5ea8..9fe91db 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/common/enrollInfo.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/common/enrollInfo.js @@ -88,29 +88,24 @@ const enrollInfo = { } }, methods: { - async onOpen(id) { - await this.findOne(id) + onOpen(id) { + return this.findOne(id) }, - async findOne(id) { - this.loading = true - const resp = await this.$axios.post("/platform/recuperation/branchUnionAudit/findOne", {id}) - this.loading = false - if (resp.code === 0) { - this.viewData = resp.data.viewData - } else { - this.viewData = {} - this.$message.error(resp.msg) - } + findOne(id) { + this.$set(this, 'loading', true) + return this.$axios.post("/platform/recuperation/branchUnionAudit/findOne", {id}).then((resp) => { + if (resp.code === 0) this.$set(this, 'viewData', resp.data.viewData) + else { this.$set(this, 'viewData', {}); this.$message.error(resp.msg) } + }).finally(() => { this.$set(this, 'loading', false) }) }, - async getModifyConfig() { - const res = await this.$axios.post('/platform/recuperation/config/fetchOne') - if (res.code === 0) { - this.modifyConfig = res.data - } + getModifyConfig() { + return this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => { + if (res.code === 0) this.$set(this, 'modifyConfig', res.data) + }) }, }, - async created() { - await this.getModifyConfig() + created() { + this.getModifyConfig() }, style: /*language=CSS*/ ` .panel-heading { diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/config/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/config/index.html index 14ea974..b122cde 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/config/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/config/index.html @@ -49,12 +49,12 @@ layout("/layouts/platform.html"){ - + + placeholder="请输入最少成团人数"> - + @@ -90,6 +90,34 @@ layout("/layouts/platform.html"){ v-model.number="formData.modifyNumber"> + + + + + + + + + + + + + 需要 @@ -104,15 +132,49 @@ layout("/layouts/platform.html"){ + + + 需要 + 不需要 + + + + + + 固定比例分配 + 分工会单独分配 + + + + + 设置分工会比例 + 已设置 {{formData.unionLimit.length}} 个分工会 + + + + + + + + + + + + - + @@ -220,6 +282,11 @@ layout("/layouts/platform.html"){ ref="drawerUserScope" :group_id.sync="formData.activityGroupId" > + +
%统一设置当前合计:{{unionLimitTotal}}%
+ + +
+ diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/joinUserImport/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/joinUserImport/index.html index 501d822..9b86f77 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/joinUserImport/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/joinUserImport/index.html @@ -1,9 +1,23 @@
- 上传参加人员 Excel下载模板 - 确认标记参加 + +
导入实际参加人员
+ +
+ + + + +
+
上一步{{stepActive===3?'完成':'下一步'}}
+
diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineAdjustment/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineAdjustment/index.html index aa6b4d3..1c4b1d5 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineAdjustment/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineAdjustment/index.html @@ -1,10 +1,54 @@
- - - + + + + + + + + + + + + + + + + + + + + + + + + +
+ 调出所选人员 + 恢复所选人员 + 发送未成团提醒 +
+ + + + +
diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineCluster/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineCluster/index.html index 1018bae..808acba 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineCluster/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineCluster/index.html @@ -1,15 +1,35 @@
- + - - + + - + +
添加团人员可通过“移动到”分配到团;每团只能设置一名团长。
+ +
未分配人员({{unSelectedUsers.length}})批量调整
+
删除团
+
+ +
+ {{unSelectedSelection.length}} +
diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/batchSelect.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/batchSelect.js index 267d7ea..f0a37a1 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/batchSelect.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/batchSelect.js @@ -183,34 +183,15 @@ const batchSelect = { } this.setLineTimeDialog = true }, - async onSelect() { - const valid = await this.$refs['form'].validate() - if (!valid) return - const confirm = await this.$confirm('请再次确认,是否为选择线路统赋时间?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' + onSelect() { + this.$refs['form'].validate((valid) => { + if (!valid) return + this.$confirm('请再次确认,是否为选择线路统赋时间?', '提示', {confirmButtonText:'确定',cancelButtonText:'取消',type:'warning'}).then(() => { + const lineIds=this.multipleSelection.map((item)=>item.id) + const fmtData=this.formData.times.map((item)=>Object.assign({},item,{signUpMode:this.formData.signUpMode,mode:GetQueryString('mode')})) + return this.$axios.post(loc() + '/setGiveLineTimes', {lineIds:JSON.stringify(lineIds),lineUnionSelects:JSON.stringify(fmtData),year:this.year}) + }).then((resp)=>{if(resp.code===0){this.$set(this,'setLineTimeDialog',false);this.$message.success(resp.msg)}else this.$message.warning(resp.msg)}).catch(()=>{}) }) - if (confirm !== 'confirm') return - const lineIds = this.multipleSelection.map(v => v.id) - const fmtData = this.formData.times.map(v => { - return { - ...v, - signUpMode: this.formData.signUpMode, - mode: GetQueryString('mode') - } - }) - const resp = await this.$axios.post(loc() + '/setGiveLineTimes', { - lineIds: JSON.stringify(lineIds), - lineUnionSelects: JSON.stringify(fmtData), - year: this.year - }) - if (resp.code === 0) { - this.setLineTimeDialog = false - this.$message.success(resp.msg) - } else { - this.$message.warning(resp.msg) - } }, }, async created() { diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/index.html index bafa707..324a213 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/index.html @@ -236,21 +236,15 @@ layout("/layouts/platform.html"){ } }, methods: { - async cancelSelect({applyCount, id: lineId, usUnionId: unionId}) { + cancelSelect({applyCount, id: lineId, usUnionId: unionId}) { const msg = applyCount > 0 ? '已经有教工选择本线路,请确认是否取消选择本线路,一旦取消将清空报名人员!!!' : '您确定要取消吗?' - const confirm = await this.$confirm(msg, '提示', { + this.$confirm(msg, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' - }) - if (confirm !== 'confirm') return - const resp = await this.$axios.post('/platform/recuperation/lineSelect/deSelect', {lineId, unionId}) - if (resp.code === 0) { - this.doSearch() - this.$message.success(resp.msg) - } else { - this.$message.warning(resp.msg) - } + }).then(() => this.$axios.post('/platform/recuperation/lineSelect/deSelect', {lineId, unionId})) + .then((resp) => { if (resp.code === 0) { this.doSearch(); this.$message.success(resp.msg) } else this.$message.warning(resp.msg) }) + .catch(() => {}) }, refresh() { this.doSearch() @@ -284,25 +278,23 @@ layout("/layouts/platform.html"){ } }) }, - async getTravelAgencyOptions() { - const {data} = await this.$axios.post('/platform/recuperation/lineSelect/getTravelAgencyOptions') - this.travelAgencyOptions = data + getTravelAgencyOptions() { + return this.$axios.post('/platform/recuperation/lineSelect/getTravelAgencyOptions').then((res) => this.$set(this, 'travelAgencyOptions', res.data || [])) }, - async getEnumOptions(enumName) { - const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: enumName }) - return resp.data + getEnumOptions(enumName) { + return this.$axios.post("/open/common/dictEnumOptions", { name: enumName }).then((resp) => resp.data || []) }, }, - async created() { + created() { this.$set(this.pageForm, 'mode', Number(`${mode}`)) if(this.pageForm.mode === 2) { this.$set(this.pageForm, 'regionalNature', '全部') } - this.unionList = await this.$businessTool.listUnion() - this.createModeList = await this.getEnumOptions('RecuperationLineCreateMode') - this.signUpModeList = await this.getEnumOptions('RecuperationSignUpMode') - this.regionalNatureList.push(...await this.getEnumOptions('RecuperationProvinceType')) - this.travelAgencyOptions = this.getTravelAgencyOptions() + this.$businessTool.listUnion().then((res) => this.$set(this, 'unionList', res || [])) + this.getEnumOptions('RecuperationLineCreateMode').then((res) => this.$set(this, 'createModeList', res)) + this.getEnumOptions('RecuperationSignUpMode').then((res) => this.$set(this, 'signUpModeList', res)) + this.getEnumOptions('RecuperationProvinceType').then((res) => this.$set(this, 'regionalNatureList', this.regionalNatureList.concat(res))) + this.getTravelAgencyOptions() this.pageData() } }) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/select.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/select.js index 2238e18..b577b4a 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/select.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/select.js @@ -253,22 +253,20 @@ const select = { doSetChangeTime(index, value){ this.$set(this.formData.times[index], "changeEndTime", value) }, - async getLineConfig(lineId) { - const {data} = await this.$axios.post(loc() + '/getLineConfig/' + lineId) - this.lineConfig = data + getLineConfig(lineId) { + return this.$axios.post(loc() + '/getLineConfig/' + lineId).then((res) => this.$set(this, 'lineConfig', res.data || {})) }, - async onOpen(id, lineName, usUnionId, signUpMode, year) { - await this.getLineConfig(id) - const resp = await this.$axios.post(loc() + '/selectLineInfo', { + onOpen(id, lineName, usUnionId, signUpMode, year) { + this.getLineConfig(id).then(() => this.$axios.post(loc() + '/selectLineInfo', { lineId: id, unionId: usUnionId, mode: GetQueryString('mode'), year: year - }) - if (resp.code === 0 && resp.data) { - this.formData = { + })).then((resp) => { + if (resp.code === 0 && resp.data) { + this.$set(this, 'formData', { times: [] - } + }) if (resp.data && resp.data.length > 0) { this.$set(this.formData, 'times', resp.data) } else { @@ -278,42 +276,26 @@ const select = { estimatedCost: this.lineConfig.cost }) } - this.formData.lineId = id - this.formData.signUpMode = signUpMode + this.$set(this.formData, 'lineId', id) + this.$set(this.formData, 'signUpMode', signUpMode) this.$set(this.formData, 'lineName', lineName) - this.setLineTimeDialog = true + this.$set(this, 'setLineTimeDialog', true) } else { this.$message.warning(resp.msg) } + }) }, - async onSelect() { - const valid = await this.$refs['form'].validate() - if (!valid) return - const confirm = await this.$confirm('请再次确认,是否选择此线路为疗休养线路?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' + onSelect() { + this.$refs['form'].validate((valid) => { + if (!valid) return + this.$confirm('请再次确认,是否选择此线路为疗休养线路?', '提示', {confirmButtonText:'确定',cancelButtonText:'取消',type:'warning'}).then(() => { + const fmtData=this.formData.times.map((item)=>Object.assign({},item,{lineId:this.formData.lineId,signUpMode:this.formData.signUpMode,mode:GetQueryString('mode')})) + return this.$axios.post(loc() + '/selectLineTimes', {lineSelects: JSON.stringify(fmtData)}) + }).then((resp) => { if (resp.code === 0) { this.$set(this,'setLineTimeDialog',false);this.$emit('refresh');this.$message.success(resp.msg) } else this.$message.warning(resp.msg) }).catch(()=>{}) }) - if (confirm !== 'confirm') return - const fmtData = this.formData.times.map(v => { - return { - ...v, - lineId: this.formData.lineId, - signUpMode: this.formData.signUpMode, - mode: GetQueryString('mode') - } - }) - const resp = await this.$axios.post(loc() + '/selectLineTimes', {lineSelects: JSON.stringify(fmtData)}) - if (resp.code === 0) { - this.setLineTimeDialog = false - this.$emit('refresh') - this.$message.success(resp.msg) - } else { - this.$message.warning(resp.msg) - } }, }, - async created() { + created() { }, style: /*language=CSS*/ ` diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/timeInfo.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/timeInfo.js index 682f03d..4d3ebb8 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/timeInfo.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineSelect/timeInfo.js @@ -76,19 +76,16 @@ const timeInfo = { } }, methods: { - async onOpen(id, usUnionId, year) { - const resp = await this.$axios.post(loc() + '/selectLineInfo', { + onOpen(id, usUnionId, year) { + this.$axios.post(loc() + '/selectLineInfo', { lineId: id, unionId: usUnionId, mode: GetQueryString('mode'), year: year + }).then((resp) => { + if (resp.code === 0) { this.$set(this, 'timeLots', resp.data); this.$set(this, 'timeLotsDialogVisible', true) } + else this.$message.warning(resp.msg) }) - if (resp.code === 0) { - this.timeLots = resp.data - this.timeLotsDialogVisible = true - } else { - this.$message.warning(resp.msg) - } }, }, style: /*language=CSS*/ ` diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineStatistics/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineStatistics/index.html new file mode 100644 index 0000000..79ebcbe --- /dev/null +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/lineStatistics/index.html @@ -0,0 +1,26 @@ + +
+ + + + + + + + + + + + +
查询
+
+ + diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/editForm.js b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/editForm.js index 840aa74..8b2d05d 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/editForm.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/editForm.js @@ -121,48 +121,36 @@ const editForm = { } }, methods: { - async onOpen(id, year) { + onOpen(id, year) { this.year = year this.visible = true - await this.getUnionSelectLine() - await this.getModifyConfig() - const {code, msg, data} = await this.$axios.post("/platform/recuperation/schoolUnionUserQuery/findOne", {id}) - if (code === 0) { - this.formData = data - if (this.config.familyInfo === 2) { - this.labelName = "家属信息" - } else { - this.formData.bedType = data.familyNumber - this.labelName = "家属数量" - } - } else { - this.$message.error(msg) - } + Promise.all([this.getUnionSelectLine(), this.getModifyConfig()]).then(() => { + this.$axios.post(queryBase + "/findOne", {id}).then((res) => { + if (res.code === 0) { + this.formData = res.data + if (this.config.familyInfo === 2) this.labelName = "家属信息" + else { this.$set(this.formData, "bedType", res.data.familyNumber); this.labelName = "家属数量" } + } else this.$message.error(res.msg) + }) + }) }, - async getModifyConfig() { - const {code, data, msg} = await this.$axios.post('/platform/recuperation/config/fetchOne') - if (code === 0) { - this.config = data - } else { - this.$message.error(msg) - } + getModifyConfig() { + return this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => { + if (res.code === 0) this.config = res.data + else this.$message.error(res.msg) + }) }, - async getUnionSelectLine() { - const resp = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/getUnionSelectLine', { + getUnionSelectLine() { + return this.$axios.post(queryBase + '/getUnionSelectLine', { year: this.year, signUpMode: 1, - }) - if (resp.code === 0) { - this.unionSelectLines = resp.data - } + }).then((resp) => { if (resp.code === 0) this.unionSelectLines = resp.data }) }, - async validateLine() { - const resp = await this.$axios.post('/platform/recuperation/line/enroll/validSignUpInfo' - , {enroll: JSON.stringify(this.formData)}) - if (resp.code !== 0) { - this.$message.warning(resp.msg) - this.formData.takePartInLineId = '' - } + validateLine() { + this.$axios.post('/platform/recuperation/line/enroll/validSignUpInfo', + {enroll: JSON.stringify(this.formData)}).then((resp) => { + if (resp.code !== 0) { this.$message.warning(resp.msg); this.$set(this.formData, 'takePartInLineId', '') } + }) }, onSubmit() { this.$refs.formRef.validate((valid) => { @@ -171,19 +159,15 @@ const editForm = { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' - }).then(async () => { + }).then(() => { if (!this.formData.takePartInLineId && !this.formData.takePartInBaseManagementId) { this.$message.warning('请选择线路') return } - const {code,msg} = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/doEdit', this.formData) - if (code === 0) { - this.$message.success(msg) - this.visible = false - this.$emit('refresh') - } else { - this.$message.error(msg) - } + this.$axios.post(queryBase + '/doEdit', this.formData).then((res) => { + if (res.code === 0) { this.$message.success(res.msg); this.visible = false; this.$emit('refresh') } + else this.$message.error(res.msg) + }) }).catch() } }) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html index 0e3847a..a3c0364 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/recuperation/schoolUnionUserQuery/index.html @@ -71,26 +71,51 @@ layout("/layouts/platform.html"){
- + - - + + - - + + + + + + +
+
+
报名状态
+
+ + 已报名 + 未报名 + 未成团 + + + 全部 + 已参加 + 未参加 + + + 线路 + 灵活组团 + +
+
- +
+
+
报名类型
+
+ + 线路({{categoryCount.xlCount||0}}) + 灵活组团({{categoryCount.lxsCount||0}}) + 定点({{categoryCount.jdCount||0}}) + +
+
+
+ + + + + + + + + + + + + +
区域
@@ -150,13 +202,17 @@ layout("/layouts/platform.html"){ - + 一键提醒 + 参加人员导入 + 导出Zip + 导出未报名人员 导出 - 设置参加人员 @@ -210,11 +266,17 @@ layout("/layouts/platform.html"){ {{row.lotName}} - + @@ -227,11 +289,32 @@ layout("/layouts/platform.html"){ - + + + +
将按当前筛选条件提醒人员,请确认提醒内容。
+ + +
+ + 下载导入模板 + +
将 Excel 文件拖到此处,或点击选择
按参加时间所属年度匹配省外线路报名
+
+ + 查看错误记录 + +
+
- +