Merge remote-tracking branch 'origin/main'

This commit is contained in:
Echo 2024-03-22 19:25:38 +08:00
commit cdb3fe978b
20 changed files with 248 additions and 135 deletions

View File

@ -14,12 +14,11 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.file.Paths;
import java.util.Map; import java.util.Map;
/** /**
* 客户端工具类 * 客户端工具类
*
*/ */
public class ServletUtils { public class ServletUtils {
@ -45,9 +44,20 @@ public class ServletUtils {
public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException { public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
// 设置 header contentType // 设置 header contentType
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); if (isPdfFile(filename)) {
response.setContentType("application/pdf;charset=utf-8");
} else {
response.setContentType("application/octet-stream;charset=utf-8");
}
// 输出附件 // 输出附件
IoUtil.write(response.getOutputStream(), false, content); IoUtil.write(response.getOutputStream(), true, content);
}
public static boolean isPdfFile(String filePath) {
// 获取文件名包括扩展名
String fileName = Paths.get(filePath).getFileName().toString();
// 检查扩展名是否为.pdf
return fileName.toLowerCase().endsWith(".pdf");
} }
/** /**

View File

@ -41,7 +41,7 @@ public class BpmOAImprestController {
} }
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得出差申请") @Operation(summary = "获得备用金申请")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<BpmOAImprestRespVO> getImprest(@RequestParam("id") Long id) { public CommonResult<BpmOAImprestRespVO> getImprest(@RequestParam("id") Long id) {
@ -49,4 +49,15 @@ public class BpmOAImprestController {
return success(BpmOAImprestConvert.INSTANCE.convert(imprest)); return success(BpmOAImprestConvert.INSTANCE.convert(imprest));
} }
@GetMapping("/getOne")
@Operation(summary = "获得备用金表单")
@Parameter(name = "userId", description = "编号", required = true, example = "1024")
public CommonResult<BpmOAImprestRespVO> getImprestByUserId(@RequestParam("userId") Long userId) {
//根据user 查询审批通过并且未报销得表单
BpmOAImprestDO imprest = imprestService.getImprestByUserId(userId);
return success(BpmOAImprestConvert.INSTANCE.convert(imprest));
}
} }

View File

@ -41,6 +41,10 @@ public class BpmOAImprestRespVO extends BpmOABaseRespVO {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate date; private LocalDate date;
@Schema(description = "报销状态", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销状态不能为空")
private Integer status;
@Schema(description = "上传文件", requiredMode = Schema.RequiredMode.NOT_REQUIRED) @Schema(description = "上传文件", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private List<UploadUserFile> fileItems; private List<UploadUserFile> fileItems;
} }

View File

@ -27,6 +27,10 @@ public class BpmOAReimbursementCreateReqVO {
@NotNull(message = "报销总金额中文大写不能为空") @NotNull(message = "报销总金额中文大写不能为空")
private String totalMoneyChinese ; private String totalMoneyChinese ;
@Schema(description = "备用金差额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@NotNull(message = "备用金差额不能为空")
private BigDecimal difference ;
@Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销发票总数不能为空") @NotNull(message = "报销发票总数不能为空")
private Integer totalQuantity ; private Integer totalQuantity ;

View File

@ -28,6 +28,10 @@ public class BpmOAReimbursementRespVO extends BpmOABaseRespVO {
@NotNull(message = "报销总金额中文大写不能为空") @NotNull(message = "报销总金额中文大写不能为空")
private String totalMoneyChinese ; private String totalMoneyChinese ;
@Schema(description = "备用金差额", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@NotNull(message = "备用金差额不能为空")
private BigDecimal difference ;
@Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "报销发票总数", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报销发票总数不能为空") @NotNull(message = "报销发票总数不能为空")
private Integer totalQuantity ; private Integer totalQuantity ;

View File

@ -5,13 +5,11 @@ import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDT
import cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO; 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 org.flowable.bpmn.model.UserTask;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; 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.List;
import java.util.Map; import java.util.Map;
@Mapper @Mapper
@ -32,56 +30,56 @@ public interface BpmMessageConvert {
/** /**
* * @param openId 微信小程序唯一id
* @param openId 微信小程序唯一id
* @param processInstanceName 流程名称 * @param processInstanceName 流程名称
* @param result 审批结果 * @param result 审批结果
* @param reason 审批原因 * @param reason 审批原因
* @param miniProgramState 小程序的状态 * @param miniProgramState 小程序的状态
* @return * @return
*/ */
default SubscribeMessageReqDTO convertApprovalResultNotification(String openId, String processInstanceName, String time, String result, String reason, String miniProgramState) { default SubscribeMessageReqDTO convertApprovalResultNotification(String openId, String processInstanceName, String time, String result, String reason, String processInstanceId,
SubscribeMessageReqDTO message = new SubscribeMessageReqDTO() ; String miniProgramState) {
message.setToUser(openId) ; SubscribeMessageReqDTO message = new SubscribeMessageReqDTO();
message.setTemplateId("OnJjp5pdjG1PHMoELYaqp3Xq8jWZ5E6ndO0clEIQ4tk") ; message.setToUser(openId);
message.setTemplateId("OnJjp5pdjG1PHMoELYaqp3Xq8jWZ5E6ndO0clEIQ4tk");
//审批类型 //审批类型
MsgData processType = new MsgData(); MsgData processType = new MsgData();
processType.setName("thing1") ; processType.setName("thing1");
processType.setValue(processInstanceName) ; processType.setValue(processInstanceName);
message.addData(processType); message.addData(processType);
//发起时间 //发起时间
MsgData createTime = new MsgData(); MsgData createTime = new MsgData();
createTime.setName("time2") ; createTime.setName("time2");
createTime.setValue(time) ; createTime.setValue(time);
message.addData(createTime); message.addData(createTime);
//审批时间 //审批时间
MsgData approvalTime = new MsgData(); MsgData approvalTime = new MsgData();
approvalTime.setName("time7") ; approvalTime.setName("time7");
approvalTime.setValue(DateUtils.dateFormat(new Date(),DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)) ; approvalTime.setValue(DateUtils.dateFormat(new Date(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
message.addData(approvalTime); message.addData(approvalTime);
//审批结果 //审批结果
MsgData approvalResult = new MsgData(); MsgData approvalResult = new MsgData();
approvalResult.setName("phrase3") ; approvalResult.setName("phrase3");
approvalResult.setValue(result) ; approvalResult.setValue(result);
message.addData(approvalResult); message.addData(approvalResult);
if(reason != null ) { if (reason != null) {
MsgData approvalReason = new MsgData(); MsgData approvalReason = new MsgData();
approvalReason.setName("thing12") ; approvalReason.setName("thing12");
approvalReason.setValue(reason) ; approvalReason.setValue(reason);
message.addData(approvalReason); message.addData(approvalReason);
} }
message.setMiniprogramState(miniProgramState) ; message.setMiniprogramState(miniProgramState);
message.setPage("pages/home/index?id=" + processInstanceId);
return message; return message;
} }
/** /**
* * @param openId 微信小程序唯一id
* @param openId 微信小程序唯一id
* @param processInstanceName 流程名称 * @param processInstanceName 流程名称
* @param startUserNickname 申请人 * @param startUserNickname 申请人
* @param time 申请时间 * @param time 申请时间
@ -89,35 +87,36 @@ public interface BpmMessageConvert {
* @param miniProgramState 小程序的状态 * @param miniProgramState 小程序的状态
* @return * @return
*/ */
default SubscribeMessageReqDTO convertProcessToDoReminder(String openId, String processInstanceName,String startUserNickname, String time, String schedule, String miniProgramState) { default SubscribeMessageReqDTO convertProcessToDoReminder(String openId, String processInstanceName, String startUserNickname, String time, String schedule, String processInstanceId, String miniProgramState) {
SubscribeMessageReqDTO message = new SubscribeMessageReqDTO() ; SubscribeMessageReqDTO message = new SubscribeMessageReqDTO();
message.setToUser(openId) ; message.setToUser(openId);
message.setTemplateId("3cP4btlFSSiZk65qVewN_WoT_bh0OfUkYzzTsADOrR4") ; message.setTemplateId("3cP4btlFSSiZk65qVewN_WoT_bh0OfUkYzzTsADOrR4");
//待办标题 //待办标题
MsgData processType = new MsgData(); MsgData processType = new MsgData();
processType.setName("thing1") ; processType.setName("thing1");
processType.setValue("您收到了一条新的待办任务:"+processInstanceName) ; processType.setValue("您收到了一条新的待办任务:" + processInstanceName);
message.addData(processType); message.addData(processType);
//申请人 //申请人
MsgData applicant = new MsgData(); MsgData applicant = new MsgData();
applicant.setName("thing4") ; applicant.setName("thing4");
applicant.setValue(startUserNickname) ; applicant.setValue(startUserNickname);
message.addData(applicant); message.addData(applicant);
//申请时间 //申请时间
MsgData createTime = new MsgData(); MsgData createTime = new MsgData();
createTime.setName("time5") ; createTime.setName("time5");
createTime.setValue(time) ; createTime.setValue(time);
message.addData(createTime); message.addData(createTime);
//当前进度 //当前进度
MsgData currentSchedule = new MsgData(); MsgData currentSchedule = new MsgData();
currentSchedule.setName("thing6") ; currentSchedule.setName("thing6");
currentSchedule.setValue(schedule) ; currentSchedule.setValue(schedule);
message.addData(currentSchedule); message.addData(currentSchedule);
message.setMiniprogramState(miniProgramState) ; message.setMiniprogramState(miniProgramState);
message.setPage("pages/bpm/task/todo/examineApprove?id=" + processInstanceId);
return message; return message;
} }
} }

View File

@ -29,6 +29,13 @@ import java.util.List;
@AllArgsConstructor @AllArgsConstructor
public class BpmOAImprestDO extends BaseDO { public class BpmOAImprestDO extends BaseDO {
/**
* 是否已报销 0否 1是 2进行中
*/
public static final Integer FLAG_FALSE = 0;
public static final Integer FLAG_TRUE = 1;
public static final Integer IN_PROGRESS = 2;
/** /**
* 出差表单主键 * 出差表单主键
*/ */
@ -70,6 +77,14 @@ public class BpmOAImprestDO extends BaseDO {
*/ */
private Integer result; private Integer result;
/**
* 报销与否状态
* 0未报销
* 1已报销
* 2进行中
*/
private Integer status;
/** /**
* 对应的流程编号 * 对应的流程编号
* *

View File

@ -55,6 +55,11 @@ public class BpmOAReimbursementDO extends BaseDO {
*/ */
private String totalMoneyChinese; private String totalMoneyChinese;
/**
* 备用差额
*/
private BigDecimal difference;
/** /**
* 报销发票总张数 * 报销发票总张数
*/ */

View File

@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.bpm.dal.mysql.oa; 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.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
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.enums.task.BpmProcessInstanceResultEnum;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
/** /**
@ -12,4 +14,11 @@ import org.apache.ibatis.annotations.Mapper;
*/ */
@Mapper @Mapper
public interface BpmOAImprestMapper extends BaseMapperX<BpmOAImprestDO> { public interface BpmOAImprestMapper extends BaseMapperX<BpmOAImprestDO> {
default BpmOAImprestDO selectByUserId(Long userId, Integer status){
return selectOne(new LambdaQueryWrapperX<BpmOAImprestDO>().eq(BpmOAImprestDO::getUserId, userId)
.eq(BpmOAImprestDO::getResult, BpmProcessInstanceResultEnum.PROCESS.getResult())
.eq(BpmOAImprestDO::getStatus, status));
}
} }

View File

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.bpm.service.message; package cn.iocoder.yudao.module.bpm.service.message;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.web.config.WebProperties; import cn.iocoder.yudao.framework.web.config.WebProperties;
import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert; import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert;
import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum; import cn.iocoder.yudao.module.bpm.enums.message.BpmMessageEnum;
@ -17,7 +16,8 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.HashMap;
import java.util.Map;
/** /**
* BPM 消息 Service 实现类 * BPM 消息 Service 实现类
@ -36,7 +36,7 @@ public class BpmMessageServiceImpl implements BpmMessageService {
private NotifyMessageSendApi notifyMessageSendApi; private NotifyMessageSendApi notifyMessageSendApi;
@Resource @Resource
private SubscribeMessageSendApi subscribeMessageSendApi ; private SubscribeMessageSendApi subscribeMessageSendApi;
@Resource @Resource
private WebProperties webProperties; private WebProperties webProperties;
@ -53,15 +53,16 @@ public class BpmMessageServiceImpl implements BpmMessageService {
BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsTemplateCode(), templateParams)); BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsTemplateCode(), templateParams));
//发送审批结果通知 //发送审批结果通知
String openId = getUserOpenId(reqDTO.getStartUserId()) ; String openId = getUserOpenId(reqDTO.getStartUserId());
if(openId != null ) { if (openId != null) {
subscribeMessageSendApi.sendApprovalResultNotification( subscribeMessageSendApi.sendApprovalResultNotification(
BpmMessageConvert.INSTANCE.convertApprovalResultNotification( BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
openId,reqDTO.getProcessInstanceName(), reqDTO.getCreateTime(), "通过", reqDTO.getReason(), openId, reqDTO.getProcessInstanceName(), reqDTO.getCreateTime(), "通过", reqDTO.getReason(),
reqDTO.getProcessInstanceId(),
/** /**
* 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版 * 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版
*/ */
"formal") ) ; "formal"));
} }
} }
@ -78,15 +79,16 @@ public class BpmMessageServiceImpl implements BpmMessageService {
reqDTO.getStartUserId(), BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams)); reqDTO.getStartUserId(), BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams));
// //发送审批结果通知 // //发送审批结果通知
String openId = getUserOpenId(reqDTO.getStartUserId()) ; String openId = getUserOpenId(reqDTO.getStartUserId());
if(openId != null ) { if (openId != null) {
subscribeMessageSendApi.sendApprovalResultNotification( subscribeMessageSendApi.sendApprovalResultNotification(
BpmMessageConvert.INSTANCE.convertApprovalResultNotification( BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
openId,reqDTO.getProcessInstanceName(),reqDTO.getCreateTime(),"不通过", reqDTO.getReason(), openId, reqDTO.getProcessInstanceName(), reqDTO.getCreateTime(), "不通过", reqDTO.getReason(),
reqDTO.getProcessInstanceId(),
/** /**
* 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版 * 跳转小程序类型developer为开发版trial为体验版formal为正式版默认为正式版
*/ */
"formal") ) ; "formal"));
} }
} }
@ -95,10 +97,10 @@ public class BpmMessageServiceImpl implements BpmMessageService {
public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) { public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
//任务分配 //任务分配
Long startUserId = reqDTO.getStartUserId(); //流程发起人 Long startUserId = reqDTO.getStartUserId(); //流程发起人
Long assigneeUserId = reqDTO.getAssigneeUserId() ; //任务审批人 Long assigneeUserId = reqDTO.getAssigneeUserId(); //任务审批人
String taskName = reqDTO.getTaskName() ; String taskName = reqDTO.getTaskName();
//如果流程发起人和任务审批是同一个人 那么不发送站内信否则就发送 //如果流程发起人和任务审批是同一个人 那么不发送站内信否则就发送
if(!assigneeUserId.toString().equals(startUserId.toString())) { if (!assigneeUserId.toString().equals(startUserId.toString())) {
Map<String, Object> templateParams = new HashMap<>(); Map<String, Object> templateParams = new HashMap<>();
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName()); templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
// templateParams.put("taskName", reqDTO.getTaskName()); // templateParams.put("taskName", reqDTO.getTaskName());
@ -112,11 +114,12 @@ public class BpmMessageServiceImpl implements BpmMessageService {
reqDTO.getAssigneeUserId(), BpmMessageEnum.TASK_ASSIGNED.getSmsTemplateCode(), templateParams)); reqDTO.getAssigneeUserId(), BpmMessageEnum.TASK_ASSIGNED.getSmsTemplateCode(), templateParams));
//微信小程序订阅消息 //微信小程序订阅消息
//发送OA流程待办提醒 //发送OA流程待办提醒
String openId = getUserOpenId(reqDTO.getStartUserId()) ; //只有在微信小程序登陆过用户才会有openid String openId = getUserOpenId(reqDTO.getStartUserId()); //只有在微信小程序登陆过用户才会有openid
if(openId != null ) { if (openId != null) {
subscribeMessageSendApi.sendProcessToDoReminder( BpmMessageConvert.INSTANCE.convertProcessToDoReminder( subscribeMessageSendApi.sendProcessToDoReminder(BpmMessageConvert.INSTANCE.convertProcessToDoReminder(
openId, reqDTO.getProcessInstanceName(), reqDTO.getStartUserNickname(),reqDTO.getCreateTime(),reqDTO.getSchedule() , openId, reqDTO.getProcessInstanceName(), reqDTO.getStartUserNickname(), reqDTO.getCreateTime(), reqDTO.getSchedule(),
"formal" ) ) ; reqDTO.getProcessInstanceId(),
"formal"));
} }
} }
} }
@ -127,10 +130,11 @@ public class BpmMessageServiceImpl implements BpmMessageService {
} }
@Resource @Resource
private AdminUserApi adminUserApi ; private AdminUserApi adminUserApi;
private String getUserOpenId(Long userId) { private String getUserOpenId(Long userId) {
AdminUserRespDTO adminUserRespDTO = adminUserApi.getUser(userId).getData(); AdminUserRespDTO adminUserRespDTO = adminUserApi.getUser(userId).getData();
String openId = adminUserRespDTO.getOpenId() ; String openId = adminUserRespDTO.getOpenId();
return openId ; return openId;
} }
} }

View File

@ -37,4 +37,12 @@ public interface BpmOAImprestService {
* @return 备用金申请 * @return 备用金申请
*/ */
BpmOAImprestDO getImprest(Long id); BpmOAImprestDO getImprest(Long id);
/**
* 获得备用金表单
*
* @param userId 编号
* @return 备用金申请
*/
BpmOAImprestDO getImprestByUserId(Long userId);
} }

View File

@ -45,6 +45,7 @@ public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAIm
//插入OA 备用金申请 //插入OA 备用金申请
BpmOAImprestDO imprest = BpmOAImprestConvert.INSTANCE.convert(createReqVO).setUserId(userId) BpmOAImprestDO imprest = BpmOAImprestConvert.INSTANCE.convert(createReqVO).setUserId(userId)
.setStatus(BpmOAImprestDO.FLAG_FALSE)
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
imprestMapper.insert(imprest) ; imprestMapper.insert(imprest) ;
@ -83,4 +84,11 @@ public class BpmOAImprestServiceImpl extends BpmOABaseService implements BpmOAIm
return imprestMapper.selectById(id); return imprestMapper.selectById(id);
} }
@Override
public BpmOAImprestDO getImprestByUserId(Long userId) {
//根据user 查询审批通过并且未报销得表单
return imprestMapper.selectByUserId(userId, BpmOAImprestDO.FLAG_FALSE);
}
} }

View File

@ -69,7 +69,7 @@ public class BpmOAProcurePayServiceImpl extends BpmOABaseService implements BpmO
private BpmProcessInstanceService bpmProcessInstanceService; private BpmProcessInstanceService bpmProcessInstanceService;
/** /**
* OA 请假对应的流程定义 KEY * OA 采购支付对应的流程定义 KEY
*/ */
public static final String PROCESS_KEY = "oa_procure_pay"; public static final String PROCESS_KEY = "oa_procure_pay";

View File

@ -40,7 +40,7 @@ public class BpmOAProcureServiceImpl extends BpmOABaseService implements BpmOAPr
@Resource @Resource
private BpmProcessInstanceApi processInstanceApi; private BpmProcessInstanceApi processInstanceApi;
/** /**
* OA 对应的流程定义 KEY * OA 采购申请对应的流程定义 KEY
*/ */
public static final String PROCESS_KEY = "oa_procure"; public static final String PROCESS_KEY = "oa_procure";

View File

@ -26,10 +26,11 @@ public interface BpmOAReimbursementService {
/** /**
* 更新报销申请的状态 * 更新报销申请的状态
* *
* @param id 编号 * @param processInstanceId
* @param result 结果 * @param id 编号
* @param result 结果
*/ */
void updateReimbursementResult(Long id, Integer result); void updateReimbursementResult(String processInstanceId, Long id, Integer result);
/** /**
* 获得报销申请 * 获得报销申请

View File

@ -5,11 +5,16 @@ import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
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.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.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.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.infra.api.file.FileApi; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
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;
@ -43,7 +48,14 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
private BpmProcessInstanceApi processInstanceApi; private BpmProcessInstanceApi processInstanceApi;
@Resource @Resource
private FileApi fileApi; @Lazy // 解决循环依赖
private BpmProcessInstanceService bpmProcessInstanceService;
@Resource
private BpmOAImprestService bpmOAImprestService;
@Resource
private BpmOAImprestMapper bpmOAImprestMapper;
@Override @Override
public Long createReimbursement(Long userId, BpmOAReimbursementCreateReqVO createReqVO) { public Long createReimbursement(Long userId, BpmOAReimbursementCreateReqVO createReqVO) {
@ -57,9 +69,15 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY) new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setVariables(processInstanceVariables).setBusinessKey(String.valueOf(reimbursement.getId()))).getCheckedData(); .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(reimbursement.getId()))).getCheckedData();
// 将工作流的编号更新到 OA 请假单中 // 将工作流的编号更新到 OA 报销表单中
reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(reimbursement.getId()).setProcessInstanceId(processInstanceId)); reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(reimbursement.getId()).setProcessInstanceId(processInstanceId));
//如果是备用金报销则更新备用金流程status
if (createReqVO.getDifference() != null) {
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestService.getImprestByUserId(userId);
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.IN_PROGRESS));
}
List<UploadUserFile> fileItems = createReqVO.getFileItems() ; List<UploadUserFile> fileItems = createReqVO.getFileItems() ;
//这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id //这里的逻辑如果fileItems不为空且有数据那么说明是上传了附件的则需要更工作流文件表对应的实例Id
if (fileItems != null && !fileItems.isEmpty()) { if (fileItems != null && !fileItems.isEmpty()) {
@ -69,8 +87,40 @@ public class BpmOAReimbursementServiceImpl extends BpmOABaseService implements B
} }
@Override @Override
public void updateReimbursementResult(Long id, Integer result) { @Transactional(rollbackFor = Exception.class)
public void updateReimbursementResult(String processInstanceId, Long id, Integer result) {
validateLeaveExists(id); validateLeaveExists(id);
//审核通过 最后节点
if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) {
ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectByUserId(Long.valueOf(instance.getStartUserId()), BpmOAImprestDO.IN_PROGRESS);
if (instance.isEnded() && bpmOAImprestDO != null) {
//将相应备用金申请状态改为 已报销
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.FLAG_TRUE));
}
}
// -- 自己取消
// -- 审核拒绝
//所有关联的采购申请改为 未支付状态
if (BpmProcessInstanceResultEnum.REJECT.getResult().equals(result)
|| BpmProcessInstanceResultEnum.CANCEL.getResult().equals(result)
|| BpmProcessInstanceResultEnum.BACK.getResult().equals(result)) {
ProcessInstance instance = bpmProcessInstanceService.getProcessInstance(processInstanceId);
BpmOAImprestDO bpmOAImprestDO = bpmOAImprestMapper.selectByUserId(Long.valueOf(instance.getStartUserId()), BpmOAImprestDO.IN_PROGRESS);
if (bpmOAImprestDO != null) {
//将相应备用金申请状态改为 未报销
bpmOAImprestMapper.updateById(new BpmOAImprestDO().setId(bpmOAImprestDO.getId()).setStatus(BpmOAImprestDO.FLAG_FALSE));
}
}
reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(id).setResult(result)); reimbursementMapper.updateById(new BpmOAReimbursementDO().setId(id).setResult(result));
} }

View File

@ -2,8 +2,6 @@ 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.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventListener;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveServiceImpl;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementService; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementServiceImpl; import cn.iocoder.yudao.module.bpm.service.oa.BpmOAReimbursementServiceImpl;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -28,7 +26,7 @@ public class BpmOAReimbursementResultListener extends BpmProcessInstanceResultEv
@Override @Override
protected void onEvent(BpmProcessInstanceResultEvent event) { protected void onEvent(BpmProcessInstanceResultEvent event) {
reimbursementService.updateReimbursementResult(Long.parseLong(event.getBusinessKey()), event.getResult()); reimbursementService.updateReimbursementResult(event.getId(), Long.parseLong(event.getBusinessKey()), event.getResult());
} }
} }

View File

@ -16,23 +16,18 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.dal.mysql.file.BpmFileMapper; import cn.iocoder.yudao.module.infra.dal.mysql.file.BpmFileMapper;
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper; import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; 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.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
/** /**
* 文件 Service 实现类 * 文件 Service 实现类
*
*/ */
@Service @Service
public class FileServiceImpl implements FileService { public class FileServiceImpl implements FileService {
@ -58,20 +53,18 @@ public class FileServiceImpl implements FileService {
Long userId = SecurityFrameworkUtils.getLoginUserId(); Long userId = SecurityFrameworkUtils.getLoginUserId();
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
String[] fileInfo = new String[4] ; String[] fileInfo = new String[4];
String name = file.getOriginalFilename() ; String name = file.getOriginalFilename();
String path = null ; String path = null;
byte[] content = IoUtil.readBytes(file.getInputStream()) ; byte[] content = IoUtil.readBytes(file.getInputStream());
// 计算默认的 path // 计算默认的 path
String type = FileTypeUtils.getMineType(content, name); String type = FileTypeUtils.getMineType(content, name);
if (StrUtil.isEmpty(path)) { StrUtil.isEmpty(path);//path = FileUtils.generatePath(content, name);
//path = FileUtils.generatePath(content, name); path = userId + "_" + timestamp;
path = userId+"_"+timestamp+""; String beginPath = name.replace(".", "_");
String beginPath = name.replace(".","_") ; path = beginPath + "_" + path + "." + FileNameUtil.extName(name);
path = beginPath+"_"+path+"."+ FileNameUtil.extName(name);;
}
// 如果 name 为空则使用 path 填充 // 如果 name 为空则使用 path 填充
if (StrUtil.isEmpty(name)) { if (StrUtil.isEmpty(name)) {
name = path; name = path;
@ -90,15 +83,15 @@ public class FileServiceImpl implements FileService {
fileDo.setUrl(url); fileDo.setUrl(url);
fileDo.setType(type); fileDo.setType(type);
fileDo.setSize(content.length); fileDo.setSize(content.length);
fileDo.setUploadUserId(userId) ; fileDo.setUploadUserId(userId);
bpmFileMapper.insert(fileDo); bpmFileMapper.insert(fileDo);
fileInfo[0] = name ; fileInfo[0] = name;
fileInfo[1] = fileDo.getUrl() ; fileInfo[1] = fileDo.getUrl();
fileInfo[2] = fileDo.getType() ; fileInfo[2] = fileDo.getType();
// 返回上传文件的访问路径 // 返回上传文件的访问路径
//return "{\"name\": \""+ fileInfo[0]+"\", \"path\": \""+ fileInfo[1]+"\", \"type\": \""+ fileInfo[2]+"\" }"; //return "{\"name\": \""+ fileInfo[0]+"\", \"path\": \""+ fileInfo[1]+"\", \"type\": \""+ fileInfo[2]+"\" }";
return fileDo ; return fileDo;
} }
@Override @Override
@ -162,11 +155,11 @@ public class FileServiceImpl implements FileService {
@Override @Override
public void deleteFile(String url) throws Exception { public void deleteFile(String url) throws Exception {
String path = url.substring( url.lastIndexOf("/")+1 ) ; String path = url.substring(url.lastIndexOf("/") + 1);
PageResult<FileDO> fileDOPageResult =fileMapper.selectPage(new FilePageReqVO().setPath(path)); PageResult<FileDO> fileDOPageResult = fileMapper.selectPage(new FilePageReqVO().setPath(path));
FileDO file = null ; FileDO file = null;
if(fileDOPageResult != null && fileDOPageResult.getTotal() >0 ) { if (fileDOPageResult != null && fileDOPageResult.getTotal() > 0) {
file = fileDOPageResult.getList().get(0) ; file = fileDOPageResult.getList().get(0);
} }
if (file == null) { if (file == null) {
@ -184,11 +177,11 @@ public class FileServiceImpl implements FileService {
@Override @Override
public void deleteBpmFile(String url) throws Exception { public void deleteBpmFile(String url) throws Exception {
String path = url.substring( url.lastIndexOf("/")+1 ) ; String path = url.substring(url.lastIndexOf("/") + 1);
PageResult<BpmFileDO> fileDOPageResult =bpmFileMapper.selectPage(new FilePageReqVO().setPath(path)); PageResult<BpmFileDO> fileDOPageResult = bpmFileMapper.selectPage(new FilePageReqVO().setPath(path));
BpmFileDO file = null ; BpmFileDO file = null;
if(fileDOPageResult != null && fileDOPageResult.getTotal() >0 ) { if (fileDOPageResult != null && fileDOPageResult.getTotal() > 0) {
file = fileDOPageResult.getList().get(0) ; file = fileDOPageResult.getList().get(0);
} }
if (file == null) { if (file == null) {
throw exception(FILE_NOT_EXISTS); throw exception(FILE_NOT_EXISTS);
@ -205,10 +198,10 @@ public class FileServiceImpl implements FileService {
@Override @Override
public void uploadBpmFileProcessInstanceId(BpmFileUploadReqVO reqVO) { public void uploadBpmFileProcessInstanceId(BpmFileUploadReqVO reqVO) {
String processInstanceId = reqVO.getProcessInstanceId() ; String processInstanceId = reqVO.getProcessInstanceId();
List<String> urls = reqVO.getUrls() ; List<String> urls = reqVO.getUrls();
LambdaUpdateWrapper<BpmFileDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>(); LambdaUpdateWrapper<BpmFileDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.in(BpmFileDO::getUrl, urls) ; lambdaUpdateWrapper.in(BpmFileDO::getUrl, urls);
lambdaUpdateWrapper.set(BpmFileDO::getProcessInstanceId, processInstanceId); // 假设 bid 是要更新的 bid lambdaUpdateWrapper.set(BpmFileDO::getProcessInstanceId, processInstanceId); // 假设 bid 是要更新的 bid
// 调用 MyBatis Plus update 方法执行批量更新 // 调用 MyBatis Plus update 方法执行批量更新
bpmFileMapper.update(null, lambdaUpdateWrapper); bpmFileMapper.update(null, lambdaUpdateWrapper);

View File

@ -30,9 +30,13 @@ public class SubscribeMessageReqDTO {
@Schema(description = "跳转小程序类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "developer为开发版trial为体验版formal为正式版默认为正式版") @Schema(description = "跳转小程序类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "developer为开发版trial为体验版formal为正式版默认为正式版")
@NotNull(message = "跳转小程序类型不能为空") @NotNull(message = "跳转小程序类型不能为空")
private String miniprogramState = "formal" ; private String miniprogramState = "formal";
@Schema(description = "小程序页面地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "pages/home/index")
@NotNull(message = "小程序页面地址不能为空")
private String page;
public void addData(MsgData data) { public void addData(MsgData data) {
this.data.add(data) ; this.data.add(data);
} }
} }

View File

@ -1,29 +1,15 @@
package cn.iocoder.yudao.module.system.api.subscribe; package cn.iocoder.yudao.module.system.api.subscribe;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.cache.CacheUtils;
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.service.social.SocialClientService; import cn.iocoder.yudao.module.system.service.social.SocialClientService;
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.Duration;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -36,7 +22,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
*/ */
@RestController // 提供 RESTful API 接口 Feign 调用 @RestController // 提供 RESTful API 接口 Feign 调用
@Validated @Validated
public class SubscribeMessageSendApiImpl implements SubscribeMessageSendApi{ public class SubscribeMessageSendApiImpl implements SubscribeMessageSendApi {
@Resource @Resource
private SocialClientService socialClientService; private SocialClientService socialClientService;
@ -55,21 +41,21 @@ public class SubscribeMessageSendApiImpl implements SubscribeMessageSendApi{
return success(1L); return success(1L);
} }
private WxMaSubscribeMessage initWxMaSubscribeMessage( SubscribeMessageReqDTO reqDTO ) { private WxMaSubscribeMessage initWxMaSubscribeMessage(SubscribeMessageReqDTO reqDTO) {
WxMaSubscribeMessage message = WxMaSubscribeMessage.builder() WxMaSubscribeMessage message = WxMaSubscribeMessage.builder()
.toUser(reqDTO.getToUser()) .toUser(reqDTO.getToUser())
.templateId(reqDTO.getTemplateId()) .templateId(reqDTO.getTemplateId())
.build(); .build();
message.setMiniprogramState(reqDTO.getMiniprogramState()); message.setMiniprogramState(reqDTO.getMiniprogramState());
List<MsgData> dataList = reqDTO.getData() ; List<MsgData> dataList = reqDTO.getData();
for (MsgData msgData : dataList) { for (MsgData msgData : dataList) {
WxMaSubscribeMessage.MsgData wxMsgData = new WxMaSubscribeMessage.MsgData() ; WxMaSubscribeMessage.MsgData wxMsgData = new WxMaSubscribeMessage.MsgData();
wxMsgData.setName(msgData.getName()) ; wxMsgData.setName(msgData.getName());
wxMsgData.setValue(msgData.getValue()) ; wxMsgData.setValue(msgData.getValue());
message.addData(wxMsgData) ; message.addData(wxMsgData);
} }
message.setPage("pages/home/index") ; message.setPage(reqDTO.getPage());
return message ; return message;
} }
} }