Merge branch 'dev' of http://47.97.8.94:19527/yj/zn-cloud into dev-考勤

This commit is contained in:
aikai 2024-05-08 09:34:56 +08:00
commit 8b42d7862f
60 changed files with 2241 additions and 110 deletions

View File

@ -31,6 +31,7 @@ public interface ErrorCodeConstants {
ErrorCode OA_SHIFTJOBS_NOT_EXISTS = new ErrorCode(1_009_001_107, "调岗申请不存在"); ErrorCode OA_SHIFTJOBS_NOT_EXISTS = new ErrorCode(1_009_001_107, "调岗申请不存在");
ErrorCode OA_SECOND_NOT_EXISTS = new ErrorCode(1_009_001_108, "借调申请不存在"); ErrorCode OA_SECOND_NOT_EXISTS = new ErrorCode(1_009_001_108, "借调申请不存在");
ErrorCode OA_IMPREST_NOT_EXISTS = new ErrorCode(1_009_001_109, "备用金申请不存在"); ErrorCode OA_IMPREST_NOT_EXISTS = new ErrorCode(1_009_001_109, "备用金申请不存在");
ErrorCode OA_INCENTIVE_NOT_EXISTS = new ErrorCode(1_009_001_110, "奖惩申请不存在");
// ========== 流程模型 1-009-002-000 ========== // ========== 流程模型 1-009-002-000 ==========
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程"); ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程");

View File

@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive.BpmOAIncentiveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive.BpmOAIncentiveRespVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAIncentiveConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAIncentiveDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAIncentiveService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
/**
* OA 奖惩申请 Controller
*
* @author 符溶馨
*/
@Tag(name = "管理后台 - OA 奖惩申请")
@RestController
@RequestMapping("/bpm/oa/incentive")
@Validated
public class BpmOAIncentiveController {
@Resource
private BpmOAIncentiveService incentiveService;
@Resource
private AdminUserApi userApi;
@Resource
private DeptApi deptApi;
@PostMapping("/create")
@Operation(summary = "创建请求申请")
public CommonResult<Long> createIncentive(@Valid @RequestBody BpmOAIncentiveCreateReqVO createReqVO) {
return success(incentiveService.createIncentive(getLoginUserId(), createReqVO));
}
@GetMapping("/get")
@Operation(summary = "获得奖惩申请")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<BpmOAIncentiveRespVO> getIncentive(@RequestParam("id") Long id) {
BpmOAIncentiveDO incentive = incentiveService.getIncentive(id);
//获得 用户信息集合
List<AdminUserRespDTO> userRespDTO = userApi.getUserListByDeptIds(incentive.getIncentiveDeptIds()).getCheckedData();
//获得 部门信息集合
Map<Long, DeptRespDTO> deptRespDTOS = deptApi.getDeptMap(incentive.getIncentiveDeptIds());
Map<String, List<String>> userInfo = new HashMap<>();
//遍历 部门map集合
deptRespDTOS.forEach((key, value) -> {
List<String> userName = userRespDTO.stream().filter(user -> user.getDeptId().toString().contains(key.toString())
&& incentive.getIncentiveUserIds().contains(user.getId()))
.map(AdminUserRespDTO::getNickname).collect(Collectors.toList());
userInfo.put(value.getName(), userName);
});
BpmOAIncentiveRespVO bpmOAIncentiveRespVO = BpmOAIncentiveConvert.INSTANCE.convert(incentive);
bpmOAIncentiveRespVO.setUserInfo(userInfo);
return success(bpmOAIncentiveRespVO);
}
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAReimbursementConvert; import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAReimbursementConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementService; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementService;
@ -34,7 +35,7 @@ public class BpmOAReimbursementController {
@PostMapping("/create") @PostMapping("/create")
// @PreAuthorize("@ss.hasPermission('bpm:oa-reimbursement:create')") // @PreAuthorize("@ss.hasPermission('bpm:oa-reimbursement:create')")
@Operation(summary = "创建请求申请") @Operation(summary = "创建请求申请")
public CommonResult<Long> createLeave(@Valid @RequestBody BpmOAReimbursementCreateReqVO createReqVO) { public CommonResult<Long> createReimbursement(@Valid @RequestBody BpmOAReimbursementCreateReqVO createReqVO) {
return success(service.createReimbursement(getLoginUserId(), createReqVO)); return success(service.createReimbursement(getLoginUserId(), createReqVO));
} }
@ -42,9 +43,10 @@ public class BpmOAReimbursementController {
// @PreAuthorize("@ss.hasPermission('bpm:oa-reimbursement:query')") // @PreAuthorize("@ss.hasPermission('bpm:oa-reimbursement:query')")
@Operation(summary = "获得报销申请") @Operation(summary = "获得报销申请")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<?> getLeave(@RequestParam("id") Long id) { public CommonResult<BpmOAReimbursementRespVO> getReimbursement(@RequestParam("id") Long id) {
BpmOAReimbursementDO reimbursement = service.getReimbursement(id); BpmOAReimbursementDO reimbursement = service.getReimbursement(id);
return success(BpmOAReimbursementConvert.INSTANCE.convert(reimbursement)); return success(service.convert(reimbursement));
} }
// @GetMapping("/page") // @GetMapping("/page")

View File

@ -0,0 +1,51 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive;
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 奖惩申请创建 Request VO")
@Data
@EqualsAndHashCode()
@ToString(callSuper = true)
public class BpmOAIncentiveCreateReqVO {
@Schema(description = "奖惩类型 字典值参考 bpm_oa_incentive_type", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "奖惩类型不能为空")
private Integer type;
@Schema(description = "奖惩人编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "奖惩人编号不能为空")
private Set<Long> incentiveUserIds;
@Schema(description = "奖惩人部门编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "奖惩人部门编号不能为空")
private Set<Long> incentiveDeptIds;
@Schema(description = "奖惩时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "奖惩时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime time;
@Schema(description = "奖惩金额", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "奖惩金额不能为空")
private BigDecimal amount;
@Schema(description = "奖惩事由", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "奖惩事由不能为空")
private String reason;
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
private List<UploadUserFile> fileItems ;
}

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 奖惩申请响应数据 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOAIncentiveRespVO extends BpmOABaseRespVO {
@Schema(description = "奖惩类型 字典值参考 bpm_oa_incentive_type")
private Integer type;
@Schema(description = "奖惩人信息列表 key:部门名称, value:用户名称集合")
private Map<String, List<String>> userInfo;
@Schema(description = "奖惩时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime time;
@Schema(description = "奖惩金额")
private BigDecimal amount;
@Schema(description = "奖惩事由")
private String reason;
@Schema(description = "上传文件")
private List<UploadUserFile> fileItems ;
}

View File

@ -1,4 +1,5 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print; package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.print;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
@ -21,4 +22,22 @@ public class BpmOAReimbursementPrintDataRespVO extends BpmOABaseRespVO {
@Schema(description = "流程审批节点信息【包含人员签名地址】", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "流程审批节点信息【包含人员签名地址】", requiredMode = Schema.RequiredMode.REQUIRED)
List<BpmTaskRespVO> processTasks ; List<BpmTaskRespVO> processTasks ;
/**
* 抄送用户信息
*/
private List<CCUser> ccUsers;
@Schema(description = "抄送用户信息")
@Data
public static class CCUser {
@Schema(description = "抄送用户编号", example = "146,128")
private Long ccUserId;
@Schema(description = "抄送用户名称", example = "张三")
private String ccUserName;
@Schema(description = "抄送用户部门名称", example = "研发部")
private String ccDeptName;
}
} }

View File

@ -15,6 +15,15 @@ import java.util.List;
@ToString(callSuper = true) @ToString(callSuper = true)
public class BpmOAReimbursementCreateReqVO { public class BpmOAReimbursementCreateReqVO {
@Schema(description = "收款人名称")
private String nickname;
@Schema(description = "收款人卡号")
private String bankNo;
@Schema(description = "开户行信息")
private String bankName;
@Schema(description = "报销项目明细", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "报销项目明细", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销项目不能为空") @NotNull(message = "报销项目不能为空")
private List<Reimbursement> reimbursements; private List<Reimbursement> reimbursements;
@ -40,5 +49,4 @@ public class BpmOAReimbursementCreateReqVO {
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
private List<UploadUserFile> fileItems ; private List<UploadUserFile> fileItems ;
} }

View File

@ -18,14 +18,18 @@ public class BpmOAReimbursementRespVO extends BpmOABaseRespVO {
/** /**
* 收款人信息 * 收款人信息
*/ */
private PayeeUser payeeUser; @Schema(description = "收款人名称")
private String nickname;
@Schema(description = "报销费用归属部门ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "开户行信息")
private Long belongDeptId ; private String bankName;
@Schema(description = "收款人卡号")
private String bankNo;
@Schema(description = "报销项目明细", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "报销项目明细", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销项目不能为空") @NotNull(message = "报销项目不能为空")
private List<Reimbursement> reimbursements; private List<ReimbursementDTO> reimbursements;
@Schema(description = "报销总金额", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "报销总金额", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销总金额不能为空") @NotNull(message = "报销总金额不能为空")
@ -39,7 +43,10 @@ public class BpmOAReimbursementRespVO extends BpmOABaseRespVO {
@NotNull(message = "报销类型不能为空") @NotNull(message = "报销类型不能为空")
private BigDecimal reimbursementType ; private BigDecimal reimbursementType ;
@Schema(description = "备用金差额", requiredMode = Schema.RequiredMode.NOT_REQUIRED) @Schema(description = "备用金金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private BigDecimal amount ;
@Schema(description = "备用金差额 = 备用金额 - 报销总金额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private BigDecimal difference ; private BigDecimal difference ;
@Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED)
@ -48,33 +55,4 @@ public class BpmOAReimbursementRespVO extends BpmOABaseRespVO {
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
private List<UploadUserFile> fileItems ; private List<UploadUserFile> fileItems ;
@Schema(description = "收款人信息")
@Data
public static class PayeeUser {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
private String nickname;
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long deptId;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
private String deptName;
@Schema(description = "电子签名", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://xxx.jpg")
private String signURL;
@Schema(description = "用户银行卡业务表ID", requiredMode = Schema.RequiredMode.REQUIRED)
private Long bankId;
@Schema(description = "开户行信息", requiredMode = Schema.RequiredMode.REQUIRED)
private String bankNName;
@Schema(description = "银行卡号", requiredMode = Schema.RequiredMode.REQUIRED)
private String bankNo;
}
} }

View File

@ -15,10 +15,13 @@ import java.util.Date;
@Data @Data
public class Reimbursement { public class Reimbursement {
@Schema(description = "所属部门ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "128")
private Long deptId;
@Schema(description = "报销金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "23.45") @Schema(description = "报销金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "23.45")
private BigDecimal money; private BigDecimal money;
@Schema(description = "报销类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "如:住宿、火车票、宴请等") @Schema(description = "报销类别 字典值 参考 bpm_oa_reimbursement_type", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String type; private String type;
@Schema(description = "发生时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-09 12:31:12") @Schema(description = "发生时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-09 12:31:12")
@ -29,4 +32,7 @@ public class Reimbursement {
@Schema(description = "费用明细", requiredMode = Schema.RequiredMode.REQUIRED, example = "请吃饭") @Schema(description = "费用明细", requiredMode = Schema.RequiredMode.REQUIRED, example = "请吃饭")
private String detail ; private String detail ;
@Schema(description = "采购计划编号", example = "1")
private Long procureId;
} }

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 功能描述 报销项目明细
* 前端返回值用
*/
@Data
public class ReimbursementDTO {
@Schema(description = "所属部门ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "128")
private Long deptId;
@Schema(description = "所属部门名称", example = "研发部")
private String deptName;
@Schema(description = "报销金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "23.45")
private BigDecimal money;
@Schema(description = "报销类别 字典值 参考 bpm_oa_reimbursement_type", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String type;
@Schema(description = "发生时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-09 12:31:12")
private Date happenTime;
@Schema(description = "发票张数", requiredMode = Schema.RequiredMode.REQUIRED, example = "3")
private Integer quantity ;
@Schema(description = "费用明细", requiredMode = Schema.RequiredMode.REQUIRED, example = "请吃饭")
private String detail ;
@Schema(description = "采购计划编号", example = "1")
private Long procureId;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.bpm.convert.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive.BpmOAIncentiveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive.BpmOAIncentiveRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAIncentiveDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 奖惩申请 Convert
*
* @author 符溶馨
*/
@Mapper
public interface BpmOAIncentiveConvert {
BpmOAIncentiveConvert INSTANCE = Mappers.getMapper(BpmOAIncentiveConvert.class);
BpmOAIncentiveDO convert(BpmOAIncentiveCreateReqVO bean);
BpmOAIncentiveRespVO convert(BpmOAIncentiveDO bean);
}

View File

@ -1,11 +1,18 @@
package cn.iocoder.yudao.module.bpm.convert.oa; package cn.iocoder.yudao.module.bpm.convert.oa;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.Reimbursement;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.ReimbursementDTO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
/** /**
* 报销申请 Convert * 报销申请 Convert
* *
@ -18,10 +25,18 @@ public interface BpmOAReimbursementConvert {
BpmOAReimbursementDO convert(BpmOAReimbursementCreateReqVO bean); BpmOAReimbursementDO convert(BpmOAReimbursementCreateReqVO bean);
BpmOAReimbursementRespVO convert(BpmOAReimbursementDO bean); default List<ReimbursementDTO> convertList(List<ReimbursementDTO> list, Map<Long, DeptRespDTO> deptMap) {
//
// List<BpmOALeaveRespVO> convertList(List<BpmOALeaveDO> list); return CollectionUtils.convertList(list, reimbursement -> convert(reimbursement, deptMap.get(reimbursement.getDeptId())));
// }
// PageResult<BpmOALeaveRespVO> convertPage(PageResult<BpmOALeaveDO> page);
default ReimbursementDTO convert(ReimbursementDTO reimbursement, DeptRespDTO dept) {
if (dept != null) {
reimbursement.setDeptName(dept.getName());
}
return reimbursement;
}
} }

View File

@ -0,0 +1,97 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
/**
* OA 奖惩申请 DO
*
* @author 符溶馨
*/
@TableName(value ="bpm_oa_incentive", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAIncentiveDO extends BaseDO {
/**
* 出差表单主键
*/
@TableId
private Long id;
/**
* 申请人的用户编号
*/
private Long userId;
/**
* 奖惩类型
* 1:奖励 2:惩罚
*/
private Integer type;
/**
* 奖惩人用户编号
*/
@TableField(typeHandler = JsonLongSetTypeHandler.class)
private Set<Long> incentiveUserIds;
/**
* 奖惩人部门编号
*/
@TableField(typeHandler = JsonLongSetTypeHandler.class)
private Set<Long> incentiveDeptIds;
/**
* 奖惩时间
*/
private LocalDateTime time;
/**
* 奖惩金额
*/
private BigDecimal amount;
/**
* 奖惩事由
*/
private String reason;
/**
* 用章的结果
*
* 枚举 {@link BpmProcessInstanceResultEnum}
* 考虑到简单所以直接复用了 BpmProcessInstanceResultEnum 枚举也可以自己定义一个枚举哈
*/
private Integer result;
/**
* 对应的流程编号
*
* 关联 ProcessInstance id 属性
*/
private String processInstanceId;
/**
* 附件基本信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<UploadUserFile> fileItems ;
}

View File

@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*; import lombok.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
/** /**
@ -49,6 +50,21 @@ public class BpmOAReimbursementDO extends BaseDO {
*/ */
private Long userId; private Long userId;
/**
* 收款人名称
*/
private String nickname;
/**
* 收款人卡号
*/
private String bankNo;
/**
* 开户行信息
*/
private String bankName;
/** /**
* 报销明细数据JSON * 报销明细数据JSON
*/ */

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAIncentiveDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 奖惩申请 Mapper
*
* @author 符溶馨
*/
@Mapper
public interface BpmOAIncentiveMapper extends BaseMapperX<BpmOAIncentiveDO> {
}

View File

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive.BpmOAIncentiveCreateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAIncentiveDO;
import javax.validation.Valid;
/**
* 奖惩申请 Service 接口
*
* @author 符溶馨
*/
public interface BpmOAIncentiveService {
/**
* 创建奖惩申请
*
* @param userId 用户编号
* @param createReqVO 创建信息
* @return 编号
*/
Long createIncentive(Long userId, @Valid BpmOAIncentiveCreateReqVO createReqVO);
/**
* 更新奖惩申请的状态
*
* @param id 编号
* @param result 结果
*/
void updateIncentiveResult(Long id, Integer result);
/**
* 获得奖惩申请
*
* @param id 编号
* @return 奖惩申请
*/
BpmOAIncentiveDO getIncentive(Long id);
}

View File

@ -0,0 +1,86 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.incentive.BpmOAIncentiveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAIncentiveConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAIncentiveDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAIncentiveMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_INCENTIVE_NOT_EXISTS;
/**
* OA 奖惩申请 Service 实现类
*
* @author 符溶馨
*/
@Service
@Validated
public class BpmOAIncentiveServiceImpl extends BpmOABaseService implements BpmOAIncentiveService{
/**
* OA 奖惩对应的流程定义 KEY
*/
public static final String PROCESS_KEY = "oa_incentive";
@Resource
private BpmOAIncentiveMapper incentiveMapper;
@Resource
private BpmProcessInstanceApi processInstanceApi;
@Override
public Long createIncentive(Long userId, BpmOAIncentiveCreateReqVO createReqVO) {
//插入OA 奖惩申请
BpmOAIncentiveDO incentive = BpmOAIncentiveConvert.INSTANCE.convert(createReqVO).setUserId(userId)
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
incentiveMapper.insert(incentive) ;
// 发起 BPM 流程
Map<String, Object> processInstanceVariables = new HashMap<>();
String processInstanceId = processInstanceApi.createProcessInstance(userId,
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(incentive.getId()))).getCheckedData();
// 将工作流的编号更新到 OA 奖惩单中
incentiveMapper.updateById(new BpmOAIncentiveDO().setId(incentive.getId()).setProcessInstanceId(processInstanceId));
List<UploadUserFile> fileItems = createReqVO.getFileItems() ;
//这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id
if (fileItems != null && !fileItems.isEmpty()) {
uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ;
}
return incentive.getId();
}
@Override
public void updateIncentiveResult(Long id, Integer result) {
validateLeaveExists(id);
incentiveMapper.updateById(new BpmOAIncentiveDO().setId(id).setResult(result));
}
private void validateLeaveExists(Long id) {
if (incentiveMapper.selectById(id) == null) {
throw exception(OA_INCENTIVE_NOT_EXISTS);
}
}
@Override
public BpmOAIncentiveDO getIncentive(Long id) {
return incentiveMapper.selectById(id);
}
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import javax.validation.Valid; import javax.validation.Valid;
@ -40,13 +41,5 @@ public interface BpmOAReimbursementService {
*/ */
BpmOAReimbursementDO getReimbursement(Long id); BpmOAReimbursementDO getReimbursement(Long id);
/** BpmOAReimbursementRespVO convert(BpmOAReimbursementDO bpmOAReimbursementDO);
* 获得请假申请分页
*
* @param userId 用户编号
* @param pageReqVO 分页查询
* @return 请假申请分页
*/
// PageResult<BpmOAReimbursementDO> getLeavePage(Long userId, BpmOALeavePageReqVO pageReqVO);
} }

View File

@ -1,16 +1,27 @@
package cn.iocoder.yudao.module.bpm.service.oa; package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.procure.BpmOAProcureListEditReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.BpmOAReimbursementRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.Reimbursement;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.reimbursement.ReimbursementDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile; import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAReimbursementConvert; import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAReimbursementConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAImprestDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAProcureDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAImprestMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAImprestMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReimbursementMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReimbursementMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -18,11 +29,10 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_REIMBURSEMENT_NOT_EXISTS; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_REIMBURSEMENT_NOT_EXISTS;
/** /**
@ -57,6 +67,15 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
@Resource @Resource
private BpmOAImprestMapper bpmOAImprestMapper; private BpmOAImprestMapper bpmOAImprestMapper;
@Resource
private BpmOAProcureService bpmOAProcureService;
@Resource
private DeptApi deptApi;
@Resource
private AdminUserApi userApi;
@Override @Override
public Long createReimbursement(Long userId, BpmOAReimbursementCreateReqVO createReqVO) { public Long createReimbursement(Long userId, BpmOAReimbursementCreateReqVO createReqVO) {
BpmOAReimbursementDO reimbursement = BpmOAReimbursementConvert.INSTANCE.convert(createReqVO).setUserId(userId) BpmOAReimbursementDO reimbursement = BpmOAReimbursementConvert.INSTANCE.convert(createReqVO).setUserId(userId)
@ -78,6 +97,31 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setReimbursementId(reimbursement.getId()).setStatus(BpmOAImprestDO.IN_PROGRESS)); bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setReimbursementId(reimbursement.getId()).setStatus(BpmOAImprestDO.IN_PROGRESS));
} }
//判断是否有 采购报销
List<Long> procureIds = new ArrayList<>();
for (Reimbursement data : reimbursement.getReimbursements()) {
//报销类别为 采购费时
if ("4".equals(data.getType())) {
BpmOAProcureDO procureDO = bpmOAProcureService.getOaProcure(data.getProcureId());
if (procureDO != null) {
procureIds.add(procureDO.getId());
}
}
}
if (!procureIds.isEmpty()) {
//所有关联的采购申请改为 进行中状态
bpmOAProcureService.updatePayFlagByIds(
new BpmOAProcureListEditReqVO()
.setPayFlag(BpmOAProcureDO.IN_PROGRESS)
.setProcureIds(procureIds)
);
}
List<UploadUserFile> fileItems = createReqVO.getFileItems() ; List<UploadUserFile> fileItems = createReqVO.getFileItems() ;
//这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id //这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id
if (fileItems != null && !fileItems.isEmpty()) { if (fileItems != null && !fileItems.isEmpty()) {
@ -95,13 +139,50 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) { if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) {
ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId); ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectOne(BpmOAImprestDO::getReimbursementId, id);
if (instance.isEnded() && bpmOAImprestDO != null) { if (instance.isEnded()) {
//获得备用金信息
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectOne(BpmOAImprestDO::getReimbursementId, id);
if (bpmOAImprestDO != null) {
//将相应备用金申请状态改为 已报销 //将相应备用金申请状态改为 已报销
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.FLAG_TRUE)); bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.FLAG_TRUE));
} }
//判断是否有采购报销
List<Long> procureIds = new ArrayList<>();
BpmOAReimbursementDO bpmOAReimbursementDO = getReimbursement(id);
List<Reimbursement> reimbursements = bpmOAReimbursementDO.getReimbursements();
//直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
//将list再次转为json串然后由json串再转为list
String json = JsonUtils.toJsonString(reimbursements);
reimbursements = JsonUtils.parseArray(json, Reimbursement.class);
for (Reimbursement reimbursement : reimbursements) {
//报销类别为 采购费时
if ("4".equals(reimbursement.getType())) {
BpmOAProcureDO procureDO = bpmOAProcureService.getOaProcure(reimbursement.getProcureId());
if (procureDO != null) {
procureIds.add(procureDO.getId());
}
}
}
if (!procureIds.isEmpty()) {
//所有关联的采购申请改为 已支付状态
bpmOAProcureService.updatePayFlagByIds(
new BpmOAProcureListEditReqVO()
.setPayFlag(BpmOAProcureDO.FLAG_TRUE)
.setProcureIds(procureIds)
);
}
}
} }
// -- 自己取消 // -- 自己取消
@ -118,6 +199,39 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
//将相应备用金申请状态改为 未报销 //将相应备用金申请状态改为 未报销
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.FLAG_FALSE)); bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.FLAG_FALSE));
} }
//判断是否有采购报销
List<Long> procureIds = new ArrayList<>();
BpmOAReimbursementDO bpmOAReimbursementDO = getReimbursement(id);
List<Reimbursement> reimbursements = bpmOAReimbursementDO.getReimbursements();
//直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
//将list再次转为json串然后由json串再转为list
String json = JsonUtils.toJsonString(reimbursements);
reimbursements = JsonUtils.parseArray(json, Reimbursement.class);
for (Reimbursement reimbursement : reimbursements) {
//报销类别为 采购费时
if ("4".equals(reimbursement.getType())) {
BpmOAProcureDO procureDO = bpmOAProcureService.getOaProcure(reimbursement.getProcureId());
if (procureDO != null) {
procureIds.add(procureDO.getId());
}
}
}
if (!procureIds.isEmpty()) {
//所有关联的采购申请改为 未支付状态
bpmOAProcureService.updatePayFlagByIds(
new BpmOAProcureListEditReqVO()
.setPayFlag(BpmOAProcureDO.FLAG_FALSE)
.setProcureIds(procureIds)
);
}
} }
reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(id).setResult(result)); reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(id).setResult(result));
@ -131,6 +245,39 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
@Override @Override
public BpmOAReimbursementDO getReimbursement(Long id) { public BpmOAReimbursementDO getReimbursement(Long id) {
return reimbursementMapper.selectById(id); return reimbursementMapper.selectById(id);
} }
@Override
public BpmOAReimbursementRespVO convert(BpmOAReimbursementDO reimbursementDO) {
List<Reimbursement> reimbursement = reimbursementDO.getReimbursements();
//直接从数据库取出来的List<Reimbursement> 实际上是List<LinkedHashMap>类型 所以不能直接遍历
//将list再次转为json串然后由json串再转为list
String json = JsonUtils.toJsonString(reimbursement);
reimbursement = JsonUtils.parseArray(json, Reimbursement.class);
//针对之前的数据 没有设置明细所属部门的 手动设置发起人的部门编号
AdminUserRespDTO userRespDTO = userApi.getUser(reimbursementDO.getUserId()).getCheckedData();
for (Reimbursement data : reimbursement) {
if (data.getDeptId() != null) {
break;
}
data.setDeptId(userRespDTO.getDeptId());
}
//获取部门信息map
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(reimbursement, Reimbursement::getDeptId));
List<ReimbursementDTO> reimbursementDTOS = BeanUtils.toBean(reimbursement, ReimbursementDTO.class);
BpmOAReimbursementRespVO bpmOAReimbursementRespVO = BeanUtils.toBean(reimbursementDO, BpmOAReimbursementRespVO.class);
bpmOAReimbursementRespVO.setReimbursements(BpmOAReimbursementConvert.INSTANCE.convertList(reimbursementDTOS, deptMap)); //拼接数据
return bpmOAReimbursementRespVO;
}
} }

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.bpm.service.oa.listener;
import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAIncentiveService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAIncentiveServiceImpl;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* OA 奖惩的结果的监听器实现类
*
* @author 符溶馨
*/
@Component
public class BpmOAIncentiveResultListener extends BpmProcessInstanceResultEventListener {
@Resource
private BpmOAIncentiveService incentiveService;
@Override
protected String getProcessDefinitionKey() {
return BpmOAIncentiveServiceImpl.PROCESS_KEY;
}
@Override
protected void onEvent(BpmProcessInstanceResultEvent event) {
incentiveService.updateIncentiveResult(Long.parseLong(event.getBusinessKey()), event.getResult());
}
}

View File

@ -418,6 +418,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
paramMap.put("post_id", postId.toString()); paramMap.put("post_id", postId.toString());
paramMap.put("user_id", userId.toString()); paramMap.put("user_id", userId.toString());
paramMap.put("dept_id", startUser.getDeptId().toString()); //配置发起人部门id paramMap.put("dept_id", startUser.getDeptId().toString()); //配置发起人部门id
paramMap.put("dept_flag", startDeptInfo.getFlag()); //配置发起人部门flag
paramMap.put("approve_reason", reqVO.getReason()); //通过原因---因为Task任务的通过是通过监听事件处理的reason数据无法传递给监听函数所以通过此中方法传递 paramMap.put("approve_reason", reqVO.getReason()); //通过原因---因为Task任务的通过是通过监听事件处理的reason数据无法传递给监听函数所以通过此中方法传递
taskService.complete(task.getId(), paramMap); taskService.complete(task.getId(), paramMap);
@ -718,6 +719,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void updateTaskExtAssign(Task task) { public void updateTaskExtAssign(Task task) {
// BpmTaskExtDO taskExtDO = // BpmTaskExtDO taskExtDO =
// new BpmTaskExtDO().setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setTaskId(task.getId()); // new BpmTaskExtDO().setAssigneeUserId(NumberUtils.parseLong(task.getAssignee())).setTaskId(task.getId());

View File

@ -74,6 +74,9 @@ public interface ErrorCodeConstants {
// ========== 通知公告 1-002-008-000 ========== // ========== 通知公告 1-002-008-000 ==========
ErrorCode NOTICE_NOT_FOUND = new ErrorCode(1_002_008_001, "当前通知公告不存在"); ErrorCode NOTICE_NOT_FOUND = new ErrorCode(1_002_008_001, "当前通知公告不存在");
ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1_002_008_002, "用户组不存在");
ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1_002_008_003, "名字为【{}】的用户组已被禁用");
// ========== 短信渠道 1-002-011-000 ========== // ========== 短信渠道 1-002-011-000 ==========
ErrorCode SMS_CHANNEL_NOT_EXISTS = new ErrorCode(1_002_011_000, "短信渠道不存在"); ErrorCode SMS_CHANNEL_NOT_EXISTS = new ErrorCode(1_002_011_000, "短信渠道不存在");
ErrorCode SMS_CHANNEL_DISABLE = new ErrorCode(1_002_011_001, "短信渠道不处于开启状态,不允许选择"); ErrorCode SMS_CHANNEL_DISABLE = new ErrorCode(1_002_011_001, "短信渠道不处于开启状态,不允许选择");
@ -199,4 +202,10 @@ public interface ErrorCodeConstants {
ErrorCode LOG_NOT_DATE = new ErrorCode(1_009_010_007, "只能修改当天提交的日志"); ErrorCode LOG_NOT_DATE = new ErrorCode(1_009_010_007, "只能修改当天提交的日志");
ErrorCode LOG_NOT_UPDATE = new ErrorCode(1_009_010_008, "已过了提交时间,不能修改"); ErrorCode LOG_NOT_UPDATE = new ErrorCode(1_009_010_008, "已过了提交时间,不能修改");
ErrorCode BANK_NOT_EXISTS = new ErrorCode(1_009_020_001, "银行卡信息不存在");
ErrorCode BANK_EXISTS = new ErrorCode(1_009_020_003, "银行卡号已存在");
ErrorCode BANK_NOT_CREATOR = new ErrorCode(1_009_020_002, "你不是当前银行卡信息的创建者,不能进行修改!");
} }

View File

@ -0,0 +1,130 @@
package cn.iocoder.yudao.module.system.controller.admin.bank;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankRespVO;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO;
import cn.iocoder.yudao.module.system.service.bank.UserBankService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 用户银行卡信息")
@RestController
@RequestMapping("/system/user-bank")
@Validated
public class UserBankController {
@Resource
private UserBankService userBankService;
@PostMapping("/create")
@Operation(summary = "创建银行卡信息")
@PreAuthorize("@ss.hasPermission('system:user-bank:create')")
public CommonResult<Long> createBank(@Valid @RequestBody UserBankSaveReqVO createReqVO) {
return success(userBankService.createBank(createReqVO));
}
@PostMapping("/create-bank")
@Operation(summary = "创建银行卡信息")
@PreAuthorize("@ss.hasPermission('system:user-bank:create')")
public CommonResult<Boolean> createPayBank(@Valid @RequestBody UserBankSaveReqVO createReqVO) {
userBankService.createPayBank(createReqVO);
return success(true);
}
@PostMapping("/create-user")
@Operation(summary = "创建用户和银行卡关联信息")
@PreAuthorize("@ss.hasPermission('system:user-bank:create')")
public CommonResult<Boolean> createUserBank(@RequestBody List<Long> bankId) {
userBankService.createUserBank(bankId);
return success(true);
}
@PutMapping("/update")
@Operation(summary = "更新银行卡信息")
@PreAuthorize("@ss.hasPermission('system:user-bank:update')")
public CommonResult<Boolean> updateBank(@Valid @RequestBody UserBankSaveReqVO updateReqVO) {
userBankService.updateBank(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户和银行卡关联信息")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('system:user-bank:delete')")
public CommonResult<Boolean> deleteUserBank(@RequestParam("id") Long id) {
userBankService.deleteUserBank(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得银行卡信息")
@Parameter(name = "bankId", description = "银行卡信息编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:user-bank:query')")
public CommonResult<UserBankRespVO> getBank(@RequestParam("bankId") Long bankId) {
BankDO userBank = userBankService.getBank(bankId);
return success(BeanUtils.toBean(userBank, UserBankRespVO.class));
}
@GetMapping("/page-bank")
@Operation(summary = "获得银行卡信息分页列表")
@PreAuthorize("@ss.hasPermission('system:user-bank:query')")
public CommonResult<PageResult<UserBankRespVO>> getBankPage(@Valid UserBankPageReqVO pageReqVO) {
PageResult<BankDO> pageResult = new PageResult<BankDO>();
List<Long> bankIds = userBankService.getBankIds(getLoginUserId());
if (bankIds.isEmpty()) {
pageResult = userBankService.getBankPageIn(pageReqVO, null);
}else {
pageResult = userBankService.getBankPageNotIn(pageReqVO, bankIds);
}
return success(BeanUtils.toBean(pageResult, UserBankRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得用户和银行卡关联信息分页")
@PreAuthorize("@ss.hasPermission('system:user-bank:query')")
public CommonResult<PageResult<UserBankRespVO>> getUserBankPage(@Valid UserBankPageReqVO pageReqVO) {
PageResult<BankDO> pageResult = new PageResult<BankDO>();
List<Long> bankIds = userBankService.getBankIds(getLoginUserId());
if (!bankIds.isEmpty()) {
pageResult = userBankService.getBankPageIn(pageReqVO, bankIds);
}
return success(BeanUtils.toBean(pageResult, UserBankRespVO.class));
}
@GetMapping("/list")
@Operation(summary = "获得用户和银行卡关联信息列表")
@PreAuthorize("@ss.hasPermission('system:user-bank:query')")
public CommonResult<List<UserBankRespVO>> getUserBankList() {
List<BankDO> bankDOS = userBankService.getBankListByUserId(getLoginUserId());
return success(BeanUtils.toBean(bankDOS, UserBankRespVO.class));
}
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.system.controller.admin.bank.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 用户银行卡信息分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class UserBankPageReqVO extends PageParam {
@Schema(description = "用户编号", example = "31665")
private Long userId;
@Schema(description = "银行卡用户名称", example = "芋艿")
private String nickname;
@Schema(description = "银行卡号")
private String bankNo;
@Schema(description = "开户行信息", example = "赵六")
private String bankName;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.system.controller.admin.bank.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 用户银行卡信息 Response VO")
@Data
@ExcelIgnoreUnannotated
public class UserBankRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3548")
@ExcelProperty("ID")
private Long id;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31665")
private Long userId;
@Schema(description = "银行卡用户名称", example = "芋艿")
@ExcelProperty("银行卡用户名称")
private String nickname;
@Schema(description = "银行卡号")
@ExcelProperty("银行卡号")
private String bankNo;
@Schema(description = "开户行信息", example = "赵六")
@ExcelProperty("开户行信息")
private String bankName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.controller.admin.bank.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 用户银行卡信息新增/修改 Request VO")
@Data
public class UserBankSaveReqVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3548")
private Long id;
@Schema(description = "银行卡用户名称", example = "芋艿")
private String nickname;
@Schema(description = "银行卡号")
private String bankNo;
@Schema(description = "开户行信息", example = "赵六")
private String bankName;
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.dept;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptRespVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptRespVO;
@ -78,6 +79,15 @@ public class DeptController {
return success(BeanUtils.toBean(list, DeptSimpleRespVO.class)); return success(BeanUtils.toBean(list, DeptSimpleRespVO.class));
} }
@GetMapping(value = {"/all-list"})
@Operation(summary = "获取部门精简信息列表", description = "只包含被开启的部门,主要用于前端的下拉选项")
@DataPermission(enable = false)
public CommonResult<List<DeptSimpleRespVO>> getAllDeptList() {
List<DeptDO> list = deptService.getDeptList(
new DeptListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
return success(BeanUtils.toBean(list, DeptSimpleRespVO.class));
}
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得部门信息") @Operation(summary = "获得部门信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@ -87,7 +97,6 @@ public class DeptController {
return success(BeanUtils.toBean(dept, DeptRespVO.class)); return success(BeanUtils.toBean(dept, DeptRespVO.class));
} }
@GetMapping("/getUserDept") @GetMapping("/getUserDept")
@Operation(summary = "获取当前登录用户部门信息") @Operation(summary = "获取当前登录用户部门信息")
public CommonResult<DeptRespVO> getUserDept() { public CommonResult<DeptRespVO> getUserDept() {

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO;
@ -83,6 +84,17 @@ public class PostController {
return success(BeanUtils.toBean(list, PostSimpleRespVO.class)); return success(BeanUtils.toBean(list, PostSimpleRespVO.class));
} }
@GetMapping(value = {"/all-list"})
@Operation(summary = "获取岗位全列表", description = "只包含被开启的岗位,主要用于前端的下拉选项")
@DataPermission(enable = false)
public CommonResult<List<PostSimpleRespVO>> getAllPostList() {
// 获得岗位列表只要开启状态的
List<PostDO> list = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
// 排序后返回给前端
list.sort(Comparator.comparing(PostDO::getSort));
return success(BeanUtils.toBean(list, PostSimpleRespVO.class));
}
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得岗位分页列表") @Operation(summary = "获得岗位分页列表")
@PreAuthorize("@ss.hasPermission('system:post:query')") @PreAuthorize("@ss.hasPermission('system:post:query')")

View File

@ -1,15 +1,14 @@
package cn.iocoder.yudao.module.system.controller.admin.notice; package cn.iocoder.yudao.module.system.controller.admin.notice;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePushReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeRespVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeRespVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO; import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO;
import cn.iocoder.yudao.module.system.service.notice.NoticeGroupService;
import cn.iocoder.yudao.module.system.service.notice.NoticeService; import cn.iocoder.yudao.module.system.service.notice.NoticeService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@ -33,7 +32,7 @@ public class NoticeController {
private NoticeService noticeService; private NoticeService noticeService;
@Resource @Resource
private WebSocketSenderApi webSocketSenderApi; private NoticeGroupService groupService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建通知公告") @Operation(summary = "创建通知公告")
@ -78,18 +77,16 @@ public class NoticeController {
} }
@PostMapping("/push") @PostMapping("/push")
@Operation(summary = "推送通知公告", description = "只发送给 websocket 连接在线的用户") @Operation(summary = "推送通知公告")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:notice:update')") @PreAuthorize("@ss.hasPermission('system:notice:update')")
public CommonResult<Boolean> push(@RequestParam("id") Long id) { public CommonResult<Boolean> push(@Valid @RequestBody NoticePushReqVO pushReqVO) {
NoticeDO notice = noticeService.getNotice(id);
Assert.notNull(notice, "公告不能为空");
// 通过 websocket 推送给在线的用户 // 通过 websocket 推送给在线的用户
//webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), "notice-push", notice); //webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), "notice-push", notice);
//小程序发送公告订阅消息 //小程序发送公告订阅消息
//获取改造方式 push 方法传入需要推送的用户ID集合 将ID集合查询出用户集合 只获取openId的用户进行推送 //获取改造方式 push 方法传入需要推送的用户ID集合 将ID集合查询出用户集合 只获取openId的用户进行推送
noticeService.sendNotice(notice); noticeService.sendNotice(pushReqVO);
return success(true); return success(true);
} }
} }

View File

@ -0,0 +1,110 @@
package cn.iocoder.yudao.module.system.controller.admin.notice;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupRespVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupUpdateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserRespVO;
import cn.iocoder.yudao.module.system.convert.notice.NoticeGroupConvert;
import cn.iocoder.yudao.module.system.convert.user.UserConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeGroupDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.notice.NoticeGroupService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - 用户组")
@RestController
@RequestMapping("/system/notice/user-group")
@Validated
public class NoticeGroupController {
@Resource
private NoticeGroupService userGroupService;
@Resource
private AdminUserService userService;
@Resource
private DeptService deptService;
@PostMapping("/create")
@Operation(summary = "创建用户组")
@PreAuthorize("@ss.hasPermission('system:notice-gropu:create')")
public CommonResult<Long> createUserGroup(@Valid @RequestBody NoticeGroupCreateReqVO createReqVO) {
return success(userGroupService.createUserGroup(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新用户组")
@PreAuthorize("@ss.hasPermission('system:notice-gropu:update')")
public CommonResult<Boolean> updateUserGroup(@Valid @RequestBody NoticeGroupUpdateReqVO updateReqVO) {
userGroupService.updateUserGroup(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户组")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('system:notice-gropu:delete')")
public CommonResult<Boolean> deleteUserGroup(@RequestParam("id") Long id) {
userGroupService.deleteUserGroup(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得用户组")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:notice-gropu:query')")
public CommonResult<NoticeGroupRespVO> getUserGroup(@RequestParam("id") Long id) {
NoticeGroupDO userGroup = userGroupService.getUserGroup(id);
//获得用户信息
List<AdminUserDO> userDOS = userService.getUserList(userGroup.getMemberUserIds());
//获得部门信息 map
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(userDOS, AdminUserDO::getDeptId));
List<UserRespVO> userRespVOS = convertList(userDOS, user -> UserConvert.INSTANCE.convert(user, deptMap.get(user.getDeptId())));
NoticeGroupRespVO noticeGroupRespVO = NoticeGroupConvert.INSTANCE.convert(userGroup);
noticeGroupRespVO.setUserInfo(userRespVOS);
noticeGroupRespVO.setMemberDeptIds(deptMap.keySet());
return success(noticeGroupRespVO);
}
@GetMapping("/page")
@Operation(summary = "获得用户组分页")
@PreAuthorize("@ss.hasPermission('system:notice-gropu:query')")
public CommonResult<PageResult<NoticeGroupRespVO>> getUserGroupPage(@Valid NoticeGroupPageReqVO pageVO) {
PageResult<NoticeGroupDO> pageResult = userGroupService.getUserGroupPage(pageVO);
return success(NoticeGroupConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/list-all-simple")
@Operation(summary = "获取用户组精简信息列表", description = "只包含被开启的用户组,主要用于前端的下拉选项")
public CommonResult<List<NoticeGroupRespVO>> getSimpleUserGroups() {
// 获用户门列表只要开启状态的
List<NoticeGroupDO> list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 排序后返回给前端
return success(NoticeGroupConvert.INSTANCE.convertList2(list));
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.system.controller.admin.notice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Set;
@Schema(description = "公告推送信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NoticePushReqVO {
@Schema(description = "公告编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
private Long id;
@Schema(description = "推送类型 | 0:全员 1:部门 2:用户组", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer type;
@Schema(description = "推送部门编号")
private List<Long> deptIds;
@Schema(description = "推送用户组编号")
private Set<Long> groupId;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.system.controller.admin.notice.vo.group;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Set;
/**
* 用户组 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class NoticeGroupBaseVO {
@Schema(description = "组名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotNull(message = "组名不能为空")
private String name;
@Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
@NotNull(message = "描述不能为空")
private String description;
@Schema(description = "成员编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3")
@NotNull(message = "成员编号数组不能为空")
private Set<Long> memberUserIds;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.system.controller.admin.notice.vo.group;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 用户组创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class NoticeGroupCreateReqVO extends NoticeGroupBaseVO {
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.system.controller.admin.notice.vo.group;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 用户组分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class NoticeGroupPageReqVO extends PageParam {
@Schema(description = "组名", example = "芋道")
private String name;
@Schema(description = "状态", example = "1")
private Integer status;
@DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.system.controller.admin.notice.vo.group;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
@Schema(description = "管理后台 - 用户组 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class NoticeGroupRespVO extends NoticeGroupBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "成员部门编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[126][128]")
@NotNull(message = "成员部门编号数组不能为空")
private Set<Long> memberDeptIds;
@Schema(description = "成员信息")
private List<UserRespVO> userInfo;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.system.controller.admin.notice.vo.group;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 用户组更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class NoticeGroupUpdateReqVO extends NoticeGroupBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "编号不能为空")
private Long id;
}

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.LogStatisticsDetailsListDTO; import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.LogStatisticsDetailsListDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.MyManageModelDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.NeedWriteHistoryDTO; import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.NeedWriteHistoryDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.LogStatisticsDetailsListVO; import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.LogStatisticsDetailsListVO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.LogStatisticsDetailsVO; import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.LogStatisticsDetailsVO;
@ -20,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@ -42,6 +44,13 @@ public class LogStatisticsController {
return success(logStatisticsService.myManageModel()); return success(logStatisticsService.myManageModel());
} }
@GetMapping("/getMyManageModelStatistics")
@Operation(summary = "获取我管理的模版的统计")
@PermitAll
public CommonResult<List<LogStatisticsModelVO>> getMyManageModelStatistics(@ModelAttribute MyManageModelDTO dto) {
return success(logStatisticsService.getMyManageModelStatistics(dto));
}
@GetMapping("/getStatistics") @GetMapping("/getStatistics")
@Operation(summary = "获取日志统计") @Operation(summary = "获取日志统计")
public CommonResult<LogStatisticsDetailsListVO> getStatistics(@ModelAttribute LogStatisticsDetailsListDTO dto) { public CommonResult<LogStatisticsDetailsListVO> getStatistics(@ModelAttribute LogStatisticsDetailsListDTO dto) {

View File

@ -14,4 +14,10 @@ public class LogStatisticsDetailsListDTO {
@Schema(description = "结束时间 格式yyyy-MM-dd 如果是日报的话 开始时间结束时间都传同一天即可") @Schema(description = "结束时间 格式yyyy-MM-dd 如果是日报的话 开始时间结束时间都传同一天即可")
private String endTime; private String endTime;
@Schema(description = "用户id")
private Long userId;
@Schema(description = "部门id")
private Long deptId;
} }

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
@Data
public class MyManageModelDTO {
@Schema(description = "当前用户id")
private Long userId;
@Schema(description = "部门id")
private Long deptId;
@Schema(description = "类型 1日报 2周报")
private Integer type;
@Schema(description = "开始时间 格式yyyy-MM-dd")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = TIME_ZONE_DEFAULT)
private Date beginTime;
@Schema(description = "结束时间 格式yyyy-MM-dd")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = TIME_ZONE_DEFAULT)
private Date endTime;
}

View File

@ -1,22 +1,19 @@
package cn.iocoder.yudao.module.system.convert.notice; package cn.iocoder.yudao.module.system.convert.notice;
import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.subscribe.dto.MsgData; import cn.iocoder.yudao.module.system.api.subscribe.dto.MsgData;
import cn.iocoder.yudao.module.system.api.subscribe.dto.SubscribeMessageReqDTO; import cn.iocoder.yudao.module.system.api.subscribe.dto.SubscribeMessageReqDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO; import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.Date; import java.util.Date;
import java.util.Map;
/** /**
* 功能描述 * 功能描述
* *
* @author: yj * @author yj
* @date: 2024年04月07日 19:44 * date 2024年04月07日 19:44
*/ */
@Mapper @Mapper
public interface NoticeConvert { public interface NoticeConvert {
@ -30,20 +27,25 @@ public interface NoticeConvert {
* @param miniProgramState 小程序的状态 * @param miniProgramState 小程序的状态
* @return * @return
*/ */
default SubscribeMessageReqDTO convertCompanyNotice(String openId, NoticeDO notice, String nickname, String miniProgramState) { default SubscribeMessageReqDTO convertCompanyNotice(String openId, NoticeDO notice, String noticeLabel, String nickname, String miniProgramState) {
SubscribeMessageReqDTO message = new SubscribeMessageReqDTO(); SubscribeMessageReqDTO message = new SubscribeMessageReqDTO();
message.setToUser(openId); message.setToUser(openId);
message.setTemplateId("OF4-948Vz9rtE_VA55rmDxo4azOwmrjjk33jDpOiPiY"); message.setTemplateId("OF4-948Vz9rtE_VA55rmDxo4azOwmrjjk33jDpOiPiY");
//通知类型 //通知类型
MsgData noticeType = new MsgData(); MsgData noticeType = new MsgData();
noticeType.setName("thing1"); noticeType.setName("thing1");
noticeType.setValue(notice.getType()+""); //这里根据业务需求填写具体的公告类型 如全员公告 xxx公告 noticeType.setValue(noticeLabel); //这里根据业务需求填写具体的公告类型 如全员公告 xxx公告
message.addData(noticeType); message.addData(noticeType);
//公告标题 //公告标题
String value = notice.getTitle();
if (value.length() > 10) {
value = value.substring(0,10) + ". . . . ";
}
MsgData title = new MsgData(); MsgData title = new MsgData();
title.setName("thing6"); title.setName("thing6");
title.setValue(notice.getTitle()); title.setValue(value);
message.addData(title); message.addData(title);
//通知内容 //通知内容
@ -65,7 +67,7 @@ public interface NoticeConvert {
message.addData(createTime); message.addData(createTime);
message.setMiniprogramState(miniProgramState); message.setMiniprogramState(miniProgramState);
message.setPage("pages/index"); message.setPage("/subPages/notice/detail?id=" + notice.getId());
return message; return message;
} }
} }

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.system.convert.notice;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupRespVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupUpdateReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeGroupDO;
import org.mapstruct.Mapper;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 用户组 Convert
*
*/
@Mapper
public interface NoticeGroupConvert {
NoticeGroupConvert INSTANCE = Mappers.getMapper(NoticeGroupConvert.class);
NoticeGroupDO convert(NoticeGroupCreateReqVO bean);
NoticeGroupDO convert(NoticeGroupUpdateReqVO bean);
NoticeGroupRespVO convert(NoticeGroupDO bean);
List<NoticeGroupRespVO> convertList(List<NoticeGroupDO> list);
PageResult<NoticeGroupRespVO> convertPage(PageResult<NoticeGroupDO> page);
@Named("convertList2")
List<NoticeGroupRespVO> convertList2(List<NoticeGroupDO> list);
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.system.dal.dataobject.bank;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 管理后台的用户银行卡信息 DO
*/
@TableName(value = "system_bank", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BankDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* 银行卡用户名称
*/
private String nickname;
/**
* 银行卡号
*/
private String bankNo;
/**
* 开户行信息
*/
private String bankName;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.system.dal.dataobject.bank;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 用户和银行卡关联 DO
*/
@TableName(value = "system_user_bank", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserBankDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 银行卡信息 ID
*/
private Long bankId;
}

View File

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.system.dal.dataobject.notice;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Set;
/**
* 公告推送 用户组
*/
@TableName(value = "system_notice_group", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NoticeGroupDO extends BaseDO {
/**
* 编号自增
*/
@TableId
private Long id;
/**
* 组名
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 成员用户编号数组
*/
@TableField(typeHandler = JsonLongSetTypeHandler.class)
private Set<Long> memberUserIds;
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.system.dal.mysql.bank;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 银行卡信息 Mapper
*
* @author 符溶馨
*/
@Mapper
public interface BankMapper extends BaseMapperX<BankDO> {
default PageResult<BankDO> selectPageIn(UserBankPageReqVO reqVO, List<Long> bankId) {
return selectPage(reqVO, new LambdaQueryWrapperX<BankDO>()
.likeIfPresent(BankDO::getNickname, reqVO.getNickname())
.inIfPresent(BankDO::getId, bankId)
.orderByDesc(BankDO::getId));
}
default PageResult<BankDO> selectPageNotIn(UserBankPageReqVO reqVO, List<Long> bankId) {
return selectPage(reqVO, new LambdaQueryWrapperX<BankDO>()
.likeIfPresent(BankDO::getNickname, reqVO.getNickname())
.notIn(BankDO::getId, bankId)
.orderByDesc(BankDO::getId));
}
default List<BankDO> selectBankList(List<Long> bankId) {
return selectList(new LambdaQueryWrapperX<BankDO>()
.in(BankDO::getId, bankId));
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.dal.mysql.bank;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.UserBankDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 用户和银行卡关联 Mapper
*
* @author 符溶馨
*/
@Mapper
public interface UserBankMapper extends BaseMapperX<UserBankDO> {
default UserBankDO selectByBankId(Long userId, Long bankId) {
return selectOne(new LambdaQueryWrapperX<UserBankDO>()
.eq(UserBankDO::getUserId, userId)
.eq(UserBankDO::getBankId, bankId));
}
}

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.system.dal.mysql.notice;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeGroupDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 公告推送用户组 Mapper
*/
@Mapper
public interface NoticeGroupMapper extends BaseMapperX<NoticeGroupDO> {
default PageResult<NoticeGroupDO> selectPage(NoticeGroupPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<NoticeGroupDO>()
.likeIfPresent(NoticeGroupDO::getName, reqVO.getName())
.eqIfPresent(NoticeGroupDO::getStatus, reqVO.getStatus())
.betweenIfPresent(NoticeGroupDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(NoticeGroupDO::getId));
}
default List<NoticeGroupDO> selectListByStatus(Integer status) {
return selectList(NoticeGroupDO::getStatus, status);
}
}

View File

@ -53,7 +53,7 @@ public interface LogStatisticsMapper extends BaseMapperX<LogStatisticsDO> {
* @param formId * @param formId
* @return * @return
*/ */
List<LogStatisticsDetailsVO> getStatistics(@Param("formId") Long formId, @Param("dateList") List<String> dateList); List<LogStatisticsDetailsVO> getStatistics(@Param("formId") Long formId, @Param("userId") Long userId, @Param("deptId") Long deptId, @Param("dateList") List<String> dateList);
/** /**
* 获取当天/本周的统计 * 获取当天/本周的统计
@ -72,7 +72,7 @@ public interface LogStatisticsMapper extends BaseMapperX<LogStatisticsDO> {
* @param dateList * @param dateList
* @return * @return
*/ */
List<LogUseVO> getMyCurrentStatistics(@Param("userId") Long userId, @Param("formId") Long formId, @Param("dateList") List<String> dateList); List<LogUseVO> getMyCurrentStatistics(@Param("userId") Long userId, @Param("deptId") Long deptId, @Param("formId") Long formId, @Param("dateList") List<String> dateList);
/** /**
* 获取我的日志历史记录 * 获取我的日志历史记录

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.system.framework.ThreadPool.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration(proxyBeanMethods = false)
public class AsyncConfig {
public static final String NOTIFY_THREAD_POOL_TASK_EXECUTOR = "NOTIFY_THREAD_POOL_TASK_EXECUTOR";
@Bean(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
public ThreadPoolTaskExecutor notifyThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2); // 设置核心线程数
executor.setMaxPoolSize(4); // 设置最大线程数
executor.setKeepAliveSeconds(60); // 设置空闲时间
executor.setQueueCapacity(100); // 设置队列大小
executor.setThreadNamePrefix("notify-"); // 配置线程池的前缀
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 进行加载
executor.initialize();
return executor;
}
}

View File

@ -0,0 +1,4 @@
/**
* 占位
*/
package cn.iocoder.yudao.module.system.framework.ThreadPool.core;

View File

@ -0,0 +1,86 @@
package cn.iocoder.yudao.module.system.service.bank;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO;
import javax.validation.Valid;
import java.util.List;
/**
* 用户银行卡信息 Service 接口
*
* @author 符溶馨
*/
public interface UserBankService {
/**
* 创建用户银行卡信息
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createBank(@Valid UserBankSaveReqVO createReqVO);
/**
* 创建用户银行卡信息
*
* @param createReqVO 创建信息
*/
void createPayBank(@Valid UserBankSaveReqVO createReqVO);
/**
* 创建用户和银行卡关联信息
*
* @param bankId 银行卡信息编号组
*/
void createUserBank(List<Long> bankId);
/**
* 更新银行卡信息
*
* @param updateReqVO 更新信息
*/
void updateBank(@Valid UserBankSaveReqVO updateReqVO);
/**
* 删除用户银行卡信息
*
* @param id 编号
*/
void deleteUserBank(Long id);
/**
* 获得用户银行卡信息
*
* @param bankId 银行卡信息编号
* @return 银行卡信息
*/
BankDO getBank(Long bankId);
/**
* 获得银行卡信息编号组
* @param userId 用户ID
* @return 银行卡信息编号组
*/
List<Long> getBankIds(Long userId);
/**
* 获得银行卡信息分页
*
* @param pageReqVO 分页查询
* @return 银行卡信息分页
*/
PageResult<BankDO> getBankPageIn(UserBankPageReqVO pageReqVO, List<Long> bankId);
/**
* 获得银行卡信息分页
*
* @param pageReqVO 分页查询
* @return 银行卡信息分页
*/
PageResult<BankDO> getBankPageNotIn(UserBankPageReqVO pageReqVO, List<Long> bankId);
List<BankDO> getBankListByUserId(Long userId);
}

View File

@ -0,0 +1,190 @@
package cn.iocoder.yudao.module.system.service.bank;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.UserBankDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.bank.BankMapper;
import cn.iocoder.yudao.module.system.dal.mysql.bank.UserBankMapper;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
/**
* 用户银行卡信息 Service 实现类
*
* @author 符溶馨
*/
@Service
@Validated
public class UserBankServiceImpl implements UserBankService {
@Resource
private UserBankMapper userBankMapper;
@Resource
private BankMapper bankMapper;
@Resource
private AdminUserService adminUserService;
@Override
public Long createBank(UserBankSaveReqVO createReqVO) {
//校验银行卡号是否已存在
Long count = bankMapper.selectCount(BankDO::getBankNo, createReqVO.getBankNo());
if (count > 0L) {
throw exception(BANK_EXISTS);
}
// 插入
BankDO bank = BeanUtils.toBean(createReqVO, BankDO.class);
bankMapper.insert(bank);
// 返回
return bank.getId();
}
@Override
public void createPayBank(UserBankSaveReqVO createReqVO) {
//校验银行卡号是否已存在
BankDO bankDO = bankMapper.selectOne(BankDO::getBankNo, createReqVO.getBankNo());
if (bankDO != null) {
UserBankDO userBankDO = userBankMapper.selectByBankId(getLoginUserId(), bankDO.getId());
if (userBankDO == null) {
userBankDO = new UserBankDO();
userBankDO.setUserId(getLoginUserId());
userBankDO.setBankId(bankDO.getId());
userBankDO.setCreator(Objects.requireNonNull(getLoginUserId()).toString());
userBankMapper.insert(userBankDO);
}
}else {
// 插入
BankDO bank = BeanUtils.toBean(createReqVO, BankDO.class);
bankMapper.insert(bank);
UserBankDO userBankDO = new UserBankDO();
userBankDO.setUserId(getLoginUserId());
userBankDO.setBankId(bank.getId());
userBankDO.setCreator(Objects.requireNonNull(getLoginUserId()).toString());
userBankMapper.insert(userBankDO);
}
}
@Override
public void createUserBank(List<Long> bankId) {
//获取当前登录用户信息
AdminUserDO adminUserDO = adminUserService.getUser(getLoginUserId());
List<UserBankDO> useDOs = bankId.stream()
.map(id -> {
UserBankDO userBankDO = new UserBankDO();
userBankDO.setUserId(adminUserDO.getId());
userBankDO.setBankId(id);
userBankDO.setCreator(String.valueOf(adminUserDO.getId()));
return userBankDO;
}).collect(Collectors.toList());
userBankMapper.insertBatch(useDOs);
}
@Override
public void updateBank(UserBankSaveReqVO updateReqVO) {
// 校验存在
validateBankExists(updateReqVO.getId());
// 更新
BankDO updateObj = BeanUtils.toBean(updateReqVO, BankDO.class);
bankMapper.updateById(updateObj);
}
@Override
public void deleteUserBank(Long id) {
// 校验存在
UserBankDO userBankDO = userBankMapper.selectByBankId(getLoginUserId(), id);
if (userBankDO == null) {
throw exception(BANK_NOT_EXISTS);
}
// 删除
userBankMapper.deleteById(userBankDO);
BankDO bankDO = bankMapper.selectById(userBankDO.getBankId());
//校验当前登录用户是否是 该银行卡信息的创建者
if (bankDO.getCreator().equals(userBankDO.getUserId().toString())) {
// 同步删除 银行卡信息
bankMapper.deleteById(bankDO.getId());
}
}
private void validateBankExists(Long id) {
BankDO bankDO = bankMapper.selectById(id);
if (bankDO == null) {
throw exception(BANK_NOT_EXISTS);
}
//校验当前登录用户是否是 该银行卡信息的创建者
if (!Long.valueOf(bankDO.getCreator()).equals(getLoginUserId())) {
throw exception(BANK_NOT_CREATOR);
}
}
@Override
public BankDO getBank(Long id) {
return bankMapper.selectById(id);
}
@Override
public List<Long> getBankIds(Long userId) {
List<UserBankDO> userBankDOS = userBankMapper.selectList(UserBankDO::getUserId, userId);
return convertList(userBankDOS, UserBankDO::getBankId);
}
@Override
public PageResult<BankDO> getBankPageIn(UserBankPageReqVO pageReqVO, List<Long> bankId) {
return bankMapper.selectPageIn(pageReqVO, bankId);
}
@Override
public PageResult<BankDO> getBankPageNotIn(UserBankPageReqVO pageReqVO, List<Long> bankId) {
return bankMapper.selectPageNotIn(pageReqVO, bankId);
}
@Override
public List<BankDO> getBankListByUserId(Long userId) {
if (getBankIds(userId).isEmpty()) {
return null;
}
return bankMapper.selectBankList(getBankIds(userId));
}
}

View File

@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.system.service.notice;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupUpdateReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeGroupDO;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* 用户组 Service 接口
*
*/
public interface NoticeGroupService {
/**
* 创建用户组
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createUserGroup(@Valid NoticeGroupCreateReqVO createReqVO);
/**
* 更新用户组
*
* @param updateReqVO 更新信息
*/
void updateUserGroup(@Valid NoticeGroupUpdateReqVO updateReqVO);
/**
* 删除用户组
*
* @param id 编号
*/
void deleteUserGroup(Long id);
/**
* 获得用户组
*
* @param id 编号
* @return 用户组
*/
NoticeGroupDO getUserGroup(Long id);
/**
* 获得用户组列表
*
* @param ids 编号
* @return 用户组列表
*/
List<NoticeGroupDO> getUserGroupList(Collection<Long> ids);
/**
* 获得指定状态的用户组列表
*
* @param status 状态
* @return 用户组列表
*/
List<NoticeGroupDO> getUserGroupListByStatus(Integer status);
/**
* 获得用户组分页
*
* @param pageReqVO 分页查询
* @return 用户组分页
*/
PageResult<NoticeGroupDO> getUserGroupPage(NoticeGroupPageReqVO pageReqVO);
/**
* 校验用户组们是否有效如下情况视为无效
* 1. 用户组编号不存在
* 2. 用户组被禁用
*
* @param ids 用户组编号数组
*/
void validUserGroups(Set<Long> ids);
}

View File

@ -0,0 +1,112 @@
package cn.iocoder.yudao.module.system.service.notice;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.group.NoticeGroupUpdateReqVO;
import cn.iocoder.yudao.module.system.convert.notice.NoticeGroupConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeGroupDO;
import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeGroupMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_GROUP_IS_DISABLE;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_GROUP_NOT_EXISTS;
/**
* 用户组 Service 实现类
*
*/
@Service
@Validated
public class NoticeGroupServiceImpl implements NoticeGroupService {
@Resource
private NoticeGroupMapper userGroupMapper;
@Override
public Long createUserGroup(NoticeGroupCreateReqVO createReqVO) {
// 插入
NoticeGroupDO userGroup = NoticeGroupConvert.INSTANCE.convert(createReqVO);
userGroupMapper.insert(userGroup);
// 返回
return userGroup.getId();
}
@Override
public void updateUserGroup(NoticeGroupUpdateReqVO updateReqVO) {
// 校验存在
this.validateUserGroupExists(updateReqVO.getId());
// 更新
NoticeGroupDO updateObj = NoticeGroupConvert.INSTANCE.convert(updateReqVO);
userGroupMapper.updateById(updateObj);
}
@Override
public void deleteUserGroup(Long id) {
// 校验存在
this.validateUserGroupExists(id);
// 删除
userGroupMapper.deleteById(id);
}
private void validateUserGroupExists(Long id) {
if (userGroupMapper.selectById(id) == null) {
throw exception(USER_GROUP_NOT_EXISTS);
}
}
@Override
public NoticeGroupDO getUserGroup(Long id) {
return userGroupMapper.selectById(id);
}
@Override
public List<NoticeGroupDO> getUserGroupList(Collection<Long> ids) {
return userGroupMapper.selectBatchIds(ids);
}
@Override
public List<NoticeGroupDO> getUserGroupListByStatus(Integer status) {
return userGroupMapper.selectListByStatus(status);
}
@Override
public PageResult<NoticeGroupDO> getUserGroupPage(NoticeGroupPageReqVO pageReqVO) {
return userGroupMapper.selectPage(pageReqVO);
}
@Override
public void validUserGroups(Set<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 获得用户组信息
List<NoticeGroupDO> userGroups = userGroupMapper.selectBatchIds(ids);
Map<Long, NoticeGroupDO> userGroupMap = CollectionUtils.convertMap(userGroups, NoticeGroupDO::getId);
// 校验
ids.forEach(id -> {
NoticeGroupDO userGroup = userGroupMap.get(id);
if (userGroup == null) {
throw exception(USER_GROUP_NOT_EXISTS);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(userGroup.getStatus())) {
throw exception(USER_GROUP_IS_DISABLE, userGroup.getName());
}
});
}
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.notice;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePushReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO; import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO;
@ -50,7 +51,7 @@ public interface NoticeService {
/** /**
* 小程序发送公告订阅消息 * 小程序发送公告订阅消息
* @param notice * @param pushReqVO 推送信息
*/ */
void sendNotice(NoticeDO notice) ; void sendNotice(NoticePushReqVO pushReqVO) ;
} }

View File

@ -7,21 +7,28 @@ import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi; import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePushReqVO;
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO;
import cn.iocoder.yudao.module.system.convert.notice.NoticeConvert; import cn.iocoder.yudao.module.system.convert.notice.NoticeConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO; import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO;
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeGroupDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeMapper; import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeMapper;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService; import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND;
import static cn.iocoder.yudao.module.system.framework.ThreadPool.config.AsyncConfig.NOTIFY_THREAD_POOL_TASK_EXECUTOR;
/** /**
* 通知公告 Service 实现类 * 通知公告 Service 实现类
@ -34,6 +41,15 @@ public class NoticeServiceImpl implements NoticeService {
@Resource @Resource
private NoticeMapper noticeMapper; private NoticeMapper noticeMapper;
@Resource
private NoticeGroupService noticeGroupService;
@Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR)
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Resource
private DictDataService dictDataService;
@Override @Override
public Long createNotice(NoticeSaveReqVO createReqVO) { public Long createNotice(NoticeSaveReqVO createReqVO) {
NoticeDO notice = BeanUtils.toBean(createReqVO, NoticeDO.class); NoticeDO notice = BeanUtils.toBean(createReqVO, NoticeDO.class);
@ -86,20 +102,54 @@ public class NoticeServiceImpl implements NoticeService {
private SubscribeMessageSendApi subscribeMessageSendApi; private SubscribeMessageSendApi subscribeMessageSendApi;
@Override @Override
public void sendNotice(NoticeDO notice) { public void sendNotice(NoticePushReqVO pushReqVO) {
//获得公告信息
NoticeDO notice = getNotice(pushReqVO.getId());
if (notice == null) {
throw exception(NOTICE_NOT_FOUND);
}
// 获得公告类型 字典label
DictDataDO dictDataDO = dictDataService.getDictData("system_notice_type", String.valueOf(notice.getType()));
//获取当前登陆用户的名称 //获取当前登陆用户的名称
LoginUser user = SecurityFrameworkUtils.getLoginUser() ; LoginUser user = SecurityFrameworkUtils.getLoginUser() ;
AdminUserDO currentUser = userService.getUser(user.getId()) ; AdminUserDO currentUser = userService.getUser(user.getId()) ;
//查询所有状态是开启的用户 List<AdminUserDO> userDOs = new ArrayList<>();
List<AdminUserDO> list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus()); switch (pushReqVO.getType()) {
for(AdminUserDO adminUserDO : list) {
if( adminUserDO.getOpenId() != null && !adminUserDO.getOpenId().equals("") ) { //全员推送
System.out.println("====" + adminUserDO.getNickname()); case 0:
//获得用户信息
userDOs = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus());
break;
//部门推送
case 1:
//获得用户信息
userDOs = userService.getUserListByDeptIds(pushReqVO.getDeptIds());
break;
//用户组推送
case 2:
//获得用户组信息
List<NoticeGroupDO> groupDOs = noticeGroupService.getUserGroupList(pushReqVO.getGroupId());
//获得用户组中 用户信息
userDOs = userService.getUserList(groupDOs.stream().flatMap(group -> group.getMemberUserIds().stream()).collect(Collectors.toSet()));
break;
}
for(AdminUserDO adminUserDO : userDOs) {
if( adminUserDO.getOpenId() != null && !adminUserDO.getOpenId().isEmpty()) {
threadPoolTaskExecutor.execute(() -> {
//获取openId有值的用户 //获取openId有值的用户
subscribeMessageSendApi.sendCompanyNotice(NoticeConvert.INSTANCE.convertCompanyNotice( subscribeMessageSendApi.sendCompanyNotice(NoticeConvert.INSTANCE.convertCompanyNotice(
adminUserDO.getOpenId(), notice , currentUser.getNickname(), adminUserDO.getOpenId(), notice, dictDataDO.getLabel(), currentUser.getNickname(),
"formal")); "formal"));
});
} }
} }
} }

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.worklog;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.LogStatisticsDetailsListDTO; import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.LogStatisticsDetailsListDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.MyManageModelDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.NeedWriteHistoryDTO; import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.NeedWriteHistoryDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.*; import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@ -105,4 +106,12 @@ public interface LogStatisticsService {
* @return * @return
*/ */
List<LogStatisticsModelVO> getNeedWriteHistory(NeedWriteHistoryDTO dto); List<LogStatisticsModelVO> getNeedWriteHistory(NeedWriteHistoryDTO dto);
/**
* 获取我管理的模版的统计
*
* @param dto
* @return
*/
List<LogStatisticsModelVO> getMyManageModelStatistics(MyManageModelDTO dto);
} }

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.LogStatisticsDetailsListDTO; import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.LogStatisticsDetailsListDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.MyManageModelDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.NeedWriteHistoryDTO; import cn.iocoder.yudao.module.system.controller.admin.worklog.dto.statistics.NeedWriteHistoryDTO;
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.*; import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.statistics.*;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@ -171,19 +172,22 @@ public class LogStatisticsServiceImpl implements LogStatisticsService {
LogRuleDO logRuleDO = logRuleService.getLogRuleByFormId(dto.getFormId()); LogRuleDO logRuleDO = logRuleService.getLogRuleByFormId(dto.getFormId());
// 判断开始时间是否当天 / 是否本周 // 判断开始时间是否当天 / 是否本周
boolean flag = false; boolean flag = false;
Date begin = DateUtil.parse(dto.getBeginTime(), "yyyy-MM-dd").toJdkDate();
List<LogStatisticsDetailsVO> logStatisticsDOS = new ArrayList<>(); List<LogStatisticsDetailsVO> logStatisticsDOS = new ArrayList<>();
List<String> dateList = new ArrayList<>();
if (StrUtil.isNotEmpty(dto.getBeginTime()) && StrUtil.isNotEmpty(dto.getEndTime())) {
Date begin = DateUtil.parse(dto.getBeginTime(), "yyyy-MM-dd").toJdkDate();
if (logRuleDO.getType() == 1) { if (logRuleDO.getType() == 1) {
flag = DateUtil.isSameDay(begin, new Date()); flag = DateUtil.isSameDay(begin, new Date());
} else if (logRuleDO.getType() == 2) { } else if (logRuleDO.getType() == 2) {
flag = DateUtil.isSameWeek(begin, new Date(), true); flag = DateUtil.isSameWeek(begin, new Date(), true);
} }
List<String> dateList = DateUtils.betweenDayStrList(dto.getBeginTime(), dto.getEndTime()); dateList = DateUtils.betweenDayStrList(dto.getBeginTime(), dto.getEndTime());
}
// 这里将区间转换为具体的日期 因为mysql BETWEEN 会导致索引失效 // 这里将区间转换为具体的日期 因为mysql BETWEEN 会导致索引失效
if (flag) { if (flag) {
logStatisticsDOS = logStatisticsMapper.getCurrentStatistics(dto.getFormId(), dateList); logStatisticsDOS = logStatisticsMapper.getCurrentStatistics(dto.getFormId(), dateList);
} else { } else {
logStatisticsDOS = logStatisticsMapper.getStatistics(dto.getFormId(), dateList); logStatisticsDOS = logStatisticsMapper.getStatistics(dto.getFormId(), dto.getUserId(), dto.getDeptId(), dateList);
} }
List<LogStatisticsDetailsVO> onTime = logStatisticsDOS.stream().filter(a -> a.getStatus() == 1).collect(Collectors.toList()); List<LogStatisticsDetailsVO> onTime = logStatisticsDOS.stream().filter(a -> a.getStatus() == 1).collect(Collectors.toList());
List<LogStatisticsDetailsVO> late = logStatisticsDOS.stream().filter(a -> a.getStatus() == 2).collect(Collectors.toList()); List<LogStatisticsDetailsVO> late = logStatisticsDOS.stream().filter(a -> a.getStatus() == 2).collect(Collectors.toList());
@ -251,7 +255,7 @@ public class LogStatisticsServiceImpl implements LogStatisticsService {
// -- 需要提交的话查看下是否需要提交 // -- 需要提交的话查看下是否需要提交
if (flag) { if (flag) {
List<String> dateList = DateUtils.betweenDayList(beginDate, endDate); List<String> dateList = DateUtils.betweenDayList(beginDate, endDate);
List<LogUseVO> logUseVOS = logStatisticsMapper.getMyCurrentStatistics(userId, logFormDO.getId(), dateList); List<LogUseVO> logUseVOS = logStatisticsMapper.getMyCurrentStatistics(userId, null, logFormDO.getId(), dateList);
//按时提交数量 //按时提交数量
Integer onTimeNum = Math.toIntExact(logUseVOS.stream().filter(a -> a.getStatus() == 1).count()); Integer onTimeNum = Math.toIntExact(logUseVOS.stream().filter(a -> a.getStatus() == 1).count());
//迟交数量 //迟交数量
@ -288,7 +292,7 @@ public class LogStatisticsServiceImpl implements LogStatisticsService {
if (flag) { if (flag) {
logStatisticsDOS = logStatisticsMapper.getCurrentStatistics(dto.getFormId(), dateList); logStatisticsDOS = logStatisticsMapper.getCurrentStatistics(dto.getFormId(), dateList);
} else { } else {
logStatisticsDOS = logStatisticsMapper.getStatistics(dto.getFormId(), dateList); logStatisticsDOS = logStatisticsMapper.getStatistics(dto.getFormId(), dto.getUserId(), dto.getDeptId(), dateList);
} }
return logStatisticsDOS; return logStatisticsDOS;
} }
@ -343,4 +347,40 @@ public class LogStatisticsServiceImpl implements LogStatisticsService {
// 这里将区间转换为具体的日期 因为mysql BETWEEN 会导致索引失效 // 这里将区间转换为具体的日期 因为mysql BETWEEN 会导致索引失效
return logStatisticsMapper.getNeedWriteHistory(dto, dateList); return logStatisticsMapper.getNeedWriteHistory(dto, dateList);
} }
@Override
public List<LogStatisticsModelVO> getMyManageModelStatistics(MyManageModelDTO dto) {
List<Long> formIds = logUseMapper.getFormIdsByDataPermission(null);
if (formIds.isEmpty()) {
return Collections.emptyList();
}
List<LogStatisticsModelVO> list = new ArrayList<>();
List<LogFormDO> formList = logFormMapper.selectList(new LambdaQueryWrapper<LogFormDO>()
.in(LogFormDO::getId, formIds)
.eq(LogFormDO::getStatus, 0)
.isNotNull(LogFormDO::getRuleId)
);
for (LogFormDO logFormDO : formList) {
LogStatisticsModelVO vo = new LogStatisticsModelVO();
BeanUtil.copyProperties(logFormDO, vo);
List<String> dateList = new ArrayList<>();
if (dto.getBeginTime() != null && dto.getEndTime() != null) {
dateList = DateUtils.betweenDayList(dto.getBeginTime(), dto.getEndTime());
}
List<LogUseVO> logUseVOS = logStatisticsMapper.getMyCurrentStatistics(dto.getUserId(), dto.getDeptId(), logFormDO.getId(), dateList);
//按时提交数量
Integer onTimeNum = Math.toIntExact(logUseVOS.stream().filter(a -> a.getStatus() == 1).count());
//迟交数量
Integer lateNum = Math.toIntExact(logUseVOS.stream().filter(a -> a.getStatus() == 2).count());
//未提交数量
Integer unSubmittedNum = Math.toIntExact(logUseVOS.stream().filter(a -> a.getStatus() == 3).count());
//按天统计
vo.setOnTimeNum(onTimeNum);
vo.setUnSubmittedNum(unSubmittedNum);
vo.setLateNum(lateNum);
list.add(vo);
}
return list;
}
} }

View File

@ -33,7 +33,7 @@
a.dept_id AS deptId, a.dept_id AS deptId,
c.`name` AS deptName, c.`name` AS deptName,
b.log_instance_ext_id AS logInstanceExtId, b.log_instance_ext_id AS logInstanceExtId,
b.`status` AS `status`, ifnull(b.`status`,3) AS `status`,
d.create_time AS createTime d.create_time AS createTime
FROM FROM
system_users AS a system_users AS a
@ -44,6 +44,13 @@
<if test="formId != null"> <if test="formId != null">
AND b.form_id = #{formId} AND b.form_id = #{formId}
</if> </if>
<if test="userId != null">
and a.id = #{userId}
</if>
<if test="deptId != null">
and a.dept_id = #{deptId}
</if>
<if test="dateList != null and dateList.size() > 0"> <if test="dateList != null and dateList.size() > 0">
AND b.time IN AND b.time IN
<foreach collection="dateList" item="date" open="(" separator="," close=")"> <foreach collection="dateList" item="date" open="(" separator="," close=")">
@ -107,6 +114,9 @@
<if test="userId != null"> <if test="userId != null">
and a.use_user_id = #{userId} and a.use_user_id = #{userId}
</if> </if>
<if test="deptId != null">
and a.use_user_dept = #{deptId}
</if>
</where> </where>
</select> </select>
<select id="getNeedWriteHistory" <select id="getNeedWriteHistory"