移植v3疗休养到这个版本上
This commit is contained in:
+22
-2
@@ -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<String> idList = Arrays.stream(ids.split(",")).map(String::trim)
|
||||
.filter(StrUtil::isNotBlank).collect(Collectors.toList());
|
||||
auditService.auditEnrolls(idList, pass, auditOpinion);
|
||||
return Result.success("审核完成");
|
||||
}
|
||||
}
|
||||
|
||||
+122
-3
@@ -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<String> 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<ExcelExportEntity> 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("导出")
|
||||
|
||||
+40
@@ -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<NutMap> rows = enrollService.satisfactionFeedbackDetails(year, typeName);
|
||||
for (int i = 0; i < rows.size(); i++) rows.get(i).setv("no", i + 1);
|
||||
List<ExcelExportEntity> 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("导出评价统计")
|
||||
|
||||
+117
@@ -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<ExcelExportEntity> 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);
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -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();
|
||||
|
||||
+17
-3
@@ -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("提醒发送失败,请检查消息中心配置");
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -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)) {
|
||||
|
||||
+1
@@ -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) {
|
||||
|
||||
+72
@@ -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));
|
||||
}
|
||||
}
|
||||
+6
@@ -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());
|
||||
|
||||
+190
-2
@@ -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<String> 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<ExcelExportEntity> 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<RecuperationEnrollExcelMode> 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<NutMap> rows = enrollService.managementList(query, false);
|
||||
Map<String, List<NutMap>> 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<String> entryNames = new HashSet<>();
|
||||
try (ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()))) {
|
||||
for (Map.Entry<String, List<NutMap>> 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<ExcelExportEntity> managementExportColumns() {
|
||||
List<ExcelExportEntity> 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("导出")
|
||||
|
||||
+34
@@ -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 端疗休养人员查询参数。
|
||||
*
|
||||
* <p>startYear、endYear 为报名年度范围;signUpStatus 为 0 未报名、1 已报名、2 未成团;
|
||||
* state 为 1 线路、2 灵活组团、3 定点;其余字段分别用于工会、单位、线路、旅行社、
|
||||
* 定点、标段、区域、报名方式、参加状态和报名日期筛选。分页结果返回 Pagination,
|
||||
* list 为人员数据,totalCount 为符合条件的总人数。</p>
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
+5
-1
@@ -41,11 +41,15 @@ public interface RecuperationAuditService extends BaseService<Audit> {
|
||||
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<String> ids, boolean pass, String auditOpinion);
|
||||
}
|
||||
|
||||
+60
@@ -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<RecuperationEnrol
|
||||
NutMap selectLineAllInfo(String usId, String usUnionId);
|
||||
|
||||
List<Sys_union> getUnions(Integer year);
|
||||
|
||||
/**
|
||||
* 查询 PC 管理端疗休养人员。
|
||||
*
|
||||
* @param query 查询参数,包含年度范围、报名状态、报名类型、工会及线路等筛选项
|
||||
* @param currentUnionOnly true 时强制限定为当前登录人的分工会,false 时允许校工会选择分工会
|
||||
* @return 分页结果;list 为报名、未报名或未成团人员,totalCount 为总人数
|
||||
*/
|
||||
Pagination managementPageData(RecuperationUserQueryPageForm query, boolean currentUnionOnly);
|
||||
|
||||
/** 按 PC 查询条件返回全部人员,用于导出;字段与分页列表一致。 */
|
||||
List<NutMap> 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<String> 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<RecuperationEnrollExcelMode> rows);
|
||||
|
||||
/** 按年度统计旅行社及具体方案的满意度评分。 */
|
||||
NutMap satisfactionRatingStatistics(Integer year);
|
||||
|
||||
/** 查询满意度评价明细,typeName 可传线路、灵活组团、定点或全部。 */
|
||||
List<NutMap> satisfactionFeedbackDetails(Integer year, String typeName);
|
||||
}
|
||||
|
||||
+5
-2
@@ -17,7 +17,10 @@ public interface RecuperationLineAdjustmentService extends BaseService<Recuperat
|
||||
/** 查询指定年度可进行人员调整的线路。 */
|
||||
List<?> findLineOptions(Integer year);
|
||||
|
||||
/** 切换指定线路中报名人员的正常/调出状态。 */
|
||||
void adjustmentUsers(String lineId, String[] loginNames);
|
||||
/** 将指定线路报名人员设置为正常或调出状态。 */
|
||||
void adjustmentUsers(String lineId, String[] loginNames, boolean normal);
|
||||
|
||||
/** 向线路调整人员发送未成团提醒,返回是否全部发送成功。 */
|
||||
boolean smsAlerts(String lineId, String[] loginNames);
|
||||
|
||||
}
|
||||
|
||||
+17
@@ -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<NutMap> lineOptions(Integer startYear, Integer endYear, String signUpMode, String regionalNature);
|
||||
}
|
||||
+24
@@ -93,4 +93,28 @@ public interface RecuperationProvinceFlexibleGroupService extends BaseService<Re
|
||||
* @param changeEndTime 变更截至时间
|
||||
*/
|
||||
void batchAssignSignUpTimes(String[] ids, Date signUpStartTime, Date signUpEndTime, Date changeEndTime);
|
||||
|
||||
/** PC 端灵活组团查询列表,返回组团数和报名人数。 */
|
||||
Pagination queryPage(PageForm pageForm, Integer startYear, Integer endYear, String groupName,
|
||||
String travelAgencyId, String searchKeyword);
|
||||
|
||||
/** 查询一个灵活组团下按团长聚合的团列表。 */
|
||||
List<NutMap> queryGroupInfo(String groupId);
|
||||
|
||||
/** 查询灵活组团报名人员;团长参数为空时返回全部人员。 */
|
||||
Pagination querySignUsers(PageForm pageForm, String groupId, String groupLeaderUserId,
|
||||
String groupLeaderLoginName, Boolean noGroupLeader);
|
||||
|
||||
/** 查询年度区间内可用旅行社。 */
|
||||
List<NutMap> queryTravelAgencyOptions(Integer startYear, Integer endYear);
|
||||
|
||||
/** 查询年度区间内的灵活组团选项。 */
|
||||
List<NutMap> queryFlexibleGroupOptions(Integer startYear, Integer endYear);
|
||||
|
||||
/** 按查询条件导出灵活组团报名人员。 */
|
||||
List<NutMap> queryExportUsers(Integer startYear, Integer endYear, String groupName,
|
||||
String travelAgencyId, String searchKeyword);
|
||||
|
||||
/** 删除灵活组团中的一条报名及其家属信息。 */
|
||||
void deleteJoinUser(String id);
|
||||
}
|
||||
|
||||
+20
-3
@@ -161,7 +161,8 @@ public class RecuperationAuditServiceImpl extends BaseServiceImpl<Audit> 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<Audit> 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<Audit> impleme
|
||||
}
|
||||
dao().update(enroll, "^stateId|selfUnionAuditId|joinLineUnionAuditId|schoolUnionAuditId$");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void auditEnrolls(List<String> ids, boolean pass, String auditOpinion) {
|
||||
if (ids == null) return;
|
||||
for (String id : ids) {
|
||||
if (StrUtil.isNotBlank(id)) auditEnroll(id, pass, auditOpinion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+522
@@ -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<RecuperationE
|
||||
private RecuperationBaseManagerService baseManagerService;
|
||||
@Inject
|
||||
private ActivityBasicScopeService activityBasicScopeService;
|
||||
@Inject
|
||||
private SmsService smsService;
|
||||
|
||||
public RecuperationEnrollServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
@@ -1157,4 +1163,520 @@ public class RecuperationEnrollServiceImpl extends BaseServiceImpl<RecuperationE
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<NutMap> 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<NutMap> 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<NutMap> 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<String> 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<String> 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<String> 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<String> selected, Set<String> 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<RecuperationEnroll> 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<RecuperationEnroll> enrolls = lineNoticeEnrolls(lineUnionSelectId);
|
||||
List<String> 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<RecuperationEnroll> 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<RecuperationEnroll> enrolls, boolean keepEnrollRecords) {
|
||||
List<String> 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<String> 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<RecuperationEnrollExcelMode> rows) {
|
||||
List<NutMap> successList = new ArrayList<>();
|
||||
List<NutMap> errorList = new ArrayList<>();
|
||||
List<RecuperationLot> 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<NutMap> 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<NutMap> 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
|
||||
""";
|
||||
}
|
||||
}
|
||||
|
||||
+37
-2
@@ -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<RecuperationEnroll> implements RecuperationLineAdjustmentService {
|
||||
|
||||
@Inject
|
||||
private SmsService smsService;
|
||||
|
||||
public RecuperationLineAdjustmentServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
@@ -159,8 +165,37 @@ public class RecuperationLineAdjustmentServiceImpl extends BaseServiceImpl<Recup
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void adjustmentUsers(String lineId, String[] loginNames) {
|
||||
public void adjustmentUsers(String lineId, String[] loginNames, boolean normal) {
|
||||
Cnd cnd = Cnd.where("takePartInLineId", "=", lineId).and("loginName", "in", loginNames);
|
||||
dao().update(RecuperationEnroll.class, Chain.makeSpecial("isNormal", "isNormal ^ 1"), cnd);
|
||||
dao().update(RecuperationEnroll.class, Chain.make("isNormal", normal), cnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean smsAlerts(String lineId, String[] loginNames) {
|
||||
Sql lineSql = Sqls.create("""
|
||||
SELECT line.lineName, line.regionalNature, lot.lotName,
|
||||
DATE_FORMAT(us.playStartTime, '%Y-%m-%d') AS playStartTime,
|
||||
DATE_FORMAT(us.playEndTime, '%Y-%m-%d') AS playEndTime
|
||||
FROM the_rapy_recuperation_line_union_select us
|
||||
LEFT JOIN the_rapy_recuperation_line line ON line.id = us.lineId
|
||||
LEFT JOIN the_rapy_recuperation_lot lot ON lot.id = line.lotId
|
||||
WHERE us.id = @lineId
|
||||
""");
|
||||
lineSql.setParam("lineId", lineId);
|
||||
NutMap line = listMap(lineSql).stream().findFirst().orElse(null);
|
||||
if (line == null) {
|
||||
return false;
|
||||
}
|
||||
List<RecuperationEnroll> 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;
|
||||
}
|
||||
}
|
||||
|
||||
+23
-9
@@ -149,7 +149,8 @@ public class RecuperationLineClusterServiceImpl extends BaseServiceImpl<Recupera
|
||||
// sql.setVar("usCnd", usCnd);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
line.id,
|
||||
us.id,
|
||||
line.id AS sourceLineId,
|
||||
line.serialNumber,
|
||||
line.lineName,
|
||||
line.regionalNature,
|
||||
@@ -168,8 +169,22 @@ public class RecuperationLineClusterServiceImpl extends BaseServiceImpl<Recupera
|
||||
gh.id AS ascriptionUnionId,
|
||||
u.username AS createUserName,
|
||||
ta.travelAgencyName,
|
||||
( SELECT count( 1 ) FROM the_rapy_recuperation_enroll $summaryCnd ) AS signUpUserNum,
|
||||
( SELECT count( 1 ) FROM the_rapy_recuperation_enroll_companion WHERE trreId IN ( SELECT id FROM the_rapy_recuperation_enroll $summaryCnd )) AS signUpUserFamilyNum
|
||||
(SELECT count(1)
|
||||
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 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<Recupera
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
Cnd summaryCnd = Cnd.NEW();
|
||||
summaryCnd.and("isNormal", "=", true);
|
||||
summaryCnd.and("takePartInLineId", "=", "us.id");
|
||||
summaryCnd.and("stateId", "=", RecuperationState.PASS);
|
||||
//如果是超级管理和校工会管理员,查看校工会线路
|
||||
if (AuthUtil.hasRoleOr("sysadmin,A06")) {
|
||||
cnd.andEX("us.unionId", "=", unionId);
|
||||
cnd.andEX("us.signUpMode", "=", Strings.isNotBlank(unionId) ? 1 : 2);
|
||||
}else{
|
||||
summaryCnd.and("takePartInUnionId", "=", "us.unionId");
|
||||
cnd.andEX("us.signUpMode", "=", 1);
|
||||
cnd.andEX("us.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
cnd.andEX("line.year", "=", year);
|
||||
cnd.and(Cnd.likeEX("line.lineName", keywords));
|
||||
sql.setVar("summaryCnd", summaryCnd);
|
||||
cnd.asc("line.serialNumber");
|
||||
sql.setCondition(cnd);
|
||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
@@ -257,6 +266,11 @@ public class RecuperationLineClusterServiceImpl extends BaseServiceImpl<Recupera
|
||||
dao().clear(RecuperationCluster.class, Cnd.where("lineId", "=", lineId));
|
||||
dao().clear(RecuperationClusterMember.class, Cnd.where("lineId", "=", lineId));
|
||||
for (RecuperationCluster cluster : clusters) {
|
||||
// 线路组团以“工会选线记录”作为业务线路 ID,保证与报名记录 takePartInLineId 一致。
|
||||
cluster.setLineId(lineId);
|
||||
if (Lang.isNotEmpty(cluster.getMembers())) {
|
||||
cluster.getMembers().forEach(member -> member.setLineId(lineId));
|
||||
}
|
||||
insertWith(cluster, "members");
|
||||
}
|
||||
}
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
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.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.staffbenefit.recuperation.model.RecuperationEnroll;
|
||||
import com.budwk.app.zhgh.staffbenefit.recuperation.service.RecuperationLineStatisticsService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** 线路统计服务,统一限定审核通过且未调出的报名记录。 */
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class RecuperationLineStatisticsServiceImpl extends BaseServiceImpl<RecuperationEnroll> 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<NutMap> 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);
|
||||
}
|
||||
}
|
||||
+153
@@ -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<NutMap> 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<NutMap> 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<NutMap> 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<NutMap> 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<NutMap> 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询旅行社编辑页中“是否灵活组团”为是且未禁用的旅行社。
|
||||
*
|
||||
|
||||
+26
-25
@@ -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()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,11 +1,73 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><search @search="doSearch"><search-item label="年度"><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" @change="doSearch"></el-date-picker></search-item><search-item label="审核状态"><el-select v-model="pageForm.audited" @change="doSearch"><el-option label="待审核" :value="false"></el-option><el-option label="已审核" :value="true"></el-option></el-select></search-item><search-item label="姓名/工号"><el-input v-model="pageForm.keyword" clearable @keyup.enter.native="doSearch"></el-input></search-item></search></el-card>
|
||||
<el-card shadow="never" class="mt20"><table-tool label="疗休养审核"></table-tool><el-table v-loading="tableLoading" :data="tableData" :size="tableSize"><el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="unitName" label="单位"></el-table-column><el-table-column prop="lineName" label="线路" min-width="160"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社"></el-table-column><el-table-column prop="stateId" label="状态"><template v-slot="{row}">{{stateText(row.stateId)}}</template></el-table-column><el-table-column label="操作" width="230"><template v-slot="{row}"><el-button size="mini" @click="view(row)">查看</el-button><el-button v-if="!pageForm.audited" size="mini" type="success" @click="openAudit(row,true)">通过</el-button><el-button v-if="!pageForm.audited" size="mini" type="danger" @click="openAudit(row,false)">驳回</el-button><el-button v-if="pageForm.audited" size="mini" @click="recall(row)">撤回</el-button></template></el-table-column></el-table><!--#include("/layouts/pagination.html"){}#--></el-card>
|
||||
<el-dialog title="报名详情" :visible.sync="viewVisible" width="760px" append-to-body><el-descriptions :column="2" border><el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item><el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item><el-descriptions-item label="身份证">{{viewData.idCard}}</el-descriptions-item><el-descriptions-item label="手机">{{viewData.mobile}}</el-descriptions-item><el-descriptions-item label="线路">{{viewData.lineName}}</el-descriptions-item><el-descriptions-item label="旅行社">{{viewData.travelAgencyName}}</el-descriptions-item></el-descriptions></el-dialog>
|
||||
<el-dialog title="审核意见" :visible.sync="auditVisible" width="520px" append-to-body><el-input type="textarea" :rows="4" v-model="auditForm.auditOpinion"></el-input><template slot="footer"><el-button @click="auditVisible=false">取消</el-button><el-button type="primary" :loading="formLoading" @click="submitAudit">确认</el-button></template></el-dialog>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度"><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" @change="doSearch"></el-date-picker></search-item>
|
||||
<search-item label="审核状态"><el-select v-model="pageForm.audited" @change="doSearch"><el-option label="待审核" :value="false"></el-option><el-option label="已审核" :value="true"></el-option></el-select></search-item>
|
||||
<search-item v-if="pageForm.stage==='school'||pageForm.stage==='travel'" label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="线路"><el-select v-model="pageForm.lineId" filterable clearable @change="doSearch"><el-option v-for="item in lineOptions" :key="item.id" :label="item.lineName" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item v-if="pageForm.stage==='travel'" label="旅行社"><el-select v-model="pageForm.agencyId" filterable clearable @change="doSearch"><el-option v-for="item in agencyOptions" :key="item.id" :label="item.travelAgencyName" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="姓名/工号"><el-input v-model="pageForm.keyword" clearable @keyup.enter.native="doSearch"></el-input></search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool :label="stageTitle">
|
||||
<el-button v-if="!pageForm.audited" type="success" size="small" @click="openBatchAudit(true)">一键通过</el-button>
|
||||
<el-button v-if="!pageForm.audited" type="danger" size="small" @click="openBatchAudit(false)">一键拒绝</el-button>
|
||||
</table-tool>
|
||||
<el-table ref="tableRef" v-loading="tableLoading" :data="tableData" :size="tableSize" row-key="id" @selection-change="selectionChange">
|
||||
<el-table-column v-if="!pageForm.audited" type="selection" reserve-selection width="50"></el-table-column>
|
||||
<el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="loginName" label="工号" width="110"></el-table-column>
|
||||
<el-table-column prop="userName" label="姓名" width="100"></el-table-column>
|
||||
<el-table-column prop="unitName" label="单位" min-width="150" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="selfUnionName" label="所属工会" min-width="130"></el-table-column>
|
||||
<el-table-column prop="lineName" label="线路" min-width="180" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="travelAgencyName" label="旅行社" min-width="150"></el-table-column>
|
||||
<el-table-column prop="signingUptime" label="报名时间" width="165"></el-table-column>
|
||||
<el-table-column prop="stateId" label="状态" width="120"><template v-slot="{row}">{{stateText(row.stateId)}}</template></el-table-column>
|
||||
<el-table-column label="操作" width="230" fixed="right"><template v-slot="{row}">
|
||||
<el-button size="mini" @click="view(row)">查看</el-button>
|
||||
<el-button v-if="!pageForm.audited" size="mini" type="success" @click="openAudit(row,true)">通过</el-button>
|
||||
<el-button v-if="!pageForm.audited" size="mini" type="danger" @click="openAudit(row,false)">拒绝</el-button>
|
||||
<el-button v-if="pageForm.audited&&canRecall(row)" size="mini" @click="recall(row)">撤回</el-button>
|
||||
</template></el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="报名详情" :visible.sync="viewVisible" width="820px" append-to-body>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item><el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="身份证">{{viewData.idCard}}</el-descriptions-item><el-descriptions-item label="手机">{{viewData.mobile}}</el-descriptions-item>
|
||||
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item><el-descriptions-item label="工会">{{viewData.unionName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="线路">{{viewData.lineName}}</el-descriptions-item><el-descriptions-item label="旅行社">{{viewData.travelAgencyName}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-table v-if="viewData.companionList&&viewData.companionList.length" :data="viewData.companionList" class="mt20">
|
||||
<el-table-column prop="userName" label="家属姓名"></el-table-column><el-table-column prop="relation" label="关系"></el-table-column><el-table-column prop="idCard" label="身份证"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
<el-dialog :title="batchMode?'一键审核':'审核意见'" :visible.sync="auditVisible" width="520px" append-to-body>
|
||||
<div class="mb10">本次将{{auditForm.pass?'通过':'拒绝'}} {{auditCount}} 条报名记录。</div>
|
||||
<el-input type="textarea" :rows="4" v-model="auditForm.auditOpinion" placeholder="请输入审核意见"></el-input>
|
||||
<template slot="footer"><el-button @click="auditVisible=false">取消</el-button><el-button type="primary" :loading="formLoading" @click="submitAudit">确认</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:"#app",mixins:[initTableMixins],data(){return {pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear(),audited:false,stage:"${stage!}"},viewVisible:false,auditVisible:false,formLoading:false,viewData:{},auditForm:{}}},methods:{pageData(){this.tableLoading=true;this.$axios.post("/platform/recuperation/audit/pageData",this.pageForm).then((res)=>{if(res.code===0){this.$set(this,"tableData",res.data.list||[]);this.$set(this.pageForm,"totalCount",res.data.totalCount||0)}}).finally(()=>{this.tableLoading=false})},stateText(state){const map={2710:"分工会待审",2715:"分工会驳回",2720:"线路工会待审",2725:"线路工会驳回",2730:"校工会待审",2735:"校工会驳回",2750:"审核通过"};return map[state]||state},view(row){this.$axios.post("/platform/recuperation/audit/findOne",{id:row.id}).then((res)=>{if(res.code===0){this.$set(this,"viewData",res.data.viewData||{});this.$set(this,"viewVisible",true)}})},openAudit(row,pass){this.$set(this,"auditForm",{id:row.id,pass:pass,auditOpinion:""});this.$set(this,"auditVisible",true)},submitAudit(){this.formLoading=true;this.$axios.post("/platform/recuperation/audit/audit",this.auditForm).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.$set(this,"auditVisible",false);this.pageData()}}).finally(()=>{this.formLoading=false})},recall(row){this.$confirm("确定撤回该审核吗?","提示").then(()=>{this.$axios.post("/platform/recuperation/audit/recall",{id:row.id}).then((res)=>{if(res.code===0)this.pageData()})}).catch(()=>{})}},created(){this.pageData()}})
|
||||
new Vue({
|
||||
el:"#app",mixins:[initTableMixins],
|
||||
data(){return{pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear().toString(),audited:false,stage:"${stage!}",keyword:'',unionId:'',lineId:'',agencyId:''},viewVisible:false,auditVisible:false,formLoading:false,viewData:{},auditForm:{pass:true,auditOpinion:''},selectedRows:[],batchMode:false,unionOptions:[],lineOptions:[],agencyOptions:[]}},
|
||||
computed:{stageTitle(){const titles={branch:'分工会审核',lineUnion:'线路工会审核',school:'校工会审核',travel:'旅行社审核'};return titles[this.pageForm.stage]||'疗休养审核'},auditCount(){return this.batchMode?this.selectedRows.length:1}},
|
||||
methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post('/platform/recuperation/audit/pageData',this.pageForm).then((res)=>{if(res.code===0){this.$set(this,'tableData',res.data.list||[]);this.$set(this.pageForm,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
stateText(state){const map={2710:'分工会待审',2715:'分工会驳回',2720:'线路工会待审',2725:'线路工会驳回',2730:'校工会待审',2735:'校工会驳回',2750:'审核通过'};return map[state]||state},
|
||||
canRecall(row){return[2715,2725,2735].indexOf(row.stateId)!==-1},selectionChange(rows){this.$set(this,'selectedRows',rows)},
|
||||
view(row){this.$axios.post('/platform/recuperation/audit/findOne',{id:row.id}).then((res)=>{if(res.code===0){this.$set(this,'viewData',(res.data&&res.data.viewData)||{});this.$set(this,'viewVisible',true)}})},
|
||||
openAudit(row,pass){this.$set(this,'batchMode',false);this.$set(this,'auditForm',{id:row.id,pass:pass,auditOpinion:''});this.$set(this,'auditVisible',true)},
|
||||
openBatchAudit(pass){if(!this.selectedRows.length){this.$message.warning('请选择需要审核的报名记录');return}this.$set(this,'batchMode',true);this.$set(this,'auditForm',{pass:pass,auditOpinion:''});this.$set(this,'auditVisible',true)},
|
||||
submitAudit(){this.$set(this,'formLoading',true);const url=this.batchMode?'/platform/recuperation/audit/oneKeyAudit':'/platform/recuperation/audit/audit';const params=Object.assign({},this.auditForm,this.batchMode?{ids:this.selectedRows.map((item)=>item.id).join(',')}:{});this.$axios.post(url,params).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.$set(this,'auditVisible',false);this.pageData()}else this.$message.warning(res.msg)}).finally(()=>{this.$set(this,'formLoading',false)})},
|
||||
recall(row){this.$confirm('确定撤回该审核吗?','提示').then(()=>{this.$axios.post('/platform/recuperation/audit/recall',{id:row.id}).then((res)=>{if(res.code===0)this.pageData()})}).catch(()=>{})},
|
||||
loadOptions(){this.$businessTool.listUnion().then((res)=>{this.$set(this,'unionOptions',res||[])});this.$axios.post('/platform/recuperation/line/pageData',{pageNumber:1,pageSize:200,year:this.pageForm.year}).then((res)=>{if(res.code===0)this.$set(this,'lineOptions',res.data.list||[])});this.$axios.post('/platform/recuperation/travelAgency/selectTravelAgency',{year:this.pageForm.year}).then((res)=>{if(res.code===0)this.$set(this,'agencyOptions',res.data||[])})}
|
||||
},created(){this.loadOptions();this.pageData()}
|
||||
})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
+28
-23
@@ -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()
|
||||
}
|
||||
})
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+7
-6
@@ -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)
|
||||
}
|
||||
|
||||
+14
-19
@@ -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 {
|
||||
|
||||
+173
-72
@@ -49,12 +49,12 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="省外最多成团人数" prop="outsideQuota">
|
||||
<el-form-item label="最少成团人数(含家属)" prop="outsideQuota">
|
||||
<el-input v-model.number="formData.outsideQuota"
|
||||
placeholder="请输入每条省外线路最多成团人数"></el-input>
|
||||
placeholder="请输入最少成团人数"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="省外名额分配比例" prop="outsideQuotaProportion">
|
||||
<el-form-item v-if="formData.outsideQuotaMode==='fixedRatio'" label="省外名额分配比例" prop="outsideQuotaProportion">
|
||||
<el-input placeholder="请输入省外名额分配比例" v-model="formData.outsideQuotaProportion">
|
||||
<template slot="append">%</template>
|
||||
</el-input>
|
||||
@@ -90,6 +90,34 @@ layout("/layouts/platform.html"){
|
||||
v-model.number="formData.modifyNumber"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="统一报名时间" required>
|
||||
<el-date-picker
|
||||
v-model="formData.signUpStartTime"
|
||||
type="datetime"
|
||||
value-format="timestamp"
|
||||
placeholder="请选择报名开始时间"
|
||||
style="width: 32%">
|
||||
</el-date-picker>
|
||||
<span style="margin: 0 10px">至</span>
|
||||
<el-date-picker
|
||||
v-model="formData.signUpEndTime"
|
||||
type="datetime"
|
||||
value-format="timestamp"
|
||||
placeholder="请选择报名结束时间"
|
||||
style="width: 32%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="统一变更截止时间" prop="changeEndTime">
|
||||
<el-date-picker
|
||||
v-model="formData.changeEndTime"
|
||||
type="datetime"
|
||||
value-format="timestamp"
|
||||
placeholder="请选择报名变更截止时间"
|
||||
style="width: 66%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="省内线路是否需要审核" prop="isSnLine">
|
||||
<el-radio-group v-model="formData.isSnLine">
|
||||
<el-radio-button :label="true">需要</el-radio-button>
|
||||
@@ -104,15 +132,49 @@ layout("/layouts/platform.html"){
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="旅行社报名是否需要审核" prop="travelAudit">
|
||||
<el-radio-group v-model="formData.travelAudit">
|
||||
<el-radio-button :label="true">需要</el-radio-button>
|
||||
<el-radio-button :label="false">不需要</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="省外名额分配方式" prop="outsideQuotaMode">
|
||||
<el-radio-group v-model="formData.outsideQuotaMode">
|
||||
<el-radio-button label="fixedRatio">固定比例分配</el-radio-button>
|
||||
<el-radio-button label="unionRatio">分工会单独分配</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="formData.outsideQuotaMode==='unionRatio'" label="分工会名额分配" prop="unionLimit">
|
||||
<el-button type="primary" size="small" @click="openUnionLimit">设置分工会比例</el-button>
|
||||
<span v-if="formData.unionLimit&&formData.unionLimit.length" class="text-success ml10">已设置 {{formData.unionLimit.length}} 个分工会</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="提醒可见人员范围" prop="remindVisibleGroupId">
|
||||
<el-select v-model="formData.remindVisibleGroupId" placeholder="请选择提醒可见人员范围"
|
||||
filterable clearable style="width: 100%">
|
||||
<el-option v-for="item in activityGroupList"
|
||||
:value="item.groupId"
|
||||
:key="item.groupId"
|
||||
:label="item.groupName"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认提醒内容" prop="remindContent">
|
||||
<el-input v-model="formData.remindContent" type="textarea" :rows="4"
|
||||
placeholder="请输入未报名、已报名或未成团人员提醒时默认带出的内容"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="全批次最多报名人数" prop="allLineSignUpNumber">
|
||||
<el-input max="100"
|
||||
placeholder="请输入全批次最多报名人数"
|
||||
v-model.number="formData.allLineSignUpNumber"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="省内起始年份" prop="provinceStartYear">
|
||||
<el-form-item label="省外起始年份" prop="provinceStartYear">
|
||||
<el-input max="100"
|
||||
placeholder="请输入省内起始年份"
|
||||
placeholder="请输入省外起始年份"
|
||||
v-model.number="formData.provinceStartYear"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
@@ -220,6 +282,11 @@ layout("/layouts/platform.html"){
|
||||
ref="drawerUserScope"
|
||||
:group_id.sync="formData.activityGroupId"
|
||||
></drawer-user-scope>
|
||||
<el-dialog title="分工会省外名额分配" :visible.sync="unionLimitVisible" width="760px" append-to-body>
|
||||
<div class="mb10"><el-input-number v-model="unionLimitQuickValue" :min="0" :max="100" :precision="2"></el-input-number><span class="ml10">%</span><el-button type="primary" size="small" class="ml10" @click="quickSetUnionLimit">统一设置</el-button><span class="ml20">当前合计:{{unionLimitTotal}}%</span></div>
|
||||
<el-table :data="formData.unionLimit" max-height="480"><el-table-column prop="unionName" label="分工会"></el-table-column><el-table-column label="名额比例" width="230"><template v-slot="{row}"><el-input-number v-model="row.limitCount" :min="0" :max="100" :precision="2"></el-input-number><span class="ml10">%</span></template></el-table-column></el-table>
|
||||
<template slot="footer"><el-button @click="unionLimitVisible=false">取消</el-button><el-button type="primary" @click="saveUnionLimit">确定</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
@@ -247,6 +314,14 @@ layout("/layouts/platform.html"){
|
||||
provinceStartYear: null,
|
||||
bedInfo: true,
|
||||
familyInfo: 1,
|
||||
signUpStartTime: null,
|
||||
signUpEndTime: null,
|
||||
changeEndTime: null,
|
||||
travelAudit: false,
|
||||
outsideQuotaMode: 'fixedRatio',
|
||||
remindVisibleGroupId: null,
|
||||
remindContent: '',
|
||||
unionLimit: [],
|
||||
},
|
||||
formRules: {
|
||||
configName: [{required: true, message: '请输入配置名称', trigger: ['blur', 'change']}],
|
||||
@@ -272,6 +347,10 @@ layout("/layouts/platform.html"){
|
||||
provinceStartYear: [{required: true, message: '请输入省内起始年份', trigger: ['change', 'blur']}],
|
||||
bedInfo: [{required: true, message: '请选择床位信息', trigger: ['change', 'blur']}],
|
||||
familyInfo: [{required: true, message: '请选择家属信息', trigger: ['change', 'blur']}],
|
||||
signUpStartTime: [{required: true, message: '请选择报名开始时间', trigger: ['change', 'blur']}],
|
||||
signUpEndTime: [{required: true, message: '请选择报名结束时间', trigger: ['change', 'blur']}],
|
||||
changeEndTime: [{required: true, message: '请选择变更截止时间', trigger: ['change', 'blur']}],
|
||||
travelAudit: [{required: true, message: '请选择旅行社报名是否审核', trigger: ['change', 'blur']}],
|
||||
},
|
||||
marks: [],
|
||||
lotDeleteList: [],
|
||||
@@ -280,43 +359,48 @@ layout("/layouts/platform.html"){
|
||||
tableScopeId: '',
|
||||
tableScopeIndex: '',
|
||||
userScopeDialog: false,
|
||||
unionLimitVisible: false,
|
||||
unionLimitQuickValue: 0,
|
||||
unionOptions: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
unionLimitTotal() {
|
||||
return (this.formData.unionLimit || []).reduce((total, item) => total + Number(item.limitCount || 0), 0).toFixed(2)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"drawer-user-scope": httpVueLoader("/components/module/activity/DrawerUserScope.vue"),
|
||||
},
|
||||
methods: {
|
||||
async deleteLotsRow(scope) {
|
||||
const res = await this.$axios.get(loc() + '/getLotsById?lotId=' + scope.row.id)
|
||||
if (res.code === 0) {
|
||||
this.LineNameList = res.data
|
||||
}
|
||||
if (!$.isEmptyObject(this.LineNameList)) {
|
||||
this.centerDialogVisible = true;
|
||||
this.tableScopeId = scope.row.id
|
||||
this.tableScopeIndex = scope.$index;
|
||||
} else {
|
||||
const confirm = await this.$confirm('您确定要删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
if (confirm !== 'confirm') return
|
||||
this.tableScopeId = scope.row.id
|
||||
this.tableScopeIndex = scope.$index;
|
||||
await this.deleteLotById();
|
||||
}
|
||||
deleteLotsRow(scope) {
|
||||
this.$axios.post(loc() + '/getLotsById', {lotId: scope.row.id}).then((res) => {
|
||||
if (res.code === 0) this.$set(this, 'LineNameList', res.data || {})
|
||||
if (!$.isEmptyObject(this.LineNameList)) {
|
||||
this.$set(this, 'centerDialogVisible', true)
|
||||
this.$set(this, 'tableScopeId', scope.row.id)
|
||||
this.$set(this, 'tableScopeIndex', scope.$index)
|
||||
} else {
|
||||
this.$confirm('您确定要删除吗?', '提示', {
|
||||
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
|
||||
}).then(() => {
|
||||
this.$set(this, 'tableScopeId', scope.row.id)
|
||||
this.$set(this, 'tableScopeIndex', scope.$index)
|
||||
this.deleteLotById()
|
||||
}).catch(() => {})
|
||||
}
|
||||
})
|
||||
},
|
||||
resetForm() {
|
||||
this.formData.lots = []
|
||||
this.$set(this.formData, 'lots', [])
|
||||
if (this.$refs['addForm']) {
|
||||
this.$refs['addForm'].resetFields()
|
||||
}
|
||||
},
|
||||
async operation() {
|
||||
const valid = await this.$refs["addForm"].validate()
|
||||
if (valid) {
|
||||
this.subLoading = true
|
||||
operation() {
|
||||
this.$refs["addForm"].validate((valid) => {
|
||||
if (!valid) return
|
||||
this.$set(this, 'subLoading', true)
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: '正在提交...',
|
||||
@@ -330,64 +414,81 @@ layout("/layouts/platform.html"){
|
||||
if (this.formData.lots && this.formData.lots.length > 0) {
|
||||
cloneData.lots = JSON.stringify(this.formData.lots)
|
||||
}
|
||||
cloneData.outsideQuotaProportion = cloneData.outsideQuotaProportion / 100
|
||||
const resp = await this.$axios.post(loc() + "/onSubmit", cloneData)
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
loading.close()
|
||||
this.subLoading = false
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
if (this.formData.unionLimit && this.formData.unionLimit.length > 0) {
|
||||
cloneData.unionLimit = JSON.stringify(this.formData.unionLimit)
|
||||
}
|
||||
cloneData.outsideQuotaProportion = cloneData.outsideQuotaProportion / 100
|
||||
this.$axios.post(loc() + "/onSubmit", cloneData).then((resp) => {
|
||||
if (resp.code === 0) this.$message.success(resp.msg)
|
||||
else this.$message.warning(resp.msg)
|
||||
}).finally(() => { loading.close(); this.$set(this, 'subLoading', false) })
|
||||
})
|
||||
},
|
||||
findOne() {
|
||||
this.getActivityGroup().then(() => this.$axios.post(loc() + "/fetchOne")).then((res) => {
|
||||
const data = res.data || {}
|
||||
if (data.outsideQuotaProportion) data.outsideQuotaProportion = data.outsideQuotaProportion * 1000 / 10
|
||||
if (!data.lots) data.lots = []
|
||||
if (!data.unionLimit) data.unionLimit = []
|
||||
this.$set(this, 'formData', data)
|
||||
})
|
||||
},
|
||||
openUnionLimit() {
|
||||
const existing = this.formData.unionLimit || []
|
||||
const limits = this.unionOptions.map((item) => {
|
||||
const old = existing.find((limit) => limit.unionId === item.id) || {}
|
||||
return {unionId: item.id, unionName: item.name, limitCount: Number(old.limitCount || 0)}
|
||||
})
|
||||
this.$set(this.formData, 'unionLimit', limits)
|
||||
this.$set(this, 'unionLimitVisible', true)
|
||||
},
|
||||
quickSetUnionLimit() {
|
||||
this.formData.unionLimit.forEach((item) => this.$set(item, 'limitCount', Number(this.unionLimitQuickValue || 0)))
|
||||
},
|
||||
saveUnionLimit() {
|
||||
if (Number(this.unionLimitTotal) > 100) {
|
||||
this.$message.warning('分工会名额比例合计不能超过100%')
|
||||
return
|
||||
}
|
||||
this.$set(this, 'unionLimitVisible', false)
|
||||
},
|
||||
async findOne() {
|
||||
await this.getActivityGroup()
|
||||
const {data} = await this.$axios.get(loc() + "/fetchOne")
|
||||
if (data.outsideQuotaProportion) {
|
||||
data.outsideQuotaProportion = data.outsideQuotaProportion * 1000 / 10
|
||||
}
|
||||
if (!data.lots) {
|
||||
data.lots = []
|
||||
}
|
||||
this.formData = data
|
||||
getActivityGroup() {
|
||||
return this.$axios.post('/platform/activity/basic/scope/getActivityUserScopeGroup').then((res) => {
|
||||
this.$set(this, 'activityGroupList', res.data || [])
|
||||
return this.activityGroupList
|
||||
})
|
||||
},
|
||||
async getActivityGroup() {
|
||||
const {data} = await this.$axios.get('/platform/activity/basic/scope/getActivityUserScopeGroup')
|
||||
this.activityGroupList = data
|
||||
closeDialog() {
|
||||
this.$set(this, 'tableScopeIndex', '');
|
||||
this.$set(this, 'tableScopeId', '');
|
||||
this.$set(this, 'centerDialogVisible', false);
|
||||
this.$set(this, 'LineNameList', {});
|
||||
},
|
||||
async closeDialog() {
|
||||
this.tableScopeIndex = '';
|
||||
this.tableScopeId = '';
|
||||
this.centerDialogVisible = false;
|
||||
this.LineNameList = {};
|
||||
},
|
||||
async deleteLotById() {
|
||||
deleteLotById() {
|
||||
if (this.tableScopeId == null || this.tableScopeId === '') {
|
||||
this.formData.lots.splice(this.tableScopeIndex, 1);
|
||||
this.$message.success('操作成功')
|
||||
return;
|
||||
}
|
||||
const resp = await this.$axios.get(loc() + '/deleteLotById?lotId=' + this.tableScopeId)
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.tableScopeId = '';
|
||||
this.centerDialogVisible = false;
|
||||
this.formData.lots.splice(this.tableScopeIndex, 1)
|
||||
await this.findOne();
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
this.$axios.post(loc() + '/deleteLotById', {lotId: this.tableScopeId}).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.$set(this, 'tableScopeId', '')
|
||||
this.$set(this, 'centerDialogVisible', false)
|
||||
this.formData.lots.splice(this.tableScopeIndex, 1)
|
||||
this.findOne()
|
||||
} else this.$message.warning(resp.msg)
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
created() {
|
||||
this.$businessTool.listUnion().then((res) => this.$set(this, 'unionOptions', res || []))
|
||||
this.findOne();
|
||||
},
|
||||
watch: {
|
||||
'formData.activityGroupId': {
|
||||
async handler(newVal, oldVal) {
|
||||
this.activityGroupList = await this.getActivityGroup()
|
||||
this.userScopeDialog = false
|
||||
handler(newVal, oldVal) {
|
||||
this.getActivityGroup().then(() => { this.$set(this, 'userScopeDialog', false) })
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度范围"><el-date-picker v-model="yearRange" type="yearrange" value-format="yyyy" range-separator="至" start-placeholder="开始年度" end-placeholder="结束年度" @change="yearChange"></el-date-picker></search-item>
|
||||
<search-item label="灵活组团"><el-select v-model="pageForm.groupName" clearable filterable @change="doSearch"><el-option v-for="item in groupOptions" :key="item.id" :label="item.groupName" :value="item.groupName"></el-option></el-select></search-item>
|
||||
<search-item label="旅行社"><el-select v-model="pageForm.travelAgencyId" clearable filterable @change="doSearch"><el-option v-for="item in agencyOptions" :key="item.id" :label="item.travelAgencyName" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="姓名/工号"><el-input v-model="pageForm.searchKeyword" clearable @keyup.enter.native="doSearch"></el-input></search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool label="省内灵活组团查询"><template slot="right"><el-button type="success" size="small" @click="doExport">导出Excel</el-button></template></table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :size="tableSize">
|
||||
<el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="year" label="年度" width="90"></el-table-column><el-table-column prop="groupName" label="组团名称" min-width="180"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" min-width="180"></el-table-column><el-table-column prop="groupCount" label="团队数" width="90"></el-table-column><el-table-column prop="signCount" label="报名人数" width="100"></el-table-column><el-table-column label="操作" width="180"><template v-slot="{row}"><el-button size="mini" @click="openGroups(row)">查看团队</el-button><el-button type="primary" size="mini" @click="openAllUsers(row)">全部人员</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="团队列表" :visible.sync="groupVisible" width="900px" append-to-body>
|
||||
<el-table v-loading="dialogLoading" :data="groups"><el-table-column prop="groupLeaderUserName" label="团长姓名"></el-table-column><el-table-column prop="groupLeaderLoginName" label="团长工号"></el-table-column><el-table-column prop="groupLeaderPassword" label="团口令"></el-table-column><el-table-column prop="userCount" label="人数" width="90"></el-table-column><el-table-column label="操作" width="100"><template v-slot="{row}"><el-button type="primary" size="mini" @click="openGroupUsers(row)">人员</el-button></template></el-table-column></el-table>
|
||||
</el-dialog>
|
||||
<el-dialog title="报名人员" :visible.sync="userVisible" width="1050px" append-to-body>
|
||||
<el-table v-loading="userLoading" :data="users"><el-table-column type="index" label="序号" width="60"></el-table-column><el-table-column prop="loginName" label="工号" width="110"></el-table-column><el-table-column prop="userName" label="姓名" width="100"></el-table-column><el-table-column prop="identity" label="身份" width="80"></el-table-column><el-table-column prop="sex" label="性别" width="60"></el-table-column><el-table-column prop="unitName" label="单位" show-overflow-tooltip></el-table-column><el-table-column prop="unionName" label="工会" show-overflow-tooltip></el-table-column><el-table-column prop="mobile" label="联系电话" width="130"></el-table-column><el-table-column prop="isFamily" label="家属人数" width="90"></el-table-column><el-table-column label="操作" width="80"><template v-slot="{row}"><el-button type="danger" size="mini" @click="deleteUser(row)">删除</el-button></template></el-table-column></el-table>
|
||||
<el-pagination class="mt20" background layout="total, sizes, prev, pager, next" :current-page="userPage.pageNumber" :page-size="userPage.pageSize" :total="userPage.totalCount" @current-change="userPageChange" @size-change="userSizeChange"></el-pagination>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el:'#app',mixins:[initTableMixins],data(){const year=new Date().getFullYear().toString();return{yearRange:[year,year],pageForm:{pageNumber:1,pageSize:10,totalCount:0,startYear:year,endYear:year,groupName:'',travelAgencyId:'',searchKeyword:''},agencyOptions:[],groupOptions:[],currentGroup:{},groups:[],users:[],groupVisible:false,userVisible:false,dialogLoading:false,userLoading:false,userPage:{pageNumber:1,pageSize:10,totalCount:0},userQuery:{}}},
|
||||
methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/pageData',this.pageForm).then((res)=>{if(res.code===0){this.$set(this,'tableData',res.data.list||[]);this.$set(this.pageForm,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
yearChange(value){this.$set(this.pageForm,'startYear',value&&value.length?value[0]:'');this.$set(this.pageForm,'endYear',value&&value.length?value[1]:'');this.loadOptions();this.doSearch()},
|
||||
loadOptions(){const params={startYear:this.pageForm.startYear,endYear:this.pageForm.endYear};this.$axios.post(loc()+'/selectTravelAgencyList',params).then((res)=>{if(res.code===0)this.$set(this,'agencyOptions',res.data||[])});this.$axios.post(loc()+'/selectFlexibleGroupList',params).then((res)=>{if(res.code===0)this.$set(this,'groupOptions',res.data||[])})},
|
||||
doExport(){window.open(loc()+'/doExport?'+$.param(this.pageForm))},
|
||||
openGroups(row){this.$set(this,'currentGroup',row);this.$set(this,'groupVisible',true);this.$set(this,'dialogLoading',true);this.$axios.post(loc()+'/getGroupInfo',{groupId:row.id}).then((res)=>{if(res.code===0)this.$set(this,'groups',res.data||[])}).finally(()=>{this.$set(this,'dialogLoading',false)})},
|
||||
openAllUsers(row){this.$set(this,'currentGroup',row);this.$set(this,'userQuery',{});this.$set(this.userPage,'pageNumber',1);this.$set(this,'userVisible',true);this.loadUsers()},
|
||||
openGroupUsers(row){this.$set(this,'userQuery',{groupLeaderUserId:row.groupLeaderUserId,groupLeaderLoginName:row.groupLeaderLoginName,noGroupLeader:!row.groupLeaderUserId&&!row.groupLeaderLoginName});this.$set(this.userPage,'pageNumber',1);this.$set(this,'userVisible',true);this.loadUsers()},
|
||||
loadUsers(){this.$set(this,'userLoading',true);const params=Object.assign({groupId:this.currentGroup.id,pageNumber:this.userPage.pageNumber,pageSize:this.userPage.pageSize},this.userQuery);this.$axios.post(loc()+'/getSignUser',params).then((res)=>{if(res.code===0){this.$set(this,'users',res.data.list||[]);this.$set(this.userPage,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'userLoading',false)})},
|
||||
userPageChange(value){this.$set(this.userPage,'pageNumber',value);this.loadUsers()},userSizeChange(value){this.$set(this.userPage,'pageSize',value);this.$set(this.userPage,'pageNumber',1);this.loadUsers()},
|
||||
deleteUser(row){this.$confirm('确定删除该报名人员吗?','提示',{type:'warning'}).then(()=>{this.$axios.post(loc()+'/deleteJoinUser',{id:row.id}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.loadUsers();this.pageData()}else this.$message.warning(res.msg)})}).catch(()=>{})}
|
||||
},created(){this.loadOptions();this.pageData()}
|
||||
})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
+17
-3
@@ -1,9 +1,23 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><el-form inline><el-form-item label="年度"><el-date-picker v-model="year" type="year" value-format="yyyy" @change="loadOptions"></el-date-picker></el-form-item><el-form-item label="线路/旅行社"><el-select v-model="targetId" filterable placeholder="请选择"><el-option v-for="item in options" :key="item.id" :label="item.lineName||item.travelAgencyName" :value="item.id"></el-option></el-select></el-form-item><el-form-item><el-upload action="/platform/recuperation/joinUserImport/readExcel" name="file" :data="uploadData" :show-file-list="false" :on-success="onUploadSuccess" accept=".xls,.xlsx"><el-button type="primary">上传参加人员 Excel</el-button></el-upload></el-form-item><el-form-item><el-button @click="downloadTemplate">下载模板</el-button></el-form-item></el-form></el-card>
|
||||
<el-card shadow="never" class="mt20"><table-tool label="匹配到的报名人员"><el-button type="primary" :loading="formLoading" @click="doImport">确认标记参加</el-button></table-tool><el-table :data="matchList"><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="takePartInTime" label="参加时间"></el-table-column><el-table-column prop="lineName" label="线路"></el-table-column></el-table></el-card>
|
||||
<el-card shadow="never">
|
||||
<div slot="header"><span>导入实际参加人员</span></div>
|
||||
<el-steps :active="stepActive" finish-status="success"><el-step title="选择线路或旅行社"></el-step><el-step title="读取人员名单"></el-step><el-step title="确认导入数据"></el-step><el-step title="导入结果"></el-step></el-steps>
|
||||
<div class="mt30" style="min-height:430px">
|
||||
<template v-if="stepActive===0"><el-form label-width="100px"><el-form-item label="年度"><el-date-picker v-model="year" type="year" value-format="yyyy" @change="loadOptions"></el-date-picker></el-form-item><el-row :gutter="20"><el-col :span="12"><el-card shadow="never"><div slot="header">线路</div><el-radio-group v-model="lineId" @change="selectLine" style="display:block"><el-radio v-for="item in lines" :key="item.id" :label="item.id" border style="display:block;margin:8px 0">{{item.label}}</el-radio></el-radio-group></el-card></el-col><el-col :span="12"><el-card shadow="never"><div slot="header">旅行社</div><el-radio-group v-model="travelAgencyId" @change="selectAgency" style="display:block"><el-radio v-for="item in travels" :key="item.id" :label="item.id" border style="display:block;margin:8px 0">{{item.label}}</el-radio></el-radio-group></el-card></el-col></el-row></el-form></template>
|
||||
<template v-if="stepActive===1"><el-button type="primary" class="mb20" @click="downloadTemplate">下载模板</el-button><el-upload ref="upload" drag :action="loc()+'/readExcel'" name="file" :auto-upload="false" :limit="1" :data="{lineId:lineId,travelAgencyId:travelAgencyId}" :on-success="uploadSuccess" :on-error="uploadError" :on-exceed="uploadExceed" accept=".xls,.xlsx"><i class="el-icon-upload"></i><div class="el-upload__text">将 Excel 文件拖到此处,或<em>点击上传</em></div><div slot="tip" class="el-upload__tip">只允许上传一个 xls/xlsx 文件</div></el-upload></template>
|
||||
<template v-if="stepActive===2"><el-alert :title="'Excel共 '+excelRows.length+' 行,合法匹配 '+matchList.length+' 行'" type="warning" :closable="false" class="mb20"></el-alert><el-table :data="matchList"><el-table-column type="index" label="序号" width="60"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="takePartInTime" label="参加时间"></el-table-column><el-table-column prop="lineName" label="线路"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社"></el-table-column></el-table></template>
|
||||
<template v-if="stepActive===3"><el-result icon="success" title="导入成功" :sub-title="'已标记实际参加 '+matchList.length+' 人'"></el-result></template>
|
||||
</div>
|
||||
<div style="text-align:center"><el-button :disabled="stepActive===0||loading" @click="prev">上一步</el-button><el-button type="primary" :loading="loading" @click="next">{{stepActive===3?'完成':'下一步'}}</el-button></div>
|
||||
</el-card>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:"#app",data(){return {year:new Date().getFullYear(),targetId:null,options:[],matchList:[],formLoading:false}},computed:{uploadData(){return {lineId:this.targetId}}},methods:{loadOptions(){this.$axios.post(loc()+"/options",{year:this.year}).then((res)=>{if(res.code===0)this.$set(this,"options",res.data||[])})},onUploadSuccess(res){if(res.code===0){this.$set(this,"matchList",res.data.matchList||[]);this.$message.success("已匹配 "+this.matchList.length+" 人")}else this.$message.warning(res.msg)},doImport(){if(!this.matchList.length){this.$message.warning("暂无匹配人员");return}this.formLoading=true;this.$axios.post(loc()+"/doImport",{enrolls:JSON.stringify(this.matchList)}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.$set(this,"matchList",[])}}).finally(()=>{this.formLoading=false})},downloadTemplate(){window.open(loc()+"/downloadTemplate")}},created(){this.loadOptions()}})
|
||||
new Vue({el:'#app',data(){return{loading:false,stepActive:0,year:new Date().getFullYear().toString(),lines:[],travels:[],lineId:'',travelAgencyId:'',excelRows:[],matchList:[]}},methods:{
|
||||
loadOptions(){this.$axios.post(loc()+'/options',{year:this.year}).then((res)=>{if(res.code===0){this.$set(this,'lines',(res.data&&res.data.lines)||[]);this.$set(this,'travels',(res.data&&res.data.travels)||[])}})},selectLine(){this.$set(this,'travelAgencyId','')},selectAgency(){this.$set(this,'lineId','')},
|
||||
uploadSuccess(res){this.$set(this,'loading',false);if(res.code===0){this.$set(this,'excelRows',res.data.excelRows||[]);this.$set(this,'matchList',res.data.matchList||[]);this.$set(this,'stepActive',2)}else{this.$message.warning(res.msg);this.$refs.upload.clearFiles()}},uploadError(){this.$set(this,'loading',false);this.$message.warning('文件上传失败')},uploadExceed(){this.$message.warning('最多只能选择一个文件')},
|
||||
prev(){this.$set(this,'stepActive',this.stepActive-1)},next(){if(this.stepActive===0){if(!this.lineId&&!this.travelAgencyId){this.$message.warning('请先选择线路或者旅行社');return}this.$set(this,'stepActive',1);return}if(this.stepActive===1){if(!this.$refs.upload.uploadFiles.length){this.$message.warning('请先选择文件');return}this.$set(this,'loading',true);this.$refs.upload.submit();return}if(this.stepActive===2){if(!this.matchList.length){this.$message.warning('没有合法数据,无法导入');return}this.$set(this,'loading',true);this.$axios.post(loc()+'/doImport',{enrolls:JSON.stringify(this.matchList)}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.$set(this,'stepActive',3)}else this.$message.warning(res.msg)}).finally(()=>{this.$set(this,'loading',false)});return}this.reset()},
|
||||
reset(){this.$set(this,'stepActive',0);this.$set(this,'lineId','');this.$set(this,'travelAgencyId','');this.$set(this,'excelRows',[]);this.$set(this,'matchList',[]);if(this.$refs.upload)this.$refs.upload.clearFiles()},downloadTemplate(){window.open(loc()+'/downloadTemplate')}
|
||||
},created(){this.loadOptions()}})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
+48
-4
@@ -1,10 +1,54 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><search @search="doSearch"><search-item label="年度"><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" @change="doSearch"></el-date-picker></search-item><search-item label="关键字"><el-input v-model="pageForm.keywords" clearable></el-input></search-item></search></el-card>
|
||||
<el-card shadow="never" class="mt20"><table-tool label="线路人员调整"></table-tool><el-table v-loading="tableLoading" :data="tableData" :size="tableSize"><el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="serialNumber" label="线路编号"></el-table-column><el-table-column prop="lineName" label="线路名称" min-width="180"></el-table-column><el-table-column prop="selectUnionName" label="报名工会"></el-table-column><el-table-column prop="signUpUserNum" label="报名人数"></el-table-column><el-table-column label="操作" width="100"><template v-slot="{row}"><el-button type="primary" size="mini" @click="openUsers(row)">调整</el-button></template></el-table-column></el-table><!--#include("/layouts/pagination.html"){}#--></el-card>
|
||||
<el-dialog title="报名人员调整" :visible.sync="usersVisible" width="900px" append-to-body><el-table :data="users" @selection-change="(rows)=>{selectedUsers=rows}"><el-table-column type="selection" width="50"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="unitName" label="单位"></el-table-column><el-table-column prop="isNormal" label="状态"><template v-slot="{row}">{{row.isNormal?'正常':'已调出'}}</template></el-table-column></el-table><template slot="footer"><el-button @click="usersVisible=false">取消</el-button><el-button type="primary" :loading="formLoading" @click="toggleUsers">切换选中人员状态</el-button></template></el-dialog>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度"><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" @change="yearChange"></el-date-picker></search-item>
|
||||
<search-item label="线路"><el-select v-model="pageForm.lineId" filterable clearable @change="doSearch"><el-option v-for="item in lineOptions" :key="item.id" :label="item.lineName" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="关键字"><el-input v-model="pageForm.keywords" clearable @keyup.enter.native="doSearch"></el-input></search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool label="线路人员调整"></table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :size="tableSize">
|
||||
<el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column>
|
||||
<el-table-column prop="serialNumber" label="线路编号" width="110"></el-table-column>
|
||||
<el-table-column prop="lineName" label="线路名称" min-width="180"></el-table-column>
|
||||
<el-table-column prop="selectUnionName" label="报名工会"></el-table-column>
|
||||
<el-table-column prop="playStartTime" label="出发日期" width="110"></el-table-column>
|
||||
<el-table-column prop="signUpUserNum" label="报名人数" width="90"></el-table-column>
|
||||
<el-table-column prop="signUpUserFamilyNum" label="家属人数" width="90"></el-table-column>
|
||||
<el-table-column label="操作" width="100"><template v-slot="{row}"><el-button type="primary" size="mini" @click="openUsers(row)">调整</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="报名人员调整" :visible.sync="usersVisible" width="1050px" append-to-body>
|
||||
<el-tabs v-model="userTab"><el-tab-pane label="正常报名人员" name="normal"></el-tab-pane><el-tab-pane label="已调出人员" name="removed"></el-tab-pane></el-tabs>
|
||||
<div class="mb10">
|
||||
<el-button v-if="userTab==='normal'" type="danger" size="small" :loading="formLoading" @click="setUsers(false)">调出所选人员</el-button>
|
||||
<el-button v-else type="success" size="small" :loading="formLoading" @click="setUsers(true)">恢复所选人员</el-button>
|
||||
<el-button v-if="userTab==='normal'" type="warning" size="small" :loading="smsLoading" @click="sendAlerts">发送未成团提醒</el-button>
|
||||
</div>
|
||||
<el-table :data="visibleUsers" @selection-change="selectionChange">
|
||||
<el-table-column type="selection" width="50"></el-table-column><el-table-column prop="loginName" label="工号" width="110"></el-table-column><el-table-column prop="userName" label="姓名" width="100"></el-table-column><el-table-column prop="sex" label="性别" width="60"></el-table-column><el-table-column prop="unitName" label="单位" show-overflow-tooltip></el-table-column><el-table-column prop="unionName" label="工会" show-overflow-tooltip></el-table-column><el-table-column prop="companionCount" label="家属人数" width="90"></el-table-column><el-table-column prop="signingUptime" label="报名时间" width="170"></el-table-column>
|
||||
</el-table>
|
||||
<template slot="footer"><el-button @click="usersVisible=false">关闭</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:"#app",mixins:[initTableMixins],data(){return {pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear(),keywords:null},usersVisible:false,formLoading:false,currentRow:{},users:[],selectedUsers:[]}},methods:{pageData(){this.tableLoading=true;this.$axios.post(loc()+"/pageData",this.pageForm).then((res)=>{if(res.code===0){this.$set(this,"tableData",res.data.list||[]);this.$set(this.pageForm,"totalCount",res.data.totalCount||0)}}).finally(()=>{this.tableLoading=false})},openUsers(row){this.$set(this,"currentRow",row);this.$axios.post(loc()+"/findUsers",{lineId:row.usId,unionId:row.unionId}).then((res)=>{if(res.code===0){this.$set(this,"users",res.data||[]);this.$set(this,"usersVisible",true)}})},toggleUsers(){const names=this.selectedUsers.map((item)=>item.loginName);if(!names.length){this.$message.warning("请选择人员");return}this.formLoading=true;this.$axios.post(loc()+"/adjustmentUsers",{lineId:this.currentRow.usId,loginNames:names}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.openUsers(this.currentRow);this.pageData()}}).finally(()=>{this.formLoading=false})}},created(){this.pageData()}})
|
||||
new Vue({
|
||||
el:'#app',mixins:[initTableMixins],
|
||||
data(){return{pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear().toString(),lineId:'',unionId:'',keywords:''},lineOptions:[],unionOptions:[],usersVisible:false,formLoading:false,smsLoading:false,currentRow:{},users:[],selectedUsers:[],userTab:'normal'}},
|
||||
computed:{visibleUsers(){return this.users.filter((item)=>this.userTab==='normal'?item.isNormal:!item.isNormal)}},
|
||||
methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/pageData',this.pageForm).then((res)=>{if(res.code===0){this.$set(this,'tableData',res.data.list||[]);this.$set(this.pageForm,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
loadOptions(){this.$axios.post(loc()+'/findLineOptions',{year:this.pageForm.year}).then((res)=>{if(res.code===0)this.$set(this,'lineOptions',res.data||[])})},
|
||||
yearChange(){this.$set(this.pageForm,'lineId','');this.loadOptions();this.doSearch()},
|
||||
openUsers(row){this.$set(this,'currentRow',row);this.$axios.post(loc()+'/findUsers',{lineId:row.usId,unionId:row.unionId}).then((res)=>{if(res.code===0){this.$set(this,'users',res.data||[]);this.$set(this,'selectedUsers',[]);this.$set(this,'userTab','normal');this.$set(this,'usersVisible',true)}})},
|
||||
selectionChange(rows){this.$set(this,'selectedUsers',rows)},selectedNames(){return this.selectedUsers.map((item)=>item.loginName)},
|
||||
setUsers(normal){const names=this.selectedNames();if(!names.length){this.$message.warning('请选择人员');return}this.$set(this,'formLoading',true);this.$axios.post(loc()+'/adjustmentUsers',{lineId:this.currentRow.usId,loginNames:names,normal:normal}).then((res)=>{if(res.code===0){this.$message.success(normal?'人员已恢复':'人员已调出');this.openUsers(this.currentRow);this.pageData()}else this.$message.warning(res.msg)}).finally(()=>{this.$set(this,'formLoading',false)})},
|
||||
sendAlerts(){const names=this.selectedNames();if(!names.length){this.$message.warning('请选择需要提醒的人员');return}this.$set(this,'smsLoading',true);this.$axios.post(loc()+'/smsAlerts',{lineId:this.currentRow.usId,loginNames:names}).then((res)=>{if(res.code===0)this.$message.success(res.msg);else this.$message.warning(res.msg)}).finally(()=>{this.$set(this,'smsLoading',false)})}
|
||||
},created(){this.$businessTool.listUnion().then((res)=>{this.$set(this,'unionOptions',res||[])});this.loadOptions();this.pageData()}
|
||||
})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
+25
-5
@@ -1,15 +1,35 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><search @search="doSearch"><search-item label="年度"><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" @change="doSearch"></el-date-picker></search-item><search-item label="线路"><el-input v-model="pageForm.keywords" clearable></el-input></search-item></search></el-card>
|
||||
<el-card shadow="never"><search @search="doSearch"><search-item label="年度"><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" @change="doSearch"></el-date-picker></search-item><search-item label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item><search-item label="线路"><el-input v-model="pageForm.keywords" clearable @keyup.enter.native="doSearch"></el-input></search-item></search></el-card>
|
||||
<el-card shadow="never" class="mt20"><table-tool label="线路组团"></table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :size="tableSize">
|
||||
<el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="serialNumber" label="线路编号"></el-table-column><el-table-column prop="lineName" label="线路名称" min-width="180"></el-table-column><el-table-column prop="ascriptionUnionName" label="工会"></el-table-column><el-table-column prop="signUpUserNum" label="报名人数"></el-table-column>
|
||||
<el-table-column label="操作" width="100"><template v-slot="{row}"><el-button size="mini" type="primary" @click="openCluster(row)">组团</el-button></template></el-table-column>
|
||||
<el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="serialNumber" label="线路编号" width="110"></el-table-column><el-table-column prop="lineName" label="线路名称" min-width="180"></el-table-column><el-table-column prop="ascriptionUnionName" label="线路归属"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社"></el-table-column><el-table-column prop="signUpUserNum" label="报名人数" width="90"></el-table-column><el-table-column prop="signUpUserFamilyNum" label="家属人数" width="90"></el-table-column>
|
||||
<el-table-column label="操作" width="150"><template v-slot="{row}"><el-button size="mini" @click="openView(row)">查看</el-button><el-button size="mini" type="primary" @click="openCluster(row)">组团</el-button></template></el-table-column>
|
||||
</el-table><!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="组团人员" :visible.sync="clusterVisible" width="900px" append-to-body><el-input type="textarea" :rows="18" v-model="clustersJson" placeholder="按旧版格式编辑组团 JSON"></el-input><template slot="footer"><el-button @click="clusterVisible=false">取消</el-button><el-button type="primary" :loading="formLoading" @click="saveCluster">保存</el-button></template></el-dialog>
|
||||
<el-dialog title="线路组团" :visible.sync="clusterVisible" width="95%" top="30px" append-to-body>
|
||||
<div class="mb10"><el-button type="primary" size="small" @click="addCluster">添加团</el-button><span class="ml20 text-danger">人员可通过“移动到”分配到团;每团只能设置一名团长。</span></div>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8"><el-card shadow="never"><div slot="header">未分配人员({{unSelectedUsers.length}})<el-button class="float-right" size="mini" type="primary" @click="batchVisible=true">批量调整</el-button></div><el-table ref="unSelectedRef" :data="unSelectedUsers" height="430" @selection-change="unSelectedChange"><el-table-column type="selection" width="45"></el-table-column><el-table-column prop="loginName" label="工号" width="95"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="unionName" label="工会" show-overflow-tooltip></el-table-column><el-table-column label="移动到" width="105"><template v-slot="{row}"><el-select size="mini" placeholder="选择团" @change="moveMember(row,$event,'unSelectedUsers')"><el-option v-for="item in clusters" :key="item.key" :label="item.clusterName" :value="item.key"></el-option></el-select></template></el-table-column></el-table></el-card></el-col>
|
||||
<el-col :span="8" v-for="cluster in clusters" :key="cluster.key"><el-card shadow="never"><div slot="header"><el-input v-model="cluster.clusterName" size="mini" maxlength="10" style="width:150px"></el-input><el-button class="float-right" size="mini" type="danger" @click="removeCluster(cluster)">删除团</el-button></div><el-table :data="cluster.members" height="430"><el-table-column prop="loginName" label="工号" width="95"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="companionCount" label="家属" width="55"></el-table-column><el-table-column label="角色" width="85"><template v-slot="{row}"><el-select v-model="row.isLeader" size="mini" @change="leaderChange(cluster,row)"><el-option label="成员" :value="false"></el-option><el-option label="团长" :value="true"></el-option></el-select></template></el-table-column><el-table-column label="移动" width="105"><template v-slot="{row}"><el-select size="mini" @change="moveMember(row,$event,cluster.key)"><el-option label="未分配" value="unSelectedUsers"></el-option><el-option v-for="item in clusters" v-if="item.key!==cluster.key" :key="item.key" :label="item.clusterName" :value="item.key"></el-option></el-select></template></el-table-column></el-table></el-card></el-col>
|
||||
</el-row>
|
||||
<template slot="footer"><el-button @click="clusterVisible=false">取消</el-button><el-button type="primary" :loading="formLoading" @click="saveCluster">提交</el-button></template>
|
||||
</el-dialog>
|
||||
<el-dialog title="批量调整" :visible.sync="batchVisible" width="460px" append-to-body><el-form label-width="90px"><el-form-item label="已选人数">{{unSelectedSelection.length}}</el-form-item><el-form-item label="目标团"><el-select v-model="batchTarget" style="width:100%"><el-option v-for="item in clusters" :key="item.key" :label="item.clusterName" :value="item.key"></el-option></el-select></el-form-item></el-form><template slot="footer"><el-button @click="batchVisible=false">取消</el-button><el-button type="primary" @click="batchMove">确定</el-button></template></el-dialog>
|
||||
<el-dialog title="团列表" :visible.sync="viewVisible" width="800px" append-to-body><el-tabs v-model="viewClusterId"><el-tab-pane v-for="item in viewClusters" :key="item.key" :name="item.key" :label="item.clusterName+'('+item.members.length+')'"><el-table :data="item.members"><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="unionName" label="工会"></el-table-column><el-table-column label="角色"><template v-slot="{row}">{{row.isLeader?'团长':'成员'}}</template></el-table-column></el-table></el-tab-pane></el-tabs></el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:"#app",mixins:[initTableMixins],data(){return {pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear(),keywords:null},clusterVisible:false,formLoading:false,currentRow:{},clustersJson:"[]"}},methods:{pageData(){this.tableLoading=true;this.$axios.post(loc()+"/pageData",this.pageForm).then((res)=>{if(res.code===0){this.$set(this,"tableData",res.data.list||[]);this.$set(this.pageForm,"totalCount",res.data.totalCount||0)}}).finally(()=>{this.tableLoading=false})},openCluster(row){this.$set(this,"currentRow",row);this.$axios.post(loc()+"/findClusterInfo",{lineId:row.id,usUnionId:row.ascriptionUnionId}).then((res)=>{if(res.code===0){this.$set(this,"clustersJson",JSON.stringify(res.data,null,2));this.$set(this,"clusterVisible",true)}})},saveCluster(){this.formLoading=true;this.$axios.post(loc()+"/setClusterMembers",{lineId:this.currentRow.id,clusters:this.clustersJson}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.$set(this,"clusterVisible",false);this.pageData()}}).finally(()=>{this.formLoading=false})}},created(){this.pageData()}})
|
||||
new Vue({el:'#app',mixins:[initTableMixins],data(){return{pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear().toString(),unionId:'',keywords:''},unionOptions:[],clusterVisible:false,viewVisible:false,batchVisible:false,formLoading:false,currentRow:{},clusters:[],unSelectedUsers:[],unSelectedSelection:[],batchTarget:'',viewClusters:[],viewClusterId:''}},methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/pageData',this.pageForm).then((res)=>{if(res.code===0){this.$set(this,'tableData',res.data.list||[]);this.$set(this.pageForm,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
loadCluster(row,viewOnly){return this.$axios.post(loc()+'/findClusterInfo',{lineId:row.id,usUnionId:row.ascriptionUnionId}).then((res)=>{if(res.code!==0){this.$message.warning(res.msg);return}const data=res.data||{};const list=[];Object.keys(data).forEach((key)=>{if(key!=='unSelectedUsers'){const item=data[key];this.$set(item,'key',key);if(!item.members)item.members=[];list.push(item)}});if(viewOnly){this.$set(this,'viewClusters',list);this.$set(this,'viewClusterId',list.length?list[0].key:'');this.$set(this,'viewVisible',true)}else{this.$set(this,'unSelectedUsers',(data.unSelectedUsers&&data.unSelectedUsers.members)||[]);this.$set(this,'clusters',list);this.$set(this,'clusterVisible',true)}})},
|
||||
openCluster(row){this.$set(this,'currentRow',row);this.loadCluster(row,false)},openView(row){this.loadCluster(row,true)},
|
||||
addCluster(){const key='cluster'+new Date().getTime();this.clusters.push({key:key,lineId:this.currentRow.id,clusterName:'团'+(this.clusters.length+1),members:[]})},
|
||||
removeCluster(cluster){this.$set(this,'unSelectedUsers',this.unSelectedUsers.concat(cluster.members||[]));this.$set(this,'clusters',this.clusters.filter((item)=>item.key!==cluster.key))},
|
||||
findGroup(key){return key==='unSelectedUsers'?this.unSelectedUsers:(this.clusters.find((item)=>item.key===key)||{members:[]}).members},
|
||||
moveMember(row,target,source){const sourceMembers=this.findGroup(source);const index=sourceMembers.findIndex((item)=>item.loginName===row.loginName);if(index!==-1)sourceMembers.splice(index,1);this.$set(row,'isLeader',false);this.findGroup(target).push(row)},
|
||||
leaderChange(cluster,row){if(row.isLeader)cluster.members.forEach((item)=>{if(item.loginName!==row.loginName)this.$set(item,'isLeader',false)})},
|
||||
unSelectedChange(rows){this.$set(this,'unSelectedSelection',rows)},batchMove(){if(!this.batchTarget||!this.unSelectedSelection.length){this.$message.warning('请选择人员和目标团');return}this.unSelectedSelection.slice().forEach((row)=>this.moveMember(row,this.batchTarget,'unSelectedUsers'));this.$set(this,'batchVisible',false);this.$set(this,'batchTarget','')},
|
||||
saveCluster(){const empty=this.clusters.find((item)=>!item.members.length);if(empty){this.$message.warning(empty.clusterName+'未分配成员');return}this.$set(this,'formLoading',true);const data=this.clusters.map((item)=>({id:item.id,lineId:this.currentRow.id,clusterName:item.clusterName,members:item.members}));this.$axios.post(loc()+'/setClusterMembers',{lineId:this.currentRow.id,clusters:JSON.stringify(data)}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.$set(this,'clusterVisible',false);this.pageData()}else this.$message.warning(res.msg)}).finally(()=>{this.$set(this,'formLoading',false)})}
|
||||
},created(){this.$businessTool.listUnion().then((res)=>{this.$set(this,'unionOptions',res||[])});this.pageData()}})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
+8
-27
@@ -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() {
|
||||
|
||||
+15
-23
@@ -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()
|
||||
}
|
||||
})
|
||||
|
||||
+20
-38
@@ -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*/ `
|
||||
|
||||
+5
-8
@@ -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*/ `
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><search @search="doSearch">
|
||||
<search-item label="年度范围"><el-date-picker v-model="yearRange" type="yearrange" value-format="yyyy" range-separator="至" @change="yearChange"></el-date-picker></search-item>
|
||||
<search-item label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="线路类型"><el-select v-model="pageForm.regionalNature" clearable @change="filterChange"><el-option label="省内" value="省内"></el-option><el-option label="省外" value="省外"></el-option></el-select></search-item>
|
||||
<search-item label="组织方式"><el-select v-model="pageForm.signUpMode" clearable @change="filterChange"><el-option label="分工会组织" value="1"></el-option><el-option label="校工会组织" value="2"></el-option></el-select></search-item>
|
||||
<search-item label="线路"><el-select v-model="pageForm.takePartInLineId" filterable clearable @change="doSearch"><el-option v-for="item in lineOptions" :key="item.id" :label="item.lineName+'-'+item.regionalNature+'【'+(item.lotName||'')+'】('+item.signUpMode+')'" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="标段"><el-select v-model="pageForm.lotId" filterable clearable @change="doSearch"><el-option v-for="item in lots" :key="item.id" :label="item.lotName" :value="item.id"></el-option></el-select></search-item>
|
||||
</search></el-card>
|
||||
<el-card shadow="never" class="mt20"><table-tool label="线路报名统计"></table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :size="tableSize"><el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="year" label="年度" width="70"></el-table-column><el-table-column prop="lineName" label="线路名称" min-width="180"></el-table-column><el-table-column prop="linePlayTime" label="出行时间" width="150"></el-table-column><el-table-column prop="travelAgencyName" label="承担旅行社" min-width="150"></el-table-column><el-table-column prop="unionName" label="选择线路工会"></el-table-column><el-table-column prop="regionalNature" label="线路类型" width="90"></el-table-column><el-table-column prop="minimumGroupSize" label="最少成团人数" width="110"></el-table-column><el-table-column label="报名人数(家属)" width="130"><template v-slot="{row}"><el-link type="primary" @click="openUsers(row)">{{Number(row.lineNum||0)+Number(row.signUpUserFamilyNum||0)}}({{row.signUpUserFamilyNum||0}})</el-link></template></el-table-column><el-table-column label="操作" width="300"><template v-slot="{row}"><el-button size="mini" @click="openUsers(row)">查看人员</el-button><el-button type="success" size="mini" @click="notice(row,true,true)">成团通知</el-button><el-dropdown class="ml10"><el-button type="warning" size="mini">未成团通知<i class="el-icon-arrow-down el-icon--right"></i></el-button><el-dropdown-menu slot="dropdown"><el-dropdown-item @click.native="notice(row,false,true)">保留报名记录</el-dropdown-item><el-dropdown-item @click.native="notice(row,false,false)">删除报名记录</el-dropdown-item></el-dropdown-menu></el-dropdown></template></el-table-column></el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="线路报名人员" :visible.sync="userVisible" width="1050px" append-to-body><div class="mb10"><el-input v-model="userPage.searchKeyword" placeholder="姓名或工号" clearable style="width:220px" @keyup.enter.native="loadUsers"></el-input><el-button type="primary" class="ml10" @click="loadUsers">查询</el-button></div><el-table v-loading="userLoading" :data="users"><el-table-column type="index" label="序号" width="60"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="unionName" label="所属工会"></el-table-column><el-table-column prop="unitName" label="所属单位"></el-table-column><el-table-column prop="familyCount" label="家属人数" width="90"></el-table-column><el-table-column prop="linePlayTime" label="出行时间"></el-table-column></el-table><el-pagination class="mt20" background layout="total, sizes, prev, pager, next" :current-page="userPage.pageNumber" :page-size="userPage.pageSize" :total="userPage.totalCount" @current-change="userPageChange" @size-change="userSizeChange"></el-pagination></el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:'#app',mixins:[initTableMixins],data(){const year=new Date().getFullYear().toString();return{yearRange:[year,year],pageForm:{pageNumber:1,pageSize:10,totalCount:0,startYear:year,endYear:year,unionId:'',regionalNature:'',signUpMode:'',takePartInLineId:'',lotId:'',selectId:''},unionOptions:[],lineOptions:[],lots:[],userVisible:false,userLoading:false,currentRow:{},users:[],userPage:{pageNumber:1,pageSize:10,totalCount:0,searchKeyword:'',unionId:'',unitId:''}}},methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/pageData',this.pageForm).then((res)=>{if(res.code===0){this.$set(this,'tableData',res.data.list||[]);this.$set(this.pageForm,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
yearChange(value){this.$set(this.pageForm,'startYear',value[0]);this.$set(this.pageForm,'endYear',value[1]);this.filterChange()},filterChange(){this.$set(this.pageForm,'takePartInLineId','');this.loadLines();this.doSearch()},
|
||||
loadLines(){this.$axios.post(loc()+'/getLineOptions',{startYear:this.pageForm.startYear,endYear:this.pageForm.endYear,signUpMode:this.pageForm.signUpMode,regionalNature:this.pageForm.regionalNature}).then((res)=>{if(res.code===0)this.$set(this,'lineOptions',res.data||[])})},
|
||||
openUsers(row){this.$set(this,'currentRow',row);this.$set(this.userPage,'pageNumber',1);this.$set(this,'userVisible',true);this.loadUsers()},loadUsers(){this.$set(this,'userLoading',true);const params=Object.assign({},this.userPage,{takePartLineId:this.currentRow.lineUId});this.$axios.post(loc()+'/getUserDateByLine',params).then((res)=>{if(res.code===0){this.$set(this,'users',res.data.list||[]);this.$set(this.userPage,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'userLoading',false)})},userPageChange(value){this.$set(this.userPage,'pageNumber',value);this.loadUsers()},userSizeChange(value){this.$set(this.userPage,'pageSize',value);this.$set(this.userPage,'pageNumber',1);this.loadUsers()},
|
||||
notice(row,success,keep){const countUrl=success?'/countSuccessNotice':'/countFailNotice';this.$axios.post(loc()+countUrl,{id:row.lineUId}).then((res)=>{if(res.code!==0){this.$message.warning(res.msg);return}const data=res.data||{};if(!data.sendCount){this.$message.warning(data.msg);return}this.$prompt('当前将通过'+data.sendTypeName+'发送'+data.sendCount+'人,请确认消息内容。','提示',{inputType:'textarea',inputValue:data.content||'',inputValidator:(value)=>!!(value&&value.trim()),inputErrorMessage:'消息内容不能为空'}).then((prompt)=>{const url=success?'/sendSuccess':'/sendFail';this.$axios.post(loc()+url,{id:row.lineUId,type:keep,content:prompt.value}).then((sendRes)=>{if(sendRes.code===0){const result=sendRes.data||{};this.$message.success(result.msg||'通知发送完成');this.pageData()}else this.$message.warning(sendRes.msg)})}).catch(()=>{})})}
|
||||
},created(){this.$businessTool.listUnion().then((res)=>{this.$set(this,'unionOptions',res||[])});this.$axios.post('/platform/recuperation/config/fetchOne').then((res)=>{if(res.code===0)this.$set(this,'lots',(res.data&&res.data.lots)||[])});this.loadLines();this.pageData()}})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
+28
-44
@@ -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()
|
||||
}
|
||||
})
|
||||
|
||||
+264
-46
@@ -71,26 +71,51 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never" class="filter-container">
|
||||
<el-form :model="pageForm" ref="pageFormRef" label-width="90px" size="medium">
|
||||
<div class="form-row">
|
||||
<el-form-item label="年度">
|
||||
<el-form-item label="开始年度">
|
||||
<el-date-picker
|
||||
v-model="pageForm.year"
|
||||
v-model="pageForm.startYear"
|
||||
type="year"
|
||||
placeholder="选择年度"
|
||||
placeholder="选择开始年度"
|
||||
value-format="yyyy"
|
||||
style="width: 100%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="pageForm.userName" placeholder="请输入姓名" clearable
|
||||
prefix-icon="el-icon-user"></el-input>
|
||||
<el-form-item label="结束年度">
|
||||
<el-date-picker v-model="pageForm.endYear" type="year" placeholder="选择结束年度"
|
||||
value-format="yyyy" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号">
|
||||
<el-input v-model="pageForm.loginName" placeholder="请输入工号" clearable
|
||||
prefix-icon="el-icon-postcard"></el-input>
|
||||
<el-form-item label="人员查询">
|
||||
<el-input v-model="pageForm.searchKeyword" placeholder="请输入姓名或工号" clearable>
|
||||
<el-select v-model="pageForm.searchName" slot="prepend" style="width: 90px">
|
||||
<el-option label="姓名" value="userName"></el-option>
|
||||
<el-option label="工号" value="loginName"></el-option>
|
||||
</el-select>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="route-line">
|
||||
<div class="route-line-title">报名状态</div>
|
||||
<div class="route-line-content">
|
||||
<el-radio-group v-model="pageForm.signUpStatus" size="small" @change="changeSignUpStatus">
|
||||
<el-radio-button :label="1">已报名</el-radio-button>
|
||||
<el-radio-button :label="0">未报名</el-radio-button>
|
||||
<el-radio-button :label="2">未成团</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-radio-group v-if="pageForm.signUpStatus===1" v-model="pageForm.isTakePartIn"
|
||||
size="small" class="ml20" @change="doSearch">
|
||||
<el-radio-button label="">全部</el-radio-button>
|
||||
<el-radio-button :label="1">已参加</el-radio-button>
|
||||
<el-radio-button :label="0">未参加</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-radio-group v-if="pageForm.signUpStatus===2" v-model="pageForm.unFormedType"
|
||||
size="small" class="ml20" @change="doSearch">
|
||||
<el-radio-button label="line">线路</el-radio-button>
|
||||
<el-radio-button label="flexible">灵活组团</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<el-form-item label="分工会">
|
||||
<el-form-item v-if="schoolMode" label="分工会">
|
||||
<el-select v-model="pageForm.unionId"
|
||||
@change="doSearch"
|
||||
placeholder="请选择所属工会"
|
||||
@@ -106,6 +131,33 @@ layout("/layouts/platform.html"){
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="route-line" v-if="pageForm.signUpStatus===1">
|
||||
<div class="route-line-title">报名类型</div>
|
||||
<div class="route-line-content">
|
||||
<el-radio-group v-model="pageForm.state" size="small" @change="changeState">
|
||||
<el-radio-button :label="1">线路({{categoryCount.xlCount||0}})</el-radio-button>
|
||||
<el-radio-button :label="2">灵活组团({{categoryCount.lxsCount||0}})</el-radio-button>
|
||||
<el-radio-button :label="3">定点({{categoryCount.jdCount||0}})</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row" v-if="pageForm.signUpStatus===1">
|
||||
<el-form-item label="报名时间">
|
||||
<el-date-picker v-model="signTime" type="daterange" range-separator="至"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd" style="width:100%" @change="changeSignTime"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="pageForm.state===2" label="旅行社">
|
||||
<el-select v-model="pageForm.agencyId" filterable clearable style="width:100%" @change="doSearch">
|
||||
<el-option v-for="item in agencyOptions" :key="item.id" :label="item.travelAgencyName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="pageForm.state===3" label="定点">
|
||||
<el-select v-model="pageForm.takePartInBaseManagementId" filterable clearable style="width:100%" @change="doSearch">
|
||||
<el-option v-for="item in baseOptions" :key="item.id" :label="item.baseName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="route-line">
|
||||
<div class="route-line-title">区域</div>
|
||||
<div class="route-line-content">
|
||||
@@ -150,13 +202,17 @@ layout("/layouts/platform.html"){
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="人员列表" ref="table_tool">
|
||||
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
|
||||
<el-button icon="el-icon-message" size="small" type="primary" @click="openRemind">一键提醒</el-button>
|
||||
<el-button v-if="schoolMode&&pageForm.signUpStatus===1" icon="el-icon-upload2" size="small" type="primary"
|
||||
@click="openImport">参加人员导入</el-button>
|
||||
<el-button v-if="schoolMode&&pageForm.signUpStatus===1" icon="el-icon-folder-opened" size="small" type="primary" @click="exportZip">导出Zip</el-button>
|
||||
<el-button v-if="schoolMode" icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
|
||||
导出未报名人员
|
||||
</el-button>
|
||||
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="doExport">
|
||||
导出
|
||||
</el-button>
|
||||
<el-button icon="el-icon-s-promotion" size="small" type="primary"
|
||||
<el-button v-if="pageForm.signUpStatus===1" icon="el-icon-s-promotion" size="small" type="primary"
|
||||
@click="openSetUpPart"
|
||||
>设置参加人员
|
||||
</el-button>
|
||||
@@ -210,11 +266,17 @@ layout("/layouts/platform.html"){
|
||||
{{row.lotName}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="250px">
|
||||
<el-table-column v-if="pageForm.signUpStatus===1" label="操作" width="250px">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||
<el-button @click="onDelete(row)" size="mini" type="danger">删除</el-button>
|
||||
<el-dropdown class="ml10" trigger="click">
|
||||
<el-button size="mini" type="primary">调整<i class="el-icon-arrow-down el-icon--right"></i></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="restoreEnroll(row)">保留报名记录</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="onDelete(row)">删除报名记录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -227,11 +289,32 @@ layout("/layouts/platform.html"){
|
||||
<enroll-info ref="enrollInfoRef"></enroll-info>
|
||||
</el-dialog>
|
||||
|
||||
<set-up-part ref="setUpRef"></set-up-part>
|
||||
<set-up-part ref="setUpRef" @refresh="doSearch"></set-up-part>
|
||||
|
||||
<edit-form ref="editRef" @refresh="doSearch"></edit-form>
|
||||
|
||||
<el-dialog title="发送提醒" :visible.sync="remindVisible" width="560px">
|
||||
<div class="mb10">将按当前筛选条件提醒人员,请确认提醒内容。</div>
|
||||
<el-input v-model="remindContent" type="textarea" :rows="5"></el-input>
|
||||
<template slot="footer">
|
||||
<el-button @click="remindVisible=false">取消</el-button>
|
||||
<el-button type="primary" :loading="remindLoading" @click="sendRemind">发送</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="参加人员导入" :visible.sync="importVisible" width="700px" append-to-body>
|
||||
<el-button type="primary" size="small" class="mb20" @click="downloadImportTemplate">下载导入模板</el-button>
|
||||
<el-upload ref="importUpload" drag :action="queryBase+'/enrollImport'" name="file" :auto-upload="false" :limit="1" :on-success="importSuccess" :on-error="importError" accept=".xls,.xlsx">
|
||||
<i class="el-icon-upload"></i><div class="el-upload__text">将 Excel 文件拖到此处,或<em>点击选择</em></div><div slot="tip" class="el-upload__tip">按参加时间所属年度匹配省外线路报名</div>
|
||||
</el-upload>
|
||||
<el-alert v-if="importResult.totalCount" class="mt20" :closable="false" type="info" :title="'总记录 '+importResult.totalCount+',成功 '+importResult.successCount+',失败 '+importResult.errorCount"></el-alert>
|
||||
<el-button v-if="importResult.errorCount" type="text" @click="importErrorVisible=true">查看错误记录</el-button>
|
||||
<template slot="footer"><el-button @click="importVisible=false">关闭</el-button><el-button type="primary" :loading="importLoading" @click="submitImport">开始导入</el-button></template>
|
||||
</el-dialog>
|
||||
<el-dialog title="导入错误记录" :visible.sync="importErrorVisible" width="900px" append-to-body><el-table :data="importResult.errorList||[]"><el-table-column prop="no" label="Excel行" width="80"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="takePartInTime" label="参加时间"></el-table-column><el-table-column prop="lotName" label="标段时间"></el-table-column><el-table-column prop="errors" label="失败原因" min-width="260"></el-table-column></el-table></el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
const queryBase = "${queryBase!'/platform/recuperation/schoolUnionUserQuery'}"
|
||||
const schoolMode = ${schoolMode!true}
|
||||
<!--#include('setUpPart.js'){}#-->
|
||||
<!--#include('editForm.js'){}#-->
|
||||
<!--#include('../line/info.js'){}#-->
|
||||
@@ -248,12 +331,20 @@ layout("/layouts/platform.html"){
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
year: new Date().getFullYear().toString(),
|
||||
loginName: '',
|
||||
userName: '',
|
||||
startYear: new Date().getFullYear().toString(),
|
||||
endYear: new Date().getFullYear().toString(),
|
||||
searchName: 'userName',
|
||||
searchKeyword: '',
|
||||
signUpStatus: 1,
|
||||
state: 1,
|
||||
isTakePartIn: '',
|
||||
unFormedType: 'line',
|
||||
takePartInLineId: '',
|
||||
unionId: '',
|
||||
signUpMode: 1,
|
||||
agencyId: '',
|
||||
takePartInBaseManagementId: '',
|
||||
// 校工会旧版默认查询全部组织形式;分工会仍默认查询分工会组织线路。
|
||||
signUpMode: schoolMode ? '' : 1,
|
||||
lotId: '',
|
||||
regionalNature: ''
|
||||
},
|
||||
@@ -270,28 +361,49 @@ layout("/layouts/platform.html"){
|
||||
],
|
||||
viewVisible: false,
|
||||
unionOptions: [],
|
||||
config: {}
|
||||
config: {},
|
||||
categoryCount: {},
|
||||
agencyOptions: [],
|
||||
baseOptions: [],
|
||||
signTime: [],
|
||||
remindVisible: false,
|
||||
remindLoading: false,
|
||||
remindContent: '',
|
||||
schoolMode: schoolMode,
|
||||
queryBase: queryBase,
|
||||
importVisible: false,
|
||||
importLoading: false,
|
||||
importErrorVisible: false,
|
||||
importResult: {totalCount:0,successCount:0,errorCount:0,errorList:[]}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetQuery() {
|
||||
this.pageForm = {
|
||||
year: new Date().getFullYear().toString(),
|
||||
loginName: '',
|
||||
userName: '',
|
||||
this.$set(this, 'pageForm', {
|
||||
startYear: new Date().getFullYear().toString(),
|
||||
endYear: new Date().getFullYear().toString(),
|
||||
searchName: 'userName',
|
||||
searchKeyword: '',
|
||||
signUpStatus: 1,
|
||||
state: 1,
|
||||
isTakePartIn: '',
|
||||
unFormedType: 'line',
|
||||
takePartInLineId: '',
|
||||
unionId: '',
|
||||
signUpMode: 1,
|
||||
agencyId: '',
|
||||
takePartInBaseManagementId: '',
|
||||
// 重置后保持与页面初始查询口径一致,避免校工会被隐藏条件 signUpMode=1 限制。
|
||||
signUpMode: schoolMode ? '' : 1,
|
||||
lotId: '',
|
||||
regionalNature: '',
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
}
|
||||
})
|
||||
this.doSearch()
|
||||
},
|
||||
openView(row) {
|
||||
this.viewVisible = true
|
||||
this.$set(this, 'viewVisible', true)
|
||||
this.$nextTick(() => {
|
||||
this.$refs.enrollInfoRef.onOpen(row.id)
|
||||
})
|
||||
@@ -305,23 +417,27 @@ layout("/layouts/platform.html"){
|
||||
cancelButtonText: '取消',
|
||||
dangerouslyUseHTMLString: true,
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
const {code, msg} = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/deleteMyEnrollInfoById', {
|
||||
}).then(() => {
|
||||
this.$axios.post(queryBase + '/deleteMyEnrollInfoById', {
|
||||
id: row.id
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doSearch()
|
||||
this.$message.success(res.msg)
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
})
|
||||
if (code === 0) {
|
||||
this.doSearch()
|
||||
this.$message.success(msg)
|
||||
} else {
|
||||
this.$message.warning(msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
noSignExport() {
|
||||
this.$downLoad('/platform/recuperation/schoolUnionUserQuery/noSignExport')
|
||||
this.$downLoad(queryBase + '/noSignExport')
|
||||
},
|
||||
doExport() {
|
||||
this.$downLoad('/platform/recuperation/schoolUnionUserQuery/exportXlsx', this.pageForm)
|
||||
this.$downLoad(queryBase + '/exportManagement', this.pageForm)
|
||||
},
|
||||
exportZip() {
|
||||
this.$downLoad(queryBase + '/exportZip', this.pageForm)
|
||||
},
|
||||
openSetUpPart() {
|
||||
const selection = this.$refs.tableRef.selection
|
||||
@@ -335,33 +451,135 @@ layout("/layouts/platform.html"){
|
||||
getConfig() {
|
||||
this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.config = res.data
|
||||
const config = res.data || {}
|
||||
const lots = (config.lots || []).filter((item, index, list) => {
|
||||
// 标段 ID 是业务主键,同一 ID 只保留首次出现的数据,避免 Vue 生成重复 key 和重复选项。
|
||||
return item && item.id && list.findIndex((lot) => lot && lot.id === item.id) === index
|
||||
})
|
||||
this.$set(config, 'lots', lots)
|
||||
this.$set(this, 'config', config)
|
||||
}
|
||||
})
|
||||
}).catch(() => { this.$message.error('疗休养配置接口请求失败') })
|
||||
},
|
||||
getLines() {
|
||||
this.$axios.post('/platform/recuperation/schoolUnionUserQuery/listLine', {
|
||||
year: this.pageForm.year,
|
||||
if (this.pageForm.state !== 1) {
|
||||
return
|
||||
}
|
||||
this.$axios.post(queryBase + '/listLine', {
|
||||
year: this.pageForm.startYear,
|
||||
unionId: this.pageForm.unionId,
|
||||
signUpMode: this.pageForm.signUpMode,
|
||||
regionalNature: this.pageForm.regionalNature
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.takePartInLines = res.data
|
||||
this.$set(this, 'takePartInLines', res.data)
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).catch(() => { this.$message.error('线路选项接口请求失败') })
|
||||
},
|
||||
changeSignUpStatus() {
|
||||
this.$set(this.pageForm, 'pageNumber', 1)
|
||||
this.doSearch()
|
||||
},
|
||||
changeState() {
|
||||
this.$set(this.pageForm, 'takePartInLineId', '')
|
||||
this.$set(this.pageForm, 'agencyId', '')
|
||||
this.$set(this.pageForm, 'takePartInBaseManagementId', '')
|
||||
this.doSearch()
|
||||
},
|
||||
changeSignTime(value) {
|
||||
this.$set(this.pageForm, 'signStartTime', value && value.length ? value[0] : '')
|
||||
this.$set(this.pageForm, 'signEndTime', value && value.length ? value[1] + ' 23:59:59' : '')
|
||||
this.doSearch()
|
||||
},
|
||||
getCategoryCount() {
|
||||
this.$axios.post(queryBase + '/getCategoryCount', this.pageForm).then((res) => {
|
||||
if (res.code === 0) this.$set(this, 'categoryCount', res.data || {})
|
||||
}).catch(() => { this.$message.error('报名分类统计接口请求失败') })
|
||||
},
|
||||
getManagementOptions() {
|
||||
if (this.pageForm.state === 2) {
|
||||
this.$axios.post('/platform/recuperation/travelAgency/selectTravelAgencyByYears', {
|
||||
startYear: this.pageForm.startYear,
|
||||
endYear: this.pageForm.endYear
|
||||
}).then((res) => { if (res.code === 0) this.$set(this, 'agencyOptions', res.data || []) })
|
||||
}
|
||||
if (this.pageForm.state === 3) {
|
||||
this.$axios.post('/platform/recuperation/baseManagement/listAllBase', this.pageForm).then((res) => {
|
||||
if (res.code === 0) this.$set(this, 'baseOptions', res.data || [])
|
||||
})
|
||||
}
|
||||
},
|
||||
restoreEnroll(row) {
|
||||
this.$axios.post(queryBase + '/restoreEnroll', {id: row.id}).then((res) => {
|
||||
if (res.code === 0) { this.$message.success(res.msg); this.doSearch() }
|
||||
})
|
||||
},
|
||||
openImport() {
|
||||
this.$set(this, 'importResult', {totalCount:0,successCount:0,errorCount:0,errorList:[]})
|
||||
this.$set(this, 'importVisible', true)
|
||||
this.$nextTick(() => { if (this.$refs.importUpload) this.$refs.importUpload.clearFiles() })
|
||||
},
|
||||
downloadImportTemplate() {
|
||||
this.$downLoad(queryBase + '/downloadImportTemplate')
|
||||
},
|
||||
submitImport() {
|
||||
if (!this.$refs.importUpload || !this.$refs.importUpload.uploadFiles.length) { this.$message.warning('请选择Excel文件'); return }
|
||||
this.$set(this, 'importLoading', true)
|
||||
this.$refs.importUpload.submit()
|
||||
},
|
||||
importSuccess(res) {
|
||||
this.$set(this, 'importLoading', false)
|
||||
if (res.code === 0) { this.$set(this, 'importResult', res.data || {}); this.$message.success(res.msg); this.doSearch() }
|
||||
else { this.$message.warning(res.msg); this.$refs.importUpload.clearFiles() }
|
||||
},
|
||||
importError() {
|
||||
this.$set(this, 'importLoading', false)
|
||||
this.$message.warning('文件上传失败')
|
||||
},
|
||||
openRemind() {
|
||||
this.$set(this, 'remindContent', this.config.remindContent || '')
|
||||
this.$set(this, 'remindVisible', true)
|
||||
},
|
||||
sendRemind() {
|
||||
this.$set(this, 'remindLoading', true)
|
||||
this.$axios.post(queryBase + '/remindUsers', Object.assign({}, this.pageForm, {
|
||||
content: this.remindContent,
|
||||
loginNames: this.$refs.tableRef.selection.map((item) => item.loginName).join(',')
|
||||
})).then((res) => {
|
||||
if (res.code === 0) { this.$message.success(res.msg); this.$set(this, 'remindVisible', false) }
|
||||
else this.$message.warning(res.msg)
|
||||
}).finally(() => { this.$set(this, 'remindLoading', false) })
|
||||
},
|
||||
doSearch(){
|
||||
this.getLines()
|
||||
this.tableKey = new Date().getTime()
|
||||
this.pageForm.pageNumber = 1
|
||||
this.getManagementOptions()
|
||||
this.getCategoryCount()
|
||||
this.$set(this, 'tableKey', new Date().getTime())
|
||||
this.$set(this.pageForm, 'pageNumber', 1)
|
||||
this.pageData()
|
||||
},
|
||||
// 共用模板必须使用 Controller 下发的接口前缀,避免 Pjax 场景下 loc() 取到外层页面地址。
|
||||
pageData() {
|
||||
this.$set(this, 'tableLoading', true)
|
||||
this.$axios.post(queryBase + '/pageData', this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'tableData', res.data.list || [])
|
||||
this.$set(this.pageForm, 'totalCount', res.data.totalCount || 0)
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.error('人员分页接口请求失败')
|
||||
}).finally(() => {
|
||||
this.$set(this, 'tableLoading', false)
|
||||
})
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
|
||||
created() {
|
||||
this.$businessTool.listUnion().then((res) => this.$set(this, 'unionOptions', res || []))
|
||||
.catch(() => { this.$message.error('工会选项接口请求失败') })
|
||||
this.doSearch()
|
||||
this.getConfig()
|
||||
}
|
||||
|
||||
+13
-17
@@ -61,11 +61,10 @@ const setUpPart = {
|
||||
this.tableData = JSON.parse(JSON.stringify(selection))
|
||||
this.getModifyConfig()
|
||||
},
|
||||
async getModifyConfig() {
|
||||
const res = await this.$axios.post('/platform/recuperation/config/fetchOne')
|
||||
if (res.code === 0) {
|
||||
this.config = res.data
|
||||
}
|
||||
getModifyConfig() {
|
||||
this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => {
|
||||
if (res.code === 0) this.config = res.data
|
||||
})
|
||||
},
|
||||
// 标段改变
|
||||
lotChange(val) {
|
||||
@@ -122,18 +121,15 @@ const setUpPart = {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async res => {
|
||||
const {
|
||||
code,
|
||||
msg
|
||||
} = await this.$axios.post("/platform/recuperation/schoolUnionUserQuery/setUpParticipants", {data: JSON.stringify(data)})
|
||||
if (code === 0) {
|
||||
this.$message.success(msg)
|
||||
this.$refs.tableRef.clearSelection()
|
||||
this.visible = false
|
||||
} else {
|
||||
this.$message.error(msg)
|
||||
}
|
||||
}).then(() => {
|
||||
this.$axios.post(queryBase + "/setUpParticipants", {data: JSON.stringify(data)}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.$refs.tableRef.clearSelection()
|
||||
this.visible = false
|
||||
this.$emit('refresh')
|
||||
} else this.$message.error(res.msg)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+15
-183
@@ -1,187 +1,19 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
placeholder="请选择年度"
|
||||
type="year"
|
||||
@change="yearChange"
|
||||
style="width: 100%"
|
||||
v-model="pageForm.year"
|
||||
value-format="yyyy"
|
||||
></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="线路">
|
||||
<el-select @change="doSearch" filterable
|
||||
placeholder="请选择线路"
|
||||
style="width: 100%;" clearable
|
||||
v-model="pageForm.lineId">
|
||||
<el-option :label="item.lineName + '(' + item.unionName + ')'" :value="item.id"
|
||||
:key="value.id"
|
||||
v-for="item in lineList"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="姓名/工号">
|
||||
<el-input placeholder="请输入姓名或工号查询" clearable v-model="pageForm.searchKeyword"
|
||||
@keyup.enter.native="doSearch"></el-input>
|
||||
</search-item>
|
||||
<search-item label="所属工会">
|
||||
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会" filterable clearable @change="doSearch">
|
||||
<el-option v-for="item in unionList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="所属单位">
|
||||
<el-select v-model="pageForm.unitId" placeholder="请选择所属单位" filterable clearable @change="doSearch">
|
||||
<el-option v-for="item in unitList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="评分:">
|
||||
<el-select clearable filterable placeholder="请选择评分"
|
||||
style="width: 100%" @change="doSearch"
|
||||
v-model="pageForm.evaluateScore">
|
||||
<el-option
|
||||
:key="item.code"
|
||||
:label="item.name"
|
||||
:value="item.code"
|
||||
v-for="item in evaluateScores">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool label="评价名单">
|
||||
<el-button type="primary" size="small" @click="exportEvaluate">
|
||||
<i class="el-icon-download"></i>
|
||||
导出名单
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize">
|
||||
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
|
||||
<el-table-column
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:key="column.prop"
|
||||
:width="column.width"
|
||||
:sortable="column.sortable"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
v-for="column in tableColumns"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="{ row }">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="evaluateDialogVisible"
|
||||
title="评分内容"
|
||||
width="30%">
|
||||
<el-form :model="formData" label-width="60px" ref="form">
|
||||
<el-form-item :rules="[{ required: true, message: ''}]" label="评分">
|
||||
<span>{{viewData.evaluateScore}}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="评价">
|
||||
<span>{{viewData.evaluateText}}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span class="dialog-footer" slot="footer">
|
||||
<el-button @click="evaluateDialogVisible = false" type="primary">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-card shadow="never"><el-row type="flex" align="middle"><el-col :span="8"><span>统计年度:</span><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" :clearable="false" @change="yearChange"></el-date-picker></el-col><el-col :span="16"><el-tabs v-model="activeTab" @tab-click="tabChange"><el-tab-pane label="满意度统计" name="summary"></el-tab-pane><el-tab-pane label="评价建议明细" name="feedback"></el-tab-pane><el-tab-pane label="评价人员名单" name="users"></el-tab-pane></el-tabs></el-col></el-row></el-card>
|
||||
<template v-if="activeTab==='summary'">
|
||||
<el-row :gutter="20" class="mt20"><el-col :span="8"><el-card shadow="never"><div slot="header">旅行社综合满意度</div><el-table v-loading="summaryLoading" :data="agencyRatings" height="530"><el-table-column type="index" label="排名" width="65"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" show-overflow-tooltip></el-table-column><el-table-column prop="avg" label="综合评分" width="90"><template v-slot="{row}">{{score(row.avg)}}</template></el-table-column><el-table-column prop="ratingCount" label="评价人数" width="85"></el-table-column></el-table></el-card></el-col><el-col :span="16"><el-card shadow="never"><div slot="header">方案服务评分</div><el-table v-loading="summaryLoading" :data="schemeRatings" height="530"><el-table-column prop="typeName" label="类型" width="85"></el-table-column><el-table-column prop="schemeName" label="方案名称" min-width="150" show-overflow-tooltip></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" min-width="130" show-overflow-tooltip></el-table-column><el-table-column label="旅行社" width="75"><template v-slot="{row}">{{score(row.travelAgencyAvg)}}</template></el-table-column><el-table-column label="行程" width="65"><template v-slot="{row}">{{score(row.journeyAvg)}}</template></el-table-column><el-table-column label="住宿/酒店" width="90"><template v-slot="{row}">{{score(row.accommodationAvg)}}</template></el-table-column><el-table-column label="餐饮" width="65"><template v-slot="{row}">{{score(row.diningAvg)}}</template></el-table-column><el-table-column label="交通" width="65"><template v-slot="{row}">{{score(row.transportationAvg)}}</template></el-table-column><el-table-column label="综合" width="65"><template v-slot="{row}"><strong>{{score(row.compositeAvg)}}</strong></template></el-table-column><el-table-column prop="ratingCount" label="人数" width="65"></el-table-column></el-table></el-card></el-col></el-row>
|
||||
</template>
|
||||
<template v-if="activeTab==='feedback'"><el-card shadow="never" class="mt20"><table-tool label="评价建议"><el-select v-model="feedbackType" size="small" style="width:140px" @change="loadFeedback"><el-option v-for="item in ['全部','线路','灵活组团','定点']" :key="item" :label="item" :value="item"></el-option></el-select><el-button type="primary" size="small" class="ml10" @click="exportFeedback">导出评价明细</el-button></table-tool><el-table v-loading="feedbackLoading" :data="feedbackDetails"><el-table-column type="index" label="序号" width="60"></el-table-column><el-table-column prop="typeName" label="报名方式" width="100"></el-table-column><el-table-column prop="schemeName" label="方案名称" min-width="160"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" min-width="140"></el-table-column><el-table-column prop="userName" label="评价人" width="100"></el-table-column><el-table-column prop="unitName" label="所属单位" min-width="140"></el-table-column><el-table-column prop="compositeScore" label="综合评分" width="100"></el-table-column><el-table-column prop="feedbackContent" label="评价建议" min-width="240" show-overflow-tooltip></el-table-column><el-table-column label="操作" width="80"><template v-slot="{row}"><el-button type="primary" size="mini" @click="viewFeedback(row)">查看</el-button></template></el-table-column></el-table></el-card></template>
|
||||
<template v-if="activeTab==='users'"><el-card shadow="never" class="mt20"><search @search="doSearch"><search-item label="线路"><el-select v-model="pageForm.lineId" filterable clearable @change="doSearch"><el-option v-for="item in lineList" :key="item.id" :label="item.lineName+'('+item.unionName+')'" :value="item.id"></el-option></el-select></search-item><search-item label="姓名/工号"><el-input v-model="pageForm.searchKeyword" clearable @keyup.enter.native="doSearch"></el-input></search-item><search-item label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionList" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item><search-item label="所属单位"><el-select v-model="pageForm.unitId" filterable clearable @change="doSearch"><el-option v-for="item in unitList" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item><search-item label="评分"><el-select v-model="pageForm.evaluateScore" clearable @change="doSearch"><el-option v-for="item in ['满意','一般','不满意']" :key="item" :label="item" :value="item"></el-option></el-select></search-item></search><table-tool label="评价人员名单"><el-button type="primary" size="small" @click="exportEvaluate">导出名单</el-button></table-tool><el-table v-loading="tableLoading" :data="tableData"><el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="lineName" label="线路"></el-table-column><el-table-column prop="playStartTime" label="出行时间"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="unitName" label="所属单位"></el-table-column><el-table-column prop="unionName" label="所属工会"></el-table-column><el-table-column prop="evaluateScore" label="评分"></el-table-column><el-table-column prop="evaluateText" label="评价" show-overflow-tooltip></el-table-column></el-table><!--#include("/layouts/pagination.html"){}#--></el-card></template>
|
||||
<el-dialog title="评价详情" :visible.sync="feedbackVisible" width="650px" append-to-body><el-descriptions :column="2" border><el-descriptions-item label="报名方式">{{feedbackDetail.typeName}}</el-descriptions-item><el-descriptions-item label="综合评分">{{feedbackDetail.compositeScore}}</el-descriptions-item><el-descriptions-item label="旅行社评分">{{feedbackDetail.evaluationForTravelAgency}}</el-descriptions-item><el-descriptions-item label="住宿/酒店评分">{{feedbackDetail.evaluationForAccommodation}}</el-descriptions-item><el-descriptions-item label="行程评分">{{feedbackDetail.evaluationForJourney}}</el-descriptions-item><el-descriptions-item label="餐饮评分">{{feedbackDetail.evaluationForDining}}</el-descriptions-item><el-descriptions-item label="交通评分">{{feedbackDetail.evaluationForTransportation}}</el-descriptions-item><el-descriptions-item label="方案">{{feedbackDetail.schemeName}}</el-descriptions-item></el-descriptions><el-alert class="mt20" :closable="false" :title="feedbackDetail.feedbackContent||'暂无评价建议'" type="info"></el-alert></el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
unionList: [],
|
||||
unitList: [],
|
||||
lineList: [],
|
||||
evaluateDialogVisible: false,
|
||||
tableColumns: [
|
||||
{prop: 'lineName', label: '线路'},
|
||||
{prop: 'playStartTime', label: '出行时间'},
|
||||
{prop: 'loginName', label: '工号'},
|
||||
{prop: 'userName', label: '姓名'},
|
||||
{prop: 'unitName', label: '所属单位'},
|
||||
{prop: 'unionName', label: '所属工会'},
|
||||
{prop: 'evaluateScore', label: '评分', sortable: true},
|
||||
{prop: 'evaluateText', label: '评价'},
|
||||
],
|
||||
viewData: {},
|
||||
evaluateScores: [
|
||||
{name: "满意", code: "满意"},
|
||||
{name: "一般", code: "一般"},
|
||||
{name: "不满意", code: "不满意"},
|
||||
],
|
||||
pageForm: {
|
||||
year: new Date().getFullYear().toString(),
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
exportEvaluate() {
|
||||
this.$downLoad(loc() + '/exportEvaluate', this.pageForm)
|
||||
},
|
||||
onView(row) {
|
||||
this.viewData = {
|
||||
lineId: row.id,
|
||||
evaluateText: row.evaluateText,
|
||||
evaluateScore: row.evaluateScore,
|
||||
}
|
||||
this.evaluateDialogVisible = true
|
||||
},
|
||||
async getLineList() {
|
||||
const resp = await this.$axios.post(loc() + '/lineList', {year: this.pageForm.year})
|
||||
this.lineList = resp.data
|
||||
},
|
||||
async yearChange() {
|
||||
this.$set(this.pageForm, "lineId", null)
|
||||
await this.getLineList()
|
||||
this.doSearch()
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.list
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.unitList = await this.$businessTool.listUnit()
|
||||
await this.getLineList()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
new Vue({el:'#app',mixins:[initTableMixins],data(){return{activeTab:'summary',pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear().toString(),lineId:'',searchKeyword:'',unionId:'',unitId:'',evaluateScore:''},unionList:[],unitList:[],lineList:[],summaryLoading:false,feedbackLoading:false,agencyRatings:[],schemeRatings:[],feedbackDetails:[],feedbackType:'全部',feedbackVisible:false,feedbackDetail:{}}},methods:{
|
||||
score(value){return value===null||value===undefined||value===''?'—':Number(value).toFixed(1)},yearChange(){this.$set(this.pageForm,'lineId','');this.loadLines();this.loadSummary();if(this.activeTab==='feedback')this.loadFeedback();if(this.activeTab==='users')this.doSearch()},tabChange(){if(this.activeTab==='summary')this.loadSummary();if(this.activeTab==='feedback')this.loadFeedback();if(this.activeTab==='users')this.pageData()},
|
||||
loadSummary(){this.$set(this,'summaryLoading',true);this.$axios.post(loc()+'/getSatisfactionRatingStatistics',{year:this.pageForm.year}).then((res)=>{if(res.code===0){this.$set(this,'agencyRatings',(res.data&&res.data.travelAgencyCompositeRatings)||[]);this.$set(this,'schemeRatings',(res.data&&res.data.schemeServiceRatings)||[])}}).finally(()=>{this.$set(this,'summaryLoading',false)})},
|
||||
loadFeedback(){this.$set(this,'feedbackLoading',true);this.$axios.post(loc()+'/getSatisfactionFeedbackDetails',{year:this.pageForm.year,typeName:this.feedbackType}).then((res)=>{if(res.code===0)this.$set(this,'feedbackDetails',res.data||[])}).finally(()=>{this.$set(this,'feedbackLoading',false)})},exportFeedback(){this.$downLoad(loc()+'/exportSatisfactionFeedbackDetails',{year:this.pageForm.year,typeName:this.feedbackType})},viewFeedback(row){this.$set(this,'feedbackDetail',row);this.$set(this,'feedbackVisible',true)},
|
||||
loadLines(){this.$axios.post(loc()+'/lineList',{year:this.pageForm.year}).then((res)=>{if(res.code===0)this.$set(this,'lineList',res.data||[])})},pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/pageData',this.pageForm).then((res)=>{if(res.code===0){this.$set(this,'tableData',res.data.list||[]);this.$set(this.pageForm,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'tableLoading',false)})},exportEvaluate(){this.$downLoad(loc()+'/exportEvaluate',this.pageForm)}
|
||||
},created(){this.$businessTool.listUnion().then((res)=>this.$set(this,'unionList',res||[]));this.$businessTool.listUnit().then((res)=>this.$set(this,'unitList',res||[]));this.loadLines();this.loadSummary()}})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
<!--# } #-->
|
||||
|
||||
Reference in New Issue
Block a user