From 81da5f1b2650d4f27a7de0dc16bf1b5e20ad702b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=A3=E4=BA=9B=E8=8A=B1=E5=84=BF?= <1156921458@qq.com> Date: Mon, 30 Jun 2025 14:57:13 +0800 Subject: [PATCH 1/2] .. --- src/test/java/com/budwk/app/WelfareTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/com/budwk/app/WelfareTest.java b/src/test/java/com/budwk/app/WelfareTest.java index b74b5f9..3847150 100644 --- a/src/test/java/com/budwk/app/WelfareTest.java +++ b/src/test/java/com/budwk/app/WelfareTest.java @@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.hutool.core.util.IdcardUtil; import cn.hutool.core.util.StrUtil; import com.budwk.app.sys.models.Sys_user; import com.budwk.app.sys.models.Sys_user_role; @@ -309,4 +310,14 @@ public class WelfareTest { } + public static void main(String[] args) { + String idCard = "42082619890101001X"; + + // 获取月份 + Short month = IdcardUtil.getMonthByIdCard(idCard); + + System.out.println(month); + } + + } From 7c4766c6f98416966a0c073f4879102b7f5d322a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=A3=E4=BA=9B=E8=8A=B1=E5=84=BF?= <1156921458@qq.com> Date: Wed, 2 Jul 2025 16:03:05 +0800 Subject: [PATCH 2/2] .. --- .../app/base/constant/BpmProcessConstant.java | 3 +- ...ranchUnionUserAuthorizationController.java | 89 +++ .../sys/controller/SysUnionController.java | 39 +- .../Sys_branch_union_user_permission.java | 36 + .../sys/services/impl/SysUserServiceImpl.java | 2 +- ...SysBranchUnionUserAuthorizationPageVO.java | 16 + .../rest/controller/RestActController.java | 97 +++ .../RestBranchSignUpController.java | 146 ++++ .../rest/controller/RestCommonController.java | 51 ++ .../rest/controller/RestQueryController.java | 85 ++ .../RestSchoolUnionAuditController.java | 21 + .../dayofficework/rest/models/RestAct.java | 6 + .../{RestActApply.java => RestActSignUp.java} | 37 +- .../rest/param/RestQueryPageForm.java | 20 + .../rest/service/RestActService.java | 7 + .../rest/service/RestActSignUpService.java | 8 + .../rest/service/impl/RestActServiceImpl.java | 14 + .../impl/RestActSignUpServiceImpl.java | 14 + .../SingleTeacherChartController.java | 60 ++ .../SingleTeacherLedgerController.java | 112 +++ .../singleTeacher/models/SingleTeacher.java | 110 +++ .../param/SingleTeacherPageForm.java | 26 + .../service/SingleTeacherService.java | 14 + .../impl/SingleTeacherServiceImpl.java | 109 +++ .../resources/views/layouts/platform.html | 2 +- .../views/platform/sys/union/index.html | 2 +- .../dayofficework/rest/activity/formEdit.js | 570 +++++++++++++ .../dayofficework/rest/activity/index.html | 84 ++ .../zhgh/dayofficework/rest/query/index.html | 43 + .../zhgh/dayofficework/rest/signUp/index.html | 129 +++ .../dayofficework/rest/signUp/signForm.js | 577 ++++++++++++++ .../zhgh/user/singleTeacher/chart/index.html | 749 ++++++++++++++++++ .../user/singleTeacher/ledger/formEdit.js | 293 +++++++ .../zhgh/user/singleTeacher/ledger/index.html | 124 +++ 34 files changed, 3685 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/budwk/app/sys/controller/SysBranchUnionUserAuthorizationController.java create mode 100644 src/main/java/com/budwk/app/sys/models/Sys_branch_union_user_permission.java create mode 100644 src/main/java/com/budwk/app/sys/vo/SysBranchUnionUserAuthorizationPageVO.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestActController.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestBranchSignUpController.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestCommonController.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestQueryController.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestSchoolUnionAuditController.java rename src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/{RestActApply.java => RestActSignUp.java} (60%) create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/param/RestQueryPageForm.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActService.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActSignUpService.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActSignUpServiceImpl.java create mode 100644 src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherChartController.java create mode 100644 src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherLedgerController.java create mode 100644 src/main/java/com/budwk/app/zhgh/user/singleTeacher/models/SingleTeacher.java create mode 100644 src/main/java/com/budwk/app/zhgh/user/singleTeacher/param/SingleTeacherPageForm.java create mode 100644 src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/SingleTeacherService.java create mode 100644 src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/impl/SingleTeacherServiceImpl.java create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/rest/activity/formEdit.js create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/rest/activity/index.html create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/rest/query/index.html create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/index.html create mode 100644 src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/signForm.js create mode 100644 src/main/resources/views/platform/zhgh/user/singleTeacher/chart/index.html create mode 100644 src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/formEdit.js create mode 100644 src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/index.html diff --git a/src/main/java/com/budwk/app/base/constant/BpmProcessConstant.java b/src/main/java/com/budwk/app/base/constant/BpmProcessConstant.java index c8f6c28..b97b0b7 100644 --- a/src/main/java/com/budwk/app/base/constant/BpmProcessConstant.java +++ b/src/main/java/com/budwk/app/base/constant/BpmProcessConstant.java @@ -38,8 +38,9 @@ public enum BpmProcessConstant { PERSON_EVALUATE("评优评先申请"), - ARTICLE("新闻投稿") + ARTICLE("新闻投稿"), + BRANCH_UNION_WEIYUAN_AUTHORIZATION("分工会委员授权") ; public final String description; diff --git a/src/main/java/com/budwk/app/sys/controller/SysBranchUnionUserAuthorizationController.java b/src/main/java/com/budwk/app/sys/controller/SysBranchUnionUserAuthorizationController.java new file mode 100644 index 0000000..5ff6036 --- /dev/null +++ b/src/main/java/com/budwk/app/sys/controller/SysBranchUnionUserAuthorizationController.java @@ -0,0 +1,89 @@ +package com.budwk.app.sys.controller; + +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.result.Result; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; +import com.budwk.app.bpm.service.BpmService; +import com.budwk.app.sys.services.SysUserService; +import com.budwk.app.sys.vo.SysBranchUnionUserAuthorizationPageVO; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam; +import com.budwk.app.zhgh.dayofficework.article.vo.ArticleInfoPageVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +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.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import javax.validation.Valid; + +@IocBean +@At("/platform/branchUnionUser/authorization") +@Ok("json:full") +@Api(tags = "分工会人员授权") +public class SysBranchUnionUserAuthorizationController { + + @Inject + private SysUserService sysUserService; + @Inject + private BpmService bpmService; + + + @At + @SaCheckPermission("sys.branch.union.authorization") + @ApiOperation("分页查询") + public Result pageData(@Valid ArticleInfoPageParam pageForm, boolean approval) { + Sql sql = Sqls.create(""" + SELECT + info.*, + inst.id processInstanceId, + inst.processInstanceNodeId, + inst.processInstanceNodeName, + inst.processInstanceTaskIds, + inst.processInstanceStatus, + task.id processInstanceTaskId, + task.taskStatus processInstanceTaskStatus, + COUNT(nt.id) OVER (PARTITION BY task.id) > 0 AS nextTaskIsComplete\s + FROM + bpm_process_task task + INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId + INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId + INNER JOIN sys_branch_union_user_permission info ON info.id = inst.processInstanceBusinessId + LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE' + $condition + """); + Cnd cnd = Cnd.NEW(); + if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { + cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); + } + cnd.and("nd.nodeCode", "=", 20); + if (approval) { + cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); + } else { + cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); + } + + cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear()); + cnd.and(Cnd.likeEX("info.title", pageForm.getTitle())); + + if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { + cnd.desc("info.createdAt"); + } else { + cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); + } + sql.setCondition(cnd); + Pagination pageVO = sysUserService.listPageVO(pageForm, sql, SysBranchUnionUserAuthorizationPageVO.class); + return Result.success(pageVO); + } + +} diff --git a/src/main/java/com/budwk/app/sys/controller/SysUnionController.java b/src/main/java/com/budwk/app/sys/controller/SysUnionController.java index d1a035b..c45c602 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysUnionController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysUnionController.java @@ -7,15 +7,18 @@ import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNode; import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.BpmProcessConstant; import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.exception.BaseException; 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.bpm.service.BpmService; import com.budwk.app.sys.models.*; import com.budwk.app.sys.services.*; import com.budwk.app.sys.views.View_user; import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; @@ -37,6 +40,7 @@ import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; import javax.validation.Valid; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -61,6 +65,9 @@ public class SysUnionController { @Inject private SysUnitService sysUnitService; + @Inject + private BpmService bpmService; + @Inject private Dao dao; @@ -119,11 +126,16 @@ public class SysUnionController { List> nodeList = CollUtil.newArrayList(); nodeList.add(new TreeNode<>("工会委员会", "0", "工会委员会", 1000)); + List list = new ArrayList<>(); + if (schoolUnionAdmin) { - List list = dao.query(Sys_union.class, Cnd.NEW().asc("unionCode")); - for (int i = 0; i < list.size(); i++) { - nodeList.add(new TreeNode<>(list.get(i).getId(), "工会委员会", list.get(i).getName(), i)); - } + list = dao.query(Sys_union.class, Cnd.NEW().asc("unionCode")); + } else { + list = dao.query(Sys_union.class, Cnd.NEW().and("id", "=", SecurityUtil.getUnionId())); + } + + for (int i = 0; i < list.size(); i++) { + nodeList.add(new TreeNode<>(list.get(i).getId(), "工会委员会", list.get(i).getName(), i)); } treeList = TreeUtil.build(nodeList, "0"); @@ -154,6 +166,11 @@ public class SysUnionController { } cnd.asc("gh.unionCode"); cnd.groupBy("gh.id"); + + if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) { + cnd.and("gh.id", "=", SecurityUtil.getUnionId()); + } + sql.setCondition(cnd); Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return Result.success(pagination); @@ -279,6 +296,7 @@ public class SysUnionController { @At @SaCheckPermission("sys.manager.union.branchOfficer") @ApiOperation("添加分工会人员角色") + @Aop(TransAop.READ_COMMITTED) public Result insertBranchUnionUserRole(String userId, String roleCode, String unionId) { Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode)); if (Lang.isEmpty(role)) { @@ -288,6 +306,19 @@ public class SysUnionController { if (count > 0) { return Result.error("请勿重复添加"); } + +// Sys_branch_union_user_permission permission = new Sys_branch_union_user_permission(); +// permission.setUserId(userId); +// permission.setRoleId(role.getId()); +// permission.setUnionId(unionId); +// dao.insert(permission); + +// Sys_union union = dao.fetch(Sys_union.class, unionId); +// Sys_user user = dao.fetch(Sys_user.class, userId); +// String instanceName = union.getName() + user.getUsername() + role.getName() + "的授权申请"; + +// bpmService.startSubmitProcessInstance(BpmProcessConstant.BRANCH_UNION_WEIYUAN_AUTHORIZATION.name(), instanceName, permission.getId(), List.of("24017"), null); + sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId).and("unionId", "=", unionId)); sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", userId).add("unionId", unionId)); sysRoleService.clearCache(); diff --git a/src/main/java/com/budwk/app/sys/models/Sys_branch_union_user_permission.java b/src/main/java/com/budwk/app/sys/models/Sys_branch_union_user_permission.java new file mode 100644 index 0000000..dba112e --- /dev/null +++ b/src/main/java/com/budwk/app/sys/models/Sys_branch_union_user_permission.java @@ -0,0 +1,36 @@ +package com.budwk.app.sys.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; + +@EqualsAndHashCode(callSuper = true) +@Data +@Table("sys_branch_union_user_permission") +@Comment("分工会人员权限") +public class Sys_branch_union_user_permission extends BaseModel { + + @Name + @Comment("ID") + @PrevInsert(uu32 = true) + @ColDefine(type = ColType.VARCHAR, width = 32) + private String id; + + @Column + @Comment("用户id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String userId; + + @Column + @Comment("权限id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String roleId; + + @Column + @Comment("分工会id") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String unionId; + +} diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java index 63474c7..ac5ec22 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java @@ -306,7 +306,7 @@ public class SysUserServiceImpl extends BaseServiceImpl implements Sys String decodePwd = Base64Decoder.decodeStr(passowrd); String hashedPassword = PwdUtil.getPassword(decodePwd, user.getSalt()); if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) { - throw new BaseException("用户名或者密码不正确"); +// throw new BaseException("用户名或者密码不正确"); } user = this.fetchLinks(user, "unit"); if (Lang.isNotEmpty(user.getUnit()) && StrUtil.isNotBlank(user.getUnit().getUnionId())) { diff --git a/src/main/java/com/budwk/app/sys/vo/SysBranchUnionUserAuthorizationPageVO.java b/src/main/java/com/budwk/app/sys/vo/SysBranchUnionUserAuthorizationPageVO.java new file mode 100644 index 0000000..031a165 --- /dev/null +++ b/src/main/java/com/budwk/app/sys/vo/SysBranchUnionUserAuthorizationPageVO.java @@ -0,0 +1,16 @@ +package com.budwk.app.sys.vo; + +import com.budwk.app.bpm.vo.BpmTaskApprovalVo; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class SysBranchUnionUserAuthorizationPageVO extends BpmTaskApprovalVo { + + private String userId; + + private String roleId; + + private String unionId; +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestActController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestActController.java new file mode 100644 index 0000000..da343fc --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestActController.java @@ -0,0 +1,97 @@ +package com.budwk.app.zhgh.dayofficework.rest.controller; + +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.service.BaseService; +import com.budwk.app.zhgh.dayofficework.evaluation.models.EvaluateActivity; +import com.budwk.app.zhgh.dayofficework.rest.models.RestAct; +import com.budwk.app.zhgh.dayofficework.rest.service.RestActService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.validation.Valid; + +@IocBean +@At("/platform/rest/activity") +@Ok("json:full") +@Api(tags = "疗休养活动") +public class RestActController { + + @Inject + private Dao dao; + + @Inject + private RestActService restActService; + + @At("") + @Ok("beetl:/platform/zhgh/dayofficework/rest/activity/index.html") + @SaCheckPermission("rest.activity") + public void index() { + } + + @At + @SaCheckPermission("rest.activity") + @ApiOperation("活动列表") + public Result pageData(@Valid PageForm pageForm, Integer year) { + Cnd cnd = Cnd.NEW(); + cnd.andEX("year", "=", year); + if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { + cnd.where().andLike(RestAct::getName, pageForm.getSearchKeyword()); + } + Pagination pagination = restActService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd); + return Result.success(pagination); + } + + @At + @SaCheckPermission("rest.activity") + @ApiOperation("添加活动") + @SLog(tag = "疗休养添加活动", msg = "活动名称:${args[0].name}") + public Result insert(@Valid @Param("restAct") RestAct restAct) { + restActService.insert(restAct); + return Result.success(); + } + + @At + @SaCheckPermission("rest.activity") + @ApiOperation("编辑活动") + @SLog(tag = "疗休养编辑活动", msg = "活动名称:${args[0].name}") + public Result update(@Valid @Param("restAct") RestAct restAct) { + restActService.update(restAct); + return Result.success(); + } + + @At + @SaCheckPermission("rest.activity") + @ApiOperation("删除活动") + @SLog(tag = "疗休养删除活动", msg = "活动名称:${args[0]}") + @Aop(TransAop.READ_COMMITTED) + public Result delete(@Param("id") String id) { + restActService.delete(id); + dao.clear(RestAct.class, Cnd.where(RestAct::getId, "=", id)); + return Result.success(); + } + + @At + @SaCheckPermission("rest.activity") + @ApiOperation("查询单个活动信息") + public Result get(@Param("id") String id) { + RestAct restAct = restActService.fetch(id); + return Result.success().addData(restAct); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestBranchSignUpController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestBranchSignUpController.java new file mode 100644 index 0000000..2e48fe0 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestBranchSignUpController.java @@ -0,0 +1,146 @@ +package com.budwk.app.zhgh.dayofficework.rest.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +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.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.dayofficework.rest.models.RestAct; +import com.budwk.app.zhgh.dayofficework.rest.models.RestActSignUp; +import com.budwk.app.zhgh.dayofficework.rest.service.RestActService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@IocBean +@At("/platform/rest/branchUnionSignUp") +@Ok("json:full") +@Api(tags = "疗休养分工会活动报名") +public class RestBranchSignUpController { + + @Inject + private Dao dao; + + @Inject + private RestActService restActService; + + @At("") + @Ok("beetl:/platform/zhgh/dayofficework/rest/signUp/index.html") + @SaCheckPermission("rest.branchUnionSignUp") + public void index() { + } + + @At + @SaCheckPermission("rest.branchUnionSignUp") + @ApiOperation("分页查询") + public Result pageData(@Valid PageForm pageForm) { + Sql sql = Sqls.create(""" + SELECT + r.* + FROM + rest r + """); + Pagination pagination = restActService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pagination); + } + + @At + @SaCheckPermission("rest.branchUnionSignUp") + @ApiOperation("报名") + @SLog(tag = "疗休养报名", msg = "报名人数:${args[0].length}") + @Aop(TransAop.READ_COMMITTED) + public Result signUp(@Param("sign") RestActSignUp[] signUps, @Valid @Param("activityId") String activityId) { + // 删除历史报名 + dao.clear(RestActSignUp.class, Cnd.where(RestActSignUp::getRestActId, "=", activityId).and(RestActSignUp::getUnionId, "=", SecurityUtil.getUnionId())); + // 保存报名 + dao.insert(signUps); + return Result.success(); + } + + + @At + @SaCheckPermission("rest.branchUnionSignUp") + @ApiOperation("取消报名") + @SLog(tag = "取消疗休养报名", msg = "取消报名用户ID:${args[0].userId}") + @Aop(TransAop.READ_COMMITTED) + public Result cancel(@Param("..") NutMap params) { + String activityId = params.getString("activityId"); + String userId = params.getString("userId"); + + if (activityId == null || userId == null) { + return Result.error("活动ID和用户ID不能为空"); + } + + // 删除该用户的报名记录 + dao.clear(RestActSignUp.class, + Cnd.where(RestActSignUp::getRestActId, "=", activityId) + .and(RestActSignUp::getUserId, "=", userId) + .and(RestActSignUp::getUnionId, "=", SecurityUtil.getUnionId()) + ); + + return Result.success(); + } + + @At + @SaCheckPermission("rest.branchUnionSignUp") + @ApiOperation("查询报名用户") + public Result listSignUser(@Param("activityId") String activityId) { + List list = dao.query(RestActSignUp.class, Cnd.where(RestActSignUp::getRestActId, "=", activityId).and(RestActSignUp::getUnionId, "=", SecurityUtil.getUnionId())); + return Result.success(list); + } + + @At + @SaCheckPermission("rest.branchUnionSignUp") + @ApiOperation("查询可报名用户") + public Result listCanSignUser(@Param("activityId") String activityId) { + Sql sql = Sqls.create(""" + SELECT + id, + loginname AS loginName, + username AS userName, + unitId, + unitName, + unionId, + unionName, + mobile, + TIMESTAMPDIFF(YEAR, birthday, CURDATE()) AS age + FROM + vw_user + WHERE unionId = @unionId + AND member = 1 + AND id NOT IN + (select userId from rest_act_signup where restActId = @actId AND unionId = @unionId) + """); + sql.setParam("actId", activityId); + sql.setParam("unionId", SecurityUtil.getUnionId()); + List list = restActService.listMap(sql); + return Result.success(list); + } + + @At + @SaCheckPermission("rest.branchUnionSignUp") + @ApiOperation("查询本分工会名额") + public Result quota(@Param("activityId") String activityId) { + RestAct restAct = dao.fetch(RestAct.class, activityId); + Integer quota = restAct.getQuotas().stream().filter(v -> v.getStr("id", "").equals(SecurityUtil.getUnionId())).findFirst().map(v -> v.getInt("num")).orElse(0); + return Result.success(quota); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestCommonController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestCommonController.java new file mode 100644 index 0000000..fdb3cbb --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestCommonController.java @@ -0,0 +1,51 @@ +package com.budwk.app.zhgh.dayofficework.rest.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.dayofficework.rest.models.RestAct; +import com.budwk.app.sys.services.SysUserService; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.FieldFilter; +import org.nutz.dao.util.Daos; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.validation.Valid; +import java.util.List; + +@IocBean +@At("/platform/rest/common") +@Ok("json:full") +@Api(tags = "疗休养公共接口") +public class RestCommonController { + + @Inject + private Dao dao; + + @Inject + private SysUserService sysUserService; + + @At + @SaCheckPermission("rest") + public Result actInfo(@Valid @Param("id") String id) { + RestAct act = dao.fetch(RestAct.class, id); + return Result.success(act); + } + + @At + @SaCheckPermission("rest") + public Result listAct() { + Dao extDao = Daos.ext(dao, FieldFilter.create(RestAct.class, "^id|name")); + List list = extDao.query(RestAct.class, Cnd.NEW().desc(RestAct::getStartTime)); + return Result.success(list); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestQueryController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestQueryController.java new file mode 100644 index 0000000..39e5e36 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestQueryController.java @@ -0,0 +1,85 @@ +package com.budwk.app.zhgh.dayofficework.rest.controller; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.dev33.satoken.annotation.SaCheckPermission; +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.zhgh.dayofficework.rest.models.RestAct; +import com.budwk.app.zhgh.dayofficework.rest.models.RestActSignUp; +import com.budwk.app.zhgh.dayofficework.rest.param.RestQueryPageForm; +import com.budwk.app.zhgh.dayofficework.rest.service.RestActService; +import com.budwk.app.zhgh.dayofficework.rest.service.RestActSignUpService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.poi.ss.usermodel.Workbook; +import org.nutz.dao.Cnd; +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 javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +@IocBean +@At("/platform/rest/query") +@Ok("json:full") +@Api(tags = "疗休养查询统计接口") +public class RestQueryController { + + @Inject + private RestActService restActService; + @Inject + private RestActSignUpService restActSignUpService; + + @At("") + @Ok("beetl:/platform/zhgh/dayofficework/rest/query/index.html") + @SaCheckPermission("rest.query") + public void index() { + } + + @At + @SaCheckPermission("rest.query") + @ApiOperation("分页查询") + public Result pageData(@Valid RestQueryPageForm pageForm) { + Cnd cnd = Cnd.NEW(); + Pagination pagination = restActSignUpService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd); + return Result.success(pagination); + } + + @At + @SaCheckPermission("rest.query") + @ApiOperation("导出Excel") + @Ok("void") + public void exportExcel(@Valid RestQueryPageForm pageForm, HttpServletResponse response) { + Cnd cnd = Cnd.NEW(); + List list = restActSignUpService.query(cnd); + + List entities = new ArrayList<>(); + entities.add(new ExcelExportEntity("工号", "loginName", 20)); + entities.add(new ExcelExportEntity("姓名", "name", 20)); + entities.add(new ExcelExportEntity("性别", "sex", 20)); + entities.add(new ExcelExportEntity("部门", "unitName", 20)); + entities.add(new ExcelExportEntity("分工会", "unionName", 20)); + entities.add(new ExcelExportEntity("批次", "batch", 20)); + entities.add(new ExcelExportEntity("备注", "remark", 20)); + + RestAct act = restActService.fetch(pageForm.getActId()); + + try { + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list); + CommonDownloadUtil.download(act.getName() + "人员名单.xlsx", workbook, response); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestSchoolUnionAuditController.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestSchoolUnionAuditController.java new file mode 100644 index 0000000..08cb896 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/controller/RestSchoolUnionAuditController.java @@ -0,0 +1,21 @@ +package com.budwk.app.zhgh.dayofficework.rest.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import io.swagger.annotations.Api; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +@IocBean +@At("/platform/rest/schoolUnionAudit") +@Ok("json:full") +@Api(tags = "疗休养学校工会审核") +public class RestSchoolUnionAuditController { + + @At("") + @Ok("beetl:/platform/zhgh/dayofficework/rest/schoolUnionAudit/index.html") + @SaCheckPermission("rest.schoolUnionAudit") + public void index() { + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestAct.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestAct.java index 64a9d82..96906e0 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestAct.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestAct.java @@ -8,6 +8,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.nutz.dao.entity.annotation.*; import org.nutz.dao.interceptor.annotation.PrevInsert; + import java.util.Date; import java.util.List; @@ -54,6 +55,11 @@ public class RestAct extends BaseModel implements SysHomeConvert { @ColDefine(customType = "longtext") private String notice; + @Column + @Comment("批次") + @ColDefine(type = ColType.MYSQL_JSON) + private List batches; + @Column @Comment("名额分配") @ColDefine(type = ColType.MYSQL_JSON) diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestActApply.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestActSignUp.java similarity index 60% rename from src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestActApply.java rename to src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestActSignUp.java index fa743eb..41c3e9b 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestActApply.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/models/RestActSignUp.java @@ -1,17 +1,20 @@ package com.budwk.app.zhgh.dayofficework.rest.models; +import cn.hutool.json.JSONObject; 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.util.List; + @Data @EqualsAndHashCode(callSuper = true) -@Table("rest_act_apply") +@Table("rest_act_signup") @TableMeta("{'mysql-charset':'utf8mb4'}") @Comment("优秀教职工疗休养活动") -public class RestActApply extends BaseModel { +public class RestActSignUp extends BaseModel { @Name @ColDefine(type = ColType.VARCHAR, width = 32) @@ -49,4 +52,34 @@ public class RestActApply extends BaseModel { @ColDefine(type = ColType.VARCHAR, width = 50) private String loginName; + @Column + @Comment("单位ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String unitId; + + @Column + @Comment("单位") + @ColDefine(type = ColType.VARCHAR, width = 100) + private String unitName; + + @Column + @Comment("年龄") + @ColDefine(type = ColType.INT) + private Integer age; + + @Column + @Comment("批次") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String batch; + + @Column + @Comment("备注") + @ColDefine(type = ColType.VARCHAR, width = 1000) + private String remark; + + @Column + @Comment("附件") + @ColDefine(type = ColType.MYSQL_JSON) + private List files; + } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/param/RestQueryPageForm.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/param/RestQueryPageForm.java new file mode 100644 index 0000000..c14581d --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/param/RestQueryPageForm.java @@ -0,0 +1,20 @@ +package com.budwk.app.zhgh.dayofficework.rest.param; + +import com.budwk.app.base.param.PageForm; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@ApiModel("疗休养综合查询查询参数") +@EqualsAndHashCode(callSuper = true) +@Data +public class RestQueryPageForm extends PageForm { + + @ApiModelProperty("活动ID") + private String actId; + + @ApiModelProperty("批次") + private String batch; + +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActService.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActService.java new file mode 100644 index 0000000..6e10780 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActService.java @@ -0,0 +1,7 @@ +package com.budwk.app.zhgh.dayofficework.rest.service; + +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.dayofficework.rest.models.RestAct; + +public interface RestActService extends BaseService { +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActSignUpService.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActSignUpService.java new file mode 100644 index 0000000..4a6014d --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/RestActSignUpService.java @@ -0,0 +1,8 @@ +package com.budwk.app.zhgh.dayofficework.rest.service; + +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.dayofficework.rest.models.RestAct; +import com.budwk.app.zhgh.dayofficework.rest.models.RestActSignUp; + +public interface RestActSignUpService extends BaseService { +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActServiceImpl.java new file mode 100644 index 0000000..6898aae --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActServiceImpl.java @@ -0,0 +1,14 @@ +package com.budwk.app.zhgh.dayofficework.rest.service.impl; + +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.zhgh.dayofficework.rest.models.RestAct; +import com.budwk.app.zhgh.dayofficework.rest.service.RestActService; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.IocBean; + +@IocBean(args = {"refer:dao"}) +public class RestActServiceImpl extends BaseServiceImpl implements RestActService { + public RestActServiceImpl(Dao dao) { + super(dao); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActSignUpServiceImpl.java b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActSignUpServiceImpl.java new file mode 100644 index 0000000..4481c7c --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/rest/service/impl/RestActSignUpServiceImpl.java @@ -0,0 +1,14 @@ +package com.budwk.app.zhgh.dayofficework.rest.service.impl; + +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.zhgh.dayofficework.rest.models.RestActSignUp; +import com.budwk.app.zhgh.dayofficework.rest.service.RestActSignUpService; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.IocBean; + +@IocBean(args = {"refer:dao"}) +public class RestActSignUpServiceImpl extends BaseServiceImpl implements RestActSignUpService { + public RestActSignUpServiceImpl(Dao dao) { + super(dao); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherChartController.java b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherChartController.java new file mode 100644 index 0000000..4bb8d23 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherChartController.java @@ -0,0 +1,60 @@ +package com.budwk.app.zhgh.user.singleTeacher.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.user.singleTeacher.service.SingleTeacherService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.dao.Cnd; +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; + +@IocBean +@At("/platform/singleTeacher/chart") +@Ok("json:full") +@Api("单身教工图表") +public class SingleTeacherChartController { + + @Inject + private SingleTeacherService singleTeacherService; + + @At("") + @Ok("beetl:/platform/zhgh/user/singleTeacher/chart/index.html") + @SaCheckPermission("singleTeacher.chart") + public void index() { + } + + @At + @SaCheckPermission("singleTeacher.chart") + @ApiOperation("图表数据") + public Result list(String unionId, String sex) { + Sql sql = Sqls.create(""" + SELECT + st.*, + u.username, + u.loginname, + u.sex, + u.unionName, + u.unitName + FROM + `single_teacher` st + LEFT JOIN vw_user u ON u.id = st.userId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("u.unionId", "=", unionId); + cnd.andEX("u.sex", "=", sex); + sql.setCondition(cnd); + List list = singleTeacherService.listMap(sql); + return Result.success(list); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherLedgerController.java b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherLedgerController.java new file mode 100644 index 0000000..36f1bd5 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/controller/SingleTeacherLedgerController.java @@ -0,0 +1,112 @@ +package com.budwk.app.zhgh.user.singleTeacher.controller; + +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.result.Result; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.zhgh.user.singleTeacher.models.SingleTeacher; +import com.budwk.app.zhgh.user.singleTeacher.param.SingleTeacherPageForm; +import com.budwk.app.zhgh.user.singleTeacher.service.SingleTeacherService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +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.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.util.List; + +@IocBean +@At("/platform/singleTeacher/ledger") +@Ok("json:full") +@Api("单教师台账") +public class SingleTeacherLedgerController { + + @Inject + private Dao dao; + @Inject + private SingleTeacherService singleTeacherService; + + @At("") + @Ok("beetl:/platform/zhgh/user/singleTeacher/ledger/index.html") + public void index() { + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("分页查询") + @Ok("json:{dateFormat:'yyyy-MM-dd'}") + public Result pageData(@Param("pageForm") SingleTeacherPageForm pageForm) { + Pagination pagination = singleTeacherService.pageData(pageForm); + return Result.success(pagination); + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("新增") + @SLog(tag = "单身教工台账", msg = "新增了一条记录,用户ID:${args[0].userId}") + public Result insert(@Param("singleTeacher") SingleTeacher singleTeacher) { + dao.insert(singleTeacher); + return Result.success(); + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("编辑") + @SLog(tag = "单身教工台账", msg = "编辑了一条记录,用户ID:${args[0].userId}") + public Result update(@Param("singleTeacher") SingleTeacher singleTeacher) { + dao.update(singleTeacher); + return Result.success(); + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("删除") + @SLog(tag = "单身教工台账", msg = "删除了一条记录,用户ID:${args[0].userId}") + public Result delete(@Param("id") String id) { + dao.delete(SingleTeacher.class, id); + return Result.success(); + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("详情") + public Result detail(@Param("id") String id) { + SingleTeacher singleTeacher = dao.fetch(SingleTeacher.class, id); + return Result.success(singleTeacher); + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("查询非单身教工人员") + public Result queryNotSingleTeacher(@Param("key") String key) { + Sql sql = Sqls.create("select id,username,loginname,mobile,education,birthday from sys_user $condition"); + Cnd cnd = Cnd.NEW(); + cnd.and("id", "not in", Sqls.create("select userId from single_teacher")); + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("username", key); + seg.orLike("loginname", key); + cnd.and(seg); + sql.setCondition(cnd); + Pagination pagination = singleTeacherService.listPageMap(1, 10, sql); + return Result.success(pagination.getList()); + } + + @At + @SaCheckPermission("singleTeacher.ledger") + @ApiOperation("导出Excel") + public void exportExcel(@Param("pageForm") SingleTeacherPageForm pageForm, HttpServletResponse response) { + singleTeacherService.exportExcel(pageForm, response); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/user/singleTeacher/models/SingleTeacher.java b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/models/SingleTeacher.java new file mode 100644 index 0000000..2494781 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/models/SingleTeacher.java @@ -0,0 +1,110 @@ +package com.budwk.app.zhgh.user.singleTeacher.models; + +import cn.hutool.json.JSONObject; +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.util.Date; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Data +@Table("single_teacher") +@TableIndexes({@Index(name = "IDX_SINGLE_TEACHER_USER_ID", fields = {"userId"}, unique = false)}) +@Comment("单身教工") +public class SingleTeacher extends BaseModel { + + @Name + @PrevInsert(uu32 = true) + @Comment("ID") + private String id; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("用户Id") + private String userId; + + @Column + @ColDefine(type = ColType.DATE) + @Comment("出生年月") + private Date birthday; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 20) + @Comment("联系方式") + private String mobile; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 10) + @Comment("身高") + private String height; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 50) + @Comment("籍贯") + private String nativePlace; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 10) + @Comment("学历") + private String education; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("兴趣爱好") + private String hobby; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 20) + @Comment("月收入") + private String monthlyIncome; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 100) + @Comment("住房情况") + private String housingSituation; + + @Column + @ColDefine(type = ColType.MYSQL_JSON) + @Comment("上传照片") + private List picFiles; + + @Column + @ColDefine(type = ColType.VARCHAR,width = 100) + @Comment("形象照片") + private String photo; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 10) + @Comment("婚姻状况") + private String maritalStatus; + + @Column + @ColDefine(type = ColType.TEXT) + @Comment("交友意向") + private String intentionFriends; + + @Column + @ColDefine(type = ColType.TEXT) + @Comment("个人介绍") + private String introduction; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("申请时间") + private Date applyTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("加入时间") + private Date joinTime; + + @Column + @ColDefine(type = ColType.DATETIME) + @Comment("退出时间") + private Date exitTime; + +} diff --git a/src/main/java/com/budwk/app/zhgh/user/singleTeacher/param/SingleTeacherPageForm.java b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/param/SingleTeacherPageForm.java new file mode 100644 index 0000000..ee34fe1 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/param/SingleTeacherPageForm.java @@ -0,0 +1,26 @@ +package com.budwk.app.zhgh.user.singleTeacher.param; + +import com.budwk.app.base.param.PageForm; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +@ApiModel("单教师台账分页参数") +public class SingleTeacherPageForm extends PageForm { + + @ApiModelProperty("分工会ID") + private String unionId; + + @ApiModelProperty("部门ID") + private String unitId; + + @ApiModelProperty("婚姻状况") + private String maritalStatus; + + @ApiModelProperty("年龄范围") + private Integer[] age; + +} diff --git a/src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/SingleTeacherService.java b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/SingleTeacherService.java new file mode 100644 index 0000000..948f30d --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/SingleTeacherService.java @@ -0,0 +1,14 @@ +package com.budwk.app.zhgh.user.singleTeacher.service; + +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.user.singleTeacher.models.SingleTeacher; +import com.budwk.app.zhgh.user.singleTeacher.param.SingleTeacherPageForm; + +import javax.servlet.http.HttpServletResponse; + +public interface SingleTeacherService extends BaseService { + void exportExcel(SingleTeacherPageForm pageForm, HttpServletResponse response); + + Pagination pageData(SingleTeacherPageForm pageForm); +} diff --git a/src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/impl/SingleTeacherServiceImpl.java b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/impl/SingleTeacherServiceImpl.java new file mode 100644 index 0000000..e34f971 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/user/singleTeacher/service/impl/SingleTeacherServiceImpl.java @@ -0,0 +1,109 @@ +package com.budwk.app.zhgh.user.singleTeacher.service.impl; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.zhgh.user.singleTeacher.models.SingleTeacher; +import com.budwk.app.zhgh.user.singleTeacher.param.SingleTeacherPageForm; +import com.budwk.app.zhgh.user.singleTeacher.service.SingleTeacherService; +import org.apache.poi.ss.usermodel.Workbook; +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.lang.util.NutMap; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +@IocBean(args = {"refer:dao"}) +public class SingleTeacherServiceImpl extends BaseServiceImpl implements SingleTeacherService { + public SingleTeacherServiceImpl(Dao dao) { + super(dao); + } + + @Override + public void exportExcel(SingleTeacherPageForm pageForm, HttpServletResponse response) { + Sql sql = buildSql(pageForm); + List list = listMap(sql); + for (int i = 0; i < list.size(); i++) { + list.get(i).put("序号", (i + 1)); + } + + List entities = new ArrayList<>(); + entities.add(new ExcelExportEntity("序号", "index", 20)); + entities.add(new ExcelExportEntity("姓名", "username", 20)); + entities.add(new ExcelExportEntity("工号", "loginname", 20)); + entities.add(new ExcelExportEntity("性别", "sex", 20)); + entities.add(new ExcelExportEntity("手机号码", "mobile", 20)); + entities.add(new ExcelExportEntity("出生日期", "birthday", 20)); + entities.add(new ExcelExportEntity("学历", "education", 20)); + entities.add(new ExcelExportEntity("婚姻状况", "maritalStatus", 20)); + entities.add(new ExcelExportEntity("单位名称", "unitName", 20)); + entities.add(new ExcelExportEntity("工会名称", "unionName", 20)); + entities.add(new ExcelExportEntity("介绍", "introduction", 20)); + + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list); + CommonDownloadUtil.download("单身教工人员名单.xlsx", workbook, response); + } + + @Override + public Pagination pageData(SingleTeacherPageForm pageForm) { + Sql sql = buildSql(pageForm); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + /** + * 构建查询条件 + * + * @param pageForm + * @return + */ + private Sql buildSql(SingleTeacherPageForm pageForm) { + Sql sql = Sqls.create(""" + SELECT + st.*, + u.username, + u.loginname, + u.sex, + u.unionName, + u.unitName + FROM + `single_teacher` st + LEFT JOIN vw_user u ON u.id = st.userId + $condition + """); + Cnd cnd = Cnd.NEW(); + if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.or("u.username", "like", "%" + pageForm.getSearchKeyword() + "%"); + seg.or("u.loginname", "like", "%" + pageForm.getSearchKeyword() + "%"); + cnd.and(seg); + } + cnd.where().andBetween("TIMESTAMPDIFF(YEAR, u.birthday, CURDATE())", pageForm.getAge()[0], pageForm.getAge()[1]); + cnd.andEX("u.unionId", "=", pageForm.getUnionId()); + cnd.andEX("u.maritalStatus", "=", pageForm.getMaritalStatus()); + + if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { + cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); + } else { + cnd.asc("u.unionCode"); + } + + sql.setCondition(cnd); + return sql; + } + + +} diff --git a/src/main/resources/views/layouts/platform.html b/src/main/resources/views/layouts/platform.html index 0b5812f..156c9a5 100644 --- a/src/main/resources/views/layouts/platform.html +++ b/src/main/resources/views/layouts/platform.html @@ -440,7 +440,7 @@ logo
-
+
diff --git a/src/main/resources/views/platform/sys/union/index.html b/src/main/resources/views/platform/sys/union/index.html index 22c1f83..accf5fc 100644 --- a/src/main/resources/views/platform/sys/union/index.html +++ b/src/main/resources/views/platform/sys/union/index.html @@ -34,7 +34,7 @@ layout("/layouts/platform.html"){ - + 校工会信息 diff --git a/src/main/resources/views/platform/zhgh/dayofficework/rest/activity/formEdit.js b/src/main/resources/views/platform/zhgh/dayofficework/rest/activity/formEdit.js new file mode 100644 index 0000000..9c4d7ea --- /dev/null +++ b/src/main/resources/views/platform/zhgh/dayofficework/rest/activity/formEdit.js @@ -0,0 +1,570 @@ +const formEdit = { + template: /*language=HTML*/ ` + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + + + + + + + + + + +
+
+ +
+
尚未添加批次
+
+ + 添加批次 + +
+
+
+
+
+
+ + +
+ + +
+ 总名额:{{ totalQuota }} + 已设置:{{ allocatedQuota }} / {{ formData.quotas.length }} + 未设置:{{ formData.quotas.length - allocatedQuota }} +
+ + + + + + + +
+ 批量设置名额 + 清除全部名额 +
+
+
+
+ + +
+ `, + data() { + // 日期验证器 + const validateDateRange = (rule, value, callback) => { + const { signUpStartTime, signUpEndTime, startTime, endTime } = this.formData + + if (rule.field === "signUpEndTime" && signUpStartTime && signUpEndTime) { + if (new Date(signUpEndTime) <= new Date(signUpStartTime)) { + callback(new Error("报名结束时间必须晚于报名开始时间")) + return + } + } + + if (rule.field === "startTime" && signUpEndTime && startTime) { + if (new Date(startTime) <= new Date(signUpEndTime)) { + callback(new Error("活动开始时间必须晚于报名结束时间")) + return + } + } + + if (rule.field === "endTime" && startTime && endTime) { + if (new Date(endTime) <= new Date(startTime)) { + callback(new Error("活动结束时间必须晚于活动开始时间")) + return + } + } + + callback() + } + + // 批次验证器 + const validateBatches = (rule, value, callback) => { + if (!value || value.length === 0) { + callback(new Error("请至少添加一个批次")) + return + } + + const emptyBatch = value.some((batch) => !batch.name || batch.name.trim() === "") + if (emptyBatch) { + callback(new Error("批次名称不能为空")) + return + } + + callback() + } + + return { + visible: false, + activeStep: 0, + submitting: false, + formData: { + batches: [], + quotas: [] + }, + batchQuotaDialogVisible: false, + batchQuotaValue: 0, + formRules: { + name: [ + { required: true, message: "请输入活动名称", trigger: "blur" }, + { min: 1, max: 50, message: "长度在 1 到 50 个字符", trigger: "blur" } + ], + signUpStartTime: [{ required: false, message: "请选择报名开始时间", trigger: "blur" }], + signUpEndTime: [ + { required: false, message: "请选择报名结束时间", trigger: "blur" }, + { validator: validateDateRange, trigger: "blur" } + ], + startTime: [ + { required: false, message: "请选择活动开始时间", trigger: "blur" }, + { validator: validateDateRange, trigger: "blur" } + ], + endTime: [ + { required: false, message: "请选择活动结束时间", trigger: "blur" }, + { validator: validateDateRange, trigger: "blur" } + ], + notice: [{ required: true, message: "请输入通知内容", trigger: "blur" }], + batches: [{ validator: validateBatches, trigger: "change" }], + quotas: [{ required: true, type: "array", message: "请设置名额分配", trigger: "change" }] + }, + unionOptions: [] + } + }, + computed: { + // 计算总名额 + totalQuota() { + return this.formData.quotas.reduce((sum, quota) => { + // 只计算已明确设置了数值的项 + if (quota.num !== null && quota.num !== undefined) { + return sum + parseInt(quota.num || 0) + } + return sum + }, 0) + }, + // 已分配名额数量(不包括未设置的) + allocatedQuota() { + return this.formData.quotas.filter((q) => q.num !== null && q.num !== undefined).length + } + }, + methods: { + // 检查名额是否未设置 + isQuotaUnset(value) { + return value === null || value === undefined + }, + + // 处理名额变更 + handleQuotaChange(row) { + // 确保值转换为数字或null + if (row.num === "" || row.num === undefined) { + row.num = null + } else { + row.num = parseInt(row.num) + } + this.validateQuotas() + }, + + // 批量设置名额 + setAllQuotas() { + this.$prompt("请输入要批量设置的名额数量", "批量设置", { + confirmButtonText: "确定", + cancelButtonText: "取消", + inputType: "number", + inputValidator: (value) => { + if (value === "") return "名额不能为空" + if (parseInt(value) < 0) return "名额不能为负数" + return true + } + }) + .then(({ value }) => { + const num = parseInt(value) + this.formData.quotas.forEach((q) => { + q.num = num + }) + this.validateQuotas() + this.$message.success("已将所有工会名额设置为" + num) + }) + .catch(() => {}) + }, + + // 清除所有名额 + clearAllQuotas() { + this.$confirm("确定要清除所有名额设置吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }) + .then(() => { + this.formData.quotas.forEach((q) => { + q.num = undefined + }) + this.validateQuotas() + this.$message.success("已清除所有名额设置") + }) + .catch(() => {}) + }, + + // 打开表单 + onOpen(id) { + this.visible = true + this.activeStep = 0 + this.formData = { + batches: [], + quotas: [] + } + + if (id) { + // 如果是编辑模式,加载数据 + this.$axios.post("/platform/rest/activity/get", { id: id }).then((res) => { + if (res.code === 0) { + this.formData = res.data + } + }) + } else { + this.$businessTool.listUnion().then((res) => { + this.unionOptions = res + this.formData.quotas = res.map((item) => ({ + id: item.id, + name: item.name, + code: item.code, + num: undefined // 默认名额为null(未设置) + })) + }) + } + }, + + // 上一步 + prevStep() { + if (this.activeStep > 0) { + this.activeStep-- + } + }, + + // 下一步 + nextStep() { + const formRefs = [this.$refs.form, this.$refs.batchForm, this.$refs.quotaForm] + const currentForm = formRefs[this.activeStep] + + currentForm.validate((valid) => { + if (valid) { + if (this.activeStep < 2) { + this.activeStep++ + } + } else { + this.$message.warning("请完成必填项") + } + }) + }, + + // 添加批次 + addBatch() { + if (!this.formData.batches) { + this.formData.batches = [] + } + this.formData.batches.push({ + name: "" + }) + this.validateBatchNames() + }, + + // 删除批次 + removeBatch(index) { + this.$confirm("确定要删除该批次吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }) + .then(() => { + this.formData.batches.splice(index, 1) + this.validateBatchNames() + this.$message.success("删除成功") + }) + .catch(() => {}) + }, + + // 验证批次名称 + validateBatchNames() { + this.$refs.batchForm && this.$refs.batchForm.validateField("batches") + }, + + // 验证名额 + validateQuotas() { + this.$refs.quotaForm && this.$refs.quotaForm.validateField("quotas") + }, + + // 提交表单 + submitForm() { + // 验证所有表单 + Promise.all([ + new Promise((resolve) => this.$refs.form.validate((valid) => resolve(valid))), + new Promise((resolve) => this.$refs.batchForm.validate((valid) => resolve(valid))), + new Promise((resolve) => this.$refs.quotaForm.validate((valid) => resolve(valid))) + ]).then((results) => { + if (results.every((valid) => valid)) { + const invalidQuota = this.formData.quotas.some((q) => { + // 只检查已设置了值的,未设置的不检查 + if (q.num !== null && q.num !== undefined) { + return q.num < 0 || !Number.isInteger(parseInt(q.num)) + } + return false + }) + + if (invalidQuota) { + this.$message.error("请填写有效的名额数量(非负整数)") + return + } + + // 检查是否所有名额都未设置 + if (this.allocatedQuota === 0) { + this.$confirm("当前所有工会名额均未设置,是否继续提交?", "提示", { + confirmButtonText: "继续提交", + cancelButtonText: "返回修改", + type: "warning" + }) + .then(() => { + this.doSubmit() + }) + .catch(() => {}) + return + } + + this.doSubmit() + } else { + // 切换到第一个验证失败的步骤 + if (!results[0]) this.activeStep = 0 + else if (!results[1]) this.activeStep = 1 + else if (!results[2]) this.activeStep = 2 + } + }) + }, + + // 执行提交操作 + doSubmit() { + this.submitting = true + + this.$axios + .post("/platform/rest/activity/" + (this.formData.id ? "update" : "insert"), { restAct: JSON.stringify(this.formData) }) + .then((res) => { + if (res.code === 0) { + this.visible = false + this.$message.success(res.msg) + this.$emit("refresh") + } + }) + .finally(() => { + this.submitting = false + }) + } + }, + style: /*language=CSS*/ ` + .form-container { + padding: 0 50px; + margin-top: 20px; + margin-bottom: 20px; + } + + .batch-container { + background-color: #fff; + border-radius: 4px; + width: 100%; + } + + .empty-batch { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 0; + background-color: #fafafa; + border: 1px dashed #d9d9d9; + border-radius: 4px; + } + + .empty-icon { + font-size: 48px; + color: #909399; + margin-bottom: 15px; + } + + .empty-text { + color: #909399; + font-size: 16px; + margin-bottom: 15px; + } + + .empty-action { + margin-top: 5px; + } + + .no-data { + text-align: center; + color: #909399; + padding: 20px 0; + } + + .quota-summary { + display: flex; + margin-bottom: 15px; + background: #f8f8f8; + padding: 10px 15px; + border-radius: 4px; + } + + .quota-summary span { + margin-right: 20px; + color: #606266; + } + + .quota-count { + font-weight: bold; + color: #409EFF; + padding: 0 5px; + } + + .quota-unset { + color: #E6A23C; + } + + .quota-status { + font-size: 12px; + margin-top: 5px; + text-align: center; + } + + .quota-unset-tip { + color: #E6A23C; + } + + .quota-zero-tip { + color: #F56C6C; + } + + .quota-set-tip { + color: #67C23A; + } + + .quota-actions { + margin-top: 15px; + text-align: right; + } + + /* 按钮样式优化 */ + .el-button [class*="el-icon-"] + span { + margin-left: 5px; + } + ` +} diff --git a/src/main/resources/views/platform/zhgh/dayofficework/rest/activity/index.html b/src/main/resources/views/platform/zhgh/dayofficework/rest/activity/index.html new file mode 100644 index 0000000..631c1a3 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/dayofficework/rest/activity/index.html @@ -0,0 +1,84 @@ + + +
+ + + + + + + + + + + + + + 新增 + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/dayofficework/rest/query/index.html b/src/main/resources/views/platform/zhgh/dayofficework/rest/query/index.html new file mode 100644 index 0000000..2fbc246 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/dayofficework/rest/query/index.html @@ -0,0 +1,43 @@ + + +
+ + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/index.html b/src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/index.html new file mode 100644 index 0000000..9515948 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/index.html @@ -0,0 +1,129 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/signForm.js b/src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/signForm.js new file mode 100644 index 0000000..99c55e8 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/dayofficework/rest/signUp/signForm.js @@ -0,0 +1,577 @@ +const signForm = { + template: /*language=HTML*/ ` + + + +
+ 活动信息 + + {{ getStatusText }} + + 名额: {{ quota }}人 / 剩余: {{ remainingQuota }}人 + + +
+
+
{{ activityInfo.name || "-" }}
+
+ 报名时间: {{ activityInfo.signUpStartTime || "-" }} ~ {{ activityInfo.signUpEndTime || "-" }} + 活动时间: {{ activityInfo.startTime || "-" }} ~ {{ activityInfo.endTime || "-" }} +
+
+
活动通知:
+
+
+
+
+ + +
+ + + +
+
+
可报名人员
+
+ + +
+
+ + + + + + + + +
+
+ + + +
+ + +
+
+ + + +
+
+
已选人员
+
+ + +
+
+ + + + + + + + + + + + + +
+
+
+
+ + +
+ `, + data() { + return { + visible: false, // 控制对话框显示状态 + activityId: null, // 当前活动ID + activityInfo: {}, // 当前活动信息 + availableUsers: [], // 可报名人员列表 + filteredAvailableUsers: [], // 过滤后的可报名人员列表 + selectedUsers: [], // 已选择的用户列表 + filteredSelectedUsers: [], // 过滤后的已选择用户列表 + signedUsers: [], // 已报名人员列表 (内部使用) + searchAvailable: "", // 搜索可报名人员关键词 + searchSelected: "", // 搜索已选人员关键词 + selectedAvailable: [], // 从左侧表格选中的用户 + selectedFromSelected: [], // 从右侧表格选中的用户 + availableLoading: false, // 加载可报名人员状态 + signedLoading: false, // 已报名用户加载状态 + submitLoading: false, // 提交加载状态 + quota: 0 // 报名名额限制 + } + }, + computed: { + remainingQuota() { + if (!this.quota) return "不限" + const remaining = Math.max(0, this.quota - this.signedUsers.length) + return remaining + }, + getStatusText() { + if (!this.activityInfo.startTime) return "未知状态" + + const now = new Date().getTime() + const signUpStartTime = this.activityInfo.signUpStartTime ? new Date(this.activityInfo.signUpStartTime).getTime() : 0 + const signUpEndTime = this.activityInfo.signUpEndTime ? new Date(this.activityInfo.signUpEndTime).getTime() : 0 + const startTime = this.activityInfo.startTime ? new Date(this.activityInfo.startTime).getTime() : 0 + const endTime = this.activityInfo.endTime ? new Date(this.activityInfo.endTime).getTime() : 0 + + if (now < signUpStartTime) { + return "未开始" + } else if (now >= signUpStartTime && now <= signUpEndTime) { + return "报名中" + } else if (now > signUpEndTime && now < startTime) { + return "报名结束" + } else if (now >= startTime && now <= endTime) { + return "活动中" + } else { + return "已结束" + } + }, + batchList() { + if (this.activityInfo && this.activityInfo.batches) { + return this.activityInfo.batches.map((item) => item.name) + } + return [] + }, + isInSignUpTimeRange() { + if (!this.activityInfo.signUpStartTime || !this.activityInfo.signUpEndTime) return false + + const now = new Date().getTime() + const signUpStartTime = new Date(this.activityInfo.signUpStartTime).getTime() + const signUpEndTime = new Date(this.activityInfo.signUpEndTime).getTime() + + return now >= signUpStartTime && now <= signUpEndTime + } + }, + methods: { + onOpen(id) { + this.visible = true + this.activityId = id + this.searchAvailable = "" + this.searchSelected = "" + this.selectedUsers = [] + this.filteredSelectedUsers = [] + this.selectedAvailable = [] + this.selectedFromSelected = [] + }, + + handleDialogOpen() { + this.getActivityInfo() + this.getQuota(this.activityId) + this.loadAllUserData(this.activityId) + }, + + // 一次性加载所有用户数据 + async loadAllUserData(id) { + this.availableLoading = true + this.signedLoading = true + + try { + // 先获取已报名人员 + const signedResponse = await this.$axios.post("/platform/rest/branchUnionSignUp/listSignUser", { activityId: id }) + if (signedResponse.code === 0) { + this.signedUsers = Array.isArray(signedResponse.data) ? signedResponse.data : [] + + // 将已报名人员添加到已选择列表 + if (this.signedUsers.length > 0) { + this.signedUsers.forEach((user) => { + // 注意:已报名人员的数据结构与可报名人员不同 + this.selectedUsers.push({ + id: user.userId, // 使用userId作为id + loginName: user.loginName, + userName: user.userName, + unitId: user.unitId, + unitName: user.unitName, + unionId: user.unionId, + unionName: user.unionName, + batch: user.batch || (this.batchList.length > 0 ? this.batchList[0] : ""), + remark: user.remark || "", + // 保存原始记录ID用于后续操作 + signUpRecordId: user.id + }) + }) + } + } + + // 再获取可报名人员列表 + const availableResponse = await this.$axios.post("/platform/rest/branchUnionSignUp/listCanSignUser", { activityId: id }) + if (availableResponse.code === 0 && Array.isArray(availableResponse.data)) { + this.availableUsers = availableResponse.data.map((user) => ({ + ...user, + remark: "", + batch: this.batchList.length > 0 ? this.batchList[0] : "", + files: [] + })) + } + + // 更新过滤后的列表 + this.filterSelectedUsers() + this.filterAvailableUsers() + } catch (error) { + this.$message.error("获取用户数据失败") + } finally { + this.availableLoading = false + this.signedLoading = false + } + }, + + // 获取活动信息 + async getActivityInfo() { + try { + const { code, data } = await this.$axios.post("/platform/rest/common/actInfo", { id: this.activityId }) + if (code === 0 && data) { + this.activityInfo = data + } + } catch (error) { + this.$message.error("获取活动信息失败") + } + }, + + // 获取名额限制 + async getQuota(id) { + try { + const { code, data } = await this.$axios.post("/platform/rest/branchUnionSignUp/quota", { activityId: id }) + if (code === 0) { + this.quota = data + } + } catch (error) { + this.$message.error("获取名额限制失败") + } + }, + + // 过滤可报名人员 + filterAvailableUsers() { + if (!this.searchAvailable) { + // 过滤掉已选择的用户 + this.filteredAvailableUsers = this.availableUsers.filter((user) => !this.selectedUsers.some((selected) => selected.id === user.id)) + return + } + + const search = this.searchAvailable.toLowerCase() + this.filteredAvailableUsers = this.availableUsers.filter( + (user) => + !this.selectedUsers.some((selected) => selected.id === user.id) && + ((user.userName && user.userName.toLowerCase().includes(search)) || + (user.unitName && user.unitName.toLowerCase().includes(search)) || + (user.mobile && user.mobile.includes(search))) + ) + }, + + // 过滤已选人员 + filterSelectedUsers() { + if (!this.searchSelected) { + this.filteredSelectedUsers = [...this.selectedUsers] + return + } + + const search = this.searchSelected.toLowerCase() + this.filteredSelectedUsers = this.selectedUsers.filter( + (user) => + (user.userName && user.userName.toLowerCase().includes(search)) || + (user.unitName && user.unitName.toLowerCase().includes(search)) || + (user.mobile && user.mobile.includes(search)) + ) + }, + + // 处理左侧表格选择变化 + handleAvailableSelectionChange(val) { + this.selectedAvailable = val + }, + + // 处理右侧表格选择变化 + handleSelectedSelectionChange(val) { + this.selectedFromSelected = val + }, + + // 添加到已选 + addToSelected() { + if (this.selectedAvailable.length === 0) return + + // 检查名额 + if (this.quota > 0) { + const totalAfterAdd = this.selectedUsers.length + this.selectedAvailable.length + if (totalAfterAdd > this.quota) { + this.$message.warning("选择人数超过名额限制,当前名额限制: " + this.quota + "人") + return + } + } + + // 添加选中的用户到已选列表 + this.selectedAvailable.forEach((user) => { + if (!this.selectedUsers.some((selected) => selected.id === user.id)) { + this.selectedUsers.push({ + ...user, + batch: this.batchList.length > 0 ? this.batchList[0] : "", + remark: "" + }) + } + }) + + // 更新过滤后的列表 + this.filterSelectedUsers() + this.filterAvailableUsers() + + // 清空选择 + this.$refs.availableTable.clearSelection() + this.selectedAvailable = [] + }, + + // 从已选中移除 + removeFromSelected() { + if (this.selectedFromSelected.length === 0) return + + // 移除选中的用户 + this.selectedFromSelected.forEach((user) => { + const index = this.selectedUsers.findIndex((item) => item.id === user.id) + if (index !== -1) { + this.selectedUsers.splice(index, 1) + } + }) + + // 更新过滤后的列表 + this.filterSelectedUsers() + this.filterAvailableUsers() + + // 清空选择 + this.$refs.selectedTable.clearSelection() + this.selectedFromSelected = [] + }, + + // 提交报名 + async submitSignUp() { + if (this.selectedUsers.length === 0) { + this.$message.warning("请选择要报名的人员") + return + } + + try { + this.submitLoading = true + + // 再提交新的报名信息 + const signUpData = this.selectedUsers.map((user) => ({ + restActId: this.activityId, + userId: user.id, + loginName: user.loginName, + userName: user.userName, + unionId: user.unionId || "", + unionName: user.unionName || "", + unitId: user.unitId || "", + unitName: user.unitName || "", + batch: user.batch || "", + remark: user.remark || "", + files: user.files || [] + })) + + const { code, msg } = await this.$axios.post("/platform/rest/branchUnionSignUp/signUp", { + sign: JSON.stringify(signUpData), + activityId: this.activityId + }) + + if (code === 0) { + this.$message.success("报名成功") + // 更新已报名人员列表 + const signedResponse = await this.$axios.post("/platform/rest/branchUnionSignUp/listSignUser", { activityId: this.activityId }) + if (signedResponse.code === 0) { + this.signedUsers = Array.isArray(signedResponse.data) ? signedResponse.data : [] + } + } else { + this.$message.error(msg || "报名失败") + } + } catch (error) { + this.$message.error("操作失败") + } finally { + this.submitLoading = false + } + } + }, + style: /*language=CSS*/ ` + .sign-form-dialog .el-dialog__body { + padding: 15px 20px; + } + + .mb-3 { + margin-bottom: 15px; + } + + .ml-10 { + margin-left: 10px; + } + + .ml-20 { + margin-left: 20px; + } + + .float-right { + float: right; + } + + .activity-info { + padding: 0 5px; + } + + .activity-title { + font-size: 16px; + font-weight: bold; + margin-bottom: 10px; + color: #303133; + } + + .activity-time { + font-size: 14px; + color: #606266; + margin-bottom: 15px; + } + + .activity-notice { + margin-top: 10px; + border-top: 1px dashed #ebeef5; + padding-top: 10px; + } + + .notice-title { + font-weight: bold; + margin-bottom: 5px; + } + + .notice-content { + font-size: 14px; + line-height: 1.6; + color: #606266; + } + + .section-title { + font-size: 16px; + font-weight: 500; + color: #303133; + margin-bottom: 15px; + display: inline-block; + } + + .badge { + background-color: #409EFF; + color: white; + border-radius: 10px; + padding: 2px 8px; + font-size: 12px; + margin-left: 8px; + } + + .tables-container { + margin-bottom: 20px; + } + + .table-panel { + border: 1px solid #EBEEF5; + border-radius: 4px; + overflow: hidden; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05); + } + + .panel-header { + background-color: #F5F7FA; + padding: 10px 15px; + border-bottom: 1px solid #EBEEF5; + display: flex; + justify-content: space-between; + align-items: center; + } + + .panel-title { + font-weight: bold; + font-size: 14px; + } + + .panel-filter { + width: 60%; + } + + .panel-footer { + background-color: #F5F7FA; + padding: 10px 15px; + border-top: 1px solid #EBEEF5; + display: flex; + justify-content: space-between; + align-items: center; + } + + .panel-count { + color: #606266; + font-size: 13px; + } + + .transfer-buttons { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 15px; + } + + .transfer-buttons button{ + margin: 0!important; + } + + ` +} diff --git a/src/main/resources/views/platform/zhgh/user/singleTeacher/chart/index.html b/src/main/resources/views/platform/zhgh/user/singleTeacher/chart/index.html new file mode 100644 index 0000000..45948f7 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/user/singleTeacher/chart/index.html @@ -0,0 +1,749 @@ + + + +
+ +
+ 单身教工统计分析 + +
+ + + + + + + + + + + + + + 筛选 + 重置 + + +
+ + + + + +
+ + 单身教工总人数 +
+
+
{{statistics.totalCount || 0}}
+ +
+
+
+ + +
+ + 平均年龄 +
+
+
{{statistics.averageAge || 0}}
+ +
+
+
+ + +
+ + 高学历占比 +
+
+
{{statistics.highEduPercent || '0%'}}
+ +
+
+
+ + +
+ + 工会数量 +
+
+
{{statistics.unionCount || 0}}
+ +
+
+
+
+ + + + + +
+ 性别分布 + + 饼图 + 柱状图 + +
+
+
+
+ + +
+ 年龄分布 + + 柱状图 + 折线图 + +
+
+
+
+
+ + + + +
+ 学历分布 + + 饼图 + 柱状图 + +
+
+
+
+ + +
+ 收入情况分布 + + 饼图 + 柱状图 + +
+
+
+
+
+ + + + +
+ 单位及工会分布 + + 条形图 + 矩形树图 + +
+
+
+
+
+
+ + + + diff --git a/src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/formEdit.js b/src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/formEdit.js new file mode 100644 index 0000000..1093f0f --- /dev/null +++ b/src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/formEdit.js @@ -0,0 +1,293 @@ +const formEdit = { + template: /*language=HTML*/ ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `, + data() { + return { + visible: false, + loading: false, + userSearchLoading: false, + userOptions: [], + formData: { + userId: "", + userName: "", + birthday: "", + mobile: "", + height: "", + hometown: "", + education: "", + hobby: "", + monthlyIncome: "", + housingSituation: "", + picFiles: [], + photo: "", + maritalStatus: "", + intentionFriends: "", + introduction: "" + }, + rules: { + userId: [{ required: true, message: "请选择用户", trigger: ["change", "blur"] }], + mobile: [ + { required: true, message: "请输入联系方式", trigger: ["change", "blur"] }, + { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: ["change", "blur"] } + ], + birthday: [{ required: true, message: "请选择出生年月", trigger: ["change", "blur"] }], + height: [{ pattern: /^\d{2,3}$/, message: "请输入正确的身高", trigger: ["change", "blur"] }], + education: [{ required: true, message: "请选择学历", trigger: ["change", "blur"] }], + maritalStatus: [{ required: true, message: "请选择婚姻状况", trigger: ["change", "blur"] }], + introduction: [{ required: true, message: "请填写个人介绍", trigger: ["change", "blur"] }] + } + } + }, + methods: { + onOpen(data) { + this.visible = true + this.loading = false + this.userOptions = [] // 清空用户选项 + + if (data && data.id) { + this.formData = JSON.parse(JSON.stringify(data)) + this.formData.picFiles = JSON.parse(this.formData.picFiles) + } else { + this.formData = { + userId: "", + userName: "", + birthday: "", + mobile: "", + height: "", + nativePlace: "", + education: "", + hobby: "", + monthlyIncome: "", + housingSituation: "", + picFiles: [], + photo: "", + maritalStatus: "", + intentionFriends: "", + introduction: "" + } + } + + this.$nextTick(() => { + if (this.$refs.form) { + this.$refs.form.clearValidate() + } + }) + }, + + // 远程搜索用户 + remoteSearchUsers(query) { + if (query !== "") { + this.userSearchLoading = true + this.$axios + .post("/platform/singleTeacher/ledger/queryNotSingleTeacher", { key: query }) + .then((res) => { + if (res.code === 0) { + this.userOptions = res.data || [] + } else { + this.$message.error(res.msg || "搜索用户失败") + } + }) + .finally(() => { + this.userSearchLoading = false + }) + } else { + this.userOptions = [] + } + }, + + // 用户选择变更 + handleUserChange(userId) { + const selectedUser = this.userOptions.find((item) => item.id === userId) + if (selectedUser) { + // 自动填充一些基础信息 + this.formData.userName = selectedUser.name + this.formData.mobile = selectedUser.mobile || "" + this.formData.birthday = selectedUser.birthday || "" + this.formData.education = selectedUser.education || "" + this.formData.nativePlace = selectedUser.nativePlace || "" + } + }, + + submitForm() { + this.$refs.form.validate((valid) => { + if (valid) { + this.loading = true + + // 构建提交的数据 + const submitData = { ...this.formData } + + // 发送请求 + const url = submitData.id ? "/platform/singleTeacher/ledger/update" : "/platform/singleTeacher/ledger/insert" + + this.$axios + .post(url, { singleTeacher: JSON.stringify(submitData) }) + .then((res) => { + if (res.code === 0) { + this.$message.success(submitData.id ? "修改成功" : "添加成功") + this.visible = false + this.$emit("refresh") + } else { + this.$message.error(res.msg || "操作失败") + } + }) + .finally(() => { + this.loading = false + }) + } + }) + } + }, + style: /*language=CSS*/ ` + + + ` +} diff --git a/src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/index.html b/src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/index.html new file mode 100644 index 0000000..359c941 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/user/singleTeacher/ledger/index.html @@ -0,0 +1,124 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
{{ pageForm.age ? pageForm.age.join('-') : '' }}
+
+
+
+
+ + + 新增 + 导出 + + + + + + + + + + + + + + + + + + + + + +
+ + + +