From 3b1041edeeef05320ea1efd847973417d2e04b8a Mon Sep 17 00:00:00 2001 From: "@jyuhsin" <729757837@qq.com> Date: Tue, 2 Sep 2025 19:01:08 +0800 Subject: [PATCH] commit --- .../service/impl/FamilyUserServiceImpl.java | 2 +- .../literacy/constant/ColumnFormTypeEnum.java | 24 + .../manage/LiteracyActivityAddController.java | 96 +++ .../LiteracyActivityApplyController.java | 176 ++++++ .../manage/LiteracyActivityController.java | 144 +++++ .../manage/LiteracyTypeController.java | 167 +++++ .../manage/LiteracyUserAdjustController.java | 179 ++++++ ...LiteracyUserBlackListManageController.java | 347 ++++++++++ .../mobile/MLiteracyActivityController.java | 373 +++++++++++ ...teracyActivityScannerQrCodeController.java | 201 ++++++ .../LiteracyActivityStatisticsController.java | 254 ++++++++ .../literacy/models/LiteracyActivity.java | 136 ++++ .../models/LiteracyActivityCourse.java | 56 ++ .../literacy/models/LiteracyBlackList.java | 31 + .../literacy/models/LiteracyCourse.java | 160 +++++ .../models/LiteracyMobileSignColumn.java | 79 +++ .../literacy/models/LiteracyType.java | 68 ++ .../literacy/models/LiteracyTypeLimit.java | 40 ++ .../literacy/models/LiteracyUser.java | 88 +++ .../literacy/models/LiteracyUserCourse.java | 89 +++ .../service/LiteracyActivityService.java | 129 ++++ .../LiteracyActivityStatisticsService.java | 68 ++ .../service/LiteracyBlackListService.java | 43 ++ .../impl/LiteracyActivityServiceImpl.java | 473 ++++++++++++++ ...LiteracyActivityStatisticsServiceImpl.java | 260 ++++++++ .../service/impl/LiteracyUserServiceImpl.java | 103 +++ .../impl/TrainSignUpUserServiceImpl.java | 2 +- .../apply/ClubUserJoinMineController.java | 8 +- .../statistics/ClubStatisticsController.java | 4 +- .../app/zhgh/club/vo/ClubUserImportVo.java | 3 - .../app/zhgh/club/vo/ClubUserJoinVo.java | 4 + .../controller/MeetingOnlineController.java | 6 +- .../MeetingStatisticsController.java | 182 ++++++ .../meeting/service/MeetingUserService.java | 36 ++ .../impl/MeetingOnlineServiceImpl.java | 16 +- .../service/impl/MeetingUserServiceImpl.java | 176 ++++++ .../service/impl/SiteApplyServiceImpl.java | 3 +- .../zhgh/activity/literacy/apply/index.html | 121 ++++ .../zhgh/activity/literacy/apply/info.js | 306 +++++++++ .../zhgh/activity/literacy/apply/signForm.js | 216 +++++++ .../activity/literacy/manage/basicForm.js | 593 ++++++++++++++++++ .../activity/literacy/manage/courseTime.js | 215 +++++++ .../activity/literacy/manage/customForm.js | 211 +++++++ .../zhgh/activity/literacy/manage/index.html | 201 ++++++ .../zhgh/activity/literacy/manage/info.js | 111 ++++ .../activity/literacy/manage/makeQrcode.js | 82 +++ .../activity/literacy/manage/unionForm.js | 221 +++++++ .../activity/literacy/statistics/index.html | 156 +++++ .../zhgh/activity/literacy/statistics/info.js | 98 +++ .../zhgh/activity/literacy/type/basicForm.js | 350 +++++++++++ .../zhgh/activity/literacy/type/index.html | 120 ++++ .../activity/literacy/userAdjust/index.html | 144 +++++ .../activity/literacy/userAdjust/userInfo.js | 224 +++++++ .../activity/literacy/userManage/index.html | 235 +++++++ .../platform/zhgh/club/common/clubUserJoin.js | 2 +- .../platform/zhgh/club/join/apply/index.html | 9 +- .../club/register/apply/clubRegisterForm.js | 3 +- .../zhgh/club/register/apply/index.html | 8 +- .../dayofficework/meeting/online/index.html | 17 +- .../meeting/statistics/index.html | 147 +++++ .../meeting/statistics/periodsInfo.js | 186 ++++++ .../zhgh/dayofficework/site/apply/apply.js | 1 + .../dayofficework/site/manage/basicForm.js | 4 +- 63 files changed, 8171 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/constant/ColumnFormTypeEnum.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityAddController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityApplyController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyTypeController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserAdjustController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserBlackListManageController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityScannerQrCodeController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/controller/statistics/LiteracyActivityStatisticsController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivity.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivityCourse.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyBlackList.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyCourse.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyMobileSignColumn.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyType.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyTypeLimit.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUser.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUserCourse.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityService.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityStatisticsService.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyBlackListService.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityStatisticsServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyUserServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingStatisticsController.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/MeetingUserService.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingUserServiceImpl.java create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/apply/index.html create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/apply/info.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/apply/signForm.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/basicForm.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/courseTime.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/customForm.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/index.html create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/info.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/makeQrcode.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/manage/unionForm.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/statistics/index.html create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/statistics/info.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/type/basicForm.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/type/index.html create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/index.html create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/userInfo.js create mode 100644 src/main/resources/views/platform/zhgh/activity/literacy/userManage/index.html create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/meeting/statistics/index.html create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/meeting/statistics/periodsInfo.js diff --git a/src/main/java/com/budwk/app/zhgh/activity/family/service/impl/FamilyUserServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/family/service/impl/FamilyUserServiceImpl.java index 5436089e..e9fa7e17 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/family/service/impl/FamilyUserServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/activity/family/service/impl/FamilyUserServiceImpl.java @@ -40,7 +40,7 @@ public class FamilyUserServiceImpl extends BaseServiceImpl impl u.unionname, tsuc.courseName, tsuu.state, - ( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId $var) tourseTotal, + ( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId $var) courseTotal, ( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId AND isAttend = 0 and tsuu.state!=2 AND now()> courseEndTime $var) AS absentCount, if(tsubl.isDisabled=1,true,false) isDisabled, group_CONCAT( tsuc.courseName ) AS courseNames diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/constant/ColumnFormTypeEnum.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/constant/ColumnFormTypeEnum.java new file mode 100644 index 00000000..630f672b --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/constant/ColumnFormTypeEnum.java @@ -0,0 +1,24 @@ +package com.budwk.app.zhgh.activity.literacy.constant; + +import com.budwk.app.base.annotation.DictEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @Author JyuHsin + * @Date 2022/11/18 + * @Description + */ +@Getter +@DictEnum(key = "ColumnFormTypeEnum", name = "控件类型") +@AllArgsConstructor +public enum ColumnFormTypeEnum { + + INPUT("INPUT", "输入框"), + SELECT("SELECT", "选择框"), + //RADIO("RADIO", "单选框"),//选项数组 + FILE("FILE", "文件"); + + private String code; + private String description; +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityAddController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityAddController.java new file mode 100644 index 00000000..b19a159b --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityAddController.java @@ -0,0 +1,96 @@ +package com.budwk.app.zhgh.activity.literacy.controller.manage; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.List; + +/** + * @author zxy + * @Description 新建活动 + * @createTime 2022年03月07日 10:16:00 + */ +@Slf4j +@IocBean +@Api(tags = "新建品牌活动") +@At("/platform/literacy/manage/activity") +public class LiteracyActivityAddController { + + @Inject + private Dao dao; + @Inject + private LiteracyActivityService literacySignUpActivityManageService; + + @At + @Ok("json:full") + @ApiOperation("品牌活动新增/修改") + @SaCheckPermission("literacy.manage.activity") + @SLog(tag = "品牌活动-活动管理", msg = "新增/修改活动") + public Result doHandle(LiteracyActivity activity) { + if (StrUtil.isBlank(activity.getId())) { + literacySignUpActivityManageService.add(activity, null); + } else { + literacySignUpActivityManageService.edit(activity); + } + return Result.success(); + } + + @At + @Ok("json:full") + @ApiOperation("获取分工会人数限制") + @SaCheckPermission("literacy.manage.activity") + public Result getUnionLimit(@Param(value = "activityScopeId") String activityScopeId) { + Sql sql = Sqls.create(""" + SELECT + gh.id, + gh.name, + gh.unioncode, + (select count(1) from `vw_user` where unionid = gh.id $cnd) as teacherCount, + NULL as ratio, + NULL as limitCount + FROM + sys_union gh + order by gh.unioncode + """); + if (StrUtil.isNotBlank(activityScopeId)) { + sql.setVar("cnd", "AND id in (select userId from activity_user_scope where groupId = '" + activityScopeId + "')"); + } + List list = literacySignUpActivityManageService.listMap(sql); + return Result.success().addData(list); + } + + @At + @Ok("json:full") + @ApiOperation("获取报名人员数量") + @SaCheckPermission("literacy.manage.activity") + public Result getRegisterUserCount(@Param(value = "courseId") String courseId) { + return Result.success().addData(dao.count(LiteracyUser.class, Cnd.where("courseId", "=", courseId))); + } + + @At + @Ok("json:full") + @ApiOperation("获取历史活动列表") + @SaCheckPermission("literacy.manage.activity") + public Result getHistoricalActList() { + List query = dao.query(LiteracyActivity.class, Cnd.NEW().desc("activityStartTime")); + return Result.success().addData(query); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityApplyController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityApplyController.java new file mode 100644 index 00000000..03557139 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityApplyController.java @@ -0,0 +1,176 @@ +package com.budwk.app.zhgh.activity.literacy.controller.manage; + +import cn.dev33.satoken.annotation.SaCheckPermission; +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.result.Result; +import com.budwk.app.sys.models.Sys_dict; +import com.budwk.app.sys.services.SysDictService; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivityCourse; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.Static; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@IocBean +@Ok("json:full") +@Api(tags = "活动报名") +@At("/platform/literacy/manage/apply") +public class LiteracyActivityApplyController { + + @Inject + private LiteracyActivityService literacyActivityService; + @Inject + private SysDictService dictService; + @Inject + private LiteracyActivityStatisticsService statisticsService; + + @At("") + @SaCheckPermission("literacy.manage.apply") + @Ok("beetl:/platform/zhgh/activity/literacy/apply/index.html") + public void index() { + } + + @At + @ApiOperation("活动查询") + @SaCheckPermission("literacy.manage.apply") + public Result activityData(PageForm pageForm, + @Param(value = "year") Integer year, + @Param(value = "activityType") Integer activityType) { + Cnd cnd = Cnd.NEW(); + cnd.andEX("`year`", "=", year); + //查询报名中 + if (activityType == 2) { + cnd.and(new Static("now() > activitySignUpStartTime and now() < activitySignUpEndTime")); + }//查询已结束的 + else if (activityType == 3) { + cnd.and(new Static("now() > activityEndTime")); + } + + if (AuthUtil.hasRole("H04") && !AuthUtil.hasRoleOr("sysadmin, A06")) { + cnd.and("activityMode", "=", 2).and("createdBy", "=", SecurityUtil.getUserId()); + } + + Pagination pagination = literacyActivityService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd); + List literacyActivities = pagination.getList(); + Map literacyTypeMap = dictService.getSubListByCode("LITERACY_SIGNUP_TYPE").stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName)); + literacyActivities.forEach(v -> v.setLiteracyType(literacyTypeMap.get(v.getLiteracyType()))); + return Result.success(pagination); + } + + @At + @ApiOperation("分活动查询") + @SaCheckPermission("literacy.manage.apply") + public Result pageData(PageForm pageForm, + @Param(value = "courseTypeId") String courseTypeId, + @Param(value = "activityId") String activityId, + @Param(value = "assortTypes") String[] assortTypes) { + Sql sql = Sqls.create(""" + SELECT + tsuc.id, + tsuc.activityId, + tsuc.courseName, + tsuc.coursePeopleNumber, + tsuc.courseLocation, + tsuc.courseType, + tsuc.courseLocationCoordinates, + tsuc.courseReservedNumber, + tsuc.courseInstructor, + tsuc.campus, + tsuc.unionLimit, + tsuc.isMobileSign, + tsuc.signType, + tsuc.isReceiveGift, + tsuc.giftType, + tsuc.reserveMode, + tsuc.waitingNum, + tsuc.assort, + type.typeName, + tsuc.courseIsLimitApply + FROM + `literacy_course` tsuc + LEFT JOIN literacy_type type ON type.id = tsuc.courseType + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("type.id", "=", courseTypeId); + cnd.and("tsuc.activityId", "=", activityId); + if(Lang.isNotEmpty(assortTypes)) { + cnd.and("tsuc.assort", "in", assortTypes); + } + + List courseArray = literacyActivityService.dao().query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId)); + courseArray = literacyActivityService.filterCourseByHostUnion(courseArray); + cnd.and("tsuc.id", "in", courseArray.stream().map(LiteracyCourse::getId).toList()); + + cnd.asc("tsuc.orderNum"); + cnd.asc("type.code"); + sql.setCondition(cnd); + + Pagination pagination = literacyActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + List courseList = pagination.getList(); + + courseList.forEach(c -> { + c.put("hasRegisterNum", statisticsService.queryCourseCount(c.getString("id"), c.getString("courseType"))); + c.put("hasWaitingNum", statisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType"))); + //当前用户是否报过 + c.put("isSign", literacyActivityService.isSignCourseByUser(c.getString("id"), SecurityUtil.getUserId())); + + if(StrUtil.isNotBlank(c.getString("unionLimit"))) { + List unionLimit = Json.fromJsonAsList(NutMap.class, c.getString("unionLimit")); + if(Lang.isNotEmpty(unionLimit)) { + NutMap nutMap = unionLimit.stream().filter(o -> o.getString("id").equals(SecurityUtil.getUnionId())).findFirst().orElse(null); + if(nutMap != null) { + c.put("coursePeopleNumber", nutMap.getInt("limitCount")); + } + } + } + }); + return Result.success(pagination); + } + + @At + @ApiOperation("获取分活动时间") + @SaCheckPermission("literacy.manage.apply") + public Result getCourseTime(String id) { + List list = literacyActivityService.dao().query(LiteracyActivityCourse.class, Cnd.where("courseId", "=", id)); + return Result.success(list); + } + + @At + @ApiOperation("查询分类标识集合") + @SaCheckPermission("literacy.manage.apply") + public Result queryCourseAssort(String activityId) { + List courseList = literacyActivityService.dao().query(LiteracyCourse.class, Cnd.where(LiteracyCourse::getActivityId, "=", activityId).asc(LiteracyCourse::getOrderNum)); + if(Lang.isEmpty(courseList)) { + return Result.success(new ArrayList<>()); + } + List assortList = courseList.stream().map(LiteracyCourse::getAssort).filter(StrUtil::isNotBlank).toList(); + return Result.success(assortList); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityController.java new file mode 100644 index 00000000..6bc4ade8 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyActivityController.java @@ -0,0 +1,144 @@ +package com.budwk.app.zhgh.activity.literacy.controller.manage; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.sys.models.Sys_home_activity; +import com.budwk.app.zhgh.activity.literacy.models.*; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +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.trans.Trans; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author zxy + * @Description 培训报名 活动管理 + * @createTime 2022年02月23日 09:57:00 + */ +@Slf4j +@IocBean +@Ok("json:full") +@Api(tags = "活动管理") +@At("/platform/literacy/manage/activity") +public class LiteracyActivityController { + + @Inject + private LiteracyActivityService literacySignUpActivityManageService; + @Inject + private Dao dao; + + @At("") + @SaCheckPermission("literacy.manage.activity") + @Ok("beetl:/platform/zhgh/activity/literacy/manage/index.html") + public void index() { + } + + @At + @ApiOperation("分页查询") + @SaCheckPermission("literacy.manage.activity") + public Result pageData(PageForm pageForm, + @Param(value = "year") Integer year, + @Param(value = "activityName") String activityName) { + Cnd cnd = Cnd.NEW(); + cnd.andEX("year", "=", year); + cnd.and(Cnd.likeEX("activityName", activityName)); + cnd.orderBy("createdAt", "desc"); + return Result.success().addData(literacySignUpActivityManageService.pageData(pageForm, cnd)); + } + + @At + @ApiOperation("活动删除") + @SaCheckPermission("literacy.manage.activity") + @SLog(tag = "品牌活动-活动管理", msg = "删除活动") + public Result onDelete(String id) { + Trans.exec(() -> { + literacySignUpActivityManageService.delete(id); + dao.clear(LiteracyCourse.class, Cnd.where("activityId", "=", id)); + dao.clear(LiteracyActivityCourse.class, Cnd.where("activityId", "=", id)); + dao.clear(LiteracyUser.class, Cnd.where("activityId", "=", id)); + dao.clear(LiteracyUserCourse.class, Cnd.where("activityId", "=", id)); + dao.clear(LiteracyActivity.class, Cnd.where("id", "=", id)); + dao.clear(LiteracyTypeLimit.class, Cnd.where("activityId", "=", id)); + dao.delete(Sys_home_activity.class, id); + }); + return Result.success(); + } + + @At + @ApiOperation("活动状态变更") + @SaCheckPermission("literacy.manage.activity") + public Result activityStatusChange(LiteracyActivity activity) { + literacySignUpActivityManageService.updateActivityStatus(activity); + dao.update(Sys_home_activity.class, + Chain.make("enable", !activity.isDisabled()), + Cnd.where("id", "=", activity.getId())); + return Result.success(); + } + + @At + @ApiOperation("查询单个活动") + @SaCheckPermission("literacy.manage.activity") + public Result findOne(@Param("id") @NotNull String id) { + NutMap dataMap = literacySignUpActivityManageService.findOne(id, null, ""); + String activityStartTime = dataMap.getString("activityStartTime"); + String activityEndTime = dataMap.getString("activityEndTime"); + if(StrUtil.isNotBlank(activityStartTime) && StrUtil.isNotBlank(activityEndTime)) { + dataMap.put("activityTime", List.of(activityStartTime, activityEndTime)); + } else { + dataMap.put("activityTime", new ArrayList<>()); + } + + String activitySignUpStartTime = dataMap.getString("activitySignUpStartTime"); + String activitySignUpEndTime = dataMap.getString("activitySignUpEndTime"); + if(StrUtil.isNotBlank(activitySignUpStartTime) && StrUtil.isNotBlank(activitySignUpEndTime)) { + dataMap.put("activitySignTime", List.of(activitySignUpStartTime, activitySignUpEndTime)); + } else { + dataMap.put("activitySignTime", new ArrayList<>()); + } + + List courseList = dataMap.getList("courseList", NutMap.class); + + //查询所有的课程类型 + List literacySignUpTypeList = dao.query(LiteracyType.class, Cnd.NEW()); + Map typeMap = literacySignUpTypeList.stream().collect(Collectors.toMap(LiteracyType::getId, LiteracyType::getTypeName)); + + courseList.forEach(v -> { + + List courseTimeList = v.getList("courseTimeList", NutMap.class); + //选择课程日期 下拉框 + List setUpCourseData = courseTimeList.stream().map(cd -> cd.getString("courseDate")).distinct().collect(Collectors.toList()); + v.put("setUpCourseData", setUpCourseData); + + courseTimeList.forEach(ct -> { + String courseStartTime = DateUtil.format(ct.getTime("courseStartTime"), "HH:mm"); + String courseEndTime = DateUtil.format(ct.getTime("courseEndTime"), "HH:mm"); + ct.put("courseStartTime", courseStartTime); + ct.put("courseEndTime", courseEndTime); + }); + + v.put("courseTypeName", typeMap.get(v.getString("courseType"))); + }); + + return Result.success().addData(dataMap); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyTypeController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyTypeController.java new file mode 100644 index 00000000..f84c0598 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyTypeController.java @@ -0,0 +1,167 @@ +package com.budwk.app.zhgh.activity.literacy.controller.manage; + +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.EnumUtil; +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.service.BaseService; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyMobileSignColumn; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyType; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.entity.annotation.ColType; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.List; + +/** + * @Author JyuHsin + * @Date 2022/9/22 + * @Description + */ +@Slf4j +@IocBean +@Ok("json:full") +@Api(tags = "活动类型管理") +@At("/platform/literacy/manage/type") +public class LiteracyTypeController { + + @Inject + private Dao dao; + @Inject + private BaseService baseService; + + @At("") + @SaCheckPermission("literacy.manage.type") + @Ok("beetl:/platform/zhgh/activity/literacy/type/index.html") + public void index() { + } + + @At + @ApiOperation("分页查询") + @SaCheckPermission("literacy.manage.type") + public Result pageData(PageForm pageForm, + @Param(value = "typeName") String typeName) { + Cnd cnd = Cnd.NEW(); + Sql sql = Sqls.create(""" + select * from literacy_type $condition + """); + if (Strings.isNotBlank(typeName)) { + cnd.and("typeName", "like", "%" + typeName + "%"); + } + if(Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())){ + cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); + } else { + cnd.asc("xh"); + } + sql.setCondition(cnd); + Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + List list = pagination.getList(); + list.forEach(item -> { + Cnd c = Cnd.NEW(); + c.and("typeId", "=", item.getString("id")); + c.asc("columnIndex"); + List signColumns = dao.query(LiteracyMobileSignColumn.class, c); + item.put("literacyMobileSignColumnList", signColumns); + + }); + return Result.success().addData(pagination); + } + + @At + @ApiOperation("活动类型新增") + @SaCheckPermission("literacy.manage.type") + @SLog(tag = "品牌活动-类型管理", msg = "活动类型新增") + public Result doAdd(@Param("data") String data) throws Exception { + LiteracyType type = Json.fromJson(LiteracyType.class, data); + int count = dao.count(LiteracyType.class, Cnd.where("code", "=", type.getCode())); + if (count > 0) { + return Result.error("编码重复!"); + } + int totalCount = dao.count(LiteracyType.class); + type.setXh(totalCount + 1); + dao.insertWith(type, "literacyMobileSignColumnList"); + return Result.success(); + } + + @At + @ApiOperation("活动类型修改") + @SaCheckPermission("literacy.manage.type") + @SLog(tag = "品牌活动-类型管理", msg = "活动类型修改") + public Result doEdit(LiteracyType type) { + int count = dao.count(LiteracyType.class, Cnd.where("code", "=", type.getCode()).and("id", "!=", type.getId())); + if (count > 0) { + return Result.error("编码重复!"); + } + dao.update(type); + dao.clear(LiteracyMobileSignColumn.class, Cnd.where("typeId", "=", type.getId())); + dao.insertLinks(type, "literacyMobileSignColumnList"); + return Result.success(); + } + + @At + @ApiOperation("活动类型删除") + @SaCheckPermission("literacy.manage.type") + @SLog(tag = "品牌活动-类型管理", msg = "活动类型删除") + public Object doDelete(@Param(value = "id") String id) { + dao.clear(LiteracyType.class, Cnd.where("id", "=", id)); + dao.clear(LiteracyMobileSignColumn.class, Cnd.where("typeId", "=", id)); + return Result.success(); + } + + @At + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("排序号变更") + @SaCheckPermission("literacy.manage.type") + public Object xhChange(String id, Integer xh, boolean toDown) { + if (toDown) { + LiteracyType next = dao.fetch(LiteracyType.class, Cnd.where("xh", "=", xh + 1)); + next.setXh(next.getXh() - 1); + dao.update(next); + dao.update(LiteracyType.class, Chain.make("xh", xh + 1), Cnd.where("id", "=", id)); + } else { + LiteracyType pre = dao.fetch(LiteracyType.class, Cnd.where("xh", "=", xh - 1)); + pre.setXh(pre.getXh() + 1); + dao.update(pre); + dao.update(LiteracyType.class, Chain.make("xh", xh - 1), Cnd.where("id", "=", id)); + } + return Result.success(); + } + + @At + @ApiOperation("获取所有类型") + @SaCheckLogin + public Result getAllType(@Param(value = "id") String id) { + List literacyTypeList = dao.query(LiteracyType.class, Cnd.NEW().andEX("id", "=", id).asc("xh")); + dao.fetchLinks(literacyTypeList, "literacyMobileSignColumnList", Cnd.NEW().asc("columnIndex")); + return Result.success().addData(literacyTypeList); + } + + @At + @ApiOperation("自定义表单字段类型") + @SaCheckPermission("literacy.manage.type") + public Result getColumnType() { + List names = EnumUtil.getNames(ColType.class); + names.add("JSON"); + return Result.success(names); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserAdjustController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserAdjustController.java new file mode 100644 index 00000000..04f38766 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserAdjustController.java @@ -0,0 +1,179 @@ +package com.budwk.app.zhgh.activity.literacy.controller.manage; + +import cn.dev33.satoken.annotation.SaCheckPermission; +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.service.BaseService; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivityCourse; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUserCourse; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author JyuHsin + * @Date 2022/9/21 + * @Description 人员调整 + */ +@Slf4j +@IocBean +@Ok("json:full") +@Api(tags = "品牌活动人员调整") +@At("/platform/literacy/manage/userAdjust") +public class LiteracyUserAdjustController { + + @Inject + private Dao dao; + @Inject + private BaseService baseService; + @Inject + private LiteracyActivityService literacyActivityManageService; + @Inject + private LiteracyActivityStatisticsService literacyActivityStatisticsService; + + @At("") + @SaCheckPermission("literacy.manage.activity.adjust") + @Ok("beetl:/platform/zhgh/activity/literacy/userAdjust/index.html") + public void index() { + } + + /** + * 活动list + * @param year 年度 + * @return + */ + @At + @ApiOperation("活动列表") + @SaCheckPermission("literacy.manage.activity.adjust") + public Result activityList(@Param(value = "year") Integer year) { + List activityList = dao.query(LiteracyActivity.class, Cnd.NEW().andEX("year", "=", year).andEX("isDisabled", "=", false).desc("activityStartTime")); + return Result.success(activityList); + } + + @At + @ApiOperation("分页查询") + @SaCheckPermission("literacy.manage.activity.adjust") + public Result pageData(PageForm pageForm, + @Param(value = "activityId") String activityId) { + Pagination pagination = literacyActivityStatisticsService.pageData(pageForm, activityId); + return Result.success(pagination); + } + + @At + @ApiOperation("子活动查询") + @SaCheckPermission("literacy.manage.activity.adjust") + public Result getCourse(String activityId) { + Sql sql = Sqls.create(""" + SELECT + tsuc.id, + tsuc.courseName, + tsuc.coursePeopleNumber, + tsuc.courseType, + tsuc.courseLocation, + tsuc.courseInstructor, + tsuc.courseReservedNumber, + tsuc.waitingNum, + tsuc.reserveMode + FROM + `literacy_course` tsuc + WHERE + tsuc.activityId = @activityId + ORDER BY courseName asc + """); + sql.setParam("activityId", activityId); + List courseList = baseService.listMap(sql); + courseList.forEach(c -> { + c.put("registerNum", literacyActivityStatisticsService.queryCourseCount(c.getString("id"), c.getString("courseType"))); + c.put("hasWaitingNum", literacyActivityStatisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType"))); + }); + return Result.success(courseList); + } + + @At + @ApiOperation("报名用户列表") + @SaCheckPermission("literacy.manage.activity.adjust") + public Result registerUserList(@Param("courseId") String courseId, + @Param(value = "unionId") String unionId, + @Param(value = "unitId") String unitId, + @Param(value = "searchName") String searchName, + @Param(value = "searchKeyword") String searchKeyword) { + List list = literacyActivityStatisticsService.registerUserList(courseId, unionId, unitId, searchName, searchKeyword); + return Result.success(list); + } + + @At + @ApiOperation("人员调整") + @SaCheckPermission("literacy.manage.activity.adjust") + @SLog(tag = "品牌活动-人员调整", msg = "人员调整") + public Result adjust(String activityId, String oldCourseId, String newCourseId, String userId) { + + Cnd oldCnd = Cnd.where("activityId", "=", activityId) + .and("courseId", "=", oldCourseId).and("userId", "=", userId); + + Cnd newCnd = Cnd.where("activityId", "=", activityId) + .and("courseId", "=", newCourseId).and("userId", "=", userId); + + //旧的报名信息 + LiteracyUser oldliteracyUser = dao.fetch(LiteracyUser.class, oldCnd); + oldliteracyUser.setCourseId(newCourseId); + oldliteracyUser.setSignUpTime(DateUtil.date()); + dao.update(oldliteracyUser); + + //新的课程的信息,上课时间 + List activityCourseList = dao.query(LiteracyActivityCourse.class, Cnd.where("activityId", "=", activityId) + .and("courseId", "=", newCourseId)); + //先清楚旧的信息 + dao.clear(LiteracyUserCourse.class, oldCnd); + //添加新的信息 + List literacyUserCourseList = new ArrayList<>(); + activityCourseList.forEach(item -> { + LiteracyUserCourse course = new LiteracyUserCourse(); + course.setActivityCourseId(activityId); + course.setCourseId(newCourseId); + course.setUserId(userId); + course.setCourseStartTime(item.getCourseStartTime()); + course.setCourseEndTime(item.getCourseEndTime()); + course.setActivityCourseId(item.getId()); + literacyUserCourseList.add(course); + }); + dao.insert(literacyUserCourseList); + return Result.success(); + } + + @At + @ApiOperation("删除报名人员") + @SaCheckPermission("literacy.manage.activity.adjust") + @SLog(tag = "品牌活动-人员调整", msg = "删除报名人员") + public Result deleteSignUser(String activityId, String courseId, String userId) { + + //删除 + Cnd cnd = Cnd.NEW(); + cnd.and("activityId", "=", activityId); + cnd.and("courseId", "=", courseId); + cnd.and("userId", "=", userId); + + dao.clear(LiteracyUser.class, cnd); + dao.clear(LiteracyUserCourse.class, cnd); + return Result.success(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserBlackListManageController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserBlackListManageController.java new file mode 100644 index 00000000..f65366e3 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/manage/LiteracyUserBlackListManageController.java @@ -0,0 +1,347 @@ +package com.budwk.app.zhgh.activity.literacy.controller.manage; + +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.afterturn.easypoi.excel.export.ExcelExportService; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyBlackListService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author zxy + * @Description 人员管理 + * @createTime 2022年03月07日 14:27:00 + */ +@IocBean +@Ok("json:full") +@Api(tags = "亲子活动人员黑名单") +@At("/platform/literacy/userManage") +public class LiteracyUserBlackListManageController { + + @Inject + private Dao dao; + @Inject + private LiteracyBlackListService literacyBlackListService; + + @At("") + @SaCheckPermission("literacy.user.activity") + @Ok("beetl:/platform/zhgh/activity/literacy/userManage/index.html") + public void index() { + } + + @At + @ApiOperation("分页查询") + @SaCheckPermission("literacy.user.activity") + public Result pageData(PageForm pageForm, + @Param(value = "activityId") String activityId, + @Param(value = "courseId") String courseId, + @Param(value = "year") Integer year, + @Param(value = "userKeyWord") String userKeyWord) { + Cnd cnd = Cnd.NEW(); + cnd.andEX("tsuu.activityId", "=", activityId); + cnd.andEX("tsuu.courseId", "=", courseId); + cnd.andEX("act.year", "=", year); + if (StrUtil.isNotBlank(userKeyWord)) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + cnd.and(seg.andLike("u.username", userKeyWord).orLike("u.loginname", userKeyWord)); + } + if(Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())){ + cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); + } + + Pagination pagination = literacyBlackListService.pageData(pageForm, cnd, activityId, courseId); + return Result.success(pagination); + } + + @At + @ApiOperation("报名人员处理") + @SaCheckPermission("literacy.user.activity") + @SLog(tag = "品牌活动-人员管理", msg = "报名人员处理") + public Result doHandleUser(@Param("userId") String userId) { + literacyBlackListService.doHandleUser(userId); + return Result.success(); + } + + @At + @ApiOperation("根据活动Id获取子活动") + @SaCheckPermission("literacy.user.activity") + public Result getCourseByActivityId(@Param("activityId") String activityId) { + List list = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId)); + return Result.success(list); + } + + @At + @ApiOperation("获取子活动具体时间") + @SaCheckPermission("literacy.user.activity") + public Result attendClassRecord(String userId) { + literacyBlackListService.attendClassRecord(userId); + return Result.success(); + } + + @At + @ApiOperation("获取候补人员") + @SaCheckPermission("literacy.user.activity") + public Result getReserveUser(String courseId) { + Sql sql = Sqls.create(""" + SELECT + uc.* , + (select signUpTime from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as signUpTime, + (select state from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as state, + u.username, + u.loginname, + u.mobile, + u.unitName, + u.unionName + FROM + literacy_user_course uc LEFT JOIN `vw_user` u on uc.userId = u.id + WHERE uc.courseId = @courseId and uc.isAttend = false HAVING state = 2 order by signUpTime desc + """).setParam("courseId", courseId); + return Result.success(literacyBlackListService.listMap(sql)); + } + + @At + @ApiOperation("补充人员") + @SaCheckPermission("literacy.user.activity") + @SLog(tag = "品牌活动-人员管理", msg = "补充人员") + public Result reserveSingUp(String[] ids, String courseId) { + //先查询这个课程有多少个未签到的人员 + Sql sql = Sqls.create(""" + SELECT + uc.* , + (select signUpTime from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as signUpTime, + (select state from literacy_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as state + FROM + literacy_user_course uc + WHERE uc.courseId = @courseId and uc.isAttend = false HAVING state = 1 order by signUpTime desc + """).setParam("courseId", courseId); + List list = literacyBlackListService.listMap(sql); + if(ids.length > list.size()) { + return Result.error("您选择了" + ids.length + "位,未签到人员只有" + list.size() + "位"); + } + //ids的长度为几,就搞几个 + List mapList = list.subList(0, ids.length); + List idList = mapList.stream().map(o -> o.getString("userId")).collect(Collectors.toList()); + //将这几个没签到的设置为4 + dao.update(LiteracyUser.class, Chain.make("state", 4), Cnd.where("courseId", "=", courseId) + .and("userId", "in", idList)); + //将补充的设置为1 + dao.update(LiteracyUser.class, Chain.make("state", 1), Cnd.where("courseId", "=", courseId) + .and("userId", "in", ids)); + return Result.success(); + } + + @At + @Ok("void") + @ApiOperation("导出签到人员") + public void exportSignPerson(@Param(value = "activityId") String activityId, + HttpServletResponse response) { + LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId); + + Sql sql = Sqls.create(""" + SELECT + uc.*, + DATE_FORMAT(uc.courseStartTime, '%Y-%m-%d %H:%i:%s') as courseStartTimeExcel, + DATE_FORMAT(uc.courseEndTime, '%Y-%m-%d %H:%i:%s') as courseEndTimeExcel, + DATE_FORMAT(uc.attendTime, '%Y-%m-%d %H:%i:%s') as attendTimeExcel, + u.username, + u.loginname, + u.unitName, + u.unionName, + u.sex + FROM + literacy_user_course uc + left join literacy_course course on uc.courseId = course.id + left join `vw_user` u on u.id = uc.userId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("uc.activityId", "=", activityId); + cnd.and("course.isMobileSign", "=", true); + cnd.desc("isAttend").desc("attendTime"); + sql.setCondition(cnd); + + List userList = literacyBlackListService.listMap(sql); + + List courseList = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId)); + + List> sheetsList = new ArrayList<>(); + + List excelCommonExportEntity = new ArrayList<>(); + excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("开始时间", "courseStartTimeExcel", 22)); + excelCommonExportEntity.add(new ExcelExportEntity("结束时间", "courseEndTimeExcel", 22)); + excelCommonExportEntity.add(new ExcelExportEntity("是否签到", "isAttend", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("签到时间", "attendTimeExcel", 22)); + + for (LiteracyCourse c : courseList) { + String courseId = c.getId(); + String courseName = c.getCourseName(); + List v = userList.stream().filter(x -> x.getString("courseId").equals(courseId)).collect(Collectors.toList()); + ExportParams userExportParams = new ExportParams(); + userExportParams.setSheetName(courseName); + + List currentEntities = new ArrayList<>(excelCommonExportEntity); + for (NutMap userSignData : v) { + if(!userSignData.getBoolean("isAttend")) { + userSignData.put("isAttend", "未签到"); + userSignData.put("attendTimeExcel", "未签到"); + }else { + userSignData.put("isAttend", "已签到"); + } + } + + Map userExportMap = new HashMap<>(); + userExportMap.put("name", courseName); + userExportMap.put("title", userExportParams); + userExportMap.put("entity", currentEntities); + userExportMap.put("data", v); + + sheetsList.add(userExportMap); + } + try { + String fileName = activity.getActivityName() + "签到人员名单.xls"; + String disposition = "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"); + response.setCharacterEncoding("utf-8"); + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", disposition); + + Workbook workbook = new HSSFWorkbook(); + for (Map map : sheetsList) { + ExcelExportService service = new ExcelExportService(); + service.createSheetForMap(workbook,(ExportParams) map.get("title"),(List) map.get("entity"),(Collection) map.get("data")); + } + + workbook.write(response.getOutputStream()); + workbook.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @At + @Ok("void") + @ApiOperation("导出领取人员") + public void exportGiftPerson(@Param(value = "activityId") String activityId, + HttpServletResponse response) { + LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId); + + Sql sql = Sqls.create(""" + SELECT + uc.*, + DATE_FORMAT(uc.courseStartTime, '%Y-%m-%d %H:%i:%s') as courseStartTimeExcel, + DATE_FORMAT(uc.courseEndTime, '%Y-%m-%d %H:%i:%s') as courseEndTimeExcel, + DATE_FORMAT(uc.receiveTime, '%Y-%m-%d %H:%i:%s') as receiveTimeExcel, + u.username, + u.loginname, + u.unitName, + u.unionName, + u.sex + FROM + literacy_user_course uc + left join literacy_course course on uc.courseId = course.id + left join `vw_user` u on u.id = uc.userId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("uc.activityId", "=", activityId); + cnd.and("course.isReceiveGift", "=", true).and("course.giftType" ,"=", 1); + cnd.desc("isReceive").desc("receiveTime"); + sql.setCondition(cnd); + + List userList = literacyBlackListService.listMap(sql); + + List courseList = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId)); + + List> sheetsList = new ArrayList<>(); + + List excelCommonExportEntity = new ArrayList<>(); + excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("开始时间", "courseStartTimeExcel", 22)); + excelCommonExportEntity.add(new ExcelExportEntity("结束时间", "courseEndTimeExcel", 22)); + excelCommonExportEntity.add(new ExcelExportEntity("是否领取", "isReceive", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("领取时间", "receiveTimeExcel", 22)); + + for (LiteracyCourse c : courseList) { + String courseId = c.getId(); + String courseName = c.getCourseName(); + List v = userList.stream().filter(x -> x.getString("courseId").equals(courseId)).collect(Collectors.toList()); + ExportParams userExportParams = new ExportParams(); + userExportParams.setSheetName(courseName); + + List currentEntities = new ArrayList<>(excelCommonExportEntity); + for (NutMap userSignData : v) { + if(!userSignData.getBoolean("isReceive")) { + userSignData.put("isReceive", "未领取"); + userSignData.put("receiveTimeExcel", "未领取"); + }else { + userSignData.put("isReceive", "已领取"); + } + } + + Map userExportMap = new HashMap<>(); + userExportMap.put("name", courseName); + userExportMap.put("title", userExportParams); + userExportMap.put("entity", currentEntities); + userExportMap.put("data", v); + + sheetsList.add(userExportMap); + } + try { + String fileName = activity.getActivityName() + "礼品领取人员名单.xls"; + String disposition = "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"); + response.setCharacterEncoding("utf-8"); + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", disposition); + + Workbook workbook = new HSSFWorkbook(); + for (Map map : sheetsList) { + ExcelExportService service = new ExcelExportService(); + service.createSheetForMap(workbook,(ExportParams) map.get("title"),(List) map.get("entity"),(Collection) map.get("data")); + } + + workbook.write(response.getOutputStream()); + workbook.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityController.java new file mode 100644 index 00000000..36b464de --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityController.java @@ -0,0 +1,373 @@ +package com.budwk.app.zhgh.activity.literacy.controller.mobile; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.sys.models.Sys_user; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope; +import com.budwk.app.zhgh.activity.literacy.models.*; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.util.cri.Static; +import org.nutz.integration.jedis.RedisService; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; + +/** + * @author zxy + * @Description TODO + * @createTime 2022年02月25日 13:44:00 + */ +@IocBean +@Ok("json:full") +@Api(tags = "亲子活动移动端") +@At("/platform/mobile/literacyActivity") +public class MLiteracyActivityController { + + private static final String REDIS_KEY_PREFIX = "m_literacy_activity"; + private final ReentrantLock lock = new ReentrantLock(true); + @Inject + private Dao dao; + @Inject + private LiteracyActivityService literacyActivityService; + @Inject + private RedisService redisService; + @Inject + private LiteracyActivityStatisticsService statisticsService; + + @At("/literacyList") + @Ok("beetl:/platform/zhghh5/activity/literacy/literacyList/index.html") + @SaCheckPermission("h5.literacy.sign") + public void literacyList() { + } + + @At("/literacyInfo") + @Ok("beetl:/platform/zhghh5/activity/literacy/literacyInfo/index.html") + @SaCheckPermission("h5.literacy.sign") + public void literacyInfo() { + } + + @At("/activityInfo") + @Ok("beetl:/platform/zhghh5/activity/literacy/activityInfo/index.html") + @SaCheckPermission("h5.literacy.sign") + public void activityInfo() { + } + + @At + @ApiOperation("分页查询") + @SaCheckPermission("h5.literacy.sign") + public Result pageData(PageForm pageForm, + @Param(value = "activityStatus") int activityStatus, + @Param(value = "year") Integer year, + @Param(value = "activityType") Integer activityType) { + Pagination pagination = literacyActivityService.mPageData(pageForm, year, activityStatus, activityType); + return Result.success(pagination); + } + + /** + * @param id 活动id + * @param tabIndex 0全部 1我的 + * @return + */ + @At + @ApiOperation("查询单个活动") + @SaCheckPermission("h5.literacy.sign") + public Result findOne(@Param("id") String id, + @Param(value = "tabIndex") Integer tabIndex, + @Param(value = "fromMode") String fromMode) { + Cnd cnd = Cnd.NEW(); + if (tabIndex > 0) { + List mySignCourseList = dao.query(LiteracyUser.class, Cnd.where("userId", "=", SecurityUtil.getUserId()).and("activityId", "=", id)); + List mySignCourseIdList = mySignCourseList.stream().map(LiteracyUser::getCourseId).collect(Collectors.toList()); + cnd.and("id", "in", mySignCourseIdList); + } + NutMap nutMap = literacyActivityService.findOne(id, cnd, fromMode); + List courseList = nutMap.getAsList("courseList", LiteracyCourse.class); + courseList.forEach(v -> { + if (v.getCourseIsLimitApply() != null && v.getCourseIsLimitApply() && v.getIsSign()) { + LiteracyActivityCourse course = dao.fetch(LiteracyActivityCourse.class, Cnd.where("courseId", "=", v.getId())); + v.setCourseTimeName(DateUtil.format(course.getCourseStartTime(), "HH:mm") + "至" + DateUtil.format(course.getCourseEndTime(), "HH:mm") + "段"); + } + }); + return Result.success(nutMap); + } + + @At + @ApiOperation("查询子活动时间段") + @SaCheckPermission("h5.literacy.sign") + public Object getCourseTimeSelectList(String courseId) { + // 查课程的时间段 + List courseList = dao.query(LiteracyActivityCourse.class, Cnd.where("courseId", "=", courseId)); + + // 查课程的报名人数 + List applyUserList = dao.query(LiteracyUserCourse.class, Cnd.where("courseId", "=", courseId)); + // 按照课程下面时间段去分组 + Map> collectMap = applyUserList.stream().collect(Collectors.groupingBy(LiteracyUserCourse::getActivityCourseId)); + List list = courseList.stream().map(v -> { + String id = v.getId(); + NutMap nutMap = NutMap.NEW(); + List literacyUserCourses = collectMap.get(id); + int remainingNum = v.getCourseLimitNum() != null ? v.getCourseLimitNum() : 0; + if (Lang.isNotEmpty(literacyUserCourses)) { + remainingNum = v.getCourseLimitNum() - literacyUserCourses.size(); + } + nutMap.put("remainingNum", remainingNum); + nutMap.put("text", DateUtil.format(v.getCourseStartTime(), "HH:mm") + "至" + DateUtil.format(v.getCourseEndTime(), "HH:mm") + "段(剩" + remainingNum + ")"); + nutMap.put("value", id); + return nutMap; + }).filter(v-> v.getInt("remainingNum") != 0).toList(); + return Result.success(list); + } + + @At + @ApiOperation("活动报名") + @SaCheckPermission("h5.literacy.sign") + @SLog(tag = "品牌活动-活动报名", msg = "活动报名") + public Result doSignUp(LiteracyUser literacyUser) { + try { + lock.lock(); + boolean courseByUser = literacyActivityService.isSignCourseByUser(literacyUser.getCourseId(), SecurityUtil.getUserId()); + if(courseByUser) { + return Result.error("您已报过该活动"); + } + //判断人数 + int number = 0; + LiteracyCourse course = literacyActivityService.dao().fetch(LiteracyCourse.class, literacyUser.getCourseId()); + LiteracyType type = literacyActivityService.dao().fetch(LiteracyType.class, course.getCourseType()); + if(type != null) { + if(type.getIsBringFamily() && type.getIsAddFamily()) { + List mobileColumnsValue = literacyUser.getMobileColumnsValue(); + NutMap map = mobileColumnsValue.stream().filter(o -> "xdqsrs".equals(o.getString("columnCode"))).findAny().orElse(null); + number = map != null ? map.getInt("columnValue") : 0; + } + } + boolean signFull = literacyActivityService.isSignFull(course, number); + if(signFull) { + return Result.error("当前报名人数已满"); + } + boolean signFullByUnionId = literacyActivityService.isSignFullByUnionId(course, number); + if(signFullByUnionId) { + return Result.error("该活动您所在的分工会名额不足"); + } + literacyActivityService.doSignUp(literacyUser); + return Result.success("报名成功"); + } catch (Exception e) { + e.printStackTrace(); + return Result.success("报名失败"); + } finally { + lock.unlock(); + } + } + + @At + @ApiOperation("取消报名") + @SaCheckPermission("h5.literacy.sign") + @SLog(tag = "品牌活动-活动报名", msg = "取消报名") + public Result cancelSignUp(@Param("activityId") String activityId, @Param("courseId") String courseId) { + String userId = SecurityUtil.getUserId(); + //取消分两种情况 + //第一种没有设置分工会人数限制,那么将候补的人按时间倒叙往上补 + //第二种如果设置了分工会人数限制,那么只将本分工会的候补人员按照时间倒叙往上补,如果本分工会没有候补人员,则名额空出来,由校工会手动调整 + LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId); + LiteracyCourse course = dao.fetch(LiteracyCourse.class, courseId); + LiteracyType type = dao.fetch(LiteracyType.class, course.getCourseType()); + //如果是正常报名取消了,将候补报名的按时间倒叙第一个改为正常报名 + Cnd cnd = Cnd.where("activityId", "=", activityId).and("courseId", "=", courseId) + .and("state", "=", 2); + //如果设置了分工会报名人数限制,则只查本分工会 + if (Lang.isNotEmpty(course.getUnionLimit())) { + cnd.and(new Static(" userId in (select id from user where unionid = '%s')".formatted(SecurityUtil.getUnionId()))); + } + cnd.asc("signUpTime"); + if (!type.getIsBringFamily() && course.getReserveMode() == 2) { + List signUpUsers = dao.query(LiteracyUser.class, cnd); + int thisSignUpUserCount = dao.count(LiteracyUser.class, + Cnd.where("activityId", "=", activityId) + .and("courseId", "=", courseId).and("userId", "=", userId) + .and("state", "in", List.of(1, 3))); + if (!signUpUsers.isEmpty() && thisSignUpUserCount > 0) { + LiteracyUser literacyUser = signUpUsers.get(0); + literacyUser.setState(1); + dao.update(literacyUser); + Sys_user user = dao.fetch(Sys_user.class, literacyUser.getUserId()); + //msgApi.sendTextMsg("【" + activity.getActivityName() + "】已候补成功,请按时参加活动!", user.getLoginname()); + } + } + //删除报名记录 + dao.clear("literacy_user_course", Cnd.where("activityId", "=", activityId) + .and("courseId", "=", courseId).and("userId", "=", userId)); + + dao.clear("literacy_user", Cnd.where("activityId", "=", activityId) + .and("courseId", "=", courseId).and("userId", "=", userId)); + return Result.success(); + } + + @At + @ApiOperation("签到") + @SaCheckPermission("h5.literacy.sign") + @SLog(tag = "品牌活动-活动报名", msg = "签到") + public Result doQd(@Param("id") String id, @Param("courseId") String courseId, @Param("point") Double[] points) { + LiteracyCourse course = dao.fetch(LiteracyCourse.class, courseId); + List coursePoints = course.getCourseLocationCoordinates(); +// if (Lang.isNotEmpty(coursePoints)) { +// //需要签到 +// if (ArrayUtil.isEmpty(points) || ArrayUtil.hasNull(points)) { +// return Result.error().addMsg("请获取当前的坐标信息"); +// } +// Double[] coursePointArray = coursePoints.toArray(new Double[]{}); +// float distance = AMapUtils.calculateLineDistance(new LatLng(points[0], points[1]), new LatLng(coursePointArray[0], coursePointArray[1])); +// +// if (distance > 500) { +// return Result.error().addMsg("请到签到点位附近签到"); +// } +// } + literacyActivityService.doQd(id); + return Result.success(); + } + + /** + * 签到信息 + * + * @param activityId + * @return + */ + @At + @ApiOperation("获取签到信息") + @SaCheckPermission("h5.literacy.sign") + public Result getQdInfoList(@Param("activityId") String activityId) { + List list = literacyActivityService.qdInfoByUserId(SecurityUtil.getUserId(), activityId); + return Result.success(list); + } + + @At + @ApiOperation("验证是否能报名") + @SaCheckPermission("h5.literacy.sign") + public Result validateSignUp(String courseId, + @Param(value = "currentFamilyNumber") Integer currentFamilyNumber) { + try { + lock.lock(); + if(StrUtil.isBlank(courseId)) { + return Result.error("报名信息为空"); + } + + currentFamilyNumber = currentFamilyNumber != null ? currentFamilyNumber : 0; + LiteracyCourse course = dao.fetch(LiteracyCourse.class, courseId); + LiteracyActivity activity = dao.fetch(LiteracyActivity.class, course.getActivityId()); + + //判断时间 + if(DateUtil.compare(new Date(), activity.getActivitySignUpStartTime(), "yyyy-MM-dd HH:mm:ss") < 0) { + return Result.error("报名未开始"); + } + if(DateUtil.compare(new Date(), activity.getActivitySignUpEndTime(), "yyyy-MM-dd HH:mm:ss") > 0) { + return Result.error("报名已结束"); + } + + //判断活动组别 + int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getActivityGroupId()).and("userId", "=", SecurityUtil.getUserId())); + if(count == 0) { + return Result.error("抱歉,您没有此次活动的权限"); + } + + //判断是否报名 + boolean courseByUser = literacyActivityService.isSignCourseByUser(courseId, SecurityUtil.getUserId()); + if(courseByUser) { + return Result.error("抱歉,您已经报名"); + } + + //判断活动人数 + boolean signFull = literacyActivityService.isSignFull(course, currentFamilyNumber); + if(signFull) { + return Result.error("名额剩余数量不足"); + } + + //判断活动限制 + boolean signCourse = literacyActivityService.isSignCourse(course, activity); + if(!signCourse) { + if(activity.getRestrictLimit() != 3) { + return Result.error("您选择的类型已达上限,不能再报该类型的了"); + } else { + return Result.error(activity.getActivityName() + "限制报" + activity.getLimitNum() + "个活动,已达上限"); + } + } + + //判断分工会人数限制 + boolean signFullByUnionId = literacyActivityService.isSignFullByUnionId(course, currentFamilyNumber); + if(signFullByUnionId) { + return Result.error("您所在的分工会名额不足"); + } + + return Result.success(); + }catch (Exception e) { + e.printStackTrace(); + return Result.error("报名失败"); + } finally { + lock.unlock(); + } + } + + @At + @ApiOperation("验证子活动是否能报名") + @SaCheckPermission("h5.literacy.sign") + public Object validateSourceSignUp(String activityCourseId, String courseId) { + try { + lock.lock(); + // 该时间段下已报名的人数 + int count = dao.count(LiteracyUserCourse.class, Cnd.where("activityCourseId", "=", activityCourseId) + .and("courseId", "=", courseId)); + // 获取改时间段下的活动课程限制报名人数 + LiteracyActivityCourse course = dao.fetch(LiteracyActivityCourse.class, activityCourseId); + Integer courseLimitNum = course.getCourseLimitNum(); + // 报名加上自己,如果大于了限制人数,那就无法报名 + if (count + 1 > courseLimitNum) { + return Result.error("该时间段名额已报满,请选择其他时段报名"); + } else { + return Result.success(); + } + } catch (Exception e) { + e.printStackTrace(); + return Result.error("报名失败"); + } finally { + lock.unlock(); + } + } + + @At + @ApiOperation("二维码签到") + @SaCheckPermission("h5.literacy.sign") + @SLog(tag = "品牌活动-活动报名", msg = "二维码签到") + public Result codeSign(String id, String codeCourseId, String clickCourseId) { + if(StrUtil.isBlank(codeCourseId) || StrUtil.isBlank(clickCourseId)) { + return Result.error("签到失败,没有获取到扫描信息"); + } + if(!codeCourseId.equals(clickCourseId)) { + return Result.error("签到失败,二维码与您当前签到信息不符"); + } + dao.update(LiteracyUserCourse.class, Chain.make("isAttend", true) + .add("attendTime", new Date()), Cnd.where("id", "=", id)); + return Result.success(); + } + +} + + diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityScannerQrCodeController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityScannerQrCodeController.java new file mode 100644 index 00000000..0a8c6c5b --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/mobile/MLiteracyActivityScannerQrCodeController.java @@ -0,0 +1,201 @@ +package com.budwk.app.zhgh.activity.literacy.controller.mobile; + +import lombok.extern.slf4j.Slf4j; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +/** + * 品牌活动扫码 + */ +@IocBean +@At("/platform/mobile/literacyActivityScannerQrCode") +@Ok("json:full") +@Slf4j +public class MLiteracyActivityScannerQrCodeController { + + /*@Inject + private WxTokenUtil; + + @Inject + private literacyActivityService literacyActivityService; + + @Inject + private Dao dao; + + @At("") + @Ok("beetl:/mobile/scannerQrCode.html") + public void scannerQrCode() { + + } + + *//** + * 微信js验证 + * + * @param url + * @return + *//* + @At("/auth/sign") + @ViReturn + @RequiresAuthentication + public Object wxAuthSign(String url) { + String jsapi_ticket = wxTokenUtil.jsTicket(); + return sign(jsapi_ticket, url); + } + + *//** + * 二维码信息 + * + * @param userId 用户id + * @param signId 签到记录id + * @param activityId 活动id + * @return + *//* + @At("/qrCodeInfo") + @RequiresAuthentication + public Object qrCodeInfo(@Param("userId") String userId, @Param("signId") String signId, @Param("activityId") String activityId) { + if (StrUtil.isBlank(userId) || StrUtil.isBlank(signId) || StrUtil.isBlank(activityId)) { + return Result.error("参数错误"); + } + try { +// Sql activitySql = Sqls.create("select activityName,cover from literacy_activity where id = @activityId"); +// activitySql.setParam("activityId",activityId); +// NutMap activityMap = (NutMap) Daos.query(dao, activitySql.toString(), Sqls.callback.map()); + + Sql signSql = Sqls.create("select isAttend,attendTime,isReceive,receiveTime from literacy_user_course where id = @signId"); + signSql.setParam("signId", signId); + NutMap attendInfo = (NutMap) Daos.query(dao, signSql.toString(), Sqls.callback.map()); + Sql userSql = Sqls.create("select id,username,loginname,unitname,unionname,sex from `user` where id = @userId"); + userSql.setParam("userId", userId); + NutMap userMap = (NutMap) Daos.query(dao, userSql.toString(), Sqls.callback.map()); + return Result.success(Map.of("signInfo", attendInfo, "userInfo", userMap)); + } catch (Exception e) { + log.error(e.getMessage()); + return Result.error("获取信息失败"); + } + } + + @At("/signInfo") + @RequiresAuthentication + public Object signInfo(@Param("signId") String signId) { + if (StrUtil.isBlank(signId)) { + return Result.error("参数错误"); + } + try { + Sql signSql = Sqls.create("select isAttend,attendTime from literacy_user_course where id = @signId"); + signSql.setParam("signId", signId); + NutMap signInfo = literacyActivityService.fetch(signSql); + return Result.success(signInfo); + } catch (Exception e) { + log.error(e.getMessage()); + return Result.error("获取信息失败"); + } + } + + *//** + * 发放礼品 + * + * @param signId + * @return + *//* + @At("/grantGiftByQrCode") + @RequiresAuthentication + public Object grantGiftByQrCode(@Param("signId") String signId) { + if (StrUtil.isBlank(signId)) { + return Result.error("参数错误"); + } + try { + Chain chain = Chain.make("isReceive", 1); + chain.add("receiveTime", new Date()); + chain.add("giftScannerCodeUserId", ShiroUtil.getPrincipalProperty("id")); + dao.update(literacyUserCourse.class, chain, Cnd.where("id", "=", signId)); + Sql signSql = Sqls.create("select isAttend,attendTime,isReceive,receiveTime from literacy_user_course where id = @signId"); + signSql.setParam("signId", signId); + NutMap signInfo = literacyActivityService.fetch(signSql); + return Result.success(signInfo); + } catch (Exception e) { + log.error(e.getMessage()); + return Result.error("获取信息失败"); + } + } + + *//** + * 二维码扫描确认签到 + * + * @param signId + * @return + *//* + @At("/confirmSignByQrCode") + @RequiresAuthentication + public Object confirmSignByQrCode(@Param("signId") String signId) { + if (StrUtil.isBlank(signId)) { + return Result.error("参数错误"); + } + try { + Chain chain = Chain.make("isAttend", 1); + chain.add("attendTime", new Date()); + chain.add("signScannerCodeUserId", ShiroUtil.getPrincipalProperty("id")); + dao.update(literacyUserCourse.class, chain, Cnd.where("id", "=", signId)); + + Sql signSql = Sqls.create("select isAttend,attendTime,isReceive,receiveTime from literacy_user_course where id = @signId"); + signSql.setParam("signId", signId); + NutMap signInfo = literacyActivityService.fetch(signSql); + return Result.success(signInfo); + } catch (Exception e) { + log.error(e.getMessage()); + return Result.error("获取信息失败"); + } + } + + + public static Map sign(String jsapi_ticket, String url) { + Map ret = new HashMap(); + String nonce_str = create_nonce_str(); + String timestamp = create_timestamp(); + String string1; + String signature = ""; + + //注意这里参数名必须全部小写,且必须有序 + string1 = "jsapi_ticket=" + jsapi_ticket + + "&noncestr=" + nonce_str + + "×tamp=" + timestamp + + "&url=" + url; + System.out.println(string1); + + try { + MessageDigest crypt = MessageDigest.getInstance("SHA-1"); + crypt.reset(); + crypt.update(string1.getBytes("UTF-8")); + signature = byteToHex(crypt.digest()); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + e.printStackTrace(); + } + + ret.put("url", url); + ret.put("jsapi_ticket", jsapi_ticket); + ret.put("nonceStr", nonce_str); + ret.put("timestamp", timestamp); + ret.put("signature", signature); + + return ret; + } + + private static String byteToHex(final byte[] hash) { + Formatter formatter = new Formatter(); + for (byte b : hash) { + formatter.format("%02x", b); + } + String result = formatter.toString(); + formatter.close(); + return result; + } + + private static String create_nonce_str() { + return UUID.randomUUID().toString(); + } + + private static String create_timestamp() { + return Long.toString(System.currentTimeMillis() / 1000); + }*/ + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/statistics/LiteracyActivityStatisticsController.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/statistics/LiteracyActivityStatisticsController.java new file mode 100644 index 00000000..59d557b0 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/controller/statistics/LiteracyActivityStatisticsController.java @@ -0,0 +1,254 @@ +package com.budwk.app.zhgh.activity.literacy.controller.statistics; + +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.afterturn.easypoi.excel.export.ExcelExportService; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +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.sys.models.Sys_file; +import com.budwk.app.sys.utils.SysFileMinIoUtil; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyMobileSignColumn; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyType; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + + +/** + * @author zxy + * @Description 培训报名 统计 + * @createTime 2022年02月23日 09:57:00 + */ +@Slf4j +@IocBean +@Ok("json:full") +@Api(tags = "品牌活动统计") +@At("/platform/literacy/statistics/activity") +public class LiteracyActivityStatisticsController { + + @Inject + private LiteracyActivityService literacyActivityManageService; + @Inject + private LiteracyActivityStatisticsService literacyActivityStatisticsService; + @Inject + private Dao dao; + + @At("") + @SaCheckPermission("literacy.statistics.activity") + @Ok("beetl:/platform/zhgh/activity/literacy/statistics/index.html") + public void index() { + } + + @At + @ApiOperation("分页查询") + @SaCheckPermission("literacy.statistics.activity") + public Result pageData(PageForm pageForm, + @Param(value = "activityId") String activityId) { + Pagination pagination = literacyActivityStatisticsService.pageData(pageForm, activityId); + return Result.success(pagination); + } + + /** + * 活动list + * + * @param year 年度 + * @return + */ + @At + @ApiOperation("活动列表") + @SaCheckPermission("literacy.statistics.activity") + public Result activityList(@Param(value = "year") Integer year) { + List list = dao.query(LiteracyActivity.class, Cnd.NEW().andEX("year", "=", year).desc("activityStartTime")); + return Result.success(list); + } + + /** + * 培训班报名人员list + * + * @param courseId + * @return + */ + @At + @ApiOperation("报名人员列表") + @SaCheckPermission("literacy.statistics.activity") + public Result registerUserList(@Param(value = "courseId") String courseId) { + return Result.success(literacyActivityStatisticsService.registerUserList(courseId)); + } + + @At + @ApiOperation("报名动态列") + @SaCheckPermission("literacy.statistics.activity") + public Object getTaleColumnInfo(@Param(value = "courseId") String courseId) { + return Result.success(literacyActivityStatisticsService.getTaleColumnInfo(courseId)); + } + + /** + * 培训班上课签到信息 + * + * @param courseId + * @return + */ + @At + @ApiOperation("获取签到信息") + @SaCheckPermission("literacy.statistics.activity") + public Result getSignInfo(@Param("courseId") String courseId) { + return Result.success(literacyActivityStatisticsService.getSignInfo(courseId)); + } + + @At + @ApiOperation("开放报名") + @SaCheckPermission("literacy.statistics.activity") + public Result signChange(@Param("courseId") String courseId, @Param("openOtherUnion") Boolean openOtherUnion) { + dao.update(LiteracyCourse.class, Chain.make("openOtherUnion", openOtherUnion) + , Cnd.where("id", "=", courseId)); + return Result.success(); + } + + @At + @Ok("void") + @ApiOperation("导出签到名单") + @SaCheckPermission("literacy.statistics.activity") + public void exportSignUser(@Param(value = "activityId") String activityId, + HttpServletResponse response) throws IOException { + try { + LiteracyActivity activity = dao.fetch(LiteracyActivity.class, activityId); + Sql sql = Sqls.create(""" + SELECT + ts.*, + CONCAT(DATE_FORMAT(ac.courseStartTime, '%H:%i:%s'),'至',DATE_FORMAT(ac.courseEndTime, '%H:%i:%s')) AS courseTime, + u.username, + u.loginname, + u.sex, + ifnull(ts.mobile, u.mobile) as mobile, + u.birthday, + tsc.courseName + FROM + literacy_user ts + left join literacy_activity_course ac on ts.activityCourseId = ac.id + left join `vw_user` u on u.id = ts. userId + left join literacy_course tsc on tsc.id = ts.courseId + WHERE + ts.activityId = @activityId + """).setParam("activityId", activityId); + List userList = literacyActivityManageService.listMap(sql); + + List courseList = dao.query(LiteracyCourse.class, Cnd.where("activityId", "=", activityId)); + + List literacyTypeList = dao.query(LiteracyType.class, Cnd.NEW()); + dao.fetchLinks(literacyTypeList, "literacyMobileSignColumnList", Cnd.NEW().asc("columnIndex")); + Map typeMap = literacyTypeList.stream().collect(Collectors.toMap(LiteracyType::getId, o -> o)); + + List> sheetsList = new ArrayList<>(); + + List excelCommonExportEntity = new ArrayList<>(); + excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("手机号", "mobile", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("生日", "birthday", 20)); + excelCommonExportEntity.add(new ExcelExportEntity("报名时段", "courseTime", 20)); + + for (LiteracyCourse c : courseList) { + String k = c.getCourseName(); + List v = userList.stream().filter(x -> x.getString("courseName").equals(k)).collect(Collectors.toList()); + ExportParams userExportParams = new ExportParams(); + userExportParams.setSheetName(k); + userExportParams.setType(ExcelType.HSSF); + + List currentEntities = new ArrayList<>(); + currentEntities.addAll(excelCommonExportEntity); + + LiteracyType signUpType = typeMap.get(c.getCourseType()); + if (Lang.isNotEmpty(signUpType.getLiteracyMobileSignColumnList())) { + for (LiteracyMobileSignColumn column : signUpType.getLiteracyMobileSignColumnList()) { + ExcelExportEntity entity = new ExcelExportEntity(); + entity.setName(column.getColumnName()); + entity.setKey(column.getColumnCode()); + entity.setWidth(20); + if (column.getColumnFormType().equals("FILE")) { + entity.setType(2); + entity.setExportImageType(2); + } + currentEntities.add(entity); + } + } + for (NutMap userSignData : v) { + String mobileColumnsValueStr = userSignData.getString("mobileColumnsValue"); + if (StrUtil.isNotBlank(mobileColumnsValueStr)) { + List mobileColumnsValue = Json.fromJsonAsList(NutMap.class, mobileColumnsValueStr); + for (NutMap cv : mobileColumnsValue) { + if (!"FILE".equals(cv.getString("columnFormType"))) { + userSignData.put(cv.getString("columnCode"), cv.getString("columnValue")); + } else { + if (StrUtil.isNotBlank(cv.getString("columnValue"))) { + List columnValue = Json.fromJsonAsList(JSONObject.class, cv.getString("columnValue")); + if (columnValue.size() == 1) { + JSONObject sysFile = columnValue.get(0); + Sys_file file = dao.fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", sysFile.get("url"))); + byte[] imageBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath()); + if (imageBytes.length > 0) { + userSignData.put(cv.getString("columnCode"), imageBytes); + } + } + } + } + } + + } + } + + Map userExportMap = new HashMap<>(); + userExportMap.put("name", k); + userExportMap.put("title", userExportParams); + userExportMap.put("entity", currentEntities); + userExportMap.put("data", v); + + sheetsList.add(userExportMap); + } + + Workbook workbook = new HSSFWorkbook(); + for (Map map : sheetsList) { + ExcelExportService service = new ExcelExportService(); + service.createSheetForMap(workbook, (ExportParams) map.get("title"), (List) map.get("entity"), (Collection) map.get("data")); + } + workbook.write(response.getOutputStream()); + workbook.close(); + + CommonDownloadUtil.download(activity.getActivityName() + "报名人员名单" + ".xlsx", workbook, response); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivity.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivity.java new file mode 100644 index 00000000..20ab61a1 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivity.java @@ -0,0 +1,136 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import com.budwk.app.base.model.BaseModel; +import com.budwk.app.sys.models.Sys_home_activity; +import com.budwk.app.sys.services.SysHomeConvert; +import lombok.Data; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; +import org.nutz.lang.Lang; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * @author zxy + * @Description 培训报名活动 + * @createTime 2022年02月23日 08:57:00 + */ +@Table +@Data +@Accessors(chain = true) +public class LiteracyActivity extends BaseModel implements Serializable, SysHomeConvert { + + @Name + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("活动名称") + private String activityName; + + @Column + @ColDefine(type = ColType.INT) + @Comment("年度") + private Integer year; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("活动报名开始时间") + private Date activitySignUpStartTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("活动报名开始时间") + private Date activitySignUpEndTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("活动开始时间") + private Date activityStartTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("活动结束时间") + private Date activityEndTime; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("是否禁用") + private boolean isDisabled; + + @Column + @ColDefine(customType = "longtext") + @Comment("活动介绍") + private String introduce; + + @Column + @ColDefine(type = ColType.INT, width = 10) + @Comment("活动限制标识") + private Integer restrictLimit; + + @Column + @ColDefine(type = ColType.INT, width = 10) + @Comment("活动限制报名个数") + private Integer limitNum; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("活动封面") + private String cover; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("微信群二维码") + private String wechat; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("上课前是否通知") + private boolean notice; + + @Column + @Comment("活动范围Id") + @ColDefine(type = ColType.INT, width = 32) + private Integer activityGroupId; + + @Column + @Comment("活动范围名称") + @ColDefine(type = ColType.VARCHAR, width = 40) + private String activityGroupName; + + /** + * 所有的培训班 + */ + @Many(field = "activityId") + private List courseList; + + @Many(field = "activityId") + private List typeLimits; + + @Column + @Comment("活动类型") + @ColDefine(type = ColType.VARCHAR, width = 20) + private String literacyType; + + @Override + public Sys_home_activity covertToSysHomeActivity() { + Sys_home_activity sysHomeActivity = new Sys_home_activity(); + sysHomeActivity.setId(this.getId()); + sysHomeActivity.setName(this.getActivityName()); + sysHomeActivity.setCover(this.getCover()); + sysHomeActivity.setUrl("/platform/literacy/manage/apply"); + sysHomeActivity.setH5Url("/platform/mobile/literacyActivity/literacyList"); + if (Lang.isNotEmpty(this.getActivitySignUpStartTime())) { + sysHomeActivity.setStartDate(this.getActivitySignUpStartTime()); + sysHomeActivity.setEndDate(this.getActivitySignUpEndTime()); + } + sysHomeActivity.setAllowUserGroupId(this.getActivityGroupId()); + sysHomeActivity.setEnable(!this.isDisabled()); + sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName()); + return sysHomeActivity; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivityCourse.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivityCourse.java new file mode 100644 index 00000000..9a59ce7b --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyActivityCourse.java @@ -0,0 +1,56 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.util.Date; + +/** + * @author zxy + * @Description 活动下的课程 + * @createTime 2022年02月23日 09:26:00 + */ +@Table +@Data +@Accessors(chain = true) +public class LiteracyActivityCourse { + + @Name + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("活动ID") + private String activityId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("课程ID") + private String courseId; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("课程开始时间") + private Date courseStartTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("课程结束时间") + private Date courseEndTime; + + @Column + @ColDefine(type = ColType.DATE) + @Comment("课程时间") + private Date courseDate; + + @Column + @ColDefine(type = ColType.INT, width = 4) + @Comment("限制人数") + private Integer courseLimitNum; + + private Integer hasRegisterNum; + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyBlackList.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyBlackList.java new file mode 100644 index 00000000..9b0c5eeb --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyBlackList.java @@ -0,0 +1,31 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import lombok.Data; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +/** + * @author zxy + * @Description 黑名单 + * @createTime 2022年03月07日 14:32:00 + */ +@Table +@Data +public class LiteracyBlackList { + + @Name + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("用户id") + private String userId; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("是否禁用") + private Boolean isDisabled; + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyCourse.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyCourse.java new file mode 100644 index 00000000..b00d6e2e --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyCourse.java @@ -0,0 +1,160 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import com.budwk.app.base.model.BaseModel; +import lombok.Data; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; +import org.nutz.lang.util.NutMap; + +import java.io.Serializable; +import java.util.List; + +/** + * @author zxy + * @Description 培训班信息 + * @createTime 2022年02月23日 09:04:00 + */ +@Table +@Data +@Accessors(chain = true) +public class LiteracyCourse extends BaseModel implements Serializable { + + @Name + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("活动ID") + private String activityId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("课程名称") + private String courseName; + + @Column + @ColDefine(type = ColType.INT) + @Comment("课程人数") + private int coursePeopleNumber; + + @Column + @ColDefine(type = ColType.INT) + @Default(value = "0") + @Comment("预留名额") + private int courseReservedNumber; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("课程地点") + private String courseLocation; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("课程类型") + private String courseType; + + @Column + @ColDefine(type = ColType.MYSQL_JSON) + @Comment("课程地点坐标") + private List courseLocationCoordinates; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 20) + @Comment("课程讲师") + private String courseInstructor; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("校区") + private String campus; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("报名人数是否限制") + private Boolean courseIsLimitApply; + + @Column + @ColDefine(type = ColType.INT) + @Comment("序号") + private int orderNum; + + @Many(field = "courseId") + private List courseTimeList; + + //已报人数 + private Integer hasRegisterNum; + + private Boolean isBringFamily; + + private Boolean isAddFamily; + + //是否报过该课程 + private Boolean isSign; + + //还能报该类型的课程吗 + private Boolean canSignThisCourseType; + + @Column + @Comment("分工会人数限制") + @ColDefine(type = ColType.MYSQL_JSON) + private List unionLimit; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("移动端是否签到") + private boolean isMobileSign; + + @Column + @ColDefine(type = ColType.INT) + @Comment("签到方式 1.扫描二维码签到 2.被扫 3.gps签到") + private Integer signType; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("移动端是否签收礼品") + private boolean isReceiveGift; + + @Column + @ColDefine(type = ColType.INT) + @Comment("领取礼品方式 1.扫描二维码 2.线下") + private Integer giftType; + + @Column + @ColDefine(type = ColType.INT) + @Comment("预留名额方式 1.报名人员减少模式 2.报名人数不变模式") + private Integer reserveMode; + + @Column + @Comment("承办工会") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String hostUnionId; + + @Column + @Comment("对内报名时间") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String interTime; + + @Column + @Comment("是否开放给其他工会") + @ColDefine(type = ColType.BOOLEAN, width = 4) + private Boolean openOtherUnion; + + @Column + @Comment("分类标识") + @ColDefine(type = ColType.VARCHAR, width = 30) + private String assort; + + @Column + @ColDefine(type = ColType.INT) + @Default(value = "0") + @Comment("候补名额数") + private Integer waitingNum; + + //候补已报人数 + private Integer hasWaitingNum; + + private String courseTimeName; + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyMobileSignColumn.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyMobileSignColumn.java new file mode 100644 index 00000000..f1687898 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyMobileSignColumn.java @@ -0,0 +1,79 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import lombok.Data; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.util.List; + +@Table("literacy_mobile_sign_column") +@Data +public class LiteracyMobileSignColumn { + + private static final long serialVersionUID = 1L; + + @Name + @Comment("id") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + /** + * train_sign_up_type id + */ + @Column + @Comment("类型id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String typeId; + + @Column + @Comment("字段名称") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String columnName; + + @Column + @Comment("字段编码") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String columnCode; + + @Column + @Comment("字段值") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String columnValue; + + @Column + @Comment("字段类型") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String columnType; + + @Column + @Comment("下拉框的值") + @ColDefine(type = ColType.MYSQL_JSON) + private List selectValues; + + @Column + @Comment("是否必填") + @ColDefine(type = ColType.BOOLEAN) + private Boolean isRequired; + + @Column + @Comment("控件类型") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String columnFormType; + + @Column + @Comment("文件个数") + @ColDefine(type = ColType.INT) + private Integer fileNumber; + + @Column + @Comment("文件类型") + @ColDefine(type = ColType.MYSQL_JSON) + private List fileType; + + @Column + @Comment("序号") + @ColDefine(type = ColType.INT, width = 1) + private Integer columnIndex; + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyType.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyType.java new file mode 100644 index 00000000..15fea80f --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyType.java @@ -0,0 +1,68 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import com.budwk.app.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * TODO + * + * @author 赵欣雨 + * @date 2020/8/18 9:16 + */ +@Data +@Table("literacy_type") +@EqualsAndHashCode(callSuper = true) +public class LiteracyType extends BaseModel implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Name + @Comment("id") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @Comment("类型编码") + @ColDefine(type = ColType.VARCHAR, width = 80) + private String code; + + @Column + @Comment("类型名称") + @ColDefine(type = ColType.VARCHAR, width = 80) + private String typeName; + + @Column + @Comment("序号") + @ColDefine(type = ColType.INT, width = 1) + private Integer xh; + + @Column + @Comment("是否携带家属") + @ColDefine(type = ColType.BOOLEAN) + @Default("0") + private Boolean isBringFamily; + + @Column + @Comment("家属纳入总人数") + @ColDefine(type = ColType.BOOLEAN) + @Default("0") + private Boolean isAddFamily; + + @Column + @Comment("本人纳入总人数") + @ColDefine(type = ColType.BOOLEAN) + @Default("1") + private Boolean selfAddFamily; + + @Many(field = "typeId") + private List literacyMobileSignColumnList; +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyTypeLimit.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyTypeLimit.java new file mode 100644 index 00000000..b3085818 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyTypeLimit.java @@ -0,0 +1,40 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import lombok.Data; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.io.Serializable; + +/** + * @Author JyuHsin + * @Date 2022/9/22 + * @Description + */ +@Table("literacy_type_limit") +@Data +public class LiteracyTypeLimit implements Serializable { + + private static final long serialVersionUID = 1L; + + @Name + @Comment("id") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @Comment("活动id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String activityId; + + @Column + @Comment("活动类型id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String typeId; + + @Column + @Comment("限制个数") + @ColDefine(type = ColType.INT, width = 10) + private int limitNum; +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUser.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUser.java new file mode 100644 index 00000000..3b3acf4f --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUser.java @@ -0,0 +1,88 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; +import org.nutz.lang.util.NutMap; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * @author zxy + * @Description 报名人员 报名记录 + * @createTime 2022年02月23日 09:34:00 + */ +@Table +@Data +@Accessors(chain = true) +@TableIndexes({@Index(name = "INDEX_TRAIN_SIGN_UP_USER_COURSEID", fields = {"courseId"}, unique = false)}) +public class LiteracyUser implements Serializable { + + @Name + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("活动ID") + private String activityId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("课程ID") + private String courseId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("用户ID") + private String userId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("工会ID") + private String unionId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("单位ID") + private String unitId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("工会") + private String unionName; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("单位") + private String unitName; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("联系方式") + private String mobile; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("报名时间") + private Date signUpTime; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("活动课程时段id") + private String activityCourseId; + + @Column + @ColDefine(type = ColType.MYSQL_JSON) + @Comment("手机端报名字段和值") + private List mobileColumnsValue; + + @Column + @ColDefine(type = ColType.INT) + @Comment("用户报名状态(1.正常 2.待报名成功 3.也是正常,但是是从2变为1的 4.废弃[就是没签到的意思])") + private Integer state; + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUserCourse.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUserCourse.java new file mode 100644 index 00000000..0ba75453 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/models/LiteracyUserCourse.java @@ -0,0 +1,89 @@ +package com.budwk.app.zhgh.activity.literacy.models; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author zxy + * @Description 用户课程表 + * @createTime 2022年02月23日 09:38:00 + */ +@Table +@Data +@Accessors(chain = true) +@TableIndexes({ + @Index(name = "INDEX_TRAIN_SIGN_UP_USER_COURSE_USERID", fields = {"userId"}, unique = false), + @Index(name = "INDEX_TRAIN_SIGN_UP_USER_COURSE_COURSEID", fields = {"courseId"}, unique = false) +}) +public class LiteracyUserCourse implements Serializable { + + @Name + @PrevInsert(uu32 = true) + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("活动ID") + private String activityId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("课程ID") + private String courseId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("用户ID") + private String userId; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("课程开始时间") + private Date courseStartTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("课程结束时间") + private Date courseEndTime; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("是否上课") + private boolean isAttend; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("上课打卡时间") + private Date attendTime; + + @Column + @ColDefine(type = ColType.BOOLEAN) + @Comment("是否领取礼品") + private Boolean isReceive; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("领取礼品时间") + private Date receiveTime; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("签到扫码人员id(二维码模式)") + private String signScannerCodeUserId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("礼品扫码人员id(二维码模式)") + private String giftScannerCodeUserId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("关联literacy_sign_up_activity_course表的id") + private String activityCourseId; + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityService.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityService.java new file mode 100644 index 00000000..dbf9abdb --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityService.java @@ -0,0 +1,129 @@ +package com.budwk.app.zhgh.activity.literacy.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyActivity; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser; +import org.nutz.dao.Cnd; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** + * @author zxy + * @Description TODO + * @createTime 2022年02月23日 17:14:00 + */ +public interface LiteracyActivityService extends BaseService { + + /** + * 添加活动 + * + * @param activity 活动信息 + * @param course 培训班信息 + */ + void add(LiteracyActivity activity, LiteracyCourse course); + + /** + * 编辑活动 + * + * @param activity 活动信息 + */ + void edit(LiteracyActivity activity); + + /** + * 更新活动状态 + * + * @param activity 活动信息 + */ + void updateActivityStatus(LiteracyActivity activity); + + /** + * 查询单条活动信息 + * + * @param id 活动ID + * @return 返回的数据与前端符合 + */ + NutMap findOne(String id, Cnd cnd, String fromMode); + + /** + * pc分页查询 + * + * @param pageForm + * @param cnd + * @return + */ + Pagination pageData(PageForm pageForm, Cnd cnd); + + + /** + * 手机端分页查询 + * + * @param pageForm 分页 + * @param year 年度 + * @param activityStatus 报名状态 0全部 1进行中 2结束 + * @return + */ + Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType); + + /** + * 手机端报名 + * + * @param trainSignUpUser 活动ID + */ + void doSignUp(LiteracyUser trainSignUpUser) throws Exception; + + /** + * 异步插入每个报名成功人员的课程数据 + * + * @param activityId + * @param courseId + * @param userId + */ + void asyncInsertUserCourse(String activityId, String courseId, String userId); + + /** + * 该培训班每个分工会名额是否报满 + * @return + */ + boolean isSignFullByUnionId(LiteracyCourse course, Integer currentFamilyNumber); + + /** + * 该培训班是否报满 + */ + boolean isSignFull(LiteracyCourse course, Integer currentFamilyNumber); + + /** + * 还能报该类型的培训班吗 比如书画班最多报一项 健身班两项 + * @return + */ + boolean isSignCourse(LiteracyCourse course, LiteracyActivity activity); + + /** + * 当前用户是否已报过该培训班 + * + * @param courseId + * @param userId + * @return + */ + boolean isSignCourseByUser(String courseId, String userId); + + /** + * 手机端签到 + * + * @param id 每个培训班每节课每个用户的记录ID + */ + void doQd(String id); + + /** + * 某个用户的签到信息 + * + * @param userId 用户id + * @param activityId 活动id + */ + List qdInfoByUserId(String userId, String activityId); + + List filterCourseByHostUnion(List courseList); +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityStatisticsService.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityStatisticsService.java new file mode 100644 index 00000000..02a43dc4 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyActivityStatisticsService.java @@ -0,0 +1,68 @@ +package com.budwk.app.zhgh.activity.literacy.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser; +import org.nutz.lang.util.NutMap; + +import java.util.List; +import java.util.Map; + +/** + * @author zxy + * @Description 报名统计service + * @createTime 2022年03月03日 10:00:00 + */ +public interface LiteracyActivityStatisticsService extends BaseService { + + /** + * 统计分页 + * + * @param pageForm + * @param activityId + * @return + */ + Pagination pageData(PageForm pageForm, String activityId); + + /** + * 该课程下的报名人员信息 + * + * @param courseId + * @return + */ + List registerUserList(String courseId); + + List getTaleColumnInfo(String courseId); + + /** + * 该课程下的报名人员信息 + * + * @param courseId + * @return + */ + List registerUserList(String courseId, String unionId, String unitId, String searchName, String searchKeyword); + + /** + * 获取每个课程的签到情况 + * + * @param courseId + * @return k->每个培训班每节课的上课时间 v->上课记录list + */ + Map> getSignInfo(String courseId); + + /** + * 报名人员list 导出 + * @param activityId + * @return + */ + List baoMingUserList(String activityId); + + int queryCourseCount(String courseId, String courseType); + + int queryCourseWaitCount(String courseId, String courseType); + + int queryCourseCount(String courseId, String courseType, String unionId); + + int queryCourseWaitCount(String courseId, String courseType, String unionId); +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyBlackListService.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyBlackListService.java new file mode 100644 index 00000000..15003233 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/LiteracyBlackListService.java @@ -0,0 +1,43 @@ +package com.budwk.app.zhgh.activity.literacy.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyBlackList; +import org.nutz.dao.Cnd; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** + * @author zxy + * @Description TODO + * @createTime 2022年03月07日 14:29:00 + */ +public interface LiteracyBlackListService extends BaseService { + + /** + * 分页 + * + * @param pageForm 分页 + * @return Pagination + */ + Pagination pageData(PageForm pageForm, Cnd cnd, String activityId, String courseId); + + /** + * 拉黑、解封用户 + * + * @param userId + */ + void doHandleUser(String userId); + + /** + * 上课记录 + * + * @param userId + * @return + */ + List attendClassRecord(String userId); + + +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityServiceImpl.java new file mode 100644 index 00000000..4a1fde18 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityServiceImpl.java @@ -0,0 +1,473 @@ +package com.budwk.app.zhgh.activity.literacy.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.sys.models.Sys_home_activity; +import com.budwk.app.sys.views.View_user; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.activity.literacy.models.*; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityService; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService; +import lombok.extern.slf4j.Slf4j; +import org.nutz.aop.interceptor.async.Async; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.Static; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author zxy + * @Description TODO + * @createTime 2022年02月23日 17:14:00 + */ +@Slf4j +@IocBean(args = {"refer:dao"}) +public class LiteracyActivityServiceImpl extends BaseServiceImpl implements LiteracyActivityService { + + @Inject + private LiteracyActivityStatisticsService statisticsService; + + public LiteracyActivityServiceImpl(Dao dao) { + super(dao); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void add(LiteracyActivity activity, LiteracyCourse course) { + + dao().insert(activity); + + //插入类型限制 + List typeLimits = activity.getTypeLimits(); + typeLimits.forEach(v -> v.setActivityId(activity.getId())); + dao().insert(typeLimits); + + List courseList = activity.getCourseList(); + for (LiteracyCourse v : courseList) { + v.setActivityId(activity.getId()); + v.setOpenOtherUnion(false); + dao().insert(v); + this.setCourseTimeAndInsert(v); + } + + if (!activity.isDisabled()) { + Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity(); + dao().insertOrUpdate(sysHomeActivity); + } + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void edit(LiteracyActivity activity) { + + //修改活动 + update(activity); + + //修改类型限制 + List typeLimits = activity.getTypeLimits(); + typeLimits.forEach(v -> v.setActivityId(activity.getId())); + if(Lang.isNotEmpty(typeLimits)) { + insertOrUpdate(typeLimits); + } + + List courseList = activity.getCourseList(); + courseList.forEach(v -> { + v.setActivityId(activity.getId()); + dao().insertOrUpdate(v); + if (Lang.isNotEmpty(v.getCourseTimeList())) { + this.setCourseTimeAndInsert(v); + } + }); + + //查询原来的活动 + List oldCourseList = dao().query(LiteracyCourse.class, Cnd.where("activityId", "=", activity.getId())); + //原来的培训班id + List oldCourseIdList = oldCourseList.stream().map(LiteracyCourse::getId).toList(); + + //原来的上课时间 + List oldActCourseTimeList = dao().query(LiteracyActivityCourse.class, Cnd.where("activityId", "=", activity.getId())); + + //现在的上课时间 + List nowCourseTimeListId = new ArrayList<>(); + activity.getCourseList().forEach(v -> { + if (v.getCourseTimeList() != null) { + nowCourseTimeListId.addAll(v.getCourseTimeList().stream().map(LiteracyActivityCourse::getId).toList()); + } + }); + + List deleteCourseTimeListId = oldActCourseTimeList.stream().map(LiteracyActivityCourse::getId).filter(id -> !nowCourseTimeListId.contains(id)).collect(Collectors.toList()); + List courseIdList = courseList.stream().map(LiteracyCourse::getId).collect(Collectors.toList()); + + //删除关联的培训班 + List deleteIdList = oldCourseIdList.stream().filter(v -> !courseIdList.contains(v)).collect(Collectors.toList()); + dao().clear(LiteracyCourse.class, Cnd.where("id", "in", deleteIdList)); + + dao().clear(LiteracyActivityCourse.class, Cnd.where("id", "in", deleteCourseTimeListId)); + dao().clear(LiteracyUser.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId())); + dao().clear(LiteracyUserCourse.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId())); + + //查询修改过培训时间的记录 + Sql tsuucSql = Sqls.create(""" + SELECT + tsuuc.id, + tsuac.courseStartTime, + tsuac.courseEndTime + FROM + `literacy_user_course` tsuuc + LEFT JOIN literacy_activity_course tsuac ON tsuac.id = tsuuc.activityCourseId + where tsuuc.courseStartTime != tsuac.courseStartTime or tsuuc.courseEndTime != tsuac.courseEndTime + """); + List tsuucList = listMap(tsuucSql); + tsuucList.forEach(v -> { + Chain chain = Chain.make("courseStartTime", v.getTime("courseStartTime")); + chain.add("courseEndTime", v.getTime("courseEndTime")); + Cnd cnd = Cnd.where("id", "=", v.getString("id")); + dao().update("literacy_user_course", chain, cnd); + }); + + if (!activity.isDisabled()) { + Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity(); + dao().insertOrUpdate(sysHomeActivity); + } else { + dao().delete(Sys_home_activity.class, activity.getId()); + } + } + + private void setCourseTimeAndInsert(LiteracyCourse course) { + course.getCourseTimeList().forEach(courseTime -> { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(courseTime.getCourseDate()); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH); + int day = calendar.get(Calendar.DATE); + + Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(courseTime.getCourseStartTime()); + startCalendar.set(year, month, day); + courseTime.setCourseStartTime(startCalendar.getTime()); + + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(courseTime.getCourseEndTime()); + endCalendar.set(year, month, day); + courseTime.setCourseEndTime(endCalendar.getTime()); + + courseTime.setActivityId(course.getActivityId()); + courseTime.setCourseId(course.getId()); + dao().insertOrUpdate(courseTime); + }); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void updateActivityStatus(LiteracyActivity activity) { + updateIgnoreNull(activity); + } + + @Override + public NutMap findOne(String id, Cnd cnd, String fromMode) { + if (Lang.isEmpty(cnd)) { + cnd = Cnd.NEW(); + } + + cnd.asc("orderNum").asc("campus").desc("courseLocation").asc("courseType").asc("courseName"); + List courseArray = dao().query(LiteracyCourse.class, cnd.and("activityId", "=", id)); + + if (StrUtil.isNotBlank(fromMode) && "mobile".equals(fromMode)) { + courseArray = this.filterCourseByHostUnion(courseArray); + } + + LiteracyActivity activity = fetchLinks(dao().fetch(LiteracyActivity.class, id), "^(conditionStructure|typeLimits)$"); + activity.setCourseList(courseArray); + + List courseList = activity.getCourseList(); + + courseList.forEach(c -> { + if (StrUtil.isNotBlank(c.getCourseType())) { + dao().fetchLinks(c, "^(courseTimeList)$", Cnd.NEW().asc("courseStartTime")); + int courseCount = statisticsService.queryCourseCount(c.getId(), c.getCourseType()); + c.setHasRegisterNum(courseCount); + int courseWaitCount = statisticsService.queryCourseWaitCount(c.getId(), c.getCourseType()); + c.setHasWaitingNum(courseWaitCount); + //当前用户是否报过 + c.setIsSign(isSignCourseByUser(c.getId(), SecurityUtil.getUserId())); + } + }); + return Lang.obj2nutmap(activity); + } + + @Override + public Pagination pageData(PageForm pageForm, Cnd cnd) { + Pagination pagination = listPageLinks(pageForm.getPageNumber(), pageForm.getPageSize(), cnd, "^(courseList)$"); + return pagination; + } + + @Override + public Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType) { + Cnd cnd = Cnd.NEW(); + cnd.andEX("year", "=", year); + switch (activityStatus) { + case 2 -> { + cnd.and(new Static("activitySignUpStartTime < now()")); + cnd.and(new Static("activitySignUpEndTime > now()")); + } + case 3 -> { + cnd.and(new Static("activityStartTime < now()")); + cnd.and(new Static("activityEndTime > now()")); + } + case 4 -> cnd.and(new Static("activityEndTime < now()")); + case 5 -> cnd.and(new Static("activityStartTime < now()")); + case 6 -> cnd.and(new Static("activityStartTime > now()")); + } + if (activityType != null && activityType == 1) { + cnd.and(new Static("id in (select activityId from literacy_user where userId = '%s')".formatted(SecurityUtil.getUserId()))); + } + cnd.and("isDisabled", "=", 0); + cnd.orderBy("activityEndTime", "desc"); + cnd.orderBy("isDisabled", "desc"); + cnd.orderBy("createdAt", "desc"); + return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public void doSignUp(LiteracyUser literacyUser) throws Exception { + String userId = SecurityUtil.getUserId(); + + //查询课程 + LiteracyCourse course = dao().fetch(LiteracyCourse.class, literacyUser.getCourseId()); + LiteracyType type = dao().fetch(LiteracyType.class, course.getCourseType()); + //如果这个课程的预留名额方式为报名人数不变 + if (course.getReserveMode() == 2) { + //如果当前报名+已报小于这个课程限制人数 + //课程已报人数 + int normalCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType()); + //+1是算自己 + int hasRegisterNum = type.getSelfAddFamily() ? normalCount + 1 : 0; + literacyUser.setState((hasRegisterNum + course.getCourseReservedNumber()) > course.getCoursePeopleNumber() ? 2 : 1); + } else { + literacyUser.setState(1); + } + + View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", SecurityUtil.getUserId())); + literacyUser.setUnionId(SecurityUtil.getUnionId()); + literacyUser.setUnionName(user.getUnionName()); + literacyUser.setUnitId(SecurityUtil.getUnitId()); + literacyUser.setUnitName(user.getUnitName()); + literacyUser.setUserId(userId); + literacyUser.setSignUpTime(new Date()); + + dao().insert(literacyUser); + + if (StrUtil.isNotBlank(literacyUser.getActivityCourseId())) { + LiteracyActivityCourse fetch = dao().fetch(LiteracyActivityCourse.class, literacyUser.getActivityCourseId()); + LiteracyUserCourse userCourse = new LiteracyUserCourse(); + userCourse.setActivityId(literacyUser.getActivityId()); + userCourse.setCourseId(literacyUser.getCourseId()); + userCourse.setUserId(literacyUser.getUserId()); + userCourse.setCourseStartTime(fetch.getCourseStartTime()); + userCourse.setCourseEndTime(fetch.getCourseEndTime()); + userCourse.setAttend(false); + userCourse.setAttendTime(null); + userCourse.setActivityCourseId(fetch.getId()); + dao().insert(userCourse); + } else { + asyncInsertUserCourse(literacyUser.getActivityId(), literacyUser.getCourseId(), literacyUser.getUserId()); + } + } + + @Async + @Override + public void asyncInsertUserCourse(String activityId, String courseId, String userId) { + log.info("异步插入{}的上课信息,课程ID为{},活动ID为{}", userId, courseId, activityId); + List courseList = dao().query(LiteracyActivityCourse.class, Cnd.where("courseId", "=", courseId)); + List list = new ArrayList<>(); + courseList.forEach(v -> { + LiteracyUserCourse userCourse = new LiteracyUserCourse(); + userCourse.setActivityId(activityId); + userCourse.setCourseId(courseId); + userCourse.setUserId(userId); + userCourse.setCourseStartTime(v.getCourseStartTime()); + userCourse.setCourseEndTime(v.getCourseEndTime()); + userCourse.setAttend(false); + userCourse.setAttendTime(null); + userCourse.setActivityCourseId(v.getId()); + list.add(userCourse); + }); + dao().insert(list); + } + + /** + * 该培训班每个分工会名额是否报满 + * @return + */ + @Override + public boolean isSignFullByUnionId(LiteracyCourse course, Integer currentFamilyNumber) { + List unionLimit = course.getUnionLimit(); + if (Lang.isEmpty(unionLimit)) { + return false; + } + String unionId = SecurityUtil.getUnionId(); + NutMap unionLimitMap = unionLimit.stream().filter(v -> v.getString("id").equals(unionId)).findAny().orElse(null); + if (Lang.isEmpty(unionLimitMap)) { + return true; + } + + LiteracyType type = dao().fetch(LiteracyType.class, course.getCourseType()); + //分工会限制人数 + int limitCount = unionLimitMap.getInt("limitCount"); + + //该课程已经报名的总人数 + int hasSignCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType(), unionId); + int hasWaitCount = statisticsService.queryCourseWaitCount(course.getId(), course.getCourseType()); + + //+1是算自己 + int current = type.getSelfAddFamily() ? 1 : 0; + currentFamilyNumber = type.getIsBringFamily() && type.getIsAddFamily() ? currentFamilyNumber : 0; + //如果还有正常名额 + if(limitCount - hasSignCount > 0) { + return (hasSignCount + current + currentFamilyNumber) > limitCount; + } else { + return (hasWaitCount + current + currentFamilyNumber) > course.getWaitingNum(); + } + } + + @Override + public boolean isSignFull(LiteracyCourse course, Integer currentFamilyNumber) { + //课程限制人数 + int coursePeopleNumber = course.getCoursePeopleNumber(); + if (coursePeopleNumber == 0) { + return true; + } + //查询课程对应的类型 + LiteracyType type = dao().fetch(LiteracyType.class, course.getCourseType()); + //课程已报人数 + int hasSignCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType()); + int hasWaitCount = statisticsService.queryCourseWaitCount(course.getId(), course.getCourseType()); + + //+1是算自己 + int current = type.getSelfAddFamily() ? 1 : 0; + currentFamilyNumber = type.getIsBringFamily() && type.getIsAddFamily() ? currentFamilyNumber : 0; + //如果还有正常名额 + if(coursePeopleNumber - hasSignCount > 0) { + return (hasSignCount + current + currentFamilyNumber + course.getCourseReservedNumber()) > coursePeopleNumber; + } else { + return (hasWaitCount + current + currentFamilyNumber) > course.getWaitingNum(); + } + } + + @Override + public boolean isSignCourse(LiteracyCourse course, LiteracyActivity activity) { + //培训班类型 + String courseType = course.getCourseType(); + + Sql sql = Sqls.create(""" + SELECT + count( tsus.id ) + FROM + `literacy_user` tsus + LEFT JOIN literacy_course tsuc ON tsuc.id = tsus.courseId + WHERE + tsuc.courseType = @courseType + AND tsus.userId = @userId + AND tsus.activityId = @activityId + """); + sql.setParam("courseType", courseType); + sql.setParam("activityId", activity.getId()); + sql.setParam("userId", SecurityUtil.getUserId()); + int hasRegisterNum = count(sql); + + //第一种无限制报名 + if (activity.getRestrictLimit() == null || activity.getRestrictLimit() == 1) { + return true; + } else if (activity.getRestrictLimit() == 2) { + LiteracyTypeLimit literacyTypeLimit = dao().fetch(LiteracyTypeLimit.class, Cnd.where("typeId", "=", courseType).and("activityId", "=", activity.getId())); + if (literacyTypeLimit == null) { + return true; + } + //此类型的班最多可报几项 + int personMaxRegisterNum = literacyTypeLimit.getLimitNum(); + if (personMaxRegisterNum == 0) { + return true; + } + return hasRegisterNum < personMaxRegisterNum; + } else if (activity.getRestrictLimit() == 3) { + //第三种,限制报几个,不跟类型挂钩 + int aCount = dao().count(LiteracyUser.class, Cnd.where("activityId", "=", activity.getId()).and("userId", "=", SecurityUtil.getUserId())); + return aCount < activity.getLimitNum(); + } + return false; + } + + @Override + public boolean isSignCourseByUser(String courseId, String userId) { + return dao().count(LiteracyUser.class, Cnd.where("courseId", "=", courseId).and("userId", "=", userId)) > 0; + } + + @Override + public void doQd(String id) { + NutMap updateMap = NutMap.NEW(); + updateMap.put("isAttend", true); + updateMap.put("attendTime", new Date()); + dao().update(LiteracyUserCourse.class, Chain.from(updateMap), Cnd.where("id", "=", id)); + } + + @Override + public List qdInfoByUserId(String userId, String activityId) { + Sql sql = Sqls.create(""" + SELECT + c.*, + t.courseLocationCoordinates, + t.isMobileSign, + t.signType, + t.isReceiveGift, + t.giftType, + (select state from literacy_user su where su.activityId = c.activityId and su.courseId = c.courseId and su.userId = c.userId) as state + FROM + `literacy_user_course` c + LEFT JOIN literacy_course t ON t.id = c.courseId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("c.activityId", "=", activityId); + cnd.and("c.userId", "=", userId); + cnd.asc("c.courseStartTime"); + + sql.setCondition(cnd); + return listMap(sql); + } + + @Override + public List filterCourseByHostUnion(List courseList) { + if (Lang.isEmpty(courseList)) { + return new ArrayList<>(); + } + return courseList.stream().filter(o -> { + if (StrUtil.isBlank(o.getInterTime()) || o.getOpenOtherUnion() == null || o.getOpenOtherUnion()) { + return true; + } else { + if (SecurityUtil.getUnionId().equals(o.getHostUnionId())) { + return true; + } else { + int compare = cn.hutool.core.date.DateUtil.compare(cn.hutool.core.date.DateUtil.date(), cn.hutool.core.date.DateUtil.parse(o.getInterTime()), "yyyy-MM-dd HH:mm"); + return compare >= 0; + } + } + }).toList(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityStatisticsServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityStatisticsServiceImpl.java new file mode 100644 index 00000000..e7a2ed64 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyActivityStatisticsServiceImpl.java @@ -0,0 +1,260 @@ +package com.budwk.app.zhgh.activity.literacy.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.zhgh.activity.literacy.models.LiteracyMobileSignColumn; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyCourse; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyType; +import com.budwk.app.zhgh.activity.literacy.models.LiteracyUser; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyActivityStatisticsService; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; + +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * @author zxy + * @Description TODO + * @createTime 2022年03月03日 10:02:00 + */ +@IocBean(args = {"refer:dao"}) +@Slf4j +public class LiteracyActivityStatisticsServiceImpl extends BaseServiceImpl implements LiteracyActivityStatisticsService { + + public LiteracyActivityStatisticsServiceImpl(Dao dao) { + super(dao); + } + + @Override + public Pagination pageData(PageForm pageForm, String activityId) { + Sql sql = Sqls.create(""" + SELECT + tsuc.id, + tsuc.courseName, + tsuc.coursePeopleNumber, + tsuc.courseReservedNumber, + type.typeName as courseType, + tsuc.courseLocation, + tsuc.courseInstructor, + tsuc.reserveMode, + tsuc.isMobileSign, + tsuc.hostUnionId, + tsuc.interTime, + tsuc.waitingNum, + tsuc.openOtherUnion, + tsuc.courseType as cType + FROM + `literacy_course` tsuc + LEFT JOIN + literacy_type type on tsuc.courseType = type.id + WHERE + tsuc.activityId = @activityId + ORDER BY tsuc.orderNum + """); + sql.setParam("activityId", activityId); + Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + List courseList = pagination.getList(); + courseList.forEach(c -> { + c.put("registerNum", queryCourseCount(c.getString("id"), c.getString("cType"))); + c.put("hasWaitingNum", queryCourseWaitCount(c.getString("id"), c.getString("cType"))); + }); + return pagination; + } + + @Override + public List registerUserList(String courseId) { + Sql sql = Sqls.create(""" + SELECT + u.loginname, + u.username, + u.sex, + tsuu.unionId, + tsuu.unionName, + tsuu.unitId, + tsuu.unitName, + ifnull(tsuu.mobile, u.mobile) as mobile, + tsuu.signUpTime, + tsuu.state, + tsuu.mobileColumnsValue + FROM + literacy_user tsuu + LEFT JOIN `vw_user` u ON u.id = tsuu.userId + $condition + ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ),u.unionid desc, u.unitid desc + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("tsuu.courseId", "=", courseId); + sql.setCondition(cnd); + List list = listMap(sql); + list.forEach(o -> { + List mobileColumnsValue = Json.fromJsonAsList(NutMap.class, o.getString("mobileColumnsValue")); + if(Lang.isNotEmpty(mobileColumnsValue)) { + mobileColumnsValue.forEach(m -> { + o.put(m.getString("columnCode"), m.getString("columnValue")); + }); + } + }); + return list; + } + + @Override + public List getTaleColumnInfo(String courseId) { + LiteracyCourse course = dao().fetch(LiteracyCourse.class, courseId); + LiteracyType upType = dao().fetch(LiteracyType.class, course.getCourseType()); + dao().fetchLinks(upType, "literacyMobileSignColumnList", Cnd.NEW().asc("columnIndex")); + + List columnList = upType.getLiteracyMobileSignColumnList(); + List columnTableList = columnList.stream().map(o -> NutMap.NEW().setv("label", o.getColumnName()).setv("prop", o.getColumnCode())).collect(Collectors.toList()); + return columnTableList; + } + + @Override + public List registerUserList(String courseId, String unionId, String unitId, String searchName, String searchKeyword) { + Sql sql = Sqls.create(""" + SELECT + tsuu.id, + u.id as userId, + u.loginname, + u.username, + u.unitname, + u.unionname, + u.sex, + ifnull(tsuu.mobile, u.mobile) as mobile, + tsuu.signUpTime, + tsuu.state + FROM + literacy_user tsuu + LEFT JOIN `vw_user` u ON u.id = tsuu.userId + $condition + ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ),u.unionid desc, u.unitid desc + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("tsuu.courseId", "=", courseId); + cnd.andEX("u.unionid", "=", unionId); + cnd.andEX("u.unitid", "=", unitId); + if (StrUtil.isNotBlank(searchKeyword)) { + SqlExpressionGroup group = new SqlExpressionGroup(); + group.andLike("username", searchKeyword).orLike("loginname", searchKeyword); + cnd.and(group); + } + sql.setCondition(cnd); + return listMap(sql); + } + + @Override + public Map> getSignInfo(String courseId) { + Sql sql = Sqls.create(""" + SELECT + tsuuc.courseStartTime, + tsuuc.courseEndTime, + tsuuc.isAttend, + tsuuc.attendTime, + u.username, + u.loginname, + u.unitname, + u.unionname + FROM + `literacy_user_course` tsuuc + LEFT JOIN `vw_user` u ON u.id = tsuuc.userId + WHERE + tsuuc.courseId = @courseId + """); + sql.setParam("courseId", courseId); + List list = listMap(sql); + + Map> courseTimeMap = list.stream().map(v -> { + String courseTime = v.getString("courseStartTime") + " 至 " + v.getString("courseEndTime"); + v.put("courseTime", courseTime); + return v; + }).collect(Collectors.groupingBy(v -> v.getString("courseTime"))); + + // 使用Stream API进行降序排序 + Map> sortedDataMap = courseTimeMap.entrySet().stream() + .sorted(Map.Entry.comparingByKey(Comparator.reverseOrder())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + + return sortedDataMap; + } + + @Override + public List baoMingUserList(String activityId) { + Sql sql = Sqls.create(""" + SELECT + u.loginname, + u.username, + u.unitname, + u.unionname, + u.sex, + u.mobile, + uc.courseName, + uc.campus + FROM + `literacy_user` uu + RIGHT JOIN literacy_course uc ON uc.id = uu.courseId + LEFT JOIN `vw_user` u ON u.id = uu.userId + WHERE + uc.activityId = @activityId + ORDER BY u.unitCode,u.unioncode,u.sex + """); + sql.setParam("activityId", activityId); + return listMap(sql); + } + + @Override + public int queryCourseCount(String courseId, String courseType) { + return this.queryCourseCount(courseId, courseType, null); + } + + @Override + public int queryCourseWaitCount(String courseId, String courseType) { + return this.queryCourseWaitCount(courseId, courseType, null); + } + + @Override + public int queryCourseCount(String courseId, String courseType, String unionId) { + return this.calcSignCount(courseId, courseType, unionId, List.of(1, 3)); + } + + @Override + public int queryCourseWaitCount(String courseId, String courseType, String unionId) { + return this.calcSignCount(courseId, courseType, unionId, List.of(2)); + } + + private int calcSignCount(String courseId, String courseType, String unionId, List stateList) { + if(StrUtil.isBlank(courseId) || StrUtil.isBlank(courseType)) { + return 0; + } + LiteracyType type = dao().fetch(LiteracyType.class, courseType); + AtomicInteger hasRegisterNum = new AtomicInteger(); + List signUpUsers = dao().query(LiteracyUser.class, Cnd.where("courseId", "=", courseId) + .and("state", "in", stateList) + .andEX("unionId", "=", unionId)); + signUpUsers.forEach(item -> { + if (type.getSelfAddFamily()) { + hasRegisterNum.getAndIncrement(); + } + if(type.getIsBringFamily() && type.getIsAddFamily()) { + List mobileColumnsValue = item.getMobileColumnsValue(); + NutMap map = mobileColumnsValue.stream().filter(o -> "xdqsrs".equals(o.getString("columnCode"))).findAny().orElse(null); + int number = map != null ? map.getInt("columnValue") : 0; + hasRegisterNum.addAndGet(number); + } + }); + return hasRegisterNum.get(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyUserServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyUserServiceImpl.java new file mode 100644 index 00000000..5bb18fdb --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/literacy/service/impl/LiteracyUserServiceImpl.java @@ -0,0 +1,103 @@ +package com.budwk.app.zhgh.activity.literacy.service.impl; + +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.zhgh.activity.literacy.models.LiteracyBlackList; +import com.budwk.app.zhgh.activity.literacy.service.LiteracyBlackListService; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Criteria; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** + * @author zxy + * @Description TODO + * @createTime 2022年03月07日 14:29:00 + */ +@IocBean(args = {"refer:dao"}) +public class LiteracyUserServiceImpl extends BaseServiceImpl implements LiteracyBlackListService { + + public LiteracyUserServiceImpl(Dao dao) { + super(dao); + } + + @Override + public Pagination pageData(PageForm pageForm, Cnd cnd, String activityId, String courseId) { + Sql sql = Sqls.create(""" + SELECT + u.id AS userId, + u.username, + u.loginname, + ifnull(tsuu.mobile, u.mobile) as mobile, + u.unitname, + u.unionname, + tsuc.courseName, + tsuu.state, + ( SELECT count( 1 ) FROM literacy_user_course WHERE userId = tsuu.userId $var) courseTotal, + ( SELECT count( 1 ) FROM literacy_user_course WHERE userId = tsuu.userId AND isAttend = 0 and tsuu.state!=2 AND now()> courseEndTime $var) AS absentCount, + if(tsubl.isDisabled=1,true,false) isDisabled, + group_CONCAT( tsuc.courseName ) AS courseNames + FROM + `literacy_user` tsuu + LEFT JOIN `vw_user` u ON u.id = tsuu.userId + LEFT JOIN literacy_activity act on act.id = tsuu.activityId + LEFT JOIN literacy_course tsuc ON tsuc.id = tsuu.courseId + LEFT JOIN literacy_black_list tsubl on tsubl.userId = tsuu.userId + $condition + ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ) + """); + cnd.groupBy("tsuu.userId"); + Criteria varCnd = Cnd.cri(); + varCnd.where().setTop(false); + varCnd.where().andEX("activityId", "=", activityId); + varCnd.where().andEX("courseId", "=", courseId); + if (!varCnd.where().isEmpty()) { + sql.vars().set("var", "and " + varCnd.toSql(null)); + } + sql.setCondition(cnd); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + + @Override + public void doHandleUser(String userId) { + LiteracyBlackList blackRecord = dao().fetch(LiteracyBlackList.class, Cnd.where("userId", "=", userId)); + if (Lang.isEmpty(blackRecord)) { + LiteracyBlackList blackList = new LiteracyBlackList(); + blackList.setUserId(userId); + blackList.setIsDisabled(true); + dao().insert(blackList); + } else { +// blackRecord.setIsDisabled(!blackRecord.getIsDisabled()); +// dao().update(blackRecord); + dao().delete(blackRecord); + } + + } + + @Override + public List attendClassRecord(String userId) { + Sql sql = Sqls.create(""" + SELECT + c.courseName, + uc.courseStartTime, + courseEndTime, + uc.isAttend, + uc.attendTime + FROM + `literacy_user_course` uc + LEFT JOIN literacy_course c ON c.id = uc.courseId + WHERE + uc.userId = @userId + """); + sql.setParam("userId", userId); + return listMap(sql); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/trainSignUp/service/impl/TrainSignUpUserServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/trainSignUp/service/impl/TrainSignUpUserServiceImpl.java index 2ba4a613..aed40ef3 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/trainSignUp/service/impl/TrainSignUpUserServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/activity/trainSignUp/service/impl/TrainSignUpUserServiceImpl.java @@ -40,7 +40,7 @@ public class TrainSignUpUserServiceImpl extends BaseServiceImpl courseEndTime $var) AS absentCount, if(tsubl.isDisabled=1,true,false) isDisabled, group_CONCAT( tsuc.courseName ) AS courseNames diff --git a/src/main/java/com/budwk/app/zhgh/club/controller/apply/ClubUserJoinMineController.java b/src/main/java/com/budwk/app/zhgh/club/controller/apply/ClubUserJoinMineController.java index b9f8d54f..3b206bac 100644 --- a/src/main/java/com/budwk/app/zhgh/club/controller/apply/ClubUserJoinMineController.java +++ b/src/main/java/com/budwk/app/zhgh/club/controller/apply/ClubUserJoinMineController.java @@ -27,6 +27,7 @@ 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.validation.Valid; @@ -49,7 +50,8 @@ public class ClubUserJoinMineController { @At @SaCheckPermission("club.join.mine") - public Result pageData(@Valid PageForm pageForm){ + public Result pageData(@Valid PageForm pageForm, + @Param("year") Integer year){ Sql sql = Sqls.create(""" SELECT info.*, @@ -83,6 +85,7 @@ public class ClubUserJoinMineController { """); Cnd cnd = Cnd.NEW(); cnd.and("info.userId", "=", SecurityUtil.getUserId()); + cnd.andEX("year(info.applyDate)", "=", year); cnd.groupBy("info.id"); cnd.desc("info.applyDate"); sql.setCondition(cnd); @@ -117,7 +120,8 @@ public class ClubUserJoinMineController { u.unionName, u.technicalTitle, u.education, - u.academicDegree + u.academicDegree, + u.position FROM club_user_apply cua LEFT JOIN vw_user u ON u.id = cua.userId diff --git a/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java b/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java index 71fb98ef..e747fdd5 100644 --- a/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java +++ b/src/main/java/com/budwk/app/zhgh/club/controller/statistics/ClubStatisticsController.java @@ -337,8 +337,8 @@ public class ClubStatisticsController { sum( CASE WHEN cu.userId is not null $myCondition THEN 1 ELSE 0 END ) AS total, sum( CASE WHEN su.userState in ('在职', '在岗') $myCondition THEN 1 ELSE 0 END ) AS `work`, sum( CASE WHEN su.userState in ('退休') $myCondition THEN 1 ELSE 0 END ) AS retire, - sum( CASE WHEN su.sex = '男' $myCondition THEN 1 ELSE 0 END ) AS man, - sum( CASE WHEN su.sex = '女' $myCondition THEN 1 ELSE 0 END ) AS woman, + sum( CASE WHEN su.sex like '%男%' $myCondition THEN 1 ELSE 0 END ) AS man, + sum( CASE WHEN su.sex like '%女%' $myCondition THEN 1 ELSE 0 END ) AS woman, sum( CASE WHEN cu.roleCode != 'CLUB_MEMBER' AND 1 = 1 $myCondition THEN 1 ELSE 0 END ) AS governing_body FROM sys_club club diff --git a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserImportVo.java b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserImportVo.java index bf9b81ad..553f8cfd 100644 --- a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserImportVo.java +++ b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserImportVo.java @@ -27,9 +27,6 @@ public class ClubUserImportVo { @ExcelProperty("姓名") private String username; - @ExcelProperty("协会职务") - private String clubPosition; - @ExcelIgnore private String errorInfo; } diff --git a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java index 2070791b..7c7137ba 100644 --- a/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java +++ b/src/main/java/com/budwk/app/zhgh/club/vo/ClubUserJoinVo.java @@ -18,4 +18,8 @@ public class ClubUserJoinVo extends ClubUserApply { private String unionName; private String sex; private String mobile; + private String technicalTitle; + private String education; + private String academicDegree; + private String position; } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingOnlineController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingOnlineController.java index 4a5e794a..13c2f331 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingOnlineController.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingOnlineController.java @@ -32,9 +32,7 @@ import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -85,8 +83,8 @@ public class MeetingOnlineController { cnd.andEX("info.typeId", "=", typeId); if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { SqlExpressionGroup seg = new SqlExpressionGroup(); - seg.orLike("info.meetingName", pageForm.getSearchKeyword()); - seg.orLike("info.location", pageForm.getSearchKeyword()); + seg.orLike("info.name", pageForm.getSearchKeyword()); + seg.orLike("info.address", pageForm.getSearchKeyword()); cnd.and(seg); } cnd.desc("info.createTime"); diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingStatisticsController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingStatisticsController.java new file mode 100644 index 00000000..dde013ed --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/controller/MeetingStatisticsController.java @@ -0,0 +1,182 @@ +package com.budwk.app.zhgh.dayofficework.meeting.controller; + +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.afterturn.easypoi.excel.export.ExcelExportService; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.services.SysRoleService; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingInfo; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingTimePeriodUser; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingType; +import com.budwk.app.zhgh.dayofficework.meeting.service.MeetingInfoService; +import com.budwk.app.zhgh.dayofficework.meeting.service.MeetingUserService; +import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate; +import com.budwk.app.zhgh.democratic.workercongress.models.Worker_congress_delegate; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @ClassName MeetingStatisticsController + * @Author JyuHsin + * @Date 2025/8/29 17:59 + * @Version 1.0 + * @Description TODO + */ +@Slf4j +@IocBean +@Ok("json:full") +@Api(tags = "会议统计") +@At("/platform/meeting/statistics") +public class MeetingStatisticsController { + + @Inject + private Dao dao; + @Inject + private MeetingInfoService infoService; + @Inject + private SysRoleService roleService; + @Inject + private MeetingUserService userService; + + @At("") + @SaCheckPermission("meeting.statistics") + @Ok("beetl:/platform/zhgh/dayofficework/meeting/statistics/index.html") + public void index() {} + + @At + @ApiOperation("分页查询") + @SaCheckPermission("meeting.statistics") + public Result pageData(PageForm pageForm, + @Param("year") Integer year, + @Param("typeId") String typeId) { + Cnd cnd = Cnd.NEW(); + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name as typeName, + @qrCodeUrl as qrCodeUrl + FROM + meeting_info info + LEFT JOIN meeting_type type ON type.id = info.typeId + $condition + """); + sql.setParam("qrCodeUrl", ""); + cnd.andEX("year(info.createTime)", "=", year); + cnd.andEX("info.typeId", "=", typeId); + if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("info.name", pageForm.getSearchKeyword()); + seg.orLike("info.address", pageForm.getSearchKeyword()); + cnd.and(seg); + } + cnd.desc("info.createTime"); + sql.setCondition(cnd); + Pagination pagination = infoService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pagination); + } + + @At + @ApiOperation("获取会议时间段") + @SaCheckPermission("meeting.statistics") + public Result view(String meetingId) { + MeetingInfo info = dao.fetch(MeetingInfo.class, meetingId); + MeetingType type = dao.fetch(MeetingType.class, info.getTypeId()); + + if("JDHHY".equals(type.getDesignId())) { + List listMap = userService.queryMeetingCount( + meetingId, + "teacher_congress_delegate", + RoleConstant.TEACHER_CONGRESS_DELEGATE_FORMAL.name(), + RoleConstant.TEACHER_CONGRESS_DELEGATE_ATTENDANCE.name(), + info.getTeacherCongressSessionId() + ); + return Result.success(listMap); + } else if("GDHHY".equals(type.getDesignId())) { + List listMap = userService.queryMeetingCount( + meetingId, + "worker_congress_delegate", + RoleConstant.WORKER_CONGRESS_DELEGATE_FORMAL.name(), + RoleConstant.WORKER_CONGRESS_DELEGATE_ATTENDANCE.name(), + info.getWorkerCongressSessionId() + ); + return Result.success(listMap); + } + return Result.success(); + } + + @At + @ApiOperation("获取人员名单") + @SaCheckPermission("meeting.statistics") + public Result queryUserTable(PageForm pageForm, + String meetingId, + String type, + String unionId, + String unitId, + String periodId) { + MeetingInfo info = dao.fetch(MeetingInfo.class, meetingId); + MeetingType meetingType = dao.fetch(MeetingType.class, info.getTypeId()); + + Pagination pagination = userService.queryUserTable(pageForm, info, meetingType, type, unionId, unitId, periodId); + return Result.success(pagination); + } + + @At + @Ok("void") + @SaCheckPermission("meeting.statistics") + public void exportUser(@Param(value = "periodId") String periodId, + @Param(value = "meetingId") String meetingId, + @Param(value = "exportColumns") NutMap[] exportColumns, + HttpServletResponse response) { + List entityList = new ArrayList<>(); + entityList.add(new ExcelExportEntity("姓名", "userName", 20)); + entityList.add(new ExcelExportEntity("工号", "loginName", 20)); + entityList.add(new ExcelExportEntity("单位", "unitName", 30)); + entityList.add(new ExcelExportEntity("分工会", "unionName", 35)); + + MeetingInfo info = dao.fetch(MeetingInfo.class, meetingId); + MeetingType meetingType = dao.fetch(MeetingType.class, info.getTypeId()); + + Workbook workbook = new XSSFWorkbook(); + for (NutMap exportColumn : exportColumns) { + List listMap = userService.queryUserTable(info, meetingType, exportColumn.getString("prop"), periodId); + ExcelExportService service = new ExcelExportService(); + ExportParams exportParams = new ExportParams(); + exportParams.setTitle(exportColumn.getString("label")); + exportParams.setSheetName(exportColumn.getString("label")); + exportParams.setType(ExcelType.XSSF); + service.createSheetForMap(workbook, exportParams, entityList, listMap); + } + + CommonDownloadUtil.download("人员列表.xlsx", workbook, response); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/MeetingUserService.java b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/MeetingUserService.java new file mode 100644 index 00000000..0af3f086 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/MeetingUserService.java @@ -0,0 +1,36 @@ +package com.budwk.app.zhgh.dayofficework.meeting.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingInfo; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingTimePeriodUser; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingType; +import org.nutz.lang.util.NutMap; + +import java.awt.*; +import java.util.List; + +/** + * @ClassName MeetingUserService + * @Author JyuHsin + * @Date 2025/9/1 10:46 + * @Version 1.0 + * @Description TODO + */ +public interface MeetingUserService extends BaseService { + + Pagination queryUserTable(PageForm pageForm, + MeetingInfo info, + MeetingType meetingType, + String type, + String unionId, + String unitId, + String periodId); + + List queryUserTable(MeetingInfo info, MeetingType meetingType, String type, String periodId); + + List queryMeetingCount(String meetingId, String tableName, String formalRoleCode, String attendanceRoleCode, String sessionId); + + List queryDelegateIds(Class delegateClass, String sessionId, String roleCode); +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingOnlineServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingOnlineServiceImpl.java index 73cc7a0d..34103c5b 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingOnlineServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingOnlineServiceImpl.java @@ -84,18 +84,18 @@ public class MeetingOnlineServiceImpl extends BaseServiceImpl imple MeetingTimePeriod timePeriod = dao().fetch(MeetingTimePeriod.class, timePeriodId); Sql sql = Sqls.create(""" SELECT - (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId) as shouldComeNumber, - (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId and (joinStatus is null or (joinStatus is not null ) and signStatus is null)) as actualComeNumber, - (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId and signStatus = 1) as signInNumber, - (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId and joinStatus = 0 ) as leaveNumber + (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId) as totalCount, + (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId and joinStatus = 1 and signStatus = 0) as noComeCount, + (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId and signStatus = 1) as comeCount, + (select count(1) from meeting_time_period_user where timePeriodId = @timePeriodId and joinStatus = 0) as leaveCount """); sql.setParam("timePeriodId", timePeriodId); NutMap dataMap = (NutMap) Daos.query(dao(), sql.toString(), Sqls.callback.map()); List> list = new ArrayList<>(); - list.add(Map.of("label", "应到人数", "key", "shouldComeNumber", "value", dataMap.getInt("shouldComeNumber", 0))); - list.add(Map.of("label", "未到人数", "key", "actualComeNumber", "value", dataMap.getInt("actualComeNumber", 0))); - list.add(Map.of("label", "签到人数", "key", "signInNumber", "value", dataMap.getInt("signInNumber", 0))); + list.add(Map.of("label", "应到人数", "key", "totalCount", "value", dataMap.getInt("totalCount", 0))); + list.add(Map.of("label", "未到人数", "key", "noComeCount", "value", dataMap.getInt("noComeCount", 0))); + list.add(Map.of("label", "签到人数", "key", "comeCount", "value", dataMap.getInt("comeCount", 0))); //如果是教代会,就查询签到的正式代表和列席代表各多少人 MeetingInfo meetingInfo = dao().fetch(MeetingInfo.class, timePeriod.getMeetingId()); @@ -118,7 +118,7 @@ public class MeetingOnlineServiceImpl extends BaseServiceImpl imple Worker_congress_delegate.class ); } - list.add(Map.of("label", "请假人数", "key", "leaveNumber", "value", dataMap.getInt("leaveNumber", 0))); + list.add(Map.of("label", "请假人数", "key", "leaveCount", "value", dataMap.getInt("leaveCount", 0))); return list; } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingUserServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingUserServiceImpl.java new file mode 100644 index 00000000..09b1c6f4 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/meeting/service/impl/MeetingUserServiceImpl.java @@ -0,0 +1,176 @@ +package com.budwk.app.zhgh.dayofficework.meeting.service.impl; + +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.services.SysRoleService; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingInfo; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingTimePeriodUser; +import com.budwk.app.zhgh.dayofficework.meeting.model.MeetingType; +import com.budwk.app.zhgh.dayofficework.meeting.service.MeetingUserService; +import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate; +import com.budwk.app.zhgh.democratic.workercongress.models.Worker_congress_delegate; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @ClassName MeetingUserServiceImpl + * @Author JyuHsin + * @Date 2025/9/1 10:47 + * @Version 1.0 + * @Description TODO + */ +@Slf4j +@IocBean(args = {"refer:dao"}) +public class MeetingUserServiceImpl extends BaseServiceImpl implements MeetingUserService { + + @Inject + private SysRoleService roleService; + + public MeetingUserServiceImpl(Dao dao) { + super(dao); + } + + @Override + public Pagination queryUserTable(PageForm pageForm, MeetingInfo info, MeetingType meetingType, String type, String unionId, String unitId, String periodId) { + Sql sql = this.generateSql(pageForm, info, meetingType.getDesignId(), type, unionId, unitId, periodId); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @Override + public List queryUserTable(MeetingInfo info, MeetingType meetingType, String type, String periodId) { + Sql sql = this.generateSql(null, info, meetingType.getDesignId(), type, null, null, periodId); + return listMap(sql); + } + + @Override + public List queryMeetingCount(String meetingId, String tableName, String formalRoleCode, String attendanceRoleCode, String sessionId) { + Sys_role formalRole = roleService.getByCode(formalRoleCode); + Sys_role attendanceRole = roleService.getByCode(attendanceRoleCode); + + Sql sql = Sqls.create(""" + SELECT + mtp.*, + count( mtpu.id ) AS totalCount, + sum( CASE WHEN mtpu.joinStatus = 0 THEN 1 ELSE 0 END ) AS leaveCount, + sum( CASE WHEN mtpu.signStatus = 1 THEN 1 ELSE 0 END ) AS comeCount, + sum( CASE WHEN mtpu.joinStatus = 1 AND mtpu.signStatus = 0 THEN 1 ELSE 0 END ) AS noComeCount, + sum( CASE WHEN (mtpu.signStatus = 1) AND (d.roleId = @formalRole) AND d.sessionId = @sessionId THEN 1 ELSE 0 END) as formalRoleCount, + sum( CASE WHEN (mtpu.signStatus = 1) AND (d.roleId = @attendanceRole) AND d.sessionId = @sessionId THEN 1 ELSE 0 END) as attendanceRoleCount + FROM + meeting_time_period mtp + LEFT JOIN meeting_time_period_user mtpu ON mtpu.timePeriodId = mtp.id + LEFT JOIN $tableName d on d.userId = mtpu.userId and d.sessionId = @sessionId + $condition + """); + sql.setParam("formalRole", formalRole.getId()); + sql.setParam("attendanceRole", attendanceRole.getId()); + sql.setParam("sessionId", sessionId); + + Cnd cnd = Cnd.NEW(); + cnd.and("mtp.meetingId", "=", meetingId); + cnd.desc("mtp.startTime"); + cnd.groupBy("mtp.id"); + + sql.setVar("tableName", tableName); + sql.setCondition(cnd); + return listMap(sql); + } + + @Override + public List queryDelegateIds(Class delegateClass, String sessionId, String roleCode) { + Sys_role role = roleService.getByCode(roleCode); + + List result = new ArrayList<>(); + // 查询代表 + List list = dao().query(delegateClass, Cnd.where("sessionId", "=", sessionId)); + for (T delegate : list) { + try { + // 获取 roleId 字段值 + Field roleIdField = delegateClass.getDeclaredField("roleId"); + roleIdField.setAccessible(true); + String roleId = (String) roleIdField.get(delegate); + + // 获取 userId 字段值 + Field userIdField = delegateClass.getDeclaredField("userId"); + userIdField.setAccessible(true); + String userId = (String) userIdField.get(delegate); + + if(Objects.equals(roleId, role.getId())) { + result.add(userId); + } + } catch (NoSuchFieldException | IllegalAccessException e) { + log.error(e.getMessage()); + } + } + return result; + } + + private Sql generateSql(PageForm pageForm, + MeetingInfo info, + String designId, + String type, + String unionId, + String unitId, + String periodId) { + Sql sql = Sqls.create(""" + select + mtpu.*, + u.sex, + u.mobile + from + meeting_time_period_user mtpu + left join vw_user u on u.id = mtpu.userId + $condition + """); + Cnd cnd = Cnd.NEW(); + switch (type) { + case "comeCount" -> cnd.and(MeetingTimePeriodUser::getSignStatus, "=", true); + case "formalRoleCount" -> { + cnd.and(MeetingTimePeriodUser::getSignStatus, "=", true); + if ("JDHHY".equals(designId)) { + cnd.and(MeetingTimePeriodUser::getUserId, "in", this.queryDelegateIds(Teacher_congress_delegate.class, info.getTeacherCongressSessionId(), RoleConstant.TEACHER_CONGRESS_DELEGATE_FORMAL.name())); + } else if ("GDHHY".equals(designId)) { + cnd.and(MeetingTimePeriodUser::getUserId, "in", this.queryDelegateIds(Worker_congress_delegate.class, info.getWorkerCongressSessionId(), RoleConstant.WORKER_CONGRESS_DELEGATE_FORMAL.name())); + } + } + case "attendanceRoleCount" -> { + cnd.and(MeetingTimePeriodUser::getSignStatus, "=", true); + if ("JDHHY".equals(designId)) { + cnd.and(MeetingTimePeriodUser::getUserId, "in", this.queryDelegateIds(Teacher_congress_delegate.class, info.getTeacherCongressSessionId(), RoleConstant.TEACHER_CONGRESS_DELEGATE_ATTENDANCE.name())); + } else if ("GDHHY".equals(designId)) { + cnd.and(MeetingTimePeriodUser::getUserId, "in", this.queryDelegateIds(Worker_congress_delegate.class, info.getWorkerCongressSessionId(), RoleConstant.WORKER_CONGRESS_DELEGATE_ATTENDANCE.name())); + } + } + case "leaveCount" -> cnd.and(MeetingTimePeriodUser::getJoinStatus, "=", false); + case "noComeCount" -> cnd.and(MeetingTimePeriodUser::getJoinStatus, "=", true).and(MeetingTimePeriodUser::getSignStatus, "=", false); + } + cnd.and(MeetingTimePeriodUser::getTimePeriodId, "=", periodId); + cnd.andEX("mtpu.unitId", "=", unitId); + cnd.andEX("mtpu.unionId", "=", unionId); + if (pageForm != null && Strings.isNotBlank(pageForm.getSearchKeyword())) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("mtpu.userName", pageForm.getSearchKeyword()); + seg.orLike("mtpu.loginName", pageForm.getSearchKeyword()); + cnd.and(seg); + } + cnd.desc("mtpu.unitId"); + sql.setCondition(cnd); + return sql; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/site/service/impl/SiteApplyServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/site/service/impl/SiteApplyServiceImpl.java index 73babb5d..516694c9 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/site/service/impl/SiteApplyServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/site/service/impl/SiteApplyServiceImpl.java @@ -1,5 +1,6 @@ package com.budwk.app.zhgh.dayofficework.site.service.impl; +import cn.hutool.core.util.StrUtil; import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.flow.entity.ProcessInstance; import com.budwk.app.flow.enums.ProcessInstanceStateEnum; @@ -54,7 +55,7 @@ public class SiteApplyServiceImpl extends BaseServiceImpl implements sql.setCondition(cnd); List applyList = listEntity(sql); long hasReserve = applyList.stream().filter(o -> o.getApplyUserId().equals(SecurityUtil.getUserId())).count(); - if(hasReserve > 0) { + if(StrUtil.isBlank(apply.getId()) && hasReserve > 0) { return Map.of(false, "您已预约该时间段"); } int count = applyList.stream().mapToInt(SiteApply::getJoinCount).sum(); diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/apply/index.html b/src/main/resources/views/platform/zhgh/activity/literacy/apply/index.html new file mode 100644 index 00000000..110eb306 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/apply/index.html @@ -0,0 +1,121 @@ + + + + +
+ + + + + + + + + + 全部 + 报名中 + 已结束 + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/apply/info.js b/src/main/resources/views/platform/zhgh/activity/literacy/apply/info.js new file mode 100644 index 00000000..e75b9506 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/apply/info.js @@ -0,0 +1,306 @@ + +const info = { + template: /*language=HTML*/ ` +
+ + + + + 类  型: + + + + + + + + 分类标识: + + + {{ item }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取 消 + + + + +
+ + 取 消 + +
+ + +
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + mixins: [initTableMixins], + components: { + "sign-form": signForm, + }, + data() { + return { + pageForm: { + assortTypes: [], + }, + assortList: [], + courseTimeListDialog: false, + viewMapDialog: false, + courseTimeList: [], + tableColumns: [ + { prop: "courseName", label: "名称" }, + { prop: "typeName", label: "类型", width: 130}, + { prop: "courseLocationCoordinates", label: "地点", width: 200 }, + { prop: "courseInstructor", label: "联系人", width: 100 }, + { prop: "courseTime", label: "时间", width: 200 }, + { prop: "applyNum", label: "已报名人数", width: 200 } + ], + activity: {}, + courseTypeList: [], + + literacyType: '', + } + }, + methods: { + tagClick(key, val) { + let idx = this.pageForm[key].indexOf(val) + if (idx !== -1) { + this.pageForm[key].splice(idx, 1) + } else { + this.pageForm[key].push(val) + } + this.doSearch() + }, + async onOpen(row) { + this.activity = row + this.$set(this.pageForm, 'activityId', row.id) + await this.pageData() + await this.getCourseTypeList() + this.queryCourseAssort() + }, + onSign(row) { + const course = this.courseTypeList.find((v) => v.id === row.courseType) + this.$axios.post("/platform/mobile/literacyActivity/validateSignUp", {courseId: row.id}) + .then((res) => { + if (res.code !== 0) { + this.$alert(res.msg, "提示", { + confirmButtonText: "确定", + type: "warning" + }) + } else { + let lave = row.coursePeopleNumber - (row.hasRegisterNum + row.courseReservedNumber) + if(row.reserveMode === 2 && lave <= 0) { + this.$alert('您当前的报名为候补报名状态', "提示", { + confirmButtonText: "确定", + type: "warning" + }) + } + this.$refs.signFormRef.onOpen(row, course) + } + }) + }, + onCancel(row) { + this.$confirm("您确定要取消吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "info" + }).then(async () => { + const resp = await this.$axios.post("/platform/mobile/literacyActivity/cancelSignUp", { + activityId: row.activityId, + courseId: row.id + }) + if (resp.code === 0) { + await this.pageData() + this.$message.success(resp.msg) + } else { + this.$message.warning(resp.msg) + } + }) + }, + async getCourseTypeList() { + const resp = await this.$axios.post("/platform/literacy/manage/type/getAllType") + if (resp.code === 0) { + this.courseTypeList = resp.data + } + }, + async openViewCourseTime(id) { + const resp = await this.$axios.post(loc() + "/getCourseTime", { id: id }) + this.courseTimeList = resp.data + this.courseTimeListDialog = true + }, + openViewMap(point) { + if (!Array.isArray(point)) { + this.$message.warning("没有设置点位,无法通过地图查看") + return + } + this.viewMapDialog = true + this.$nextTick(() => { + const viewMap = new AMap.Map("viewMap", { + resizeEnable: true, + center: point, + zoom: 16 + }) + if (viewMarker) { + viewMap.remove(viewMarker) + } + viewMarker = new AMap.Marker({ + position: point, + offset: new AMap.Pixel(-13, -30) + }) + viewMap.add(viewMarker) + viewMap.setFitView(null, false, [150, 60, 100, 60]) + }) + }, + calcSignUpCount(o) { + let lave = o.coursePeopleNumber - (o.hasRegisterNum + o.courseReservedNumber) + if(o.reserveMode === 2) { + let lave2 = o.waitingNum - o.hasWaitingNum + return "余" + lave +"/" + o.coursePeopleNumber + "人" + + ",候补余" + lave2 + "/" + o.waitingNum + "人" + } else { + return "余" + lave +"/" + o.coursePeopleNumber + "人" + } + }, + async pageData() { + const pageForm = clone({...this.pageForm}) + pageForm.assortTypes = JSON.stringify(pageForm.assortTypes) + const resp = await this.$axios.post(loc() + "/pageData", pageForm) + if (resp.code === 0) { + this.tableData = resp.data.list + this.pageForm.totalCount = resp.data.totalCount + } else { + this.$message.warning(resp.msg) + } + }, + queryCourseAssort() { + console.log(this.activity) + this.$axios.post(loc() + "/queryCourseAssort", {activityId: this.activity.id}) + .then((resp) => { + this.assortList = resp.data + }) + }, + }, + created() { + + }, + style: /*language=CSS*/ ` + .glow-box { + min-height: calc(100vh - 56px - 40px - 50px - 80px); + max-height: calc(100vh - 56px - 40px - 50px - 80px); + overflow-y: auto; + background: #F0F2F5; + } + img { + width: 100%; + height: 180px; + } + .title { + background: white; + height: 20px; + } + .query-row { + display: flex; + align-items: center; + padding: 6px 0; + } + .query-row:not(:last-child) { + border-bottom: 1px dashed rgb(230, 230, 230); + } + .query-row > .query-title { + width: 100px; + max-width: 100px; + min-width: 100px; + overflow: hidden; + } + .query-row > .query-content { + min-width: 200px; + overflow: hidden; + } + .query-row > .query-content > .el-tag { + margin-bottom: 5px; + margin-top: 5px; + } + @media screen and (max-width: 992px) { + .query-row:nth-child(4) .query-content .el-col:not(:last-child) { + margin-bottom: 5px; + } + + .query-title { + display: none; + } + } + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/apply/signForm.js b/src/main/resources/views/platform/zhgh/activity/literacy/apply/signForm.js new file mode 100644 index 00000000..47cd4349 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/apply/signForm.js @@ -0,0 +1,216 @@ +const signForm = { + template: /*language=HTML*/ ` +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取 消 + 提 交 + + +
+ `, + store, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + signDialog: false, + formData: {}, + courseRow: {}, + courseTimeSelectList: [], + } + }, + methods: { + async getCourseTimeSelectList(o) { + const resp = await $.post('/platform/mobile/literacyActivity/getCourseTimeSelectList',{ courseId: o.id }) + if (resp.code === 0) { + this.courseTimeSelectList = resp.data + } else { + this.$message.warning('获取时段信息失败,请联系管理员') + } + }, + async onOpen(row, course) { + this.initData(row, course) + if (row.courseIsLimitApply) { + await this.getCourseTimeSelectList(row) + } + this.courseRow = row + this.signDialog = true + }, + async onSubmit() { + //获取家属是多少人 + let per = 0 + this.formData.literacyMobileSignColumnList.forEach((item) => { + if (item.columnCode === "xdqsrs") { + per += Number(item.columnValue) + } + }) + const res = await this.$axios.post("/platform/mobile/literacyActivity/validateSignUp", { + courseId: this.formData.courseId, + currentFamilyNumber: per + }) + if (res.code !== 0) { + this.$message.warning(res.msg) + return + } + this.$refs["form"].validate(async (valid) => { + if (valid) { + if (this.courseRow.courseIsLimitApply) { + const resp = await this.$axios.post('/platform/mobile/literacyActivity/validateSourceSignUp', { + activityCourseId: this.formData.activityCourseId, + courseId: this.courseRow.id + }) + if (resp.code !== 0) { + this.$message.warning(res.msg) + return + } + } + this.$confirm("您确定要提交吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(async () => { + const mobileColumnsValue = this.formData.literacyMobileSignColumnList.map((v) => { + return { + columnName: v.columnName, + columnValue: v.columnValue, + columnCode: v.columnCode, + columnFormType: v.columnFormType + } + }) + this.formData.mobileColumnsValue = JSON.stringify(mobileColumnsValue) + const resp = await this.$axios.post("/platform/mobile/literacyActivity/doSignUp", this.formData) + if (resp.code === 0) { + this.signDialog = false + this.$message.success(resp.msg) + this.$emit('refresh') + } else { + this.$message.warning(resp.msg) + } + }) + } + }) + }, + initData(row, course) { + this.formData = { + activityId: row.activityId, + courseId: row.id, + username: this.$store.state.user.username, + loginname: this.$store.state.user.loginname, + unionName: this.$store.state.user.union.name, + unitName: this.$store.state.user.unit.name, + sex: this.$store.state.user.sex, + mobile: this.$store.state.user.mobile, + literacyMobileSignColumnList: course.literacyMobileSignColumnList + } + this.formData.literacyMobileSignColumnList.forEach((item) => { + item.columnValue = "" + }) + this.$nextTick(() => { + this.$refs.form.clearValidate() + }) + }, + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/basicForm.js b/src/main/resources/views/platform/zhgh/activity/literacy/manage/basicForm.js new file mode 100644 index 00000000..11ad54cc --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/basicForm.js @@ -0,0 +1,593 @@ + + +const basicForm = { + template: /*language=HTML*/ ` +
+ +
+ + + + + 沿用之前活动 + 不沿用之前活动 + + + + + + + + + + + + + + + + + + + + + 通知 + 不通知 + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ 设置 +
+
+
+
+ + + + + + + +
+ + + + + + + + + + + + + +
+
+
+
{{literacyType + '信息(温馨提示:如不需要人数限制,下方人数框填写0或者不填)'}}
+
+ 添加{{ literacyType }} +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
个人报名数量限制
+ + + 无限制 + 按类型限制 + 按活动限制 + +
+
注:无限制指对报名的个数不做任何限制
+
+
+ 设置报名限制 + 注:按类型限制指对每个类型下的个数进行限制 +
+
+
+
+ + 注:按活动限制指只能报{{formData.limitNum}}个,不与类型关联 +
+
+
+
+
+
+
+ 取消 + 上一步 + 下一步 + 保存 + 提交 +
+ + + + + + + + + + + 取消 + 确定 + + + + + + + + +
+ `, + dicts: ["CAMPUS", "LITERACY_SIGNUP_TYPE"], + data() { + return { + signUpDialog: false, + step: 1, + formData: { + notice: false, + courseList: [ + { orderNum: 1, courseName: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false }, + ], + conditionStructure: { + method: "AND", + conditions: [{}] + }, + restrictLimit: 1, + limitNum: 1, + typeLimits: [] + }, + historicalActList: [], + literacyTypeList: [], + literacyType: "培训班", + activityGroupList: [], + pickerOptions: { + disabledDate(time) { + return time.getTime() < Date.now() - 24 * 60 * 60 * 1000 + } + }, + campusList: [], + courseTypeList: [], + } + }, + components: { + "drawer-user-scope": httpVueLoader("/components/module/activity/DrawerUserScope.vue"), + "course-time": courseTime, + "custom-form": customForm, + }, + methods: { + async validNumber(row, old) { + if (GetQueryString("id") === "") { + if (row.courseReservedNumber > row.coursePeopleNumber && row.reserveMode === 1) { + this.$alert("预留人数不能大于" + this.literacyType + "人数!", "提示", { + confirmButtonText: "确定" + }) + row.courseReservedNumber = 0 + } + } else { + const registerUserCount = await this.getRegisterUserCount(row.id) + if (row.courseReservedNumber + registerUserCount > row.coursePeopleNumber) { + if (row.reserveMode === 1) { + let num = row.coursePeopleNumber - registerUserCount + let str = + "您设置的" + + this.literacyType + + "人数为" + + row.coursePeopleNumber + + "人,当前报名人数为" + + registerUserCount + + "人,预留名额上限为" + + num + + "人!" + this.$alert(str, "提示", { + confirmButtonText: "确定" + }) + row.courseReservedNumber = 0 + } + } + } + }, + async getRegisterUserCount(courseId) { + const resp = await this.$axios.post("/platform/literacy/manage/activity/getRegisterUserCount", { courseId }) + return resp.code === 0 ? resp.data : 0 + }, + courseTypeChange(val, row) { + row.reserveMode = 1 + }, + setSignUpCondition() { + if (this.formData.courseList !== undefined && this.formData.courseList.length > 0) { + const courseValid = this.formData.courseList.some((item, index) => { + if (item.courseType === undefined) { + this.$message.warning("请在" + (index + 1) + "行" + this.literacyType + "信息中选择类型!") + return true + } + return false + }) + if (courseValid) { + return + } + const array = [...new Set(this.formData.courseList.map((o) => o.courseType))] + const typeArray = clone([...this.courseTypeList].filter((x) => array.some((y) => x.id === y))) + const arr = [] + typeArray.forEach((item) => { + const t = this.formData.typeLimits.find(o => o.typeId === item.id) + if (t) { + const type = this.courseTypeList.find(o => o.id === t.typeId) + t.code = type.code + t.typeName = type.typeName + arr.push(t) + } else { + arr.push({ + code: item.code, + typeName: item.typeName, + typeId: item.id, + limitNum: 0 + }) + } + }) + this.formData.typeLimits = arr + this.signUpDialog = true + } else { + this.$message.warning("请在" + this.literacyType + "信息中选择类型!") + } + }, + doLimitNum() { + this.signUpDialog = false + }, + openMoreInfo(row, index) { + this.$refs.customFormRef.onOpen(this.formData, row, index) + }, + async removeTableCourse(index) { + const confirm = await this.$confirm( + "请确认是否删除此" + this.literacyType + "?如果该" + this.literacyType + "已有报名人员,会随之一起删除!确定吗?", + "提示", + { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + } + ) + if (confirm) { + this.formData.courseList.splice(index, 1) + } + }, + openSetUpCourseTime(index) { + this.$refs.courseTimeRef.onOpen(this.formData, index) + }, + courseOrderNumChange() { + this.formData.courseList = this.formData.courseList.sort((a, b) => a.orderNum - b.orderNum) + }, + addCourse() { + this.formData.courseList.push({ courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false }) + }, + async historicalActChange(val) { + const resp = await this.$axios.post("/platform/literacy/manage/activity/findOne", {id: val}) + if (resp.code === 0) { + this.formData = resp.data + this.typeChange(this.formData.literacyType) + this.formData.id = "" + } + }, + typeChange(val) { + const type = this.dict.type.LITERACY_SIGNUP_TYPE.find(o => o.code === val) + this.literacyType = type?.name || "培训班" + }, + changeActivity(val) { + if (val) { + const group = this.activityGroupList.find(v => v.groupId === val) + this.$set(this.formData, "activityGroupName", group.groupName) + } else { + this.$set(this.formData, "activityGroupName", "全部教职工") + } + }, + async getActivityGroup() { + const { data } = await this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup") + return data + }, + async getHistoricalActList() { + const resp = await this.$axios.post("/platform/literacy/manage/activity/getHistoricalActList", {}) + return resp.data + }, + async onSave() { + let valid = false + this.$refs.form.validateField("activityName", (errMsg) => { + valid = errMsg === "" + }) + if (!valid) { + this.$message.warning("请输入活动名称") + return + } + await this.doHandle('保存') + }, + onSubmit() { + this.$refs["form"].validate(async (valid, errMsg) => { + if (valid) { + const courseValid = this.formData.courseList.some((v, i) => { + const basicValid = v.courseName && v.coursePeopleNumber && v.courseLocation && v.courseInstructor && v.courseType + const timeValid = + v.courseTimeList.length > 0 && + v.courseTimeList.every((x) => { + return x.courseStartTime && x.courseEndTime && x.courseStartTime < x.courseEndTime + }) + if (!timeValid) { + this.$message.warning("第" + (i + 1) + "行时间填写有误,请核查") + return true + } + if (!basicValid) { + this.$message.warning("第" + (i + 1) + "行信息填写有误,请核查") + return true + } + if (v.isMobileSign === true && v.signType === 3 && (v.courseLocationCoordinates === undefined || v.courseLocationCoordinates.length < 2)) { + this.$message.warning("第" + (i + 1) + "行地点坐标填写有误,请核查") + return true + } + if (v.isMobileSign === true && v.signType === 3 && (v.signType === "" || v.signType === undefined)) { + this.$message.warning("第" + (i + 1) + "行签到方式填写有误,请核查") + return true + } + return false + }) + if (courseValid) return + if (this.formData.restrictLimit === 2 && this.formData.typeLimits.length === 0) { + this.$message.warning("请设置报名限制") + return + } + this.formData.isDisabled = false + await this.doHandle('提交') + } else { + if(Object.keys(errMsg).length > 0) { + this.$message.warning(errMsg[Object.keys(errMsg)[0]][0].message) + return + } + this.$message.warning("存在必填项未填写") + } + }) + }, + async doHandle(type) { + const cloneData = clone(this.formData) + cloneData.activitySignUpStartTime = cloneData.activitySignTime !== undefined ? cloneData.activitySignTime[0] : null + cloneData.activitySignUpEndTime = cloneData.activitySignTime !== undefined ? cloneData.activitySignTime[1] : null + cloneData.activityStartTime = cloneData.activityTime !== undefined ? cloneData.activityTime[0] : null + cloneData.activityEndTime = cloneData.activityTime !== undefined ? cloneData.activityTime[1] : null + if (cloneData.activityStartTime !== undefined && cloneData.activityStartTime !== null) { + cloneData.year = new Date(cloneData.activityStartTime).getFullYear() + } + cloneData.typeLimits = JSON.stringify(this.formData.typeLimits) + cloneData.courseList = JSON.stringify(cloneData.courseList) + const confirm = await this.$confirm("您确定要" + type + "吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }) + if (confirm !== "confirm") return + const resp = await this.$axios.post("/platform/literacy/manage/activity/doHandle", cloneData) + if (resp.code === 0) { + this.$message.success(resp.msg) + this.step = 1 + this.$emit('refresh') + this.$emit('back') + } else { + this.$message.warning(resp.msg) + } + }, + async getAllType() { + const resp = await this.$axios.post("/platform/literacy/manage/type/getAllType", {}) + return resp.data + }, + async init(row) { + if (row && row.id) { + const resp = await this.$axios.post("/platform/literacy/manage/activity/findOne", {id: row.id}) + if (resp.code === 0) { + this.formData = resp.data + this.typeChange(this.formData.literacyType) + } + } + }, + async initData(row) { + this.activityGroupList = await this.getActivityGroup() + this.historicalActList = await this.getHistoricalActList() + this.courseTypeList = await this.getAllType() + await this.init(row) + }, + }, + watch: { + 'formData.restrictLimit'(val) { + if (!this.formData.id) { + this.formData.limitNum = val === 3 ? 1 : '' + } + }, + 'formData.activityGroupId': { + async handler(newVal, oldVal) { + this.activityGroupList = await this.getActivityGroup() + this.userScopeDialog = false + }, + deep: true + }, + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/courseTime.js b/src/main/resources/views/platform/zhgh/activity/literacy/manage/courseTime.js new file mode 100644 index 00000000..3835e7f4 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/courseTime.js @@ -0,0 +1,215 @@ +const courseTime = { + template: /*language=HTML*/ ` +
+ +
温馨提示:有人员报名后,禁止修改下列时间,如有修改,请联系管理员
+
选择日期
+ +
设置时间
+ + + + 一键设置开始/结束时间 + 报名人数是否限制: + + + + + + + + + + + + + + + + + + + + + + + 确定 + +
+
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + const that = this + return { + setUpCourseDialog: false, + courseIndex: 0, + formData: {}, + courseTimeOneKeySet: { + startTime: "", + endTime: "" + }, + setUpCoursePickerOptions: { + disabledDate(time) { + return ( + time.getTime() < Date.parse(that.$moment(that.formData.activityTime[0]).format("YYYY-MM-DD") + " 00:00:00") || + time.getTime() > Date.parse(that.$moment(that.formData.activityTime[1]).format("YYYY-MM-DD") + " 00:00:00") + ) + } + }, + } + }, + methods: { + removeSetUpTableCourseRow(row, index) { + this.formData.courseList[this.courseIndex].courseTimeList.splice(index, 1) + //培训时间列表日期数组 + const courseDateArray = this.formData.courseList[this.courseIndex].courseTimeList.map((v) => + this.$moment(v.courseDate).format("YYYY-MM-DD") + ) + //选择课程日期数组 + const scdList = this.formData.courseList[this.courseIndex].setUpCourseData + + this.formData.courseList[this.courseIndex].setUpCourseData = scdList.filter((v) => { + return courseDateArray.includes(this.$moment(v).format("YYYY-MM-DD")) + }) + }, + oneKeySetStartEndTime() { + const { startTime, endTime } = this.courseTimeOneKeySet + this.formData.courseList[this.courseIndex].courseTimeList.forEach((v) => { + this.$set(v, "courseStartTime", startTime) + this.$set(v, "courseEndTime", endTime) + }) + this.$forceUpdate() + }, + setUpCourseDataChange(val) { + if (!val) { + this.formData.courseList[this.courseIndex].courseTimeList = [] + return + } + //培训时间日期Set + if (this.formData.courseList[this.courseIndex].courseTimeList === undefined) { + this.$set(this.formData.courseList[this.courseIndex], "courseTimeList", []) + } + const ctList = new Set( + this.formData.courseList[this.courseIndex].courseTimeList.map((v) => this.$moment(v.courseDate).format("YYYY-MM-DD")) + ) + val.forEach((v) => { + if (!ctList.has(v)) { + this.formData.courseList[this.courseIndex].courseTimeList.push({ + courseDate: v, + courseTime: null + }) + } + }) + this.formData.courseList[this.courseIndex].courseTimeList = this.formData.courseList[this.courseIndex].courseTimeList.filter((v) => { + return val.includes(this.$moment(v.courseDate).format("YYYY-MM-DD")) + }) + this.formData.courseList[this.courseIndex].courseTimeList.sort((a, b) => { + return Date.parse(a["courseDate"]) - Date.parse(b["courseDate"]) + }) + }, + //设置课程时间确定 + doConfirmSetUpCourse() { + const courseTableData = this.formData.courseList[this.courseIndex].courseTimeList + if (courseTableData.length === 0) { + this.$message.warning("请填写时间!") + return + } + if (courseTableData && courseTableData.length > 0) { + const valid = courseTableData.every((v) => v.courseStartTime && v.courseEndTime && v.courseStartTime < v.courseEndTime) + if (!valid) { + this.$message.warning("时间填写不完整或者有误!") + return + } + this.setUpCourseDialog = false + } + }, + onOpen(formData, index) { + this.formData = formData + this.courseIndex = index + if (!this.formData.activityTime || this.formData.activityTime.length === 0) { + this.$message.warning("请先设置活动起止时间") + return + } + this.courseIndex = index + this.setUpCourseDialog = true + }, + }, + created() { + if(!this.formData.courseList) { + this.formData = {courseList: [{unionLimit: []}]} + } + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/customForm.js b/src/main/resources/views/platform/zhgh/activity/literacy/manage/customForm.js new file mode 100644 index 00000000..320c9bbe --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/customForm.js @@ -0,0 +1,211 @@ + +const customForm = { + template: /*language=HTML*/ ` +
+ + + + 分工会人数限制 + + + + 设置分工会人数限制 + + + 已设置 + + 未设置 + + + + + + 承办工会 + + + + + + + + + + + 对内报名时间 + + + + + + + + + 是否签到 + + + + 签到 + 不签到 + + + + + + + 签到方式 + + + + 扫描二维码 + 被扫 + GPS定位签到 + + + + + + + 地点坐标 + + + 设置签到点 + + + + + + 是否领取礼品 + + + + 领取 + 不领取 + + + + + + + 领取方式 + + + + 扫描二维码 + 面对面确认 + + + + + + + 报名方式 + + + + 报名人员减少模式 + 候补模式 + + + + + + 候补数量 + + + + + +
+ 取 消 + 保 存 +
+
+ + + + + 确 定 + + + + +
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + moreInfoDrawer: false, + unionList: [], + formData: {}, + moreInfoRow: {}, + moreInfoIndex: 0, + + mapDialog: false, + mapIndex: 0, + } + }, + components: { + "union-form": unionForm, + "map-container": httpVueLoader("/components/plugins/mapContainer/MapContainer.vue?v=1.0.1") + }, + methods: { + openMap(index) { + this.mapIndex = index + this.mapDialog = true + }, + openSetUpUnionLimit(index) { + this.$refs.unionFormRef.onOpen(this.formData, index) + }, + async onOpen(formData, chooseRow, index) { + this.formData = formData + this.moreInfoRow = chooseRow + this.moreInfoIndex = index + this.unionList = await this.$businessTool.listUnion() + this.moreInfoDrawer = true + }, + }, + created() { + if(!this.formData.courseList) { + this.formData = {courseList: [{unionLimit: []}]} + } + }, + style: /*language=CSS*/ ` + .my-drawer .el-col-4 { + text-align: right; + } + .my-drawer .el-row { + margin-bottom: 20px; + } + .el-drawer__body { + padding: 20px; + } + .el-row--flex { + align-items: center; + } + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/index.html b/src/main/resources/views/platform/zhgh/activity/literacy/manage/index.html new file mode 100644 index 00000000..5728ed1c --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/index.html @@ -0,0 +1,201 @@ + + + + +
+ + + + + + + + + + + + + + + + 新建活动 + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + 关 闭 + +
+
+
+ + + diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/info.js b/src/main/resources/views/platform/zhgh/activity/literacy/manage/info.js new file mode 100644 index 00000000..6f1b161f --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/info.js @@ -0,0 +1,111 @@ +const info = { + template: /*language=HTML*/ ` +
+ + + + {{viewData.activityName}} + {{viewData.year}} + {{$moment(viewData.createdAt).format('YYYY-MM-DD HH:mm:ss')}} + {{viewData.activityStartTime}} + {{viewData.activityEndTime}} + {{viewData.activitySignUpStartTime}} + {{viewData.activitySignUpEndTime}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 关 闭 + + + + +
+
+
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + literacyType: '', + viewData: {}, + courseTimeListDialog: false, + courseTimeList: [], + + viewMapDialog: false, + } + }, + methods: { + initData(id) { + this.$axios.post(loc() + "/findOne", { id: id }) + .then((resp) => { + if (resp.code === 0) { + this.viewData = resp.data + const type = this.dict.type.LITERACY_SIGNUP_TYPE.find((o) => o.code === resp.data.literacyType) + this.literacyType = type?.name || "培训班" + } + }) + }, + openViewCourseTime(courseTimeList) { + this.courseTimeList = courseTimeList + this.courseTimeListDialog = true + }, + openViewMap(point) { + if (!Array.isArray(point)) { + this.$message.warning("没有设置点位,无法通过地图查看") + return + } + this.viewMapDialog = true + this.$nextTick(() => { + viewMap = new AMap.Map("viewMap", { + resizeEnable: true, + center: point, + zoom: 16 + }) + if (viewMarker) { + viewMap.remove(viewMarker) + } + viewMarker = new AMap.Marker({ + position: point, + offset: new AMap.Pixel(-13, -30) + }) + viewMap.add(viewMarker) + viewMap.setFitView(null, false, [150, 60, 100, 60]) + }) + }, + }, + style: /*language=CSS*/ ` + .el-button--text { + padding: 0; + } + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/makeQrcode.js b/src/main/resources/views/platform/zhgh/activity/literacy/manage/makeQrcode.js new file mode 100644 index 00000000..4b878a01 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/makeQrcode.js @@ -0,0 +1,82 @@ +const makeQrcode = { + template: /*language=HTML*/ ` +
+ + + + + + + + + + + + + + + + + + + + + + 关 闭 + + +
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + courseDialog: false, + literacyType: "", + courseList: [], + } + }, + methods: { + initData(row) { + this.courseList = row.courseList + const type = this.dict.type.LITERACY_SIGNUP_TYPE.find((o) => o.code === row.literacyType) + this.literacyType = type?.name || "培训班" + this.courseDialog = true + }, + makeCourseCode(row) { + const o = {courseId: row.id} + const content = jrQrcode.getQrBase64(JSON.stringify(o)) + let image = new Image() + image.src = content + let viewer = new Viewer(image, { + zIndex: 99999999, + }) + viewer.show() + }, + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/manage/unionForm.js b/src/main/resources/views/platform/zhgh/activity/literacy/manage/unionForm.js new file mode 100644 index 00000000..e5586085 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/manage/unionForm.js @@ -0,0 +1,221 @@ +const unionForm = { + template: /*language=HTML*/ ` +
+ +
+
分段设置
+
+ 应用分段设置 +
+
+ + + + + + + + + + + + + + + + + +
+ ({{index+1}}). + {{item}} +
+
+ +
+
比例设置
+
+ 一键比例: + + 应用比例设置 +
+
+ + + + + + + + + + + + +
+ 限制总人数:{{summaryCount}}人 +
+ 清空分工会人数限制 + 取消 + 确定 +
+
+
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + formData: {}, + unionLimitIndex: 0, + setUpUnionLimitDialog: false, + unionList: [], + unionUserNumCalc: [{}], + unionUserNumOneKeyRatio: null, + summaryCount: 0, + } + }, + computed: { + unionUserNumCalcTips() { + return this.unionUserNumCalc.map((v) => { + return ( + (v.startNum ? v.startNum : "?") + + "-" + + (v.endNum ? v.endNum : "?") + + "人的分工会,限报" + + (v.resultNum ? v.resultNum : "?") + + "人" + ) + }) + } + }, + methods: { + calSummaryCount() { + const array = this.formData.courseList[this.unionLimitIndex].unionLimit + if (array) { + this.summaryCount = array.reduce((prev, curr) => { + const value = Number(curr.limitCount) + if (!isNaN(value)) { + return prev + curr.limitCount + } else { + return prev + } + }, 0) + } + }, + async onOpen(formData, index) { + this.unionList = await this.$businessTool.listUnion() + this.formData = formData + this.unionLimitIndex = index + this.setUpUnionLimitDialog = true + if ( + !this.formData.courseList[this.unionLimitIndex].unionLimit || + this.formData.courseList[this.unionLimitIndex].unionLimit.length === 0 + ) { + const resp = await this.$axios.get("/platform/literacy/manage/activity/getUnionLimit", { + activityScopeId: this.formData.activityGroupId + }) + if (resp.code === 0) { + this.$set(this.formData.courseList[this.unionLimitIndex], "unionLimit", resp.data) + } + } + this.summaryCount = this.formData.courseList[this.unionLimitIndex].unionLimit.reduce((prev, curr) => { + const value = Number(curr.limitCount) + if (!isNaN(value)) { + return prev + curr.limitCount + } else { + return prev + } + }, 0) + }, + unionLimitQuickSetting() { + this.unionUserNumCalc.forEach((v, i) => { + const startNum = v.startNum + const endNum = v.endNum + const resultNum = v.resultNum + if (startNum > endNum) { + this.$message.warning("第" + (i + 1) + "行设置错误") + } else { + this.formData.courseList[this.unionLimitIndex].unionLimit.forEach((x) => { + if (x.teacherCount >= startNum && x.teacherCount <= endNum) { + x.limitCount = resultNum + } + }) + this.calSummaryCount() + } + }) + }, + doConfirmSetUpUnionLimit() { + this.setUpUnionLimitDialog = false + }, + //应用比例设置 + applyScaleSettings() { + this.formData.courseList[this.unionLimitIndex].unionLimit.forEach((v) => { + v.limitCount = parseFloat(((v.teacherCount * this.unionUserNumOneKeyRatio) / 100).toFixed(0)) + if (v.ratio) { + v.limitCount = parseFloat(((v.teacherCount * v.ratio) / 100).toFixed(0)) + } + }) + this.calSummaryCount() + }, + async clearUnionLimit() { + const confirm = await this.$confirm("确定要清空分工会人数限制吗, 是否继续?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }) + if ("confirm" === confirm) { + this.formData.courseList[this.unionLimitIndex].unionLimit = [] + this.unionUserNumOneKeyRatio = null + this.unionUserNumCalc = [{}] + this.setUpUnionLimitDialog = false + } + }, + }, + created() { + if(!this.formData.courseList) { + this.formData = {courseList: [{unionLimit: []}]} + } + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/statistics/index.html b/src/main/resources/views/platform/zhgh/activity/literacy/statistics/index.html new file mode 100644 index 00000000..525f10ff --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/statistics/index.html @@ -0,0 +1,156 @@ + + + + +
+ + + + + + + + + + + + + + + + 导出报名人员 + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/statistics/info.js b/src/main/resources/views/platform/zhgh/activity/literacy/statistics/info.js new file mode 100644 index 00000000..99dbd84c --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/statistics/info.js @@ -0,0 +1,98 @@ +const info = { + template: /*language=HTML*/ ` +
+ + + + + + + + + + + + + + {{key}} + + + + + + + + + + + + + +
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + registerUserTableData: [], + registerUserTableColumns: [ + { label: "姓名", prop: "username" }, + { label: "工号", prop: "loginname" }, + { label: "单位", prop: "unitName" }, + { label: "分工会", prop: "unionName" }, + { label: "联系方式", prop: "mobile" }, + { label: "报名时间", prop: "signUpTime" }, + { label: "报名状态", prop: "state" } + ], + cloneTableColumns: [ + {label: '姓名', prop: 'username'}, + {label: '工号', prop: 'loginname'}, + {label: '单位', prop: 'unitName'}, + {label: '分工会', prop: 'unionName'}, + {label: '联系方式', prop: 'mobile'}, + {label: '报名时间', prop: 'signUpTime'}, + {label: '报名状态', prop: 'state'}, + ], + userSignInfo: {}, + clickRow: {} + } + }, + methods: { + async onOpen(row) { + this.clickRow = row + const resp_register = await this.$axios.post(loc() + "/registerUserList", {courseId: row.id}) + this.registerUserTableData = resp_register.data + const resp_signInfo = await this.$axios.post(loc() + "/getSignInfo", {courseId: row.id}) + this.userSignInfo = resp_signInfo.data + const resp_columnInfo = await $.get(loc() + '/getTaleColumnInfo', {courseId: row.id}) + if (resp_columnInfo.data) { + this.registerUserTableColumns = [] + this.registerUserTableColumns = this.cloneTableColumns.concat(resp_columnInfo.data) + } + } + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/type/basicForm.js b/src/main/resources/views/platform/zhgh/activity/literacy/type/basicForm.js new file mode 100644 index 00000000..5e5a60c5 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/type/basicForm.js @@ -0,0 +1,350 @@ +const basicForm = { + template: /*language=HTML*/ ` +
+ + + + + + + + + + 携带 + 不携带 + + + + + 纳入 + 不纳入 + + + + + 纳入 + 不纳入 + + + + +
+
+ 报名填写字段 + + 注:移动端报名时字段的显示顺序会按照下面表格中的序号进行排列、字段编码不能重复 + +
+
+ + + 添加 + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 取 消 + 确 定 +
+ + + + + + + + + + + +
+ 取 消 + 确 定 +
+
+
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + formData: { + literacyMobileSignColumnList: [{ isRequired: false }], + isBringFamily: false, + isAddFamily: false, + selfAddFamily: true, + }, + rules: { + typeName: [{ required: true, message: "请输入类型名称", trigger: ["change", "blur"] }], + code: [{ required: true, message: "请输入类型编码", trigger: ["change", "blur"] }], + isBringFamily: [{ required: true, message: "请选择是否携带家属", trigger: ["blur", "change"] }], + isAddFamily: [{ required: true, message: "请选择家属是否纳入总人数", trigger: ["blur", "change"] }] + }, + columnTypeOptions: [], + columnFormTypeList: [], + clickRow: {}, + paramFormRules: { + selectValues: [{ required: true, message: "请选择选项列表", trigger: ["blur"] }], + fileType: [{ required: true, message: "请选择文件类型", trigger: ["blur"] }], + fileNumber: [{ required: true, message: "请输入文件个数", trigger: ["blur", "change"] }] + }, + detailedParamsVisible: false, + } + }, + methods: { + isBringFamilyInput(o) { + this.$set(this.formData, "isAddFamily", o === true ? false : null) + if (o === true) { + this.formData.literacyMobileSignColumnList.unshift({ + columnName: "携带亲属人数", + columnCode: "xdqsrs", + columnFormType: "INPUT", + columnType: "INT", + isRequired: true + }) + } else { + this.formData.literacyMobileSignColumnList.forEach((item, index) => { + if (item.columnCode === "xdqsrs" && this.formData.isBringFamily === false) { + this.formData.literacyMobileSignColumnList.splice(index, 1) + } + }) + } + }, + columnFormTypeChange(val, index) { + if (val === "FILE") { + this.formData.literacyMobileSignColumnList[index].columnType = "JSON" + this.formData.literacyMobileSignColumnList[index].isDisabled = true + } else { + this.formData.literacyMobileSignColumnList[index].columnType = "" + this.formData.literacyMobileSignColumnList[index].isDisabled = false + } + }, + doHandle() { + if (this.formData.id) { + this.doEdit() + } else { + this.doAdd() + } + }, + async doDetailParams() { + const isValid = await this.$refs["paramForm"].validate() + if (isValid) { + this.detailedParamsVisible = false + } + }, + openDetailedParams(row, index) { + this.clickRow = row + this.detailedParamsVisible = true + if (this.$refs["paramForm"]) this.$refs["paramForm"].clearValidate() + }, + doAdd() { + this.$refs["addForm"].validate((valid) => { + if (valid) { + const newListLength = new Set(this.formData.literacyMobileSignColumnList.map((item) => item.columnCode)).size + const listLength = this.formData.literacyMobileSignColumnList.length + if (listLength > newListLength) { + this.$message.warning('字段编码不能重复') + return + } + const cloneData = clone(this.formData) + this.$axios.post(loc() + "/doAdd", { data: JSON.stringify(cloneData) }).then((res) => { + if (res.code === 0) { + this.$message.success(res.msg) + this.$emit('refresh') + } else { + this.$message.error(res.msg) + } + }) + } + }) + }, + doEdit() { + this.$refs["addForm"].validate((valid) => { + if (valid) { + const newListLength = new Set(this.formData.literacyMobileSignColumnList.map((item) => item.columnCode)).size + const listLength = this.formData.literacyMobileSignColumnList.length + if (listLength > newListLength) { + this.$message.warning('字段编码不能重复') + return + } + const cloneData = clone(this.formData) + cloneData.literacyMobileSignColumnList = JSON.stringify(cloneData.literacyMobileSignColumnList) + this.$axios.post(loc() + "/doEdit", cloneData).then((res) => { + if (res.code === 0) { + this.$message.success(res.msg) + this.$emit('refresh') + } else { + this.$message.error(res.msg) + } + }) + } + }) + }, + async getColTypeOptions() { + const resp = await this.$axios.get(loc() + "/getColumnType") + this.columnTypeOptions = resp.data + }, + async getEnumOptions() { + const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: "ColumnFormTypeEnum" }) + return resp.data + }, + initData(row) { + if(row && row.id) { + this.formData = JSON.parse(JSON.stringify(row)) + this.formData.literacyMobileSignColumnList.forEach((item) => { + item.isDisabled = item.columnFormType === "FILE" + }) + } else { + this.formData = { + literacyMobileSignColumnList: [{ isRequired: false }], + isBringFamily: false, + isAddFamily: false, + selfAddFamily: true, + } + if (this.$refs["addForm"]) this.$refs["addForm"].resetFields() + } + }, + }, + async created() { + await this.getColTypeOptions() + this.columnFormTypeList = await this.getEnumOptions() + }, + style: /*language=CSS*/ ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/type/index.html b/src/main/resources/views/platform/zhgh/activity/literacy/type/index.html new file mode 100644 index 00000000..7aee3621 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/type/index.html @@ -0,0 +1,120 @@ + + + + +
+ + + + + + +
+ + diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/index.html b/src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/index.html new file mode 100644 index 00000000..bd58a59c --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/index.html @@ -0,0 +1,144 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/userInfo.js b/src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/userInfo.js new file mode 100644 index 00000000..bfde0ab9 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/userAdjust/userInfo.js @@ -0,0 +1,224 @@ +const userInfo = { + template: /*language=HTML*/ ` +
+
{{ registerCourse.courseName + '报名人员' }}
+
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + 注:如单选为灰色选择不了,则表示对应的{{ literacyType }}人数已满!候补报名不做调整。 + + + + + + + + + + + + + 取 消 + 确 定 + + +
+ `, + dicts: ["LITERACY_SIGNUP_TYPE"], + data() { + return { + afterAdjustCourse: "", + adjustDialogVisible: false, + unionList: [], + unitList: [], + registerForm: { + unionId: "", + unitId: "" + }, + registerCourse: {}, + courseList: [], + userInfo: {}, + chooseRow: {}, + registerUserTableData: [], + registerUserTableColumns: [ + { label: "姓名", prop: "username" }, + { label: "工号", prop: "loginname" }, + { label: "单位", prop: "unitName" }, + { label: "分工会", prop: "unionName" }, + { label: "联系方式", prop: "mobile" }, + { label: "报名时间", prop: "signUpTime" }, + { label: "报名状态", prop: "state" } + ], + literacyType: '', + activity: {}, + } + }, + methods: { + async onOpen(row, activity) { + this.registerCourse = row + this.registerForm.courseId = row.id + this.activity = activity + const resp_register = await this.$axios.post(loc() + "/registerUserList", this.registerForm) + this.registerUserTableData = resp_register.data + + const type = this.dict.type.LITERACY_SIGNUP_TYPE.find(o => o.code === activity.literacyType) + this.literacyType = type?.name || "培训班" + }, + getCurrentRow(row) { + this.chooseRow = row + }, + async doAdjust() { + if (!this.afterAdjustCourse) { + this.$message.warning("请选择要调整的" + this.literacyType + "!") + return + } + this.$confirm( + "您确定要将" + + "" + + this.userInfo.username + + "" + + "的报名信息调整到" + + "" + + this.chooseRow.courseName + + "" + + "中吗?", + "提示", + { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning", + dangerouslyUseHTMLString: true + } + ) + .then(async () => { + const loading = this.$loading({ + lock: true, + text: "努力调整中,感谢您的耐心等待。。。", + spinner: "el-icon-loading", + background: "rgba(0, 0, 0, 0.7)" + }) + const resp = await this.$axios.post(loc() + "/adjust", { + activityId: this.activity.id, + oldCourseId: this.registerCourse.id, + newCourseId: this.afterAdjustCourse, + userId: this.userInfo.userId + }) + loading.close() + if (resp.code === 0) { + this.$message.success(resp.msg) + this.adjustDialogVisible = false + await this.registerSearch() + this.$emit("refresh", null) + } else { + this.$message.warning(resp.msg) + } + }) + .catch(() => {}) + }, + async adjust(o) { + this.userInfo = o + this.afterAdjustCourse = "" + await this.getCourse(this.activity.id) + this.adjustDialogVisible = true + }, + deleteSignUser(o) { + this.$confirm("您确定要删除" + "" + o.username + "" + "的报名信息吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning", + dangerouslyUseHTMLString: true + }) + .then(async () => { + const resp = await this.$axios.post(loc() + "/deleteSignUser", { + activityId: this.activity.id, + courseId: this.registerCourse.id, + userId: o.userId + }) + if (resp.code === 0) { + this.$message.success(resp.msg) + await this.registerSearch() + this.$emit("refresh", null) + } else { + this.$message.warning(resp.msg) + } + }) + .catch(() => {}) + }, + async registerSearch() { + this.registerForm.courseId = this.registerCourse.id + const resp_register = await $.get(loc() + "/registerUserList", this.registerForm) + this.registerUserTableData = resp_register.data + }, + async getCourse(val) { + const {data} = await this.$axios.post(loc() + "/getCourse", {activityId: val}) + this.courseList = data + } + }, + async created() { + this.unionList = await this.$businessTool.listUnion() + this.unitList = await this.$businessTool.listUnit(this.registerForm.unionId) + }, + style: /*language=CSS*/ ` + .adjustDialog .el-radio__label { + display: none; + } + .adjustDialog .el-dialog__body { + max-height: 600px; + overflow-y: auto; + } + ` +} diff --git a/src/main/resources/views/platform/zhgh/activity/literacy/userManage/index.html b/src/main/resources/views/platform/zhgh/activity/literacy/userManage/index.html new file mode 100644 index 00000000..0a1e80b3 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/activity/literacy/userManage/index.html @@ -0,0 +1,235 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + 补充人员 + 导出签到名单 + 导出领取名单 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取 消 + 确 定 + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/club/common/clubUserJoin.js b/src/main/resources/views/platform/zhgh/club/common/clubUserJoin.js index 6908f7f7..e0ef248f 100644 --- a/src/main/resources/views/platform/zhgh/club/common/clubUserJoin.js +++ b/src/main/resources/views/platform/zhgh/club/common/clubUserJoin.js @@ -33,7 +33,7 @@ const clubUserJoin = { {{viewData.unitName}} - {{viewData.governmentPosition}} + {{viewData.position}} {{viewData.technicalTitle}} diff --git a/src/main/resources/views/platform/zhgh/club/join/apply/index.html b/src/main/resources/views/platform/zhgh/club/join/apply/index.html index c1bc6131..4f9a84ff 100644 --- a/src/main/resources/views/platform/zhgh/club/join/apply/index.html +++ b/src/main/resources/views/platform/zhgh/club/join/apply/index.html @@ -56,8 +56,8 @@ layout("/layouts/platform.html"){ - - + + @@ -143,7 +143,7 @@ layout("/layouts/platform.html"){ // birthday: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], // mobile: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], // email: [{ required: true, message: "请填写", trigger: ["blur", "change"] }], - governmentPosition: [{ required: false, message: "请填写", trigger: ["blur", "change"] }], + position: [{ required: false, message: "请填写", trigger: ["blur", "change"] }], technicalTitle: [{ required: false, message: "请填写", trigger: ["blur", "change"] }], education: [{ required: false, message: "请填写", trigger: ["blur", "change"] }], academicDegree: [{ required: false, message: "请填写", trigger: ["blur", "change"] }], @@ -251,7 +251,8 @@ layout("/layouts/platform.html"){ this.$set(this.formData, "political", user.political) this.$set(this.formData, "education", user.education) this.$set(this.formData, "technicalTitle", user.technicalTitle) - this.$set(this.formData, "governmentPosition", user.governmentPosition) + this.$set(this.formData, "position", user.position) + this.$set(this.formData, "academicDegree", user.academicDegree) } } }, diff --git a/src/main/resources/views/platform/zhgh/club/register/apply/clubRegisterForm.js b/src/main/resources/views/platform/zhgh/club/register/apply/clubRegisterForm.js index f276042b..6725aeea 100644 --- a/src/main/resources/views/platform/zhgh/club/register/apply/clubRegisterForm.js +++ b/src/main/resources/views/platform/zhgh/club/register/apply/clubRegisterForm.js @@ -10,7 +10,8 @@ const CLUB_FORM_TEMPLATE = { - + + diff --git a/src/main/resources/views/platform/zhgh/club/register/apply/index.html b/src/main/resources/views/platform/zhgh/club/register/apply/index.html index 71bdaa6e..6c38bfce 100644 --- a/src/main/resources/views/platform/zhgh/club/register/apply/index.html +++ b/src/main/resources/views/platform/zhgh/club/register/apply/index.html @@ -104,13 +104,13 @@ layout("/layouts/platform.html"){ let formData = {} try { let hz = this.$refs.clubManagerRef.managePerson.filter((o) => o.roleCode === CLUB_ROLE_CONSTANT.CLUB_PRESIDENT) - if (hz.length > 1) { - this.$message.warning({ title: "警告", message: "会长只能有1人!" }) + if (hz.length !== 1) { + this.$message.warning({ title: "警告", message: "会长需要1人" }) return } let msz = this.$refs.clubManagerRef.managePerson.filter((o) => o.roleCode === CLUB_ROLE_CONSTANT.CLUB_SECRETARY) - if (msz.length > 1) { - this.$message.warning({ title: "警告", message: "秘书长只能有1人" }) + if (msz.length !== 1) { + this.$message.warning({ title: "警告", message: "秘书长需要1人" }) return } formData.sponsor = this.$refs.clubSponsorRef.sponsorData diff --git a/src/main/resources/views/platform/zhgh/dayofficework/meeting/online/index.html b/src/main/resources/views/platform/zhgh/dayofficework/meeting/online/index.html index 84c14a61..85267b71 100644 --- a/src/main/resources/views/platform/zhgh/dayofficework/meeting/online/index.html +++ b/src/main/resources/views/platform/zhgh/dayofficework/meeting/online/index.html @@ -148,7 +148,7 @@ layout("/layouts/platform.html"){ {{ $moment(row.createdAt).format('YYYY-MM-DD') }} - + -