feat(bpm): 新增出差申请和开票申请功能

- 新增 BpmOAEvectionApi、BpmOAEvectionDTO 和相关服务实现类,用于处理出差申请
- 新增 BpmOAInvoiceController、BpmOAInvoiceCreateReqVO 和相关数据对象,用于处理开票申请
- 修改现有接口和数据结构以支持新功能
This commit is contained in:
furongxin 2024-11-09 09:55:25 +08:00
parent 8e13ad7fc2
commit 7552a1294e
45 changed files with 1240 additions and 72 deletions

View File

@ -20,8 +20,8 @@ public interface BpmOAEntryApi {
String PREFIX = ApiConstants.PREFIX + "/oa/entry";
@GetMapping(PREFIX + "/getGoOutByTime")
@Operation(summary = "取当日以及昨日外出的用户编号")
@GetMapping(PREFIX + "/getEntryByTime")
@Operation(summary = "得指定入职时间的入职申请列表")
@Parameter(name = "entryDate", description = "时间格式yyyy-MM-dd", required = true, example = "2024-05-11")
@PermitAll
CommonResult<List<BpmOAEntryDTO>> getEntryListByTime(@RequestParam(name = "entryDate") LocalDate entryDate);

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.bpm.api.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.bpm.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import javax.annotation.security.PermitAll;
import java.util.List;
import java.util.Map;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 流程实例")
public interface BpmOAEvectionApi {
String PREFIX = ApiConstants.PREFIX + "/oa/evection";
@GetMapping(PREFIX + "/getEvectionByTime")
@Operation(summary = "获取当日以及昨日出差的用户编号")
@PermitAll
CommonResult<Map<String, List<Long>>> getEvectionUserList();
}

View File

@ -0,0 +1,65 @@
package cn.iocoder.yudao.module.bpm.api.oa.vo;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
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;
/**
* @author 符溶馨
*/
@Schema(description = "管理后台 - 出差申请 请求Request VO")
@Data
@ToString(callSuper = true)
public class BpmOAEvectionDTO {
@Schema(description = "入职申请表单主键", example = "1")
private Long id;
@Schema(description = "用户id")
private Long userId;
@Schema(description = "出差原因", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "出差事由不能为空")
private String reason;
@Schema(description = "随行人用户编号")
private Set<Long> togetherUserIds;
@Schema(description = "随行人用户名称")
private String togetherUserName;
@Schema(description = "出差起点", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "出差起点不能为空")
private String startLocation;
@Schema(description = "出差终点", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "出差终点不能为空")
private String endLocation;
@Schema(description = "出差的开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
@Schema(description = "出差的结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
@Schema(description = "出差时长", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "出差时长不能为空")
private BigDecimal timeLength;
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
private List<UploadUserFile> fileItems;
}

View File

@ -43,6 +43,9 @@ public interface ErrorCodeConstants {
ErrorCode OA_HIRE_NOT_EXISTS = new ErrorCode(1_009_001_117, "招聘申请不存在");
ErrorCode OA_BUSINESS_HOSPITALITY_NOT_EXISTS = new ErrorCode(1_009_001_118, "商务招待申请不存在");
ErrorCode OA_FINANCE_NOT_EXISTS = new ErrorCode(1_009_001_119, "活动经费申请不存在");
ErrorCode OA_EVECTION_IS_EXISTS = new ErrorCode(1_009_001_120, "该时间段您正在出差!请重新选择正确出差时间。");
ErrorCode OA_INVOICE_NOT_EXISTS = new ErrorCode(1_009_001_121, "开票申请不存在");
ErrorCode OA_REPLACEMENT_CARD_NOT_EXISTS = new ErrorCode(1_009_001_122, "补卡申请不存在");
// ========== 流程模型 1-009-002-000 ==========
ErrorCode MODEL_KEY_EXISTS = new ErrorCode(1_009_002_000, "已经存在流程标识为【{}】的流程");

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.bpm.api.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAEvectionDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAEvectionService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDate;
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;
/**
* Flowable 流程实例 Api 实现类
*/
@RestController
@Validated
public class BpmOAEvectionApiImpl implements BpmOAEvectionApi {
@Resource
private BpmOAEvectionService evectionService;
@Override
public CommonResult<Map<String, List<Long>>> getEvectionUserList() {
LocalDate now = LocalDate.now();
List<BpmOAEvectionDO> evectionOn = evectionService.getEvectionListByStartTime(now);
List<BpmOAEvectionDO> evectionOff = evectionService.getEvectionListByEndTime(now.minusDays(1));
Map<String, List<Long>> result = new HashMap<>();
result.put("on", evectionOn.stream().map(BpmOAEvectionDO::getUserId).distinct().collect(Collectors.toList()));
result.put("off", evectionOff.stream().map(BpmOAEvectionDO::getUserId).distinct().collect(Collectors.toList()));
return success(result);
}
}

View File

@ -1,13 +1,13 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContractRespVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAContractConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAContractService;
import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -16,6 +16,7 @@ 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;
@ -36,10 +37,7 @@ public class BpmOAContractController {
private BpmOAContractService contractService;
@Resource
private BpmHistoryProcessInstanceService historyProcessInstanceService;
@Resource
private BpmTaskService taskService;
private AdminUserApi userApi;
@PostMapping("/create")
@Operation(summary = "创建请求申请")
@ -66,4 +64,16 @@ public class BpmOAContractController {
return success(BpmOAContractConvert.INSTANCE.convert(contract));
}
@GetMapping("/getListByDeptId")
@Operation(summary = "获得同部门的合同审批")
public CommonResult<List<BpmOAContractRespVO>> getListByDeptId() {
// 获取同部门所有用户id
List<Long> userIds = userApi.getUserIdsByUserIdGroupByDept(getLoginUserId()).getCheckedData();
List<BpmOAContractDO> contracts = contractService.getListByDeptId(userIds);
return success(BeanUtils.toBean(contracts, BpmOAContractRespVO.class));
}
}

View File

@ -15,6 +15,8 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.format.DateTimeFormatter;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@ -45,8 +47,11 @@ public class BpmOAFinanceController {
public CommonResult<BpmOAFinanceRespVO> getFinance(@RequestParam("id") Long id) {
BpmOAFinanceDO finance = financeService.getFinance(id);
BpmOAFinanceRespVO respVO = BeanUtils.toBean(finance, BpmOAFinanceRespVO.class);
respVO.setStartTime(finance.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
respVO.setEndTime(finance.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return success(BeanUtils.toBean(finance, BpmOAFinanceRespVO.class));
return success(respVO);
}
@GetMapping("/getByProcessInstanceId")
@ -55,6 +60,11 @@ public class BpmOAFinanceController {
public CommonResult<BpmOAFinanceRespVO> getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
BpmOAFinanceDO finance = financeService.getByProcessInstanceId(processInstanceId);
return success(BeanUtils.toBean(finance, BpmOAFinanceRespVO.class));
BpmOAFinanceRespVO respVO = BeanUtils.toBean(finance, BpmOAFinanceRespVO.class);
respVO.setStartTime(finance.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
respVO.setEndTime(finance.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return success(respVO);
}
}

View File

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAInvoiceService;
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 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/invoice")
@Validated
public class BpmOAInvoiceController {
@Resource
private BpmOAInvoiceService invoiceService;
@PostMapping("/create")
@Operation(summary = "创建请求申请")
public CommonResult<Long> createInvoice(@Valid @RequestBody BpmOAInvoiceCreateReqVO createReqVO) {
return success(invoiceService.createInvoice(getLoginUserId(), createReqVO));
}
@GetMapping("/get")
@Operation(summary = "获得开票申请")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<BpmOAInvoiceRespVO> getInvoice(@RequestParam("id") Long id) {
BpmOAInvoiceDO invoice = invoiceService.getInvoice(id);
BpmOAInvoiceRespVO bpmOAInvoiceRespVO = BeanUtils.toBean(invoice, BpmOAInvoiceRespVO.class);
return success(bpmOAInvoiceRespVO);
}
@GetMapping("/getByProcessInstanceId")
@Operation(summary = "获得开票申请")
@Parameter(name = "BpmOAInvoiceRespVO", description = "流程实例编号", required = true, example = "1024")
public CommonResult<BpmOAInvoiceRespVO> getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
BpmOAInvoiceDO invoice = invoiceService.getByProcessInstanceId(processInstanceId);
BpmOAInvoiceRespVO bpmOAInvoiceRespVO = BeanUtils.toBean(invoice, BpmOAInvoiceRespVO.class);
return success(bpmOAInvoiceRespVO);
}
}

View File

@ -0,0 +1,60 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard.BpmOAReplacementCardCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard.BpmOAReplacementCardRespVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReplacementCardDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReplacementCardService;
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 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/replacementCard")
@Validated
public class BpmOAReplacementCardController {
@Resource
private BpmOAReplacementCardService replacementCardService;
@PostMapping("/create")
@Operation(summary = "创建请求申请")
public CommonResult<Long> createReplacementCard(@Valid @RequestBody BpmOAReplacementCardCreateReqVO createReqVO) {
return success(replacementCardService.createReplacementCard(getLoginUserId(), createReqVO));
}
@GetMapping("/get")
@Operation(summary = "获得补卡申请")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<BpmOAReplacementCardRespVO> getReplacementCard(@RequestParam("id") Long id) {
BpmOAReplacementCardDO replacementCard = replacementCardService.getReplacementCard(id);
return success(BeanUtils.toBean(replacementCard, BpmOAReplacementCardRespVO.class));
}
@GetMapping("/getByProcessInstanceId")
@Operation(summary = "获得补卡申请")
@Parameter(name = "processInstanceId", description = "流程实例编号", required = true, example = "1024")
public CommonResult<BpmOAReplacementCardRespVO> getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
BpmOAReplacementCardDO replacementCard = replacementCardService.getByProcessInstanceId(processInstanceId);
return success(BeanUtils.toBean(replacementCard, BpmOAReplacementCardRespVO.class));
}
}

View File

@ -6,11 +6,13 @@ 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.time.LocalDate;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
/**
* @author 符溶馨
*/
@ -30,7 +32,8 @@ public class BpmOABusinessHospitalityRespVO extends BpmOABaseRespVO {
@Schema(description = "招待日期", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "招待日期不能为空")
private LocalDate entertainDate;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private String entertainDate;
@Schema(description = "招待地点")
private String entertainLocation;

View File

@ -8,7 +8,7 @@ import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ -35,12 +35,12 @@ public class BpmOAFinanceCreateReqVO {
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
private String startTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
private String endTime;
@Schema(description = "活动地址", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动地址不能为空")
@ -48,10 +48,10 @@ public class BpmOAFinanceCreateReqVO {
@Schema(description = "活动费用预算", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动费用预算不能为空")
private Integer costBudget;
private BigDecimal costBudget;
@Schema(description = "费用明细")
private List<CostDetail> costDetails;
private List<CostDetail> costDetail;
@Schema(description = "流程实例编号")
private String processInstanceId;

View File

@ -6,14 +6,11 @@ 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.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 活动经费申请 请求Request VO
*
@ -35,13 +32,11 @@ public class BpmOAFinanceRespVO extends BpmOABaseRespVO {
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动开始时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime;
private String startTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动结束时间不能为空")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime;
private String endTime;
@Schema(description = "活动地址", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动地址不能为空")
@ -49,10 +44,10 @@ public class BpmOAFinanceRespVO extends BpmOABaseRespVO {
@Schema(description = "活动费用预算", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动费用预算不能为空")
private Integer costBudget;
private BigDecimal costBudget;
@Schema(description = "费用明细")
private List<CostDetail> costDetails;
private List<CostDetail> costDetail;
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
private List<UploadUserFile> fileItems;

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.finance;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "活动费用明细 VO")
@Data
public class CostDetail {
@ -11,5 +13,5 @@ public class CostDetail {
private String name;
@Schema(description = "费用")
private Integer cost;
private BigDecimal cost;
}

View File

@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
@Schema(description = "管理后台 - 开票申请创建 Request VO")
@Data
@EqualsAndHashCode()
@ToString(callSuper = true)
public class BpmOAInvoiceCreateReqVO {
@Schema(description = "计划开票日期", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "计划开票日期不能为空")
private LocalDate invoiceDate;
@Schema(description = "项目编号")
private Long projectId;
@Schema(description = "开票金额", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开票金额不能为空")
private BigDecimal amount;
@Schema(description = "开票内容", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开票内容不能为空")
private String content;
@Schema(description = "开票单位名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开票单位名称不能为空")
private String unitName;
@Schema(description = "开票单位纳税人识别号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "开票单位纳税人识别号不能为空")
private String unitTin;
@Schema(description = "开票单位地址")
private String unitAddress;
@Schema(description = "开票单位电话")
private String unitPhone;
@Schema(description = "开票单位开户银行")
private String unitBankName;
@Schema(description = "开票单位银行账号")
private String unitBankNo;
@Schema(description = "关联合同业务流程编号")
private String contractInstanceId;
@Schema(description = "流程实例编号")
private String processInstanceId;
@Schema(description = "状态-参见 bpm_process_instance_result 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer result;
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
private List<UploadUserFile> fileItems ;
}

View File

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
@Schema(description = "管理后台 - 奖惩申请响应数据 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOAInvoiceRespVO extends BpmOABaseRespVO {
@Schema(description = "计划开票日期", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDate invoiceDate;
@Schema(description = "项目编号")
private Long projectId;
@Schema(description = "开票金额", requiredMode = Schema.RequiredMode.REQUIRED)
private BigDecimal amount;
@Schema(description = "开票内容", requiredMode = Schema.RequiredMode.REQUIRED)
private String content;
@Schema(description = "开票单位名称", requiredMode = Schema.RequiredMode.REQUIRED)
private String unitName;
@Schema(description = "开票单位纳税人识别号", requiredMode = Schema.RequiredMode.REQUIRED)
private String unitTin;
@Schema(description = "开票单位地址")
private String unitAddress;
@Schema(description = "开票单位电话")
private String unitPhone;
@Schema(description = "开票单位开户银行")
private String unitBankName;
@Schema(description = "开票单位银行账号")
private String unitBankNo;
@Schema(description = "关联合同业务流程编号")
private String contractInstanceId;
@Schema(description = "上传文件")
private List<UploadUserFile> fileItems ;
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 补卡申请 创建 Request VO
*
* @author 符溶馨
*/
@Schema(description = "管理后台 - 薪资付款申请创建 Request VO")
@Data
@EqualsAndHashCode()
@ToString(callSuper = true)
public class BpmOAReplacementCardCreateReqVO {
@Schema(description = "补卡明细", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "补卡明细不能为空")
private List<ReplacementCardItemVO> applicationItem;
@Schema(description = "流程实例编号")
private String processInstanceId;
@Schema(description = "状态-参见 bpm_process_instance_result 枚举")
private Integer result;
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "附件不能为空")
private List<UploadUserFile> fileItems;
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOABaseRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
/**
* @author 符溶馨
*/
@Schema(description = "管理后台 - 薪资付款申请 请求Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BpmOAReplacementCardRespVO extends BpmOABaseRespVO {
@Schema(description = "补卡明细")
private List<ReplacementCardItemVO> applicationItem;
@Schema(description = "上传文件")
private List<UploadUserFile> fileItems;
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
@Schema(description = "管理后台 - 补卡明细 Response VO")
@Data
public class ReplacementCardItemVO {
@Schema(description = "补卡日期")
private LocalDate date;
@Schema(description = "补卡事由")
private String reason;
}

View File

@ -209,7 +209,7 @@ public class BpmTaskController {
List<HistoricTaskInstance> tasks = taskService.getListTasksByProcessInstanceId(processInstanceId);
// 获取用户信息
List<String> userIds = convertList(tasks, HistoricTaskInstance::getAssignee);
List<String> userIds = tasks.stream().map(HistoricTaskInstance::getAssignee).distinct().collect(Collectors.toList());
if (CollUtil.isEmpty(userIds)) {
return success(userRespDTO);
}

View File

@ -17,7 +17,7 @@ import java.util.List;
*
* @author 符溶馨
*/
@TableName(value ="bpm_oa_business_card", autoResultMap = true)
@TableName(value ="bpm_oa_business_hospitality", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)

View File

@ -10,6 +10,7 @@ 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;
@ -66,13 +67,13 @@ public class BpmOAFinanceDO extends BaseDO {
/**
* 活动费用预算
*/
private Integer costBudget;
private BigDecimal costBudget;
/**
* 活动费用明细
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<CostDetail> costDetails;
private List<CostDetail> costDetail;
/**
* 申请的结果

View File

@ -0,0 +1,114 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
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.LocalDate;
import java.util.List;
/**
* OA 开票申请 DO
*
* @author 符溶馨
*/
@TableName(value ="bpm_oa_invoice", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAInvoiceDO extends BaseDO {
/**
* 开票申请表单主键
*/
@TableId
private Long id;
/**
* 申请人的用户编号
*/
private Long userId;
/**
* 计划开票日期
*/
private LocalDate invoiceDate;
/**
* 项目编号
*/
private Long projectId;
/**
* 开票金额
*/
private BigDecimal amount;
/**
* 开票内容
*/
private String content;
/**
* 开票单位名称
*/
private String unitName;
/**
* 开票单位纳税人识别号
*/
private String unitTin;
/**
* 开票单位地址
*/
private String unitAddress;
/**
* 开票单位联系电话
*/
private String unitPhone;
/**
* 开票单位开户银行
*/
private String unitBankName;
/**
* 开票单位银行账号
*/
private String unitBankNo;
/**
* 关联合同业务流程编号
*/
private String contractInstanceId;
/**
* 申请的结果
* 枚举 {@link BpmProcessInstanceResultEnum}
* 考虑到简单所以直接复用了 BpmProcessInstanceResultEnum 枚举也可以自己定义一个枚举哈
*/
private Integer result;
/**
* 对应的流程编号
* 关联 ProcessInstance id 属性
*/
private String processInstanceId;
/**
* 附件基本信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<UploadUserFile> fileItems ;
}

View File

@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.bpm.dal.dataobject.oa;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard.ReplacementCardItemVO;
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.util.List;
/**
* OA 补卡申请 DO
*
* @author 符溶馨
*
*/
@TableName(value ="bpm_oa_replacement_card", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BpmOAReplacementCardDO extends BaseDO {
/**
* 出差表单主键
*/
@TableId
private Long id;
/**
* 申请人的用户编号
* 关联 AdminUserDO id 属性
*/
private Long userId;
/**
* 补卡明细
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<ReplacementCardItemVO> applicationItem;
/**
* 申请的结果
* 枚举 {@link BpmProcessInstanceResultEnum}
* 考虑到简单所以直接复用了 BpmProcessInstanceResultEnum 枚举也可以自己定义一个枚举哈
*/
private Integer result;
/**
* 对应的流程编号
* 关联 ProcessInstance id 属性
*/
private String processInstanceId;
/**
* 附件基本信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<UploadUserFile> fileItems ;
}

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.evection.BpmOAEvectionCreateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAEvectionDO;
import org.apache.ibatis.annotations.Mapper;
@ -14,4 +16,10 @@ import org.apache.ibatis.annotations.Mapper;
public interface BpmOAEvectionMapper extends BaseMapperX<BpmOAEvectionDO> {
default Long selectIsExist(Long userId, BpmOAEvectionCreateReqVO createReqVO) {
return selectCount(new LambdaQueryWrapperX<BpmOAEvectionDO>()
.eq(BpmOAEvectionDO::getUserId, userId)
.leIfPresent(BpmOAEvectionDO::getStartTime, createReqVO.getEndTime())
.geIfPresent(BpmOAEvectionDO::getEndTime, createReqVO.getStartTime()));
}
}

View File

@ -0,0 +1,9 @@
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.BpmOAInvoiceDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BpmOAInvoiceMapper extends BaseMapperX<BpmOAInvoiceDO> {
}

View File

@ -0,0 +1,9 @@
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.BpmOAReplacementCardDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BpmOAReplacementCardMapper extends BaseMapperX<BpmOAReplacementCardDO> {
}

View File

@ -5,5 +5,5 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASalaryDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BpmOaSalaryMapper extends BaseMapperX<BpmOASalaryDO> {
public interface BpmOASalaryMapper extends BaseMapperX<BpmOASalaryDO> {
}

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.contract.BpmOAContract
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAContractDO;
import javax.validation.Valid;
import java.util.List;
public interface BpmOAContractService {
@ -38,4 +39,11 @@ public interface BpmOAContractService {
* @return 出差申请
*/
BpmOAContractDO getByProcessInstanceId(String processInstanceId);
/**
* 获取当前用户所在部门的合同列表
* @param userIds 用户编号集合
* @return 合同列表
*/
List<BpmOAContractDO> getListByDeptId(List<Long> userIds);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
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.contract.BpmOAContractCreateReqVO;
@ -108,4 +109,12 @@ public class BpmOAContractServiceImpl extends BpmOABaseService implements BpmOAC
}
return bpmOAContractDOS.get(0);
}
@Override
public List<BpmOAContractDO> getListByDeptId(List<Long> userIds) {
return contractMapper.selectList(new LambdaQueryWrapperX<BpmOAContractDO>()
.eq(BpmOAContractDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())
.inIfPresent(BpmOAContractDO::getUserId, userIds));
}
}

View File

@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.evection.BpmOAEvection
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAEvectionDO;
import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;
public interface BpmOAEvectionService {
@ -38,4 +40,18 @@ public interface BpmOAEvectionService {
* @return 出差申请
*/
BpmOAEvectionDO getByProcessInstanceId(String processInstanceId);
/**
* 获得指定开始时间的出差申请列表
* @param date 当前日期
* @return 出差申请列表
*/
List<BpmOAEvectionDO> getEvectionListByStartTime(LocalDate date);
/**
* 获得指定结束时间的出差申请列表
* @param date 当前日期
* @return 出差申请列表
*/
List<BpmOAEvectionDO> getEvectionListByEndTime(LocalDate date);
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
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.evection.BpmOAEvectionCreateReqVO;
@ -9,15 +10,20 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAEvectionDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAEvectionMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
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.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EVECTION_IS_EXISTS;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EVECTION_NOT_EXISTS;
/**
@ -44,9 +50,18 @@ public class BpmOAEvectionServiceImpl extends BpmOABaseService implements BpmOAE
@Resource
private BpmHistoryProcessInstanceService historyProcessInstanceService;
@Resource
private AdminUserApi userApi;
@Override
public Long createEvection(Long userId, BpmOAEvectionCreateReqVO createReqVO) {
// 校验当前选择的时间段内 是否在出差中
Long count = evectionMapper.selectIsExist(userId, createReqVO);
if (count > 0L) {
throw exception(OA_EVECTION_IS_EXISTS);
}
//插入OA 出差申请
BpmOAEvectionDO evection = BpmOAEvectionConvert.INSTANCE.convert(createReqVO).setUserId(userId)
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
@ -72,6 +87,13 @@ public class BpmOAEvectionServiceImpl extends BpmOABaseService implements BpmOAE
if (fileItems != null && !fileItems.isEmpty()) {
uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ;
}
// 发起出差申请后判断是否是当天的出差
if (evection.getStartTime().toLocalDate().isEqual(LocalDate.now())) {
// 设置外勤打卡权限
userApi.updateFieldworkType(getLoginUserId(), 1);
}
return evection.getId();
}
@ -80,6 +102,16 @@ public class BpmOAEvectionServiceImpl extends BpmOABaseService implements BpmOAE
validateLeaveExists(id);
evectionMapper.updateById(new BpmOAEvectionDO().setId(id).setResult(result));
// -- 自己取消
// -- 审核拒绝
if (BpmProcessInstanceResultEnum.REJECT.getResult().equals(result)
|| BpmProcessInstanceResultEnum.CANCEL.getResult().equals(result)
|| BpmProcessInstanceResultEnum.BACK.getResult().equals(result)) {
// 发起外出申请后设置关闭外勤打卡权限
userApi.updateFieldworkType(getLoginUserId(), 0);
}
}
private void validateLeaveExists(Long id) {
@ -99,4 +131,20 @@ public class BpmOAEvectionServiceImpl extends BpmOABaseService implements BpmOAE
return evectionMapper.selectOne(BpmOAEvectionDO::getProcessInstanceId, processInstanceId);
}
@Override
public List<BpmOAEvectionDO> getEvectionListByStartTime(LocalDate now) {
return evectionMapper.selectList(new LambdaQueryWrapperX<BpmOAEvectionDO>()
.eq(BpmOAEvectionDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())
.likeIfPresent(BpmOAEvectionDO::getStartTime, now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
}
@Override
public List<BpmOAEvectionDO> getEvectionListByEndTime(LocalDate date) {
return evectionMapper.selectList(new LambdaQueryWrapperX<BpmOAEvectionDO>()
.eq(BpmOAEvectionDO::getResult, BpmProcessInstanceResultEnum.APPROVE.getResult())
.likeIfPresent(BpmOAEvectionDO::getEndTime, date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
}
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO;
import javax.validation.Valid;
/**
* 开票申请 Service 接口
*
* @author 符溶馨
*/
public interface BpmOAInvoiceService {
/**
* 创建开票申请
*
* @param userId 用户编号
* @param createReqVO 创建信息
* @return 编号
*/
Long createInvoice(Long userId, @Valid BpmOAInvoiceCreateReqVO createReqVO);
/**
* 更新开票申请的状态
*
* @param id 编号
* @param result 结果
*/
void updateInvoiceResult(Long id, Integer result);
/**
* 获得开票申请
*
* @param id 编号
* @return 开票申请
*/
BpmOAInvoiceDO getInvoice(Long id);
/**
* 获得指定开票申请
* @param processInstanceId 流程实例编号
* @return 开票申请
*/
BpmOAInvoiceDO getByProcessInstanceId(String processInstanceId);
}

View File

@ -0,0 +1,107 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
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.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.invoice.BpmOAInvoiceCreateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAInvoiceDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAInvoiceMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService;
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_INVOICE_NOT_EXISTS;
/**
* OA 开票申请 Service 实现类
*
* @author 符溶馨
*/
@Service
@Validated
public class BpmOAInvoiceServiceImpl extends BpmOABaseService implements BpmOAInvoiceService{
/**
* OA 开票申请对应的流程定义 KEY
*/
public static final String PROCESS_KEY = "oa_invoice_2";
@Resource
private BpmOAInvoiceMapper invoiceMapper;
@Resource
private BpmProcessInstanceApi processInstanceApi;
@Resource
private BpmHistoryProcessInstanceService historyProcessInstanceService;
@Override
public Long createInvoice(Long userId, BpmOAInvoiceCreateReqVO createReqVO) {
//插入OA 开票申请
BpmOAInvoiceDO invoice = BeanUtils.toBean(createReqVO, BpmOAInvoiceDO.class)
.setUserId(userId)
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
invoiceMapper.insert(invoice) ;
// 发起 BPM 流程
Map<String, Object> processInstanceVariables = new HashMap<>();
String processInstanceId = processInstanceApi.createProcessInstance(userId,
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(invoice.getId()))).getCheckedData();
// 将工作流的编号更新到 OA 开票申请单中
invoiceMapper.updateById(new BpmOAInvoiceDO().setId(invoice.getId()).setProcessInstanceId(processInstanceId));
if (createReqVO.getProcessInstanceId() != null && createReqVO.getResult() == 3) {
historyProcessInstanceService.createHistoryProcessInstance(processInstanceId, createReqVO.getProcessInstanceId());
}
List<UploadUserFile> fileItems = createReqVO.getFileItems() ;
//这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id
if (fileItems != null && !fileItems.isEmpty()) {
uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ;
}
return invoice.getId();
}
@Override
public void updateInvoiceResult(Long id, Integer result) {
validateLeaveExists(id);
invoiceMapper.updateById(new BpmOAInvoiceDO().setId(id).setResult(result));
}
private void validateLeaveExists(Long id) {
if (invoiceMapper.selectById(id) == null) {
throw exception(OA_INVOICE_NOT_EXISTS);
}
}
@Override
public BpmOAInvoiceDO getInvoice(Long id) {
return invoiceMapper.selectById(id);
}
@Override
public BpmOAInvoiceDO getByProcessInstanceId(String processInstanceId) {
List<BpmOAInvoiceDO> bpmOAInvoiceDOS = invoiceMapper.selectList(BpmOAInvoiceDO::getProcessInstanceId, processInstanceId);
if (CollectionUtil.isEmpty(bpmOAInvoiceDOS)) {
return null;
}
return bpmOAInvoiceDOS.get(0);
}
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard.BpmOAReplacementCardCreateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReplacementCardDO;
import javax.validation.Valid;
/**
* 补卡申请 Service 接口
*
* @author 符溶馨
*/
public interface BpmOAReplacementCardService {
/**
* 创建补卡申请
*
* @param userId 用户编号
* @param createReqVO 创建信息
* @return 编号
*/
Long createReplacementCard(Long userId, @Valid BpmOAReplacementCardCreateReqVO createReqVO);
/**
* 更新补卡申请的状态
*
* @param id 编号
* @param result 结果
*/
void updateReplacementCardResult(Long id, Integer result);
/**
* 获得补卡申请
*
* @param id 编号
* @return 补卡申请
*/
BpmOAReplacementCardDO getReplacementCard(Long id);
/**
* 获得指定的补卡申请
* @param processInstanceId 流程实例编号
* @return 补卡申请
*/
BpmOAReplacementCardDO getByProcessInstanceId(String processInstanceId);
}

View File

@ -0,0 +1,101 @@
package cn.iocoder.yudao.module.bpm.service.oa;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
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.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.replacementCard.BpmOAReplacementCardCreateReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReplacementCardDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReplacementCardMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService;
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_REPLACEMENT_CARD_NOT_EXISTS;
/**
* OA 补卡申请 Service 实现类
*
* @author 符溶馨
*/
@Service
@Validated
public class BpmOAReplacementCardServiceImpl extends BpmOABaseService implements BpmOAReplacementCardService{
/**
* OA 补卡申请对应的流程定义 KEY
*/
public static final String PROCESS_KEY = "oa_replacementCard_2";
@Resource
private BpmOAReplacementCardMapper replacementCardMapper;
@Resource
private BpmProcessInstanceApi processInstanceApi;
@Resource
private BpmHistoryProcessInstanceService historyProcessInstanceService;
@Override
public Long createReplacementCard(Long userId, BpmOAReplacementCardCreateReqVO createReqVO) {
//插入OA 补卡申请
BpmOAReplacementCardDO replacementCard = BeanUtils.toBean(createReqVO, BpmOAReplacementCardDO.class)
.setUserId(userId)
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
replacementCardMapper.insert(replacementCard);
// 发起 BPM 流程
Map<String, Object> processInstanceVariables = new HashMap<>();
String processInstanceId = processInstanceApi.createProcessInstance(userId,
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(replacementCard.getId()))).getCheckedData();
// 将工作流的编号更新到 OA 补卡申请单中
replacementCardMapper.updateById(new BpmOAReplacementCardDO().setId(replacementCard.getId()).setProcessInstanceId(processInstanceId));
// 判断是否为重新发起的流程
if (createReqVO.getProcessInstanceId() != null && createReqVO.getResult() == 3) {
historyProcessInstanceService.createHistoryProcessInstance(processInstanceId, createReqVO.getProcessInstanceId());
}
List<UploadUserFile> fileItems = createReqVO.getFileItems() ;
//这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id
if (fileItems != null && !fileItems.isEmpty()) {
uploadBpmFileProcessInstanceId(processInstanceId,fileItems) ;
}
return replacementCard.getId();
}
@Override
public void updateReplacementCardResult(Long id, Integer result) {
validateLeaveExists(id);
replacementCardMapper.updateById(new BpmOAReplacementCardDO().setId(id).setResult(result));
}
private void validateLeaveExists(Long id) {
if (replacementCardMapper.selectById(id) == null) {
throw exception(OA_REPLACEMENT_CARD_NOT_EXISTS);
}
}
@Override
public BpmOAReplacementCardDO getReplacementCard(Long id) {
return replacementCardMapper.selectById(id);
}
@Override
public BpmOAReplacementCardDO getByProcessInstanceId(String processInstanceId) {
return replacementCardMapper.selectOne(BpmOAReplacementCardDO::getProcessInstanceId, processInstanceId);
}
}

View File

@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.salary.BpmOASalaryCreateReqVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOASalaryConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASalaryDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOaSalaryMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOASalaryMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@ -37,7 +37,7 @@ public class BpmOASalaryServiceImpl extends BpmOABaseService implements BpmOASal
public static final String PROCESS_KEY = "oa_salary_2";
@Resource
private BpmOaSalaryMapper salaryMapper;
private BpmOASalaryMapper salaryMapper;
@Resource
private BpmProcessInstanceApi processInstanceApi;

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.BpmOAInvoiceService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAInvoiceServiceImpl;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* OA 奖惩的结果的监听器实现类
*
* @author 符溶馨
*/
@Component
public class BpmOAInvoiceResultListener extends BpmProcessInstanceResultEventListener {
@Resource
private BpmOAInvoiceService invoiceService;
@Override
protected String getProcessDefinitionKey() {
return BpmOAInvoiceServiceImpl.PROCESS_KEY;
}
@Override
protected void onEvent(BpmProcessInstanceResultEvent event) {
invoiceService.updateInvoiceResult(Long.parseLong(event.getBusinessKey()), event.getResult());
}
}

View File

@ -0,0 +1,32 @@
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.BpmOAReplacementCardService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReplacementCardServiceImpl;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* OA 用章单的结果的监听器实现类
*
* @author 符溶馨
*/
@Component
public class BpmOAReplacementCardResultListener extends BpmProcessInstanceResultEventListener {
@Resource
private BpmOAReplacementCardService ReplacementCardService;
@Override
protected String getProcessDefinitionKey() {
return BpmOAReplacementCardServiceImpl.PROCESS_KEY;
}
@Override
protected void onEvent(BpmProcessInstanceResultEvent event) {
ReplacementCardService.updateReplacementCardResult(Long.parseLong(event.getBusinessKey()), event.getResult());
}
}

View File

@ -39,17 +39,17 @@ spring:
primary: master
datasource:
master:
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:

View File

@ -39,17 +39,17 @@ spring:
primary: master
datasource:
master:
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:

View File

@ -187,10 +187,8 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
queryWrapper.eq(AdminUserDO::getUserType, 1);
queryWrapper.likeIfPresent(AdminUserDO::getNickname, pageReqVO.getName());
queryWrapper.inIfPresent(AdminUserDO::getDeptId, deptIds);
if ((pageReqVO.getName() == null && pageReqVO.getDeptId() == null) || pageReqVO.getMonth() != null) {
queryWrapper.eq("MONTH(t.birthday_day)", date.getMonthValue());
queryWrapper.ge("DAY(t.birthday_day)", date.getDayOfMonth());
}
queryWrapper.eq("MONTH(t.birthday_day)", date.getMonthValue());
queryWrapper.ge("DAY(t.birthday_day)", date.getDayOfMonth());
queryWrapper.groupBy("t.id");
queryWrapper.orderByAsc("DAY(t.birthday_day)");

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.framework.rpc.config;
import cn.iocoder.yudao.module.bpm.api.model.BpmModelApi;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAEntryApi;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAEvectionApi;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAGoOutApi;
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
@ -11,6 +12,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {FileApi.class, WebSocketSenderApi.class, FactoryInfoApi.class, BpmModelApi.class, BpmOAGoOutApi.class, BpmOAEntryApi.class, ConfigApi.class})
@EnableFeignClients(clients = {FileApi.class, WebSocketSenderApi.class, FactoryInfoApi.class, BpmModelApi.class, BpmOAGoOutApi.class, BpmOAEntryApi.class, ConfigApi.class, BpmOAEvectionApi.class})
public class RpcConfiguration {
}

View File

@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAEntryApi;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAEvectionApi;
import cn.iocoder.yudao.module.bpm.api.oa.BpmOAGoOutApi;
import cn.iocoder.yudao.module.bpm.api.oa.vo.BpmOAEntryDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@ -35,6 +36,9 @@ public class FieldworkJob {
@Resource
private BpmOAEntryApi entryApi;
@Resource
private BpmOAEvectionApi evectionApi;
/**
* 外勤打卡权限调整 针对外出申请流程
*/
@ -48,15 +52,6 @@ public class FieldworkJob {
// 获取用户编号
Map<String, List<Long>> goOutList = goOutApi.getLeaveListByTime().getCheckedData();
if (CollectionUtil.isNotEmpty(goOutList.get("now"))) {
// 讲需要当天外出的用户设置外勤打卡权限
adminUserMapper.update(new AdminUserDO().setFieldworkFlag(1).setFieldworkType(2),
new LambdaQueryWrapper<AdminUserDO>()
.in(AdminUserDO::getId, goOutList.get("now"))
.ne(AdminUserDO::getFieldworkType, 1));
}
if (CollectionUtil.isNotEmpty(goOutList.get("yesterday"))) {
// 将昨日外出的用户关闭外勤打卡权限
@ -65,6 +60,15 @@ public class FieldworkJob {
.in(AdminUserDO::getId, goOutList.get("yesterday"))
.eq(AdminUserDO::getFieldworkType, 2));
}
if (CollectionUtil.isNotEmpty(goOutList.get("now"))) {
// 讲需要当天外出的用户设置外勤打卡权限
adminUserMapper.update(new AdminUserDO().setFieldworkFlag(1).setFieldworkType(2),
new LambdaQueryWrapper<AdminUserDO>()
.in(AdminUserDO::getId, goOutList.get("now"))
.ne(AdminUserDO::getFieldworkType, 1));
}
}catch (Exception ex) {
log.info(ex.toString());
}
@ -72,10 +76,46 @@ public class FieldworkJob {
// 修改的入职日期为当天的用户状态
updEntryUser();
// 修改出差人员的外勤打卡权限
updateEvection();
// 返回执行成功
return ReturnT.SUCCESS;
}
/**
* 修改出差人员的外勤打卡权限
*/
private void updateEvection() {
// 外勤打卡权限变更
try {
// 获取用户编号
Map<String, List<Long>> list = evectionApi.getEvectionUserList().getCheckedData();
if (CollectionUtil.isNotEmpty(list.get("off"))) {
// 将昨日出差的用户关闭外勤打卡权限
adminUserMapper.update(new AdminUserDO().setFieldworkFlag(0).setFieldworkType(0),
new LambdaQueryWrapper<AdminUserDO>()
.in(AdminUserDO::getId, list.get("off"))
.eq(AdminUserDO::getFieldworkType, 2));
}
if (CollectionUtil.isNotEmpty(list.get("on"))) {
// 讲需要当天出差的用户设置外勤打卡权限
adminUserMapper.update(new AdminUserDO().setFieldworkFlag(1).setFieldworkType(2),
new LambdaQueryWrapper<AdminUserDO>()
.in(AdminUserDO::getId, list.get("on"))
.ne(AdminUserDO::getFieldworkType, 1));
}
}catch (Exception ex) {
log.info(ex.toString());
}
}
/**
* 修改的入职日期为当天的用户状态
*/

View File

@ -39,17 +39,17 @@ spring:
primary: master
datasource:
master:
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:

View File

@ -39,17 +39,17 @@ spring:
primary: master
datasource:
master:
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
name: ruoyi-vue-pro-dev
url: jdbc:mysql://rm-bp1yloyj508qld78jno.mysql.rds.aliyuncs.com:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
name: ruoyi-vue-pro
url: jdbc:mysql://47.97.8.94:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
driver-class-name: com.mysql.jdbc.Driver
username: root
password: Znalyrds2024
password: yhtkj@2024!
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis: