diff --git a/src/main/java/com/budwk/app/sys/controller/SysRoleController.java b/src/main/java/com/budwk/app/sys/controller/SysRoleController.java index f468276c..d9a8991e 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysRoleController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysRoleController.java @@ -401,7 +401,8 @@ public class SysRoleController { public Object user(@Param("roleId") String roleId, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) { try { - Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_user_role b,sys_unit c WHERE a.unitid=c.id and a.id=b.userId and b.roleId=@roleId $s $o"); + // sys_user_role 会按单位、工会等业务范围保存多条记录,这里只按用户维度展示一次。 + Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_unit c WHERE a.unitid=c.id and EXISTS (SELECT 1 FROM sys_user_role b WHERE b.userId=a.id and b.roleId=@roleId) $s $o"); sql.params().set("roleId", roleId); if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) { sql.vars().set("s", " and a." + searchName + " like '%" + searchKeyword + "%'"); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalSatisfactionStatisticsController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalSatisfactionStatisticsController.java new file mode 100644 index 00000000..c51b6f86 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalSatisfactionStatisticsController.java @@ -0,0 +1,39 @@ +package com.budwk.app.zhgh.democratic.proposal.controller.query; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSatisfactionStatisticsParam; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.validation.Valid; + +@IocBean +@At("/platform/proposal/query/satisfactionStatistics") +@Ok("json:full") +@Api(tags = "提案满意度统计") +public class ProposalSatisfactionStatisticsController { + + @Inject + private ProposalCommonService proposalCommonService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/proposal/query/satisfactionStatistics/index.html") + @SaCheckPermission("proposal.query.satisfactionStatistics") + public void index() { + } + + @At + @SaCheckPermission("proposal.query.satisfactionStatistics") + @ApiOperation("提案满意度统计") + public Result data(@Valid @Param("pageForm") ProposalSatisfactionStatisticsParam pageForm) { + return Result.success(proposalCommonService.satisfactionStatistics(pageForm)); + } + +} diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSatisfactionStatisticsParam.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSatisfactionStatisticsParam.java new file mode 100644 index 00000000..de3531fa --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSatisfactionStatisticsParam.java @@ -0,0 +1,17 @@ +package com.budwk.app.zhgh.democratic.proposal.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(description = "提案满意度统计参数") +public class ProposalSatisfactionStatisticsParam { + + @ApiModelProperty(name = "教代会ID") + private String sessionId; + + @ApiModelProperty(name = "提案类别ID") + private String[] typeIds; + +} 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..fdb3f184 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 @@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.service.common; import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSatisfactionStatisticsParam; import org.nutz.lang.util.NutMap; import javax.servlet.http.HttpServletResponse; @@ -113,4 +114,12 @@ public interface ProposalCommonService extends BaseService { */ List mergeProposal(String id); + /** + * 按提案类别统计立案同意提案的反馈完成率和满意率。 + * + * @param param 统计筛选参数,包含届次和提案类别 + * @return 每个提案类别的统计结果 + */ + List satisfactionStatistics(ProposalSatisfactionStatisticsParam param); + } 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 79a816d8..52d9e964 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 @@ -29,6 +29,7 @@ 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.*; import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSatisfactionStatisticsParam; import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; @@ -513,6 +514,9 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp HashMap docData = new HashMap<>(); Teacher_congress_session session = dao().fetch(Teacher_congress_session.class, sessionId); + if (ObjectUtil.isEmpty(session)) { + throw new BaseException("请选择教代会后再导出年度报告"); + } docData.put("sessionName", session.getFullName()); docData.put("startDate", DateUtil.format(session.getStartDate(), "yyyy年MM月dd日")); @@ -623,7 +627,8 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp for (int i = 0; i < transactList.size(); i++) { NutMap v = transactList.get(i); v.setv("index", i + 1); - v.setv("ratio", NumberUtil.decimalFormat("#.##%", v.getInt("sum") / sum)); + // 当前届次没有提案时避免除以 0;有数据时使用小数计算,保证比例准确。 + v.setv("ratio", sum == 0 ? "0%" : NumberUtil.decimalFormat("#.##%", v.getInt("sum") * 1.0 / sum)); } docData.put("transacts", transactList); @@ -649,9 +654,9 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp type.id ORDER BY type.CODE - """); + """); newSessionSql.setParam("newSessionId", nextSession.getId()); - List newSessionProposals = listMap(sql); + List newSessionProposals = listMap(newSessionSql); docData.put("newSum", newSessionProposals.stream().mapToInt(v -> v.getInt("count", 0)).sum()); docData.put("newTypesSummary", newSessionProposals.stream() @@ -683,4 +688,75 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp } return null; } + + @Override + public List satisfactionStatistics(ProposalSatisfactionStatisticsParam param) { + Sql sql = Sqls.create(""" + SELECT + type.id AS typeId, + type.code AS typeCode, + type.name AS typeName, + COUNT(DISTINCT info.id) AS filingCount, + COUNT(DISTINCT CASE WHEN latestFeedback.processInstanceId IS NOT NULL THEN info.id END) AS feedbackCount, + COUNT(DISTINCT CASE WHEN latestFeedback.processInstanceId IS NULL AND info.id IS NOT NULL THEN info.id END) AS unFeedbackCount, + COUNT(DISTINCT CASE WHEN latestFeedback.tf_feedback IS NOT NULL AND latestFeedback.tf_feedback != 'DISSATISFIED' THEN info.id END) AS satisfiedCount, + COUNT(DISTINCT CASE WHEN latestFeedback.tf_feedback = 'DISSATISFIED' THEN info.id END) AS dissatisfiedCount, + ROUND( + CASE + WHEN COUNT(DISTINCT info.id) = 0 THEN 0 + ELSE COUNT(DISTINCT CASE WHEN latestFeedback.processInstanceId IS NOT NULL THEN info.id END) * 100.0 / COUNT(DISTINCT info.id) + END, + 2 + ) AS completionRate, + ROUND( + CASE + WHEN COUNT(DISTINCT CASE WHEN latestFeedback.processInstanceId IS NOT NULL THEN info.id END) = 0 THEN 0 + ELSE COUNT(DISTINCT CASE WHEN latestFeedback.tf_feedback IS NOT NULL AND latestFeedback.tf_feedback != 'DISSATISFIED' THEN info.id END) * 100.0 / COUNT(DISTINCT CASE WHEN latestFeedback.processInstanceId IS NOT NULL THEN info.id END) + END, + 2 + ) AS satisfactionRate + FROM + proposal_type type + LEFT JOIN proposal_info info ON info.typeId = type.id + AND info.caseFilingResult = 'CONFIRM_FILING' + AND (@sessionId IS NULL OR @sessionId = '' OR info.sessionId = @sessionId) + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN ( + SELECT + processInstanceId, + JSON_UNQUOTE(JSON_EXTRACT(variable, '$.tf_feedback')) AS tf_feedback + FROM ( + SELECT + processInstanceId, + variable, + ROW_NUMBER() OVER (PARTITION BY processInstanceId ORDER BY finishTime DESC, id DESC) AS rn + FROM + wf_process_task + WHERE + taskName = 'feedback' + AND taskState = 20 + ) feedbackTask + WHERE feedbackTask.rn = 1 + ) latestFeedback ON latestFeedback.processInstanceId = ins.id + $condition + GROUP BY + type.id + ORDER BY + type.code + """); + sql.setParam("sessionId", param == null ? null : param.getSessionId()); + + Cnd cnd = Cnd.NEW(); + if (param != null && Lang.isNotEmpty(param.getTypeIds())) { + cnd.and("type.id", "in", param.getTypeIds()); + } + sql.setCondition(cnd); + List list = listMap(sql); + for (NutMap row : list) { + // 前端直接展示百分比文本,避免每个页面重复处理空值和数值格式。 + row.put("completionRateText", ObjectUtil.defaultIfNull(row.get("completionRate"), 0).toString() + "%"); + row.put("satisfactionRateText", ObjectUtil.defaultIfNull(row.get("satisfactionRate"), 0).toString() + "%"); + } + return list; + } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceMineController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceMineController.java index 99cebbda..a1dcd8d1 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceMineController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceMineController.java @@ -34,6 +34,8 @@ import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import javax.servlet.http.HttpServletResponse; + /** * @ClassName CondolenceApplyController * @Author JyuHsin @@ -140,6 +142,16 @@ public class CondolenceMineController { //smsService.send("20182040", "这是一条由智慧工会系统发出的测试消息。"); return Result.success(nutMap); } + + @At + @Ok("void") + @ApiOperation("导出报销单") + @SaCheckPermission("condolence.mine") + @SLog(tag = "职工慰问系统-我的申请", msg = "导出慰问报销单") + public void doExport(@Param("id") String id, HttpServletResponse response) { + condolenceService.exportReimbursement(id, response); + } + @Inject private SmsService smsService; } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceReadController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceReadController.java index 8c75efe2..9b835fd1 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceReadController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/controller/CondolenceReadController.java @@ -5,29 +5,15 @@ import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.util.StrUtil; -import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.result.Result; import com.budwk.app.base.utils.CommonDownloadUtil; -import com.budwk.app.base.utils.PageUtil; -import com.budwk.app.flow.entity.ProcessInstance; -import com.budwk.app.flow.enums.ProcessTaskStateEnum; -import com.budwk.app.sys.param.SysMsgSummaryPageForm; -import com.budwk.app.web.commons.auth.utils.AuthUtil; -import com.budwk.app.web.commons.auth.utils.SecurityUtil; -import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence; import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Workbook; -import org.nutz.dao.Cnd; -import org.nutz.dao.Dao; -import org.nutz.dao.Sqls; -import org.nutz.dao.sql.Sql; -import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.lang.util.NutMap; @@ -68,56 +54,16 @@ public class CondolenceReadController { @SaCheckPermission("condolence.read") public Result pageData(PageForm pageForm, @Param(value = "year") Integer year, + @Param(value = "month") String month, @Param(value = "type") String type, @Param(value = "unionId") String unionId, - @Param(value = "unitId") String unitId) { - Sql sql = Sqls.create(""" - SELECT - info.*, - ins.id AS instanceId, - type.name as typeName, - ins.state instanceState, - ins.processDefineId instanceProcessDefineId, - t.displayName taskName - FROM - condolence info - LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id - LEFT JOIN ( - SELECT - processInstanceId, - displayName, - createdAt, - ROW_NUMBER() OVER (PARTITION BY processInstanceId ORDER BY createdAt DESC) AS rn - FROM wf_process_task - ) t ON t.processInstanceId = ins.id AND t.rn = 1 - LEFT JOIN condolence_type type ON info.type = type.id - $condition - """); - Cnd cnd = Cnd.NEW(); - cnd.andEX("info.type", "=", type); - cnd.andEX("YEAR(info.createTime)", "=", year); - cnd.andEX("info.applyUnionId", "=", unionId); - cnd.andEX("info.applyUnitId", "=", unitId); - - if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { - SqlExpressionGroup seg = new SqlExpressionGroup(); - seg.or("info.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%"); - seg.or("info.helpLoginName", "like", "%" + pageForm.getSearchKeyword() + "%"); - cnd.and(seg); - } - - if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) { - cnd.and("info.applyUnionId", "=", SecurityUtil.getUnionId()); - } - - if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { - cnd.desc("info.createTime"); - } else { - cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); - } - sql.setCondition(cnd); - Pagination pageVO = condolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); - return Result.success(pageVO); + @Param(value = "unitId") String unitId, + @Param(value = "userState") String userState) { + Pagination pageVO = condolenceService.pageReadData(pageForm, year, month, type, unionId, unitId, userState); + return Result.success(NutMap.NEW() + .addv("list", pageVO.getList()) + .addv("totalCount", pageVO.getTotalCount()) + .addv("totalMoney", condolenceService.sumReadMoney(pageForm, year, month, type, unionId, unitId, userState))); } @At @@ -126,47 +72,24 @@ public class CondolenceReadController { @ApiOperation("导出职工慰问汇总表") public void onExport(PageForm pageForm, @Param(value = "year") Integer year, + @Param(value = "month") String month, @Param(value = "type") String type, @Param(value = "unionId") String unionId, @Param(value = "unitId") String unitId, + @Param(value = "userState") String userState, HttpServletResponse response) { //查询审核通过的数据 - Sql sql = Sqls.create(""" - select - con.*, - type.name as typeName - from - condolence con - left join wf_process_instance ins on ins.businessNo = con.id - left join condolence_type type on type.id = con.type - $condition - """); - Cnd cnd = Cnd.NEW(); - cnd.and(ProcessInstance::getState, "=", ProcessTaskStateEnum.FINISHED.getCode()); - cnd.andEX("con.type", "=", type); - cnd.andEX("YEAR(info.createTime)", "=", year); - cnd.andEX("con.applyUnionId", "=", unionId); - cnd.andEX("con.applyUnitId", "=", unitId); - if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { - SqlExpressionGroup seg = new SqlExpressionGroup(); - seg.or("info.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%"); - seg.or("info.helpLoginName", "like", "%" + pageForm.getSearchKeyword() + "%"); - cnd.and(seg); - } - if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) { - cnd.and("con.applyUnionId", "=", SecurityUtil.getUnionId()); - } - sql.setCondition(cnd); - List list = condolenceService.listMap(sql); + List list = condolenceService.listCompletedReadData(pageForm, year, month, type, unionId, unitId, userState); List exportEntities = new ArrayList<>(); exportEntities.add(new ExcelExportEntity("慰问对象", "helpUserName", 20)); exportEntities.add(new ExcelExportEntity("慰问对象工号", "helpLoginName", 20)); + exportEntities.add(new ExcelExportEntity("在职状态", "userState", 20)); exportEntities.add(new ExcelExportEntity("申请人", "applyUserName", 20)); exportEntities.add(new ExcelExportEntity("所在工会", "helpUnionName", 20)); exportEntities.add(new ExcelExportEntity("所在单位", "helpUnitName", 20)); exportEntities.add(new ExcelExportEntity("慰问类型", "typeName", 20)); - exportEntities.add(new ExcelExportEntity("拟补贴金额", "money", 20)); + exportEntities.add(new ExcelExportEntity("慰问金额", "money", 20)); exportEntities.add(new ExcelExportEntity("申请理由", "remark", 20)); ExportParams exportParams = new ExportParams(); @@ -174,4 +97,19 @@ public class CondolenceReadController { Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list); CommonDownloadUtil.download("申报人汇总.xlsx", workbook, response); } + + @At + @Ok("void") + @SaCheckPermission("condolence.read") + @ApiOperation("导出慰问附件压缩包") + public void exportZip(PageForm pageForm, + @Param(value = "year") Integer year, + @Param(value = "month") String month, + @Param(value = "type") String type, + @Param(value = "unionId") String unionId, + @Param(value = "unitId") String unitId, + @Param(value = "userState") String userState, + HttpServletResponse response) { + condolenceService.exportReadZip(pageForm, year, month, type, unionId, unitId, userState, response); + } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/CondolenceService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/CondolenceService.java index 37865c7e..d8fc285b 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/CondolenceService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/CondolenceService.java @@ -1,7 +1,14 @@ package com.budwk.app.zhgh.staffbenefit.condolence.service; import com.budwk.app.base.service.BaseService; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence; +import org.nutz.lang.util.NutMap; + +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.util.List; /** * @ClassName CondolenceService @@ -11,4 +18,68 @@ import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence; * @Description TODO */ public interface CondolenceService extends BaseService { + + /** + * 导出已完成流程的慰问报销单。 + * + * @param id 慰问申请ID + * @param response 文件下载响应 + */ + void exportReimbursement(String id, HttpServletResponse response); + + /** + * 查询阅览页列表数据,月份优先于年度筛选。 + * + * @param pageForm 分页筛选参数 + * @param year 年度 + * @param month 月份,格式 yyyy-MM + * @param type 慰问类型 + * @param unionId 所属工会 + * @param unitId 所属单位 + * @param userState 慰问对象在职状态 + * @return 阅览页分页数据 + */ + Pagination pageReadData(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState); + + /** + * 统计阅览页筛选条件下的慰问金额合计。 + * + * @param pageForm 分页筛选参数 + * @param year 年度 + * @param month 月份,格式 yyyy-MM + * @param type 慰问类型 + * @param unionId 所属工会 + * @param unitId 所属单位 + * @param userState 慰问对象在职状态 + * @return 慰问金额合计 + */ + BigDecimal sumReadMoney(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState); + + /** + * 查询阅览页筛选出的已完成慰问数据。 + * + * @param pageForm 分页筛选参数 + * @param year 年度 + * @param month 月份,格式 yyyy-MM + * @param type 慰问类型 + * @param unionId 所属工会 + * @param unitId 所属单位 + * @param userState 慰问对象在职状态 + * @return 已完成慰问数据 + */ + List listCompletedReadData(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState); + + /** + * 导出阅览页筛选出的慰问附件和报销单压缩包。 + * + * @param pageForm 分页筛选参数 + * @param year 年度 + * @param month 月份,格式 yyyy-MM + * @param type 慰问类型 + * @param unionId 所属工会 + * @param unitId 所属单位 + * @param userState 慰问对象在职状态 + * @param response 文件下载响应 + */ + void exportReadZip(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState, HttpServletResponse response); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/impl/CondolenceServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/impl/CondolenceServiceImpl.java index 2b6eecec..c7997c4c 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/impl/CondolenceServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/condolence/service/impl/CondolenceServiceImpl.java @@ -1,11 +1,52 @@ package com.budwk.app.zhgh.staffbenefit.condolence.service.impl; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.URLUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.base.utils.SysOfficeTemplateUtil; +import com.budwk.app.flow.engine.FlowEngine; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.flow.vo.ProcessTaskVO; +import com.budwk.app.sys.services.SysFileService; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence; import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceService; +import com.deepoove.poi.XWPFTemplate; import lombok.extern.slf4j.Slf4j; import org.nutz.dao.Dao; +import org.nutz.dao.Cnd; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; +import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; + +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * @ClassName CondolenceServiceImpl @@ -18,7 +59,418 @@ import org.nutz.ioc.loader.annotation.IocBean; @IocBean(args = {"refer:dao"}) public class CondolenceServiceImpl extends BaseServiceImpl implements CondolenceService { + private static final String[] RMB_UPPER_DIGITS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}; + + @Inject + private FlowEngine flowEngine; + @Inject + private SysOfficeTemplateUtil sysOfficeTemplateUtil; + @Inject + private SysFileService sysFileService; + public CondolenceServiceImpl(Dao dao) { super(dao); } + + @Override + public void exportReimbursement(String id, HttpServletResponse response) { + NutMap info = fetchCompletedCondolenceInfo(id); + String memberName = StrUtil.blankToDefault(info.getString("helpUserName"), "慰问"); + CommonDownloadUtil.download(memberName + "慰问报销单.docx", createReimbursementDocxBytes(info), response); + } + + @Override + public Pagination pageReadData(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState) { + Sql sql = buildReadSql(pageForm, year, month, type, unionId, unitId, userState, false, true); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + @Override + public BigDecimal sumReadMoney(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState) { + Sql sql = Sqls.create(""" + SELECT + COALESCE(SUM(info.money), 0) AS totalMoney + FROM + condolence info + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN condolence_type type ON type.id = info.type + LEFT JOIN `vw_user` helpUser ON helpUser.id = info.helpUserId + $condition + """); + sql.setCondition(buildReadCondition(pageForm, year, month, type, unionId, unitId, userState, false, false)); + sql.setCallback(Sqls.callback.map()); + dao().execute(sql); + NutMap result = (NutMap) sql.getResult(); + return toBigDecimal(result == null ? null : result.get("totalMoney")); + } + + @Override + public List listCompletedReadData(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState) { + Sql sql = buildReadSql(pageForm, year, month, type, unionId, unitId, userState, true, false); + return listMap(sql); + } + + @Override + public void exportReadZip(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState, HttpServletResponse response) { + List list = listCompletedReadData(pageForm, year, month, type, unionId, unitId, userState); + response.setContentType("application/octet-stream;charset=UTF-8"); + response.setHeader("Content-Disposition", "attachment;filename=" + URLUtil.encode("职工慰问附件.zip")); + try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) { + Set entryNames = new HashSet<>(); + for (int i = 0; i < list.size(); i++) { + NutMap row = list.get(i); + String folderName = uniqueEntryName(entryNames, buildRowFolderName(row, i + 1) + "/"); + zipOutputStream.putNextEntry(new ZipEntry(folderName)); + zipOutputStream.closeEntry(); + + writeZipEntry(zipOutputStream, entryNames, folderName + sanitizeFileName(row.getString("helpUserName")) + "慰问报销单.docx", createReimbursementDocxBytes(row)); + writeAttachmentFolder(zipOutputStream, entryNames, folderName, row); + } + zipOutputStream.finish(); + } catch (IOException e) { + log.error("职工慰问附件ZIP导出失败,错误信息:{}", e.getMessage()); + } + } + + /** + * 阅览页、ZIP 和 Excel 导出共用同一套筛选条件,避免不同出口查出的人员不一致。 + */ + private Sql buildReadSql(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState, boolean completedOnly, boolean withTask) { + Sql sql = Sqls.create(withTask ? """ + SELECT + info.*, + helpUser.userState AS userState, + ins.id AS instanceId, + type.name AS typeName, + ins.state AS instanceState, + ins.processDefineId AS instanceProcessDefineId, + t.displayName AS taskName + FROM + condolence info + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN ( + SELECT + processInstanceId, + displayName, + createdAt, + ROW_NUMBER() OVER (PARTITION BY processInstanceId ORDER BY createdAt DESC) AS rn + FROM wf_process_task + ) t ON t.processInstanceId = ins.id AND t.rn = 1 + LEFT JOIN condolence_type type ON info.type = type.id + LEFT JOIN `vw_user` helpUser ON helpUser.id = info.helpUserId + $condition + """ : """ + SELECT + info.*, + helpUser.userState AS userState, + type.name AS typeName, + ins.id AS instanceId + FROM + condolence info + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN condolence_type type ON type.id = info.type + LEFT JOIN `vw_user` helpUser ON helpUser.id = info.helpUserId + $condition + """); + sql.setCondition(buildReadCondition(pageForm, year, month, type, unionId, unitId, userState, completedOnly, true)); + return sql; + } + + /** + * 组装阅览页查询条件,月份筛选优先于年度筛选。 + */ + private Cnd buildReadCondition(PageForm pageForm, Integer year, String month, String type, String unionId, String unitId, String userState, boolean completedOnly, boolean withOrder) { + Cnd cnd = Cnd.NEW(); + if (completedOnly) { + cnd.and("ins.state", "=", ProcessTaskStateEnum.FINISHED.getCode()); + } + cnd.andEX("info.type", "=", type); + if (StrUtil.isNotBlank(month)) { + cnd.and("DATE_FORMAT(info.createTime, '%Y-%m')", "=", month); + } else { + cnd.andEX("YEAR(info.createTime)", "=", year); + } + cnd.andEX("info.applyUnionId", "=", unionId); + cnd.andEX("info.applyUnitId", "=", unitId); + cnd.andEX("helpUser.userState", "=", userState); + if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.or("info.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%"); + seg.or("info.helpLoginName", "like", "%" + pageForm.getSearchKeyword() + "%"); + cnd.and(seg); + } + if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) { + cnd.and("info.applyUnionId", "=", SecurityUtil.getUnionId()); + } + if (withOrder) { + if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { + cnd.desc("info.createTime"); + } else { + cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); + } + } + return cnd; + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); + } + if (value instanceof BigDecimal) { + return ((BigDecimal) value).setScale(2, RoundingMode.HALF_UP); + } + return new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP); + } + + /** + * 根据慰问记录生成报销单 Word 字节,供单条导出和 ZIP 导出复用。 + */ + private byte[] createReimbursementDocxBytes(NutMap info) { + HashMap docData = new HashMap<>(); + docData.put("condolenceType", info.getString("typeName")); + docData.put("applyTime", formatDocDate(info.getString("createTime"))); + docData.put("condolenceTime", info.getString("occurTime")); + docData.put("memberName", info.getString("helpUserName")); + docData.put("reason", info.getString("remark")); + docData.put("condolenceMoney", formatMoney(info.getDouble("money"))); + docData.put("applyUserName", info.getString("applyUserName")); + docData.put("bankCardNumber", info.getString("bankCardNumber")); + docData.put("bankOfDeposit", info.getString("bankOfDeposit")); + putPictureRenderData(docData, info.getString("signature"), "applyUserSign", "applyUserSignature", "申请人签字"); + // 慰问金额合计(大写)按模板格子拆成“仟、佰、拾、元、角、分”六个字段。 + docData.putAll(buildMoneyDigitMap(info.getDouble("money"))); + + List doneTaskVos = getDoneTaskVos(info.getLong("instanceId")); + putApprovalSign(docData, doneTaskVos, "分工会审核", "branchChairmanSign", "branchChairmanSignTime", "branchChairmanTime", "分工会主席填写时间"); + putApprovalSign(docData, doneTaskVos, "校工会审核", "unionChairmanSign", "unionChairmanSignTime", "unionChairmanTime", "工会主席填写时间"); + + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("condolence")) + .render(docData) + .writeAndClose(byteArrayOutputStream); + return byteArrayOutputStream.toByteArray(); + } catch (IOException e) { + log.error("慰问报销单生成失败,id:{},错误信息:{}", info.getString("id"), e.getMessage()); + return new byte[0]; + } + } + + private void writeAttachmentFolder(ZipOutputStream zipOutputStream, Set entryNames, String folderName, NutMap row) throws IOException { + String attachmentFolder = folderName + "附件/"; + zipOutputStream.putNextEntry(new ZipEntry(uniqueEntryName(entryNames, attachmentFolder))); + zipOutputStream.closeEntry(); + List files = parseFiles(row.getString("files")); + for (int i = 0; i < files.size(); i++) { + JSONObject file = files.get(i); + String fileId = getFileId(file); + if (StrUtil.isBlank(fileId)) { + continue; + } + try { + String fileName = sanitizeFileName(StrUtil.blankToDefault(file.getStr("name"), "附件" + (i + 1))); + writeZipEntry(zipOutputStream, entryNames, attachmentFolder + fileName, sysFileService.download(fileId)); + } catch (Exception e) { + log.error("慰问附件写入ZIP失败,慰问ID:{},文件ID:{},错误信息:{}", row.getString("id"), fileId, e.getMessage()); + } + } + } + + private List parseFiles(String filesStr) { + if (StrUtil.isBlank(filesStr)) { + return new ArrayList<>(); + } + try { + return JSONUtil.parseArray(filesStr).toList(JSONObject.class); + } catch (Exception e) { + log.error("慰问附件解析失败,附件内容:{}", filesStr); + return new ArrayList<>(); + } + } + + private String getFileId(JSONObject file) { + String filePath = ""; + JSONObject response = file.getJSONObject("response"); + if (response != null) { + filePath = response.getStr("data"); + } + if (StrUtil.isBlank(filePath)) { + filePath = file.getStr("url"); + } + if (StrUtil.isBlank(filePath)) { + filePath = file.getStr("downloadPath"); + } + if (StrUtil.isBlank(filePath)) { + filePath = file.getStr("id"); + } + if (StrUtil.isBlank(filePath)) { + return ""; + } + int index = filePath.indexOf("id="); + if (index >= 0) { + return filePath.substring(index + 3); + } + return filePath; + } + + private void writeZipEntry(ZipOutputStream zipOutputStream, Set entryNames, String entryName, byte[] bytes) throws IOException { + if (bytes == null || bytes.length == 0) { + return; + } + zipOutputStream.putNextEntry(new ZipEntry(uniqueEntryName(entryNames, entryName))); + zipOutputStream.write(bytes); + zipOutputStream.closeEntry(); + } + + private String buildRowFolderName(NutMap row, int index) { + String name = StrUtil.blankToDefault(row.getString("helpUserName"), "慰问人"); + String loginName = StrUtil.blankToDefault(row.getString("helpLoginName"), ""); + String createTime = StrUtil.blankToDefault(row.getString("createTime"), ""); + String folderName = index + "." + name + (StrUtil.isBlank(loginName) ? "" : "_" + loginName) + "_" + createTime; + return sanitizeFileName(folderName); + } + + private String sanitizeFileName(String fileName) { + String name = StrUtil.blankToDefault(fileName, "未命名"); + return name.replaceAll("[\\\\/:*?\"<>|\\r\\n]", "_"); + } + + private String uniqueEntryName(Set entryNames, String entryName) { + String name = entryName; + int count = 1; + while (entryNames.contains(name)) { + int slashIndex = entryName.lastIndexOf("/"); + int dotIndex = entryName.lastIndexOf("."); + if (dotIndex > slashIndex) { + name = entryName.substring(0, dotIndex) + "(" + count + ")" + entryName.substring(dotIndex); + } else if (entryName.endsWith("/")) { + name = entryName.substring(0, entryName.length() - 1) + "(" + count + ")/"; + } else { + name = entryName + "(" + count + ")"; + } + count++; + } + entryNames.add(name); + return name; + } + + /** + * 只允许已完成流程导出,避免未审批完成的数据生成正式报销单。 + */ + private NutMap fetchCompletedCondolenceInfo(String id) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + ins.id AS instanceId + FROM + condolence info + LEFT JOIN condolence_type type ON info.type = type.id + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + WHERE + ins.state = 20 AND info.id = @id + """).setParam("id", id); + sql.setCallback(Sqls.callback.map()); + dao().execute(sql); + NutMap info = (NutMap) sql.getResult(); + if (info == null) { + throw new RuntimeException("慰问流程未完成或记录不存在,不能导出报销单"); + } + return info; + } + + /** + * 读取已办流程任务,后续从任务表单变量中取审批签字。 + */ + private List getDoneTaskVos(Long instanceId) { + List doneTaskVos = new ArrayList<>(); + List doneTaskList = flowEngine.processTaskService().getDoneTaskList(instanceId, null); + for (ProcessTask doneTask : doneTaskList) { + ProcessTaskVO taskVO = flowEngine.processTaskService().findById(doneTask.getId()); + doneTaskVos.add(taskVO); + } + return doneTaskVos; + } + + /** + * 将指定审批节点最近一次签字和填写时间放入模板字段。 + */ + private void putApprovalSign(Map docData, List doneTaskVos, String taskName, String templateField, String... timeFields) { + doneTaskVos.stream() + .filter(task -> taskName.equals(task.getDisplayName())) + .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) + .ifPresent(task -> { + Dict taskFormData = task.getTaskFormData(); + String signTime = taskFormData.getStr("finishTimeForDocx"); + if (StrUtil.isBlank(signTime) && task.getFinishTime() != null) { + signTime = DateUtil.format(task.getFinishTime(), "yyyy年MM月dd日"); + } + for (String timeField : timeFields) { + docData.put(timeField, signTime); + } + String sign = taskFormData.getStr("tf_userSign"); + if (StrUtil.isBlank(sign)) { + sign = taskFormData.getStr("tf_sign"); + } + if (StrUtil.isNotBlank(sign)) { + putPictureRenderData(docData, sign, templateField); + } + }); + } + + /** + * 将签字图片同时写入多个模板字段,兼容不同模板占位符命名。 + */ + private void putPictureRenderData(Map docData, String sign, String... templateFields) { + if (StrUtil.isBlank(sign)) { + return; + } + for (String templateField : templateFields) { + docData.put(templateField, sysOfficeTemplateUtil.createPictureRenderData(sign)); + } + } + + private String formatDocDate(String date) { + if (StrUtil.isBlank(date)) { + return ""; + } + try { + return DateUtil.format(DateUtil.parse(date), "yyyy年MM月dd日"); + } catch (Exception e) { + return date; + } + } + + private String formatMoney(Double money) { + if (money == null) { + return ""; + } + return BigDecimal.valueOf(money).setScale(2, RoundingMode.HALF_UP).toPlainString(); + } + + /** + * 报销单模板只预留到仟位,金额超过 9999.99 时直接提示,防止生成错误单据。 + */ + private Map buildMoneyDigitMap(Double money) { + BigDecimal amount = money == null ? BigDecimal.ZERO : BigDecimal.valueOf(money); + amount = amount.setScale(2, RoundingMode.HALF_UP); + if (amount.compareTo(new BigDecimal("9999.99")) > 0) { + throw new RuntimeException("慰问金额超过报销单模板支持范围"); + } + long cents = amount.movePointRight(2).longValue(); + Map map = new HashMap<>(); + map.put("Qian", toUpperDigit((int) (cents / 100000 % 10))); + map.put("Bai", toUpperDigit((int) (cents / 10000 % 10))); + map.put("Shi", toUpperDigit((int) (cents / 1000 % 10))); + map.put("Yuan", toUpperDigit((int) (cents / 100 % 10))); + map.put("Jiao", toUpperDigit((int) (cents / 10 % 10))); + map.put("Fen", toUpperDigit((int) (cents % 10))); + return map; + } + + private String toUpperDigit(int digit) { + if (digit < 0 || digit > 9) { + return ""; + } + return RMB_UPPER_DIGITS[digit]; + } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 4a00be9d..87e2ef24 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,17 +1,85 @@ - + - + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - + + + + + + ${LOG_HOME}/app.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + ${LOG_HOME}/app-%d{yyyy-MM-dd}.log + 300 + + + + + + + + + + + + + + + + + + + + + + + + <!– ERROR级别日志文件配置 –> ${LOG_HOME}/error.log @@ -41,19 +109,31 @@ ${LOG_HOME}/error-%d{yyyy-MM-dd}.log - 30 + 300 - + <!– 框架日志级别 –> + <!– –> - + <!– 日志级别和appender的关联 –> + - + --> + + + + diff --git a/src/main/resources/views/layouts/v4/home/user.js b/src/main/resources/views/layouts/v4/home/user.js index 10fde3b2..03cfb61b 100644 --- a/src/main/resources/views/layouts/v4/home/user.js +++ b/src/main/resources/views/layouts/v4/home/user.js @@ -258,7 +258,12 @@ const user = { this.$message.warning("当前流程没有配置地址") return } - window.open(formKey + "?taskId=" + taskId + "&bizId=" + businessNo + "&taskKey=" + taskKey + "&tab=" + this.activeTab) + var viewUrl = formKey + "?taskId=" + taskId + "&bizId=" + businessNo + "&taskKey=" + taskKey + "&tab=" + this.activeTab + // 首页待办进入提案附议 second 节点时,默认打开受邀附议页签,避免影响其他流程跳转。 + if (formKey === "/platform/proposal/seconded" && taskKey === "second" && this.activeTab === "todo") { + viewUrl += "&secondedTab=inviteSeconded" + } + window.open(viewUrl) }, getRoleNames() { $.post("/platform/sys/role/getRoleNames").then(res => { diff --git a/src/main/resources/views/layouts/v4/todo.html b/src/main/resources/views/layouts/v4/todo.html index 06bfecaa..1b4f732a 100644 --- a/src/main/resources/views/layouts/v4/todo.html +++ b/src/main/resources/views/layouts/v4/todo.html @@ -420,7 +420,12 @@ layout("/layouts/v4/baseLayout.html"){ this.$message.warning("当前流程没有配置地址") return } - window.open(formKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey) + var viewUrl = formKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey + // 待办中心进入提案附议 second 节点时,默认打开受邀附议页签,避免影响其他流程跳转。 + if (formKey === "/platform/proposal/seconded" && taskKey === "second" && this.activeTab === "todo") { + viewUrl += "&secondedTab=inviteSeconded" + } + window.open(viewUrl) }, // 获取空状态文本 diff --git a/src/main/resources/views/platform/flow/todoCenter/index.html b/src/main/resources/views/platform/flow/todoCenter/index.html index e7458d5d..e6c6f8b4 100644 --- a/src/main/resources/views/platform/flow/todoCenter/index.html +++ b/src/main/resources/views/platform/flow/todoCenter/index.html @@ -464,7 +464,12 @@ layout("/layouts/v4/baseLayout.html"){ this.$message.warning("当前流程没有配置地址") return } - window.open(formKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey) + var viewUrl = formKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey + // 待办中心进入提案附议 second 节点时,默认打开受邀附议页签,避免影响其他流程跳转。 + if (formKey === "/platform/proposal/seconded" && taskKey === "second" && this.activeTab === "todo") { + viewUrl += "&secondedTab=inviteSeconded" + } + window.open(viewUrl) }, // 获取空状态文本 diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html index 984199f6..0be23e2c 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html @@ -337,12 +337,13 @@ layout("/layouts/platform.html"){ }, listSession() { this.$axios.post("/platform/proposal/common/listSession", { - orderBy: "asc" + orderBy: "desc" }).then((res) => { if (res.code === 0) { this.sessionOptions = res.data if (this.sessionOptions) { this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id) + this.$set(this.pageForm, "sessionIds", [this.sessionOptions[0].id]) this.listDelegation() this.pageData() } diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/query/satisfactionStatistics/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/query/satisfactionStatistics/index.html new file mode 100644 index 00000000..f1574366 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/query/satisfactionStatistics/index.html @@ -0,0 +1,106 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html index 20da45d6..39661193 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html @@ -87,7 +87,7 @@ layout("/layouts/platform.html"){ 查看 审核 - 撤回 + 撤回 diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html index a212b3af..96931278 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html @@ -205,6 +205,14 @@ layout("/layouts/platform.html"){ } }, methods: { + initSecondedTab: function () { + // 只响应首页待办跳转传入的提案附议专用参数,普通菜单进入仍默认主动附议。 + if (GetQueryString("secondedTab") === "inviteSeconded") { + this.$set(this, "activeTab", "inviteSeconded") + this.$set(this.pageForm, "approval", false) + } + }, + syncTableColumns: function () { if (this.activeTab === "inviteSeconded") { this.$set(this, "tableColumns", this.inviteColumns) @@ -455,6 +463,7 @@ layout("/layouts/platform.html"){ } }, created() { + this.initSecondedTab() this.syncTableColumns() this.pageData() this.listOpenSession() diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/condolence/branchUnionApproval/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/condolence/branchUnionApproval/index.html index 9afd3410..b21da14b 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/condolence/branchUnionApproval/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/condolence/branchUnionApproval/index.html @@ -81,6 +81,10 @@ layout("/layouts/platform.html"){ :rules="[{required:true,message:'必填',trigger:['change','blur']}]"> + + + 取消 @@ -135,7 +139,8 @@ layout("/layouts/platform.html"){ this.showApprovalForm = true this.formData = { processTaskId: row.taskId, - taskName: row.curTaskName + taskName: row.curTaskName, + tf_userSign: null } this.$refs.condolenceInfoRef.onOpen(row) }) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/condolence/mine/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/condolence/mine/index.html index 662aea6b..14ebfd97 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/condolence/mine/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/condolence/mine/index.html @@ -60,6 +60,7 @@ layout("/layouts/platform.html"){