From 728a54cc02ff66e38bc8719ecc0f3155e597084c Mon Sep 17 00:00:00 2001 From: zhangmei <645025773@qq.com> Date: 星期五, 14 二月 2025 15:27:56 +0800 Subject: [PATCH] Merge branch 'master' of https://gitee.com/xiaochen991015/xizang into xizang-changyun --- ruoyi-admin/src/main/resources/application-test.yml | 6 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInformationServiceImpl.java | 9 ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java | 4 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java | 124 + ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java | 18 ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java | 8 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserDecodeData.java | 52 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java | 3 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java | 20 ruoyi-common/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java | 311 +++ ruoyi-system/src/main/java/com/ruoyi/system/mapper/TCheckAcceptRecordMapper.java | 15 ruoyi-admin/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java | 4 ruoyi-applet/src/main/resources/application-test.yml | 14 ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultRepairMessageService.java | 16 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/COSController.java | 55 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultRepairMessageMapper.java | 21 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WebUtils.java | 48 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java | 110 + ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java | 21 ruoyi-common/src/main/java/com/ruoyi/common/core/exception/ServiceException.java | 74 ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java | 16 ruoyi-system/src/main/java/com/ruoyi/system/model/TCheckAcceptRecord.java | 2 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml | 15 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java | 102 + ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCache.java | 117 + ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/model/WeixinProperties.java | 79 ruoyi-common/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java | 50 ruoyi-system/src/main/java/com/ruoyi/system/dto/TFaultRepairMessageDTO.java | 10 ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java | 8 ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java | 4 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TDeptToUserMapper.java | 9 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxAppletTools.java | 123 + ruoyi-system/src/main/java/com/ruoyi/system/vo/SysUserVO.java | 4 ruoyi-system/pom.xml | 4 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java | 80 ruoyi-system/src/main/resources/mapper/system/TItemMapper.xml | 2 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java | 3 ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml | 103 + ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCacheTemplate.java | 34 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TTenantResp.java | 70 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/AccessTokenRespBody.java | 28 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java | 69 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java | 135 + ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java | 27 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/SHA1.java | 36 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java | 514 +++++ ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java | 3 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resq/Code2SessionResqBody.java | 21 ruoyi-applet/src/main/resources/mybatis-config.xml | 2 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletPhoneEncrypteData.java | 19 ruoyi-system/src/main/java/com/ruoyi/system/vo/TItemTypeVO.java | 18 ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java | 10 ruoyi-system/src/main/java/com/ruoyi/system/vo/TBillVO.java | 16 ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml | 48 ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java | 22 ruoyi-system/src/main/java/com/ruoyi/system/service/TTenantService.java | 5 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxException.java | 55 ruoyi-system/src/main/java/com/ruoyi/system/vo/TCheckAcceptRecordVO.java | 20 ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java | 496 ----- ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java | 11 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java | 5 ruoyi-system/src/main/resources/mapper/system/TFaultAreaDicMapper.xml | 6 ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultAreaDicService.java | 6 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java | 24 ruoyi-system/src/main/java/com/ruoyi/system/service/TCheckAcceptRecordService.java | 9 ruoyi-common/src/main/java/com/ruoyi/common/core/utils/Constants.java | 143 + ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/WxLoginController.java | 255 ++ ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxUtils.java | 175 ++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultAreaDicServiceImpl.java | 6 ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml | 6 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/Watermark.java | 9 ruoyi-system/src/main/resources/mapper/system/TItemTypeMapper.xml | 7 ruoyi-system/src/main/resources/mapper/system/TDeptToUserMapper.xml | 3 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java | 1 ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java | 13 ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java | 22 ruoyi-applet/src/main/resources/application-prod.yml | 8 ruoyi-applet/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java | 4 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java | 132 - ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java | 1 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUserApplet.java | 263 +++ ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultAreaDicMapper.java | 6 ruoyi-system/src/main/java/com/ruoyi/system/service/TItemTypeService.java | 5 ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml | 2 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserEncrypteData.java | 20 ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/RespBody.java | 19 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TItemTypeMapper.java | 5 ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultAreaDicVO.java | 18 ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml | 15 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TItemTypeServiceImpl.java | 6 ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultRepairMessageVO.java | 22 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TItemTypeController.java | 1 ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java | 187 ++ ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxJsonUtils.java | 109 + ruoyi-system/src/main/java/com/ruoyi/system/vo/FaultConcatInfoVO.java | 17 ruoyi-common/src/main/java/com/ruoyi/common/redis/service/RedisService.java | 273 +++ ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/Code2SessionRespBody.java | 29 97 files changed, 4,415 insertions(+), 740 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java index 4ce9a6b..be95875 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java @@ -34,6 +34,9 @@ @Autowired TBillService tBillService; + + + @PreAuthorize("@ss.hasPermi('system:bill:list')") @PostMapping("list") @ApiOperation("分页查询账单列表") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java index 6cdd012..b6dee08 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TCheckAcceptRecordController.java @@ -1,9 +1,28 @@ package com.ruoyi.web.controller.api; -import org.springframework.web.bind.annotation.RequestMapping; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.system.model.TCheckAcceptRecord; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.model.THouse; +import com.ruoyi.system.query.TCheckAcceptRecordQuery; +import com.ruoyi.system.service.TCheckAcceptRecordService; +import com.ruoyi.system.service.TContractService; +import com.ruoyi.system.service.THouseService; +import com.ruoyi.system.vo.TCheckAcceptRecordVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.BeanUtils; +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.*; -import org.springframework.web.bind.annotation.RestController; +import java.util.List; /** * <p> @@ -13,9 +32,110 @@ * @author xiaochen * @since 2025-01-17 */ +@Api(tags = "验收记录管理") @RestController @RequestMapping("/t-check-accept-record") public class TCheckAcceptRecordController { + private final TCheckAcceptRecordService checkAcceptRecordService; + private final TContractService contractService; + private final THouseService houseService; + @Autowired + public TCheckAcceptRecordController(TCheckAcceptRecordService checkAcceptRecordService, TContractService contractService, THouseService houseService) { + this.checkAcceptRecordService = checkAcceptRecordService; + this.contractService = contractService; + this.houseService = houseService; + } + + /** + * 获取验收记录管理列表 + */ + @PreAuthorize("@ss.hasPermi('system:accept:list')") + @ApiOperation(value = "获取验收记录分页列表") + @PostMapping(value = "/pageList") + public R<PageInfo<TCheckAcceptRecordVO>> pageList(@RequestBody TCheckAcceptRecordQuery query) { + return R.ok(checkAcceptRecordService.pageList(query)); + } + + /** + * 通过合同id查询房屋信息 + */ + @ApiOperation(value = "通过合同id查询房屋信息") + @PostMapping(value = "/getHouseByContractId") + public R<THouse> getHouseByContractId(@RequestParam String contractId) { + TContract contract = contractService.getById(contractId); + THouse house = houseService.getById(contract.getHouseId()); + return R.ok(house); + } + + /** + * 通过房屋id查询合同信息 + */ + @ApiOperation(value = "通过房屋id查询合同信息") + @PostMapping(value = "/getContractByHouseId") + public R<TContract> getContractByHouseId(@RequestParam String houseId) { + TContract contract = contractService.getOne(Wrappers.lambdaQuery(TContract.class) + .eq(TContract::getHouseId, houseId) + .orderByDesc(TContract::getCreateTime) + .in(TContract::getStatus, 4, 6, 7) + .last("LIMIT 1")); + return R.ok(contract); + } + + /** + * 添加验收记录管理 + */ + @PreAuthorize("@ss.hasPermi('system:accept:add')") + @Log(title = "验收记录信息-新增验收记录", businessType = BusinessType.INSERT) + @ApiOperation(value = "添加验收记录") + @PostMapping(value = "/add") + public R<Boolean> add(@Validated @RequestBody TCheckAcceptRecord dto) { + // 添加验收记录 + checkAcceptRecordService.save(dto); + + // TODO 生成结算帐单 + + return R.ok(); + } + + /** + * 查看验收记录详情 + */ + @PreAuthorize("@ss.hasPermi('system:accept:detail')") + @ApiOperation(value = "查看验收记录详情") + @GetMapping(value = "/getDetailById") + public R<TCheckAcceptRecordVO> getDetailById(@RequestParam String id) { + TCheckAcceptRecord checkAcceptRecord = checkAcceptRecordService.getById(id); + TCheckAcceptRecordVO checkAcceptRecordVO = new TCheckAcceptRecordVO(); + BeanUtils.copyProperties(checkAcceptRecord, checkAcceptRecordVO); + // 查询合同信息 + checkAcceptRecordVO.setContract(contractService.getById(checkAcceptRecord.getContractId())); + // 查询房屋信息 + checkAcceptRecordVO.setHouse(houseService.getById(checkAcceptRecord.getHouseId())); + return R.ok(checkAcceptRecordVO); + } + + /** + * 删除验收记录 + */ + @PreAuthorize("@ss.hasPermi('system:accept:delete')") + @Log(title = "验收记录信息-删除验收记录", businessType = BusinessType.DELETE) + @ApiOperation(value = "删除验收记录") + @DeleteMapping(value = "/deleteById") + public R<Boolean> deleteById(@RequestParam String id) { + return R.ok(checkAcceptRecordService.removeById(id)); + } + + /** + * 批量删除验收记录 + */ + @PreAuthorize("@ss.hasPermi('system:accept:delete')") + @Log(title = "验收记录信息-删除验收记录", businessType = BusinessType.DELETE) + @ApiOperation(value = "批量删除验收记录") + @DeleteMapping(value = "/deleteByIds") + public R<Boolean> deleteByIds(@RequestBody List<String> ids) { + return R.ok(checkAcceptRecordService.removeByIds(ids)); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java index e0d70ff..c8a0d28 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java @@ -47,7 +47,9 @@ import java.io.IOException; import java.math.BigDecimal; import java.net.URLEncoder; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.*; /** @@ -72,6 +74,109 @@ private TBillService billService; @Autowired private TCheckAcceptRecordService checkAcceptRecordService; + @ApiOperation(value = "测试生成账单") + @PostMapping(value = "/testBill") + + public R testBill(String id) { + TContract contract = contractService.getById(id); + // 查询所有已签订的合同并且未生成第一笔账单的 + + List<TBill> bills = new ArrayList<>(); + List<TContractRentType> contractRentTypes = contractRentTypeService.list(); + contract.setFirstPayTime(contract.getStartTime().plusDays(10)); + // 第一次应缴费日期 + LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0); + TBill rentBill = new TBill(); + rentBill.setContractId(contract.getId()); + rentBill.setContractNumber(contract.getContractNumber()); + rentBill.setPayableFeesTime(firstPayTime); + rentBill.setPayFeesStatus("1"); + rentBill.setBillType("1"); + rentBill.setStartTime(contract.getStartPayTime()); + TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); + + if (tContractRentType!=null && contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(tContractRentType.getChangeTime())){ + // 计算租金变动的天数 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L; + contract.setChangeTime(LocalDateTime.now()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){ + long originalDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + }else{ + rentBill.setPayableFeesMoney(contractRentTypeMoney); + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + } + + if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ + rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); + }else{ + rentBill.setEndTime(contract.getEndTime()); + } + }else{ + if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ + rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); + }else{ + rentBill.setEndTime(contract.getEndTime()); + } + // 不走递增递减 + long allDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), rentBill.getEndTime()); + rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + + } + // 租金账单 + bills.add(rentBill); + // 押金账单 + TBill depositBill = new TBill(); + depositBill.setContractId(contract.getId()); + depositBill.setContractNumber(contract.getContractNumber()); + depositBill.setPayableFeesMoney(contract.getDeposit()); + depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney()); + + depositBill.setPayableFeesTime(firstPayTime); + depositBill.setPayFeesStatus("1"); + depositBill.setBillType("2"); + contractService.updateById(contract); + billService.save(rentBill); + billService.save(depositBill); + return R.ok(); + } @ApiOperation(value = "获取合同分页列表") @PostMapping(value = "/contractList") @PreAuthorize("@ss.hasPermi('system:contract:list')") @@ -84,6 +189,7 @@ @PostMapping(value = "/addContract") @PreAuthorize("@ss.hasPermi('system:contract:add')") public R<Boolean> addContract(@Validated @RequestBody TContractDTO dto) { + dto.setChangeRent(dto.getMonthRent()); contractService.save(dto); if (dto.getIsIncreasing()){ TContractRentType tContractRentType = new TContractRentType(); @@ -100,6 +206,8 @@ @Log(title = "合同管理-编辑合同", businessType = BusinessType.UPDATE) @ApiOperation(value = "编辑合同") @PostMapping(value = "/updateContract") + @PreAuthorize("@ss.hasPermi('system:contract:update')") + public R<Boolean> updateContract(@Validated @RequestBody TContractDTO dto) { contractService.updateById(dto); contractRentTypeService.remove(new LambdaQueryWrapper<TContractRentType>() @@ -118,6 +226,8 @@ } @Log(title = "合同管理-批量删除合同", businessType = BusinessType.DELETE) @ApiOperation(value = "批量删除合同") + @PreAuthorize("@ss.hasPermi('system:contract:delete')") + @DeleteMapping(value = "/deleteContractByIds") public R<Boolean> deleteContractByIds (@RequestParam String ids) { @@ -129,6 +239,8 @@ @ApiOperation(value = "查询合同信息信息") @GetMapping(value = "/getContractById") + @PreAuthorize("@ss.hasPermi('system:contract:detail')") + public R<TContractVO> getContractById(@RequestParam String id) { TContractVO res = new TContractVO(); TContract contract = contractService.getById(id); @@ -158,32 +270,50 @@ payMoney = payMoney.add(tBill.getPayFeesMoney()).add(tBill.getPayableFeesPenalty()); } TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery().eq(TCheckAcceptRecord::getContractId, id).one(); - res.setCheckResult(tCheckAcceptRecord.getCheckResult()); + res.setCheckResult(Objects.nonNull(tCheckAcceptRecord)?tCheckAcceptRecord.getCheckResult():false); res.setPayMoney(payMoney); return R.ok(res); } @Log(title = "合同管理-撤销审批", businessType = BusinessType.UPDATE) @ApiOperation(value = "撤销审批") + @PreAuthorize("@ss.hasPermi('system:contract:revoke')") + @GetMapping(value = "/updateContractStatus") public R<Boolean> updateContractStatus(String id) { TContract contract = contractService.getById(id); contract.setStatus("1"); + contractService.updateById(contract); + return R.ok(); + } + @PreAuthorize("@ss.hasPermi('system:contract:confirm')") + + @Log(title = "合同管理-确认结算", businessType = BusinessType.UPDATE) + @ApiOperation(value = "确认结算") + @PostMapping(value = "/confirmSettlement") + + public R<Boolean> confirmSettlement(String id) { + TContract contract = contractService.getById(id); + contract.setStatus("8"); + contractService.updateById(contract); return R.ok(); } @ApiOperation(value = "终止合同剩余未缴费账单列表") @PostMapping(value = "/contractBillList") + @PreAuthorize("@ss.hasPermi('system:contract:billList')") public R<PageInfo<BillVO>> contractBillList(@RequestBody TContractBillQuery query) { return R.ok(contractService.contractBillList(query)); } @ApiOperation(value = "终止合同") @PostMapping(value = "/terminateContract") + @PreAuthorize("@ss.hasPermi('system:contract:terminate')") public R terminateContract(@RequestBody TerminateContractDTO dto) { contractService.terminateContract(dto); return R.ok(); } @ApiOperation(value = "根据合同id查看验收记录") @GetMapping(value = "/getCheckByContractId") + @PreAuthorize("@ss.hasPermi('system:contract:checkDetail')") public R<CheckAcceptRecordVO> getCheckByContractId(String id) { return R.ok(contractService.getCheckByContractId(id)); } @@ -191,6 +321,8 @@ private WordUtil wordUtil; @ApiOperation(value = "生成合同附件") @PostMapping("/set") + @Log(title = "生成合同附件", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:contract:set')") public R<List<String>> set(@RequestBody SetContractDto dto,HttpServletResponse response){ List<TContract> list = contractService.lambdaQuery().in(TContract::getId, dto.getIds()).list(); List<String> res = new ArrayList<>(); @@ -228,6 +360,7 @@ * 导出 */ @ApiOperation(value = "导出") + @PreAuthorize("@ss.hasPermi('system:contract:export')") @Log(title = "导出", businessType = BusinessType.EXPORT) @PostMapping("/export") public void exportOpticalInspection(@RequestBody TContractQuery query) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java index 612ca22..928ee34 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultAreaDicController.java @@ -53,7 +53,6 @@ return R.ok(faultAreaDicService.pageList(query)); } - @PreAuthorize("@ss.hasPermi('system:faultArea:list')") @ApiOperation(value = "获取故障区域列表") @PostMapping(value = "/list") public R<List<TFaultAreaDic>> list() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java index 963d22b..b5148ff 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java @@ -1,9 +1,22 @@ package com.ruoyi.web.controller.api; -import org.springframework.web.bind.annotation.RequestMapping; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.system.model.TFaultRepairMessage; +import com.ruoyi.system.query.TFaultRepairMessageQuery; +import com.ruoyi.system.service.TFaultRepairMessageService; +import com.ruoyi.system.vo.TFaultRepairMessageVO; +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.*; -import org.springframework.web.bind.annotation.RestController; +import java.util.List; /** * <p> @@ -13,9 +26,72 @@ * @author xiaochen * @since 2025-01-17 */ +@Api(tags = "报修管理") @RestController @RequestMapping("/t-fault-repair-message") public class TFaultRepairMessageController { + private final TFaultRepairMessageService tFaultRepairMessageService; + + @Autowired + public TFaultRepairMessageController(TFaultRepairMessageService tFaultRepairMessageService) { + this.tFaultRepairMessageService = tFaultRepairMessageService; + } + + /** + * 获取报修管理列表 + */ + @PreAuthorize("@ss.hasPermi('system:fault:list')") + @ApiOperation(value = "获取报修分页列表") + @PostMapping(value = "/pageList") + public R<PageInfo<TFaultRepairMessageVO>> pageList(@RequestBody TFaultRepairMessageQuery query) { + return R.ok(tFaultRepairMessageService.pageList(query)); + } + + /** + * 处理维修 + */ + @PreAuthorize("@ss.hasPermi('system:fault:update')") + @Log(title = "报修信息-处理维修", businessType = BusinessType.UPDATE) + @ApiOperation(value = "处理维修") + @PostMapping(value = "/update") + public R<Boolean> update(@Validated @RequestBody TFaultRepairMessage faultRepairMessage) { + faultRepairMessage.setStatus(2); + return R.ok(tFaultRepairMessageService.updateById(faultRepairMessage)); + } + + /** + * 查看报修详情 + */ + @PreAuthorize("@ss.hasPermi('system:fault:detail')") + @ApiOperation(value = "查看报修详情") + @GetMapping(value = "/getDetailById") + public R<TFaultRepairMessageVO> getDetailById(@RequestParam String id) { + TFaultRepairMessageVO faultRepairMessageVO = tFaultRepairMessageService.getDetailById(id); + return R.ok(faultRepairMessageVO); + } + + /** + * 删除报修 + */ + @PreAuthorize("@ss.hasPermi('system:fault:delete')") + @Log(title = "报修信息-删除报修", businessType = BusinessType.DELETE) + @ApiOperation(value = "删除报修") + @DeleteMapping(value = "/deleteById") + public R<Boolean> deleteById(@RequestParam String id) { + return R.ok(tFaultRepairMessageService.removeById(id)); + } + + /** + * 批量删除报修 + */ + @PreAuthorize("@ss.hasPermi('system:fault:delete')") + @Log(title = "报修信息-删除报修", businessType = BusinessType.DELETE) + @ApiOperation(value = "批量删除报修") + @DeleteMapping(value = "/deleteByIds") + public R<Boolean> deleteByIds(@RequestBody List<String> ids) { + return R.ok(tFaultRepairMessageService.removeByIds(ids)); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TItemTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TItemTypeController.java index e35db1f..648c2e8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TItemTypeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TItemTypeController.java @@ -54,7 +54,6 @@ /** * 获取维修物品分类管理列表 */ - @PreAuthorize("@ss.hasPermi('system:itemType:list')") @ApiOperation(value = "获取维修物品分类列表") @PostMapping(value = "/list") public R<List<TItemType>> list() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java index d739523..8c232f4 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java @@ -54,7 +54,7 @@ //注入创建时间 if ("createTime".equals(field.getName())) { field.setAccessible(true); - field.set(parameter, LocalDateTime.now()); +// field.set(parameter, LocalDateTime.now()); field.setAccessible(false); } } catch (Exception e) { @@ -77,7 +77,7 @@ } if ("updateTime".equals(field.getName())) { field.setAccessible(true); - field.set(parameter, LocalDateTime.now()); +// field.set(parameter, new Date()); field.setAccessible(false); } } catch (Exception e) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index 3475998..27aea74 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -82,105 +82,6 @@ // } /** - * 人员借用列表 - */ -// @ApiOperation(value = "人员借用列表") -// @GetMapping("/userBorrowList") -// public AjaxResult userBorrowList(@RequestParam(required = false) String name, -// @RequestParam(required = false) Integer type) -// { -// -// UserAddListVO userAddListVO = new UserAddListVO(); -// -// Long companyId = tokenService.getLoginUser().getUser().getCompanyId(); -// -// List<TCompany> companyList = new ArrayList<>(); -// List<TDept> deptList = new ArrayList<>(); -// List<SysUser> userList = new ArrayList<>(); -// // 查询公司 -// if(Objects.nonNull(type) && type == 1){ -// companyList = companyService.userAddListByCompanyName(name); -// } -// // 查询部门 -// if(Objects.nonNull(type) && type == 2){ -// deptList = tDeptService.userAddListByDeptName(name); -// } -// // 查询用户 -// if(Objects.nonNull(type) && type == 3){ -// userList = userService.selectListByNamePhone(name); -// } -// -// if(Objects.isNull(type)){ -// companyList = companyService.userAddListByCompanyName(name); -// deptList = tDeptService.userAddListByDeptName(name); -// userList = userService.selectListByNamePhone(name); -// } -// -// List<Long> companyIds = companyList.stream().map(TCompany::getId).collect(Collectors.toList()); -// List<Long> deptCompanyIds = deptList.stream().map(TDept::getCompanyId).collect(Collectors.toList()); -// List<Long> userCompanyIds = userList.stream().map(SysUser::getCompanyId).collect(Collectors.toList()); -// companyIds.addAll(deptCompanyIds); -// companyIds.addAll(userCompanyIds); -// -// companyIds = companyIds.stream().distinct().collect(Collectors.toList()); -// -// if(CollectionUtils.isEmpty(companyIds)){ -// return AjaxResult.success(userAddListVO); -// } -// SysUser user1 = tokenService.getLoginUser().getUser(); -// if(!user1.isAdmin()){ -// companyIds = companyIds.stream().filter(e->!e.equals(companyId)).collect(Collectors.toList()); -// } -// -// // 查询符合要求的公司 -// List<UserLevelVO> parent = companyService.userAddListByCompanyIds(companyIds); -// -// List<TDept> depts = tDeptService.selectList(); -// -// List<SysUser> sysUsers = userService.selectList(); -// -// for (UserLevelVO userLevelVO : parent) { -// -// // 找到公司下的部门 -// List<TDept> tDepts = depts.stream().filter(e -> userLevelVO.getKey().equals(e.getCompanyId())).collect(Collectors.toList()); -// List<UserLevelVO> children = new ArrayList<>(); -// // 封装部门 -// for (TDept dept : tDepts) { -// userLevelVO.setChildren(children); -// UserLevelVO userLevelVO1 = new UserLevelVO(); -// userLevelVO1.setKey(dept.getId()); -// userLevelVO1.setTitle(dept.getDeptName()); -// // 找到部门下的人员 -// List<SysUser> users; -// if(StringUtils.isNotEmpty(name) && type == 3){ -// users = sysUsers.stream().filter(e -> userLevelVO1.getKey().equals(e.getDeptId()) -// && ((StringUtils.isNotEmpty(e.getNickName()) && e.getNickName().contains(name))) -// || (StringUtils.isNotEmpty(e.getPhonenumber()) && e.getPhonenumber().contains(name))).collect(Collectors.toList()); -// }else { -// users = sysUsers.stream().filter(e -> userLevelVO1.getKey().equals(e.getDeptId())).collect(Collectors.toList()); -// } -// List<UserLevelVO> children1 = new ArrayList<>(); -// // 封装人员 -// for (SysUser user : users) { -// UserLevelVO userLevelVO2 = new UserLevelVO(); -// userLevelVO2.setKey(user.getUserId()); -// userLevelVO2.setTitle(user.getNickName()); -// userLevelVO2.setAvatar(user.getAvatar()); -// userLevelVO2.setFlag(true); -// children1.add(userLevelVO2); -// } -// userLevelVO1.setChildren(children1); -// -// children.add(userLevelVO1); -// } -// userLevelVO.setChildren(children); -// } -// userAddListVO.setUserLevelVOS(parent); -// userAddListVO.setUserList(sysUsers); -// return AjaxResult.success(userAddListVO); -// } - - /** * 获取用户详情 */ @ApiOperation(value = "获取用户详情") @@ -245,37 +146,6 @@ return AjaxResult.success(); } - -// @Log(title = "用户管理", businessType = BusinessType.EXPORT) -//// // @PreAuthorize("@ss.hasPermi('system:user:export')") -// @PostMapping("/export") -// public void export(HttpServletResponse response, SysUser user) -// { -// List<SysUser> list = userService.selectUserList(user); -// ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); -// util.exportExcel(response, list, "用户数据"); -// } - -// @Log(title = "用户管理", businessType = BusinessType.IMPORT) -//// // @PreAuthorize("@ss.hasPermi('system:user:import')") -// @PostMapping("/importData") -// public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception -// { -// ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); -// List<SysUser> userList = util.importExcel(file.getInputStream()); -// String operName = getUsername(); -// String message = userService.importUser(userList, updateSupport, operName); -// return AjaxResult.success(message); -// } - -// @PostMapping("/importTemplate") -// public void importTemplate(HttpServletResponse response) -// { -// ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); -// util.importTemplateExcel(response, "用户数据"); -// } - - /** * 新增用户 */ @@ -295,7 +165,7 @@ return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); } user.setCreateBy(getUsername()); - user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setPassword(SecurityUtils.encryptPassword("123456")); userService.insertUser(user); return AjaxResult.success(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java index 05076e9..a878cdb 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java @@ -51,17 +51,16 @@ long hours = ChronoUnit.HOURS.between(payableFeesTime, now); long l = hours / 72; if (l>0){ - // 计算每天租金 - long days = ChronoUnit.DAYS.between(tBill.getStartTime(),tBill.getEndTime()); - BigDecimal everyDayMoney = tBill.getPayableFeesMoney().divide(new BigDecimal(days), 2, BigDecimal.ROUND_DOWN); // 违约金比例 BigDecimal proportion = contract.getProportion(); - // 预期x天后的违约金 - BigDecimal money = everyDayMoney.multiply(proportion).multiply(new BigDecimal(l)); - tBill.setPayableFeesPenalty(money); + // 应缴违约金 + BigDecimal money = tBill.getOutstandingMoney().multiply(proportion); + TBill changeBill = new TBill(); + changeBill.setId(tBill.getId()); + changeBill.setPayableFeesPenalty(money); + billService.lockAndUpdateInfo(changeBill,2); } } - billService.updateBatchById(list); } catch (Exception e) { e.printStackTrace(); @@ -69,497 +68,24 @@ } - // 每天凌晨00点执行的定时任务 用于合同生成第一笔账单 - @Scheduled(cron = "0 0 0 * * ?") - public void dayOfFirstBill() { - try { - // 查询所有已签订的合同并且未生成第一笔账单的 - List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4) - .isNull(TContract::getFirstPayTime).list(); - List<TBill> bills = new ArrayList<>(); - List<TContractRentType> contractRentTypes = contractRentTypeService.list(); - for (TContract contract : list) { - contract.setFirstPayTime(contract.getStartTime().plusDays(10)); - // 第一次应缴费日期 - LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0); - LocalDate localDate = contract.getStartTime().plusDays(10).toLocalDate(); - LocalDate now = LocalDate.now(); - // 如果应缴费日期和当前时间不相同 跳过 - if (!localDate.equals(now)) { - continue; - } - TBill rentBill = new TBill(); - rentBill.setContractId(contract.getId()); - rentBill.setContractNumber(contract.getContractNumber()); - LocalDateTime startPayTime = contract.getStartPayTime(); - LocalDateTime endTime1 = contract.getEndTime(); -// // 计算两个时间相差多少天 -// // 如果时间小于30天 需要计算每日租金 -// if (days<30){ -// rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); -// }else{ -// rentBill.setPayableFeesMoney(contract.getPayType().equals("1")?contract.getMonthRent(): -// contract.getPayType().equals("2")?contract.getMonthRent().multiply(new BigDecimal("3")):contract.getMonthRent().multiply(new BigDecimal("12")).setScale(2,BigDecimal.ROUND_DOWN)); -// } - rentBill.setPayableFeesTime(firstPayTime); - rentBill.setPayFeesStatus("1"); - rentBill.setBillType("1"); - rentBill.setStartTime(contract.getStartPayTime()); - TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); - if (tContractRentType!=null && contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(tContractRentType.getChangeTime())){ - // 计算租金变动的天数 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L; - contract.setChangeTime(LocalDateTime.now()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue()))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue()))); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ - rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); - }else{ - rentBill.setEndTime(contract.getEndTime()); - } - }else{ - if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ - rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); - }else{ - rentBill.setEndTime(contract.getEndTime()); - } - // 不走递增递减 - long allDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), rentBill.getEndTime()); - rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); - } - // 租金账单 - bills.add(rentBill); - // 押金账单 - TBill depositBill = new TBill(); - depositBill.setContractId(contract.getId()); - depositBill.setContractNumber(contract.getContractNumber()); - depositBill.setPayableFeesMoney(contract.getDeposit()); - depositBill.setPayableFeesTime(firstPayTime); - depositBill.setPayFeesStatus("1"); - depositBill.setBillType("2"); - bills.add(depositBill); - } - contractService.updateBatchById(list); - billService.saveBatch(bills); - } catch (Exception e) { - e.printStackTrace(); - } - } - - // 每天凌晨00点执行的定时任务 用于生成合同期最后一笔账单 + // 每天凌晨00点执行的定时任务 根据应缴费日期修改账单状态 @Scheduled(cron = "0 0 0 * * ?") public void dayOfEndBill() { try { - // 查询所有已签订的合同并且已经生成第一笔账单的 - List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4) - .ge(TContract::getEndTime,LocalDateTime.now()) - .isNotNull(TContract::getFirstPayTime).list(); - List<TContractRentType> contractRentTypes = contractRentTypeService.list(); - List<TBill> bills = new ArrayList<>(); - for (TContract contract : list) { - TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime) - .last("limit 1").one(); - if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) - && - (contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)) - .with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime()) - && beforeBill.getEndTime().isBefore(contract.getEndTime()) - ){ - TBill tBill = new TBill(); - tBill.setContractId(contract.getId()); - long days = ChronoUnit.DAYS.between((contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.firstDayOfMonth()), contract.getEndTime())+1L; - if (contract.getIsIncreasing()){ - TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); - if (tContractRentType!=null - && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) - && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ - // 如果没变过 - if (contract.getChangeTime()==null){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue()))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue()))); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - }else{ - // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 - if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue()))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue()))); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - }else{ - // 不涨租金 用上次的 - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))) ; - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent()).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent()).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - } - } - - } - }else{ - long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); - tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); - } - tBill.setContractNumber(contract.getContractNumber()); - if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){ - tBill.setPayableFeesTime(contract.getEndTime().withHour(0).withMinute(0).withSecond(0)); - }else{ - tBill.setPayableFeesTime((contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).withHour(0).withMinute(0).withSecond(0))); - } + List<TBill> list = billService.lambdaQuery().eq(TBill::getPayFeesStatus, "2").list(); + for (TBill tBill : list) { + if (tBill.getPayableFeesTime().toLocalDate().equals(LocalDate.now())){ tBill.setPayFeesStatus("1"); - tBill.setBillType("1"); - tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); - tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); - bills.add(tBill); } } - billService.saveBatch(bills); + billService.updateBatchById(list); } catch (Exception e) { e.printStackTrace(); } } - // 每月15号凌晨执行的定时任务 用于生成租金账单 - @Scheduled(cron = "0 0 0 15 * ?") - public void monthOfBill() { - try { - // 查询所有已签订的合同 - List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4) - .isNotNull(TContract::getFirstPayTime) - .ge(TContract::getEndTime, LocalDateTime.now()) - .list(); - List<TContractRentType> contractRentTypes = contractRentTypeService.list(); - List<TBill> bills = new ArrayList<>(); - for (TContract contract : list) { - TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime) - .last("limit 1").one(); - if (beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate()))continue; - if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime())){ - TBill tBill = new TBill(); - tBill.setContractId(contract.getId()); - tBill.setContractNumber(contract.getContractNumber()); - // 根据支付方式判断需不需要生成订单 - if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) - && - (contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)) - .with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime()) - && beforeBill.getEndTime().isBefore(contract.getEndTime()) - ){ - tBill.setContractId(contract.getId()); - long days = ChronoUnit.DAYS.between(beforeBill.getEndTime(), (contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.lastDayOfMonth()))+1L; - if (contract.getIsIncreasing()){ - TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); - if (tContractRentType!=null - && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) - && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ - // 如果没变过 - if (contract.getChangeTime()==null){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue()))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue()))); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - }else{ - // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 - if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).subtract(tContractRentType.getNumericalValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN)))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue()))); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue()))); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - }else{ - // 不涨租金 用上次的 - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))) ; - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(days))); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent()).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent()).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - } - } - - } - }else{ - long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), (contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.lastDayOfMonth())); - tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); - } - tBill.setContractNumber(contract.getContractNumber()); - if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){ - tBill.setPayableFeesTime(contract.getEndTime()); - }else{ - tBill.setPayableFeesTime((contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12))); - } - tBill.setPayFeesStatus("1"); - tBill.setBillType("1"); - tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); - tBill.setEndTime(contract.getEndTime()); - bills.add(tBill); - } - tBill.setPayableFeesMoney(contract.getMonthRent().multiply(new BigDecimal("3"))); - tBill.setPayableFeesTime(LocalDateTime.now().withHour(0).withMinute(0).withSecond(0)); - tBill.setPayFeesStatus("1"); - tBill.setBillType("1"); - tBill.setStartTime(beforeBill.getEndTime().plusMonths(1).with(TemporalAdjusters.firstDayOfMonth())); - tBill.setEndTime(beforeBill.getEndTime().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth())); - bills.add(tBill); - } - } - billService.saveBatch(bills); - } catch (Exception e) { - e.printStackTrace(); - } - } public static void main(String[] args) { diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml index 4ca4b21..93fd2c2 100644 --- a/ruoyi-admin/src/main/resources/application-test.yml +++ b/ruoyi-admin/src/main/resources/application-test.yml @@ -193,9 +193,9 @@ accessPath: /file/ allowExt: .jpg|.png|.gif|.jpeg|.doc|.docx|.apk|.MP4|.mp4|.pdf|.PDF wx: - config: - appId: wxc3985a05da7d86dc - secret: 5cca42633c25439613b328c08ef20cc9 + conf: + appId: wxe91f1af7638aa5dd + secretId: a787e1a462715604e0c9528b6d8960d1 #OSS及短信配置 code: config: diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/COSController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/COSController.java new file mode 100644 index 0000000..3d7d593 --- /dev/null +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/COSController.java @@ -0,0 +1,55 @@ +package com.ruoyi.web.controller.api; + +import com.ruoyi.common.core.domain.R; +import com.ruoyi.web.controller.tool.TencentCosUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-30 9:27 + */ +@RestController +@RequestMapping("/cos") +@Api(tags = "公共-文件上传") +public class COSController { + + @Resource + private TencentCosUtil tencentCosUtil; + + @PostMapping("/upload") + @ApiOperation(value = "文件上传", tags = "公共-文件上传") + @ApiImplicitParams({ + @ApiImplicitParam(value = "文件", name = "file", dataType = "MultipartFile", required = true) + }) + public R<String> upload(@RequestParam("file") MultipartFile file) { + String url = tencentCosUtil.upLoadFile(file); + return R.ok(url, url); + } + @PostMapping("/downloadImg") + @ApiOperation(value = "文件下载", tags = "公共-文件下载") + @ApiImplicitParams({ + @ApiImplicitParam(value = "文件url", name = "url", dataType = "String", required = true) + }) + public String downloadImg(@RequestParam("url") String url) { + return tencentCosUtil.downLoadFileImg(url); + } + @PostMapping("/download") + @ApiOperation(value = "文件下载", tags = "公共-文件下载") + @ApiImplicitParams({ + @ApiImplicitParam(value = "文件url", name = "url", dataType = "String", required = true) + }) + public void download(@RequestParam("url") String url) { + tencentCosUtil.downLoadFile(url); + } +} diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java index 98558e2..c90ea72 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java @@ -55,9 +55,8 @@ @ApiOperation(value = "缴费账单查询分页列表") @PostMapping("list") public R<PageInfo<TBillDto>> list(@RequestBody TBillQuery query){ - if (StringUtils.isEmpty(query.getUserId())){ - throw new ServiceException("用户ID不能为空"); - } + String userId = tokenService.getLoginUserApplet().getUserId(); + query.setUserId(userId); PageInfo<TBillDto> pageInfo = tBillService.queryPage(query); return R.ok(pageInfo); } @@ -65,9 +64,8 @@ @ApiOperation(value = "缴费账单查询列表") @PostMapping("/getBillIds") public R<List<String>> getBillIds(@RequestBody TBillQuery query){ - if (StringUtils.isEmpty(query.getUserId())){ - throw new ServiceException("用户ID不能为空"); - } + String userId = tokenService.getLoginUserApplet().getUserId(); + query.setUserId(userId); List<String> billIds = tBillService.getBillIds(query); return R.ok(billIds); } @@ -90,9 +88,14 @@ billVO.setHouse(houseService.getById(contract.getHouseId())); billVO.setMonthRent(contract.getMonthRent()); billVO.setPayType(contract.getPayType()); + billVO.setDeposit(contract.getDeposit()); + billVO.setPartyOnePerson(contract.getPartyOnePerson()); + billVO.setPartyOnePhone(contract.getPartyOnePhone()); + billVO.setConcatStartTime(contract.getStartTime()); + billVO.setConcatEndTime(contract.getEndTime()); }); billVO.setBillType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BILL_TYPE,billVO.getBillType())); - billVO.setPayFeesStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_PAY_FEES_STATUS,billVO.getPayFeesStatus())); +// billVO.setPayFeesStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_PAY_FEES_STATUS,billVO.getPayFeesStatus())); return R.ok(billVO); } @@ -119,8 +122,7 @@ @PostMapping(value = "/invoiceList") public R<PageInfo<TBillDto>> invoiceList(@RequestBody TBillQuery query) { -// Long userId = tokenService.getLoginUser().getUserId(); - String userId = "1881967035070177281"; + String userId = tokenService.getLoginUserApplet().getUserId(); query.setUserId(userId); PageInfo<TBillDto> pageInfo = tBillService.invoiceList(query); return R.ok(pageInfo); diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java index 963d22b..9ea04c2 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java @@ -1,9 +1,26 @@ package com.ruoyi.web.controller.api; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.dto.TFaultRepairMessageDTO; +import com.ruoyi.system.model.*; +import com.ruoyi.system.service.*; +import com.ruoyi.system.vo.TFaultAreaDicVO; +import com.ruoyi.system.vo.TItemTypeVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; +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 java.util.List; +import java.util.stream.Collectors; /** * <p> @@ -13,9 +30,94 @@ * @author xiaochen * @since 2025-01-17 */ +@Api(tags = "报修管理") @RestController @RequestMapping("/t-fault-repair-message") public class TFaultRepairMessageController { + private final TFaultRepairMessageService tFaultRepairMessageService; + private final TItemService itemService; + private final TItemTypeService itemTypeService; + private final TFaultAreaDicService faultAreaDicService; + private final TFaultDescribeDicService faultDescribeDicService; + private final TokenService tokenService; + private final TContractService contractService; + private final THouseService houseService; + + @Autowired + public TFaultRepairMessageController(TFaultRepairMessageService tFaultRepairMessageService, TItemService itemService, TItemTypeService itemTypeService, TFaultAreaDicService faultAreaDicService, TFaultDescribeDicService faultDescribeDicService, TokenService tokenService, TContractService contractService, THouseService houseService) { + this.tFaultRepairMessageService = tFaultRepairMessageService; + this.itemService = itemService; + this.itemTypeService = itemTypeService; + this.faultAreaDicService = faultAreaDicService; + this.faultDescribeDicService = faultDescribeDicService; + this.tokenService = tokenService; + this.contractService = contractService; + this.houseService = houseService; + } + + /** + * 获取维修物品二级结构 + */ + @ApiOperation(value = "获取维修物品二级结构") + @PostMapping(value = "/getItemList") + public R<List<TItemTypeVO>> getItemList() { + List<TItemTypeVO> itemTypes = itemTypeService.getItemList(); + List<TItem> items = itemService.list(); + itemTypes.forEach(itemType -> { + itemType.setItemList(items.stream().filter(item -> itemType.getId().equals(item.getTypeId())).collect(Collectors.toList())); + }); + return R.ok(itemTypes); + } + + /** + * 获取故障区域列表 + */ + @ApiOperation(value = "获取故障区域二级结构") + @PostMapping(value = "/getAreaDicList") + public R<List<TFaultAreaDicVO>> getAreaDicList() { + List<TFaultAreaDicVO> faultAreaDicVOS = faultAreaDicService.getAreaDicList(); + List<TFaultDescribeDic> faultDescribeDicList = faultDescribeDicService.list(); + faultAreaDicVOS.forEach(areaDicVO -> { + areaDicVO.setFaultDescribeDicList(faultDescribeDicList.stream().filter(item -> areaDicVO.getId().equals(item.getFaultId())).collect(Collectors.toList())); + }); + return R.ok(faultAreaDicVOS); + } + + /** + * 通过当前租户查询合同房源信息 + */ + @ApiOperation(value = "通过当前租户查询合同房源信息") + @PostMapping(value = "/getConcatByTenantId") + public R<List<TContract>> getConcatByTenantId() { + +// Long userId = tokenService.getLoginUser().getUserId(); + String tenantId = "1881967035070177281"; + // 查询合同信息 + List<TContract> list = contractService.list(Wrappers.lambdaQuery(TContract.class) + .eq(TContract::getTenantId, tenantId) + .eq(TContract::getStatus, 4)); + if(CollectionUtils.isEmpty(list)){ + return R.ok(list); + } + List<String> houseIds = list.stream().map(TContract::getHouseId).collect(Collectors.toList()); + List<THouse> houseList = houseService.list(Wrappers.lambdaQuery(THouse.class) + .in(THouse::getId, houseIds)); + list.forEach(item -> { + item.setHouseName(houseList.stream().filter(house -> house.getId().equals(item.getHouseId())).findFirst().orElse(new THouse()).getHouseName()); + }); + return R.ok(list); + } + + /** + * 添加报修信息 + */ + @ApiOperation(value = "添加报修信息") + @PostMapping(value = "/addFault") + public R<String> addFault(@RequestBody TFaultRepairMessageDTO dto) { + tFaultRepairMessageService.save(dto); + return R.ok(); + } + } diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java index dd18571..a46014a 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java @@ -2,19 +2,16 @@ import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.system.model.TInformation; import com.ruoyi.system.query.TInformationQuery; import com.ruoyi.system.service.TInformationService; 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.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.*; /** * <p> @@ -30,9 +27,11 @@ public class TInformationController { private final TInformationService informationService; + private final RedisCache redisCache; @Autowired - public TInformationController(TInformationService informationService) { + public TInformationController(TInformationService informationService, RedisCache redisCache) { this.informationService = informationService; + this.redisCache = redisCache; } /** @@ -44,5 +43,16 @@ return R.ok(informationService.pageList(query)); } + /** + * 获取资讯管理详情 + */ + @ApiOperation(value = "获取资讯管理详情") + @GetMapping(value = "/getDetailById") + public R<TInformation> getDetailById(@RequestParam String id) { + // 处理查看次数 + redisCache.increment(Constants.INFORMATION_VIEW + id); + return R.ok(informationService.getById(id)); + } + } diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/WxLoginController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/WxLoginController.java new file mode 100644 index 0000000..c784c42 --- /dev/null +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/WxLoginController.java @@ -0,0 +1,255 @@ +package com.ruoyi.web.controller.api; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.R; + +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.TTenantResp; +import com.ruoyi.common.core.domain.model.LoginBody; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.LoginUserApplet; +import com.ruoyi.common.core.utils.HttpUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.framework.web.service.SysLoginService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.model.TTenant; +import com.ruoyi.system.service.TTenantService; +import com.ruoyi.system.utils.wx.body.resp.Code2SessionRespBody; +import com.ruoyi.system.utils.wx.body.resq.Code2SessionResqBody; +import com.ruoyi.system.utils.wx.model.WeixinProperties; +import com.ruoyi.system.utils.wx.pojo.AppletUserDecodeData; +import com.ruoyi.system.utils.wx.pojo.AppletUserEncrypteData; +import com.ruoyi.system.utils.wx.tools.WxAppletTools; +import com.ruoyi.system.utils.wx.tools.WxUtils; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * <p> + * 微信小程序登录 前端控制器 + * </p> + * + * @author xiaochen + * @since 2024-08-06 + */ +@Slf4j +@RestController +@RequestMapping("/wxLogin") +public class WxLoginController { + + @Autowired + private WeixinProperties wxConfig; + @Autowired + private RestTemplate wxRestTemplate; + @Resource + private RedisService redisService; + @Resource + private TTenantService tTenantService; + + /** + * 上传文件存储在本地的根路径 + */ +// @Value("${file.upload.location}") +// private String localFilePath; + + @Resource + private TokenService tokenService; + @Autowired + private SysLoginService loginService; + /** + * 账号密码登录 + * + * @param loginBody 登录信息 + * @return 结果 + */ + @ApiOperation(value = "账号密码登录",notes = "管理员账号密码登录") + @PostMapping("/login") + public AjaxResult login(@RequestBody LoginBody loginBody) + { + AjaxResult ajax = AjaxResult.success(); + // 生成令牌 + LoginUser loginUser = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), + loginBody.getUuid()); + ajax.put(Constants.TOKEN, tokenService.createToken(loginUser)); + List<SysRole> roles = loginUser.getUser().getRoles(); + if(CollectionUtils.isEmpty(roles)){ + return AjaxResult.error("请关联角色!"); + } + if(roles.get(0).getStatus() == 1){ + return AjaxResult.error("该账号角色已被禁用!"); + } + return ajax; + } + + @ApiOperation(value = "通过code获得openid,获取用户信息",tags = {"微信小程序登录"}) + @PostMapping("/openIdByJsCode") + public R<Map<String, Object>> openIdByJsCode(@RequestBody AppletUserEncrypteData data) { + log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", data.getCode()); + WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); + Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(data.getCode())); + String openid = body.getOpenid(); + String sessionKey = body.getSessionKey(); + // 用户信息解密 数据验签 +// if (StringUtils.isNotBlank(data.getSignature())) { +// WxUtils.verifySignature(data.getRawData(), sessionKey, data.getSignature()); +// } + if(StringUtils.isEmpty(data.getEncryptedData()) || StringUtils.isEmpty(data.getIv())){ + return R.fail("已拒绝授权"); + } + AppletUserDecodeData appletUserDecodeData = WxUtils.encryptedData(data.getEncryptedData(), sessionKey, data.getIv()); + appletUserDecodeData.setOpenId(openid); + // 先使用openId和当前手机号进行查询 + TTenant tenant = tTenantService.getOne(Wrappers.lambdaQuery(TTenant.class) + .eq(TTenant::getOpenId, appletUserDecodeData.getOpenId()) + .eq(TTenant::getPhone, appletUserDecodeData.getPhoneNumber())); + if (tenant==null){ +// appUser.setTenantAttributes(); +// appUser.setTenantType(); + tenant = new TTenant(); + tenant.setPhone(appletUserDecodeData.getPhoneNumber()); + tenant.setAccount(appletUserDecodeData.getPhoneNumber()); + tenant.setPassword(SecurityUtils.encryptPassword(appletUserDecodeData.getPhoneNumber().substring(5))); + tenant.setOpenId(appletUserDecodeData.getOpenId()); + // 手机号中间四位替换为* + tenant.setResidentName(appletUserDecodeData.getPhoneNumber().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")); + tTenantService.save(tenant); + } + LoginUserApplet loginUserApplet = new LoginUserApplet(); + TTenantResp tTenantResp = new TTenantResp(); + BeanUtils.copyProperties(tenant, tTenantResp); + loginUserApplet.setUser(tTenantResp); + loginUserApplet.setUserId(tenant.getId()); + Map<String, Object> tokenInfos = new HashMap<>(); + tokenInfos.put("token",tokenService.createTokenApplet(loginUserApplet)); + tokenInfos.put("info",loginUserApplet); + return R.ok(tokenInfos); + } + + + + + +// @ApiOperation(value = "获取微信小程序二维码",tags = {"获取微信小程序二维码"}) +// @PostMapping("/getQRCode") +// public AjaxResult getQRCode() { +// InputStream inputStream = null; +// OutputStream outputStream = null; +// WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); +// String accessToken = appletTools.getAccessToken(""); +// try { +// String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken; +// Map<String, Object> param = new HashMap<>(); +//// param.put("page", "pageA/houseDetail"); +// param.put("check_path", false); +// param.put("env_version", "trial"); +// param.put("width", 200); //二维码尺寸 +// param.put("is_hyaline", true); // 是否需要透明底色, is_hyaline 为true时,生成透明底色的小程序码 参数仅对小程序码生效 +// param.put("auto_color", true); // 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 参数仅对小程序码生效 +// Map<String, Object> line_color = new HashMap<>(); +// line_color.put("r", 0); +// line_color.put("g", 0); +// line_color.put("b", 0); +// param.put("line_color", line_color); +// System.err.println("调用生成微信URL接口传参:" + param); +// MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); +// HttpEntity requestEntity = new HttpEntity(param, headers); +// ResponseEntity<byte[]> entity = wxRestTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]); +// System.err.println("调用小程序生成微信永久小程序码URL接口返回结果:" + entity.getBody()); +// byte[] result = entity.getBody(); +// System.err.println(Base64.encodeBase64String(result)); +// inputStream = new ByteArrayInputStream(result); +// String finalFileName = System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + ".jpeg"; +//// MultipartFile multipartFile = convertInputStreamToMultipartFile(inputStream, finalFileName, "image/jpeg"); +//// String name = FileUploadUtils.upload(localFilePath, multipartFile); +//// System.err.println(name); +// return AjaxResult.success(null); +// } catch (Exception e) { +// System.err.println("调用小程序生成微信永久小程序码URL接口异常" + e); +// } finally { +// if (inputStream != null) { +// try { +// inputStream.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// if (outputStream != null) { +// try { +// outputStream.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// } +// return AjaxResult.success(); +// } + + + /** + * 获取微信token + * @return + */ + @PostMapping("/getWXToken") + public R<String> getWXToken(){ + WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); + String accessToken = appletTools.getAccessToken(""); + return R.ok(accessToken); + } + + + /** + * 敏感词检测 + * @param content + * @param openid + * @return + */ + @PostMapping("/sensitiveWordDetection") + public R<Boolean> sensitiveWordDetection (@RequestParam("content") String content, @RequestParam("openid") String openid){ + WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); + String accessToken = appletTools.getAccessToken(""); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("content", content); + jsonObject.put("version", 2); + jsonObject.put("scene", 2); + jsonObject.put("openid", openid); + String post = HttpUtils.post("https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken, jsonObject.toString()); + JSONObject object = JSONObject.parseObject(post); + Integer errcode = object.getInteger("errcode"); + if(0 != errcode){ + throw new RuntimeException(object.getString("errmsg")); + } + JSONArray detail = object.getJSONArray("detail"); + for (int i = 0; i < detail.size(); i++) { + JSONObject jsonObject1 = detail.getJSONObject(i); + Integer errcode1 = jsonObject1.getInteger("errcode"); + if(0 == errcode1){ + String suggest = jsonObject1.getString("suggest"); + Integer label = jsonObject1.getInteger("label"); + String keyword = jsonObject1.getString("keyword"); + Integer prob = jsonObject1.getInteger("prob"); + if(("risky".equals(suggest) || "review".equals(suggest)) && 100 != label && com.ruoyi.common.utils.StringUtils.isNotEmpty(keyword) && 80 <= prob){ + return R.ok(true); + } + } + } + return R.ok(false); + } +} diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java index ae4b66e..57a4ff0 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/interceptor/MybatisInterceptor.java @@ -56,7 +56,7 @@ //注入创建时间 if ("createTime".equals(field.getName())) { field.setAccessible(true); - field.set(parameter, new Date()); +// field.set(parameter, new Date()); field.setAccessible(false); } } catch (Exception e) { @@ -79,7 +79,7 @@ } if ("updateTime".equals(field.getName())) { field.setAccessible(true); - field.set(parameter, new Date()); +// field.set(parameter, new Date()); field.setAccessible(false); } } catch (Exception e) { diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java new file mode 100644 index 0000000..f86298b --- /dev/null +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java @@ -0,0 +1,187 @@ +package com.ruoyi.web.controller.tool; + +import com.qcloud.cos.COSClient; +import com.qcloud.cos.ClientConfig; +import com.qcloud.cos.auth.BasicCOSCredentials; +import com.qcloud.cos.auth.COSCredentials; +import com.qcloud.cos.http.HttpProtocol; +import com.qcloud.cos.model.ObjectMetadata; +import com.qcloud.cos.model.PutObjectResult; +import com.qcloud.cos.region.Region; +import com.ruoyi.common.utils.WebUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Base64; +import java.util.UUID; + +/** + * @author HJL + */ +@Component +public class TencentCosUtil { + + /** + * COS的SecretId + */ + @Value("${cos.client.accessKey}") + private String secretId; + /** + * COS的SecretKey + */ + @Value("${cos.client.secretKey}") + private String secretKey; + /** + * 文件上传后访问路径的根路径,后面要最佳文件名字与类型 + */ + @Value("${cos.client.rootSrc}") + private String rootSrc; + /** + * 上传的存储桶的地域 + */ + @Value("${cos.client.bucketAddr}") + private String bucketAddr; + /** + * 存储桶的名字,是自己在存储空间自己创建的,我创建的名字是:qq-test-1303****** + */ + @Value("${cos.client.bucket}") + private String bucketName; + /** + * 文件存放位置 + */ + @Value("${cos.client.location}") + private String location; + + /** + * 1.调用静态方法getCosClient()就会获得COSClient实例 + * 2.本方法根据永久密钥初始化 COSClient的,官方是不推荐,官方推荐使用临时密钥,是可以限制密钥使用权限,创建cred时有些区别 + * + * @return COSClient实例 + */ + private COSClient getCosClient() { + // 1 初始化用户身份信息(secretId, secretKey)。 + COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); + // 2.1 设置存储桶的地域(上文获得) + Region region = new Region(bucketAddr); + ClientConfig clientConfig = new ClientConfig(region); + // 2.2 使用https协议传输 + clientConfig.setHttpProtocol(HttpProtocol.https); + // 生成 cos 客户端 + return new COSClient(cred, clientConfig); + } + + /** + * 只要调用静态方法upLoadFile(MultipartFile multipartFile)就可以获取上传后文件的全路径 + * + * @param file + * @return 返回文件的浏览全路径 + */ + public String upLoadFile(MultipartFile file) { + try { + // 获取上传的文件的输入流 + InputStream inputStream = file.getInputStream(); + // 避免文件覆盖,获取文件的原始名称,如123.jpg,然后通过截取获得文件的后缀,也就是文件的类型 + String originalFilename = file.getOriginalFilename(); + //获取文件的类型 + String fileType = originalFilename.substring(originalFilename.lastIndexOf(".")); + //使用UUID工具 创建唯一名称,放置文件重名被覆盖,在拼接上上命令获取的文件类型 + String fileName = UUID.randomUUID() + fileType; + // 指定文件上传到 COS 上的路径,即对象键。最终文件会传到存储桶名字中的images文件夹下的fileName名字 + String key = location+"/" + fileName; + // 创建上传Object的Metadata + ObjectMetadata objectMetadata = new ObjectMetadata(); + // - 使用输入流存储,需要设置请求长度 + objectMetadata.setContentLength(inputStream.available()); + // - 设置缓存 + objectMetadata.setCacheControl("no-cache"); + // - 设置Content-Type + objectMetadata.setContentType(fileType); + //上传文件 + PutObjectResult putResult = getCosClient().putObject(bucketName, key, inputStream, objectMetadata); + // 创建文件的网络访问路径 + String url = rootSrc + key; + //关闭 cosClient,并释放 HTTP 连接的后台管理线程 + getCosClient().shutdown(); + return url; + } catch (Exception e) { + e.printStackTrace(); + // 发生IO异常、COS连接异常等,返回空 + return null; + } + } + + /** + * 下载文件 + * @param file + * @return + */ + public void downLoadFile(String file) { + HttpServletResponse response = WebUtils.response(); + String replace = file.replace(rootSrc, ""); + response.setHeader("Access-Control-Expose-Headers","File-Type"); + COSCredentials cred = new BasicCOSCredentials( + secretId, + secretKey); + // 2.1 设置存储桶的地域(上文获得) + Region region = new Region(bucketAddr); + ClientConfig clientConfig = new ClientConfig(region); + // 2.2 使用https协议传输 + clientConfig.setHttpProtocol(HttpProtocol.https); + COSClient cosClient = new COSClient(cred, clientConfig); + try { + // 5. 下载文件并获取输入流 + InputStream inputStream = cosClient.getObject(bucketName, replace).getObjectContent(); + ServletOutputStream outputStream = response.getOutputStream(); + // 6. 处理输入流,例如读取内容或保存到本地文件 + // 这里仅作示例,实际应用中需要根据需求处理输入流 + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) != -1) { + // 处理读取到的数据 + outputStream.write(buffer, 0, len); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + // 7. 关闭输入流 + cosClient.shutdown(); + } + } + public String downLoadFileImg(String file) { + byte[] data = null; + String replace = file.replace(rootSrc, ""); + COSCredentials cred = new BasicCOSCredentials( + secretId, + secretKey); + // 2.1 设置存储桶的地域(上文获得) + Region region = new Region(bucketAddr); + ClientConfig clientConfig = new ClientConfig(region); + // 2.2 使用https协议传输 + clientConfig.setHttpProtocol(HttpProtocol.https); + COSClient cosClient = new COSClient(cred, clientConfig); + try { + // 5. 下载文件并获取输入流 + InputStream inputStream = cosClient.getObject(bucketName, replace).getObjectContent(); + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + // 6. 处理输入流,例如读取内容或保存到本地文件 + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) != -1) { + // 处理读取到的数据 + swapStream.write(buffer, 0, len); + } + data = swapStream.toByteArray(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + // 7. 关闭输入流 + cosClient.shutdown(); + } + return Base64.getEncoder().encodeToString(data); + } +} \ No newline at end of file diff --git a/ruoyi-applet/src/main/resources/application-prod.yml b/ruoyi-applet/src/main/resources/application-prod.yml index 47a6c8f..b652f22 100644 --- a/ruoyi-applet/src/main/resources/application-prod.yml +++ b/ruoyi-applet/src/main/resources/application-prod.yml @@ -206,3 +206,11 @@ accessKeySecret: 0SRb6XGkciQDPWn2rYqbJtq2qRMDY8 signName: "四川金达通信工程" templateCode: "SMS_293985284" +cos: + client: + accessKey: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x + secretKey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU + bucket: xzgttest-1305134071 + bucketAddr: ap-chengdu + rootSrc: https://xzgttest-1305134071.cos.ap-chengdu.myqcloud.com/ + location: xizang diff --git a/ruoyi-applet/src/main/resources/application-test.yml b/ruoyi-applet/src/main/resources/application-test.yml index 355f277..a0e94e7 100644 --- a/ruoyi-applet/src/main/resources/application-test.yml +++ b/ruoyi-applet/src/main/resources/application-test.yml @@ -193,9 +193,9 @@ accessPath: /file/ allowExt: .jpg|.png|.gif|.jpeg|.doc|.docx|.apk|.MP4|.mp4|.pdf|.PDF wx: - config: - appId: wxc3985a05da7d86dc - secret: 5cca42633c25439613b328c08ef20cc9 + conf: + appId: wxe91f1af7638aa5dd + secretId: a787e1a462715604e0c9528b6d8960d1 #OSS及短信配置 code: config: @@ -205,3 +205,11 @@ accessKeySecret: 0SRb6XGkciQDPWn2rYqbJtq2qRMDY8 signName: "四川金达通信工程" templateCode: "SMS_293985284" +cos: + client: + accessKey: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x + secretKey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU + bucket: xzgttest-1305134071 + bucketAddr: ap-chengdu + rootSrc: https://xzgttest-1305134071.cos.ap-chengdu.myqcloud.com/ + location: xizang diff --git a/ruoyi-applet/src/main/resources/mybatis-config.xml b/ruoyi-applet/src/main/resources/mybatis-config.xml index 7d487eb..53c5587 100644 --- a/ruoyi-applet/src/main/resources/mybatis-config.xml +++ b/ruoyi-applet/src/main/resources/mybatis-config.xml @@ -10,7 +10,7 @@ <setting name="cacheEnabled" value="true"/> <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false --> <!-- <setting name="lazyLoadingEnabled" value="true"/> --> - <setting name="mapUnderscoreToCamelCase" value="false"/><!--是否将map下划线方式转为驼峰式命名--> + <setting name="mapUnderscoreToCamelCase" value="true"/><!--是否将map下划线方式转为驼峰式命名--> <!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖--> <!-- <setting name="aggressiveLazyLoading" value="false"/>--> <!-- Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST --> diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index c075328..82b912c 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -83,6 +83,10 @@ * 令牌前缀 */ public static final String LOGIN_USER_KEY = "login_user_key"; + /** + * 小程序 + */ + public static final String LOGIN_USER_APPLET_KEY = "login_user_applet_key"; /** * 用户ID @@ -128,6 +132,10 @@ * LDAPS 远程方法调用 */ public static final String LOOKUP_LDAPS = "ldaps:"; + /** + * LDAPS 远程方法调用 + */ + public static final String INFORMATION_VIEW = "information_view:"; /** * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java index 19a3caf..35fdf8f 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java @@ -43,4 +43,8 @@ * 账单类型 1=租金 2=押金 3=生活费用 */ public static final String DICT_TYPE_BILL_TYPE = "t_bill_type"; + /** + * 验收记录情况 1=良好 2=一般 3=较差 + */ + public static final String DICT_TYPE_CHECK_SITUATION = "t_check_situation"; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java index 21ff250..9a6eea2 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java @@ -125,8 +125,11 @@ @TableField(exist = false) private String roleName; - + @TableField(exist = false) private String deptName; + @ApiModelProperty(value = "部门id集合") + @TableField(exist = false) + private List<String> deptIds; public String getRoleName() { return roleName; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TTenantResp.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TTenantResp.java new file mode 100644 index 0000000..33b6fec --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/TTenantResp.java @@ -0,0 +1,70 @@ +package com.ruoyi.common.core.domain.entity; + +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.common.core.domain.BaseModel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDate; + +/** + * <p> + * 租户 + * </p> + * + * @author xiaochen + * @since 2025-01-20 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="TTenant对象", description="登录返回") +public class TTenantResp { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + @ApiModelProperty(value = "住户名称") + private String residentName; + + @ApiModelProperty(value = "入住时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private LocalDate checkinTime; + + @ApiModelProperty(value = "租户属性") + private String tenantAttributes; + + @ApiModelProperty(value = "租户类型") + private String tenantType; + + @ApiModelProperty(value = "联系电话") + private String phone; + + @ApiModelProperty(value = "证件号码") + private String idCard; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "银行转账专号") + private String bankNumber; + + @ApiModelProperty(value = "通讯地址") + private String mailAddress; + + @ApiModelProperty(value = "登录账号") + private String account; + + @ApiModelProperty(value = "登录密码") + private String password; + @ApiModelProperty(value = "微信openid") + private String openId; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUserApplet.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUserApplet.java new file mode 100644 index 0000000..186be08 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUserApplet.java @@ -0,0 +1,263 @@ +package com.ruoyi.common.core.domain.model; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.entity.TTenantResp; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.Set; + +/** + * 登录用户身份权限 + * + * @author ruoyi + */ +@Data +public class LoginUserApplet implements UserDetails +{ + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private String userId; + + /** + * 部门ID + */ + private Long deptId; + + /** + * 用户唯一标识 + */ + private String token; + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + /** + * 登录地点 + */ + private String loginLocation; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + + /** + * 权限列表 + */ + private Set<String> permissions; + + /** + * 用户信息 + */ + private TTenantResp user; + + + public LoginUserApplet() + { + } + + public LoginUserApplet(TTenantResp user, Set<String> permissions) + { + this.user = user; + this.permissions = permissions; + } + + public LoginUserApplet(String userId, Long deptId, TTenantResp user, Set<String> permissions) + { + this.userId = userId; + this.deptId = deptId; + this.user = user; + this.permissions = permissions; + } + + public String getUserId() + { + return userId; + } + + public void setUserId(String userId) + { + this.userId = userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + @JSONField(serialize = false) + @Override + public String getPassword() + { + return user.getPassword(); + } + + @Override + public String getUsername() + { + return user.getResidentName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @JSONField(serialize = false) + @Override + public boolean isEnabled() + { + return true; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public Set<String> getPermissions() + { + return permissions; + } + + public void setPermissions(Set<String> permissions) + { + this.permissions = permissions; + } + + + + @Override + public Collection<? extends GrantedAuthority> getAuthorities() + { + return null; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/exception/ServiceException.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/exception/ServiceException.java new file mode 100644 index 0000000..4983866 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/exception/ServiceException.java @@ -0,0 +1,74 @@ +package com.ruoyi.common.core.exception; + +/** + * 业务异常 + * + * @author ruoyi + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + * 和 {@link CommonResult#getDetailMessage()} 一致的设计 + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java index f405893..96864ac 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java @@ -330,4 +330,14 @@ Long result = (Long) redisTemplate.execute(UNLOCK_SCRIPT, Collections.singletonList(lockKeyWithPrefix), requestId); return result != null && result == 1L; } + + /** + * 自增 + * @param key 要加一的键 + */ + public int increment(String key) { + // +1 操作 + return redisTemplate.opsForValue().increment(key).intValue(); + } + } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/utils/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/utils/Constants.java new file mode 100644 index 0000000..8144c3a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/utils/Constants.java @@ -0,0 +1,143 @@ +package com.ruoyi.common.core.utils; + +/** + * 通用常量信息 + * + * @author ruoyi + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 成功标记 + */ + public static final Integer SUCCESS = 200; + + /** + * 失败标记 + */ + public static final Integer FAIL = 500; + + /** + * 登录成功状态 + */ + public static final String LOGIN_SUCCESS_STATUS = "1"; + + /** + * 登录失败状态 + */ + public static final String LOGIN_FAIL_STATUS = "2"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 验证码有效期(分钟) + */ + public static final long CAPTCHA_EXPIRATION = 2; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" }; + + /** + * 时间格式化 + */ + public static final String DATE_FORMATTER_TIME = "yyyy-MM-dd HH:mm:ss"; + public static final String DATE_FORMATTER_DATE = "yyyy-MM-dd"; + /** + * 修改手机号后缀 + */ + public static final String UPDATE_PHONE = "_updatePhone"; + /** + * 申请建桩后缀 + */ + public static final String APPLY_CHARGING = "_applyCharging"; + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.ruoyi.common.core.utils.file" }; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java new file mode 100644 index 0000000..7d25f7a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java @@ -0,0 +1,311 @@ +package com.ruoyi.common.core.utils; + +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.*; +import java.io.*; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; + +/** + * 通用http发送方法 + * + * @author ruoyi + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url) + { + return sendGet(url, StringUtils.EMPTY); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param) + { + return sendGet(url, param, Constants.UTF8); + } + + /** + * 向指定 URL 发送GET方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @param contentType 编码类型 + * @return 所代表远程资源的响应结果 + */ + public static String sendGet(String url, String param, String contentType) + { + StringBuilder result = new StringBuilder(); + BufferedReader in = null; + try + { + String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; + log.info("sendGet - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection connection = realUrl.openConnection(); + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (in != null) + { + in.close(); + } + } + catch (Exception ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) + { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try + { + log.info("sendPost - {}", url); + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + out = new PrintWriter(conn.getOutputStream()); + out.print(param); + out.flush(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + if (in != null) + { + in.close(); + } + } + catch (IOException ex) + { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + public static String sendSSLPost(String url, String param) + { + StringBuilder result = new StringBuilder(); + String urlNameString = url + "?" + param; + try + { + log.info("sendSSLPost - {}", urlNameString); + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); + URL console = new URL(urlNameString); + HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + + conn.setSSLSocketFactory(sc.getSocketFactory()); + conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); + conn.connect(); + InputStream is = conn.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String ret = ""; + while ((ret = br.readLine()) != null) + { + if (ret != null && !"".equals(ret.trim())) + { + result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); + } + } + log.info("recv - {}", result); + conn.disconnect(); + br.close(); + } + catch (ConnectException e) + { + log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); + } + return result.toString(); + } + + public static String post(String strURL, String params) { + String result = ""; + BufferedReader reader = null; + try { + URL url = new URL(strURL);// 创建连接 + HttpURLConnection connection = (HttpURLConnection) url + .openConnection(); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setUseCaches(false); + connection.setInstanceFollowRedirects(true); + connection.setRequestMethod("POST"); // 设置请求方式 + connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式 + connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式 + connection.connect(); + if (params != null && !StringUtils.isEmpty(params)) { + byte[] writebytes = params.getBytes(); + // 设置文件长度 + // connection.setRequestProperty("Content-Length", String.valueOf(writebytes.length)); + OutputStream outwritestream = connection.getOutputStream(); + outwritestream.write(params.getBytes()); + outwritestream.flush(); + outwritestream.close(); + // Log.d("hlhupload", "doJsonPost: conn"+connection.getResponseCode()); + } + if (connection.getResponseCode() == 200) { + log.info("<<<<<<<<<<<<<请求响应:{}", connection.getResponseMessage()); + reader = new BufferedReader( + new InputStreamReader(connection.getInputStream())); + result = reader.readLine(); + log.info("<<<<<<<<<<<<<请求响应:{}", result); + } else { + throw new ServiceException(connection.getResponseMessage()); + } + } catch (Exception e) { + throw new ServiceException("http的post请求异常!" + e.getMessage()); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + private static class TrustAnyTrustManager implements X509TrustManager + { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[] {}; + } + } + + private static class TrustAnyHostnameVerifier implements HostnameVerifier + { + @Override + public boolean verify(String hostname, SSLSession session) + { + return true; + } + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java b/ruoyi-common/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..c9f3b66 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java @@ -0,0 +1,50 @@ +package com.ruoyi.common.redis.configure; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; + +import java.nio.charset.Charset; + +/** + * Redis使用FastJson序列化 + * + * @author ruoyi + */ +public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> +{ + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + private Class<T> clazz; + + + public FastJson2JsonRedisSerializer(Class<T> clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/redis/service/RedisService.java b/ruoyi-common/src/main/java/com/ruoyi/common/redis/service/RedisService.java new file mode 100644 index 0000000..1ae72cd --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/redis/service/RedisService.java @@ -0,0 +1,273 @@ +package com.ruoyi.common.redis.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * spring redis 工具类 + * + * @author ruoyi + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisService +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public <T> void setCacheObject(final String key, final T value) + { + redisTemplate.opsForValue().set(key, value); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) + { + redisTemplate.opsForValue().set(key, value, timeout, timeUnit); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout) + { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public boolean expire(final String key, final long timeout, final TimeUnit unit) + { + return redisTemplate.expire(key, timeout, unit); + } + + /** + * 获取有效时间 + * + * @param key Redis键 + * @return 有效时间 + */ + public long getExpire(final String key) + { + return redisTemplate.getExpire(key); + } + + /** + * 判断 key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public Boolean hasKey(String key) + { + return redisTemplate.hasKey(key); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public <T> T getCacheObject(final String key) + { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 删除单个对象 + * + * @param key + */ + public boolean deleteObject(final String key) + { + return redisTemplate.delete(key); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + * @return + */ + public boolean deleteObject(final Collection collection) + { + return redisTemplate.delete(collection) > 0; + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public <T> long setCacheList(final String key, final List<T> dataList) + { + Long count = redisTemplate.opsForList().rightPushAll(key, dataList); + return count == null ? 0 : count; + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public <T> List<T> getCacheList(final String key) + { + return redisTemplate.opsForList().range(key, 0, -1); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) + { + BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key); + Iterator<T> it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 获得缓存的set + * + * @param key + * @return + */ + public <T> Set<T> getCacheSet(final String key) + { + return redisTemplate.opsForSet().members(key); + } + + /** + * 缓存Map + * + * @param key + * @param dataMap + */ + public <T> void setCacheMap(final String key, final Map<String, T> dataMap) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + } + } + + public <T> void setCacheMap(final String key, final Map<String, T> dataMap, long timeout) + { + if (dataMap != null) { + redisTemplate.opsForHash().putAll(key, dataMap); + redisTemplate.expire(key, timeout, TimeUnit.SECONDS); + } + } + + /** + * 获得缓存的Map + * + * @param key + * @return + */ + public <T> Map<String, T> getCacheMap(final String key) + { + return redisTemplate.opsForHash().entries(key); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public <T> void setCacheMapValue(final String key, final String hKey, final T value) + { + redisTemplate.opsForHash().put(key, hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public <T> T getCacheMapValue(final String key, final String hKey) + { + HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash(); + return opsForHash.get(key, hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) + { + return redisTemplate.opsForHash().multiGet(key, hKeys); + } + + /** + * 删除Hash中的某条数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return 是否成功 + */ + public boolean deleteCacheMapValue(final String key, final String hKey) + { + return redisTemplate.opsForHash().delete(key, hKey) > 0; + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public Collection<String> keys(final String pattern) + { + return redisTemplate.keys(pattern); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 1a4e0fa..5f90047 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -118,6 +118,7 @@ "/applet/changepwd", "/captchaImage","/getCode","/loginCode", "/operations/getBySingleNum/**", "/user/getUserInfoByNumber/**", + "/wxLogin/**", "/open/**" ).permitAll() // 静态资源,可匿名访问 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java index 3eb2495..9015708 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -5,6 +5,8 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.core.domain.model.LoginUserApplet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; @@ -32,12 +34,22 @@ throws ServletException, IOException { LoginUser loginUser = tokenService.getLoginUser(request); - if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) + LoginUserApplet applet = tokenService.getLoginUserApplet(request); + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())|| + StringUtils.isNotNull(applet)) { - tokenService.verifyToken(loginUser); - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); - authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authenticationToken); + if (StringUtils.isNotNull(loginUser)){ + tokenService.verifyToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + if (StringUtils.isNotNull(applet)){ + tokenService.verifyTokenApplet(applet); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(applet, null, applet.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } } chain.doFilter(request, response); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java index d4e744e..a7a640b 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -4,6 +4,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; + +import com.ruoyi.common.core.domain.model.LoginUserApplet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -66,6 +68,15 @@ return getLoginUser(ServletUtils.getRequest()); } /** + * 小程序获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUserApplet getLoginUserApplet() + { + return getLoginUserApplet(ServletUtils.getRequest()); + } + /** * 获取用户身份信息 * * @return 用户信息 @@ -83,6 +94,33 @@ String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); LoginUser user = redisCache.getCacheObject(userKey); + return user; + } + catch (Exception e) + { + log.error("获取用户信息异常'{}'", e.getMessage()); + } + } + return null; + } + /** + * 小程序获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUserApplet getLoginUserApplet(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = getToken(request); + if (StringUtils.isNotEmpty(token)) + { + try + { + Claims claims = parseToken(token); + // 解析对应的权限以及用户信息 + String uuid = (String) claims.get(Constants.LOGIN_USER_APPLET_KEY); + String userKey = getTokenKey(uuid); + LoginUserApplet user = redisCache.getCacheObject(userKey); return user; } catch (Exception e) @@ -133,6 +171,23 @@ claims.put(Constants.LOGIN_USER_KEY, token); return createToken(claims); } + /** + * 创建用户小程序令牌 + * + * @param loginUser 用户信息 + * @return 令牌 + */ + public String createTokenApplet(LoginUserApplet loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + setUserAgentApplet(loginUser); + refreshTokenApplet(loginUser); + + Map<String, Object> claims = new HashMap<>(); + claims.put(Constants.LOGIN_USER_APPLET_KEY, token); + return createTokenApplet(claims); + } /** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 @@ -149,6 +204,21 @@ refreshToken(loginUser); } } + /** + * 小程序验证令牌有效期,相差不足20分钟,自动刷新缓存 + * + * @param loginUser + * @return 令牌 + */ + public void verifyTokenApplet(LoginUserApplet loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshTokenApplet(loginUser); + } + } /** * 刷新令牌有效期 @@ -156,6 +226,19 @@ * @param loginUser 登录信息 */ public void refreshToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + /** + * 刷新令牌有效期 + * + * @param loginUser 登录信息 + */ + public void refreshTokenApplet(LoginUserApplet loginUser) { loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); @@ -178,6 +261,20 @@ loginUser.setBrowser(userAgent.getBrowser().getName()); loginUser.setOs(userAgent.getOperatingSystem().getName()); } + /** + * 设置用户代理信息 + * + * @param loginUser 登录信息 + */ + public void setUserAgentApplet(LoginUserApplet loginUser) + { + UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = IpUtils.getIpAddr(); + loginUser.setIpaddr(ip); + loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); + } /** * 从数据声明生成令牌 @@ -192,6 +289,19 @@ .signWith(SignatureAlgorithm.HS512, secret).compact(); return token; } + /** + * 小程序从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + private String createTokenApplet(Map<String, Object> claims) + { + String token = Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } /** * 从令牌中获取数据声明 diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml index 0747834..80a2359 100644 --- a/ruoyi-system/pom.xml +++ b/ruoyi-system/pom.xml @@ -79,6 +79,10 @@ <artifactId>bankapi</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>com.fasterxml.jackson.datatype</groupId> + <artifactId>jackson-datatype-jsr310</artifactId> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TFaultRepairMessageDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TFaultRepairMessageDTO.java new file mode 100644 index 0000000..e65bec9 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TFaultRepairMessageDTO.java @@ -0,0 +1,10 @@ +package com.ruoyi.system.dto; + +import com.ruoyi.system.model.TFaultRepairMessage; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +@Data +@ApiModel(value = "报修dto") +public class TFaultRepairMessageDTO extends TFaultRepairMessage { +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java index c98a23f..843a7fc 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java @@ -2,6 +2,7 @@ import java.util.List; +import com.ruoyi.system.model.TDeptToUser; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import com.ruoyi.system.domain.SysUserRole; @@ -70,4 +71,6 @@ * @return 结果 */ public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); + + void insertBatchUserDept(List<TDeptToUser> deptToUserList); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TCheckAcceptRecordMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TCheckAcceptRecordMapper.java index 2a7f4d6..ee37eff 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TCheckAcceptRecordMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TCheckAcceptRecordMapper.java @@ -1,7 +1,13 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TCheckAcceptRecord; +import com.ruoyi.system.query.TCheckAcceptRecordQuery; +import com.ruoyi.system.vo.TCheckAcceptRecordVO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * <p> @@ -13,4 +19,13 @@ */ public interface TCheckAcceptRecordMapper extends BaseMapper<TCheckAcceptRecord> { + /** + * 分页查询验收记录 + * @param query + * @param pageInfo + * @return + */ + List<TCheckAcceptRecordVO> pageList(@Param("query") TCheckAcceptRecordQuery query, @Param("pageInfo")PageInfo<TCheckAcceptRecordVO> pageInfo); + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TDeptToUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TDeptToUserMapper.java index effd9a5..37dfe49 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TDeptToUserMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TDeptToUserMapper.java @@ -2,6 +2,7 @@ import com.ruoyi.system.model.TDeptToUser; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; /** * <p> @@ -11,6 +12,14 @@ * @author xiaochen * @since 2025-02-06 */ +@Mapper public interface TDeptToUserMapper extends BaseMapper<TDeptToUser> { + /** + * 根据用户ID删除部门用户中间表 + * + * @param userId 用户ID + * @return 删除结果 + **/ + int deleteUserDeptByUserId(Long userId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultAreaDicMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultAreaDicMapper.java index a4dcc5e..7879534 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultAreaDicMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultAreaDicMapper.java @@ -4,6 +4,7 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TFaultAreaDic; import com.ruoyi.system.query.TFaultAreaDicQuery; +import com.ruoyi.system.vo.TFaultAreaDicVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -28,4 +29,9 @@ */ List<TFaultAreaDic> pageList(@Param("query")TFaultAreaDicQuery query, @Param("pageInfo")PageInfo<TFaultAreaDic> pageInfo); + /** + * 查询列表 + * @return + */ + List<TFaultAreaDicVO> getAreaDicList(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultRepairMessageMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultRepairMessageMapper.java index 66060aa..b9774a9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultRepairMessageMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TFaultRepairMessageMapper.java @@ -1,7 +1,13 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TFaultRepairMessage; +import com.ruoyi.system.query.TFaultRepairMessageQuery; +import com.ruoyi.system.vo.TFaultRepairMessageVO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * <p> @@ -13,4 +19,19 @@ */ public interface TFaultRepairMessageMapper extends BaseMapper<TFaultRepairMessage> { + /** + * 根据id查询报修管理 + * @param id + * @return + */ + TFaultRepairMessageVO getDetailById(@Param("id") String id); + + /** + * 分页查询报修管理 + * @param query + * @param pageInfo + * @return + */ + List<TFaultRepairMessageVO> pageList(@Param("query") TFaultRepairMessageQuery query, @Param("pageInfo")PageInfo<TFaultRepairMessageVO> pageInfo); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TItemTypeMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TItemTypeMapper.java index 8b6aca6..3edc837 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TItemTypeMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TItemTypeMapper.java @@ -4,6 +4,7 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TItemType; import com.ruoyi.system.query.TItemTypeQuery; +import com.ruoyi.system.vo.TItemTypeVO; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -25,4 +26,8 @@ * @return */ List<TItemType> pageList(@Param("query") TItemTypeQuery query, @Param("pageInfo")PageInfo<TItemType> pageInfo); + + List<TItemTypeVO> getItemList(); + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TCheckAcceptRecord.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TCheckAcceptRecord.java index 4a266e8..6a50c67 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TCheckAcceptRecord.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TCheckAcceptRecord.java @@ -84,7 +84,7 @@ @TableField("pictures") private String pictures; - @ApiModelProperty(value = "验收结果 1=合格 2=不合格") + @ApiModelProperty(value = "验收结果 1=合格 0=不合格") @TableField("check_result") private Boolean checkResult; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java index 5a87bcd..800f497 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java @@ -133,6 +133,16 @@ @TableField("remark") private String remark; + /** + * 1 待提交 + * 2 待审批 + * 3 未签订 + * 4 已签订 + * 5 已驳回 + * 6 已终止 + * 7 待结算 + * 8 已结算 + */ @ApiModelProperty(value = "状态 待提交 待审批 未签订 已签订....") @TableField("status") private String status; @@ -151,5 +161,8 @@ @ApiModelProperty(value = "合计年租金") @TableField("total_year") private BigDecimal totalYear; + @ApiModelProperty(value = "房屋名称") + @TableField(exist = false) + private String houseName; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java index a0b05ef..c1dec51 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TFaultRepairMessage.java @@ -34,12 +34,20 @@ private String id; @ApiModelProperty(value = "用户id") - @TableField("app_user_id") - private String appUserId; + @TableField("tenant_id") + private String tenantId; + + @ApiModelProperty(value = "物品分类id") + @TableField("item_type_id") + private String itemTypeId; @ApiModelProperty(value = "物品id") @TableField("item_id") private String itemId; + + @ApiModelProperty(value = "合同id") + @TableField("contract_id") + private String contractId; @ApiModelProperty(value = "故障区域") @TableField("fault_area_name") @@ -99,6 +107,10 @@ @TableField("attachment") private String attachment; + @ApiModelProperty(value = "附件名称 逗号分割") + @TableField("attachment_name") + private String attachmentName; + @ApiModelProperty(value = "状态 1=待处理 2=已处理") @TableField("status") private Integer status; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java index 7ebb8ff..10e3f55 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TInformation.java @@ -67,4 +67,8 @@ @TableField("attachment_name") private String attachmentName; + @ApiModelProperty(value = "查看次数") + @TableField(exist = false) + private Integer viewCount; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java index 92a1d88..cca42c8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java @@ -88,5 +88,8 @@ @ApiModelProperty(value = "登录密码") @TableField("password") private String password; + @ApiModelProperty(value = "微信openid") + @TableField("open_id") + private String openId; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java index 8609862..3727f0a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/SysUserQuery.java @@ -5,18 +5,20 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.util.List; + @Data @ApiModel(value = "账户列表query") public class SysUserQuery extends BasePage { @ApiModelProperty(value = "姓名") - private String nickName; + private String nickNameAndPhone; @ApiModelProperty(value = "角色id") private Integer roleId; - @ApiModelProperty(value = "手机号") - private String phonenumber; + @ApiModelProperty(value = "部门id集合") + private List<String> deptIds; @ApiModelProperty(value = "状态 0=正常 1=停用") private String status; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java new file mode 100644 index 0000000..89da8f4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TCheckAcceptRecordQuery.java @@ -0,0 +1,22 @@ +package com.ruoyi.system.query; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.core.domain.model.TimeRangeQueryBody; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "验收记录查询对象query") +public class TCheckAcceptRecordQuery extends TimeRangeQueryBody { + + @ApiModelProperty(value = "房屋名称") + private String houseName; + + @ApiModelProperty(value = "合同编号") + private String contractNumber; + + @ApiModelProperty(value = "验收结果 1=合格 0=不合格") + private Boolean checkResult; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java new file mode 100644 index 0000000..3aa2f26 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFaultRepairMessageQuery.java @@ -0,0 +1,27 @@ +package com.ruoyi.system.query; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.ruoyi.common.core.domain.BasePage; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "报修列表查询query") +public class TFaultRepairMessageQuery extends BasePage { + + @ApiModelProperty(value = "用户id") + private String tenantId; + + @ApiModelProperty(value = "联系电话") + private String contactNumber; + + @ApiModelProperty(value = "状态 1=待处理 2=已处理") + private Integer status; + + @ApiModelProperty(value = "报修类型 1=常规维修 2=紧急抢修") + private Integer repairType; + + @ApiModelProperty(value = "处理人") + private String handlePerson; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TCheckAcceptRecordService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TCheckAcceptRecordService.java index 4344575..dd07c92 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TCheckAcceptRecordService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TCheckAcceptRecordService.java @@ -1,7 +1,10 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TCheckAcceptRecord; +import com.ruoyi.system.query.TCheckAcceptRecordQuery; +import com.ruoyi.system.vo.TCheckAcceptRecordVO; /** * <p> @@ -13,4 +16,10 @@ */ public interface TCheckAcceptRecordService extends IService<TCheckAcceptRecord> { + /** + * 获取验收记录分页列表 + * @param query + * @return + */ + PageInfo<TCheckAcceptRecordVO> pageList(TCheckAcceptRecordQuery query); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultAreaDicService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultAreaDicService.java index 5ef09fb..721a161 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultAreaDicService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultAreaDicService.java @@ -4,6 +4,9 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TFaultAreaDic; import com.ruoyi.system.query.TFaultAreaDicQuery; +import com.ruoyi.system.vo.TFaultAreaDicVO; + +import java.util.List; /** * <p> @@ -28,4 +31,7 @@ * @return */ boolean isExit(TFaultAreaDic dto); + + List<TFaultAreaDicVO> getAreaDicList(); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultRepairMessageService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultRepairMessageService.java index a51a68f..272ec26 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultRepairMessageService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TFaultRepairMessageService.java @@ -1,7 +1,10 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TFaultRepairMessage; +import com.ruoyi.system.query.TFaultRepairMessageQuery; +import com.ruoyi.system.vo.TFaultRepairMessageVO; /** * <p> @@ -13,4 +16,17 @@ */ public interface TFaultRepairMessageService extends IService<TFaultRepairMessage> { + /** + * 查看报修详情 + * @param id + * @return + */ + TFaultRepairMessageVO getDetailById(String id); + + /** + * 获取报修分页列表 + * @param query + * @return + */ + PageInfo<TFaultRepairMessageVO> pageList(TFaultRepairMessageQuery query); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TItemTypeService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TItemTypeService.java index d542486..14ee3d1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TItemTypeService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TItemTypeService.java @@ -4,6 +4,9 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TItemType; import com.ruoyi.system.query.TItemTypeQuery; +import com.ruoyi.system.vo.TItemTypeVO; + +import java.util.List; /** * <p> @@ -28,4 +31,6 @@ * @return */ PageInfo<TItemType> pageList(TItemTypeQuery query); + + List<TItemTypeVO> getItemList(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TTenantService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TTenantService.java index 0357962..590f644 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TTenantService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TTenantService.java @@ -2,9 +2,12 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.system.utils.wx.pojo.AppletUserDecodeData; import com.ruoyi.system.model.TTenant; import com.ruoyi.system.query.TTenantQuery; import com.ruoyi.system.vo.TenantVO; + +import java.util.Map; /** * <p> @@ -22,4 +25,6 @@ * @return */ PageInfo<TenantVO> pageList(TTenantQuery query); + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 5fc26a4..ed7ae34 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -6,8 +6,14 @@ import java.util.stream.Collectors; import javax.validation.Validator; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.system.mapper.*; +import com.ruoyi.system.model.TDept; +import com.ruoyi.system.model.TDeptToUser; import com.ruoyi.system.query.SysUserQuery; +import com.ruoyi.system.service.TDeptToUserService; import com.ruoyi.system.vo.SysUserVO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,11 +33,6 @@ import com.ruoyi.system.domain.SysPost; import com.ruoyi.system.domain.SysUserPost; import com.ruoyi.system.domain.SysUserRole; -import com.ruoyi.system.mapper.SysPostMapper; -import com.ruoyi.system.mapper.SysRoleMapper; -import com.ruoyi.system.mapper.SysUserMapper; -import com.ruoyi.system.mapper.SysUserPostMapper; -import com.ruoyi.system.mapper.SysUserRoleMapper; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysUserService; @@ -59,9 +60,13 @@ @Autowired private SysUserPostMapper userPostMapper; + @Autowired + private TDeptToUserMapper deptToUserMapper; @Autowired private ISysConfigService configService; + @Autowired + private TDeptMapper deptMapper; @Autowired protected Validator validator; @@ -264,7 +269,7 @@ // 新增用户信息 int rows = userMapper.insertUser(user); // 新增用户岗位关联 -// insertUserPost(user); + insertUserDept(user); // 新增用户与角色管理 insertUserRoleId(user); return rows; @@ -297,10 +302,10 @@ userRoleMapper.deleteUserRoleByUserId(userId); // 新增用户与角色管理 insertUserRoleId(user); - // 删除用户与岗位关联 -// userPostMapper.deleteUserPostByUserId(userId); - // 新增用户与岗位管理 -// insertUserPost(user); + // 删除用户与部门关联 + deptToUserMapper.deleteUserDeptByUserId(userId); + // 新增用户与部门管理 + insertUserDept(user); return userMapper.updateUser(user); } @@ -401,6 +406,17 @@ } /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserDept(SysUser user) + { + this.insertUserDept(user.getUserId(), user.getDeptIds()); + } + + + /** * 新增用户岗位信息 * * @param user 用户对象 @@ -460,6 +476,26 @@ ur.setUserId(userId); ur.setRoleId(roleId); userRoleMapper.insertUserRole(ur); + } + } + /** + * 新增用户部门信息 + * + * @param userId 用户ID + * @param deptIds 部门id集合 + */ + public void insertUserDept(Long userId, List<String> deptIds) + { + if (Objects.nonNull(userId) && !CollectionUtils.isEmpty(deptIds)){ + List<TDeptToUser> deptToUserList = new ArrayList<>(); + for (String deptId : deptIds) { + // 新增用户与角色管理 + TDeptToUser deptToUser = new TDeptToUser(); + deptToUser.setUserId(userId); + deptToUser.setDeptId(deptId); + deptToUserList.add(deptToUser); + } + userRoleMapper.insertBatchUserDept(deptToUserList); } } @@ -628,6 +664,19 @@ public PageInfo<SysUserVO> pageList(SysUserQuery query) { PageInfo<SysUserVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<SysUserVO> list = userMapper.pageList(query,pageInfo); + if(CollectionUtils.isEmpty(list)){ + return pageInfo; + } + List<Long> userIds = list.stream().map(SysUserVO::getUserId).collect(Collectors.toList()); + // 查询所有部门 + List<TDept> depts = deptMapper.selectList(Wrappers.lambdaQuery(TDept.class)); + List<TDeptToUser> tDeptToUsers = deptToUserMapper.selectList(Wrappers.lambdaQuery(TDeptToUser.class) + .in(TDeptToUser::getUserId, userIds)); + for (SysUserVO sysUserVO : list) { + tDeptToUsers.stream().filter(tDeptToUser -> tDeptToUser.getUserId().equals(sysUserVO.getUserId())).forEach(tDeptToUser -> { + sysUserVO.setDeptList(depts.stream().filter(tDept -> tDept.getId().equals(tDeptToUser.getDeptId())).map(TDept::getDeptName).collect(Collectors.toList())); + }); + } pageInfo.setRecords(list); return pageInfo; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java index 4181286..48052e2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java @@ -1,10 +1,18 @@ package com.ruoyi.system.service.impl; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.constant.DictConstants; +import com.ruoyi.common.utils.DictUtils; import com.ruoyi.system.mapper.TCheckAcceptRecordMapper; import com.ruoyi.system.model.TCheckAcceptRecord; +import com.ruoyi.system.query.TCheckAcceptRecordQuery; import com.ruoyi.system.service.TCheckAcceptRecordService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.system.vo.SysUserVO; +import com.ruoyi.system.vo.TCheckAcceptRecordVO; import org.springframework.stereotype.Service; + +import java.util.List; /** * <p> @@ -17,4 +25,17 @@ @Service public class TCheckAcceptRecordServiceImpl extends ServiceImpl<TCheckAcceptRecordMapper, TCheckAcceptRecord> implements TCheckAcceptRecordService { + @Override + public PageInfo<TCheckAcceptRecordVO> pageList(TCheckAcceptRecordQuery query) { + PageInfo<TCheckAcceptRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); + List<TCheckAcceptRecordVO> list = this.baseMapper.pageList(query,pageInfo); + list.forEach(item -> { + item.setCleanSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getCleanSituation())); + item.setOverallSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getOverallSituation())); + item.setDeviceSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getDeviceSituation())); + item.setFurnitureSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getFurnitureSituation())); + }); + pageInfo.setRecords(list); + return pageInfo; + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java index 458ec6c..405a874 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java @@ -17,16 +17,21 @@ import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TContractRentTypeService; import com.ruoyi.system.service.TContractService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.vo.BillVO; import com.ruoyi.system.vo.CheckAcceptRecordVO; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; +import java.time.LocalDate; 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; @@ -118,6 +123,7 @@ CheckAcceptRecordVO checkAcceptRecordVO = new CheckAcceptRecordVO(); TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordMapper.selectOne(new LambdaQueryWrapper<TCheckAcceptRecord>() .eq(TCheckAcceptRecord::getContractId, id)); + if (tCheckAcceptRecord==null)return checkAcceptRecordVO; BeanUtils.copyProperties(tCheckAcceptRecord,checkAcceptRecordVO); THouse tHouse = houseMapper.selectById(tCheckAcceptRecord.getHouseId()); tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); @@ -125,7 +131,8 @@ checkAcceptRecordVO.setHouse(tHouse); return checkAcceptRecordVO; } - + @Autowired + private TContractRentTypeService contractRentTypeService; @Override public R signContract(SignContractDTO dto) { TContract contract = contractMapper.selectById(dto.getId()); @@ -134,42 +141,475 @@ contract.setSignature(dto.getSignature()); contract.setStatus("2"); contractMapper.updateById(contract); - // 用户签订合同后 生成第一批账单包含租金账单和押金账单 后续账单通过定时任务生成 - TBill rent = new TBill(); - rent.setContractId(contract.getId()); - // 应缴费租金 - BigDecimal payableFeesMoney = new BigDecimal("0"); - LocalDateTime startTime = contract.getStartTime(); - LocalDateTime endTime = contract.getEndTime(); -// // 计算相差多少天 -// long days = ChronoUnit.DAYS.between(startTime, endTime); -// // 计算相差多少个月 -// long months = ChronoUnit.MONTHS.between(startTime, endTime); -// if (months<=31){ -// // 小于等于一个月 合计租金就是首笔账单金额 -// payableFeesMoney = contract.getTotalRent(); -// }else{ -// switch (contract.getPayType()){ -// case "1": -// break; -// case "2": -// break; -// case "3": -// break; -// } -// } -// -// rent.setPayableFeesMoney(payableFeesMoney); -// rent.setPayableFeesTime(contract.getFirstPayTime()); -// rent.setPayFeesStatus("1"); -// rent.setBillType("1"); -// -// TBill deposit = new TBill(); -// deposit.setContractId(contract.getId()); -// deposit.setPayableFeesMoney(contract.getDeposit()); -// deposit.setPayableFeesTime(contract.getFirstPayTime()); -// deposit.setPayFeesStatus("1"); -// deposit.setBillType("2"); + contract.setFirstPayTime(contract.getStartTime().plusDays(10)); + List<TBill> bills = new ArrayList<>(); + List<TContractRentType> contractRentTypes = contractRentTypeService.list(); + // 生成第一笔账单 + // 第一次应缴费日期 + LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0); + TBill rentBill = new TBill(); + rentBill.setContractId(contract.getId()); + rentBill.setContractNumber(contract.getContractNumber()); + rentBill.setPayableFeesTime(firstPayTime); + if (firstPayTime.toLocalDate().equals(LocalDate.now())){ + rentBill.setPayFeesStatus("1"); + }else { + rentBill.setPayFeesStatus("2"); + } + rentBill.setBillType("1"); + rentBill.setStartTime(contract.getStartPayTime()); + TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); + if (tContractRentType!=null && contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(tContractRentType.getChangeTime())){ + // 计算租金变动的天数 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L; + contract.setChangeTime(LocalDateTime.now()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ + rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); + }else{ + rentBill.setEndTime(contract.getEndTime()); + } + }else{ + if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ + rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); + }else{ + rentBill.setEndTime(contract.getEndTime()); + } + // 不走递增递减 + long allDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), rentBill.getEndTime()); + rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + + } + // 押金账单 + TBill depositBill = new TBill(); + depositBill.setContractId(contract.getId()); + depositBill.setContractNumber(contract.getContractNumber()); + depositBill.setPayableFeesMoney(contract.getDeposit()); + depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney()); + depositBill.setStartTime(contract.getStartPayTime()); + depositBill.setEndTime(contract.getEndTime()); + depositBill.setPayableFeesTime(firstPayTime); + if (firstPayTime.toLocalDate().equals(LocalDate.now())){ + depositBill.setPayFeesStatus("1"); + + }else { + depositBill.setPayFeesStatus("2"); + + } + depositBill.setBillType("2"); + this.updateById(contract); + billService.save(rentBill); + billService.save(depositBill); + // 生成后续账单 + try { + TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime) + .last("limit 1").one(); + if (!beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())){ + + + while(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isBefore(contract.getEndTime())){ + + TBill tBill = new TBill(); + tBill.setContractId(contract.getId()); + tBill.setContractNumber(contract.getContractNumber()); + // 根据支付方式判断需不需要生成订单 + if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) + && + (contract.getPayType().equals("1")? + beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? + beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)) + .with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime()) + && beforeBill.getEndTime().isBefore(contract.getEndTime()) + ){ + tBill.setContractId(contract.getId()); + if (contract.getIsIncreasing()){ + if (tContractRentType!=null + && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) + && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ + // 如果没变过 + if (contract.getChangeTime()==null){ + contract.setChangeTime(LocalDateTime.now()); + // 租金递增递减的时长 天 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + }else{ + // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 + if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ + contract.setChangeTime(LocalDateTime.now()); + // 租金递增递减的时长 天 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + }else{ + // 不涨租金 用上次的 + // 租金递增递减的时长 天 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + } + } + + } + }else{ + long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), (contract.getPayType().equals("1")? + beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? + beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)).with(TemporalAdjusters.lastDayOfMonth())); + tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + } + tBill.setContractNumber(contract.getContractNumber()); + if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){ + tBill.setPayableFeesTime(contract.getEndTime()); + }else{ + tBill.setPayableFeesTime((contract.getPayType().equals("1")? + beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")? + beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12))); + } + tBill.setPayFeesStatus("2"); + tBill.setBillType("1"); + tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); + tBill.setEndTime(contract.getEndTime()); + } + billMapper.insert(tBill); + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime) + .last("limit 1").one(); + // 生成最后一笔账单 + if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) + && + (contract.getPayType().equals("1")? + beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? + beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)) + .with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime()) + && beforeBill.getEndTime().isBefore(contract.getEndTime()) + ){ + TBill tBill = new TBill(); + tBill.setContractId(contract.getId()); + + if (contract.getIsIncreasing()){ + if (tContractRentType!=null + && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) + && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ + // 如果没变过 + if (contract.getChangeTime()==null){ + contract.setChangeTime(LocalDateTime.now()); + // 租金递增递减的时长 天 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); + + // 不需要涨租金的时间段 + if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){ + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + }else{ + tBill.setPayableFeesMoney(contractRentTypeMoney); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + + }else{ + // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 + if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ + contract.setChangeTime(LocalDateTime.now()); + // 租金递增递减的时长 天 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + }else{ + // 不涨租金 用上次的 + // 租金递增递减的时长 天 + long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()){ + case 1: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contractRentTypeMoney); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()){ + case 1: + contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); + contract.setChangeRent(contractRentTypeMoney); + + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); + originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + } + } + + } + }else{ + long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); + tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + + } + tBill.setContractNumber(contract.getContractNumber()); + if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){ + tBill.setPayableFeesTime(contract.getEndTime().withHour(0).withMinute(0).withSecond(0)); + }else{ + tBill.setPayableFeesTime((contract.getPayType().equals("1")? + beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15):contract.getPayType().equals("2")? + beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15):beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).withHour(0).withMinute(0).withSecond(0))); + } + tBill.setPayFeesStatus("1"); + tBill.setBillType("1"); + tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); + tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); + billService.save(tBill); + } + return R.ok(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultAreaDicServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultAreaDicServiceImpl.java index 094504b..93d55ba 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultAreaDicServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultAreaDicServiceImpl.java @@ -11,6 +11,7 @@ import com.ruoyi.system.query.TFaultAreaDicQuery; import com.ruoyi.system.service.TFaultAreaDicService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.system.vo.TFaultAreaDicVO; import com.ruoyi.system.vo.TenantVO; import org.springframework.stereotype.Service; @@ -45,4 +46,9 @@ return this.count(Wrappers.lambdaQuery(TFaultAreaDic.class).eq(TFaultAreaDic::getFaultAreaName, dto.getFaultAreaName())) > 0; } } + + @Override + public List<TFaultAreaDicVO> getAreaDicList() { + return this.baseMapper.getAreaDicList(); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java index d406d42..8c3df80 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFaultRepairMessageServiceImpl.java @@ -1,10 +1,16 @@ package com.ruoyi.system.service.impl; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.mapper.TFaultRepairMessageMapper; import com.ruoyi.system.model.TFaultRepairMessage; +import com.ruoyi.system.query.TFaultRepairMessageQuery; import com.ruoyi.system.service.TFaultRepairMessageService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.system.vo.SysOperLogVO; +import com.ruoyi.system.vo.TFaultRepairMessageVO; import org.springframework.stereotype.Service; + +import java.util.List; /** * <p> @@ -17,4 +23,16 @@ @Service public class TFaultRepairMessageServiceImpl extends ServiceImpl<TFaultRepairMessageMapper, TFaultRepairMessage> implements TFaultRepairMessageService { + @Override + public TFaultRepairMessageVO getDetailById(String id) { + return this.baseMapper.getDetailById(id); + } + + @Override + public PageInfo<TFaultRepairMessageVO> pageList(TFaultRepairMessageQuery query) { + PageInfo<TFaultRepairMessageVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); + List<TFaultRepairMessageVO> list = this.baseMapper.pageList(query,pageInfo); + pageInfo.setRecords(list); + return pageInfo; + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInformationServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInformationServiceImpl.java index 282470c..103124e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInformationServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInformationServiceImpl.java @@ -1,12 +1,15 @@ package com.ruoyi.system.service.impl; import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.system.mapper.TInformationMapper; import com.ruoyi.system.model.TInformation; import com.ruoyi.system.query.TInformationQuery; import com.ruoyi.system.service.TInformationService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.vo.HouseVO; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -22,10 +25,16 @@ @Service public class TInformationServiceImpl extends ServiceImpl<TInformationMapper, TInformation> implements TInformationService { + @Autowired + private RedisCache redisCache; + @Override public PageInfo<TInformation> pageList(TInformationQuery query) { PageInfo<TInformation> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TInformation> list = this.baseMapper.pageList(query,pageInfo); + list.forEach(item -> { + item.setViewCount(redisCache.getCacheObject(Constants.INFORMATION_VIEW + item.getId())); + }); pageInfo.setRecords(list); return pageInfo; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TItemTypeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TItemTypeServiceImpl.java index 8696828..d579295 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TItemTypeServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TItemTypeServiceImpl.java @@ -10,6 +10,7 @@ import com.ruoyi.system.query.TItemTypeQuery; import com.ruoyi.system.service.TItemTypeService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.system.vo.TItemTypeVO; import org.springframework.stereotype.Service; import java.util.List; @@ -43,4 +44,9 @@ pageInfo.setRecords(list); return pageInfo; } + + @Override + public List<TItemTypeVO> getItemList() { + return this.baseMapper.getItemList(); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java index c6d65f1..95a8452 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTenantServiceImpl.java @@ -1,18 +1,20 @@ package com.ruoyi.system.service.impl; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.TTenantMapper; import com.ruoyi.system.model.TTenant; import com.ruoyi.system.query.TTenantQuery; import com.ruoyi.system.service.TTenantService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.system.vo.SysUserVO; +import com.ruoyi.system.utils.wx.pojo.AppletUserDecodeData; import com.ruoyi.system.vo.TenantVO; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Map; /** * <p> @@ -30,10 +32,11 @@ PageInfo<TenantVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TenantVO> list = this.baseMapper.pageList(query,pageInfo); for (TenantVO tenantVO : list) { - tenantVO.setTenantAttributesName(DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_ATTRIBUTE,tenantVO.getTenantAttributes())); - tenantVO.setTenantTypeName(DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_TYPE,tenantVO.getTenantType())); + 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()):""); } pageInfo.setRecords(list); return pageInfo; } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/AccessTokenRespBody.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/AccessTokenRespBody.java new file mode 100644 index 0000000..db2d1b4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/AccessTokenRespBody.java @@ -0,0 +1,28 @@ +package com.ruoyi.system.utils.wx.body.resp; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * AccessToken 全局唯一 + * + * @author xiaochen + */ +@Data +public class AccessTokenRespBody extends RespBody implements Serializable { + + /** + * 获取到的凭证 + */ + @JsonProperty("access_token") + private String accessToken; + /** + * 凭证有效时间,单位:秒 + */ + @JsonProperty("expires_in") + private int expiresIn; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/Code2SessionRespBody.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/Code2SessionRespBody.java new file mode 100644 index 0000000..d741edb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/Code2SessionRespBody.java @@ -0,0 +1,29 @@ +package com.ruoyi.system.utils.wx.body.resp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author xiaochen + * @ClassName Code2SessionRespBody + * @Description + * @date 2021-07-28 12:35 + */ +@Data +public class Code2SessionRespBody extends RespBody { + /** + * 用户唯一标识 + */ + @JsonProperty("openid") + private String openid; + /** + * 会话密钥 + */ + @JsonProperty("session_key") + private String sessionKey; + /** + * 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 UnionID 机制说明。 + */ + @JsonProperty("unionid") + private String unionid; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/RespBody.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/RespBody.java new file mode 100644 index 0000000..ee60ab3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resp/RespBody.java @@ -0,0 +1,19 @@ +package com.ruoyi.system.utils.wx.body.resp; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author xiaochen + * @ClassName RespBody + * @Description + * @date 2021-07-28 11:44 + */ +@Data +public class RespBody { + @JsonProperty("errcode") + private Integer errorCode; + + @JsonProperty("errmsg") + private String errorMsg; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resq/Code2SessionResqBody.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resq/Code2SessionResqBody.java new file mode 100644 index 0000000..424e376 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/body/resq/Code2SessionResqBody.java @@ -0,0 +1,21 @@ +package com.ruoyi.system.utils.wx.body.resq; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author xiaochen + * @ClassName Code2SessionResqBody + * @Description + * @date 2021-07-28 11:47 + */ +@Data +public class Code2SessionResqBody { + @JsonProperty("js_code") + private String jsCode; + + public Code2SessionResqBody build(String jsCode) { + this.jsCode = jsCode; + return this; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/model/WeixinProperties.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/model/WeixinProperties.java new file mode 100644 index 0000000..fdeb5ab --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/model/WeixinProperties.java @@ -0,0 +1,79 @@ +package com.ruoyi.system.utils.wx.model; + +import lombok.ToString; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author xiaochen + * @ClassName WeixinProperties + * @Description + * @date 2024-08-14 13:55 + */ +@ToString +@Component +@ConfigurationProperties(prefix = "wx.conf") +public class WeixinProperties { + /** + * 默认开启 + */ + private boolean enabled = true; + /** + * 获取 App ID + * + * @return App ID + */ + private String appId; + /** + * 获取 Mch ID + * + * @return Mch ID + */ + private String mchId; + + /** + * 获取 secret ID + * + * @return secret ID + */ + private String secretId; + + public String getSecretId() { + return secretId; + } + + public void setSecretId(String secretId) { + this.secretId = secretId; + } + + /** + * HTTP(S) 连接超时时间,单位毫秒 + * + */ + public int getHttpConnectTimeoutMs() { + return 6 * 1000; + } + + /** + * HTTP(S) 读数据超时时间,单位毫秒 + */ + public int getHttpReadTimeoutMs() { + return 8 * 1000; + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getMchId() { + return mchId; + } + + public void setMchId(String mchId) { + this.mchId = mchId; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletPhoneEncrypteData.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletPhoneEncrypteData.java new file mode 100644 index 0000000..c7f5257 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletPhoneEncrypteData.java @@ -0,0 +1,19 @@ +package com.ruoyi.system.utils.wx.pojo; + +import lombok.Data; + +/** + * @author xiaochen + * @ClassName AppletUserDecodeData + * @Description + * @date 2021-08-13 17:46 + * 小程序加密数据体 + * + */ +@Data +public class AppletPhoneEncrypteData { + private String encryptedData; + private String openid; + private String unionid; + private String iv; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserDecodeData.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserDecodeData.java new file mode 100644 index 0000000..a3573ad --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserDecodeData.java @@ -0,0 +1,52 @@ +package com.ruoyi.system.utils.wx.pojo; + +import lombok.Data; + +/** + * @author xiaochen + * @ClassName AppletUserDecodeData + * @Description + * 用户主体信息部分 + * { + * "openId": "OPENID", + * "nickName": "NICKNAME", + * "gender": GENDER, + * "city": "CITY", + * "province": "PROVINCE", + * "country": "COUNTRY", + * "avatarUrl": "AVATARURL", + * "unionId": "UNIONID", + * "watermark": + * { + * "appid":"APPID", + * "timestamp":TIMESTAMP + * } + * } + * 电话部分 + * { + * "phoneNumber": "13580006666", + * "purePhoneNumber": "13580006666", + * "countryCode": "86", + * "watermark": + * { + * "appid":"APPID", + * "timestamp": TIMESTAMP + * } + * } + * + */ +@Data +public class AppletUserDecodeData { + private String openId; + private String unionId; + private String nickName; + private int gender; + private String city; + private String province; + private String country; + private String avatarUrl; + private Watermark watermark; + private String phoneNumber; + private String purePhoneNumber; + private String countryCode; +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserEncrypteData.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserEncrypteData.java new file mode 100644 index 0000000..16d0057 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/AppletUserEncrypteData.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.utils.wx.pojo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author xiaochen + * @ClassName AppletUserDecodeData + * @Description + * 小程序加密数据体 + * + */ +@Data +public class AppletUserEncrypteData extends AppletPhoneEncrypteData { + private String rawData; + private String signature; + private String code; + @ApiModelProperty(value = "邀请用户id") + private Long inviteUserId; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/Watermark.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/Watermark.java new file mode 100644 index 0000000..16f4f7a --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/pojo/Watermark.java @@ -0,0 +1,9 @@ +package com.ruoyi.system.utils.wx.pojo; + +import lombok.Data; + +@Data +public class Watermark { + private String appid; + private String timestamp; +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/SHA1.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/SHA1.java new file mode 100644 index 0000000..2b74822 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/SHA1.java @@ -0,0 +1,36 @@ +package com.ruoyi.system.utils.wx.tools; + +import java.security.MessageDigest; + +public class SHA1 { + + + /** + * 用SHA1算法生成安全签名 + * + * @param str + * @return + * @throws WxException + */ + public static String getSHA1(String str) throws WxException { + try { + // SHA1签名生成 + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(str.getBytes()); + byte[] digest = md.digest(); + StringBuffer hexstr = new StringBuffer(); + String shaHex; + for (int i = 0; i < digest.length; i++) { + shaHex = Integer.toHexString(digest[i] & 0xFF); + if (shaHex.length() < 2) { + hexstr.append(0); + } + hexstr.append(shaHex); + } + return hexstr.toString(); + } catch (Exception e) { + throw new WxException(WxException.ComputeSignatureError); + } + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WebUtils.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WebUtils.java new file mode 100644 index 0000000..c2e15e1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WebUtils.java @@ -0,0 +1,48 @@ +package com.ruoyi.system.utils.wx.tools; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +/** + * @Author xiaochen + * @Date 2019/08/26 10:28 AM + * @Description + */ +public final class WebUtils { + + private WebUtils() { + } + + /** + * 当前请求 + */ + public static HttpServletRequest request() { + return contextHolder() == null ? null : contextHolder().getRequest(); + } + + /** + * 当前响应 + */ + public static HttpServletResponse response() { + return contextHolder() == null ? null : contextHolder().getResponse(); + } + + /** + * 当前session + */ + public static HttpSession session() { + return request() == null ? null : request().getSession(); + } + + /** + * 当前ServletRequest + */ + public static ServletRequestAttributes contextHolder() { + return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxAppletTools.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxAppletTools.java new file mode 100644 index 0000000..2298a44 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxAppletTools.java @@ -0,0 +1,123 @@ +package com.ruoyi.system.utils.wx.tools; + + +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.system.utils.wx.body.resp.AccessTokenRespBody; +import com.ruoyi.system.utils.wx.body.resp.Code2SessionRespBody; +import com.ruoyi.system.utils.wx.body.resq.Code2SessionResqBody; +import com.ruoyi.system.utils.wx.model.WeixinProperties; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StringUtils; +import org.springframework.web.client.RestTemplate; + +import java.text.MessageFormat; +import java.util.concurrent.TimeUnit; + +/** + * @author xiaochen + * @ClassName WxAppletTools + * @Description + * @date 2024-8-04 13:55 + */ +@Slf4j +public class WxAppletTools { + private final static String ACCESSTOKEN_CACHE_KEY = "accessToken"; + /** + * 请求参数 + * 属性 类型 默认值 必填 说明 + * appid string 是 小程序 appId + * secret string 是 小程序 appSecret + * js_code string 是 登录时获取的 code + * grant_type string 是 授权类型,此处只需填写 authorization_cod + * <p> + * 返回值: + * <p> + * 属性 类型 说明 + * openid string 用户唯一标识 + * session_key string 会话密钥 + * unionid string 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 UnionID 机制说明。 + * errcode number 错误码 + * errmsg string 错误信息 + */ + private static final String JSCODE_2_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code"; + /** + * 请求参数 + * 属性 类型 默认值 必填 说明 + * grant_type string 是 填写 client_credential + * appid string 是 小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态) + * secret string 是 小程序唯一凭证密钥,即 AppSecret,获取方式同 appid + * 返回值 + * Object + * 返回的 JSON 数据包 + * <p> + * 属性 类型 说明 + * access_token string 获取到的凭证 + * expires_in number 凭证有效时间,单位:秒。目前是7200秒之内的值。 + * errcode number 错误码 + * errmsg string 错误信息 + */ + public static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"; + private WeixinProperties wxConfig; + private RestTemplate wxRestTemplate; + private RedisService redisService; + + public WxAppletTools(RestTemplate wxRestTemplate, WeixinProperties wxConfig, RedisService redisService) { + this.wxRestTemplate = wxRestTemplate; + this.wxConfig = wxConfig; + this.redisService = redisService; + } + + /** + * 自定义部分数据 + * + * @param wxConfig + * @return + */ + public WxAppletTools build(WeixinProperties wxConfig) { + this.wxConfig = wxConfig; + return this; + } + + /** + * @param resqBody + * @return + */ + public Code2SessionRespBody getOpenIdByJscode2session(Code2SessionResqBody resqBody) { + long start = System.currentTimeMillis(); + String requestUrl = MessageFormat.format(JSCODE_2_SESSION_URL, wxConfig.getAppId(), wxConfig.getSecretId(), resqBody.getJsCode()); + long end = System.currentTimeMillis(); + log.info("code换取sessionKey时间:{}", (end - start)); + String respBody = wxRestTemplate.getForEntity(requestUrl, String.class).getBody(); + end = System.currentTimeMillis(); + log.info("code换取sessionKey时间:{}", (end - start)); + log.info("Jscode2session:{}", respBody); + Code2SessionRespBody code2SessionRespBody = WxJsonUtils.parseObject(respBody, Code2SessionRespBody.class); + // 判断有误异常 + if (StringUtils.hasLength(code2SessionRespBody.getErrorMsg())) { + // 抛出错误 + throw new WxException(code2SessionRespBody.getErrorCode() + ":" + code2SessionRespBody.getErrorMsg()); + } + return code2SessionRespBody; + } + + /** + * @return + */ + public String getAccessToken(String version) { + String accessToken = redisService.getCacheObject(ACCESSTOKEN_CACHE_KEY + version); + if (StringUtils.hasLength(accessToken)) { + return accessToken; + } + String requestUrl = MessageFormat.format(ACCESS_TOKEN_URL, wxConfig.getAppId(), wxConfig.getSecretId()); + String respBody = wxRestTemplate.getForEntity(requestUrl, String.class).getBody(); + AccessTokenRespBody accessTokenRespBody = WxJsonUtils.parseObject(respBody, AccessTokenRespBody.class); + // 判断有误异常 + if (StringUtils.hasLength(accessTokenRespBody.getErrorMsg())) { + // 抛出错误 + throw new WxException(accessTokenRespBody.getErrorCode() + ":" + accessTokenRespBody.getErrorMsg()); + } + redisService.setCacheObject(ACCESSTOKEN_CACHE_KEY + version, accessTokenRespBody.getAccessToken(), 7200L, TimeUnit.SECONDS); + return accessTokenRespBody.getAccessToken(); + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCache.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCache.java new file mode 100644 index 0000000..fa82920 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCache.java @@ -0,0 +1,117 @@ +package com.ruoyi.system.utils.wx.tools; + +import java.util.concurrent.TimeUnit; + +/** + * 缓存 + * + * @author xiaochen + */ +class WxCache { + /** + * 缓存的初始化容量 + */ + private int initialCapacity = 50; + /** + * 缓存最大容量 + */ + private long maximumSize = 200L; + /** + * 缓存时长 + */ + private long duration = 7000L; + /** + * 时长单位,自动转换 + * 支持: + * 时 + * 分 + * 秒 + * 天 + */ + private TimeUnit timeunit = TimeUnit.SECONDS; + + public int getInitialCapacity() { + return initialCapacity; + } + + public void setInitialCapacity(int initialCapacity) { + this.initialCapacity = initialCapacity; + } + + public long getMaximumSize() { + return maximumSize; + } + + public void setMaximumSize(long maximumSize) { + this.maximumSize = maximumSize; + } + + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public TimeUnit getTimeunit() { + return timeunit; + } + + public void setTimeunit(TimeUnit timeunit) { + this.timeunit = timeunit; + } + + public static class Builder { + private int initialCapacity; + private long maximumSize; + private long duration; + private TimeUnit timeunit; + + public Builder setInitialCapacity(int initialCapacity) { + this.initialCapacity = initialCapacity; + return this; + } + + public Builder setMaximumSize(long maximumSize) { + this.maximumSize = maximumSize; + return this; + } + + public Builder setDuration(long duration) { + this.duration = duration; + return this; + } + + public Builder setTimeUnit(TimeUnit timeunit) { + this.timeunit = timeunit; + return this; + } + + public WxCache build() { + return new WxCache(this); + } + } + + public static Builder options() { + return new Builder(); + } + + private WxCache(Builder builder) { + this.initialCapacity = 0 == builder.initialCapacity ? this.initialCapacity : builder.initialCapacity; + this.maximumSize = 0L == builder.maximumSize ? this.maximumSize : builder.maximumSize; + this.duration = 0L == builder.duration ? this.duration : builder.duration; + this.timeunit = null == builder.timeunit ? this.timeunit : builder.timeunit; + } + + @Override + public String toString() { + return "WxCache{" + + "initialCapacity=" + initialCapacity + + ", maximumSize=" + maximumSize + + ", duration=" + duration + + ", timeunit=" + timeunit + + '}'; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCacheTemplate.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCacheTemplate.java new file mode 100644 index 0000000..8640177 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxCacheTemplate.java @@ -0,0 +1,34 @@ +package com.ruoyi.system.utils.wx.tools; + +/** + * @author xiaochen + * @ClassName WxCacheTemplate + * @Description + * @date 2021-01-11 11:27 + */ +public interface WxCacheTemplate<T> { + /** + * 保存key + * + * @param key + * @param value + * @return + */ + boolean setKey(String key, T value); + + /** + * 获取缓存 + * + * @param key + * @return + */ + T getKey(String key); + + /** + * 删除 + * + * @param key + * @return + */ + boolean delKey(String key); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxException.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxException.java new file mode 100644 index 0000000..09d46ae --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxException.java @@ -0,0 +1,55 @@ +package com.ruoyi.system.utils.wx.tools; + +/** + * @author lihen + */ +public class WxException extends RuntimeException { + + private final static int OK = 0; + private final static int ValidateSignatureError = -40001; + private final static int ParseXmlError = -40002; + public final static int ComputeSignatureError = -40003; + private final static int IllegalAesKey = -40004; + private final static int ValidateAppidError = -40005; + private final static int EncryptAESError = -40006; + private final static int DecryptAESError = -40007; + private final static int IllegalBuffer = -40008; + + private int code; + + private static String getMessage(int code) { + switch (code) { + case ValidateSignatureError: + return "签名验证错误"; + case ParseXmlError: + return "xml解析失败"; + case ComputeSignatureError: + return "sha加密生成签名失败"; + case IllegalAesKey: + return "SymmetricKey非法"; + case ValidateAppidError: + return "appid校验失败"; + case EncryptAESError: + return "aes加密失败"; + case DecryptAESError: + return "aes解密失败"; + case IllegalBuffer: + return "解密后得到的buffer非法"; + default: + return null; + } + } + + public int getCode() { + return code; + } + + WxException(int code) { + super(getMessage(code)); + this.code = code; + } + + public WxException(String message) { + super(message); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxJsonUtils.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxJsonUtils.java new file mode 100644 index 0000000..cc6113e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxJsonUtils.java @@ -0,0 +1,109 @@ +package com.ruoyi.system.utils.wx.tools; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Json转换工具类 + * 参考:https://blog.csdn.net/weixin_38413579/article/details/82562634 + * @author madman + */ +@Slf4j +public final class WxJsonUtils { + public static final String dateFormat = "yyyy-MM-dd"; + public static final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; + private static final ObjectMapper OM = new ObjectMapper(); + private static final JavaTimeModule timeModule = new JavaTimeModule(); + + /** + * 转换LocalDateTime + */ + static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { + @Override + public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(localDateTime.format(DateTimeFormatter.ofPattern(dateTimeFormat))); + } + } + + /** + * 转换LocalDate + */ + static class LocalDateSerializer extends JsonSerializer<LocalDate> { + @Override + public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(localDate.format(DateTimeFormatter.ofPattern(dateFormat))); + } + } + + /** + * 设置 ObjectMapper + * + * @return + */ + private static ObjectMapper getObjectMapper() { + // 序列化 + timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); + timeModule.addSerializer(LocalDate.class, new LocalDateSerializer()); + // 反序列化 + timeModule.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(dateTimeFormat))); + timeModule.addDeserializer(LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern(dateFormat))); + // 允许对象忽略json中不存在的属性 + OM.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + OM.registerModule(timeModule); + return OM; + } + + /** + * 将对象序列化 + */ + public static <T> String toJsonString(T obj) { + try { + ObjectMapper om = getObjectMapper(); + return om.writeValueAsString(obj); + } catch (JsonProcessingException e) { + log.error("转json字符串失败:{}", obj); + return null; + } + } + + /** + * 反序列化对象字符串 + */ + public static <T> T parseObject(String json, Class<T> clazz) { + try { + ObjectMapper om = getObjectMapper(); + return om.readValue(json, clazz); + } catch (JsonProcessingException e) { + throw new RuntimeException("反序列化对象字符串失败"); + } + } + + /** + * 反序列化字符串成为对象 + */ + public static <T> T parseObject(String json, TypeReference<T> valueTypeRef) { + try { + ObjectMapper om = getObjectMapper(); + return om.readValue(json, valueTypeRef); + } catch (JsonProcessingException e) { + throw new RuntimeException("反序列化字符串成为对象失败"); + } + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxUtils.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxUtils.java new file mode 100644 index 0000000..6287358 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/wx/tools/WxUtils.java @@ -0,0 +1,175 @@ +package com.ruoyi.system.utils.wx.tools; + +import com.ruoyi.system.utils.wx.pojo.AppletUserDecodeData; +import com.ruoyi.common.utils.sign.Base64; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.CharEncoding; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.AlgorithmParameters; +import java.security.Security; +import java.util.Arrays; + +/** + * @Description 获取用户信息工具类 + * @Author xiaochen + * @Date 2021/8/12 15:45 + */ +@Slf4j +public class WxUtils { + + /** + * 微信小程序API 用户数据的解密 + * + * @param encryptedData + * @param sessionKey + * @param iv + * @return + */ + public static AppletUserDecodeData encryptedData(String encryptedData, String sessionKey, String iv) { + // 被加密的数据 + byte[] dataByte = Base64.decode(encryptedData); + // 加密秘钥 + byte[] keyByte = Base64.decode(sessionKey); + // 偏移量 + byte[] ivByte = Base64.decode(iv); + try { + // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要 + int base = 16; + if (keyByte.length % base != 0) { + int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); + byte[] temp = new byte[groups * base]; + Arrays.fill(temp, (byte) 0); + System.arraycopy(keyByte, 0, temp, 0, keyByte.length); + keyByte = temp; + } + // 初始化 + Security.addProvider(new BouncyCastleProvider()); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); + SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); + AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); + parameters.init(new IvParameterSpec(ivByte)); + cipher.init(Cipher.DECRYPT_MODE, spec, parameters); + byte[] resultByte = cipher.doFinal(dataByte); + if (null != resultByte && resultByte.length > 0) { + String result = new String(resultByte, CharEncoding.UTF_8); + log.info("解密原串:{}", result); + return WxJsonUtils.parseObject(result, AppletUserDecodeData.class); + } + throw new RuntimeException("解密的数据为空"); + } catch (Exception e) { + log.error("解密失败. error = {}", e.getMessage(), e); + throw new RuntimeException(e.getMessage()); + } + } + + /** + * 微信小程序API 用户数据的签名验证 + * signature = sha1( rawData + session_key ) + * + * @param rawData 不包括敏感信息的原始数据字符串,用于计算签名。 + * @param sessionKey + */ + public static void verifySignature(String rawData, String sessionKey, String signature) { + String serverSignature = SHA1.getSHA1(rawData + sessionKey); + log.info(rawData + ">>>>>>:" + sessionKey + " === " + serverSignature + " ======" + signature); + if (!signature.equals(serverSignature)) { + throw new RuntimeException("数据验签不通过"); + } + } + + /** + * 根据流接收请求数据 + * + * @param request + * @return + */ + public static String streamBodyByReceive(HttpServletRequest request) throws IOException { + log.info("微信异步回调地址:{}", request.getRequestURL()); + StringBuffer buffer = new StringBuffer(); + InputStream inputStream = request.getInputStream(); + InputStreamReader reader = new InputStreamReader(inputStream); + BufferedReader bufferedReader = new BufferedReader(reader); + String body = null; + while ((body = bufferedReader.readLine()) != null) { + buffer.append(body); + } + String data = buffer.toString(); + reader.close(); + inputStream.close(); + log.info("微信异步回调数据:{}", data); + return data; + } + + /** + * 日志 + * + * @return + */ + public static Logger getLogger() { + Logger logger = LoggerFactory.getLogger("wxpay java sdk"); + return logger; + } + + /** + * debug + * + * @param msg + * @param args + */ + public static void debug(String msg, Object... args) { + Logger log = getLogger(); + if (log.isDebugEnabled()) { + log.debug(msg, args); + } + } + + /** + * info + * + * @param msg + * @param args + */ + public static void info(String msg, Object... args) { + Logger log = getLogger(); + if (log.isInfoEnabled()) { + log.info(msg, args); + } + } + + /** + * warn + * + * @param msg + * @param args + */ + public static void warn(String msg, Object... args) { + Logger log = getLogger(); + if (log.isWarnEnabled()) { + log.warn(msg, args); + } + } + + /** + * error + * + * @param msg + * @param args + */ + public static void error(String msg, Object... args) { + Logger log = getLogger(); + if (log.isErrorEnabled()) { + log.error(msg, args); + } + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/FaultConcatInfoVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/FaultConcatInfoVO.java new file mode 100644 index 0000000..8974d8c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/FaultConcatInfoVO.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.vo; + +import com.ruoyi.system.model.TContract; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +@ApiModel(value = "报修房源信息VO") +public class FaultConcatInfoVO extends TContract { + + @ApiModelProperty(value = "房屋名称") + private String houseName; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/SysUserVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/SysUserVO.java index 15cf0d2..09a4e0d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/vo/SysUserVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/SysUserVO.java @@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.util.List; + @Data @ApiModel(value = "账户列表VO") public class SysUserVO extends SysUser { @@ -14,7 +16,7 @@ @ApiModelProperty(value = "单位名称") private String companyName; @ApiModelProperty(value = "部门") - private String deptName; + private List<String> deptList; @ApiModelProperty(value = "角色") private String roleName; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TBillVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TBillVO.java index 6b4bbbe..604ff8b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TBillVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TBillVO.java @@ -1,6 +1,7 @@ package com.ruoyi.system.vo; import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillDetail; import com.ruoyi.system.model.THouse; @@ -9,6 +10,7 @@ import lombok.Data; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.List; @Data @@ -26,4 +28,18 @@ @ApiModelProperty(value = "租金支付方式 月付 季付 年付") private String payType; + + @ApiModelProperty(value = "押金") + private BigDecimal deposit; + @ApiModelProperty(value = "甲方联系人") + private String partyOnePerson; + + @ApiModelProperty(value = "甲方联系方式") + private String partyOnePhone; + @ApiModelProperty(value = "合同开始时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime concatStartTime; + @ApiModelProperty(value = "合同结束时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime concatEndTime; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TCheckAcceptRecordVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TCheckAcceptRecordVO.java new file mode 100644 index 0000000..23de55e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TCheckAcceptRecordVO.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.vo; + +import com.ruoyi.system.model.TCheckAcceptRecord; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.model.THouse; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "验收记录VO") +public class TCheckAcceptRecordVO extends TCheckAcceptRecord { + + @ApiModelProperty(value = "合同信息") + private TContract contract; + + @ApiModelProperty(value = "房屋信息") + private THouse house; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultAreaDicVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultAreaDicVO.java new file mode 100644 index 0000000..9c3da5d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultAreaDicVO.java @@ -0,0 +1,18 @@ +package com.ruoyi.system.vo; + +import com.ruoyi.system.model.TFaultAreaDic; +import com.ruoyi.system.model.TFaultDescribeDic; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel(value = "故障区域vo") +public class TFaultAreaDicVO extends TFaultAreaDic { + + @ApiModelProperty(value = "故障描述") + private List<TFaultDescribeDic> faultDescribeDicList; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultRepairMessageVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultRepairMessageVO.java new file mode 100644 index 0000000..47c0123 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TFaultRepairMessageVO.java @@ -0,0 +1,22 @@ +package com.ruoyi.system.vo; + +import com.ruoyi.system.model.TFaultRepairMessage; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "报修VO") +public class TFaultRepairMessageVO extends TFaultRepairMessage { + + @ApiModelProperty(value = "物品名称") + private String itemName; + + @ApiModelProperty(value = "物品分类名称") + private String itemTypeName; + + @ApiModelProperty(value = "用户名称") + private String residentName; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TItemTypeVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TItemTypeVO.java new file mode 100644 index 0000000..9c13408 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TItemTypeVO.java @@ -0,0 +1,18 @@ +package com.ruoyi.system.vo; + +import com.ruoyi.system.model.TItem; +import com.ruoyi.system.model.TItemType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +@ApiModel(value = "物品类型VO") +public class TItemTypeVO extends TItemType { + + @ApiModelProperty(value = "维修物品集合") + private List<TItem> itemList; + +} diff --git a/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml index faaee57..cc568e7 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -92,21 +92,6 @@ sol.oper_time AS operTime, sol.cost_time AS costTime,sol.companyName AS companyName,sol.roleName AS roleName,sol.phonenumber AS phonenumber, sol.userId AS userId,sol.nickName AS nickName from sys_oper_log sol - <where> - <if test="query.companyName != null and query.companyName != ''"> - AND sol.companyName LIKE concat('%',#{query.companyName},'%') - </if> - <if test="query.roleName != null and query.roleName != ''"> - AND sol.roleName LIKE concat('%',#{query.roleName},'%') - </if> - <if test="query.nickName != null and query.nickName != ''"> - AND sol.nickName LIKE concat('%',#{query.nickName},'%') - </if> - <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''"> - AND DATE_FORMAT(sol.oper_time, '%Y-%m-%d %H:%i:%s') >= #{query.startTime} - AND DATE_FORMAT(sol.oper_time, '%Y-%m-%d %H:%i:%s') <= #{query.endTime} - </if> - </where> ORDER BY sol.oper_time DESC </select> diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 7336905..7487409 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -228,19 +228,24 @@ from sys_user u left join sys_user_role ur on u.user_id = ur.user_id left join sys_role r on r.role_id = ur.role_id + left join t_dept_to_user tdtu on u.user_id = tdtu.user_id WHERE u.del_flag = 0 - <if test="query.nickName != null and query.nickName != ''"> - AND u.nick_name LIKE concat('%',#{query.nickName},'%') + <if test="query.nickNameAndPhone != null and query.nickNameAndPhone != ''"> + AND (u.nick_name LIKE concat('%',#{query.nickNameAndPhone},'%') + OR u.phonenumber LIKE concat('%',#{query.nickNameAndPhone},'%')) </if> <if test="query.roleId != null"> AND r.role_id = #{query.roleId} </if> - <if test="query.phonenumber != null and query.phonenumber != ''"> - AND u.phonenumber LIKE concat('%',#{query.phonenumber},'%') - </if> <if test="query.status != null and query.status != ''"> AND u.status = #{query.status} </if> + <if test="query.deptIds != null and query.deptIds.size()>0"> + AND u.user_id IN (select DISTINCT user_id from t_dept_to_user where dept_id IN + <foreach collection="query.deptIds" close=")" open="(" item="deptId" separator=","> + #{deptId} + </foreach>) + </if> ORDER BY u.create_time DESC </select> <select id="selectIdByPhone" resultType="java.lang.Long"> diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml index f7715e4..9b0d3cd 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -33,6 +33,12 @@ <insert id="insertUserRole"> insert into sys_user_role(user_id, role_id) values (#{userRole.userId},#{userRole.roleId}) </insert> + <insert id="insertBatchUserDept"> + insert into sys_user_role(user_id, dept_id) values + <foreach item="item" index="index" collection="deptToUserList" separator=","> + (#{item.userId},#{item.deptId}) + </foreach> + </insert> <delete id="deleteUserRoleInfo" parameterType="SysUserRole"> delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} diff --git a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml index 150e9c2..2e99a8c 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml @@ -28,7 +28,53 @@ <!-- 通用查询结果列 --> <sql id="Base_Column_List"> - id, contract_id, house_id, check_time, lease_reason, check_person, accompany_person, overall_situation, furniture_situation, device_situation, clean_situation, other_problem, pictures, check_result, check_money, create_time, update_time, create_by, update_by, disabled + id, contract_id, house_id, check_time, lease_reason, check_person, accompany_person, overall_situation, furniture_situation, device_situation, clean_situation, + other_problem, pictures, check_result, check_money, create_time, update_time, create_by, update_by, disabled </sql> + <select id="pageList" resultType="com.ruoyi.system.vo.TCheckAcceptRecordVO"> + select + t.id, + t.contract_id, + t.house_id, + t.check_time, + t.lease_reason, + t.check_person, + t.accompany_person, + t.overall_situation, + t.furniture_situation, + t.device_situation, + t.clean_situation, + t.other_problem, + t.pictures, + t.check_result, + t.check_money, + t.create_time, + t.update_time, + t.create_by, + t.update_by, + t.disabled, + c.contract_number, + h.house_name + from t_check_accept_record t + left join t_contract c on t.contract_id = c.id + left join t_house h on t.house_id = h.id + <where> + <if test="query.contractNumber != null and query.contractNumber != ''"> + AND c.contract_number LIKE concat('%', #{query.contractNumber}, '%') + </if> + <if test="query.checkResult != null"> + AND t.check_result = #{query.checkResult} + </if> + <if test="query.houseName != null and query.houseName != ''"> + AND h.house_name LIKE concat('%', #{query.houseName}, '%') + </if> + <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''"> + AND t.check_time >= #{query.startTime} + AND t.check_time <= #{query.endTime} + </if> + AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} + </where> + ORDER BY t.create_time DESC + </select> </mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml index 9728d27..eb9f2e8 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml @@ -80,7 +80,7 @@ select t1.*,t2.contract_number as contractNumber,t3.resident_name as residentName,t3.phone as phone from t_bill t1 left join t_contract t2 on t1.contract_id = t2.id - left join t_resident t3 on t2.tenant_id = t3.id + left join t_tenant t3 on t2.tenant_id = t3.id where t2.id = #{query.id} and (t1.pay_fees_status = 1 or t1.pay_fees_status = 4) AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} diff --git a/ruoyi-system/src/main/resources/mapper/system/TDeptToUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TDeptToUserMapper.xml index 8e20f23..a740cf8 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TDeptToUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TDeptToUserMapper.xml @@ -13,5 +13,8 @@ <sql id="Base_Column_List"> id, dept_id, user_id </sql> + <delete id="deleteUserDeptByUserId"> + delete from t_dept_to_user where user_id=#{userId} + </delete> </mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TFaultAreaDicMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TFaultAreaDicMapper.xml index cb2bf60..d3d53ba 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TFaultAreaDicMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TFaultAreaDicMapper.xml @@ -24,5 +24,11 @@ WHERE disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} ORDER BY sort_by,create_time DESC </select> + <select id="getAreaDicList" resultType="com.ruoyi.system.vo.TFaultAreaDicVO"> + SELECT <include refid="Base_Column_List"></include> + FROM t_fault_area_dic + WHERE disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} + ORDER BY sort_by,create_time DESC + </select> </mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml index 99bc9d9..56ca1b4 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml @@ -5,8 +5,10 @@ <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TFaultRepairMessage"> <id column="id" property="id" /> - <result column="app_user_id" property="appUserId" /> + <result column="tenant_id" property="tenantId" /> <result column="item_id" property="itemId" /> + <result column="item_type_id" property="itemTypeId" /> + <result column="contract_id" property="contractId" /> <result column="fault_area_name" property="faultAreaName" /> <result column="describe_name" property="describeName" /> <result column="describe_detail" property="describeDetail" /> @@ -18,9 +20,10 @@ <result column="leave_message" property="leaveMessage" /> <result column="handle_person" property="handlePerson" /> <result column="handle_time" property="handleTime" /> - <result column="reault_describe" property="reaultDescribe" /> + <result column="result_describe" property="resultDescribe" /> <result column="repair_picture" property="repairPicture" /> <result column="attachment" property="attachment" /> + <result column="attachment_name" property="attachmentName" /> <result column="status" property="status" /> <result column="create_time" property="createTime" /> <result column="update_time" property="updateTime" /> @@ -31,7 +34,101 @@ <!-- 通用查询结果列 --> <sql id="Base_Column_List"> - id, app_user_id, item_id, fault_area_name, describe_name, describe_detail, fault_pictures, service_address, repair_type, visit_time, contact_number, leave_message, handle_person, handle_time, reault_describe, repair_picture, attachment, status, create_time, update_time, create_by, update_by, disabled + id, tenant_id, item_id,item_type_id,contract_id, fault_area_name, describe_name, describe_detail, fault_pictures, service_address, repair_type, + visit_time, contact_number, leave_message, handle_person, handle_time, result_describe, repair_picture, attachment,attachment_name, status, + create_time,update_time, create_by, update_by, disabled </sql> + <select id="getDetailById" resultType="com.ruoyi.system.vo.TFaultRepairMessageVO"> + SELECT + t.id, + t.tenant_id, + t.item_id, + t.item_type_id, + t.contract_id, + t.fault_area_name, + t.describe_name, + t.describe_detail, + t.fault_pictures, + t.service_address, + t.repair_type, + t.visit_time, + t.contact_number, + t.leave_message, + t.handle_person, + t.handle_time, + t.result_describe, + t.repair_picture, + t.attachment, + t.attachment_name, + t.status, + t.create_time, + t.update_time, + t.create_by, + t.update_by, + t.disabled, + i.item_name AS itemName, + it.type_name AS itemTypeName, + tnt.resident_name AS residentName + from t_fault_repair_message t + LEFT JOIN t_item i ON t.item_id = i.id + LEFT JOIN t_item_type it ON t.item_type_id = it.id + LEFT JOIN t_tenant tnt ON t.tenant_id = tnt.id + WHERE t.id = #{id} + </select> + <select id="pageList" resultType="com.ruoyi.system.vo.TFaultRepairMessageVO"> + SELECT + t.id, + t.tenant_id, + t.item_id, + t.item_type_id, + t.contract_id, + t.fault_area_name, + t.describe_name, + t.describe_detail, + t.fault_pictures, + t.service_address, + t.repair_type, + t.visit_time, + t.contact_number, + t.leave_message, + t.handle_person, + t.handle_time, + t.result_describe, + t.repair_picture, + t.attachment, + t.attachment_name, + t.status, + t.create_time, + t.update_time, + t.create_by, + t.update_by, + t.disabled, + i.item_name AS itemName, + it.type_name AS itemTypeName, + tnt.resident_name AS residentName + from t_fault_repair_message t + LEFT JOIN t_item i ON t.item_id = i.id + LEFT JOIN t_item_type it ON t.item_type_id = it.id + LEFT JOIN t_tenant tnt ON t.tenant_id = tnt.id + <where> + <if test="query.tenantId != null and query.tenantId != ''"> + AND t.tenant_id = #{query.tenantId} + </if> + <if test="query.contactNumber != null and query.contactNumber != ''"> + AND t.contact_number LIKE CONCAT('%', #{query.contactNumber}, '%') + </if> + <if test="query.status != null"> + AND t.status = #{query.status} + </if> + <if test="query.repairType != null"> + AND t.repair_type = #{query.repairType} + </if> + <if test="query.handlePerson != null and query.handlePerson != ''"> + AND t.handle_person LIKE CONCAT('%', #{query.handlePerson}, '%') + </if> + AND t.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} + </where> + ORDER BY t.create_time DESC + </select> </mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TItemMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TItemMapper.xml index 84d057e..7a03ea8 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TItemMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TItemMapper.xml @@ -22,7 +22,7 @@ </sql> <select id="pageList" resultType="com.ruoyi.system.vo.TItemVO"> select - t.id, t.type_id, t.item_name, t.sort_by, t.pictures, t.create_time, t.update_time, t.create_by, t.update_by, t.disabled + t.id, t.type_id, t.item_name, t.sort_by, t.pictures, t.create_time, t.update_time, t.create_by, t.update_by, t.disabled, tt.type_name from t_item t left join t_item_type tt on t.type_id = tt.id diff --git a/ruoyi-system/src/main/resources/mapper/system/TItemTypeMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TItemTypeMapper.xml index 51d9e9a..4f0c44e 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TItemTypeMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TItemTypeMapper.xml @@ -25,5 +25,12 @@ where disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} ORDER BY sort_by,create_time DESC </select> + <select id="getItemList" resultType="com.ruoyi.system.vo.TItemTypeVO"> + select + <include refid="Base_Column_List"/> + from t_item_type + where disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} + ORDER BY sort_by,create_time DESC + </select> </mapper> -- Gitblit v1.7.1