From c5fbf8576c004d04d7a3f56e352ffdad3a5ec87e Mon Sep 17 00:00:00 2001 From: Paidax Date: Fri, 20 Mar 2026 15:09:35 +0800 Subject: [PATCH] =?UTF-8?q?git=E6=9F=A5=E7=9C=8B=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../budwk/app/base/utils/FileExcelUtil.java | 99 +++ .../budwk/app/base/utils/FileWordUtil.java | 81 ++ .../app/flow/service/FlowCommonService.java | 53 +- .../app/flow/service/ProcessTaskService.java | 8 + .../service/impl/ProcessTaskServiceImpl.java | 10 + .../app/sys/services/SysUserService.java | 1 + .../sys/services/impl/SysUserServiceImpl.java | 9 + .../app/web/controllers/BasicsController.java | 51 ++ .../proposal/constants/ProposalState.java | 79 ++ .../common/ProposalCommonController.java | 2 +- .../ProposalAllFinishedController.java | 82 ++ .../transact/ProposalCaseCheckController.java | 106 +++ ...ProposalCommitteeFilingUnitController.java | 232 +++--- .../transact/ProposalMineController.java | 43 + .../transact/ProposalPreAuditController.java | 107 +++ ...roposalSchoolLeaderApprovalController.java | 12 +- .../transact/ProposalSecondedController.java | 62 +- .../ProposalUnSubmitQueryController.java | 103 +++ .../ProposalUnderTakeReplyController.java | 1 + .../transact/ProposalWriteController.java | 56 ++ ...ProposalSchoolLeaderAssignmentHandler.java | 55 ++ .../proposal/models/ProposalSecond.java | 4 + .../service/ProposalWriteService.java | 5 + .../service/common/ProposalCommonService.java | 12 + .../common/ProposalCommonServiceImpl.java | 222 ++++- .../impl/ProposalWriteServiceImpl.java | 191 ++++- .../platform/js/mixin/initTableMixins.js | 25 + .../templates/proposal/export/proposal.docx | Bin 0 -> 15180 bytes .../templates/proposal/proposal.xlsx | Bin 0 -> 12033 bytes .../proposal/transact/allFinished/index.html | 108 +++ .../proposal/transact/caseCheck/index.html | 202 +++++ .../transact/committeeFilingUnit/index.html | 760 ++++++++---------- .../proposal/transact/delegation/index.html | 1 + .../proposal/transact/mine/index.html | 131 ++- .../proposal/transact/preAudit/index.html | 179 +++++ .../proposal/transact/seconded/index.html | 26 +- .../transact/unSubmitQuery/index.html | 161 ++++ .../proposal/transact/unitReply/index.html | 88 +- .../proposal/transact/write/index.html | 166 +++- 39 files changed, 2924 insertions(+), 609 deletions(-) create mode 100644 src/main/java/com/budwk/app/base/utils/FileExcelUtil.java create mode 100644 src/main/java/com/budwk/app/base/utils/FileWordUtil.java create mode 100644 src/main/java/com/budwk/app/web/controllers/BasicsController.java create mode 100644 src/main/java/com/budwk/app/zhgh/democratic/proposal/constants/ProposalState.java create mode 100644 src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalAllFinishedController.java create mode 100644 src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java create mode 100644 src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java create mode 100644 src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnSubmitQueryController.java create mode 100644 src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalSchoolLeaderAssignmentHandler.java create mode 100644 src/main/resources/templates/proposal/export/proposal.docx create mode 100644 src/main/resources/templates/proposal/proposal.xlsx create mode 100644 src/main/resources/views/platform/zhgh/democratic/proposal/transact/allFinished/index.html create mode 100644 src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html create mode 100644 src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html create mode 100644 src/main/resources/views/platform/zhgh/democratic/proposal/transact/unSubmitQuery/index.html diff --git a/src/main/java/com/budwk/app/base/utils/FileExcelUtil.java b/src/main/java/com/budwk/app/base/utils/FileExcelUtil.java new file mode 100644 index 00000000..72b15d9f --- /dev/null +++ b/src/main/java/com/budwk/app/base/utils/FileExcelUtil.java @@ -0,0 +1,99 @@ +package com.budwk.app.base.utils; + +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @version 1.0 + * @Author FKY + * @name:FileExcelUtil + * @Date 2026/1/31 15:33 + * @注释 + */ +@Slf4j +public class FileExcelUtil { + + public static Map readExcelTable(File file){ + Map dataMap = new HashMap<>(); + try { + FileInputStream fis = new FileInputStream(file); + Workbook workbook = new XSSFWorkbook(fis); + + Sheet sheet = workbook.getSheetAt(0); + + // 遍历所有行 + for (Row row : sheet) { + int rowColumnIndex = 0 ; + String keyName = ""; + String keyValue = ""; + + // 遍历所有单元格 + for (Cell cell : row) { + String cellValue = String.valueOf(getCellValue(cell)); + + log.info("| " + cellValue + " "); + + if((rowColumnIndex % 2) <= 0) { + keyName = cellValue; + } else { + keyValue = cellValue; + } + if(StrUtil.isNotBlank(keyName) && StrUtil.isNotBlank(keyValue)) { + if(keyName.contains("*")) { + keyName = keyName.replace("*", ""); + } + dataMap.put(keyName, keyValue); + keyName = ""; + keyValue = ""; + } + rowColumnIndex ++; + } + } + }catch (Exception e) { + e.printStackTrace(); + } + return dataMap; + } + + public static Object getCellValue(Cell cell) { + CellType cellType = cell.getCellType(); + + if (cellType == CellType.FORMULA) { + cellType = cell.getCachedFormulaResultType(); + } + + switch (cellType) { + case STRING: + return cell.getStringCellValue(); + case NUMERIC: + if (isCellDateType(cell)) { + return cell.getDateCellValue(); + } + return cell.getNumericCellValue(); + case BOOLEAN: + return cell.getBooleanCellValue(); + case BLANK: + return ""; + default: + return ""; + } + } + + public static Boolean isCellDateType(Cell cell) { + try { + cell.getDateCellValue(); + } catch (Exception e) { + return false; + } + return true; + } +} diff --git a/src/main/java/com/budwk/app/base/utils/FileWordUtil.java b/src/main/java/com/budwk/app/base/utils/FileWordUtil.java new file mode 100644 index 00000000..4c8af936 --- /dev/null +++ b/src/main/java/com/budwk/app/base/utils/FileWordUtil.java @@ -0,0 +1,81 @@ +package com.budwk.app.base.utils; + +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.apache.poi.xwpf.usermodel.XWPFTableRow; + +import java.io.File; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @version 1.0 + * @Author FKY + * @name:FileWordUtil + * @Date 2026/1/31 15:01 + * @注释 + */ +@Slf4j +public class FileWordUtil { + + public static List> readWordTable(File file) { + List> dataMaps = new ArrayList<>(); + try{ + FileInputStream fis = new FileInputStream(file); + XWPFDocument document = new XWPFDocument(fis); + + // 获取所有表格 + List tables = document.getTables(); + log .info("文档中共有 " + tables.size() + " 个表格"); + + // 遍历每个表格 + for (int t = 0; t < tables.size(); t++) { + log.info("\n--- 表格 " + (t + 1) + " ---"); + XWPFTable table = tables.get(t); + Map dataMap = new HashMap<>(); + + // 遍历表格的每一行 + for (XWPFTableRow row : table.getRows()) { + int rowColumnIndex = 0 ; + String keyName = ""; + String keyValue = ""; + // 遍历行中的每个单元格 + for (XWPFTableCell cell : row.getTableCells()) { + // 获取单元格文本并打印 + String cellText = cell.getText(); + log.info("| " + cellText + " "); + if((rowColumnIndex % 2) <= 0) { + keyName = cellText; + } else { + keyValue = cellText; + } + if(StrUtil.isNotBlank(keyName) && StrUtil.isNotBlank(keyValue)) { + if(keyName.contains("*")) { + keyName = keyName.replace("*", ""); + } + + dataMap.put(keyName, keyValue); + keyName = ""; + keyValue = ""; + } + rowColumnIndex ++; + } + log.info("|"); // 换行 + } + if(!dataMap.isEmpty()){ + dataMaps.add(dataMap); + } + } + } catch (Exception e) { + e.printStackTrace(); + log.error("读取word文件出错",e); + } + return dataMaps; + } +} diff --git a/src/main/java/com/budwk/app/flow/service/FlowCommonService.java b/src/main/java/com/budwk/app/flow/service/FlowCommonService.java index bd6b9010..10f18aca 100644 --- a/src/main/java/com/budwk/app/flow/service/FlowCommonService.java +++ b/src/main/java/com/budwk/app/flow/service/FlowCommonService.java @@ -3,19 +3,34 @@ package com.budwk.app.flow.service; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; import com.budwk.app.base.event.flow.jumptofirsttask.FlowJumpToFirstTaskNodePublisher; +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.enums.ProcessSubmitTypeEnum; +import com.budwk.app.flow.engine.event.ProcessEvent; +import com.budwk.app.flow.engine.event.ProcessPublisher; +import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.*; import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import java.util.List; + @IocBean public class FlowCommonService { @Inject private FlowEngine flowEngine; + @Inject + private Dao dao; + /** * 执行任务 * @param args @@ -70,4 +85,40 @@ public class FlowCommonService { } } + @Aop(TransAop.READ_COMMITTED) + public Result revokeTask(Long taskId) { + // 自己任务 + ProcessTask selfTask = dao.fetch(ProcessTask.class, taskId); + selfTask.setTaskState(ProcessTaskStateEnum.DOING.getCode()); + + // 撤销任务 + List taskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskParentId, "=", taskId)); + for (ProcessTask task : taskList) { + task.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode()); + dao.update(task); + } + // 会签并行任务 撤销后续任务 + if (selfTask.getPerformType().equals(ProcessTaskPerformTypeEnum.COUNTERSIGN.getCode())) { + List doingTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.DOING.getCode()) + .and(ProcessTask::getProcessInstanceId, "=", selfTask.getProcessInstanceId())); + for (ProcessTask doingTask : doingTasks) { + doingTask.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode()); + dao.update(doingTask); + } + } + + // 激活 + dao.update(selfTask); + + // 流程激活 + dao.update(ProcessInstance.class, Chain.make("state", ProcessInstanceStateEnum.DOING.getCode()),Cnd.where(ProcessInstance::getId, "=", selfTask.getProcessInstanceId())); + + // 发送任务撤回事件 确保上面执行成功 + for (ProcessTask task : taskList) { + ProcessPublisher.notify(ProcessEvent.builder().eventType(ProcessEventTypeEnum.PROCESS_TASK_REVOKE).sourceId(task.getId()).build()); + } + + return Result.success(); + } + } diff --git a/src/main/java/com/budwk/app/flow/service/ProcessTaskService.java b/src/main/java/com/budwk/app/flow/service/ProcessTaskService.java index 44b298a9..6cd7c226 100644 --- a/src/main/java/com/budwk/app/flow/service/ProcessTaskService.java +++ b/src/main/java/com/budwk/app/flow/service/ProcessTaskService.java @@ -211,4 +211,12 @@ public interface ProcessTaskService extends BaseService { */ List getDoingTaskByBizIdTaskName(List bizIds, String taskName); + /** + * 获取已结束的任务 + * + * @param bizIds 业务ID + * @param taskName 任务名称 + * @return + */ + List getDoneTaskByBizIdTaskName(List bizIds, String taskName); } diff --git a/src/main/java/com/budwk/app/flow/service/impl/ProcessTaskServiceImpl.java b/src/main/java/com/budwk/app/flow/service/impl/ProcessTaskServiceImpl.java index 943a009d..39a4e18b 100644 --- a/src/main/java/com/budwk/app/flow/service/impl/ProcessTaskServiceImpl.java +++ b/src/main/java/com/budwk/app/flow/service/impl/ProcessTaskServiceImpl.java @@ -87,6 +87,16 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl impleme return vo; } + @Override + public List getDoneTaskByBizIdTaskName(List bizIds, String taskName) { + List instances = dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", bizIds)); + List instanceIds = instances.stream().map(ProcessInstance::getId).toList(); + List tasks = dao().query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instanceIds) + .and(ProcessTask::getTaskName, "=", taskName) + .and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.FINISHED.getCode())); + return tasks; + } + @Override @Aop(TransAop.READ_COMMITTED) public void saveProcessTask(ProcessTask processTask) { diff --git a/src/main/java/com/budwk/app/sys/services/SysUserService.java b/src/main/java/com/budwk/app/sys/services/SysUserService.java index 29e6fdc2..2cce57f7 100644 --- a/src/main/java/com/budwk/app/sys/services/SysUserService.java +++ b/src/main/java/com/budwk/app/sys/services/SysUserService.java @@ -197,4 +197,5 @@ public interface SysUserService extends BaseService { */ String loginPlus(Sys_user user, LoginType loginType, HttpServletRequest request); + Sys_user getByLoginName(String loginName); } diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java index 28ec5dc8..e1cde543 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java @@ -449,4 +449,13 @@ public class SysUserServiceImpl extends BaseServiceImpl implements Sys return Globals.AppDomain + "/platform/home"; } } + + @Override + public Sys_user getByLoginName(String loginName) { + Sql sql = Sqls.create("select * from sys_user where loginname = @loginname"); + sql.params().set("loginname", loginName); + sql.setCallback(Sqls.callback.record()); + this.dao().execute(sql); + return sql.getObject(Sys_user.class); + } } diff --git a/src/main/java/com/budwk/app/web/controllers/BasicsController.java b/src/main/java/com/budwk/app/web/controllers/BasicsController.java new file mode 100644 index 00000000..a6cc7656 --- /dev/null +++ b/src/main/java/com/budwk/app/web/controllers/BasicsController.java @@ -0,0 +1,51 @@ +package com.budwk.app.web.controllers; + +import org.apache.commons.io.IOUtils; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.log.Log; +import org.nutz.log.Logs; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; + +/** + * @Author: 1V + * @DateTime: 2020/12/3 8:50 + * @Description: TODO + */ +@At("/platform/basics") +@IocBean +@Ok("json") +public class BasicsController { + private static final Log log = Logs.get(); + + private final String TEMPLATE_PATH = "templates"; + + /** + * 下载模板文件 + * + * @param filePath + * @param fileName + * @param response + */ + @At + public void downloadTemplate(String filePath, String fileName, HttpServletResponse response) throws IOException { + try { + response.setHeader("Content-Disposition", "attachment;filename=" + .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8")))); + + if (filePath.startsWith("/")) { + filePath = filePath.substring(1); + } + InputStream fin = Thread.currentThread().getContextClassLoader().getResourceAsStream(TEMPLATE_PATH + "/" + filePath); + + IOUtils.copy(fin, response.getOutputStream()); + } catch (Exception e) { + log.error(e); + } + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/constants/ProposalState.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/constants/ProposalState.java new file mode 100644 index 00000000..1dea11fb --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/constants/ProposalState.java @@ -0,0 +1,79 @@ +package com.budwk.app.zhgh.democratic.proposal.constants; + +/** + * @author: Aaron + * @create: 2021-01-27 09:54 + * @description: 提案状态 + **/ +public interface ProposalState { + + /** + * 未提交 + */ + Integer UNSUBMIT = 100; + + /** + * 邀请附议人 + */ + Integer INVIRTE = 150; + + /** + * 待团长审核 + */ + Integer DELEGATION = 200; + + /** + * 预审核 + */ + Integer PREAUDIT = 250; + + /** + * 待提案委员会立案审核 + */ + Integer CASE = 300; + + /** + * 执委会建议 + */ + Integer EXECUTORREAD = 310; + + /** + * 分管校领导建议 + */ + Integer BRANCHLEADERREAD = 320; + + /** + * 校长、书记建议 + */ + Integer PRINCIPALREAD = 330; + + /** + * 待提案委员会确认承办单位 + */ + Integer CASEUNIT = 400; + + /** + * 待承办单位答复 + */ + Integer UNITREPLY = 500; + + /** + * 待承办单位分管校领导审批 + */ + Integer LEADERAUDIT = 600; + + /** + * 待反馈评分 + */ + Integer FEEDBACKSCORE = 700; + + /** + * 待提案委员会审查 + */ + Integer CASE_CHECK = 800; + + /** + * 已完结 + */ + Integer FINISH = 900; +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/common/ProposalCommonController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/common/ProposalCommonController.java index 7e6cac3d..306a5543 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/common/ProposalCommonController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/common/ProposalCommonController.java @@ -102,7 +102,7 @@ public class ProposalCommonController { @Ok("void") @SaCheckPermission("proposal") public void exportProposalAsDocx(String id, HttpServletResponse response) { - proposalCommonService.exportProposalAsDocx(id, response); + proposalCommonService.exportProposalAsDocx(id, response); } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalAllFinishedController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalAllFinishedController.java new file mode 100644 index 00000000..d6d3016a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalAllFinishedController.java @@ -0,0 +1,82 @@ +package com.budwk.app.zhgh.democratic.proposal.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.base.service.BaseService; +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.proposal.param.ProposalSearchParam; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.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; +import java.util.List; + +/** + * @version 1.0 + * @Author FKY + * @name:ProposalAllFinishedController + * @Date 2026/3/17 15:33 + * @注释 + */ +@IocBean +@At("/platform/proposal/all/finished") +@Slf4j +@Ok("json:full") +@Api(tags = "提案管理-办结") +public class ProposalAllFinishedController { + + @Inject + private BaseService baseService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/proposal/transact/allFinished/index.html") + @SaCheckPermission("proposal.mine") + public void index() { + } + + @At + @SaCheckPermission("proposal.allFinishedQuery") + @ApiOperation("分页列表") + public Result pageData(@Valid ProposalSearchParam pageForm, 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 + FROM wf_process_instance ins + LEFT JOIN proposal_info info ON info.id = ins.businessNo + LEFT JOIN proposal_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 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("ins.state", "=", "20"); + + if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + } + ProposalSearchParam.buildSearch(cnd, pageForm); + sql.setCondition(cnd); + Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql); + return Result.success(pagination); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java new file mode 100644 index 00000000..98e6f06c --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java @@ -0,0 +1,106 @@ +package com.budwk.app.zhgh.democratic.proposal.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.base.service.BaseService; +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.proposal.param.ProposalSearchParam; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.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; +import java.util.List; + +/** + * @version 1.0 + * @Author FKY + * @name:ProposalCaseCheckController + * @Date 2026/3/17 13:35 + * @注释 + */ +@IocBean +@At("/platform/proposal/case/check") +@Slf4j +@Ok("json:full") +@Api(tags = "提案管理-提案委员会审查") +public class ProposalCaseCheckController { + + @Inject + private BaseService baseService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/proposal/transact/caseCheck/index.html") + @SaCheckPermission("proposal.mine") + public void index() { + } + + @At + @SaCheckPermission("proposal.caseCheck") + @ApiOperation("分页列表") + public Result pageData(@Valid ProposalSearchParam pageForm, 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 wf_process_task_actor ta ON ta.processTaskId = t.id + 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 proposal_info info ON info.id = ins.businessNo + LEFT JOIN proposal_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 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("t.taskName", "=", "caseCheck"); + + if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ + 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()); + } + ProposalSearchParam.buildSearch(cnd, pageForm); + cnd.groupBy("t.id"); + cnd.desc("t.createdAt"); + sql.setCondition(cnd); + Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql); + return Result.success(pagination); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java index 6fb61a6a..283360e7 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java @@ -1,23 +1,26 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; +import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.json.JSONObject; -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.result.Result; import com.budwk.app.base.service.BaseService; -import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum; -import com.budwk.app.bpm.models.BpmProcessTask; -import com.budwk.app.bpm.service.BpmService; +import com.budwk.app.flow.constant.FlowConst; +import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.entity.ProcessTaskActor; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.flow.service.FlowCommonService; +import com.budwk.app.flow.service.ProcessTaskService; import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; -import com.budwk.app.zhgh.democratic.proposal.controller.vo.ProposalInfoPageVO; -import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; -import com.budwk.app.zhgh.democratic.proposal.param.ProposalCommitteeFilingUnitApprovalParam; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.service.ProposalCommitteeFilingUnitService; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -25,10 +28,10 @@ import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Cnd; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; -import org.nutz.dao.util.cri.Static; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; @@ -46,10 +49,15 @@ public class ProposalCommitteeFilingUnitController { @Inject private BaseService baseService; @Inject - private BpmService bpmService; - @Inject private ProposalCommitteeFilingUnitService proposalCommitteeFilingUnitService; + @Inject + private ProposalCommonService proposalCommonService; + @Inject + private FlowCommonService flowCommonService; + @Inject + private ProcessTaskService processTaskService; + @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html") @SaCheckPermission("proposal.committeeFilingUnit") @@ -64,123 +72,143 @@ public class ProposalCommitteeFilingUnitController { SELECT info.*, type.name AS typeName, - tcs.fullName AS sessionName, - tcd.`name` AS delegationName, - inst.id processInstanceId, - inst.processInstanceNodeId, - inst.processInstanceNodeName, - inst.processInstanceTaskIds, - inst.processInstanceStatus, - task.id processInstanceTaskId, - task.taskStatus processInstanceTaskStatus, - COUNT(p.consolidationIds) > 0 AS isConsolidation, - EXISTS ( - SELECT 1 - FROM bpm_process_task next_task - WHERE next_task.prevTaskId = task.id - AND next_task.taskStatus = 'COMPLETE' - ) AS nextTaskIsComplete + IF(mer.proposalId IS NOT NULL, 1, 0) AS merge, + 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 OR (ins.state = 20 AND info.caseFilingResult = 'NOT'), 1, 0) AS canRevoke FROM - bpm_process_task task - INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId - INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId - INNER JOIN proposal_info info ON info.id = inst.processInstanceBusinessId - LEFT JOIN proposal_consolidation p ON JSON_CONTAINS(p.consolidationIds, JSON_QUOTE(info.id)) + wf_process_task t + LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + 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 proposal_info info ON info.id = ins.businessNo LEFT JOIN proposal_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 bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE' + LEFT JOIN proposal_merge mer ON mer.proposalId = info.id + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId $condition """); Cnd cnd = Cnd.NEW(); + cnd.and("t.taskName", "=", "committeeFilingUnit"); if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { - cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname()))); + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); } - cnd.and("nd.nodeCode", "=", 70); if (approval) { - cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE); + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); } else { - cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE); + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); } ProposalSearchParam.buildSearch(cnd, pageForm); - cnd.and(new Static(""" - NOT EXISTS( - SELECT 1 - FROM bpm_process_task t2 - WHERE t2.processInstanceId = task.processInstanceId - AND t2.processTaskNodeCode = task.processTaskNodeCode - AND t2.createdOn > task.createdOn - ) - """)); - cnd.groupBy("info.id"); - cnd.groupBy("task.id"); + cnd.groupBy("t.id"); + cnd.desc("t.createdAt"); sql.setCondition(cnd); - Pagination pagination = baseService.listPageVO(pageForm, sql, ProposalInfoPageVO.class); + Pagination pagination = proposalCommitteeFilingUnitService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return Result.success(pagination); } @At @SaCheckPermission("proposal.committeeFilingUnit") + @ApiOperation("执行任务") @Aop(TransAop.READ_COMMITTED) - @SLog(tag = "委员会确认承办单位", msg = "委员会确认承办单位") - @ApiOperation("委员会确认承办单位") - public Result approval(@Valid @Param("approval") ProposalCommitteeFilingUnitApprovalParam approvalParam) { - proposalCommitteeFilingUnitService.approval(approvalParam); - return Result.success(); - } + public Result executeTask(@Param("data") String data) { + Dict args = Json.fromJson(Dict.class, data); + String proposalId = args.getStr("proposalId"); - @At - @SaCheckPermission("proposal.committeeFilingUnit") - @Aop(TransAop.READ_COMMITTED) - @SLog(tag = "委员会确认承办单位", msg = "委员会确认承办单位撤回") - public Result revoke(@Valid String taskId) { - proposalCommitteeFilingUnitService.revoke(taskId); - return Result.success(); - } + // 查询是否提案 - @At - @SaCheckPermission("proposal.committeeFilingUnit") - @ApiOperation("查询立案的结果及承办单位") - public Result committeeFiling(@Valid String processInstanceId, @Valid String processInstanceTaskId) { - JSONObject newJson = new JSONObject(); - - BpmProcessTask caseUnitTask = proposalCommitteeFilingUnitService.dao().fetch(BpmProcessTask.class, - Cnd.where(BpmProcessTask::getId, "=", processInstanceTaskId) - .and(BpmProcessTask::getProcessInstanceId, "=", processInstanceId) - .and(BpmProcessTask::getProcessTaskNodeCode, "=", 70) - .and(BpmProcessTask::getDelFlag, "=", 0) - ); - if (ObjectUtil.isNotNull(caseUnitTask) && ObjectUtil.isNotEmpty(caseUnitTask.getExtVariable())) { - JSONObject jsonObject = caseUnitTask.getExtVariable(); - newJson.set("caseFilingResult", jsonObject.get("caseFilingResult")); - newJson.set("hostUnitId", jsonObject.get("hostUnitId")); - newJson.set("helpUnitIds", jsonObject.getBeanList("helpUnitIds", String.class)); - newJson.set("approvalOpinion", jsonObject.get("approvalOpinion")); - newJson.set("consolidationIds", jsonObject.getBeanList("consolidationIds", String.class)); - return Result.success(newJson); + // 单条审核 + List mergeProposalIds = proposalCommonService.mergeProposal(proposalId); + if (ObjectUtil.isEmpty(mergeProposalIds)) { + flowCommonService.executeTask(args); + return Result.success(); } - BpmProcessTask caseTask = proposalCommitteeFilingUnitService.dao().fetch(BpmProcessTask.class, - Cnd.where(BpmProcessTask::getProcessInstanceId, "=", processInstanceId) - .and(BpmProcessTask::getDelFlag, "=", 0) - .and(BpmProcessTask::getProcessTaskNodeCode, "=", 60) - .desc(BpmProcessTask::getCreatedOn) - ); - JSONObject jsonObject = caseTask.getExtVariable(); - newJson.set("caseFilingResult", jsonObject.get("caseFilingResult")); - newJson.set("hostUnitId", jsonObject.get("hostUnitId")); - newJson.set("helpUnitIds", jsonObject.getBeanList("helpUnitIds", String.class)); - newJson.set("approvalOpinion", jsonObject.get("approvalOpinion")); - newJson.set("consolidationIds", jsonObject.getBeanList("consolidationIds", String.class)); - return Result.success(newJson); + // 并案审核 + ProcessTask thisTask = baseService.dao().fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY)); + List mergeTasks = processTaskService.getDoingTaskByBizIdTaskName(mergeProposalIds, thisTask.getTaskName()); + for (ProcessTask mergeTask : mergeTasks) { + Dict cloneArgs = args.clone(); + cloneArgs.put(FlowConst.PROCESS_TASK_ID_KEY, mergeTask.getId()); + flowCommonService.executeTask(cloneArgs); + } + + ProposalInfo info = proposalCommonService.fetch(proposalId); + info.setCaseFilingResult(args.getStr("caseFilingResult")); + return Result.success(); } + + @At + @SaCheckLogin + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("撤销任务") + public Result revokeTask(@Param("taskId") Long taskId,@Param("proposalId")String proposalId) { + // 单条审核 + List mergeProposalIds = proposalCommonService.mergeProposal(proposalId); + if (ObjectUtil.isEmpty(mergeProposalIds)) { + flowCommonService.revokeTask(taskId); + return Result.success(); + } + // 并案审核 + ProcessTask thisTask = baseService.dao().fetch(ProcessTask.class, taskId); + List mergeTasks = processTaskService.getDoneTaskByBizIdTaskName(mergeProposalIds, thisTask.getTaskName()); + for (ProcessTask mergeTask : mergeTasks) { + flowCommonService.revokeTask(mergeTask.getId()); + } + return Result.success(); + } + + @At @SaCheckPermission("proposal.committeeFilingUnit") - @ApiOperation("查询承办单位") - public Result listUnderTake() { - List list = baseService.dao().query(ProposalUndertake.class, Cnd.NEW().asc(ProposalUndertake::getCode)); - return Result.success(list); + public Result doUpData(){ + List tasks = baseService.dao().query(ProcessTask.class, Cnd.where("taskName", "=", "personnelOffice")); + List list = tasks.stream().map(ProcessTask::getId).toList(); + + List actorList = baseService.dao().query(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "in", list)); + + List instanceList = baseService.dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getProcessDefineId, "=", 396)); + + for (ProcessTask task : tasks) { + task.setTaskName("committee"); + task.setDisplayName("提案委员会立案"); + task.setFormKey("/platform/proposal/committee"); + task.setH5FormKey(""); + } + + for (ProcessTaskActor actor : actorList) { + actor.setActorId("1fb89886bf4c43dcb48409c83d3363c3"); + actor.setActorAccount("018054"); + actor.setActorName("赵丽霞"); + actor.setActorUnitName("工会"); + actor.setActorUnitId("0011"); + } + + for (ProcessInstance instance : instanceList) { + instance.setProcessDefineId(400L); + } + + baseService.update(tasks); + baseService.update(actorList); + baseService.update(instanceList); + + return Result.success(); } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java index fc560560..538aaca7 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalMineController.java @@ -1,6 +1,7 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; @@ -9,6 +10,8 @@ import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.result.Result; +import com.budwk.app.base.utils.FileExcelUtil; +import com.budwk.app.base.utils.FileWordUtil; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.FlowEngine; import com.budwk.app.flow.entity.ProcessInstance; @@ -38,13 +41,19 @@ import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; import org.nutz.lang.util.NutMap; +import org.nutz.mvc.annotation.AdaptBy; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import org.nutz.mvc.upload.TempFile; +import org.nutz.mvc.upload.UploadAdaptor; import javax.validation.Valid; +import java.io.File; +import java.io.IOException; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.Objects; @IocBean @@ -83,6 +92,7 @@ public class ProposalMineController { Sql sql = Sqls.create(""" SELECT info.*, + sd.name as sourceName, type.name AS typeName, tcs.fullName AS sessionName, tcd.`name` AS delegationName, @@ -110,6 +120,7 @@ public class ProposalMineController { 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 + left join sys_dict sd on sd.code = info.source $condition """); @@ -372,5 +383,37 @@ public class ProposalMineController { return Result.success(); } + @At + @AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"}) + @Aop(TransAop.READ_COMMITTED) + public Object importProposal(TempFile file, String templateType) throws Exception { + if (file == null) { + return Result.error("文件不能为空!"); + } + String name = file.getSubmittedFileName(); + String suffix = FileUtil.getSuffix(name); + if(!List.of("xls", "xlsx", "docx", "doc").contains(suffix.toLowerCase())) { + throw new RuntimeException("文件格式错误: 不支持该文件{" + suffix + "}导入!"); + } + // word docx 文件导入 + if(templateType.equals("2")) { + List> dataMaps = FileWordUtil.readWordTable(file.getFile()); + if(dataMaps == null || dataMaps.size() == 0) { + throw new RuntimeException("文件内容错误: 文件内容不能为空!"); + } + for (Map dataMap : dataMaps) { + proposalCommonService.importProposal(dataMap); + } + + // excel xlsx 文件导入 + } else { + Map dataMap = FileExcelUtil.readExcelTable(file.getFile()); + if(dataMap == null || dataMap.size() == 0) { + throw new RuntimeException("文件内容错误: 文件内容不能为空!"); + } + proposalCommonService.importProposal(dataMap); + } + return Result.success(); + } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java new file mode 100644 index 00000000..1409bd6a --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java @@ -0,0 +1,107 @@ +package com.budwk.app.zhgh.democratic.proposal.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.base.service.BaseService; +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.proposal.param.ProposalSearchParam; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.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; +import java.util.List; + +/** + * @version 1.0 + * @Author FKY + * @name:ProposalPreAuditController + * @Date 2026/3/16 17:30 + * @注释 + */ +@IocBean +@At("/platform/proposal/pre/audit") +@Slf4j +@Ok("json:full") +@Api(tags = "提案管理-校工会预审核") +public class ProposalPreAuditController { + + @Inject + private BaseService baseService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/proposal/transact/preAudit/index.html") + @SaCheckPermission("proposal.mine") + public void index() { + } + + + @At + @SaCheckPermission("proposal.preAudit") + @ApiOperation("分页列表") + public Result pageData(@Valid ProposalSearchParam pageForm, 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 wf_process_task_actor ta ON ta.processTaskId = t.id + 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 proposal_info info ON info.id = ins.businessNo + LEFT JOIN proposal_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 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("t.taskName", "=", "preAudit"); + + if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())){ + 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()); + } + ProposalSearchParam.buildSearch(cnd, pageForm); + cnd.groupBy("t.id"); + cnd.desc("t.createdAt"); + sql.setCondition(cnd); + Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql); + return Result.success(pagination); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java index 59839257..babd05bc 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java @@ -109,7 +109,7 @@ public class ProposalSchoolLeaderApprovalController { $condition """); Cnd cnd = Cnd.NEW(); - cnd.and("t.taskName", "=", "school_leader"); + cnd.and("t.taskName", "=", "schoolLeader"); if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); @@ -145,6 +145,14 @@ public class ProposalSchoolLeaderApprovalController { Dict args = Json.fromJson(Dict.class, data); String proposalId = args.getStr("proposalId"); + ProcessTask thisTask = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY)); + ProcessTask parentTask = dao.fetch(ProcessTask.class, Cnd.where("id", "=", thisTask.getTaskParentId())); + Dict dict = Json.fromJson(Dict.class, parentTask.getVariable()); + + args.put("tf_caseFilingResult", dict.getStr("tf_caseFilingResult")); + + // 方案流程实例 + // 单条审核 List mergeProposalIds = proposalCommonService.mergeProposal(proposalId); if (ObjectUtil.isEmpty(mergeProposalIds)) { @@ -153,7 +161,7 @@ public class ProposalSchoolLeaderApprovalController { } // 并案审核 - ProcessTask thisTask = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY)); + List mergeTasks = processTaskService.getDoingTaskByBizIdTaskName(mergeProposalIds, thisTask.getTaskName()); for (ProcessTask mergeTask : mergeTasks) { Dict cloneArgs = args.clone(); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java index 0d6c7261..90d63f92 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java @@ -1,28 +1,41 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import com.aspose.slides.internal.og.and; +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.result.Result; import com.budwk.app.base.service.BaseService; import com.budwk.app.bpm.service.BpmService; +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.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.proposal.models.ProposalSecond; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; import com.budwk.app.zhgh.democratic.proposal.service.ProposalSecondedService; import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; 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.dao.util.cri.Static; +import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.lang.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; @@ -83,9 +96,11 @@ public class ProposalSecondedController { t.finishTime, t.taskParentId, t.variable taskVariable, - ta.actorName taskActorName, + if(t.taskName = 'second', ta.actorId, ps.seconderId) taskActorUserId, + if(t.taskName = 'second', ta.actorName, ps.userName) taskActorName, IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, - IF(rt.id IS NOT NULL, 1, 0) AS canRevoke + IF(rt.id IS NOT NULL, 1, 0) AS canRevoke, + sum( CASE WHEN ps.seconderId=@seconderId and ps.isAgree is not null THEN 1 ELSE 0 END ) as count FROM wf_process_task t LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId @@ -93,13 +108,16 @@ public class ProposalSecondedController { 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 proposal_info info ON info.id = ins.businessNo + LEFT JOIN proposal_second ps ON ps.proposalId = info.id LEFT JOIN proposal_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 $condition """); Cnd cnd = Cnd.NEW(); - cnd.and("t.taskName", "=", "second"); + cnd.and("t.taskName", "in", List.of("invite", "second", "delegation", "committee")); + cnd.and(new Static("ps.isAgree is null")); + sql.setParam("seconderId", SecurityUtil.getUserId()); if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); @@ -122,4 +140,42 @@ public class ProposalSecondedController { return Result.success(pagination); } + @At + @SaCheckPermission("proposal.seconded") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("修改提案附议信息") + @SLog(tag = "提案管理系统-附议提案", msg = "修改提案附议信息") + public Result updateInfo(@Param("proposalId") String proposalId, + @Param("taskActorUserId") String taskActorUserId, + @Param("opinion") String opinion, + @Param("submitType") Integer submitType) { + // 查询附议信息表 + ProposalSecond proposalSecond = dao.fetch( + ProposalSecond.class, + Cnd.where(ProposalSecond::getProposalId, "=", proposalId) + .and(ProposalSecond::getSeconderId, "=", taskActorUserId) + ); + proposalSecond.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode())); + proposalSecond.setOpinion(opinion); + proposalSecond.setSecondedTime(DateUtil.date()); + dao.update(proposalSecond); + + // 流程实例 + ProcessInstance processInstance = dao.fetch(ProcessInstance.class,Cnd.where(ProcessInstance::getBusinessNo, "=", proposalId)); + if(processInstance == null) return Result.success(); + + ProcessTask processTask = dao.fetch(ProcessTask.class,Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId()) + .and(ProcessTask::getTaskName, "=", "second") + .and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.ABANDON.getCode()) + .and(new Static("id in (select processTaskId from wf_process_task_actor where actorId='" + taskActorUserId + "')")) + .limit(1,1)); + if(processTask == null) return Result.success(); + + processTask.setTaskState(ProcessTaskStateEnum.FINISHED.getCode()); + processTask.setFinishTime(DateUtil.date()); + dao.update(processTask); + + return Result.success(); + } + } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnSubmitQueryController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnSubmitQueryController.java new file mode 100644 index 00000000..bb1f2759 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnSubmitQueryController.java @@ -0,0 +1,103 @@ +package com.budwk.app.zhgh.democratic.proposal.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; +import io.swagger.annotations.ApiOperation; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpression; +import org.nutz.dao.util.cri.SqlExpressionGroup; +import org.nutz.dao.util.cri.Static; +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 javax.validation.Valid; + +/** + * 未提交预审汇总 + */ +@IocBean +@Ok("json:full") +@At("/platform/proposal/unSubmitQuery") +public class ProposalUnSubmitQueryController { + + @Inject + private ProposalCommonService proposalCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/proposal/transact/unSubmitQuery/index.html") + @SaCheckPermission("proposal.unSubmitQuery") + public void index() { + } + + @At + @ApiOperation("分页列表") + public Result pageData(@Valid ProposalSearchParam pageForm, String searchName, String searchKeyword, String searchName2, String searchKeyword2) { + Sql sql = Sqls.create(""" + SELECT + distinct + info.id, + info.code as proposalCode, + info.name as proposalName, + vu.username, + vu.mobile, + vu.unitName, + tcd.name as delegationName, + pt.name as typeName, + manner.name as mannerName, + (select count(DISTINCT(seconderId))from proposal_seconded where proposalId = info.id) AS secondedNum, + (select count(DISTINCT(seconderId))from proposal_seconded where proposalId = info.id and isAgree = 1) AS secondedAgreeNum, + IF(info.stateCode <= 200 ,'未审核','已审核') AS delegationAudit + FROM + proposal_info info + left join vw_user vu on info.createUserId = vu.id + left join teacher_congress_delegation tcd on info.delegationId = tcd.id + left join proposal_type pt on info.typeId = pt.id + left join sys_dict manner on manner.`code` = info.source + left join `wf_process_instance` ins on ins.businessNo = info.id + left join wf_process_task nt on nt.processInstanceId = ins.id + $condition + """); + Cnd cnd = Cnd.NEW(); + SqlExpressionGroup group = Cnd.exps("ins.state", "=", 30); + group.or("ins.state", "=", 45); + group.or("ins.state", "=", 10); + group.orIsNull("ins.id"); + cnd.and(group); + + SqlExpressionGroup group2 = Cnd.exps("ins.state", "=", 30); + group2.or("ins.state", "=", 45); + group2.or(new Static("ins.id not in (select processInstanceId from wf_process_task where taskName='delegation')")); + cnd.and(group2); + + if(searchName != null && StrUtil.isNotBlank(searchKeyword)) { + if(searchName.equals("proposalName")) { + cnd.and("info.name", "like", "%" + searchKeyword + "%"); + } + if(searchName.equals("proposalCode")) { + cnd.and("info.code", "like", "%" + searchKeyword + "%"); + } + } + + if(searchName2 != null && StrUtil.isNotBlank(searchKeyword2)) { + if(searchName2.equals("su.username")) { + cnd.and("vu.username", "like", "%" + searchKeyword2 + "%"); + } + } + if(pageForm.getSessionId() != null) { + cnd.and("info.sessionId", "=", pageForm.getSessionId()); + } + + sql.setCondition(cnd); + Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pagination); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java index 8db12644..74f627d5 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java @@ -155,6 +155,7 @@ public class ProposalUnderTakeReplyController { } @At + @Aop(TransAop.READ_COMMITTED) @SaCheckPermission("proposal.unitReply") @ApiOperation("执行任务") public Result executeTask(@Param("data") String data) { diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java index ada91b1d..4b8e8956 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java @@ -1,10 +1,13 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.io.FileUtil; 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.base.utils.FileExcelUtil; +import com.budwk.app.base.utils.FileWordUtil; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.FlowEngine; import com.budwk.app.flow.entity.ProcessInstance; @@ -13,8 +16,10 @@ 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.proposal.constants.ProposalState; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; 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; @@ -26,11 +31,16 @@ 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.AdaptBy; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import org.nutz.mvc.upload.TempFile; +import org.nutz.mvc.upload.UploadAdaptor; + import javax.validation.Valid; import java.util.List; +import java.util.Map; /** * 提案撰写 @@ -49,6 +59,8 @@ public class ProposalWriteController { private FlowEngine flowEngine; @Inject private FlowCommonService flowCommonService; + @Inject + private ProposalCommonService proposalCommonService; @At("") @@ -74,6 +86,8 @@ public class ProposalWriteController { if (StrUtil.isBlank(proposalInfo.getCode())) { proposalInfo.setCode(proposalWriteService.generateProposalCode(proposalInfo.getSessionId(), proposalInfo.getDelegationId())); } + // 状态码 + proposalInfo.setStateCode(ProposalState.UNSUBMIT); dao.insertOrUpdate(proposalInfo); return Result.success(proposalInfo); } @@ -103,6 +117,8 @@ public class ProposalWriteController { flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args); } + // 更新提案状态码 + proposalCommonService.updateStateCode(proposalInfo.getId(), ProposalState.INVIRTE); return Result.success(proposalInfo); } @@ -151,6 +167,14 @@ public class ProposalWriteController { return Result.success().addData(sysDicts); } + @At + @SaCheckPermission("proposal.write") + @ApiOperation("查询自己可撰写的提案方式(个人、代表团、委员会)") + public Result listSourceByCode(@Valid String code) { + List sysDicts = proposalWriteService.listSourceByCode(code); + return Result.success().addData(sysDicts); + } + @At @SaCheckPermission("proposal.write") @ApiOperation("检查提案撰写时间") @@ -160,4 +184,36 @@ public class ProposalWriteController { return Result.success().addData(flag); } + @At + @AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"}) + @Aop(TransAop.READ_COMMITTED) + public Result importProposal(TempFile file, String templateType) { + if (file == null) { + return Result.error("文件不能为空!"); + } + String name = file.getSubmittedFileName(); + String suffix = FileUtil.getSuffix(name); + if(!List.of("xls", "xlsx", "docx", "doc").contains(suffix.toLowerCase())) { + throw new RuntimeException("文件格式错误: 不支持该文件{" + suffix + "}导入!"); + } + ProposalInfo proposalInfo = null; + // word docx 文件导入 + if(templateType.equals("2")) { + List> dataMaps = FileWordUtil.readWordTable(file.getFile()); + if(dataMaps == null || dataMaps.size() == 0) { + throw new RuntimeException("文件内容错误: 文件内容不能为空!"); + } + proposalInfo = proposalWriteService.importProposal(dataMaps.get(0)); + + // excel xlsx 文件导入 + } else { + Map dataMap = FileExcelUtil.readExcelTable(file.getFile()); + if(dataMap == null || dataMap.size() == 0) { + throw new RuntimeException("文件内容错误: 文件内容不能为空!"); + } + proposalInfo = proposalWriteService.importProposal(dataMap); + } + return Result.success(proposalInfo); + } + } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalSchoolLeaderAssignmentHandler.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalSchoolLeaderAssignmentHandler.java new file mode 100644 index 00000000..202e2187 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalSchoolLeaderAssignmentHandler.java @@ -0,0 +1,55 @@ +package com.budwk.app.zhgh.democratic.proposal.handler; + +import cn.hutool.core.lang.Dict; +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.flow.entity.Candidate; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** + * 提案主管校领导处理人 + */ +public class ProposalSchoolLeaderAssignmentHandler implements AssignmentHandler { + + @Override + public List assign(TaskModel model, Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + ProposalConfig proposalConfig = dao.fetch(ProposalConfig.class, Cnd.NEW()); + List unitIds = proposalConfig.getSchoolLeaderUnitIds(); + Sql sql = Sqls.create("select id,username,loginname from vw_user where unitId in (@unitIds)"); + sql.setParam("unitIds", unitIds); + sql.setCallback(Sqls.callback.maps()); + dao.execute(sql); + List list = sql.getList(NutMap.class); + + List candidates = list.stream().map(item -> Candidate.builder() + .userId(item.getString("id")) + .userName(item.getString("username")) + .ext(Dict.of("loginName", item.getString("loginname"))) + .build() + ).toList(); + if(candidates.size() > 0) { + return candidates.stream().map(Candidate::getUserId).toList(); + } + return List.of(); + } + + @Override + public String getMessage() { + return "指定主管校领导"; + } + + @Override + public int getOrder() { + return 220; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/models/ProposalSecond.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/models/ProposalSecond.java index 46080d51..9d82764a 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/models/ProposalSecond.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/models/ProposalSecond.java @@ -77,4 +77,8 @@ public class ProposalSecond extends BaseModel { @ColDefine(type = ColType.BOOLEAN) private Boolean isAgree; + @Column + @Comment("附议人内容") + @ColDefine(type = ColType.VARCHAR, width = 500) + private String opinion; } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java index c0578f22..2dc013b2 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java @@ -4,7 +4,9 @@ import com.budwk.app.base.service.BaseService; import com.budwk.app.sys.models.Sys_dict; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import javax.validation.Valid; import java.util.List; +import java.util.Map; public interface ProposalWriteService extends BaseService { @@ -18,4 +20,7 @@ public interface ProposalWriteService extends BaseService { */ String generateProposalCode(String sessionId,String delegationId); + List listSourceByCode(@Valid String code); + + ProposalInfo importProposal(Map stringStringMap); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java index eb8ad319..a416a455 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java @@ -8,6 +8,7 @@ import org.nutz.lang.util.NutMap; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.util.List; +import java.util.Map; public interface ProposalCommonService extends BaseService { @@ -113,4 +114,15 @@ public interface ProposalCommonService extends BaseService { */ List mergeProposal(String id); + /** + * 导入提案 + * + * @param dataMap + */ + void importProposal(Map dataMap); + + /** + * 修改提案状态码 + */ + void updateStateCode(String id, Integer stateCode); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java index 5f1b98e8..14b5fc0f 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java @@ -1,6 +1,8 @@ package com.budwk.app.zhgh.democratic.proposal.service.common; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -23,13 +25,15 @@ 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.sys.services.SysUserService; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.base.Globals; -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.proposal.constants.ProposalState; +import com.budwk.app.zhgh.democratic.proposal.models.*; import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam; +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.delegate.service.TeacherCongressDelegateService; import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; @@ -47,11 +51,14 @@ 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.Strings; import org.nutz.lang.util.NutMap; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; @@ -70,6 +77,12 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp private FlowEngine flowEngine; @Inject private SysDictService sysDictService; + @Inject + private SysUserService sysUserService; + @Inject + private TeacherCongressDelegateService teacherCongressDelegateService; + @Inject + private ProposalWriteService proposalWriteService; public ProposalCommonServiceImpl(Dao dao) { super(dao); @@ -193,14 +206,15 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp 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)); - List feedBackDict = sysDictService.getSubListByCode("PROPOSAL_FEEDBACK"); - Map feedBackMap = feedBackDict.stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName)); +// List feedBackDict = sysDictService.getSubListByCode("PROPOSAL_FEEDBACK"); +// Map feedBackMap = feedBackDict.stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName)); // 流程实例 @@ -217,20 +231,86 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp Map> taskGroups = doneTaskVos.stream().collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName)); docData.putAll(taskGroups); + // 提案附议 + List secondInfos = new ArrayList<>(); + List secondTaskVos = taskGroups.get("提案附议"); + if(secondTaskVos != null && secondTaskVos.size() > 0) { + for (ProcessTaskVO secondTaskVO : secondTaskVos) { + Dict taskFormData = secondTaskVO.getTaskFormData(); + if(taskFormData == null) { + continue; + } + NutMap secondInfo = new NutMap(); + secondInfo.put("s_username", taskFormData.getStr("userName")); + secondInfo.put("s_unitName", taskFormData.getStr("unitName")); + Sql taskUserSql = Sqls.create("select mobile from sys_user where loginname=@loginname and delFlag != 1 limit 0,1"); + taskUserSql.setParam("loginname", taskFormData.getStr("loginName")); + taskUserSql.setCallback(Sqls.callback.map()); + execute(taskUserSql); + NutMap taskUserMap = (NutMap) taskUserSql.getResult(); + secondInfo.put("s_mobile", taskUserMap.getString("mobile")); + secondInfos.add(secondInfo); + } + } + + // 代表团意见 + List delegationAuditList = new ArrayList<>(); + List delegationTaskVos = taskGroups.get("团长审核"); + if(delegationTaskVos != null && delegationTaskVos.size() > 0) { + for (ProcessTaskVO delegationTaskVO : delegationTaskVos) { + Dict taskFormData = delegationTaskVO.getTaskFormData(); + if(taskFormData == null) { + continue; + } + + NutMap delegationAudit = new NutMap(); + delegationAudit.put("opinion", taskFormData.getStr("opinion")); + delegationAudit.put("username", taskFormData.getStr("userName")); + delegationAudit.put("auditTime", DateUtil.format(delegationTaskVO.getFinishTime(), "yyyy-MM-dd HH:mm:ss")); + + delegationAuditList.add(delegationAudit); + } + } + + // 导出单元格数据信息 + Map docCellDataMap = new HashMap<>(); + // 编号 + docCellDataMap.put("proposalCode", docData.getString("code")); + // 提交时间 + docCellDataMap.put("createTime", docData.getString("createTime")); + // 提案人 + docCellDataMap.put("username", docData.getString("createUserName")); + // 所在代表团 + docCellDataMap.put("delegationName", docData.getString("delegationName")); + // 所在单位 + docCellDataMap.put("unitName", docData.getString("unitName")); + // 联系方式 + docCellDataMap.put("mobile", docData.getString("mobile")); + // 提案名称 + docCellDataMap.put("proposalName", docData.getString("name")); + // 提案内容 + docCellDataMap.put("brief", docData.getString("brief")); + // 建议措施 + docCellDataMap.put("measures", docData.getString("measures")); + LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy(); htmlRenderPolicy.getConfig().setShowDefaultTableBorderInTableCell(true); Configure config = Configure.builder() + .bind("secondedList", policy) .bind("seconders", policy) - .bind("提案附议", policy) .bind("brief", htmlRenderPolicy) .bind("measures", htmlRenderPolicy) .bind("taskFormData.tf_opinion", htmlRenderPolicy) .build(); + Map renderDocCellDataMap = MapUtil.of("proposal", docCellDataMap); + renderDocCellDataMap.put("secondedList", secondInfos); + renderDocCellDataMap.put("delegationAuditList", delegationAuditList); + try { - XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("proposal"), config).render(docData).writeAndClose(byteArrayOutputStream); + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("proposal"), config).render(renderDocCellDataMap).writeAndClose(byteArrayOutputStream); } catch (IOException e) { log.error("提案导出失败{},提案id:{}", e.getMessage(), id); } @@ -632,4 +712,130 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp } return null; } + + @Override + public void importProposal(Map dataMap) { + String loginName = MapUtil.getStr(dataMap, "工号", ""); + String username = MapUtil.getStr(dataMap, "提案人", ""); + String proposalDate = MapUtil.getStr(dataMap, "提案时间", ""); + String proposalType = MapUtil.getStr(dataMap, "提案类型", ""); + String proposalSource = MapUtil.getStr(dataMap, "提案方式", ""); + String proposalName = MapUtil.getStr(dataMap, "提案名称", ""); + String proposalContent = MapUtil.getStr(dataMap, "案由", ""); + String proposalMeasures = MapUtil.getStr(dataMap, "建议措施", ""); + + // 工号 + if(StrUtil.isBlank(loginName)) { + throw new RuntimeException("工号不能为空"); + } + Sys_user user = sysUserService.getByLoginName(loginName); + if(user == null){ + throw new RuntimeException("工号不存在"); + } + if(StrUtil.isNotBlank(username) && !username.equals(user.getUsername())) { + throw new RuntimeException("工号和提案人不一致"); + } + + // 提案时间 + if(StrUtil.isBlank(proposalDate)) { + throw new RuntimeException("提案时间不能为空"); + } + + // 提案类型 + if(StrUtil.isBlank(proposalType)) { + throw new RuntimeException("提案类型不能为空"); + } + ProposalType proposalTypeObj = dao().fetch(ProposalType.class, Cnd.where(ProposalType::getName, "=", proposalType)); + if(proposalTypeObj == null) { + throw new RuntimeException("提案类型不存在"); + } + + // 提案方式 + if(StrUtil.isBlank(proposalSource)) { + throw new RuntimeException("提案方式不能为空"); + } + Sys_dict dict = sysDictService.fetch(Cnd.where("code", "=", "PROPOSAL_SOURCE")); + if(dict == null) { + throw new RuntimeException("提案方式字典配置不存在"); + } + List sysDicts = sysDictService.query(Cnd.where("parentId", "=", Strings.sNull(dict.getId())).asc("location")); + if(sysDicts == null || sysDicts.size() == 0) { + throw new RuntimeException("提案方式字典配置不存在"); + } + Sys_dict proposalSourceDict = sysDicts.stream().filter(v -> v.getName().equals(proposalSource)).findFirst().orElse(null); + if(proposalSourceDict == null) { + throw new RuntimeException("提案方式不存在"); + } + + // 提案名称 + if(StrUtil.isBlank(proposalName)) { + throw new RuntimeException("提案名称不能为空"); + } + + // 案由 + if(StrUtil.isBlank(proposalContent)) { + throw new RuntimeException("案由不能为空"); + } + + // 建议措施 + if(StrUtil.isBlank(proposalMeasures)) { + throw new RuntimeException("建议措施不能为空"); + } + + // 判断当前导入用户是否是代表 + Teacher_congress_delegate delegate = teacherCongressDelegateService.fetch(Cnd.where(Teacher_congress_delegate::getUserId, "=", SecurityUtil.getUserId()) + .and(Teacher_congress_delegate::getDelFlag, "!=", 1).limit(1)); + if(delegate == null) { + throw new RuntimeException("当前用户不是代表"); + } + + // 教代会 + List teacherCongressSessions = this.dao().query(Teacher_congress_session.class, Cnd.where("enable", "=", 1).desc("startDate")); + if(teacherCongressSessions == null || teacherCongressSessions.size() <= 0) { + throw new RuntimeException("没有开启的教代会"); + } + Teacher_congress_session teacherCongressSession = teacherCongressSessions.get(0); + + // 保存到数据库 + ProposalInfo proposalInfo = new ProposalInfo(); + // 状态码 + proposalInfo.setStateCode(ProposalState.UNSUBMIT); + // 教代会信息 + proposalInfo.setSessionId(teacherCongressSession.getId()); + // 代表团ID + proposalInfo.setDelegationId(delegate.getDelegationId()); + // 提案编号 + Sql sql = Sqls.create("select max(code) proposalCode from proposal_info where sessionId='%s' and stateCode<='%s'".formatted(proposalInfo.getSessionId(), ProposalState.CASE)); + sql.setCallback(Sqls.callback.map()); + Map map = this.dao().execute(sql).getObject(Map.class); + int proposalCode = MapUtil.getInt(map, "proposalCode", -1); + if (proposalCode == -1) { + proposalCode = Integer.parseInt(com.budwk.app.sys.utils.DateUtil.getYear() + "01"); + } else { + proposalCode = proposalCode + 1; + } + proposalInfo.setCode(proposalCode + ""); + // 提案人 + proposalInfo.setCreateUserId(user.getId()); + proposalInfo.setCreateUserName(user.getUsername()); + // 提案名称 + proposalInfo.setName(proposalName); + // 提案时间 + proposalInfo.setCreateTime(proposalDate); + // 提案方式 + proposalInfo.setSource(proposalSourceDict.getCode()); + // 提案类型 + proposalInfo.setTypeId(proposalTypeObj.getId()); + // 案由 + proposalInfo.setBrief(proposalContent); + // 建议措施 + proposalInfo.setMeasures(proposalMeasures); + this.insert(proposalInfo); + } + + @Override + public void updateStateCode(String id, Integer stateCode) { + Sql sql = Sqls.create("update proposal_info set stateCode='%s' where id='%s'".formatted(stateCode, id)); + this.dao().execute(sql); + } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java index 01cebf2a..f28a1798 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java @@ -1,30 +1,44 @@ package com.budwk.app.zhgh.democratic.proposal.service.impl; import cn.hutool.core.convert.Convert; +import cn.hutool.core.map.MapUtil; 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.models.Sys_user; import com.budwk.app.sys.services.SysDictService; +import com.budwk.app.sys.services.SysUserService; import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.proposal.constants.ProposalState; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalType; 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.delegate.service.TeacherCongressDelegateService; 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.Sqls; import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; import java.util.ArrayList; import java.util.List; +import java.util.Map; @IocBean(args = {"refer:dao"}) public class ProposalWriteServiceImpl extends BaseServiceImpl implements ProposalWriteService { @Inject private SysDictService sysDictService; + @Inject + private TeacherCongressDelegateService teacherCongressDelegateService; + @Inject + private SysUserService sysUserService; public ProposalWriteServiceImpl(Dao dao) { super(dao); @@ -67,28 +81,163 @@ public class ProposalWriteServiceImpl extends BaseServiceImpl impl @Override public String generateProposalCode(String sessionId, String delegationId) { //查询届次下 某代表团的提案数量 - Teacher_congress_session session = dao().fetch(Teacher_congress_session.class, sessionId); - Teacher_congress_delegation delegation = dao().fetch(Teacher_congress_delegation.class, delegationId); - - Sql sql = Sqls.fetchString(""" - SELECT - MAX( t1.code ) as proposalCode - FROM - proposal_info t1 - WHERE - t1.sessionId = @sessionId - AND t1.delegationId = @delegationId - """); - sql.setParam("sessionId", sessionId); - sql.setParam("delegationId", delegationId); - execute(sql); - String proposalCode = sql.getString(); - if (StrUtil.isBlank(proposalCode)) { - proposalCode = delegation.getCode() + "-" + "01"; +// Teacher_congress_session session = dao().fetch(Teacher_congress_session.class, sessionId); +// Teacher_congress_delegation delegation = dao().fetch(Teacher_congress_delegation.class, delegationId); +// +// Sql sql = Sqls.fetchString(""" +// SELECT +// MAX( t1.code ) as proposalCode +// FROM +// proposal_info t1 +// WHERE +// t1.sessionId = @sessionId +// AND t1.delegationId = @delegationId +// """); +// sql.setParam("sessionId", sessionId); +// sql.setParam("delegationId", delegationId); +// execute(sql); +// String proposalCode = sql.getString(); +// if (StrUtil.isBlank(proposalCode)) { +// proposalCode = delegation.getCode() + "-" + "01"; +// } else { +// String s = String.format("%02d", (Convert.toInt(proposalCode.substring(proposalCode.length() - 2))) + 1); +// proposalCode = delegation.getCode() + "-" + s; +// } + Sql sql = Sqls.create("select max(code) proposalCode from proposal_info where sessionId='%s' and stateCode<='%s'".formatted(sessionId, ProposalState.CASE)); + sql.setCallback(Sqls.callback.map()); + Map map = this.dao().execute(sql).getObject(Map.class); + int proposalCode = MapUtil.getInt(map, "proposalCode", -1); + if (proposalCode == -1) { + proposalCode = Integer.parseInt(com.budwk.app.sys.utils.DateUtil.getYear() + "01"); } else { - String s = String.format("%02d", (Convert.toInt(proposalCode.substring(proposalCode.length() - 2))) + 1); - proposalCode = delegation.getCode() + "-" + s; + proposalCode = proposalCode + 1; } - return proposalCode; + return String.valueOf(proposalCode); + } + + @Override + public List listSourceByCode(String code) { + Sys_dict dict = sysDictService.fetch(Cnd.where("code", "=", code)); + return dict == null ? new ArrayList<>() : sysDictService.query(Cnd.where("parentId", "=", Strings.sNull(dict.getId())).asc("location")); + } + + @Override + public ProposalInfo importProposal(Map dataMap) { + String loginName = MapUtil.getStr(dataMap, "工号", ""); + String username = MapUtil.getStr(dataMap, "提案人", ""); + String proposalDate = MapUtil.getStr(dataMap, "提案时间", ""); + String proposalType = MapUtil.getStr(dataMap, "提案类型", ""); + String proposalSource = MapUtil.getStr(dataMap, "提案方式", ""); + String proposalName = MapUtil.getStr(dataMap, "提案名称", ""); + String proposalContent = MapUtil.getStr(dataMap, "案由", ""); + String proposalMeasures = MapUtil.getStr(dataMap, "建议措施", ""); + + // 工号 + if(StrUtil.isBlank(loginName)) { + throw new RuntimeException("工号不能为空"); + } + Sys_user user = sysUserService.getByLoginName(loginName); + if(user == null){ + throw new RuntimeException("工号不存在"); + } + if(StrUtil.isNotBlank(username) && !username.equals(user.getUsername())) { + throw new RuntimeException("工号和提案人不一致"); + } + + // 提案时间 + if(StrUtil.isBlank(proposalDate)) { + throw new RuntimeException("提案时间不能为空"); + } + + // 提案类型 + if(StrUtil.isBlank(proposalType)) { + throw new RuntimeException("提案类型不能为空"); + } + ProposalType proposalTypeObj = dao().fetch(ProposalType.class, Cnd.where(ProposalType::getName, "=", proposalType)); + if(proposalTypeObj == null) { + throw new RuntimeException("提案类型不存在"); + } + + // 提案方式 + if(StrUtil.isBlank(proposalSource)) { + throw new RuntimeException("提案方式不能为空"); + } + Sys_dict dict = sysDictService.fetch(Cnd.where("code", "=", "PROPOSAL_SOURCE")); + if(dict == null) { + throw new RuntimeException("提案方式字典配置不存在"); + } + List sysDicts = sysDictService.query(Cnd.where("parentId", "=", Strings.sNull(dict.getId())).asc("location")); + if(sysDicts == null || sysDicts.size() == 0) { + throw new RuntimeException("提案方式字典配置不存在"); + } + Sys_dict proposalSourceDict = sysDicts.stream().filter(v -> v.getName().equals(proposalSource)).findFirst().orElse(null); + if(proposalSourceDict == null) { + throw new RuntimeException("提案方式不存在"); + } + + // 提案名称 + if(StrUtil.isBlank(proposalName)) { + throw new RuntimeException("提案名称不能为空"); + } + + // 案由 + if(StrUtil.isBlank(proposalContent)) { + throw new RuntimeException("案由不能为空"); + } + + // 建议措施 + if(StrUtil.isBlank(proposalMeasures)) { + throw new RuntimeException("建议措施不能为空"); + } + + // 判断当前导入用户是否是代表 + Teacher_congress_delegate delegate = teacherCongressDelegateService.fetch(Cnd.where(Teacher_congress_delegate::getUserId, "=", SecurityUtil.getUserId()) + .and(Teacher_congress_delegate::getDelFlag, "!=", 1).limit(1)); + if(delegate == null) { + throw new RuntimeException("当前用户不是代表"); + } + + // 教代会 + List teacherCongressSessions = this.dao().query(Teacher_congress_session.class, Cnd.where("enable", "=", 1).desc("startDate")); + if(teacherCongressSessions == null || teacherCongressSessions.size() <= 0) { + throw new RuntimeException("没有开启的教代会"); + } + Teacher_congress_session teacherCongressSession = teacherCongressSessions.get(0); + + // 保存到数据库 + ProposalInfo proposalInfo = new ProposalInfo(); + // 状态码 + proposalInfo.setStateCode(ProposalState.UNSUBMIT); + // 教代会信息 + proposalInfo.setSessionId(teacherCongressSession.getId()); + // 代表团ID + proposalInfo.setDelegationId(delegate.getDelegationId()); + // 提案编号 + Sql sql = Sqls.create("select max(code) proposalCode from proposal_info where sessionId='%s' and stateCode<='%s'".formatted(proposalInfo.getSessionId(), ProposalState.CASE)); + sql.setCallback(Sqls.callback.map()); + Map map = this.dao().execute(sql).getObject(Map.class); + int proposalCode = MapUtil.getInt(map, "proposalCode", -1); + if (proposalCode == -1) { + proposalCode = Integer.parseInt(com.budwk.app.sys.utils.DateUtil.getYear() + "01"); + } else { + proposalCode = proposalCode + 1; + } + proposalInfo.setCode(proposalCode + ""); + // 提案人 + proposalInfo.setCreateUserId(user.getId()); + proposalInfo.setCreateUserName(user.getUsername()); + // 提案名称 + proposalInfo.setName(proposalName); + // 提案时间 + proposalInfo.setCreateTime(proposalDate); + // 提案方式 + proposalInfo.setSource(proposalSourceDict.getCode()); + // 提案类型 + proposalInfo.setTypeId(proposalTypeObj.getId()); + // 案由 + proposalInfo.setBrief(proposalContent); + // 建议措施 + proposalInfo.setMeasures(proposalMeasures); + return proposalInfo; } } diff --git a/src/main/resources/static/assets/platform/js/mixin/initTableMixins.js b/src/main/resources/static/assets/platform/js/mixin/initTableMixins.js index 0c9c3205..f0796c12 100644 --- a/src/main/resources/static/assets/platform/js/mixin/initTableMixins.js +++ b/src/main/resources/static/assets/platform/js/mixin/initTableMixins.js @@ -114,6 +114,31 @@ const initTableMixins = { this.$set(this.pageForm, 'isAudit', approvalParam === 'done') this._approvalInitialized = true; } + }, + fileHandleRemove(file, fileList) { + return fileList; + }, + fileHandleChange(file, fileList, {type, size}) { + const removeFile = () => { + fileList.splice(fileList.findIndex(v => v === file)) + } + + if (!file.size) { + this.notifyWarning('您选择的是空文件!') + removeFile() + } + + if (type && type.length && !type.includes(file.name.split('.').pop().toLowerCase())) { + this.notifyWarning(`文件只能是 ${type.map(v => v.toUpperCase()).join('/')} 格式!`) + removeFile() + } + + if (size && !file.size < size) { + this.notifyWarning(`文件大小不能超过 ${size / 1024 / 1024}MB!`) + removeFile() + } + + return fileList; } }, created() { diff --git a/src/main/resources/templates/proposal/export/proposal.docx b/src/main/resources/templates/proposal/export/proposal.docx new file mode 100644 index 0000000000000000000000000000000000000000..6bb5bf22e90b53e608d7367fe8597551f11cac00 GIT binary patch literal 15180 zcmb7r19WBE(r#?q?zm&ywr$%^I<{@ww%M`WaYr3no#ds@x#ymH`rY@B|IIOywbx$t z&6=}nt=e^mp>2NYZQlG!%Dhj<918JIzm*RDy|c= z8fOW8wBwnRLFWtZ<@X3jI(Fc`x@nMu9I`go6r%R2&c2>AgpiTLkyKOb3eg1%72h&$d@~URw2f#J%S!*iLP4g?3+-s8Q z`uOb-(M7$4)C7Gmr%s=T9%k!CjGMN@XFUNuFlM;oL%h{Jj1pPwGjIYjG)iuaYPeH= zsERBb?pRwW7O$A-eZFYW(?)9`8Z^G>PfEBgT938DB8SF^9@8K{lPDYKXTDVW=j?lq zOCPRSF>w=?HXV9@1~)Qx^AV{-sbJZLe z!Z7ErDV8Tgs*E}=+UC&$UAJzY?Rn>Y5V&E=6q6Wd*Y5l_&)eW-uldQ{UHQ|E`Yeg1 z#&>ZQr6Dd&6Lp;`KdCGNuUE98jHI_-1_DJ47JCkWd&qw}s!x}lU-83HP9Kg!{7*+2 z+Bz8j@|1UcpUeOqOz?$Rr(lw2M&kx)>6#2sBXUA4Igot>l5K?996994GeRedtjL

AuO7OWmg}F5@#MJ%}NT-0?l4XLTKtfc^TXx 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/templates/proposal/proposal.xlsx b/src/main/resources/templates/proposal/proposal.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8390a93837ae97a528e23fb632daed3d87907eb0 GIT binary patch literal 12033 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≀?zF_~DwZ4DD{z9)?@ayu6_4B{iB7^iFwfth5D9S*;WHF$Z1SVJ#sLz@-FTef|-N*$y literal 0 HcmV?d00001 diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/allFinished/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/allFinished/index.html new file mode 100644 index 00000000..6746a702 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/allFinished/index.html @@ -0,0 +1,108 @@ + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html new file mode 100644 index 00000000..c0f5d880 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html @@ -0,0 +1,202 @@ + +
+ + + + + + + + + + + + + + + + + + + + 已审核 + 未审核 + + + + + + + + + + + + + + + + +
+ + diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html index b765f067..c1fe9f43 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html @@ -2,429 +2,351 @@ layout("/layouts/platform.html"){ #--> - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - 重新并案审核 - - 已审核 - 未审核 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 已审核 + 未审核 + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html index 367a6095..a2f10044 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/delegation/index.html @@ -107,6 +107,7 @@ layout("/layouts/platform.html"){ tableColumns: [ {label: "提案编号", prop: "code"}, {label: "提案名称", prop: "name", width: "200px"}, + {label: "提案人", prop: "createUserName", width: "80px"}, {label: "提案类别", prop: "typeName"}, {label: "届次", prop: "sessionName"}, {label: "代表团", prop: "delegationName"}, diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/mine/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/mine/index.html index cbd5d1c7..9e7d2dc9 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/mine/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/mine/index.html @@ -22,7 +22,11 @@ layout("/layouts/platform.html"){ - + + 导入提案 + + {{ (row.startTaskId) ? row.taskName : '待提交' }} @@ -75,6 +82,60 @@ layout("/layouts/platform.html"){ + + + + + + + excel + word + + + + + + 下载模板 + + + + + + + + + 选择文件 + + + + + + 取 消 + 确定 + +