diff --git a/src/main/java/com/budwk/app/base/constant/RoleConstant.java b/src/main/java/com/budwk/app/base/constant/RoleConstant.java index 056327f3..2a10d21c 100644 --- a/src/main/java/com/budwk/app/base/constant/RoleConstant.java +++ b/src/main/java/com/budwk/app/base/constant/RoleConstant.java @@ -16,6 +16,10 @@ RoleConstant { UNION_COMMITTEE_MEMBER("工代会委员"), + OFFICE_MANAGER("两办办公室负责人"), + SCHOOL_SECRETARY("学校书记"), + SCHOOL_HEADMASTER("学校校长"), + SCHOOL_UNION_ADMIN("校工会管理员"), SCHOOL_UNION_CHAIRMAN("校工会主席"), SCHOOL_UNION_VICE_CHAIRMAN("校工会副主席"), diff --git a/src/main/java/com/budwk/app/flow/handler/FlowGeneralRoleCodeByArgsAssignmentHandler.java b/src/main/java/com/budwk/app/flow/handler/FlowGeneralRoleCodeByArgsAssignmentHandler.java new file mode 100644 index 00000000..50bd5861 --- /dev/null +++ b/src/main/java/com/budwk/app/flow/handler/FlowGeneralRoleCodeByArgsAssignmentHandler.java @@ -0,0 +1,57 @@ +package com.budwk.app.flow.handler; + +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.flow.engine.AssignmentHandler; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.model.TaskModel; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.models.Sys_user_role; +import com.budwk.app.sys.services.SysRoleService; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.lang.Lang; + +import java.util.List; + +/** + * @ClassName FlowGeneralRoleCodeByArgsAssignmentHandler + * @Author JyuHsin + * @Date 2026/1/31 16:58 + * @Version 1.0 + * @Description 根据参数的roleCode获取审核人 + */ +public class FlowGeneralRoleCodeByArgsAssignmentHandler implements AssignmentHandler { + @Override + public List assign(TaskModel model, Execution execution) { + String roleCode = execution.getArgs().getStr("roleCode"); + if (StrUtil.isBlank(roleCode)) { + throw new BaseException("参数 roleCode 不能为空"); + } + + SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class); + Sys_role role = sysRoleService.getByCode(roleCode); + + List roles = ServiceContext.find(Dao.class).query( + Sys_user_role.class, + Cnd.where(Sys_user_role::getRoleId, "=", role.getId()) + ); + + if (Lang.isEmpty(roles)) { + throw new RuntimeException(role.getName() + "未设置用户。"); + } + + return roles.stream().map(Sys_user_role::getUserId).distinct().toList(); + } + + @Override + public String getMessage() { + return "根据角色编码获取审核人(根据args中的roleCode)"; + } + + @Override + public int getOrder() { + return AssignmentHandler.super.getOrder(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/common/OpinionCommonController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/common/OpinionCommonController.java new file mode 100644 index 00000000..f68a9138 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/common/OpinionCommonController.java @@ -0,0 +1,97 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.common; + +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionType; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalType; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; +import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation; +import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; +import io.swagger.annotations.ApiOperation; +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.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.List; + +@IocBean +@At("/platform/opinion/common") +@Ok("json:full") +public class OpinionCommonController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + + @At + @SaCheckPermission("opinion") + @ApiOperation("意见详情") + public Result opinionInfo(@Valid String id) { + return Result.success(opinionCommonService.info(id)); + } + + @At + @ApiOperation("查询全部的意见类型") + @SaCheckLogin + public Result listOpinionType(){ + List list = dao.query(OpinionType.class, Cnd.NEW().asc(OpinionType::getCode)); + return Result.success(list); + } + + @At + @SaCheckLogin + @ApiOperation("查询全部的教代会") + public Result listSession() { + List list = dao.query(Teacher_congress_session.class, Cnd.NEW().desc("startDate")); + return Result.success(list); + } + + @At + @SaCheckLogin + @ApiOperation("查询开启的教代会") + public Result listOpenSession() { + List list = dao.query(Teacher_congress_session.class, Cnd.where("enable", "=", 1).desc("startDate")); + return Result.success(list); + } + + @At + @SaCheckLogin + @ApiOperation("查询当前用户所属的教代会") + public Result listOpenSessionByUser() { + List list = dao.query(Teacher_congress_session.class, Cnd.where("enable", "=", 1).desc("startDate")); + return Result.success(list); + } + + @At + @SaCheckLogin + @ApiOperation("查询当前教代会的代表团") + public Result listDelegation(@Valid String sessionId) { + List list = dao.query(Teacher_congress_delegation.class, Cnd.where("sessionId", "=", sessionId).asc("code")); + return Result.success(list); + } + + @At + @SaCheckLogin + @ApiOperation("承办单位列表") + public Result listUnderTake() { + List list = dao.query(ProposalUndertake.class, Cnd.NEW()); + return Result.success(list); + } + + @At + @Ok("void") + @SaCheckPermission("proposal") + public void exportProposalAsDocx(String id, HttpServletResponse response) { + opinionCommonService.exportOpinionAsDocx(id, response); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/config/OpinionConfigTypeController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/config/OpinionConfigTypeController.java new file mode 100644 index 00000000..55e1c31c --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/config/OpinionConfigTypeController.java @@ -0,0 +1,102 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.config; + +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.base.service.BaseService; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionType; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalType; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +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.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import javax.validation.Valid; + +/** + * @ClassName OpinionConfigTypeController + * @Author JyuHsin + * @Date 2026/2/2 10:16 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/config/type") +@Slf4j +@Ok("json:full") +@Api("意见类型配置") +public class OpinionConfigTypeController { + + @Inject + private Dao dao; + @Inject + private BaseService baseService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/config/type/index.html") + @SaCheckPermission("opinion.config.type") + public void index() { + } + + @At + @SaCheckPermission("opinion.config.type") + @ApiModelProperty("分页查询意见类型") + public Result pageData(@Valid PageForm pageForm, String name){ + Sql sql = Sqls.create("select * from opinion_type $condition"); + Cnd cnd = Cnd.NEW(); + cnd.and(Cnd.likeEX("name", name)); + sql.setCondition(cnd); + Pagination pagination = baseService.listPageVO(pageForm, sql, OpinionType.class); + return Result.success(pagination); + } + + @At + @SaCheckPermission("opinion.config.type") + @ApiModelProperty("新增意见类型") + @SLog(type = "意见类型配置", tag = "新增意见类型", msg = "${type.name}") + public Result insert(OpinionType type){ + int count = dao.count(OpinionType.class, Cnd.where("code", "=", type.getCode())); + if(count>0){ + return Result.error("编码重复!"); + } + dao.insert(type); + return Result.success(); + } + + @At + @SaCheckPermission("opinion.config.type") + @ApiModelProperty("修改意见类型") + @SLog(type = "意见类型配置", tag = "修改意见类型", msg = "${type.name}") + public Result update(OpinionType type){ + int count = dao.count(OpinionType.class, Cnd.where("code", "=", type.getCode()).and("id", "!=", type.getId())); + if (count > 0) { + return Result.error("编码重复!"); + } + dao.updateIgnoreNull(type); + return Result.success(); + } + + @At + @SaCheckPermission("opinion.config.type") + @ApiModelProperty("删除意见类型") + @SLog(type = "意见类型配置", tag = "删除意见类型", msg = "id:${id}") + public Result delete(@Valid Integer id){ + int count = dao.count(OpinionInfo.class, Cnd.where(OpinionInfo::getTypeId, "=", id)); + if(count > 0){ + return Result.error("该类型有关联的意见,无法删除!"); + } + dao.delete(OpinionType.class, id); + return Result.success(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionFeedbackController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionFeedbackController.java new file mode 100644 index 00000000..bc1437e6 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionFeedbackController.java @@ -0,0 +1,114 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +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.List; + +/** + * @ClassName OpinionFeedbackController + * @Author JyuHsin + * @Date 2026/2/3 15:21 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/feedback") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-反馈评价") +public class OpinionFeedbackController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/feedback/index.html") + @SaCheckPermission("opinion.feedback") + public void index() { + } + + @At + @SaCheckPermission("opinion.feedback") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId, + @Param(value = "approval") Boolean approval) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, + t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, + IF(rt.id IS NOT NULL, 1, 0) AS canRevoke, + t.variable->>'$.underTakeName' AS underTakeName, + IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') = 1, 1, 0) AS underTakeIsMaster + FROM + wf_process_task t + LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId + LEFT JOIN opinion_info info ON info.id = ins.businessNo + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 + LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("info.sessionId", "=", sessionId); + cnd.and("t.taskName", "in", List.of("feedback")); + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + + if (approval) { + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } + + OpinionSearchParam.buildSearch(cnd, pageForm); + + cnd.groupBy("t.id"); + sql.setCondition(cnd); + + Pagination pageVO = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pageVO); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionMineController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionMineController.java new file mode 100644 index 00000000..59a49f76 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionMineController.java @@ -0,0 +1,136 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaMode; +import com.budwk.app.base.annotation.SLog; +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.flow.engine.FlowEngine; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.OpinionWriteService; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; +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.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; + +/** + * @ClassName OpinionMineController + * @Author JyuHsin + * @Date 2026/2/2 17:13 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/mine") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-我的意见") +public class OpinionMineController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + @Inject + private FlowEngine flowEngine; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/mine/index.html") + @SaCheckPermission("opinion.mine") + public void index() { + } + + @At("/h5") + @Ok("beetl:/platform/zhghh5/democratic/opinion/transact/mine/index.html") + @SaCheckPermission("h5.opinion.mine") + public void h5Index() { + } + + @At + @SaCheckPermission("opinion.mine") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, String sessionId) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, + t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke, + (select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId + FROM + opinion_info info + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id + LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10 + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + $condition + """); + + Cnd cnd = Cnd.NEW(); + if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name(), RoleConstant.SCHOOL_UNION_PROPOSAL_ADMIN.name())) { + cnd.and("info.createUserId", "=", SecurityUtil.getUserId()); + } + OpinionSearchParam.buildSearch(cnd, pageForm); + cnd.andEX("info.sessionId", "=", sessionId); + cnd.groupBy("info.id"); + sql.setCondition(cnd); + Pagination pagination = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pagination); + } + + @At + @ApiOperation("删除") + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission(value = {"opinion.mine", "h5.opinion.mine"}, mode = SaMode.OR) + @SLog(tag = "教代会意见系统-我的意见", msg = "删除意见") + public Result delete(@Param("id") String id) { + dao.delete(OpinionInfo.class, id); + flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id); + return Result.success(); + } + + @At + @SaCheckPermission(value = {"opinion.mine", "h5.opinion.mine"}, mode = SaMode.OR) + public Result detail(@Valid String id) { + OpinionInfo info = dao.fetch(OpinionInfo.class, id); + return Result.success(info); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionOfficeAuditController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionOfficeAuditController.java new file mode 100644 index 00000000..d176ff25 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionOfficeAuditController.java @@ -0,0 +1,112 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +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.List; + +/** + * @ClassName OpinionOfficeAuditController + * @Author JyuHsin + * @Date 2026/2/3 10:37 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/office") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-两办审核") +public class OpinionOfficeAuditController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/office/index.html") + @SaCheckPermission("opinion.office") + public void index() { + } + + @At + @SaCheckPermission("opinion.office") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId, + @Param(value = "approval") Boolean approval) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, + t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, + IF(rt.id IS NOT NULL, 1, 0) AS canRevoke + FROM + wf_process_task t + LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId + LEFT JOIN opinion_info info ON info.id = ins.businessNo + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 + LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("info.sessionId", "=", sessionId); + cnd.and("t.taskName", "=", "office"); + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + + if (approval) { + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } + + OpinionSearchParam.buildSearch(cnd, pageForm); + + cnd.groupBy("t.id"); + sql.setCondition(cnd); + + Pagination pageVO = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pageVO); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSchoolAuditController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSchoolAuditController.java new file mode 100644 index 00000000..ee8c3317 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSchoolAuditController.java @@ -0,0 +1,146 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.Dict; +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.flow.constant.FlowConst; +import com.budwk.app.flow.engine.FlowEngine; +import com.budwk.app.flow.engine.util.FlowUtil; +import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +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.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.List; + +/** + * @ClassName OpinionSchoolAuditController + * @Author JyuHsin + * @Date 2026/2/2 17:50 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/schoolAudit") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-校工会审核") +public class OpinionSchoolAuditController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + @Inject + private FlowEngine flowEngine; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/schoolAudit/index.html") + @SaCheckPermission("opinion.schoolAudit") + public void index() { + } + + @At + @SaCheckPermission("opinion.schoolAudit") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId, + @Param(value = "approval") Boolean approval) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, + t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, + IF(rt.id IS NOT NULL, 1, 0) AS canRevoke + FROM + wf_process_task t + LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId + LEFT JOIN opinion_info info ON info.id = ins.businessNo + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 + LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("info.sessionId", "=", sessionId); + cnd.and("t.taskName", "=", "schoolAudit"); + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + + if (approval) { + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } + + OpinionSearchParam.buildSearch(cnd, pageForm); + + cnd.groupBy("t.id"); + sql.setCondition(cnd); + + Pagination pageVO = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pageVO); + } + + @At + @SaCheckPermission("opinion.schoolAudit") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("修改意见") + @SLog(tag = "意见管理系统-校工会审核", msg = "修改意见") + public Result edit(@Param("info") OpinionInfo opinionInfo) { + dao.update(opinionInfo); + + ProcessInstance instance = dao.fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", opinionInfo.getId())); + Dict dict = FlowUtil.variableToDict(instance.getVariable()); + dict.set(FlowConst.FORM_DATA, opinionInfo); + dao.update(instance); + + List doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null); + for (ProcessTask task : doingTaskList) { + Dict args = FlowUtil.variableToDict(task.getVariable()); + args.set(FlowConst.FORM_DATA, opinionInfo); + } + dao.update(doingTaskList); + + return Result.success(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSchoolSubmitController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSchoolSubmitController.java new file mode 100644 index 00000000..199d1868 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSchoolSubmitController.java @@ -0,0 +1,154 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.Dict; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.ProcessSubmitTypeEnum; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.flow.service.FlowCommonService; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +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.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.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.validation.Valid; +import java.util.List; + +/** + * @ClassName OpinionSchoolSubmitController + * @Author JyuHsin + * @Date 2026/2/3 14:34 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/schoolSubmit") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-校工会提交") +public class OpinionSchoolSubmitController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + @Inject + private FlowCommonService flowCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/schoolSubmit/index.html") + @SaCheckPermission("opinion.schoolSubmit") + public void index() { + } + + @At + @SaCheckPermission("opinion.schoolSubmit") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId, + @Param(value = "approval") Boolean approval) { + Sql sql = getSql(pageForm, sessionId, approval); + Pagination pageVO = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pageVO); + } + + @At + @SaCheckPermission("opinion.schoolSubmit") + @Aop(TransAop.READ_COMMITTED) + public Result queryBatch(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId, + @Param(value = "approval") Boolean approval) { + Sql sql = getSql(pageForm, sessionId, approval); + List list = opinionCommonService.listMap(sql); + List taskIds = list.stream().map(o -> o.getString("taskId")).filter(Strings::isNotBlank).toList(); + return Result.success(taskIds); + } + + @At + @ApiOperation("执行任务") + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission("opinion.schoolSubmit") + public Result executeTask(@Param("data") String[] taskIds) { + List taskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getId, "in", taskIds)); + for (ProcessTask task : taskList) { + Dict args = Dict.create(); + args.set("processTaskId", task.getId()); + args.set("taskName", task.getTaskName()); + args.set("submitType", ProcessSubmitTypeEnum.AGREE.getCode()); + args.set("tf_opinion", "同意"); + flowCommonService.executeTask(args); + } + return Result.success(); + } + + private Sql getSql(OpinionSearchParam pageForm, String sessionId, Boolean approval) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, + t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, + IF(rt.id IS NOT NULL, 1, 0) AS canRevoke + FROM + wf_process_task t + LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId + LEFT JOIN opinion_info info ON info.id = ins.businessNo + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 + LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("info.sessionId", "=", sessionId); + cnd.and("t.taskName", "in", List.of("schoolSubmit")); + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + + if (approval) { + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } + + OpinionSearchParam.buildSearch(cnd, pageForm); + + cnd.groupBy("t.id"); + sql.setCondition(cnd); + return sql; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSummaryController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSummaryController.java new file mode 100644 index 00000000..efc04386 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionSummaryController.java @@ -0,0 +1,106 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +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.flow.enums.ProcessInstanceStateEnum; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +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.List; + +/** + * @ClassName OpinionSummaryController + * @Author JyuHsin + * @Date 2026/2/3 17:55 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/summary") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-查询统计") +public class OpinionSummaryController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/summary/index.html") + @SaCheckPermission("opinion.summary") + public void index() { + } + + @At + @SaCheckPermission("opinion.summary") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.state instanceState, + ins.processDefineId instanceProcessDefineId, + t.displayName taskName + FROM + opinion_info info + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN ( + SELECT + processInstanceId, + displayName, + createdAt, + ROW_NUMBER() OVER (PARTITION BY processInstanceId ORDER BY createdAt DESC) AS rn + FROM wf_process_task + ) t ON t.processInstanceId = ins.id AND t.rn = 1 + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN vw_user u ON u.id = info.createUserId + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode()); + cnd.andEX("info.sessionId", "=", sessionId); + + if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_SECRETARY.name(), RoleConstant.SCHOOL_HEADMASTER.name())) { + // 其他校领导看自己单位 + cnd.and("u.unit", "=", SecurityUtil.getUnitId()); + } + + OpinionSearchParam.buildSearch(cnd, pageForm); + + cnd.groupBy("info.id"); + sql.setCondition(cnd); + + Pagination pageVO = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pageVO); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionUnitReplyController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionUnitReplyController.java new file mode 100644 index 00000000..f5eeba17 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionUnitReplyController.java @@ -0,0 +1,116 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.param.OpinionSearchParam; +import com.budwk.app.zhgh.democratic.opinion.service.common.OpinionCommonService; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +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.List; + +/** + * @ClassName OpinionUnitReplyController + * @Author JyuHsin + * @Date 2026/2/3 10:50 + * @Version 1.0 + * @Description TODO + */ +@IocBean +@At("/platform/opinion/unitReply") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-承办答复") +public class OpinionUnitReplyController { + + @Inject + private Dao dao; + @Inject + private OpinionCommonService opinionCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/unitReply/index.html") + @SaCheckPermission("opinion.unitReply") + public void index() { + } + + @At + @SaCheckPermission("opinion.unitReply") + @Aop(TransAop.READ_COMMITTED) + public Result pageData(@Valid OpinionSearchParam pageForm, + @Param(value = "String") String sessionId, + @Param(value = "approval") Boolean approval) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, + t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, + IF(rt.id IS NOT NULL, 1, 0) AS canRevoke, + t.variable->>'$.underTakeName' AS underTakeName, + IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') in (true, 1), 1, 0) AS underTakeIsMaster + FROM + wf_process_task t + LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId + LEFT JOIN opinion_info info ON info.id = ins.businessNo + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 + LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 + LEFT JOIN wf_process_task_actor pta ON pta.processTaskId = nt.id + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.andEX("info.sessionId", "=", sessionId); + cnd.and("t.taskName", "in", List.of("master_reply", "slave_reply")); + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + + if (approval) { + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("pta.actorId", "in", List.of(SecurityUtil.getUserId())); + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } + + OpinionSearchParam.buildSearch(cnd, pageForm); + + cnd.groupBy("t.id"); + sql.setCondition(cnd); + + Pagination pageVO = opinionCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pageVO); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionWriteController.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionWriteController.java new file mode 100644 index 00000000..8c001d76 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/controller/transact/OpinionWriteController.java @@ -0,0 +1,145 @@ +package com.budwk.app.zhgh.democratic.opinion.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.result.Result; +import com.budwk.app.flow.constant.FlowConst; +import com.budwk.app.flow.engine.FlowEngine; +import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.ProcessSubmitTypeEnum; +import com.budwk.app.flow.service.FlowCommonService; +import com.budwk.app.sys.models.Sys_dict; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.opinion.service.OpinionWriteService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService; +import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate; +import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; +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.Cnd; +import org.nutz.dao.Dao; +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; +import java.util.List; + +/** + * 意见撰写 + */ +@IocBean +@At("/platform/opinion/write") +@Slf4j +@Ok("json:full") +@Api(tags = "意见管理-意见撰写") +public class OpinionWriteController { + @Inject + private Dao dao; + @Inject + private OpinionWriteService opinionWriteService; + @Inject + private FlowEngine flowEngine; + @Inject + private FlowCommonService flowCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/opinion/transact/write/index.html") + @SaCheckPermission("opinion.write") + public void index() { + } + + @At("/h5") + @Ok("beetl:/platform/zhghh5/democratic/opinion/transact/write/index.html") + @SaCheckPermission("h5.opinion.write") + public void h5Index() { + } + + @At + @SaCheckPermission("opinion.write") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("保存意见") + @SLog(tag = "意见管理系统-我的意见", msg = "保存意见") + public Result save(@Param("info") OpinionInfo opinionInfo) { + if (StrUtil.isBlank(opinionInfo.getCode())) { + opinionInfo.setCode(opinionWriteService.generateOpinionCode(opinionInfo.getSessionId(), opinionInfo.getDelegationId())); + } + dao.insertOrUpdate(opinionInfo); + return Result.success(opinionInfo); + } + + @At + @SaCheckPermission("opinion.write") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("提交意见") + @SLog(tag = "意见管理系统-我的意见", msg = "提交意见") + public Result submit(@Param("info") OpinionInfo opinionInfo) { + if (StrUtil.isBlank(opinionInfo.getCode())) { + opinionInfo.setCode(opinionWriteService.generateOpinionCode(opinionInfo.getSessionId(), opinionInfo.getDelegationId())); + } + dao.insertOrUpdate(opinionInfo); + + // 开启流程实例 + Dict args = Dict.create(); + args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode()); + args.set(FlowConst.FORM_DATA, opinionInfo); + + ProcessInstance instance = flowEngine.startProcessInstanceByKey("JDHYJ", opinionInfo.getId(), SecurityUtil.getUserId(), args); + + // 自动完成第一个申请任务 + List doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null); + for (ProcessTask task : doingTaskList) { + flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args); + } + + return Result.success(opinionInfo); + } + + @At + @SaCheckPermission("opinion.write") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("重新提交意见") + @SLog(tag = "意见管理系统-我的意见", msg = "重新提交意见") + public Result submitAgain(@Param("info") OpinionInfo opinionInfo, @Param("taskId") Long taskId) { + dao.insertOrUpdate(opinionInfo); + + Dict dict = Dict.create(); + dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId); + dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode()); + + flowCommonService.executeTask(dict); + return Result.success(); + } + + @At + @SaCheckPermission("opinion.write") + @ApiOperation("意见详情") + public Result detail(@Valid String id) { + OpinionInfo info = dao.fetch(OpinionInfo.class, id); + return Result.success(info); + } + + @At + @SaCheckPermission("opinion.write") + @ApiOperation("查询代表所属代表团") + public Result searchDelegation(@Valid String sessionId, String userId) { + if (StrUtil.isBlank(userId)) { + userId = SecurityUtil.getUserId(); + } + Teacher_congress_delegate delegate = dao.fetch(Teacher_congress_delegate.class, + Cnd.where(Teacher_congress_delegate::getSessionId, "=", sessionId) + .and(Teacher_congress_delegate::getUserId, "=", userId) + ); + return Result.success().addData(delegate != null ? delegate.getDelegationId() : null); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionCreatedUserAssignmentHandler.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionCreatedUserAssignmentHandler.java new file mode 100644 index 00000000..d96ecadd --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionCreatedUserAssignmentHandler.java @@ -0,0 +1,45 @@ +package com.budwk.app.zhgh.democratic.opinion.handler; + +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.flow.engine.AssignmentHandler; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.model.TaskModel; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import org.nutz.dao.Dao; +import org.nutz.lang.Lang; + +import java.util.List; + +/** + * @ClassName OpinionCreatedUserAssignmentHandler + * @Author JyuHsin + * @Date 2026/2/3 15:26 + * @Version 1.0 + * @Description TODO + */ +public class OpinionCreatedUserAssignmentHandler implements AssignmentHandler { + @Override + public List assign(TaskModel model, Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + String opinionId = execution.getProcessInstance().getBusinessNo(); + + OpinionInfo info = dao.fetch(OpinionInfo.class, opinionId); + if (info == null || StrUtil.isBlank(info.getCreateUserId())) { + throw new BaseException("未查询到意见人信息"); + } + + return List.of(info.getCreateUserId()); + } + + @Override + public String getMessage() { + return "获取意见人"; + } + + @Override + public int getOrder() { + return AssignmentHandler.super.getOrder(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionMasterUnitAssignmentHandler.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionMasterUnitAssignmentHandler.java new file mode 100644 index 00000000..e3ddc7cd --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionMasterUnitAssignmentHandler.java @@ -0,0 +1,83 @@ +package com.budwk.app.zhgh.democratic.opinion.handler; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.flow.engine.AssignmentHandler; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.model.TaskModel; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.models.Sys_user_role; +import com.budwk.app.sys.services.SysRoleService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; + +import java.util.List; + +/** + * @ClassName OpinionMasterUnitAssignmentHandler + * @Author JyuHsin + * @Date 2026/2/3 11:13 + * @Version 1.0 + * @Description TODO + */ +public class OpinionMasterUnitAssignmentHandler implements AssignmentHandler { + @Override + public List assign(TaskModel model, Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class); + + String opinionId = execution.getProcessInstance().getBusinessNo(); + + String masterUnitId = execution.getArgs().getStr("tf_masterUnitId"); + + if(StrUtil.isBlank(masterUnitId)){ + ProposalReplyUnit masterUnit = dao.fetch(ProposalReplyUnit.class, Cnd.where(ProposalReplyUnit::getProposalId, "=", opinionId).and(ProposalReplyUnit::getIsMaster, "=", 1)); + if (masterUnit == null) { + throw new BaseException("系统异常"); + } + masterUnitId = masterUnit.getUnitId(); + } + + if(StrUtil.isBlank(masterUnitId)){ + throw new BaseException("提案没有主办单位"); + } + + ProposalUndertake undertake = dao.fetch(ProposalUndertake.class, masterUnitId); + if (undertake == null) { + throw new BaseException("主办单位不存在"); + } + + Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER); + + List sysUserRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId()).and(Sys_user_role::getUnderTakeId, "=", undertake.getId())); + List selectUserIds = sysUserRoles.stream().map(Sys_user_role::getUserId).toList(); + + if (selectUserIds.isEmpty()) { + throw new BaseException("主办单位没有负责人"); + } + + + // 参数 + Dict args = execution.getArgs(); + args.set("underTakeName", undertake.getName()); + args.set("underTakeId", undertake.getId()); + args.set("underTakeIsMaster",true); + + return selectUserIds; + } + + @Override + public String getMessage() { + return "意见主办单位处理人"; + } + + @Override + public int getOrder() { + return AssignmentHandler.super.getOrder(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionSlaveUnitAssignmentHandler.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionSlaveUnitAssignmentHandler.java new file mode 100644 index 00000000..fcca0cd6 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/handler/OpinionSlaveUnitAssignmentHandler.java @@ -0,0 +1,62 @@ +package com.budwk.app.zhgh.democratic.opinion.handler; + +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.flow.engine.AssignmentHandler; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.model.TaskModel; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.models.Sys_user_role; +import com.budwk.app.sys.services.SysRoleService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName OpinionSlaveUnitAssignmentHandler + * @Author JyuHsin + * @Date 2026/2/3 11:15 + * @Version 1.0 + * @Description TODO + */ +public class OpinionSlaveUnitAssignmentHandler implements AssignmentHandler { + @Override + public List assign(TaskModel model, Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class); + + List assignee = new ArrayList<>(); + + List helpUnitIds = (List) execution.getArgs().get("tf_slaveUnitIds"); + + if (helpUnitIds != null && !helpUnitIds.isEmpty()) { + + Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER); + + for (String helpUnitId : helpUnitIds) { + ProposalUndertake undertake = dao.fetch(ProposalUndertake.class, helpUnitId); + List sysUserRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId()).and(Sys_user_role::getUnderTakeId, "=", undertake.getId())); + if (sysUserRoles.isEmpty()) { + throw new BaseException(undertake.getName() + "单位没有设置负责人!"); + } + assignee.addAll(sysUserRoles.stream().map(Sys_user_role::getUserId).toList()); + } + return assignee; + } + return assignee; + } + + @Override + public String getMessage() { + return "意见协办单位处理人"; + } + + @Override + public int getOrder() { + return AssignmentHandler.super.getOrder(); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/listenter/OpinionOfficeSuffixInterceptor.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/listenter/OpinionOfficeSuffixInterceptor.java new file mode 100644 index 00000000..bcd2427f --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/listenter/OpinionOfficeSuffixInterceptor.java @@ -0,0 +1,85 @@ +package com.budwk.app.zhgh.democratic.opinion.listenter; + +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.flow.constant.FlowConst; +import com.budwk.app.flow.engine.FlowInterceptor; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.util.FlowUtil; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.entity.ProcessTaskActor; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionReplyUnit; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.json.Json; + +import java.util.List; + +/** + * @ClassName OpinionOfficeSuffixInterceptor + * @Author JyuHsin + * @Date 2026/2/3 14:04 + * @Version 1.0 + * @Description TODO + */ +public class OpinionOfficeSuffixInterceptor implements FlowInterceptor { + @Override + public void intercept(Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + + String opinionId = execution.getProcessInstance().getBusinessNo(); + String officeResult = execution.getArgs().getStr(FlowConst.TASK_FORM_DATA_PREFIX + "officeResult"); + + if (StrUtil.isNotBlank(officeResult) && "YES".equals(officeResult)) { + // 删除原来的记录 + dao.clear(OpinionReplyUnit.class, Cnd.where(OpinionReplyUnit::getOpinionId, "=", opinionId)); + + // 主办单位 + String masterUnitId = execution.getArgs().getStr(FlowConst.TASK_FORM_DATA_PREFIX + "masterUnitId"); + ProposalUndertake masterUnit = dao.fetch(ProposalUndertake.class, masterUnitId); + OpinionReplyUnit masterReplyUnit = new OpinionReplyUnit(); + masterReplyUnit.setOpinionId(opinionId); + masterReplyUnit.setUnitId(masterUnit.getId()); + masterReplyUnit.setUnitCode(masterUnit.getCode()); + masterReplyUnit.setUnitName(masterUnit.getName()); + masterReplyUnit.setIsMaster(true); + dao.insert(masterReplyUnit); + + // 协办单位 + List helpUnitIds = (List) execution.getArgs().getObj(FlowConst.TASK_FORM_DATA_PREFIX + "slaveUnitIds"); + if(ObjectUtil.isNotEmpty(helpUnitIds)){ + for (String helpUnitId : helpUnitIds) { + ProposalUndertake helpUnit = dao.fetch(ProposalUndertake.class, helpUnitId); + OpinionReplyUnit helpReplyUnit = new OpinionReplyUnit(); + helpReplyUnit.setOpinionId(opinionId); + helpReplyUnit.setUnitId(helpUnit.getId()); + helpReplyUnit.setUnitCode(helpUnit.getCode()); + helpReplyUnit.setUnitName(helpUnit.getName()); + helpReplyUnit.setIsMaster(false); + dao.insert(helpReplyUnit); + } + } + } + + // 当前任务 + List processTaskList = execution.getProcessTaskList(); + + for (ProcessTask task : processTaskList) { + // 办理人 + ProcessTaskActor taskActor = dao.fetch(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId())); + String actorUnitId = taskActor.getActorUnitId(); + OpinionReplyUnit replyUnit = dao.fetch(OpinionReplyUnit.class, Cnd.where(OpinionReplyUnit::getOpinionId, "=", opinionId).and(OpinionReplyUnit::getUnitId, "=", actorUnitId)); + + Dict variable = FlowUtil.variableToDict(task.getVariable()); + variable.set("underTakeName", replyUnit.getUnitName()); + variable.set("underTakeId", replyUnit.getUnitId()); + variable.set("underTakeIsMaster", replyUnit.getIsMaster()); + task.setVariable(Json.toJson(variable)); + } + dao.update(processTaskList,"variable"); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionInfo.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionInfo.java new file mode 100644 index 00000000..545080a0 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionInfo.java @@ -0,0 +1,125 @@ +package com.budwk.app.zhgh.democratic.opinion.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 org.nutz.json.JsonField; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = true) +@Table("opinion_info") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("教代会意见") +@TableIndexes({ + @Index(name = "INDEX_OPINION_INFO_SESSION_CODE", fields = {"sessionId", "code"}) +}) +public class OpinionInfo extends BaseModel { + + @Name + @Comment("ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + @PrevInsert(uu32 = true) + private String id; + + @Column + @Comment("意见编号") + @ColDefine(type = ColType.VARCHAR, width = 20) + private String code; + + @Column + @Comment("意见名称") + @ColDefine(type = ColType.VARCHAR, width = 100) + @NotBlank(message = "意见名称不能为空") + @Size(max = 100) + private String name; + + @Column + @Comment("意见类型") + @ColDefine(type = ColType.INT) + private Integer typeId; + + @Column + @Comment("教代会ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String sessionId; + + @Column + @Comment("意见人ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String createUserId; + + @Column + @Comment("意见人姓名") + @ColDefine(type = ColType.VARCHAR, width = 100) + private String createUserName; + + @Column + @Comment("意见人工号") + @ColDefine(type = ColType.VARCHAR, width = 120) + private String createUserLoginName; + + @Column + @Comment("联系电话") + @ColDefine(type = ColType.VARCHAR, width = 20) + private String mobile; + + @Column + @Comment("所属代表团ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String delegationId; + + @Column + @Comment("单位") + @ColDefine(type = ColType.VARCHAR, width = 100) + private String unitName; + + @Column + @Comment("创建时间") + @ColDefine(type = ColType.VARCHAR, width = 30) + @JsonField(dataFormat = "yyyy-MM-dd") + private String createTime; + + @Column + @Comment("意见和建议") + @ColDefine(type = ColType.TEXT) + private String brief; + + @Column + @Comment("工作措施") + @ColDefine(type = ColType.TEXT) + private String measures; + + @Column + @Comment("建议落实部门") + @ColDefine(type = ColType.MYSQL_JSON) + private List suggestUnits; + + @Column + @Comment("附件") + @ColDefine(type = ColType.MYSQL_JSON) + private List files; + + @Column + @Comment("意见人签字ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String signId; + + @Column + @Comment("是否公示意见") + @ColDefine(type = ColType.BOOLEAN) + @Default(value = "0") + private Boolean publicity; + + @Column + @Comment("是否优秀意见") + @ColDefine(type = ColType.BOOLEAN) + @Default(value = "0") + private Boolean excellent; +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionReplyUnit.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionReplyUnit.java new file mode 100644 index 00000000..bd996988 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionReplyUnit.java @@ -0,0 +1,62 @@ +package com.budwk.app.zhgh.democratic.opinion.models; + +import com.budwk.app.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; + +/** + * @ClassName OpinionReplyUnit + * @Author JyuHsin + * @Date 2026/2/3 14:00 + * @Version 1.0 + * @Description TODO + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@Table("opinion_reply_unit") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("意见承办单位信息") +public class OpinionReplyUnit extends BaseModel { + + @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 opinionId; + + @Column + @Comment("承办单位ID") + @ColDefine(type = ColType.VARCHAR, width = 32) + private String unitId; + + @Column + @Comment("承办单位code") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String unitCode; + + @Column + @Comment("承办单位名称") + @ColDefine(type = ColType.VARCHAR, width = 255) + private String unitName; + + @Column + @Comment("是否主办单位") + @ColDefine(type = ColType.BOOLEAN) + @Default("0") + private Boolean isMaster; + + @Column + @Comment("是否答复") + @ColDefine(type = ColType.BOOLEAN) + @Default("0") + private Boolean isReply; +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionType.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionType.java new file mode 100644 index 00000000..8d634c7a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/models/OpinionType.java @@ -0,0 +1,36 @@ +package com.budwk.app.zhgh.democratic.opinion.models; + +import com.budwk.app.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.nutz.dao.entity.annotation.*; + +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@Table("opinion_type") +@TableMeta("{'mysql-charset':'utf8mb4'}") +@Comment("意见类型") +public class OpinionType extends BaseModel { + + @Id + @Comment("id") + private Integer id; + + @Column + @Comment("编码") + @ColDefine(type = ColType.VARCHAR, width = 10) + private String code; + + @Column + @Comment("名称") + @ColDefine(type = ColType.VARCHAR, width = 10) + private String name; + + @Column + @Comment("排序") + @ColDefine(type = ColType.INT) + private Integer sort; + +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/param/OpinionSearchParam.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/param/OpinionSearchParam.java new file mode 100644 index 00000000..53cd5476 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/param/OpinionSearchParam.java @@ -0,0 +1,64 @@ +package com.budwk.app.zhgh.democratic.opinion.param; + +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.utils.PageUtil; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.Cnd; +import org.nutz.dao.util.cri.SqlExpressionGroup; + +/** + * 意见通用搜索 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OpinionSearchParam extends PageForm { + + private String name; + private String code; + private String sessionId; + private String delegationId; + private String createUserName; + private String createUserLoginName; + private String createUserKeyword; + + /** + * 构建通用查询参数 + * + * @param cnd cnd + * @param searchParam searchParam + */ + public static void buildSearch(Cnd cnd, OpinionSearchParam searchParam) { + if (cnd == null) { + cnd = Cnd.NEW(); + } + if (StrUtil.isNotBlank(searchParam.getName())) { + cnd.where().andLike("info.name", searchParam.getName()); + } + if (StrUtil.isNotBlank(searchParam.getCode())) { + cnd.where().andLike("info.code", searchParam.getCode()); + } + cnd.andEX("info.sessionId", "=", searchParam.getSessionId()); + cnd.andEX("info.delegationId", "=", searchParam.getDelegationId()); + if (StrUtil.isNotBlank(searchParam.getCreateUserName())) { + cnd.where().andLike("info.createUserName", searchParam.getCreateUserName()); + } + if (StrUtil.isNotBlank(searchParam.getCreateUserLoginName())) { + cnd.where().andLike("info.createUserLoginName", searchParam.getCreateUserLoginName()); + } + + if (StrUtil.isNotBlank(searchParam.getCreateUserKeyword())) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("info.createUserName", searchParam.getCreateUserKeyword()); + seg.orLike("info.createUserLoginName", searchParam.getCreateUserKeyword()); + cnd.and(seg); + } + + if (StrUtil.isAllNotBlank(searchParam.getPageOrderName(), searchParam.getPageOrderBy())) { + cnd.orderBy(searchParam.getPageOrderName(), PageUtil.getOrder(searchParam.getPageOrderBy())); + } else { + cnd.asc("info.code"); + } + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/OpinionWriteService.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/OpinionWriteService.java new file mode 100644 index 00000000..640fd35d --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/OpinionWriteService.java @@ -0,0 +1,20 @@ +package com.budwk.app.zhgh.democratic.opinion.service; + +import com.budwk.app.base.service.BaseService; +import com.budwk.app.sys.models.Sys_dict; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; + +import java.util.List; + +public interface OpinionWriteService extends BaseService { + + /** + * 生成意见编号 代表团编码+顺序号 + * + * @param sessionId 届次id + * @param delegationId 代表团id + */ + String generateOpinionCode(String sessionId,String delegationId); + +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/common/OpinionCommonService.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/common/OpinionCommonService.java new file mode 100644 index 00000000..8e38f6da --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/common/OpinionCommonService.java @@ -0,0 +1,82 @@ +package com.budwk.app.zhgh.democratic.opinion.service.common; + +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import org.nutz.lang.util.NutMap; + +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.util.List; + +public interface OpinionCommonService extends BaseService { + + /** + * 查询意见信息 + */ + NutMap info(String id); + + /** + * 导出word + * + * @param id + * @param response + */ + void exportOpinionAsDocx(String id, HttpServletResponse response); + + /** + * 导出word + * + * @param id + * @param byteArrayOutputStream + */ + void exportOpinionAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream); + + /** + * 导出单个反馈表 + * + * @param id + * @param byteArrayOutputStream + */ + void exportOpinionFeedBackAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream); + + + /** + * 导出征集表 + * + * @param id + * @param byteArrayOutputStream + */ + void exportCollectAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream); + + /** + * 根据意见id查询团长 + * + * @param proposalId + * @return + */ + String getDelegationHeadByOpinionId(String proposalId); + + /** + * 根据代表团id查询团长 + * + * @param delegationId + * @return + */ + String getDelegationHeadById(String delegationId); + + /** + * 获取自管代表团 + * + * @return + */ + List getSelfManageDelegationIds(); + + /** + * 获取自管承办单位 + * + * @return + */ + ProposalUndertake getSelfManageUndertake(); +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/common/OpinionCommonServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/common/OpinionCommonServiceImpl.java new file mode 100644 index 00000000..14d2aea2 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/common/OpinionCommonServiceImpl.java @@ -0,0 +1,332 @@ +package com.budwk.app.zhgh.democratic.opinion.service.common; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.base.utils.SysOfficeTemplateUtil; +import com.budwk.app.flow.constant.FlowConst; +import com.budwk.app.flow.engine.FlowEngine; +import com.budwk.app.flow.engine.util.FlowUtil; +import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.flow.vo.ProcessTaskVO; +import com.budwk.app.sys.models.Sys_dict; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.models.Sys_user; +import com.budwk.app.sys.models.Sys_user_role; +import com.budwk.app.sys.services.SysDictService; +import com.budwk.app.sys.services.SysRoleService; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.web.commons.base.Globals; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalConsolidation; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalMerge; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; +import lombok.extern.slf4j.Slf4j; +import org.ddr.poi.html.HtmlRenderPolicy; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.FieldFilter; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.Daos; +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 javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@IocBean(args = {"refer:dao"}) +public class OpinionCommonServiceImpl extends BaseServiceImpl implements OpinionCommonService { + + //找出富文本里面上传的图片 + static String IMG_SRC_REGEX = "]*src\\s*=\\s*([\"'])(/platform/sys/file/download\\?id=.*?)\\1[^>]*>"; + + @Inject + private SysRoleService sysRoleService; + @Inject + private SysOfficeTemplateUtil sysOfficeTemplateUtil; + @Inject + private FlowEngine flowEngine; + @Inject + private SysDictService sysDictService; + + public OpinionCommonServiceImpl(Dao dao) { + super(dao); + } + + @Override + public NutMap info(String id) { + if (StrUtil.isBlank(id)) { + throw new BaseException("意见信息不存在"); + } + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName, + tcs.fullName as sessionName, + tcd.unionName, + tcde.NAME AS delegationName + FROM + `opinion_info` info + LEFT JOIN teacher_congress_session tcs ON tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegate tcd ON tcd.userId = info.createUserId + AND tcd.sessionId = info.sessionId + LEFT JOIN teacher_congress_delegation tcde ON tcde.id = tcd.delegationId + LEFT JOIN opinion_type type on type.id = info.typeId + WHERE + info.id = @id + """).setParam("id", id); + NutMap info = (NutMap) dao().execute(sql.setCallback(Sqls.callback.map())).getResult(); + if (StrUtil.isNotBlank(info.getString("suggestUnits"))) { + info.put("suggestUnits", String.join(",", Json.fromJson(ArrayList.class, info.getString("suggestUnits")))); + } + + return info; + } + + @Override + public void exportOpinionAsDocx(String id, HttpServletResponse response) { + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + exportOpinionAsDocx(id, byteArrayOutputStream); + FieldFilter fieldFilter = FieldFilter.create(OpinionInfo.class, "^name|code$"); + OpinionInfo opinionInfo = Daos.ext(dao(), fieldFilter).fetch(OpinionInfo.class, id); + String name = opinionInfo.getName(); + String code = opinionInfo.getCode(); + CommonDownloadUtil.download(code + "-" + name + ".docx", byteArrayOutputStream.toByteArray(), response); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void exportOpinionAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) { + if (id == null || id.isEmpty()) { + throw new BaseException("意见信息不存在"); + } + + //基本信息 + Sql sql = Sqls.create(""" + SELECT + info.name, + info.code, + info.brief, + info.measures, + info.createUserName, + DATE_FORMAT(info.createTime, '%Y年%m月%d日') AS createTime, + info.unitName, + tcde.unitName, + tcde.mobile, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName + FROM + opinion_info info + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName + WHERE info.id = @id + """).setParam("id", id); + sql.setCallback(Sqls.callback.map()); + execute(sql); + NutMap docData = (NutMap) sql.getResult(); + //处理下富文本 + String brief = docData.getString("brief"); + String measures = docData.getString("measures"); + docData.put("brief", sysOfficeTemplateUtil.convertRichTextToDocText(brief)); + docData.put("measures", sysOfficeTemplateUtil.convertRichTextToDocText(measures)); + + // 流程实例 + ProcessInstance processInstance = dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", id)); + + List doneTaskVos = new ArrayList<>(); + List doneTaskList = flowEngine.processTaskService().getDoneTaskList(processInstance.getId(), null); + for (ProcessTask doneTask : doneTaskList) { + ProcessTaskVO taskVO = flowEngine.processTaskService().findById(doneTask.getId()); + doneTaskVos.add(taskVO); + } + + // 按任务节点分组 + Map> taskGroups = doneTaskVos.stream().collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName)); + docData.putAll(taskGroups); + + LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); + HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy(); + htmlRenderPolicy.getConfig().setShowDefaultTableBorderInTableCell(true); + + Configure config = Configure.builder() + .bind("brief", htmlRenderPolicy) + .bind("measures", htmlRenderPolicy) + .bind("taskFormData.tf_opinion", htmlRenderPolicy) + .build(); + + try { + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("opinion"), config).render(docData).writeAndClose(byteArrayOutputStream); + } catch (IOException e) { + log.error("意见导出失败{},提案id:{}", e.getMessage(), id); + } + } + + @Override + public void exportOpinionFeedBackAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) { + if (id == null || id.isEmpty()) { + throw new BaseException("意见信息不存在"); + } + + //基本信息 + Sql sql = Sqls.create(""" + SELECT + info.name, + info.code, + info.measures, + info.createUserName, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + tcs.j, + tcs.c + FROM + opinion_info info + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName + WHERE info.id = @id + """).setParam("id", id); + sql.setCallback(Sqls.callback.map()); + execute(sql); + NutMap info = (NutMap) sql.getResult(); + + // 获取流程实例 + ProcessInstance processInstance = dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", id)); + + HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy(); + htmlRenderPolicy.getConfig().setShowDefaultTableBorderInTableCell(true); + + Configure config = Configure.builder().build(); + try { + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("opinion_feedback"), config).render(info).writeAndClose(byteArrayOutputStream); + } catch (IOException e) { + log.error("意见导出失败{},提案id:{}", e.getMessage(), id); + } + } + + @Override + public void exportCollectAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) { + if (id == null || id.isEmpty()) { + throw new BaseException("意见信息不存在"); + } + + //基本信息 + Sql sql = Sqls.create(""" + SELECT + info.name, + info.code, + info.researchFindings, + info.brief, + info.measures, + info.createUserName, + tcde.unitName, + tcde.mobile, + type.name AS typeName, + tcs.j, + tcs.c, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName + FROM + opinion_info info + LEFT JOIN opinion_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName + WHERE info.id = @id + """).setParam("id", id); + sql.setCallback(Sqls.callback.map()); + execute(sql); + NutMap info = (NutMap) sql.getResult(); + HashMap docData = new HashMap<>(info); + + //处理下富文本 + String brief = info.getString("brief"); + String measures = info.getString("measures"); + info.put("brief", sysOfficeTemplateUtil.convertRichTextToDocText(brief)); + info.put("measures", sysOfficeTemplateUtil.convertRichTextToDocText(measures)); + + // 高校 + info.put("schoolName", Globals.AppName); + + Configure config = Configure.builder().build(); + try { + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("opinion"), config).render(docData).writeAndClose(byteArrayOutputStream); + } catch (IOException e) { + log.error("提案导出失败{},提案id:{}", e.getMessage(), id); + } + + } + + @Override + public String getDelegationHeadByOpinionId(String opinionId) { + OpinionInfo opinionInfo = dao().fetch(OpinionInfo.class, opinionId); + return getDelegationHeadById(opinionInfo.getDelegationId()); + } + + @Override + public String getDelegationHeadById(String delegationId) { + Sys_role sys_role = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_HEAD); + Sys_user_role sys_user_role = dao().fetch(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sys_role.getId()).and(Sys_user_role::getTcDelegationId, "=", delegationId)); + if (ObjectUtil.isEmpty(sys_user_role)) { + throw new BaseException("代表团没有设置团长,无法流转到下一步,请联系管理员进行设置。"); + } + Sys_user sys_user = dao().fetch(Sys_user.class, sys_user_role.getUserId()); + if (ObjectUtil.isEmpty(sys_user)) { + throw new BaseException("代表团没有设置团长,无法流转到下一步,请联系管理员进行设置。"); + } + return sys_user.getLoginname(); + } + + @Override + public List getSelfManageDelegationIds() { + Sys_role role = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_DELEGATION_HEAD.name()); + Sys_role viceRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_VICE_DELEGATION_HEAD.name()); + List sysUserRoles = dao().query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "in", List.of(role.getId(), viceRole.getId())) + .and(Sys_user_role::getUserId, "=", SecurityUtil.getUserId())); + List delegationIds = sysUserRoles.stream() + .map(Sys_user_role::getTcDelegationId) + .filter(StrUtil::isNotBlank) + .toList(); + return delegationIds; + } + + @Override + public ProposalUndertake getSelfManageUndertake() { + Sys_role role = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER.name()); + Sys_user_role userRole = dao().fetch(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", role.getId()) + .and(Sys_user_role::getUserId, "=", SecurityUtil.getUserId())); + if(Lang.isEmpty(userRole)) { + throw new RuntimeException("当前登录用户不是" + role.getName()); + } + return dao().fetch(ProposalUndertake.class, Cnd.where(ProposalUndertake::getId, "=", userRole.getUnderTakeId())); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/impl/OpinionWriteServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/impl/OpinionWriteServiceImpl.java new file mode 100644 index 00000000..4f2e8d81 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/opinion/service/impl/OpinionWriteServiceImpl.java @@ -0,0 +1,57 @@ +package com.budwk.app.zhgh.democratic.opinion.service.impl; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.sys.models.Sys_dict; +import com.budwk.app.sys.services.SysDictService; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.opinion.models.OpinionInfo; +import com.budwk.app.zhgh.democratic.opinion.service.OpinionWriteService; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService; +import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation; +import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; +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 java.util.ArrayList; +import java.util.List; + +@IocBean(args = {"refer:dao"}) +public class OpinionWriteServiceImpl extends BaseServiceImpl implements OpinionWriteService { + + public OpinionWriteServiceImpl(Dao dao) { + super(dao); + } + + @Override + public String generateOpinionCode(String sessionId, String delegationId) { + Teacher_congress_delegation delegation = dao().fetch(Teacher_congress_delegation.class, delegationId); + + Sql sql = Sqls.fetchString(""" + SELECT + MAX( t1.code ) as opinionCode + FROM + opinion_info t1 + WHERE + t1.sessionId = @sessionId + AND t1.delegationId = @delegationId + """); + sql.setParam("sessionId", sessionId); + sql.setParam("delegationId", delegationId); + execute(sql); + String opinionCode = sql.getString(); + if (StrUtil.isBlank(opinionCode)) { + opinionCode = delegation.getCode() + "-" + "01"; + } else { + String s = String.format("%02d", (Convert.toInt(opinionCode.substring(opinionCode.length() - 2))) + 1); + opinionCode = delegation.getCode() + "-" + s; + } + return opinionCode; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/common/TeacherCongressCommonController.java b/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/common/TeacherCongressCommonController.java index 4d21097c..7421d316 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/common/TeacherCongressCommonController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/teachercongress/common/TeacherCongressCommonController.java @@ -5,10 +5,13 @@ import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.result.Result; import com.budwk.app.sys.models.Sys_role; import com.budwk.app.sys.services.SysRoleService; +import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate; import com.budwk.app.zhgh.democratic.teachercongress.delegation.models.Teacher_congress_delegation; import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; +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.mvc.annotation.At; @@ -49,6 +52,23 @@ public class TeacherCongressCommonController { return Result.success(list); } + @At + @SaCheckLogin + public Result listDelegate(String sessionId, String keyWord) { + Cnd cnd = Cnd.NEW(); + cnd.and("sessionId", "=", sessionId); + + SqlExpressionGroup group = new SqlExpressionGroup(); + group.orLike("userName", keyWord); + group.orLike("loginName", keyWord); + cnd.and(group); + + cnd.limit(1, 5); + + List list = dao.query(Teacher_congress_delegate.class, cnd); + return Result.success(list); + } + /** * 代表类型 * @return diff --git a/src/main/resources/static/components/plugins/sysCard/index.vue b/src/main/resources/static/components/plugins/sysCard/index.vue new file mode 100644 index 00000000..b6352758 --- /dev/null +++ b/src/main/resources/static/components/plugins/sysCard/index.vue @@ -0,0 +1,120 @@ + + + + + diff --git a/src/main/resources/views/layouts/v4/baseLayout.html b/src/main/resources/views/layouts/v4/baseLayout.html index e2d0e857..8c5ac578 100644 --- a/src/main/resources/views/layouts/v4/baseLayout.html +++ b/src/main/resources/views/layouts/v4/baseLayout.html @@ -362,6 +362,7 @@ Vue.component("excel-import", httpVueLoader("/components/plugins/sysImport/excelImport.vue?v=" + new Date().getTime())) Vue.component("flow-form-button", httpVueLoader("/components/plugins/flowable/formButton.vue?v=" + new Date().getTime())) Vue.component("snaker-flow", httpVueLoader("/components/plugins/snaker/snakerFlow.vue?v=" + new Date().getTime())) + Vue.component("custom-card", httpVueLoader("/components/plugins/sysCard/index.vue?v=" + new Date().getTime())) Vue.component( "snaker-flow-task-form-action", httpVueLoader("/components/plugins/snaker/snakerFlowTaskFormAction.vue?v=" + new Date().getTime()) diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/common/info.js b/src/main/resources/views/platform/zhgh/democratic/opinion/common/info.js new file mode 100644 index 00000000..080acf11 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/common/info.js @@ -0,0 +1,146 @@ +const OPINION_INFO = { + name: "OpinionInfo", + /*language=HTML*/ + template: ` +
+
+ 意见基础信息 +
+

+ {{ viewData.name }} +

+ + {{ viewData.code }} + {{viewData.createUserName }} + {{ viewData.createTime }} + {{ viewData.sessionName || '暂无' }} + {{ viewData.unitName }} + {{ viewData.delegationName }} + + {{viewData.typeName}} + + + {{viewData.suggestUnits}} + + +
+
+ +
+
+ + + + + + + + +
+ + + + +
+ `, + dicts: ["PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK", "PROPOSAL_REPLY_IMPLEMENT"], + props: { + hide_slave: false + }, + data() { + return { + viewData: {}, + doneTasks: [], + row: null, + } + }, + methods: { + // 打开 + onOpen(row) { + this.row = row + this.visible = true + this.getInfo() + this.getDoneTasks() + }, + + // 获取申请信息 + getInfo() { + this.$axios.post("/platform/opinion/common/opinionInfo", {id: this.row.id}).then((res) => { + if (res.code === 0) { + this.viewData = res.data + } + }) + }, + + // 获取已办任务审批记录 + getDoneTasks() { + this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => { + if (res.code === 0) { + this.doneTasks = res.data + } + }) + }, + + }, + style: + /*language=CSS*/ + ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/config/type/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/config/type/index.html new file mode 100644 index 00000000..ce642f29 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/config/type/index.html @@ -0,0 +1,106 @@ + + +
+ + + + + + + + + + + 新增 + + + + + + + + + + + + + + + + + + + + + +
+ 取消 + 提交 +
+
+
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/feedback/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/feedback/index.html new file mode 100644 index 00000000..eeafc227 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/feedback/index.html @@ -0,0 +1,214 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + 已审核 + 未审核 + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/mine/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/mine/index.html new file mode 100644 index 00000000..c91e0495 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/mine/index.html @@ -0,0 +1,170 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/office/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/office/index.html new file mode 100644 index 00000000..9e33af30 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/office/index.html @@ -0,0 +1,257 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + 已审核 + 未审核 + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/schoolAudit/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/schoolAudit/index.html new file mode 100644 index 00000000..1b18628d --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/schoolAudit/index.html @@ -0,0 +1,278 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + 已审核 + 未审核 + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/schoolSubmit/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/schoolSubmit/index.html new file mode 100644 index 00000000..b929dab6 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/schoolSubmit/index.html @@ -0,0 +1,183 @@ + + +
+ + + + + + + + + + + + + + + + + + + + 一键提交 + + 已审核 + 未审核 + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/summary/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/summary/index.html new file mode 100644 index 00000000..2ad9ada4 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/summary/index.html @@ -0,0 +1,117 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/unitReply/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/unitReply/index.html new file mode 100644 index 00000000..9d820b95 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/unitReply/index.html @@ -0,0 +1,223 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + 已审核 + 未审核 + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/write/form.js b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/write/form.js new file mode 100644 index 00000000..f27bc390 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/write/form.js @@ -0,0 +1,374 @@ +const BASIC_FORM = { + name: "BasicForm", + /*language=HTML*/ + template: ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `, + props: { + school: { + type: Boolean, + default: false, + required: true + } + }, + data() { + return { + bizId: '', + taskId: '', + formData: {}, + sessionOptions: [], + delegationOptions: [], + typeOptions: [], + formRules: { + createUserId: [{required: true, message: "请选择意见人", trigger: ["blur", "change"]}], + createTime: [{required: true, message: "请输入意见时间", trigger: ["blur", "change"]}], + name: [{required: true, message: "请输入意见名称", trigger: ["blur", "change"]}], + delegationId: [{required: true, message: "请选择所属代表团", trigger: ["blur", "change"]}], + sessionId: [{required: true, message: "请选择所属教代会", trigger: ["blur", "change"]}], + typeId: [{required: true, message: "请选择意见类别", trigger: ["blur", "change"]}], + suggestUnits: [{required: true, message: "请选择建议承办单位", trigger: ["blur", "change"]}], + brief: [{required: true, message: "请输入意见和建议", trigger: ["blur", "change"]}], + measures: [{required: true, message: "请输入工作措施", trigger: ["blur", "change"]}], + unitName: [{required: true, message: "请输入单位", trigger: ["blur", "change"]}], + mobile: [{required: true, message: "请输入联系方式", trigger: ["blur", "change"]}], + signature: [{required: false, message: "请扫描二维码进行签字", trigger: ["blur", "change"]}] + }, + // 建议承办单位 + suggestUnitOptions: [], + + tempUserId: '', + } + }, + methods: { + async ready(bizId, taskId) { + this.bizId = bizId + this.taskId = taskId + await this.init() + this.listSuggestUnit() + this.listOpinionType() + this.echoRepresentativeName() + }, + async edit() { + const valid = await this.$refs["addForm"].validate() + if (valid) { + if (!this.formData.name || this.formData.name.trim().length < 1) { + this.$message.warning("请输入意见名称") + return + } + + this.$confirm("您确定要提交吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(() => { + const loading = createLoading('正在提交中') + this.$axios.post('/platform/opinion/schoolAudit/edit', { info: JSON.stringify(this.formData) }).then(res => { + loading.close() + if (res.code === 0) { + this.$message.success("提交成功") + this.$emit('edit') + } + }) + }) + } + }, + userChange(val) { + const user = this.$refs.userSelectRef.options.find(item => item.userId === val) + this.searchDelegation() + this.$set(this.formData, "createUserName", user?.userName) + this.$set(this.formData, "createUserLoginName", user?.loginName) + this.$set(this.formData, "mobile", user?.mobile) + this.$set(this.formData, "unitName", user.unitName) + }, + async onSave() { + const valid = await this.$refs["addForm"].validate() + if (valid) { + if (!this.formData.name || this.formData.name.trim().length < 1) { + this.$message.warning("请输入意见名称") + return + } + + this.$axios.post("/platform/opinion/write/save", {info: JSON.stringify(this.formData)}).then((res) => { + if (res.code === 0) { + this.$message.success(res.msg) + this.formData = res.data + commonUtil.pjaxPush('/platform/opinion/mine') + } + }) + } + }, + // 提交 + async onSubmit() { + const valid = await this.$refs["addForm"].validate() + if (valid) { + if (!this.formData.name || this.formData.name.trim().length < 1) { + this.$message.warning("请输入意见名称") + return + } + + this.$confirm("您确定要提交吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(() => { + const loading = createLoading('正在提交中') + this.$axios.post('/platform/opinion/write/submit', {info: JSON.stringify(this.formData)}).then(res => { + loading.close() + if (res.code === 0) { + this.$message.success("提交成功") + commonUtil.pjaxPush('/platform/opinion/mine') + } + }) + }) + } + }, + // 重新提交 + async onSubmitAgain() { + const valid = await this.$refs["addForm"].validate() + if (valid) { + if (!this.formData.name || this.formData.name.trim().length < 1) { + this.$message.warning("请输入意见名称") + return + } + + this.$confirm("您确定要提交吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(() => { + this.$axios.post('/platform/opinion/write/submitAgain', { + info: JSON.stringify(this.formData), + taskId: GetQueryString("taskId") + }).then(res => { + if (res.code === 0) { + this.$message.success("提交成功") + commonUtil.pjaxPush('/platform/opinion/mine') + } + }) + }) + } + }, + // 获取意见类别 + listOpinionType() { + this.$axios.post("/platform/opinion/common/listOpinionType").then((res) => { + if (res.code === 0) { + this.typeOptions = res.data + } + }) + }, + //教代会change + async meetingChange(val) { + this.formData.delegationId = null + this.formData.committeeId = null + this.listDelegation() + this.searchDelegation() + }, + // 建议承办单位 + listSuggestUnit() { + this.$axios.post("/platform/opinion/common/listUnderTake").then((res) => { + if (res.code === 0) { + this.suggestUnitOptions = res.data + } + }) + }, + // 获取代表团 + listDelegation() { + return this.$axios.post("/platform/opinion/common/listDelegation", {sessionId: this.formData.sessionId}).then((res) => { + if (res.code === 0) { + this.delegationOptions = res.data + } + }) + }, + // 查询开启的教代会 + listOpenSession(isModify = false) { + this.$axios.post("/platform/opinion/common/listOpenSession").then(async (res) => { + if (res.code === 0) { + this.sessionOptions = res.data + if (!isModify && this.sessionOptions) { + this.$set(this.formData, "sessionId", this.sessionOptions[0].id) + // 获取代表团 + await this.searchDelegation() + } + await this.listDelegation() + } + }) + }, + //查询代表的代表团 + searchDelegation() { + return this.$axios.post("/platform/opinion/write/searchDelegation", { + sessionId: this.formData.sessionId, + userId: this.formData.createUserId + }).then((res) => { + if (res.code === 0) { + this.$set(this.formData, "delegationId", res.data) + } + }) + }, + async init() { + // 清空显示值 + this.$set(this.formData, "createUserId", ''); + if (this.bizId) { + const res = await this.$axios.post("/platform/opinion/write/detail", {id: this.bizId}) + if (res.code === 0) { + this.formData = res.data + this.tempUserId = this.formData.createUserId; + this.listOpenSession(true) + } + } else { + this.listOpenSession(false) + + // 临时存储用户ID + this.tempUserId = this.$store.state.user.id; + + this.$set(this.formData, "createUserName", this.$store.state.user.username) + this.$set(this.formData, "createUserLoginName", this.$store.state.user.loginname) + this.$set(this.formData, "createTime", this.$moment().format("YYYY-MM-DD")) + this.$set(this.formData, "mobile", this.$store.state.user.mobile) + this.$set(this.formData, "unitName", this.$store.state.user.unit?.name) + } + }, + // 回显代表姓名 + echoRepresentativeName() { + const checkRefAndSet = () => { + if (this.$refs.userSelectRef) { + // 1. 设置options + this.$refs.userSelectRef.options = [{ + userId: this.tempUserId || this.$store.state.user.id, + userName: this.formData.createUserName || this.$store.state.user.username, + loginName: this.formData.createUserLoginName || this.$store.state.user.loginname + }]; + // 2. 延迟赋值,确保options已生效 + this.$nextTick(() => { + this.$set(this.formData, "createUserId", this.tempUserId || this.$store.state.user.id); + }); + } else { + setTimeout(checkRefAndSet, 50); + } + }; + + this.$nextTick(() => { + checkRefAndSet(); + }); + }, + }, + mounted() { + this.$emit('ready') + }, + style: + /*language=CSS*/ + ` + + ` +} diff --git a/src/main/resources/views/platform/zhgh/democratic/opinion/transact/write/index.html b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/write/index.html new file mode 100644 index 00000000..a18f5024 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/opinion/transact/write/index.html @@ -0,0 +1,49 @@ + + + + +
+ + + + + + + + +
+ + +