无关风月
2025-02-27 7685af4ed67c693d197393f56f392d7b12434853
Merge branch 'master' of https://gitee.com/xiaochen991015/xizang
1 文件已复制
1 文件已重命名
49个文件已修改
1个文件已删除
8个文件已添加
2102 ■■■■■ 已修改文件
pom.xml 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/StateProcessController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/DataUpdateHandlerConfig.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MybatisPlusConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-test.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/StateProcessController.java 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TContractController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/THouseController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/WxLoginController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/core/config/DataUpdateHandlerConfig.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/core/config/MybatisPlusConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/resources/application-test.yml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/DataUpdateHandlerConfig.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/MailProperties.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/SmsConfig.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseModel.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/SmsUtil.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/bo/ProcessAgreeBO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/bo/ProcessRefuseBO.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/bo/ProcessTaskListBO.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/importExcel/TBankFlowImportExcel.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/StateTaskCenterMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/StateProcessInstanceAction.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/StateTaskCenter.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/StateProcessTemplateService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/StateTaskCenterService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TBankFlowService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TBillDetailService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java 684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillDetailServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessDetailVO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -87,24 +87,24 @@
            </dependency>
            <!-- excel工具 -->
<!--            <dependency>-->
<!--                <groupId>org.apache.poi</groupId>-->
<!--                <artifactId>poi-ooxml</artifactId>-->
<!--                <version>${poi.version}</version>-->
<!--            </dependency>-->
           <dependency>
               <groupId>org.apache.poi</groupId>
               <artifactId>poi-ooxml</artifactId>
               <version>${poi.version}</version>
           </dependency>
<!--            <dependency>-->
<!--                <groupId>org.apache.poi</groupId>-->
<!--                <artifactId>poi</artifactId>-->
<!--                <version>${poi.version}</version>-->
<!--            </dependency>-->
           <dependency>
               <groupId>org.apache.poi</groupId>
               <artifactId>poi</artifactId>
               <version>${poi.version}</version>
           </dependency>
<!--            <dependency>-->
<!--                <groupId>org.apache.poi</groupId>-->
<!--                <artifactId>poi-ooxml-schemas</artifactId>-->
<!--                <version>${poi.version}</version>-->
<!--            </dependency>-->
           <dependency>
               <groupId>org.apache.poi</groupId>
               <artifactId>poi-ooxml-schemas</artifactId>
               <version>${poi.version}</version>
           </dependency>
            <!-- velocity代码生成使用模板 -->
            <dependency>
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/StateProcessController.java
@@ -1,5 +1,6 @@
package com.ruoyi.web.controller.api;
import com.aizuda.bpm.engine.entity.FlwTask;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -18,9 +19,11 @@
import com.ruoyi.system.bo.*;
import com.ruoyi.system.model.StateProcessModule;
import com.ruoyi.system.model.StateProcessTemplate;
import com.ruoyi.system.model.TContract;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.StateProcessModuleService;
import com.ruoyi.system.service.StateProcessTemplateService;
import com.ruoyi.system.vo.ProcessDetailVO;
import com.ruoyi.system.vo.ProcessTaskListVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -163,6 +166,13 @@
        return AjaxResult.success(processTemplateService.dealTaskPage(processTemplatePageBO));
    }
    //待办和已办列表
    @ApiOperation("待办和已办列表")
    @PostMapping("/dealAndWait/task/page")
    public AjaxResult<PageInfo<ProcessTaskListVO>> dealAndWaitTaskPage(@RequestBody ProcessTaskListBO processTemplatePageBO) {
        return AjaxResult.success(processTemplateService.dealAndWaitTaskPage(processTemplatePageBO));
    }
    //抄送
    @ApiOperation("抄送列表")
    @PostMapping("/copy/task/page")
@@ -188,4 +198,12 @@
        return AjaxResult.success();
    }
    //审核详情
    @ApiOperation("审核详情")
    @GetMapping("/detail")
    public AjaxResult<ProcessDetailVO> detail(@RequestParam String taskId) {
        ProcessDetailVO detail = processTemplateService.detail(taskId);
        return AjaxResult.success(detail);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java
@@ -1,8 +1,13 @@
package com.ruoyi.web.controller.api;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.WebUtils;
import com.ruoyi.system.importExcel.TBankFlowImportExcel;
import com.ruoyi.system.model.TBankFlow;
import com.ruoyi.system.query.TBankFlowQuery;
import com.ruoyi.system.service.TBankFlowService;
@@ -14,6 +19,15 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * <p>
@@ -28,6 +42,7 @@
public class TBankFlowController {
    @Autowired
    private TBankFlowService flowService;
    /**
     * 获取流水列表
     */
@@ -40,8 +55,65 @@
    @ApiOperation(value = "根据支付方式统计流水金额")
    @PostMapping("/getPaymentStats")
    public R<TBankFlowStatisticsVo> getPaymentStats(@RequestBody TBankFlowQuery query){
    public R<TBankFlowStatisticsVo> getPaymentStats(@RequestBody TBankFlowQuery query) {
        return R.ok(flowService.getPaymentStats(query));
    }
    @PostMapping("importBankFlow")
    public void importElectronic(@RequestBody MultipartFile file) {
        try (
                InputStream is = file.getInputStream();
        ) {
            List<TBankFlowImportExcel> failList = new Vector<>();
            EasyExcel.read(is, TBankFlowImportExcel.class, new AnalysisEventListener<TBankFlowImportExcel>() {
                private final List<TBankFlowImportExcel> list = new ArrayList<>();
                final AtomicInteger all = new AtomicInteger();
                @Override
                public void invoke(TBankFlowImportExcel data, AnalysisContext context) {
                    all.addAndGet(1);
                    boolean isok = data.validate();
                    if (!isok) {
                        failList.add(data);
                        return;
                    }
                    list.add(data);
                    int size = list.size();
                    if (size >= 100) {
                        flowService.saveImportBatch(list, failList);
                        list.clear();
                    }
                }
                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    int size = list.size();
                    if (size > 0) {
                        flowService.saveImportBatch(list, failList);
                    }
                }
            }).sheet().doRead();
            // 导出导入结果
            HttpServletResponse response = WebUtils.response();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            if (failList.size() > 0) {
                EasyExcel.write(response.getOutputStream(), TBankFlowImportExcel.class).sheet("Sheet1").doWrite(failList);
            } else {
                TBankFlowImportExcel result = new TBankFlowImportExcel();
                result.setResult("全部成功");
                failList.add(result);
                EasyExcel.write(response.getOutputStream(), TBankFlowImportExcel.class).sheet("Sheet1").doWrite(failList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("银行流水返回结果导出失败");
        }
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java
@@ -6,17 +6,19 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.dto.*;
import com.ruoyi.system.model.TBill;
import com.ruoyi.system.model.TBillDetail;
import com.ruoyi.system.query.TBillQuery;
import com.ruoyi.system.service.TBillDetailService;
import com.ruoyi.system.service.TBillService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
 * <p>
@@ -34,7 +36,8 @@
    @Autowired
    TBillService tBillService;
    @Autowired
    TBillDetailService tBillDetailService;
    @PreAuthorize("@ss.hasPermi('system:bill:list')")
@@ -52,6 +55,22 @@
        tBillService.saveBill(bill);
        return R.ok();
    }
    @ApiOperation("通过ID查找详情")
    @GetMapping("getDetailById")
    public R<TBillDto> getDetailById(@Validated @NotEmpty String id){
        TBillDto dto = tBillService.getDetailByBillId(id);
        if (dto.getBillType().equals("3")){
            List<TBillDetail> details = tBillDetailService.getByBillId(id);
            for (TBillDetail detail : details) {
                if (detail.getLiveType()==1)dto.setWater(detail); //水费
                else dto.setElect(detail);  //电费
            }
        }
        return R.ok(dto);
    }
    @PreAuthorize("@ss.hasPermi('system:bill:checkOfflinePay')")
    @ApiOperation("确认线下缴费")
    @PostMapping("checkOfflinePay")
@@ -70,7 +89,7 @@
    @PreAuthorize("@ss.hasPermi('system:bill:sendMailBatchByBillIds')")
    @ApiOperation("账单批量发送短信通知")
    @ApiOperation("账单批量发送邮箱通知")
    @PostMapping("sendMailBatchByBillIds")
    public R sendMailBatchByBillIds(@Validated @RequestBody SmsByBillDto dto){
        Integer failNum = tBillService.sendMailBatchByBillIds(dto);
@@ -85,5 +104,8 @@
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -179,7 +179,6 @@
    @ApiOperation(value = "获取合同分页列表")
    @PostMapping(value = "/contractList")
    @PreAuthorize("@ss.hasPermi('system:contract:list')")
    public R<PageInfo<TContract>> contractList(@RequestBody TContractQuery query) {
        return R.ok(contractService.contractList(query));
    }
@@ -190,6 +189,22 @@
    public R<Boolean> addContract(@Validated @RequestBody TContractDTO dto) {
        dto.setChangeRent(dto.getMonthRent());
        contractService.save(dto);
        if (dto.getStatus().equals("2")){
            //发起合同新增审批
            ProcessStartBO processStartBO = new ProcessStartBO();
            processStartBO.setCategory(ProcessCategoryEnum.CATEGORY1.getValue().toString());
            processStartBO.setModuleName("合同新增审批");
            processStartBO.setName(dto.getContractName());
            //需要显示发起申请人所在单位
//            String cedName = SecurityUtils.getLoginUser().getUser().getDept().getDeptName();
//            String remark = String.format("【镇/街】:%s,【征收实施单位】:%s,【申请金额】:%s万元", stateProject.getStreet(), cedName, stateApplyRecord.getAmount());
            processStartBO.setRemark("");
            Map<String, Object> variable = new HashMap<>();
            variable.put("projectId", dto.getId());
            processStartBO.setVariable(variable);
            //开启工作流程
            stateProcessTemplateService.start(processStartBO);
        }
        if (dto.getIsIncreasing()){
            TContractRentType tContractRentType = new TContractRentType();
            tContractRentType.setContractId(dto.getId());
@@ -199,23 +214,6 @@
            tContractRentType.setChangeTime(dto.getChangeTime());
            tContractRentType.setCycleTime(dto.getCycleTime());
            contractRentTypeService.save(tContractRentType);
            if (dto.getStatus().equals("2")){
                //发起合同新增审批
                ProcessStartBO processStartBO = new ProcessStartBO();
                processStartBO.setCategory(ProcessCategoryEnum.CATEGORY1.getValue().toString());
                processStartBO.setModuleName("合同新增审批");
                processStartBO.setName(dto.getContractName());
                //需要显示发起申请人所在单位
//            String cedName = SecurityUtils.getLoginUser().getUser().getDept().getDeptName();
//            String remark = String.format("【镇/街】:%s,【征收实施单位】:%s,【申请金额】:%s万元", stateProject.getStreet(), cedName, stateApplyRecord.getAmount());
                processStartBO.setRemark("");
                Map<String, Object> variable = new HashMap<>();
                variable.put("projectId", dto.getId());
                processStartBO.setVariable(variable);
                //开启工作流程
                stateProcessTemplateService.start(processStartBO);
            }
        }
        return R.ok();
    }
@@ -322,7 +320,6 @@
    @PreAuthorize("@ss.hasPermi('system:contract:terminate')")
    public R terminateContract(@RequestBody TerminateContractDTO dto) {
        contractService.terminateContract(dto);
        // 生成房屋验收记录 待验收
        return R.ok();
    }
    @ApiOperation(value = "根据合同id查看验收记录")
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java
@@ -57,7 +57,6 @@
    public R<Boolean> updateHouse(@Validated @RequestBody THouseDTO dto) {
        return R.ok(tHouseService.updateById(dto));
    }
    @Log(title = "房屋基础信息管理-查询房屋信息", businessType = BusinessType.DELETE)
    @ApiOperation(value = "查询房屋信息")
    @GetMapping(value = "/getHouseById")
    @PreAuthorize("@ss.hasPermi('system:house:detail')")
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
@@ -116,7 +116,7 @@
        return AjaxResult.success(roleService.selectRoleById(roleId));
    }
    @PreAuthorize("@ss.hasPermi('system:role:detail')")
//    @PreAuthorize("@ss.hasPermi('system:role:detail')")
    @ApiOperation("角色详情")
    @GetMapping("/roleInfo")
    public AjaxResult roleInfo(@RequestParam Long roleId)
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -192,7 +192,9 @@
        }
        user.setUpdateBy(getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        if(StringUtils.isNotEmpty(user.getPassword())){
            user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        }
        return AjaxResult.success(userService.updateUser(user));
    }
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/DataUpdateHandlerConfig.java
New file
@@ -0,0 +1,61 @@
package com.ruoyi.web.core.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Configuration;
/**
 * @author xiaochen
 * @ClassName DataUpdateInterceptor
 * @Description 数据更新操作处理
 * @date 2021-12-15
 * <p>
 * 注意,之前在此处注入了 JwtTokenUtils
 * <p>
 * 造成spring循环依赖,项目支棱不起来
 */
@Slf4j
@Configuration
public class DataUpdateHandlerConfig implements MetaObjectHandler {
    /**
     * 新增数据执行
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        //  获取登录信息
        String userName = SecurityUtils.getUsername();
        if (StringUtils.isNotBlank(userName)) {
            this.setFieldValByName("createBy", userName, metaObject);
            this.setFieldValByName("updateBy", userName, metaObject);
        } else {
            this.setFieldValByName("createBy", userName, metaObject);
            this.setFieldValByName("updateBy", userName, metaObject);
        }
    }
    /**
     * 修改数据执行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        //  获取登录信息
        String userName = SecurityUtils.getUsername();
        if (StringUtils.isNotBlank(userName)){
            this.setFieldValByName("createBy", userName, metaObject);
            this.setFieldValByName("updateBy", userName, metaObject);
        } else {
            this.setFieldValByName("createBy", userName, metaObject);
            this.setFieldValByName("updateBy", userName, metaObject);
        }
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MybatisPlusConfig.java
File was renamed from ruoyi-common/src/main/java/com/ruoyi/common/config/MybatisPlusConfig.java
@@ -1,4 +1,4 @@
package com.ruoyi.common.config;
package com.ruoyi.web.core.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
ruoyi-admin/src/main/resources/application-test.yml
@@ -225,4 +225,4 @@
  appId: 1400957506
  secretid: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x
  secretkey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU
  sign: 四川金达通信工程
  sign: 畅云出行
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
@@ -310,6 +310,14 @@
        return R.ok(tenantService.pageListApplet(query));
    }
    /**
     * 获取租户管理列表
     */
    @ApiOperation(value = "获取租户详情")
    @GetMapping(value = "/getTenantDetailById")
    public R<TTenant> getTenantDetailById(@RequestParam String id) {
        return R.ok(tenantService.getById(id));
    }
    /**
     * 租户详情-租房信息
     */
    @ApiOperation(value = "租户详情-租房信息列表")
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/StateProcessController.java
New file
@@ -0,0 +1,209 @@
package com.ruoyi.web.controller.api;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.BaseModel;
import com.ruoyi.common.core.domain.BasePage;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.bo.*;
import com.ruoyi.system.model.StateProcessModule;
import com.ruoyi.system.model.StateProcessTemplate;
import com.ruoyi.system.model.TContract;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.StateProcessModuleService;
import com.ruoyi.system.service.StateProcessTemplateService;
import com.ruoyi.system.vo.ProcessDetailVO;
import com.ruoyi.system.vo.ProcessTaskListVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
@Api(tags = "审批流程管理")
@RequestMapping("/state-process")
@RestController
@RequiredArgsConstructor
public class StateProcessController {
    private final StateProcessTemplateService processTemplateService;
    private final StateProcessModuleService processModuleService;
    private final ISysUserService sysUserService;
    //应用流程分页列表
    @ApiOperation("应用流程分页列表")
    @PostMapping("/module/page")
    public AjaxResult<List<StateProcessModule>> modulePage(@RequestBody BasePage basePage) {
        LambdaQueryWrapper<StateProcessModule> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(StateProcessModule::getCategory);
        //查询应用流程列表
        List<StateProcessModule> result = processModuleService.list(queryWrapper);
        List<String> updateUserId = result.stream().map(BaseModel::getUpdateBy).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(updateUserId)){
            //根据用户id查询用户信息
            List<SysUser> sysUsers = sysUserService.selectUserByUserNameList(updateUserId);
            Map<Long, SysUser> sysUserMap;
            if (!CollectionUtils.isEmpty(sysUsers)){
                sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
            } else {
                sysUserMap = new HashMap<>();
            }
            //遍历列表,设置更新人名称
            result.forEach(e -> {
                SysUser sysUser = sysUserMap.get(e.getUpdateBy());
                if (Objects.nonNull(sysUser)){
                    e.setUpdateBy(sysUser.getNickName());
                }
            });
        }
        return AjaxResult.success(result);
    }
    //修改应用流程
    @Log(title = "审批流程管理-修改应用流程", businessType = BusinessType.UPDATE)
    @ApiOperation("修改应用流程")
    @PostMapping("/module/update")
    public AjaxResult<PageInfo<StateProcessModule>> moduleUpdate(@RequestBody ProcessModuleUpdateBO processModuleUpdateBO) {
        StateProcessTemplate stateProcessTemplate = processTemplateService.getById(processModuleUpdateBO.getTemplateId());
        if (Objects.isNull(stateProcessTemplate)) {
            return AjaxResult.success();
        }
        StateProcessModule stateProcessModule = new StateProcessModule();
        stateProcessModule.setId(processModuleUpdateBO.getId());
        stateProcessModule.setTemplateId(processModuleUpdateBO.getTemplateId());
        stateProcessModule.setTemplateName(stateProcessTemplate.getTemplateName());
        stateProcessModule.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        stateProcessModule.setCreateTime(LocalDateTime.now());
        stateProcessModule.setUpdateTime(LocalDateTime.now());
        stateProcessModule.setRemark(processModuleUpdateBO.getRemark());
        processModuleService.updateById(stateProcessModule);
        return AjaxResult.success();
    }
    //流程模版分页
    @ApiOperation("流程模版分页")
    @PostMapping("/template/page")
    public AjaxResult<Page<StateProcessTemplate>> page(ProcessTemplatePageBO request) {
        Page<StateProcessTemplate> templatePage = processTemplateService.page(request);
        return AjaxResult.success(templatePage);
    }
    //查询流程模版
    @ApiOperation("查询流程模版")
    @GetMapping("/template/getById")
    public AjaxResult<StateProcessTemplate> selectById(@RequestParam String id) {
        return AjaxResult.success(processTemplateService.getById(id));
    }
    //修改并部署模版
    @Log(title = "审批流程管理-修改并部署模版", businessType = BusinessType.UPDATE)
    @ApiOperation("修改并部署模版")
    @PostMapping("/template/update")
    public AjaxResult<Boolean> update(@RequestBody ProcessUpdateBO processUpdateBO) {
        return AjaxResult.success(processTemplateService.update(processUpdateBO));
    }
    //删除模版
    @Log(title = "审批流程管理-删除模版", businessType = BusinessType.DELETE)
    @ApiOperation("删除模版")
    @GetMapping("/template/deleteById")
    public AjaxResult<Boolean> deleteById(@RequestParam String id) {
        StateProcessTemplate template = processTemplateService.getById(id);
        //查询是否存在使用的
        LambdaUpdateWrapper<StateProcessModule> moduleLambdaUpdateWrapper = new LambdaUpdateWrapper<>();;
        moduleLambdaUpdateWrapper.eq(StateProcessModule::getTemplateId, template.getId());
        if (processModuleService.getBaseMapper().exists(moduleLambdaUpdateWrapper)) {
            throw new GlobalException("该模版在应用流程中已使用!");
        }
        //根据key修改所有版本为已删除
        boolean result = processTemplateService.remove(Wrappers.lambdaQuery(StateProcessTemplate.class)
                .eq(StateProcessTemplate::getTemplateKey, template.getTemplateKey()));
        return AjaxResult.success(result);
    }
    //创建并部署模版
    @Log(title = "审批流程管理-创建并部署模版", businessType = BusinessType.INSERT)
    @ApiOperation("创建并部署模版")
    @PostMapping("/template/create")
    public AjaxResult<Boolean> create(@RequestBody ProcessCreateBO processCreateBO) {
        return AjaxResult.success(processTemplateService.create(processCreateBO));
    }
    //流程发起
    @Log(title = "审批流程管理-流程发起", businessType = BusinessType.INSERT)
    @ApiOperation("流程发起")
    @PostMapping("/start")
    public AjaxResult<Boolean> start(@RequestBody ProcessStartBO processStartBO) {
        return AjaxResult.success(processTemplateService.start(processStartBO));
    }
    //待办
    @ApiOperation("待办列表")
    @PostMapping("/wait/task/page")
    public AjaxResult<PageInfo<ProcessTaskListVO>> waitTaskPage(@RequestBody ProcessTaskListBO processTemplatePageBO) {
        return AjaxResult.success(processTemplateService.waitTaskPageApplet(processTemplatePageBO));
    }
    //已办
    @ApiOperation("已办列表")
    @PostMapping("/deal/task/page")
    public AjaxResult<PageInfo<ProcessTaskListVO>> dealTaskPage(@RequestBody ProcessTaskListBO processTemplatePageBO) {
        return AjaxResult.success(processTemplateService.dealTaskPageApplet(processTemplatePageBO));
    }
    //我发起的
    @ApiOperation("我发起的列表")
    @PostMapping("/initiate/task/page")
    public AjaxResult<PageInfo<ProcessTaskListVO>> initiateTaskPage(@RequestBody ProcessTaskListBO processTemplatePageBO) {
        return AjaxResult.success(processTemplateService.initiateTaskPage(processTemplatePageBO));
    }
    //抄送
    @ApiOperation("抄送列表")
    @PostMapping("/copy/task/page")
    public AjaxResult<PageInfo<ProcessTaskListVO>> copyTaskPage(@RequestBody ProcessTaskListBO processTaskListBO){
        return AjaxResult.success(processTemplateService.copyTaskPage(processTaskListBO));
    }
    //审核通过
    @Log(title = "审批流程管理-审核通过", businessType = BusinessType.UPDATE)
    @ApiOperation("审核通过")
    @PostMapping("/agree")
    public AjaxResult<Object> agree(@RequestBody ProcessAgreeBO processAgreeBO) {
        processTemplateService.agree(processAgreeBO);
        return AjaxResult.success();
    }
    //审核拒绝
    @Log(title = "审批流程管理-审核拒绝", businessType = BusinessType.UPDATE)
    @ApiOperation("审核拒绝")
    @PostMapping("/refuse")
    public AjaxResult<Object> refuse(@RequestBody ProcessRefuseBO processRefuseBO) {
        processTemplateService.refuse(processRefuseBO);
        return AjaxResult.success();
    }
    //审核详情
    @ApiOperation("审核详情")
    @GetMapping("/detail")
    public AjaxResult<ProcessDetailVO> detail(@RequestParam String taskId) {
        ProcessDetailVO detail = processTemplateService.detail(taskId);
        return AjaxResult.success(detail);
    }
}
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -60,7 +60,6 @@
    @ApiOperation(value = "我的合同分页列表")
    @PostMapping(value = "/contractList")
    public R<PageInfo<TContract>> contractList(@RequestBody TContractAppletQuery query) {
        // todo 获取登陆人id
        LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet();
        if (loginUserApplet==null){
            return R.fail(401,"登录失效");
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/THouseController.java
@@ -1,8 +1,19 @@
package com.ruoyi.web.controller.api;
import com.ruoyi.common.constant.DictConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.system.model.THouse;
import com.ruoyi.system.service.THouseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -13,9 +24,21 @@
 * @author xiaochen
 * @since 2025-01-17
 */
@Api(tags = "房屋管理")
@RestController
@RequestMapping("/t-house")
public class THouseController {
    @Autowired
    private THouseService tHouseService;
    @ApiOperation(value = "查询房屋信息")
    @GetMapping(value = "/getHouseById")
    @PreAuthorize("@ss.hasPermi('system:house:detail')")
    public R<THouse> getHouseById(@RequestParam String id) {
        THouse tHouse = tHouseService.getById(id);
        tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus()));
        tHouse.setBusinessAttributes(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BUSINESS_ATTRIBUTES,tHouse.getBusinessAttributes()));
        return R.ok(tHouse);
    }
}
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/WxLoginController.java
@@ -135,6 +135,7 @@
        LoginUserApplet loginUserApplet = new LoginUserApplet();
        TTenantResp tTenantResp = new TTenantResp();
        BeanUtils.copyProperties(tenant, tTenantResp);
        tTenantResp.setResidentName(appletUserDecodeData.getPhoneNumber());
        loginUserApplet.setUser(tTenantResp);
        loginUserApplet.setUserId(tenant.getId());
        Map<String, Object> tokenInfos = new HashMap<>();
ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -130,7 +130,7 @@
            String code = String.valueOf((int) (Math.random() * 1000000));
            redisCache.setCacheObject(phone, code,5*60,TimeUnit.SECONDS);
            try {
                smsUtil.sendSms(phone, "", new String[]{code});
                smsUtil.sendSms(phone, "2369926", new String[]{code});
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
ruoyi-applet/src/main/java/com/ruoyi/web/core/config/DataUpdateHandlerConfig.java
New file
@@ -0,0 +1,61 @@
package com.ruoyi.web.core.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Configuration;
/**
 * @author xiaochen
 * @ClassName DataUpdateInterceptor
 * @Description 数据更新操作处理
 * @date 2021-12-15
 * <p>
 * 注意,之前在此处注入了 JwtTokenUtils
 * <p>
 * 造成spring循环依赖,项目支棱不起来
 */
@Slf4j
@Configuration
public class DataUpdateHandlerConfig implements MetaObjectHandler {
    /**
     * 新增数据执行
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        //  获取登录信息
//        String userName = SecurityUtils.getUsernameApplet();
//        if (StringUtils.isNotBlank(userName)) {
//            this.setFieldValByName("createBy", userName, metaObject);
//            this.setFieldValByName("updateBy", userName, metaObject);
//        } else {
//            this.setFieldValByName("createBy", userName, metaObject);
//            this.setFieldValByName("updateBy", userName, metaObject);
//        }
    }
    /**
     * 修改数据执行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        //  获取登录信息
//        String userName = SecurityUtils.getUsernameApplet();
//        if (StringUtils.isNotBlank(userName)){
//            this.setFieldValByName("createBy", userName, metaObject);
//            this.setFieldValByName("updateBy", userName, metaObject);
//        } else {
//            this.setFieldValByName("createBy", userName, metaObject);
//            this.setFieldValByName("updateBy", userName, metaObject);
//        }
    }
}
ruoyi-applet/src/main/java/com/ruoyi/web/core/config/MybatisPlusConfig.java
copy from ruoyi-common/src/main/java/com/ruoyi/common/config/MybatisPlusConfig.java copy to ruoyi-applet/src/main/java/com/ruoyi/web/core/config/MybatisPlusConfig.java
File was copied from ruoyi-common/src/main/java/com/ruoyi/common/config/MybatisPlusConfig.java
@@ -1,4 +1,4 @@
package com.ruoyi.common.config;
package com.ruoyi.web.core.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
ruoyi-applet/src/main/resources/application-test.yml
@@ -220,3 +220,9 @@
    bucketAddr: ap-chengdu
    rootSrc: https://xzgttest-1305134071.cos.ap-chengdu.myqcloud.com/
    location: xizang
sms:
  enable: true
  appId: 1400957506
  secretid: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x
  secretkey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU
  sign: 畅云出行
ruoyi-common/pom.xml
@@ -200,7 +200,11 @@
            <artifactId>hutool-all</artifactId>
            <version>5.8.4</version>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version> <!-- 请检查是否有更新的版本 -->
        </dependency>
    </dependencies>
</project>
ruoyi-common/src/main/java/com/ruoyi/common/config/DataUpdateHandlerConfig.java
File was deleted
ruoyi-common/src/main/java/com/ruoyi/common/config/MailProperties.java
New file
@@ -0,0 +1,30 @@
package com.ruoyi.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
    private String smtpHost="gz-smtp.qcloudmail.com";
    private Integer smtpPort = 465;
    private String userAddr = "test@xzgtmail.591taxi.cn";
    private String password = "CY20250226pass";
    private String userName = "测试";
    /**
     * 账单提醒 ,同一个用户离上次发送短信的最小间隔
     * 单位分钟
     */
    private Integer billSmsDelayPeriod = 60;
    /**
     * 账单提醒 ,同一个用户离上次发送邮件的最小间隔
     * 单位分钟
     */
    private Integer billMailDelayPeriod = 60;
}
ruoyi-common/src/main/java/com/ruoyi/common/config/SmsConfig.java
@@ -10,7 +10,7 @@
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(SmsProperties.class)
@EnableConfigurationProperties({SmsProperties.class, MailProperties.class})
@ConditionalOnProperty(value = SmsProperties.ENABLE_KEY,matchIfMissing = true)
public class SmsConfig {
@@ -33,6 +33,5 @@
        // 实例化要请求产品(sms)的client对象,第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8
        return new SmsClient(cred, "ap-guangzhou", clientProfile);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseModel.java
@@ -41,7 +41,6 @@
     * 新增和更新执行
     */
    @ApiModelProperty(value = "记录修改人,前端忽略")
    @JsonIgnore
    @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
    private String updateBy;
    /**
ruoyi-common/src/main/java/com/ruoyi/common/utils/SmsUtil.java
@@ -1,8 +1,12 @@
package com.ruoyi.common.utils;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.config.SmsProperties;
import com.ruoyi.common.exception.ServiceException;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
@@ -19,15 +23,34 @@
    @Resource
    SmsProperties smsProperties;
    @Resource
    SmsClient smsClient;
    static SmsClient smsClient;
    public SmsProperties getPro(){
    public SmsProperties getPro() {
        return smsProperties;
    }
    public SmsClient createSmsClient(SmsProperties properties) {
        // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId,SecretKey。
        // 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中,请参考凭证管理 https://github.com/TencentCloud/tencentcloud-sdk-java?tab=readme-ov-file#%E5%87%AD%E8%AF%81%E7%AE%A1%E7%90%86。
        // 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。
        // SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi
        // Credential cred = new Credential("SecretId", "SecretKey");
        Credential cred = new Credential(properties.getSecretid(), properties.getSecretkey());
        // 实例化一个http选项,可选的,没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        // 指定接入地域域名,默认就近地域接入域名为 sms.tencentcloudapi.com ,也支持指定地域域名访问,例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com
        httpProfile.setEndpoint("sms.tencentcloudapi.com");
        // 实例化一个客户端配置对象
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品(sms)的client对象,第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8
        return new SmsClient(cred, "ap-guangzhou", clientProfile);
    }
    public boolean sendSms(String phone,String templateId,String[] param){
        phone = phone.startsWith("+86")?phone:("+86"+phone);
        SendSmsRequest req = new SendSmsRequest();
        req.setSmsSdkAppid(smsProperties.getAppId());
        req.setPhoneNumberSet(new String[]{phone});
@@ -38,7 +61,8 @@
        req.setSessionContext("");
        req.setExtendCode("");
        try {
            smsClient.SendSms(req);
            SendSmsResponse sendSmsResponse = smsClient.SendSms(req);
            System.out.println(JSON.toJSONString(sendSmsResponse));
            return true;
        } catch (TencentCloudSDKException e) {
            log.error("发送短信失败,{},{}",phone,param,e);
@@ -49,5 +73,17 @@
        }
    }
    public static void main(String[] args) {
        SmsProperties properties = new SmsProperties();
        properties.setAppId("1400957506");
        properties.setSign("畅云出行");
        properties.setSecretid("AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x");
        properties.setSecretkey("lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU");
        SmsUtil smsUtil = new SmsUtil();
        smsUtil.smsProperties = properties;
        smsUtil.smsClient = smsUtil.createSmsClient(properties);
        boolean isok = smsUtil.sendSms("15826040006", "2369926", new String[]{"526584"});
        System.out.println(isok);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java
New file
@@ -0,0 +1,108 @@
package com.ruoyi.common.utils;
import com.ruoyi.common.config.MailProperties;
import com.ruoyi.common.exception.ServiceException;
import com.sun.xml.internal.org.jvnet.mimepull.MIMEMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
@Component
@Slf4j
public class TencentMailUtil {
    @Autowired
    MailProperties properties;
    public MailProperties getPro() {
        return properties;
    }
    /**
     *
     * @param emailAddress  邮件接收者email地址
     * @param param 用户房屋地址参数
     */
    public void send(String emailAddress,String param){
        // 配置发送邮件的环境属性
        final Properties props = new Properties();
        // 表示SMTP发送邮件,需要进行身份验证
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", properties.getSmtpHost());
        // 如果使用ssl,则去掉使用25端口的配置,进行如下配置,
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.port", properties.getSmtpPort());
        props.put("mail.smtp.port", properties.getSmtpPort());
        // 发件人的账号,填写控制台配置的发信地址,比如xxx@xxx.com
        props.put("mail.user", properties.getUserAddr());
        // 访问SMTP服务时需要提供的密码(在控制台选择发信地址进行设置)
        props.put("mail.password", properties.getPassword());
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.put("mail.smtp.ssl.enable", "false");
        // 构建授权信息,用于进行SMTP进行身份验证
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 用户名、密码
                String userName = props.getProperty("mail.user");
                String password = props.getProperty("mail.password");
                return new PasswordAuthentication(userName, password);
            }
        };
        // 使用环境属性和授权信息,创建邮件会话
        Session mailSession = Session.getInstance(props, authenticator);
//        mailSession.setDebug(true);
        //UUID uuid = UUID.randomUUID();
        //final String messageIDValue = "<" + uuid.toString() + ">";
        // 创建邮件消息
        MimeMessage message = new MimeMessage(mailSession) {
            //@Override
            //protected void updateMessageID() throws MessagingException {
            //设置自定义Message-ID值
            //setHeader("Message-ID", messageIDValue);
            //}
        };
        try {
            // 设置发件人邮件地址和名称。填写控制台配置的发信地址,比如xxx@xxx.com。和上面的mail.user保持一致。名称用户可以自定义填写。
            InternetAddress from = new InternetAddress(properties.getUserAddr(), properties.getUserName());
            message.setFrom(from);
            //可选。设置回信地址
//            Address[] a = new Address[1];
//            a[0] = new InternetAddress("***");
//            message.setReplyTo(a);
            // 设置收件人邮件地址,比如yyy@yyy.com
            InternetAddress to = new InternetAddress(emailAddress);
            message.setRecipient(MimeMessage.RecipientType.TO, to);
            //如果同时发给多人,才将上面两行替换为如下(因为部分收信系统的一些限制,尽量每次投递给一个人;同时我们限制单次允许发送的人数是50人):
            // 设置邮件标题
            message.setSubject("您的"+param+"账单提醒");
            message.setHeader("Content-Transfer-Encoding", "base64");
            // 设置邮件的内容体 type: text/plain(纯文本)text/html(HTML 文档)
            message.setContent("邻居您好!您"+param+",提醒您有账单需要处理,如已处理请忽略此短信,感谢您的支持!如有疑问请详询:4008888888。", "text/html;charset=UTF-8");
            //发送邮件
            Transport.send(message);
        } catch (MessagingException | UnsupportedEncodingException e) {
            log.error("发送邮件发生异常",e);
            throw new ServiceException("发送邮件失败,请检查");
        }
    }
//    public static void main(String[] args) {
//        TencentMailUtil tencentMailUtil = new TencentMailUtil();
//        MailProperties properties = new MailProperties();
//        tencentMailUtil.properties = properties;
//        tencentMailUtil.send("214491528@qq.com","大学城揽院24栋");
//
//    }
}
ruoyi-system/pom.xml
@@ -51,6 +51,12 @@
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--集成EasyExcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.6</version>
        </dependency>
<!--        <dependency>-->
ruoyi-system/src/main/java/com/ruoyi/system/bo/ProcessAgreeBO.java
@@ -22,5 +22,9 @@
     * 理由
     */
    private String remark;
    /**
     * 图片
     */
    private String pictures;
}
ruoyi-system/src/main/java/com/ruoyi/system/bo/ProcessRefuseBO.java
@@ -22,6 +22,9 @@
     * 理由
     */
    private String remark;
    /**
     * 图片
     */
    private String pictures;
}
ruoyi-system/src/main/java/com/ruoyi/system/bo/ProcessTaskListBO.java
@@ -1,8 +1,11 @@
package com.ruoyi.system.bo;
import com.ruoyi.common.core.domain.BasePage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Setter
@Getter
@@ -10,11 +13,13 @@
    /**
     * 任务名称
     */
    @ApiModelProperty(value = "任务名称")
    private String name;
    /**
     * 任务名称
     */
    @ApiModelProperty(value = "任务名称")
    private String moduleName;
//    /**
//     * 流程实例状态( 0,审批中 1,审批通过 2,审批拒绝 3)
@@ -23,5 +28,25 @@
    /**
     * 创建人
     */
    @ApiModelProperty(value = "创建人")
    private String createBy;
    @ApiModelProperty(value = "乙方名称")
    private String partyTwoName;
    @ApiModelProperty(value = "合同编号")
    private String contractNumber;
    @ApiModelProperty(value = "合同名称")
    private String contractName;
    @ApiModelProperty(value = "合同状态")
    private String status;
    @ApiModelProperty(value = "前端忽略")
    private List<String> instanceIds;
    @ApiModelProperty(value = "时间筛选 1=1天 2=7天 3=30天")
    private Integer timeType;
    @ApiModelProperty(value = "排序  1=最早到达 2=最新到达")
    private Integer sortBy=2;
}
ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java
@@ -1,8 +1,10 @@
package com.ruoyi.system.dto;
import com.ruoyi.system.model.TBill;
import com.ruoyi.system.model.TBillDetail;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@@ -17,6 +19,26 @@
    private String account;
    private String houseName;
    /**
     * 合同信息
     */
    private String contractName;
    private String partyTwoName;
    private BigDecimal totalYear;
    private String payType;
    private BigDecimal deposit;
    /**
     * 水费
     */
    private TBillDetail water;
    /**
     * 电费
     */
    private TBillDetail elect;
}
ruoyi-system/src/main/java/com/ruoyi/system/importExcel/TBankFlowImportExcel.java
New file
@@ -0,0 +1,51 @@
package com.ruoyi.system.importExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.io.Serializable;
import java.math.BigDecimal;
/**
 * @author 64502
 */
@Data
@ApiModel(value="银行流水导入Excel")
public class TBankFlowImportExcel implements Serializable {
    @ExcelProperty("银行流水号")
    private String bankSerialNumber;
    @ExcelProperty("流水金额")
    private BigDecimal flowMoney;
    @ExcelProperty("支付时间")
    private String payTime;
    @ExcelProperty("付款人")
    private String payer;
    @ExcelProperty("导入结果")
    private String result;
    public boolean validate() {
        if (StringUtils.isEmpty(bankSerialNumber)){
            result = "银行流水号不能为空";
            return false;
        }
        if (StringUtils.isEmpty(payTime)){
            result = "支付时间不能为空";
            return false;
        }
        if (flowMoney == null){
            result = "流水金额不能为空";
            return false;
        }
        return true;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/StateTaskCenterMapper.java
@@ -1,9 +1,23 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.bo.ProcessTaskListBO;
import com.ruoyi.system.model.StateTaskCenter;
import com.ruoyi.system.vo.ProcessTaskListVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface StateTaskCenterMapper extends BaseMapper<StateTaskCenter> {
    /**
     * 分页查询
     * @param processTaskListBO
     * @param pageInfo
     * @return
     */
    List<ProcessTaskListVO> pageList(@Param("query") ProcessTaskListBO processTaskListBO, @Param("pageInfo") PageInfo<ProcessTaskListVO> pageInfo);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java
@@ -34,5 +34,5 @@
     */
    List<TBillDto> invoiceList(@Param("query")TBillQuery query, @Param("pageInfo")PageInfo<TBillDto> pageInfo);
    TBillDto selectTenentByBillId(@Param("billId") String billId);
    TBillDto selectDetailByBillId(@Param("billId") String billId);
}
ruoyi-system/src/main/java/com/ruoyi/system/model/StateProcessInstanceAction.java
@@ -42,5 +42,11 @@
    @ApiModelProperty(value = "备注")
    @TableField("remark")
    private String remark;
    @ApiModelProperty(value = "图片")
    @TableField("pictures")
    private String pictures;
    @TableField(exist = false)
    private String nickName;
}
ruoyi-system/src/main/java/com/ruoyi/system/model/StateTaskCenter.java
@@ -35,5 +35,8 @@
    private String flowId;
    @TableField("variable")
    private String variable;
    @ApiModelProperty(value = "合同项目id")
    @TableField("project_id")
    private String projectId;
}
ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
@@ -90,9 +92,9 @@
    private String handlePerson;
    @ApiModelProperty(value = "处理时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @TableField("handle_time")
    private LocalDateTime handleTime;
    private LocalDate handleTime;
    @ApiModelProperty(value = "结果描述")
    @TableField("result_describe")
ruoyi-system/src/main/java/com/ruoyi/system/service/StateProcessTemplateService.java
@@ -6,6 +6,7 @@
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.bo.*;
import com.ruoyi.system.model.StateProcessTemplate;
import com.ruoyi.system.vo.ProcessDetailVO;
import com.ruoyi.system.vo.ProcessTaskListVO;
public interface StateProcessTemplateService extends IService<StateProcessTemplate> {
@@ -26,9 +27,11 @@
    //待办
    PageInfo<ProcessTaskListVO> waitTaskPage(ProcessTaskListBO processTaskListBO);
    PageInfo<ProcessTaskListVO> waitTaskPageApplet(ProcessTaskListBO processTaskListBO);
    //已办
    PageInfo<ProcessTaskListVO> dealTaskPage(ProcessTaskListBO processTaskListBO);
    PageInfo<ProcessTaskListVO> dealTaskPageApplet(ProcessTaskListBO processTaskListBO);
    //抄送
    PageInfo<ProcessTaskListVO> copyTaskPage(ProcessTaskListBO processTaskListBO);
@@ -38,4 +41,10 @@
    //拒绝
    void refuse(ProcessRefuseBO processRefuseBO);
    PageInfo<ProcessTaskListVO> dealAndWaitTaskPage(ProcessTaskListBO processTemplatePageBO);
    ProcessDetailVO detail(String taskId);
    PageInfo<ProcessTaskListVO> initiateTaskPage(ProcessTaskListBO processTemplatePageBO);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/StateTaskCenterService.java
@@ -1,7 +1,12 @@
package com.ruoyi.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.bo.ProcessTaskListBO;
import com.ruoyi.system.model.StateTaskCenter;
import com.ruoyi.system.vo.ProcessTaskListVO;
public interface StateTaskCenterService extends IService<StateTaskCenter> {
    PageInfo<ProcessTaskListVO> pageList(ProcessTaskListBO processTaskListBO);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/TBankFlowService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.importExcel.TBankFlowImportExcel;
import com.ruoyi.system.model.TBankFlow;
import com.ruoyi.system.query.TBankFlowQuery;
import com.ruoyi.system.vo.TBankFlowStatisticsVo;
@@ -21,8 +22,9 @@
    PageInfo<TBankFlow> pageList(TBankFlowQuery query);
    List<TBankFlow> makeQuery(TBankFlowQuery query);
    TBankFlowStatisticsVo getPaymentStats( TBankFlowQuery query);
    List<TBankFlow> searchByBankSerialNumber(String bankSerialNumber);
    void saveImportBatch(List<TBankFlowImportExcel> list, List<TBankFlowImportExcel> failList);
    TBankFlow findUniq(String bankSerialNumber);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/TBillDetailService.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.system.model.TBillDetail;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
 * <p>
 * 账单水电费子表 服务类
@@ -13,4 +16,7 @@
 */
public interface TBillDetailService extends IService<TBillDetail> {
    List<TBillDetail> getByBillId(@NotEmpty String billId);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
@@ -10,6 +10,7 @@
import com.ruoyi.system.query.TBillQuery;
import com.taxi591.bankapi.dto.ChargeBillRequest;
import javax.validation.constraints.NotEmpty;
import java.math.BigDecimal;
import java.util.List;
import java.util.function.Consumer;
@@ -81,4 +82,6 @@
    Integer sendSmsByBillIds(SmsByBillDto dto);
    Integer sendMailBatchByBillIds(SmsByBillDto dto);
    TBillDto getDetailByBillId(@NotEmpty String id);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java
@@ -22,5 +22,4 @@
    TFlowManagementStatisticsVo getPaymentStats(TFlowManagementQuery req);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java
@@ -231,10 +231,14 @@
            }
            case CATEGORY2: {
                // 合同签订审批
                int submitStatus = status==0?3:(status==1?4:5);
                contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus);
                break;
            }
            case CATEGORY3: {
                // 合同提前终止审批
                int submitStatus = status==0?4:(status==1?6:5);
                contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus);
                break;
            }
            default:
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -29,8 +30,10 @@
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.bo.*;
import com.ruoyi.system.mapper.StateProcessTemplateMapper;
import com.ruoyi.system.mapper.TContractMapper;
import com.ruoyi.system.model.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.vo.ProcessDetailVO;
import com.ruoyi.system.vo.ProcessTaskListVO;
import lombok.AllArgsConstructor;
import org.apache.commons.io.IOUtils;
@@ -71,6 +74,8 @@
    private FlwHisTaskActorMapper flwHisTaskActorMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private TContractMapper contractMapper;
    /**
     * 流程模版分页
@@ -141,7 +146,7 @@
        // 更新模板, version+1
        StateProcessTemplate processTemplate = new StateProcessTemplate();
        processTemplate.setId(IdUtils.simpleUUID());
        processTemplate.setId(processUpdateBO.getId());
        processTemplate.setWorkFlowId(deployId);
        processTemplate.setWorkflowVersion(flwProcess.getProcessVersion());
        processTemplate.setTemplateName(processUpdateBO.getTemplateName());
@@ -152,20 +157,20 @@
        processTemplate.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
        processTemplate.setUpdateTime(LocalDateTime.now());
        processTemplate.setTemplateVersion(temp.getTemplateVersion() + 1);
        this.save(processTemplate);
        return this.updateById(processTemplate);
        //查询版本是否绑定流程,更新
        LambdaQueryWrapper<StateProcessModule> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StateProcessModule::getTemplateId, processUpdateBO.getId());
        List<StateProcessModule> stateProcessModules = stateProcessModuleService.list(queryWrapper);
        if (Objects.isNull(stateProcessModules) || stateProcessModules.isEmpty()) {
            return true;
        }
        for (StateProcessModule stateProcessModule : stateProcessModules) {
            stateProcessModule.setTemplateId(processTemplate.getId());
            stateProcessModule.setTemplateName(processTemplate.getTemplateName());
        }
        return stateProcessModuleService.updateBatchById(stateProcessModules);
//        LambdaQueryWrapper<StateProcessModule> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(StateProcessModule::getTemplateId, processUpdateBO.getId());
//        List<StateProcessModule> stateProcessModules = stateProcessModuleService.list(queryWrapper);
//        if (Objects.isNull(stateProcessModules) || stateProcessModules.isEmpty()) {
//            return true;
//        }
//        for (StateProcessModule stateProcessModule : stateProcessModules) {
//            stateProcessModule.setTemplateId(processTemplate.getId());
//            stateProcessModule.setTemplateName(processTemplate.getTemplateName());
//        }
//        return stateProcessModuleService.updateBatchById(stateProcessModules);
    }
    /**
@@ -262,6 +267,7 @@
            stateTaskCenter.setRemark(processStartBO.getRemark());
            stateTaskCenter.setCreateBy(loginUser.getUser().getNickName());
            stateTaskCenter.setVariable(JSONUtil.toJsonStr(processStartBO.getVariable()));
            stateTaskCenter.setProjectId(JSONObject.parseObject(JSONUtil.toJsonStr(processStartBO.getVariable())).getString("projectId"));
            stateTaskCenterService.save(stateTaskCenter);
            // action记录
@@ -352,6 +358,156 @@
        //转换类
        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
        // 查询合同信息
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            // 查询合同信息
            TContract contract = contractMapper.selectById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
            processTaskListVO.setContract(contract);
        }
        pageInfo.setRecords(processTaskListVOS);
        List<String> updateUserId = processTaskListVOS.stream().map(ProcessTaskListVO::getCreateBy).collect(Collectors.toList());
        Map<Long, SysUser> sysUserMap;
        if (!CollectionUtils.isEmpty(updateUserId)) {
            //根据用户id查询更新人信息
            List<SysUser> sysUsers = sysUserService.selectUserByUserNameList(updateUserId);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
            } else {
                sysUserMap = new HashMap<>();
            }
        } else {
            sysUserMap = new HashMap<>();
        }
        Map<Long, List<FlwTask>> flwHisTaskMap = flwTasks.stream().collect(Collectors.groupingBy(FlwTask::getInstanceId));
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            List<FlwTask> flwTask = flwHisTaskMap.get(NumberUtil.parseLong(processTaskListVO.getFlowId()));
            if (!CollectionUtils.isEmpty(flwTask) && ObjectUtil.isNotEmpty(flwTask.get(0))) {
                //待审核
                processTaskListVO.setStatus("0");
                processTaskListVO.setNodeName(flwTask.get(0).getTaskName());
                processTaskListVO.setTaskId(flwTask.get(0).getId().toString());
                processTaskListVO.setVariable(flwTask.get(0).getVariable());
            }
            SysUser sysUser = sysUserMap.get(processTaskListVO.getCreateBy());
            if (Objects.nonNull(sysUser)) {
                processTaskListVO.setCreateBy(sysUser.getNickName());
            }
        }
        return pageInfo;
    }
    /**
     * 待办
     * @param processTaskListBO
     * @return
     */
    @Override
    public PageInfo<ProcessTaskListVO> waitTaskPageApplet(ProcessTaskListBO processTaskListBO) {
        String startTime = null;
        String endTime = null;
        if(Objects.nonNull(processTaskListBO.getTimeType())){
            switch (processTaskListBO.getTimeType()){
                case 1:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
                case 2:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -7), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
                case 3:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -30), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
            }
        }
        //获取当前登录用户信息
        Long userId = SecurityUtils.getLoginUser().getUserId();
        //或签时查询其他审批人是否通过(不能省略),比如 同一任务需要A,B审核,A通过了,B不用在审核了,在历史表查询A的审核记录
        LambdaQueryWrapper<FlwHisInstance> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(FlowEntity::getCreateTime);
        //待审核
        lambdaQueryWrapper.eq(FlwHisInstance::getInstanceState, 0);
        List<Long> flwHisInstances = flwHisInstanceMapper.selectList(lambdaQueryWrapper).stream()
                .map(FlwHisInstance::getId).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(flwHisInstances)) {
            return new PageInfo<>();
        }
        //查询任务参与者
        LambdaQueryWrapper<FlwTaskActor> query = new LambdaQueryWrapper<>();
        query.and(qy -> qy.eq(FlwTaskActor::getActorId, userId)
                //0指定用户
                .eq(FlwTaskActor::getActorType, 0)
                .or().in(FlwTaskActor::getActorId, userId)
                //1指定角色
                .eq(FlwTaskActor::getActorType, 1));
        if (ObjectUtil.isNotNull(processTaskListBO) && ObjectUtil.isNotNull(flwHisInstances)) {
            // 添加条件
            query = query.in(FlwTaskActor::getInstanceId, flwHisInstances);
        }
        List<FlwTaskActor> flwTaskActorPage = flwTaskActorMapper.selectList(query);
        if (ObjectUtil.isEmpty(flwTaskActorPage)) {
            return new PageInfo<>();
        }
        //查询任务信息
        List<FlwTask> flwTasks = flwTaskMapper.selectList(Wrappers.<FlwTask>lambdaQuery()
                .orderByDesc(FlwTask::getCreateTime)
                .in(FlwTask::getId, flwTaskActorPage.stream()
                        .map(FlwTaskActor::getTaskId).collect(Collectors.toList())));
        if (ObjectUtil.isNull(flwTasks)) {
            return new PageInfo<>();
        }
        List<String> instanceIds = flwTasks.stream().map(FlwTask::getInstanceId)
                .map(String::valueOf).collect(Collectors.toList());
        //分页查询任务中心任务
        LambdaQueryWrapper<StateTaskCenter> stateTaskQuery = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(processTaskListBO.getName())) {
            stateTaskQuery.like(StateTaskCenter::getName, processTaskListBO.getName());
        }
        if (ObjectUtil.isNotEmpty(processTaskListBO.getModuleName())) {
            stateTaskQuery.like(StateTaskCenter::getModuleName, processTaskListBO.getModuleName());
        }
        if (ObjectUtil.isNotEmpty(processTaskListBO.getCreateBy())) {
            stateTaskQuery.like(StateTaskCenter::getCreateBy, processTaskListBO.getCreateBy());
        }
        if (ObjectUtil.isNotEmpty(startTime) && ObjectUtil.isNotEmpty(endTime)) {
            stateTaskQuery.between(StateTaskCenter::getCreateTime, startTime, endTime);
        }
        if(Objects.isNull(processTaskListBO.getSortBy())){
            processTaskListBO.setSortBy(2);
        }
        if (processTaskListBO.getSortBy() == 1) {
            stateTaskQuery.orderByAsc(BaseModel::getCreateTime);
        }
        if (processTaskListBO.getSortBy() == 2) {
            stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
        }
        stateTaskQuery.in(StateTaskCenter::getFlowId, instanceIds);
        PageInfo pageInfo = new PageInfo(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
        PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
        //转换类
        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
        // 查询合同信息
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            // 查询合同信息
            TContract contract = contractMapper.selectById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
            processTaskListVO.setContract(contract);
        }
        pageInfo.setRecords(processTaskListVOS);
        List<String> updateUserId = processTaskListVOS.stream().map(ProcessTaskListVO::getCreateBy).collect(Collectors.toList());
@@ -439,6 +595,152 @@
        PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
        //转换类
        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
        // 查询合同信息
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            // 查询合同信息
            TContract contract = contractMapper.selectById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
            processTaskListVO.setContract(contract);
        }
        pageInfo.setRecords(processTaskListVOS);
        if (ObjectUtil.isEmpty(processTaskListVOS)) {
            return pageInfo;
        }
        Map<Long, List<FlwHisTask>> flwHisTaskMap = flwHisTaskList.stream().collect(Collectors.groupingBy(FlwHisTask::getInstanceId));
        //查询原因
        List<String> taskIds = flwHisTaskList.stream().map(FlowEntity::getId).map(String::valueOf).collect(Collectors.toList());
        List<StateProcessInstanceAction> actions = stateProcessInstanceActionService.list(
                Wrappers.<StateProcessInstanceAction>lambdaQuery().in(StateProcessInstanceAction::getNodeId, taskIds));
        Map<String, StateProcessInstanceAction> actionMap = actions.stream().collect(Collectors.toMap(StateProcessInstanceAction::getNodeId, Function.identity()));
        List<String> updateUserId = processTaskListVOS.stream().map(ProcessTaskListVO::getCreateBy).collect(Collectors.toList());
        Map<Long, SysUser> sysUserMap;
        if (!CollectionUtils.isEmpty(updateUserId)) {
            List<SysUser> sysUsers = sysUserService.selectUserByUserNameList(updateUserId);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
            } else {
                sysUserMap = new HashMap<>();
            }
        } else {
            sysUserMap = new HashMap<>();
        }
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            List<FlwHisTask> flwHisTasks = flwHisTaskMap.get(NumberUtil.parseLong(processTaskListVO.getFlowId()));
            if (ObjectUtil.isNotEmpty(flwHisTaskMap)) {
                //当某个用户在同一个模块审批流的多个节点都存在时,多次审核后,已审核列表页报错
                for (FlwHisTask flwHisTask : flwHisTasks) {
                    if (flwHisTask.getInstanceId().toString().equals(processTaskListVO.getFlowId())) {
                        //10等于发起人与审批人一致自动审核完成
                        processTaskListVO.setStatus(flwHisTask.getTaskState() == 10 ? "2" : flwHisTask.getTaskState().toString());
                        processTaskListVO.setNodeName(flwHisTask.getTaskName());
                        processTaskListVO.setTaskId(flwHisTask.getId().toString());
                        processTaskListVO.setVariable(flwHisTask.getVariable());
                    }
                }
            }
            StateProcessInstanceAction action = actionMap.get(processTaskListVO.getTaskId());
            if (ObjectUtil.isNotEmpty(action)) {
                processTaskListVO.setReason(action.getRemark());
            }
            SysUser sysUser = sysUserMap.get(processTaskListVO.getCreateBy());
            if (Objects.nonNull(sysUser)) {
                processTaskListVO.setCreateBy(sysUser.getNickName());
            }
        }
        return pageInfo;
    }
    @Override
    public PageInfo<ProcessTaskListVO> dealTaskPageApplet(ProcessTaskListBO processTaskListBO) {
        String startTime = null;
        String endTime = null;
        if(Objects.nonNull(processTaskListBO.getTimeType())){
            switch (processTaskListBO.getTimeType()){
                case 1:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
                case 2:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -7), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
                case 3:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -30), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
            }
        }
        //获取当前登录用户信息
        Long userId = SecurityUtils.getLoginUser().getUserId();
        LambdaQueryWrapper<FlwHisTaskActor> query = Wrappers.<FlwHisTaskActor>lambdaQuery()
                .and(qy -> qy.eq(FlwTaskActor::getActorId, userId)
                        //0指定用户
                        .eq(FlwTaskActor::getActorType, 0)
                        //指定角色
                        .or().in(FlwTaskActor::getActorId, userId)
                        .eq(FlwTaskActor::getActorType, 1));
        List<FlwHisTaskActor> flwHisTaskActors = flwHisTaskActorMapper.selectList(query);
        List<Long> hisTaskIds = flwHisTaskActors.stream().map(FlwTaskActor::getTaskId).collect(Collectors.toList());
        if (hisTaskIds.isEmpty()) {
            return new PageInfo<>();
        }
        List<FlwHisTask> flwHisTaskList = flwHisTaskMapper.selectList(
                Wrappers.<FlwHisTask>lambdaQuery()
                        .notIn(FlwHisTask::getTaskType, TaskType.cc.getValue(), TaskType.major.getValue())
                        .orderByDesc(FlwHisTask::getCreateTime)
                        .in(FlwHisTask::getId, hisTaskIds));
        if (ObjectUtil.isEmpty(flwHisTaskList)) {
            new PageInfo<>();
        }
        List<String> instanceId = flwHisTaskList.stream().map(FlwTask::getInstanceId)
                .map(String::valueOf).collect(Collectors.toList());
        //分页查询任务中心任务
        LambdaQueryWrapper<StateTaskCenter> stateTaskQuery = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(processTaskListBO.getName())) {
            stateTaskQuery.like(StateTaskCenter::getName, processTaskListBO.getName());
        }
        if (ObjectUtil.isNotEmpty(processTaskListBO.getModuleName())) {
            stateTaskQuery.like(StateTaskCenter::getModuleName, processTaskListBO.getModuleName());
        }
        if (ObjectUtil.isNotEmpty(processTaskListBO.getCreateBy())) {
            stateTaskQuery.like(StateTaskCenter::getCreateBy, processTaskListBO.getCreateBy());
        }
        if (ObjectUtil.isEmpty(instanceId)) {
            return new PageInfo<>();
        }
        if (ObjectUtil.isNotEmpty(startTime) && ObjectUtil.isNotEmpty(endTime)) {
            stateTaskQuery.between(StateTaskCenter::getCreateTime, startTime, endTime);
        }
        if(Objects.isNull(processTaskListBO.getSortBy())){
            processTaskListBO.setSortBy(2);
        }
        if (processTaskListBO.getSortBy() == 1) {
            stateTaskQuery.orderByAsc(BaseModel::getCreateTime);
        }
        if (processTaskListBO.getSortBy() == 2) {
            stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
        }
        stateTaskQuery.in(StateTaskCenter::getFlowId, instanceId);
        PageInfo pageInfo = new PageInfo<>(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
        PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
        //转换类
        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
        // 查询合同信息
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            // 查询合同信息
            TContract contract = contractMapper.selectById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
            processTaskListVO.setContract(contract);
        }
        pageInfo.setRecords(processTaskListVOS);
        if (ObjectUtil.isEmpty(processTaskListVOS)) {
@@ -612,6 +914,7 @@
        stateProcessInstanceAction.setActionType(StateProcessActionEnum.APPROVED.getValue());
        stateProcessInstanceAction.setNodeId(processAgreeBO.getTaskId());
        stateProcessInstanceAction.setRemark(processAgreeBO.getRemark());
        stateProcessInstanceAction.setPictures(processAgreeBO.getPictures());
        stateProcessInstanceActionService.save(stateProcessInstanceAction);
    }
@@ -629,9 +932,364 @@
        record.setActionType(StateProcessActionEnum.REJECTED.getValue());
        record.setNodeId(processRefuseBO.getTaskId());
        record.setRemark(processRefuseBO.getRemark());
        record.setPictures(processRefuseBO.getPictures());
        stateProcessInstanceActionService.save(record);
    }
    @Override
    public PageInfo<ProcessTaskListVO> dealAndWaitTaskPage(ProcessTaskListBO processTaskListBO) {
        //获取当前登录用户信息
        Long userId = SecurityUtils.getLoginUser().getUserId();
        //或签时查询其他审批人是否通过(不能省略),比如 同一任务需要A,B审核,A通过了,B不用在审核了,在历史表查询A的审核记录
        LambdaQueryWrapper<FlwHisInstance> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(FlowEntity::getCreateTime);
        //待审核,通过,拒绝
        lambdaQueryWrapper.in(FlwHisInstance::getInstanceState, 0,1,2);
        List<Long> flwHisInstances = flwHisInstanceMapper.selectList(lambdaQueryWrapper).stream()
                .map(FlwHisInstance::getId).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(flwHisInstances)) {
            return new PageInfo<>();
        }
        //查询任务参与者
        LambdaQueryWrapper<FlwTaskActor> query = new LambdaQueryWrapper<>();
        query.and(qy -> qy.eq(FlwTaskActor::getActorId, userId)
                //0指定用户
                .eq(FlwTaskActor::getActorType, 0)
                .or().in(FlwTaskActor::getActorId, userId)
                //1指定角色
                .eq(FlwTaskActor::getActorType, 1));
        if (ObjectUtil.isNotNull(processTaskListBO) && ObjectUtil.isNotNull(flwHisInstances)) {
            // 添加条件
            query = query.in(FlwTaskActor::getInstanceId, flwHisInstances);
        }
        List<FlwTaskActor> flwTaskActorPage = flwTaskActorMapper.selectList(query);
        if (ObjectUtil.isEmpty(flwTaskActorPage)) {
            return new PageInfo<>();
        }
        //查询任务信息
        List<FlwTask> flwTasks = flwTaskMapper.selectList(Wrappers.<FlwTask>lambdaQuery()
                .orderByDesc(FlwTask::getCreateTime)
                .in(FlwTask::getId, flwTaskActorPage.stream()
                        .map(FlwTaskActor::getTaskId).collect(Collectors.toList())));
        if (ObjectUtil.isNull(flwTasks)) {
            return new PageInfo<>();
        }
        List<String> instanceIds = flwTasks.stream().map(FlwTask::getInstanceId)
                .map(String::valueOf).collect(Collectors.toList());
        //分页查询任务中心任务
//        LambdaQueryWrapper<StateTaskCenter> stateTaskQuery = new LambdaQueryWrapper<>();
//        if (ObjectUtil.isNotEmpty(processTaskListBO.getName())) {
//            stateTaskQuery.like(StateTaskCenter::getName, processTaskListBO.getName());
//        }
//        if (ObjectUtil.isNotEmpty(processTaskListBO.getModuleName())) {
//            stateTaskQuery.like(StateTaskCenter::getModuleName, processTaskListBO.getModuleName());
//        }
//        if (ObjectUtil.isNotEmpty(processTaskListBO.getCreateBy())) {
//            stateTaskQuery.like(StateTaskCenter::getCreateBy, processTaskListBO.getCreateBy());
//        }
//        stateTaskQuery.in(StateTaskCenter::getFlowId, instanceIds);
//        stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
        processTaskListBO.setInstanceIds(instanceIds);
//        PageInfo pageInfo = new PageInfo(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
//        PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
//        //转换类
//        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
//        // 查询合同信息
//        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
//            // 查询合同信息
//            TContract contract = contractService.getById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
//            processTaskListVO.setContract(contract);
//        }
//        pageInfo.setRecords(processTaskListVOS);
        PageInfo<ProcessTaskListVO> processTaskListVOS = stateTaskCenterService.pageList(processTaskListBO);
        List<String> updateUserId = processTaskListVOS.getRecords().stream().map(ProcessTaskListVO::getCreateBy).collect(Collectors.toList());
        Map<Long, SysUser> sysUserMap;
        if (!CollectionUtils.isEmpty(updateUserId)) {
            //根据用户id查询更新人信息
            List<SysUser> sysUsers = sysUserService.selectUserByUserNameList(updateUserId);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
            } else {
                sysUserMap = new HashMap<>();
            }
        } else {
            sysUserMap = new HashMap<>();
        }
        Map<Long, List<FlwTask>> flwHisTaskMap = flwTasks.stream().collect(Collectors.groupingBy(FlwTask::getInstanceId));
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS.getRecords()) {
            List<FlwTask> flwTask = flwHisTaskMap.get(NumberUtil.parseLong(processTaskListVO.getFlowId()));
            if (!CollectionUtils.isEmpty(flwTask) && ObjectUtil.isNotEmpty(flwTask.get(0))) {
                //待审核
                processTaskListVO.setStatus("0");
                processTaskListVO.setNodeName(flwTask.get(0).getTaskName());
                processTaskListVO.setTaskId(flwTask.get(0).getId().toString());
                processTaskListVO.setVariable(flwTask.get(0).getVariable());
            }
            SysUser sysUser = sysUserMap.get(processTaskListVO.getCreateBy());
            if (Objects.nonNull(sysUser)) {
                processTaskListVO.setCreateBy(sysUser.getNickName());
            }
        }
        return processTaskListVOS;
    }
//    @Override
//    public PageInfo<ProcessTaskListVO> dealAndWaitTaskPage(ProcessTaskListBO processTaskListBO) {
//        //获取当前登录用户信息
//        Long userId = SecurityUtils.getLoginUser().getUserId();
//
//        //或签时查询其他审批人是否通过(不能省略),比如 同一任务需要A,B审核,A通过了,B不用在审核了,在历史表查询A的审核记录
//        LambdaQueryWrapper<FlwHisInstance> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.orderByDesc(FlowEntity::getCreateTime);
//        //待审核,通过,拒绝
//        lambdaQueryWrapper.in(FlwHisInstance::getInstanceState, 0,1,2);
//
//        List<Long> flwHisInstances = flwHisInstanceMapper.selectList(lambdaQueryWrapper).stream()
//                .map(FlwHisInstance::getId).collect(Collectors.toList());
//
//        //查询任务参与者
//        LambdaQueryWrapper<FlwTaskActor> query = new LambdaQueryWrapper<>();
//        query.and(qy -> qy.eq(FlwTaskActor::getActorId, userId)
//                //0指定用户
//                .eq(FlwTaskActor::getActorType, 0)
//                .or().in(FlwTaskActor::getActorId, userId)
//                //1指定角色
//                .eq(FlwTaskActor::getActorType, 1));
//        if (ObjectUtil.isNotNull(processTaskListBO) && ObjectUtil.isNotNull(flwHisInstances)) {
//            // 添加条件
//            query = query.in(FlwTaskActor::getInstanceId, flwHisInstances);
//        }
//        List<FlwTaskActor> flwTaskActorPage = flwTaskActorMapper.selectList(query);
//        List<String> instanceIds = new ArrayList<>();
//        List<FlwTask> flwTasks = new ArrayList<>();
//        if (ObjectUtil.isNotEmpty(flwTaskActorPage)) {
//            //查询任务信息
//            flwTasks = flwTaskMapper.selectList(Wrappers.<FlwTask>lambdaQuery()
//                    .orderByDesc(FlwTask::getCreateTime)
//                    .in(FlwTask::getId, flwTaskActorPage.stream()
//                            .map(FlwTaskActor::getTaskId).collect(Collectors.toList())));
//            if (ObjectUtil.isNotNull(flwTasks)) {
//                instanceIds = flwTasks.stream().map(FlwTask::getInstanceId)
//                        .map(String::valueOf).collect(Collectors.toList());
//            }
//        }
//
//        LambdaQueryWrapper<FlwHisTaskActor> hisQuery= Wrappers.<FlwHisTaskActor>lambdaQuery()
//                .and(qy -> qy.eq(FlwTaskActor::getActorId, userId)
//                        //0指定用户
//                        .eq(FlwTaskActor::getActorType, 0)
//                        //指定角色
//                        .or().in(FlwTaskActor::getActorId, userId)
//                        .eq(FlwTaskActor::getActorType, 1));
//        List<FlwHisTaskActor> flwHisTaskActors = flwHisTaskActorMapper.selectList(hisQuery);
//        List<Long> hisTaskIds = flwHisTaskActors.stream().map(FlwTaskActor::getTaskId).collect(Collectors.toList());
//
//        if (!CollectionUtils.isEmpty(hisTaskIds)) {
//            List<FlwHisTask> flwHisTaskList = flwHisTaskMapper.selectList(
//                    Wrappers.<FlwHisTask>lambdaQuery()
//                            .notIn(FlwHisTask::getTaskType, TaskType.cc.getValue(), TaskType.major.getValue())
//                            .orderByDesc(FlwHisTask::getCreateTime)
//                            .in(FlwHisTask::getId, hisTaskIds));
//            if (ObjectUtil.isNotEmpty(flwHisTaskList)) {
//                instanceIds.addAll(flwHisTaskList.stream().map(FlwHisTask::getInstanceId)
//                        .map(String::valueOf).collect(Collectors.toList()));
//            }
//        }
//
//
//        //分页查询任务中心任务
////        LambdaQueryWrapper<StateTaskCenter> stateTaskQuery = new LambdaQueryWrapper<>();
////        if (ObjectUtil.isNotEmpty(processTaskListBO.getName())) {
////            stateTaskQuery.like(StateTaskCenter::getName, processTaskListBO.getName());
////        }
////        if (ObjectUtil.isNotEmpty(processTaskListBO.getModuleName())) {
////            stateTaskQuery.like(StateTaskCenter::getModuleName, processTaskListBO.getModuleName());
////        }
////        if (ObjectUtil.isNotEmpty(processTaskListBO.getCreateBy())) {
////            stateTaskQuery.like(StateTaskCenter::getCreateBy, processTaskListBO.getCreateBy());
////        }
////        stateTaskQuery.in(StateTaskCenter::getFlowId, instanceIds);
////        stateTaskQuery.orderByDesc(BaseModel::getCreateTime);
//        processTaskListBO.setInstanceIds(instanceIds);
////        PageInfo pageInfo = new PageInfo(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
////        PageInfo<StateTaskCenter> taskCenters = stateTaskCenterService.page(pageInfo,stateTaskQuery);
////        //转换类
////        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
////        // 查询合同信息
////        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
////            // 查询合同信息
////            TContract contract = contractService.getById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
////            processTaskListVO.setContract(contract);
////        }
////        pageInfo.setRecords(processTaskListVOS);
//
//        PageInfo<ProcessTaskListVO> processTaskListVOS = stateTaskCenterService.pageList(processTaskListBO);
//
//        List<String> updateUserId = processTaskListVOS.getRecords().stream().map(ProcessTaskListVO::getCreateBy).collect(Collectors.toList());
//        Map<Long, SysUser> sysUserMap;
//        if (!CollectionUtils.isEmpty(updateUserId)) {
//            //根据用户id查询更新人信息
//            List<SysUser> sysUsers = sysUserService.selectUserByUserNameList(updateUserId);
//
//            if (!CollectionUtils.isEmpty(sysUsers)) {
//                sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
//            } else {
//                sysUserMap = new HashMap<>();
//            }
//        } else {
//            sysUserMap = new HashMap<>();
//        }
//
//        Map<Long, List<FlwTask>> flwHisTaskMap = new HashMap<>();
//        if(!CollectionUtils.isEmpty(flwTasks)){
//            flwHisTaskMap = flwTasks.stream().collect(Collectors.groupingBy(FlwTask::getInstanceId));
//        }
//
//        for (ProcessTaskListVO processTaskListVO : processTaskListVOS.getRecords()) {
//            if(!CollectionUtils.isEmpty(flwHisTaskMap)){
//                List<FlwTask> flwTask = flwHisTaskMap.get(NumberUtil.parseLong(processTaskListVO.getFlowId()));
//                if (!CollectionUtils.isEmpty(flwTask) && ObjectUtil.isNotEmpty(flwTask.get(0))) {
//                    //待审核
//                    processTaskListVO.setStatus("0");
//                    processTaskListVO.setNodeName(flwTask.get(0).getTaskName());
//                    processTaskListVO.setTaskId(flwTask.get(0).getId().toString());
//                    processTaskListVO.setVariable(flwTask.get(0).getVariable());
//                }
//            }
//            SysUser sysUser = sysUserMap.get(processTaskListVO.getCreateBy());
//            if (Objects.nonNull(sysUser)) {
//                processTaskListVO.setCreateBy(sysUser.getNickName());
//            }
//        }
//        return processTaskListVOS;
//    }
    @Override
    public ProcessDetailVO detail(String taskId) {
        ProcessDetailVO processDetailVO = new ProcessDetailVO();
        FlwTask flwTask = flwTaskMapper.selectById(Long.valueOf(taskId));
        TContract contract;
        Long instanceId;
        if(Objects.nonNull(flwTask)){
            instanceId = flwTask.getInstanceId();
            // 查询合同信息
            contract = contractMapper.selectById(JSONObject.parseObject(flwTask.getVariable()).getString("projectId"));
        }else {
            FlwHisTask flwHisTask = flwHisTaskMapper.selectById(Long.valueOf(taskId));
            if(Objects.isNull(flwHisTask)){
                throw new GlobalException("流程不存在");
            }
            instanceId = flwHisTask.getInstanceId();
            contract = contractMapper.selectById(Objects.requireNonNull(JSONObject.parseObject(flwHisTask.getVariable())).getString("projectId"));
        }
        BeanUtil.copyProperties(contract, processDetailVO);
        // 查询历史任务
        List<FlwHisTask> flwHisTasks = flwHisTaskMapper.selectList(Wrappers.<FlwHisTask>lambdaQuery().eq(FlwHisTask::getInstanceId, instanceId));
        processDetailVO.setFlwHisTasks(flwHisTasks);
        List<StateProcessInstanceAction> list = stateProcessInstanceActionService.list(Wrappers.<StateProcessInstanceAction>lambdaQuery().eq(StateProcessInstanceAction::getInstanceId, flwTask.getInstanceId())
                .orderByDesc(StateProcessInstanceAction::getCreateTime));
        for (StateProcessInstanceAction stateProcessInstanceAction : list) {
            SysUser sysUser = sysUserService.selectUserById(Long.valueOf(stateProcessInstanceAction.getAuditorId()));
            if(Objects.nonNull(sysUser)){
                stateProcessInstanceAction.setNickName(sysUser.getNickName());
            }
        }
        processDetailVO.setInstanceActions(list);
        return processDetailVO;
    }
    @Override
    public PageInfo<ProcessTaskListVO> initiateTaskPage(ProcessTaskListBO processTaskListBO) {
        String startTime = null;
        String endTime = null;
        if(Objects.nonNull(processTaskListBO.getTimeType())){
            switch (processTaskListBO.getTimeType()){
                case 1:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
                case 2:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -7), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
                case 3:
                    startTime = DateUtil.format(DateUtil.offsetDay(new Date(), -30), "yyyy-MM-dd") + " 00:00:00";
                    endTime = DateUtil.format(DateUtil.offsetDay(new Date(), -1), "yyyy-MM-dd") + " 23:59:59";
                    break;
            }
        }
        //获取当前登录用户信息
        Long userId = SecurityUtils.getLoginUser().getUserId();
        //分页查询任务中心任务
        LambdaQueryWrapper<FlwHisTask> stateTaskQuery = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(startTime) && ObjectUtil.isNotEmpty(endTime)) {
            stateTaskQuery.between(FlwHisTask::getCreateTime, startTime, endTime);
        }
        if(Objects.isNull(processTaskListBO.getSortBy())){
            processTaskListBO.setSortBy(2);
        }
        if (processTaskListBO.getSortBy() == 1) {
            stateTaskQuery.orderByAsc(FlwHisTask::getCreateTime);
        }
        if (processTaskListBO.getSortBy() == 2) {
            stateTaskQuery.orderByDesc(FlwHisTask::getCreateTime);
        }
        stateTaskQuery.eq(FlwHisTask::getParentTaskId, 0L);
        stateTaskQuery.like(FlwHisTask::getCreateId, userId);
        PageInfo pageInfo = new PageInfo<>(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
        PageInfo<FlwHisTask> taskCenters = flwHisTaskMapper.selectPage(pageInfo,stateTaskQuery);
        //转换类
        List<ProcessTaskListVO> processTaskListVOS = BeanUtil.copyToList(taskCenters.getRecords(), ProcessTaskListVO.class);
        // 查询合同信息
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            // 查询合同信息
            TContract contract = contractMapper.selectById(JSONObject.parseObject(processTaskListVO.getVariable()).getString("projectId"));
            processTaskListVO.setContract(contract);
        }
        pageInfo.setRecords(processTaskListVOS);
        if (ObjectUtil.isEmpty(processTaskListVOS)) {
            return pageInfo;
        }
        List<String> updateUserId = processTaskListVOS.stream().map(ProcessTaskListVO::getCreateBy).collect(Collectors.toList());
        Map<Long, SysUser> sysUserMap;
        if (!CollectionUtils.isEmpty(updateUserId)) {
            List<SysUser> sysUsers = sysUserService.selectUserByUserNameList(updateUserId);
            if (!CollectionUtils.isEmpty(sysUsers)) {
                sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
            } else {
                sysUserMap = new HashMap<>();
            }
        } else {
            sysUserMap = new HashMap<>();
        }
        for (ProcessTaskListVO processTaskListVO : processTaskListVOS) {
            SysUser sysUser = sysUserMap.get(processTaskListVO.getCreateBy());
            if (Objects.nonNull(sysUser)) {
                processTaskListVO.setCreateBy(sysUser.getNickName());
            }
        }
        return pageInfo;
    }
    private FlowCreator currentFlowCreator() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (null == loginUser || null == loginUser.getUser().getUserId()) {
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateTaskCenterServiceImpl.java
@@ -1,11 +1,24 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.system.bo.ProcessTaskListBO;
import com.ruoyi.system.mapper.StateTaskCenterMapper;
import com.ruoyi.system.model.StateTaskCenter;
import com.ruoyi.system.model.TFaultAreaDic;
import com.ruoyi.system.service.StateTaskCenterService;
import com.ruoyi.system.vo.ProcessTaskListVO;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StateTaskCenterServiceImpl extends ServiceImpl<StateTaskCenterMapper, StateTaskCenter> implements StateTaskCenterService {
    @Override
    public PageInfo<ProcessTaskListVO> pageList(ProcessTaskListBO processTaskListBO) {
        PageInfo<ProcessTaskListVO> pageInfo = new PageInfo<>(processTaskListBO.getPageNum(), processTaskListBO.getPageSize());
        List<ProcessTaskListVO> list = this.baseMapper.pageList(processTaskListBO,pageInfo);
        pageInfo.setRecords(list);
        return pageInfo;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java
@@ -1,16 +1,30 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.importExcel.TBankFlowImportExcel;
import com.ruoyi.system.mapper.TBankFlowMapper;
import com.ruoyi.system.model.TBankFlow;
import com.ruoyi.system.model.TFlowManagement;
import com.ruoyi.system.query.TBankFlowQuery;
import com.ruoyi.system.query.TFlowManagementQuery;
import com.ruoyi.system.service.TBankFlowService;
import com.ruoyi.system.service.TFlowManagementService;
import com.ruoyi.system.vo.TBankFlowStatisticsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;
/**
@@ -23,6 +37,8 @@
 */
@Service
public class TBankFlowServiceImpl extends ServiceImpl<TBankFlowMapper, TBankFlow> implements TBankFlowService {
    @Autowired
    TFlowManagementService flowManagementService;
    @Override
    public PageInfo<TBankFlow> pageList(TBankFlowQuery query) {
        PageInfo<TBankFlow> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
@@ -61,4 +77,70 @@
        queryWrapper.like(StringUtils.isNotEmpty(bankSerialNumber),TBankFlow::getBankSerialNumber,bankSerialNumber);
        return this.baseMapper.selectList(queryWrapper);
    }
    @Override
    public void saveImportBatch(List<TBankFlowImportExcel> list, List<TBankFlowImportExcel> failList) {
        for (TBankFlowImportExcel row : list) {
            try {
                TBankFlow preexist = findUniq(row.getBankSerialNumber());
                if (preexist != null){
                    row.setResult("流水号已存在"+row.getBankSerialNumber());
                    failList.add(row);
                    continue;
                }
                TBankFlow flow = new TBankFlow();
                BeanUtils.copyProperties(row,flow);
                try {
                    LocalDateTime parse = LocalDateTime.parse(row.getPayTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    flow.setPayTime(parse);
                }catch (DateTimeParseException e){
                    row.setResult("支付时间格式不正确"+row.getPayTime());
                    failList.add(row);
                    continue;
                }
                TFlowManagementQuery query = new TFlowManagementQuery();
                query.setBankSerialNumber(row.getBankSerialNumber());
                List<TFlowManagement> list1 = flowManagementService.makeQuery(query);
                for (TFlowManagement tFlowManagement : list1) {
                    // 如果相同流水号金额相同 :抵扣金额为流水金额,剩余金额为0,状态为正常
                    if (row.getFlowMoney().compareTo(tFlowManagement.getFlowMoney()) == 0){
                        flow.setDeductionMoney(tFlowManagement.getFlowMoney());
                        flow.setRemainingMoney(BigDecimal.ZERO);
                        flow.setFlowStatus(1);
                        this.baseMapper.insert(flow);
                        break;
                    }else {
                        // 流水号相同,金额不同:已抵扣金额为系统流水金额,剩余金额 = 银行流水金额-系统流水金额,状态为异常
                        flow.setDeductionMoney(tFlowManagement.getFlowMoney());
                        flow.setRemainingMoney(row.getFlowMoney().divide(tFlowManagement.getFlowMoney(),2, RoundingMode.HALF_DOWN));
                        flow.setFlowStatus(2);
                        this.baseMapper.insert(flow);
                        break;
                    }
                }
                // 系统流水查找不到:抵扣金额为0,剩余金额为流水金额,状态为异常
                flow.setDeductionMoney(BigDecimal.ZERO);
                flow.setRemainingMoney(row.getFlowMoney());
                flow.setFlowStatus(2);
                this.baseMapper.insert(flow);
            }catch (Exception e){
                log.error("导入银行流水信息异常",e);
                row.setResult("导入异常:"+e.getMessage());
                failList.add(row);
            }
        }
    }
    /**
     * 根据流水号查找唯一流水
     * @param bankSerialNumber
     * @return
     */
    @Override
    public TBankFlow findUniq(String bankSerialNumber) {
        LambdaQueryWrapper<TBankFlow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(bankSerialNumber),TBankFlow::getBankSerialNumber,bankSerialNumber);
        return this.baseMapper.selectOne(queryWrapper);
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillDetailServiceImpl.java
@@ -1,10 +1,15 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.mapper.TBillDetailMapper;
import com.ruoyi.system.model.TBillDetail;
import com.ruoyi.system.model.TOrderBill;
import com.ruoyi.system.service.TBillDetailService;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
 * <p>
@@ -17,4 +22,8 @@
@Service
public class TBillDetailServiceImpl extends ServiceImpl<TBillDetailMapper, TBillDetail> implements TBillDetailService {
    @Override
    public List<TBillDetail> getByBillId(@NotEmpty String billId) {
        return list(new LambdaQueryWrapper<TBillDetail>().eq(TBillDetail::getBillId,billId));
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.config.SmsProperties;
import com.ruoyi.common.constant.AmountConstant;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
@@ -9,6 +10,7 @@
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SmsUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.TencentMailUtil;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.dto.OfflinePayCheckDto;
import com.ruoyi.system.dto.SmsByBillDto;
@@ -30,6 +32,7 @@
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.stream.Collectors;
import java.math.BigDecimal;
@@ -79,6 +82,9 @@
    @Resource
    SmsUtil smsUtil;
    @Resource
    TencentMailUtil mailUtil;
    public PageInfo<TBillDto> queryPage(TBillQuery query){
        PageInfo<TBill> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
@@ -359,9 +365,9 @@
    public Integer sendSmsByBillIds(SmsByBillDto dto) {
        int failNum = 0;
        for (String billId : dto.getBillIds()) {
            TBillDto bill = getTenentByBillId(billId);
            TBillDto bill = getDetailByBillId(billId);
            if (bill.getSmsLastTime()!=null
                    && (System.currentTimeMillis()-bill.getSmsLastTime().getTime()<smsUtil.getPro().getBillSmsDelayPeriod()*60*1000L)){
                    && (System.currentTimeMillis()-bill.getSmsLastTime().getTime()<mailUtil.getPro().getBillSmsDelayPeriod()*60*1000L)){
                throw new ServiceException("有账单最近一次发送的时间是:"+DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bill.getSmsLastTime()));
            }
            if (StringUtils.isEmpty(bill.getPhone())){
@@ -388,9 +394,9 @@
    public Integer sendMailBatchByBillIds(SmsByBillDto dto) {
        int failNum = 0;
        for (String billId : dto.getBillIds()) {
            TBillDto bill = getTenentByBillId(billId);
            TBillDto bill = getDetailByBillId(billId);
            if (bill.getSmsLastTime()!=null
                    && (System.currentTimeMillis()-bill.getSmsLastTime().getTime()<smsUtil.getPro().getBillMailDelayPeriod()*60*1000L)){
                    && (System.currentTimeMillis()-bill.getSmsLastTime().getTime()<mailUtil.getPro().getBillMailDelayPeriod()*60*1000L)){
                throw new ServiceException("有账单最近一次发送的时间是:"+DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bill.getSmsLastTime()));
            }
            if (StringUtils.isEmpty(bill.getEmail())){
@@ -400,7 +406,7 @@
            TBill save = new TBill();
            save.setId(bill.getId());
            try {
                //todo  发送邮件
                mailUtil.send(bill.getEmail(),bill.getHouseName());
                save.setMailStatus(1);
            }catch (ServiceException e){
                failNum++;
@@ -413,8 +419,8 @@
        return failNum;
    }
    private TBillDto getTenentByBillId(String billId) {
        return getBaseMapper().selectTenentByBillId(billId);
    public TBillDto getDetailByBillId(@NotEmpty String billId) {
        return getBaseMapper().selectDetailByBillId(billId);
    }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
@@ -5,8 +5,10 @@
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.constant.DictConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.ProcessCategoryEnum;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.bo.ProcessStartBO;
import com.ruoyi.system.dto.SignContractDTO;
import com.ruoyi.system.dto.TerminateContractDTO;
import com.ruoyi.system.mapper.TBillMapper;
@@ -17,6 +19,7 @@
import com.ruoyi.system.query.TContractAppletQuery;
import com.ruoyi.system.query.TContractBillQuery;
import com.ruoyi.system.query.TContractQuery;
import com.ruoyi.system.service.StateProcessTemplateService;
import com.ruoyi.system.service.TBillService;
import com.ruoyi.system.service.TContractRentTypeService;
import com.ruoyi.system.service.TContractService;
@@ -32,9 +35,7 @@
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
/**
 * <p>
@@ -56,6 +57,8 @@
    private TBillService billService;
    @Resource
    private TContractMapper contractMapper;
    @Autowired
    private StateProcessTemplateService stateProcessTemplateService;
    @Override
    public PageInfo<TContract> contractList(TContractQuery query) {
@@ -101,6 +104,19 @@
        contract.setTerminateRemark(dto.getTerminateRemark());
        contract.setStatus("4");
        this.baseMapper.updateById(contract);
        // 进入合同提前终止审批流程
        ProcessStartBO processStartBO = new ProcessStartBO();
        processStartBO.setCategory(ProcessCategoryEnum.CATEGORY3.getValue().toString());
        processStartBO.setModuleName("合同提前终止审批");
        processStartBO.setName(contract.getContractName());
        processStartBO.setRemark("");
        Map<String, Object> variable = new HashMap<>();
        variable.put("projectId", dto.getId());
        processStartBO.setVariable(variable);
        //开启工作流程
        stateProcessTemplateService.start(processStartBO);
        // 生成验收记录
        TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord();
        tCheckAcceptRecord.setContractId(dto.getId());
@@ -155,9 +171,21 @@
        if (contract.getStatus().equals("4"))return R.fail("该合同已签订");
        contract.setSignature(dto.getSignature());
        contract.setStatus("4");
        contractMapper.updateById(contract);
        contract.setFirstPayTime(contract.getStartTime().plusDays(10));
        List<TBill> bills = new ArrayList<>();
        contractMapper.updateById(contract);
        // 进入签订审批流程
        ProcessStartBO processStartBO = new ProcessStartBO();
        processStartBO.setCategory(ProcessCategoryEnum.CATEGORY2.getValue().toString());
        processStartBO.setModuleName("合同签订审批");
        processStartBO.setName(contract.getContractName());
        processStartBO.setRemark("");
        Map<String, Object> variable = new HashMap<>();
        variable.put("projectId", dto.getId());
        processStartBO.setVariable(variable);
        //开启工作流程
        stateProcessTemplateService.start(processStartBO);
        List<TContractRentType> contractRentTypes = contractRentTypeService.list();
        // 生成第一笔账单
        // 第一次应缴费日期
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java
@@ -50,4 +50,5 @@
    public TFlowManagementStatisticsVo getPaymentStats(TFlowManagementQuery query) {
        return this.baseMapper.getPaymentStats(query);
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.basic.PageInfo;
import com.ruoyi.common.constant.DictConstants;
@@ -18,18 +19,16 @@
import com.ruoyi.system.query.TTenantAppletQuery;
import com.ruoyi.system.query.TTenantQuery;
import com.ruoyi.system.service.TTenantService;
import com.ruoyi.system.utils.wx.pojo.AppletUserDecodeData;
import com.ruoyi.system.vo.ExamineVO;
import com.ruoyi.system.vo.TBillVO;
import com.ruoyi.system.vo.TenantVO;
import com.sun.corba.se.spi.ior.IdentifiableFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.token.TokenService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -47,10 +46,6 @@
    private THouseMapper houseMapper;
    @Autowired
    private TContractMapper contractMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private TokenService tokenService;
    @Override
    public PageInfo<TenantVO> pageList(TTenantQuery query) {
        PageInfo<TenantVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
@@ -67,9 +62,32 @@
    public PageInfo<TenantVO> pageListApplet(TTenantAppletQuery query) {
        PageInfo<TenantVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        List<TenantVO> list = this.baseMapper.pageListApplet(query,pageInfo);
        List<String> ids = list.stream().map(TTenant::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(ids)){
            return new PageInfo<>();
        }
        List<TContract> contracts = contractMapper.selectList(Wrappers.lambdaQuery(TContract.class)
                .in(TContract::getTenantId, ids)
                .eq(TContract::getStatus, 4));
        List<THouse> houses = new ArrayList<>();
        if(!CollectionUtils.isEmpty(contracts)){
            List<String> houseIds = contracts.stream().map(TContract::getHouseId).collect(Collectors.toList());
            houses = houseMapper.selectList(Wrappers.lambdaQuery(THouse.class)
                    .in(THouse::getId, houseIds));
        }
        for (TenantVO tenantVO : list) {
            tenantVO.setTenantAttributesName(StringUtils.isNotBlank(tenantVO.getTenantAttributes())?DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_ATTRIBUTE,tenantVO.getTenantAttributes()):"");
            tenantVO.setTenantTypeName(StringUtils.isNotBlank(tenantVO.getTenantType())?DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_TYPE,tenantVO.getTenantType()):"");
            if(!CollectionUtils.isEmpty(houses)){
                List<TContract> contractList = contracts.stream().filter(contract -> contract.getTenantId().equals(tenantVO.getId())).collect(Collectors.toList());
                if(!CollectionUtils.isEmpty(contractList)){
                    TContract contract = contractList.get(0);
                    List<THouse> houseList = houses.stream().filter(house -> house.getId().equals(contract.getHouseId())).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(houseList))
                        tenantVO.setHouseName(houseList.get(0).getHouseName());
                }
            }
        }
        pageInfo.setRecords(list);
        return pageInfo;
ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessDetailVO.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.system.vo;
import com.aizuda.bpm.engine.entity.FlwHisTask;
import com.ruoyi.system.model.StateProcessInstanceAction;
import com.ruoyi.system.model.TContract;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "审批流详情返回VO")
public class ProcessDetailVO extends TContract {
    @ApiModelProperty(value = "操作记录集合")
    private List<StateProcessInstanceAction> instanceActions;
    @ApiModelProperty(value = "历史任务")
    private List<FlwHisTask> flwHisTasks;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java
@@ -1,11 +1,18 @@
package com.ruoyi.system.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.system.model.TContract;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
@Data
@@ -39,4 +46,105 @@
    private String variable;
    private String reason;
    @ApiModelProperty(value = "合同信息")
    private TContract contract;
    @ApiModelProperty(value = "合同id")
    private String contractId;
    @ApiModelProperty(value = "合同编号")
    private String contractNumber;
    @ApiModelProperty(value = "合同名称")
    private String contractName;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime startTime;
    @ApiModelProperty(value = "结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime endTime;
    @ApiModelProperty(value = "开始计费时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime startPayTime;
    @ApiModelProperty(value = "每月租金")
    private BigDecimal monthRent;
    @ApiModelProperty(value = "押金")
    private BigDecimal deposit;
    @ApiModelProperty(value = "变动后递增或递减之后的每月租金 前端忽略")
    private BigDecimal changeRent;
    @ApiModelProperty(value = "租金支付方式 月付 季付 年付")
    private String payType;
    @ApiModelProperty(value = "账单第一次支付日期 合同生效日期+10天 (不是真正的支付日期)生成第一次帐单后存值")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime firstPayTime;
    @ApiModelProperty(value = "变动时间 根据周期改变 前端忽略")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime changeTime;
    @ApiModelProperty(value = "是否递增递减 true=是 false=否")
    private Boolean isIncreasing;
    @ApiModelProperty(value = "押金是否随租金递增递减 true=是 false=否")
    private Boolean isIncreasingDeposit;
    @ApiModelProperty(value = "违约金比例")
    private BigDecimal proportion;
    @ApiModelProperty(value = "房屋id")
    private String houseId;
    @ApiModelProperty(value = "甲方名称")
    private String partyOneName;
    @ApiModelProperty(value = "甲方联系人")
    private String partyOnePerson;
    @ApiModelProperty(value = "甲方联系方式")
    private String partyOnePhone;
    @ApiModelProperty(value = "租户id")
    private String tenantId;
    @ApiModelProperty(value = "乙方名称")
    private String partyTwoName;
    @ApiModelProperty(value = "乙方联系人")
    private String partyTwoPerson;
    @ApiModelProperty(value = "乙方联系方式")
    private String partyTwoPhone;
    @ApiModelProperty(value = "合同附件,多个逗号拼接")
    private String contractFile;
    /**
     * 1    待提交
     * 2    待审批
     * 3    未签订
     * 4    已签订
     * 5    已驳回
     * 6    已终止
     * 7    待结算
     * 8    已结算
     */
    @ApiModelProperty(value = "合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算")
    private String contractStatus;
    @ApiModelProperty(value = "内存大小多个文件逗号拼接")
    private String memory;
    @ApiModelProperty(value = "附件名称 逗号拼接")
    private String contractFileName;
    @ApiModelProperty(value = "租户确认合同电子签名")
    private String signature;
    @ApiModelProperty(value = "终止合同备注说明")
    private String terminateRemark;
    @ApiModelProperty(value = "合计年租金")
    private BigDecimal totalYear;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantVO.java
@@ -18,4 +18,7 @@
    @ApiModelProperty(value = "租户类型")
    private String tenantTypeName;
    @ApiModelProperty(value = "房屋名称")
    private String houseName;
}
ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml
New file
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.StateTaskCenterMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.system.model.StateTaskCenter">
        <id column="id" property="id" />
        <result column="`name`" property="name" />
        <result column="module_name" property="moduleName" />
        <result column="remark" property="remark" />
        <result column="category" property="category" />
        <result column="flow_id" property="flowId" />
        <result column="variable" property="variable" />
        <result column="project_id" property="projectId" />
    </resultMap>
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, `name`, module_name, remark,category,flow_id,variable,project_id,create_time, update_time, create_by, update_by, disabled
    </sql>
    <select id="pageList" resultType="com.ruoyi.system.vo.ProcessTaskListVO">
        select stc.id, stc.`name`, stc.module_name, stc.remark,stc.category,stc.flow_id,stc.variable,
               tc.id AS contractId, tc.contract_number, tc.contract_name, tc.start_time, tc.end_time,tc.deposit, tc.pay_type,
               tc.first_pay_time, tc.isIncreasing,tc.isIncreasing_deposit,tc.proportion, tc.house_id, tc.party_one_name, tc.party_one_person,
               tc.party_one_phone, tc.tenant_id, tc.party_two_name,tc.party_two_person, tc.party_two_phone,tc.memory, tc.contract_file_name,
               tc.signature, tc.terminate_remark, tc.total_year,tc.status AS contractStatus
        from state_task_center stc
        LEFT JOIN t_contract tc ON stc.project_id = tc.id
        <where>
            <if test="query.instanceIds != null and query.instanceIds.size()>0">
                AND stc.flow_id IN
                <foreach collection="query.instanceIds" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            </if>
            <if test="query.name != null and query.name !=''">
                AND stc.`name` like concat('%',#{query.name},'%')
            </if>
            <if test="query.moduleName != null and query.moduleName !=''">
                AND stc.module_name like concat('%',#{query.moduleName},'%')
            </if>
            <if test="query.createBy != null and query.createBy !=''">
                AND stc.create_by like concat('%',#{query.createBy},'%')
            </if>
            <if test="query.partyTwoName != null and query.partyTwoName !=''">
                AND tc.party_two_name like concat('%',#{query.partyTwoName},'%')
            </if>
            <if test="query.contractNumber != null and query.contractNumber !=''">
                AND tc.contract_number like concat('%',#{query.contractNumber},'%')
            </if>
            <if test="query.contractName != null and query.contractName !=''">
                AND tc.contract_name like concat('%',#{query.contractName},'%')
            </if>
            <if test="query.status != null and query.status !=''">
                AND tc.status = #{query.status}
            </if>
            AND tc.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
        </where>
        ORDER BY stc.create_time DESC
    </select>
</mapper>
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -191,7 +191,7 @@
        from sys_user u
        WHERE u.del_flag = 0
        <if test="names != null and names.size()>0">
            AND u.nick_name IN
            AND u.user_name IN
            <foreach collection="names" close=")" open="(" item="name" separator=",">
                #{name}
            </foreach>
ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
@@ -130,14 +130,15 @@
        order by b.pay_fees_time
    </select>
    <select id="selectTenentByBillId" resultType="com.ruoyi.system.dto.TBillDto">
    <select id="selectDetailByBillId" resultType="com.ruoyi.system.dto.TBillDto">
        SELECT
            b.*,
            t.resident_name as residentName,
            t.email,
            t.phone,
            t.account,
            h.house_name as houseName
            h.house_name as houseName,
            c.contract_name,c.pay_type,c.party_two_name,c.total_year,c.deposit
        FROM
            t_bill b
        LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0
ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
@@ -9,7 +9,6 @@
        <result column="contract_name" property="contractName" />
        <result column="start_time" property="startTime" />
        <result column="end_time" property="endTime" />
        <result column="month_rent" property="monthRent" />
        <result column="deposit" property="deposit" />
        <result column="pay_type" property="payType" />
        <result column="first_pay_time" property="firstPayTime" />
@@ -41,9 +40,9 @@
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, contract_number, contract_name, start_time, end_time, total_rent, deposit, pay_type, first_pay_time, isIncreasing, isIncreasing_deposit,
        id, contract_number, contract_name, start_time, end_time, deposit, pay_type, first_pay_time, isIncreasing, isIncreasing_deposit,
            proportion, house_id, party_one_name, party_one_person, party_one_phone, tenant_id, party_two_name, party_two_person, party_two_phone,
            memory, contract_file_name, signature, terminate_remark, total_year
            memory, contract_file_name, signature, terminate_remark, total_year,status
    </sql>
    <select id="contractList" resultType="com.ruoyi.system.model.TContract">
        select t1.* from t_contract t1
@@ -64,8 +63,8 @@
                and t1.tenant_id = #{query.tenantId}
            </if>
            AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()}
        </where>
        order by t1.create_time desc
    </select>
    <select id="contractAppletList" resultType="com.ruoyi.system.model.TContract">
        select t1.* from t_contract t1