generator/src/main/java/com/ruoyi/system/controller/TOrderBillController.java
File was deleted generator/src/main/java/com/ruoyi/system/controller/TPayOrderController.java
File was deleted generator/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java
File was deleted generator/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java
File was deleted generator/src/main/java/com/ruoyi/system/model/TOrderBill.java
File was deleted generator/src/main/java/com/ruoyi/system/model/TPayOrder.java
File was deleted generator/src/main/java/com/ruoyi/system/service/TOrderBillService.java
File was deleted generator/src/main/java/com/ruoyi/system/service/TPayOrderService.java
File was deleted generator/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java
File was deleted generator/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java
File was deleted generator/src/main/resources/mapping/TBankFlowMapper.xml
File was deleted generator/src/main/resources/mapping/TOrderBillMapper.xml
File was deleted generator/src/main/resources/mapping/TPayOrderMapper.xml
File was deleted generator/src/test/java/com/xizang/CodeGeneratorTests.java
@@ -35,7 +35,7 @@ // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = "D:\\畅云\\项目\\xizangweb\\xizang\\generator"; String projectPath = "F:\\workSpace\\xizang\\generator"; gc.setOutputDir(projectPath + "/src/main/java") .setAuthor("xiaochen") .setMapperName("%sMapper") ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillConfirmController.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.web.controller.api; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 账单线下缴费关联表 前端控制器 * </p> * * @author xiaochen * @since 2025-02-10 */ @RestController @RequestMapping("/t-bill-confirm") public class TBillConfirmController { } ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java
@@ -3,11 +3,14 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.service.TBillService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -34,6 +37,14 @@ return R.ok(pageInfo); } @PostMapping("add") public R<PageInfo<TBillDto>> add(@Validated @RequestBody TbillSaveDto bill){ tBillService.saveBill(bill); return R.ok(); } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillDetailController.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.web.controller.api; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 账单水电费子表 前端控制器 * </p> * * @author xiaochen * @since 2025-02-10 */ @RestController @RequestMapping("/t-bill-detail") public class TBillDetailController { } ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -37,6 +37,7 @@ import org.apache.poi.ss.usermodel.Workbook; 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.*; @@ -72,12 +73,15 @@ private TCheckAcceptRecordService checkAcceptRecordService; @ApiOperation(value = "获取合同分页列表") @PostMapping(value = "/contractList") @PreAuthorize("@ss.hasPermi('system:contract:list')") public R<PageInfo<TContract>> contractList(@RequestBody TContractQuery query) { return R.ok(contractService.contractList(query)); } @Log(title = "合同管理-新增合同", businessType = BusinessType.INSERT) @ApiOperation(value = "新增合同") @PostMapping(value = "/addContract") @PreAuthorize("@ss.hasPermi('system:contract:add')") public R<Boolean> addContract(@Validated @RequestBody TContractDTO dto) { contractService.save(dto); if (dto.getIsIncreasing()){ @@ -210,17 +214,13 @@ String url = wordUtil.generatePdf("/templates", "1_yzj_租赁合同.xml", templateParam, "租赁合同", "E:\\"); return R.ok(url); } @ApiOperation(value = "导出") @PostMapping("/export") public void export(@RequestBody TContractQuery query){ contractService.export(query); } /** * 光缆巡检列表导出 */ @ApiOperation(value = "光缆巡检列表导出") @Log(title = "现场作业-光缆巡检列表导出", businessType = BusinessType.EXPORT) @PostMapping("/exportOpticalInspection") @ApiOperation(value = "导出") @Log(title = "导出", businessType = BusinessType.EXPORT) @PostMapping("/export") public void exportOpticalInspection(@RequestBody TContractQuery query) { List<ContractExport> contractExports = new ArrayList<>(); ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java
@@ -6,7 +6,6 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.dto.TDeptUpAndDownDTO; ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java
@@ -22,6 +22,7 @@ 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.security.access.prepost.PreInvocationAuthorizationAdviceVoter; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -45,18 +46,21 @@ @Log(title = "房屋基础信息管理-新增房屋", businessType = BusinessType.INSERT) @ApiOperation(value = "新增房屋") @PostMapping(value = "/addHouse") @PreAuthorize("@ss.hasPermi('system:house:add')") public R<Boolean> addHouse(@Validated @RequestBody THouseDTO dto) { return R.ok(tHouseService.save(dto)); } @Log(title = "房屋基础信息管理-编辑房屋", businessType = BusinessType.UPDATE) @ApiOperation(value = "编辑房屋") @PostMapping(value = "/updateHouse") @PreAuthorize("@ss.hasPermi('system:house:edit')") public R<Boolean> updateHouse(@Validated @RequestBody THouseDTO dto) { return R.ok(tHouseService.updateById(dto)); } @Log(title = "房屋基础信息管理-查询房屋信息", businessType = BusinessType.DELETE) @ApiOperation(value = "查询房屋信息") @GetMapping(value = "/getHouseById") @PreAuthorize("@ss.hasPermi('system:house:detail')") public R<THouse> getHouseById(@RequestParam String id) { THouse tHouse = tHouseService.getById(id); tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); @@ -66,16 +70,21 @@ @Log(title = "房屋基础信息管理-删除房屋", businessType = BusinessType.DELETE) @ApiOperation(value = "删除房屋") @DeleteMapping(value = "/deleteHouseById") @PreAuthorize("@ss.hasPermi('system:house:delete')") public R<Boolean> deleteHouseById(@RequestParam String id) { return R.ok(tHouseService.removeById(id)); } @ApiOperation(value = "获取房屋分页列表") @PostMapping(value = "/houseList") @PreAuthorize("@ss.hasPermi('system:house:list')") public R<PageInfo<THouse>> houseList(@RequestBody THouseQuery query) { return R.ok(tHouseService.houseList(query)); } @ApiOperation(value = "历史租户列表") @PostMapping(value = "/userHistoryList") @PreAuthorize("@ss.hasPermi('system:house:historyList')") public R<PageInfo<HouseVO>> userHistoryList(@RequestBody TUserHistoryQuery query) { return R.ok(tHouseService.userHistoryList(query)); } ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
New file @@ -0,0 +1,183 @@ package com.ruoyi.web.controller.task; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TContract; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TContractService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; import java.util.stream.Collectors; /** * @author zhibing.pu * @date 2023/7/11 8:39 */ @Component public class TaskUtil { @Autowired private TContractService contractService; @Autowired private TBillService billService; // 每天凌晨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<>(); for (TContract contract : list) { contract.setFirstPayTime(contract.getStartTime().plusDays(10)); // 第一次应缴费日期 LocalDateTime firstPayTime = contract.getStartTime().plusDays(10); 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(); // 计算两个时间相差多少天 long days = ChronoUnit.DAYS.between(startPayTime, endTime1)+1L; // 如果时间小于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()); if ((contract.getEndTime().getYear() == contract.getStartTime().getYear()) && (contract.getEndTime().getMonth() == contract.getStartTime().getMonth())) { // 如果同年同月 那么账单周期为合同结束时间 rentBill.setEndTime(contract.getEndTime()); } else { // 否则 取当月最后一天 LocalDateTime endTime = contract.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).withSecond(59).withHour(23).withMinute(59); rentBill.setEndTime(endTime); } // 租金账单 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点执行的定时任务 用于生成合同期最后一笔账单 @Scheduled(cron = "0 0 0 * * ?") public void dayOfEndBill() { try { // 查询所有已签订的合同并且已经生成第一笔账单的 List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4).isNotNull(TContract::getFirstPayTime).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()))&&beforeBill.getEndTime().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())){ TBill tBill = new TBill(); tBill.setContractId(contract.getId()); tBill.setContractNumber(contract.getContractNumber()); tBill.setPayableFeesMoney(contract.getMonthRent()); tBill.setPayableFeesTime(LocalDateTime.now()); tBill.setPayFeesStatus("1"); tBill.setBillType("1"); tBill.setStartTime(beforeBill.getEndTime().plusMonths(1).with(TemporalAdjusters.firstDayOfMonth())); tBill.setEndTime(contract.getEndTime()); bills.add(tBill); } } billService.saveBatch(bills); } catch (Exception e) { e.printStackTrace(); } } // 每月15号凌晨执行的定时任务 用于生成租金账单 @Scheduled(cron = "0 0 0 15 * ?") public void monthOfBill() { try { // 查询所有已签订的合同 且合同时间大于15号 List<TContract> list = contractService.lambdaQuery().eq(TContract::getStatus, 4) .isNotNull(TContract::getFirstPayTime) .ge(TContract::getEndTime, LocalDateTime.now()) .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(1).with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime())){ TBill tBill = new TBill(); tBill.setContractId(contract.getId()); tBill.setContractNumber(contract.getContractNumber()); tBill.setPayableFeesMoney(contract.getMonthRent()); tBill.setPayableFeesTime(LocalDateTime.now()); 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) { LocalDateTime now = LocalDateTime.now().minusMonths(1).withDayOfMonth(31); System.err.println(now); LocalDateTime now2 = now.plusMonths(1); System.err.println(now2); LocalDateTime now1 = LocalDateTime.now(); long days = ChronoUnit.DAYS.between(now, now1); long days2 = ChronoUnit.DAYS.between(now.plusDays(1), now1); System.err.println(days); System.err.println(days2); // LocalDateTime endTime = now.with(TemporalAdjusters.lastDayOfMonth()).withSecond(59).withHour(23).withMinute(59); // // System.err.println(endTime); } } ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/PayController.java
@@ -1,17 +1,30 @@ package com.ruoyi.web.controller.api; import cn.hutool.core.collection.CollectionUtil; import com.ruoyi.common.constant.AmountConstant; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.dto.MakeOrderDto; import com.ruoyi.system.dto.MakeOrderResp; import com.ruoyi.system.dto.OfflinePayDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillConfirm; import com.ruoyi.system.service.TBillConfirmService; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TPayOrderService; import io.swagger.annotations.ApiOperation; import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Collections; import java.util.List; @RestController @RequestMapping("/t-pay") @@ -22,6 +35,12 @@ @Autowired TPayOrderService tPayOrderService; @Autowired TBillService tBillService; @Autowired TBillConfirmService tBillConfirmService; @ApiOperation(value = "创建支付订单") @PostMapping("makeOrder") public R<MakeOrderResp> makeOrder(@Validated @RequestBody MakeOrderDto dto){ @@ -30,6 +49,23 @@ } @PostMapping("offlinePay") public R offlinePay(@Validated @RequestBody OfflinePayDto dto){ List<TBill> tBills = tBillService.listByIds(dto.getBillIds()); for (TBill tBill : tBills) { TBill save = new TBill(); save.setId(tBill.getId()); save.setPayFeesType(2); save.setVoucher(dto.getVoucher()); save.setPayFeesStatus("2"); tBillService.lockAndUpdateInfo(save); } TBillConfirm confirm = new TBillConfirm(); confirm.setBillId(CollectionUtil.join(dto.getBillIds(),",")); confirm.setVoucher(dto.getVoucher()); confirm.setPayFeesMoney(new BigDecimal(dto.getAmount()).divide(AmountConstant.b100).setScale(2, RoundingMode.HALF_DOWN).doubleValue()); tBillConfirmService.save(confirm); return R.ok(); } } ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillConfirmController.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.web.controller.api; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 账单线下缴费关联表 前端控制器 * </p> * * @author xiaochen * @since 2025-02-10 */ @RestController @RequestMapping("/t-bill-confirm") public class TBillConfirmController { } ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java
@@ -1,18 +1,30 @@ package com.ruoyi.web.controller.api; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TInvoiceDTO; import com.ruoyi.system.model.*; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.service.TBillDetailService; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TInvoiceService; import com.ruoyi.system.service.TInvoiceToBillService; import com.ruoyi.system.vo.TBillVO; 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.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; /** * <p> @@ -22,13 +34,21 @@ * @author xiaochen * @since 2025-01-17 */ @Api(tags = "缴费账单") @RestController @RequestMapping("/t-bill") public class TBillController { @Autowired TBillService tBillService; @Autowired TBillDetailService billDetailService; @Autowired TInvoiceService invoiceService; @Autowired TInvoiceToBillService invoiceToBillService; @ApiOperation(value = "缴费账单查询分页列表") @PostMapping("list") public R<PageInfo<TBillDto>> list(@RequestBody TBillQuery query){ if (StringUtils.isEmpty(query.getUserId())){ @@ -38,6 +58,43 @@ return R.ok(pageInfo); } @ApiOperation(value = "查看缴费账单详情") @GetMapping(value = "/getDetailById") public R<TBillVO> getDetailById(@RequestParam String id) { TBill bill = tBillService.getById(id); TBillVO billVO = new TBillVO(); BeanUtils.copyProperties(bill, billVO); // 查询水电费列表 if("3".equals(bill.getBillType())){ List<TBillDetail> list = billDetailService.list(Wrappers.lambdaQuery(TBillDetail.class) .eq(TBillDetail::getBillId, id)); billVO.setBillDetailList(list); } billVO.setBillType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BILL_TYPE,billVO.getBillType())); billVO.setPayFeesStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_PAY_FEES_STATUS,billVO.getPayFeesStatus())); return R.ok(billVO); } @ApiOperation(value = "缴费账单开票") @PostMapping(value = "/invoice") public R<String> invoice(@RequestBody TInvoiceDTO dto) { // 添加开票信息 invoiceService.save(dto); // 添加开票信息中间表信息 List<String> billIds = dto.getBillIds(); List<TInvoiceToBill> sysInvoiceToBills = new ArrayList<>(); for (String billId : billIds) { TInvoiceToBill tInvoiceToBill = new TInvoiceToBill(); tInvoiceToBill.setInvoiceId(dto.getId()); tInvoiceToBill.setBillId(billId); sysInvoiceToBills.add(tInvoiceToBill); } invoiceToBillService.saveBatch(sysInvoiceToBills); return R.ok(); } } ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java
@@ -1,6 +1,17 @@ package com.ruoyi.web.controller.api; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.R; 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; @@ -13,9 +24,25 @@ * @author xiaochen * @since 2025-01-17 */ @Api(tags = "资讯管理") @RestController @RequestMapping("/t-information") public class TInformationController { private final TInformationService informationService; @Autowired public TInformationController(TInformationService informationService) { this.informationService = informationService; } /** * 获取资讯管理管理列表 */ @ApiOperation(value = "获取资讯管理分页列表") @PostMapping(value = "/pageList") public R<PageInfo<TInformation>> pageList(@RequestBody TInformationQuery query) { return R.ok(informationService.pageList(query)); } } ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
@@ -66,7 +66,7 @@ @PostMapping("/list") public AjaxResult list(@RequestBody SysRoleQuery query) { PageInfo<SysRole> list = roleService.selectList(query); PageInfo<SysRole> list = roleService.selectPageList(query); return AjaxResult.success(list); } ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java
@@ -39,4 +39,8 @@ * 缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期 5=已失效 */ public static final String DICT_TYPE_PAY_FEES_STATUS = "t_pay_fees_status"; /** * 账单类型 1=租金 2=押金 3=生活费用 */ public static final String DICT_TYPE_BILL_TYPE = "t_bill_type"; } ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
@@ -1,16 +1,14 @@ package com.ruoyi.common.core.redis; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.*; import java.util.concurrent.TimeUnit; 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.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.RedisScript; import org.springframework.stereotype.Component; /** @@ -22,6 +20,15 @@ @Component public class RedisCache { private static final String LOCK_PREFIX = "lock:"; private static final RedisScript<Long> UNLOCK_SCRIPT = new DefaultRedisScript<>( "if redis.call('get', KEYS[1]) == ARGV[1] then " + " return redis.call('del', KEYS[1]) " + "else " + " return 0 " + "end", Long.class ); @Autowired public RedisTemplate redisTemplate; @@ -265,4 +272,33 @@ { return redisTemplate.keys(pattern); } /** * 尝试加锁 * * @param lockKey 锁的key * @param requestId 锁的持有者标识符(如UUID) * @param expireTime 锁的过期时间(秒) * @return 加锁成功返回true,否则返回false */ public boolean tryLock(String lockKey, String requestId, long expireTime) { String lockKeyWithPrefix = LOCK_PREFIX + lockKey; // 使用SET命令的NX和PX选项来加锁 Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKeyWithPrefix, requestId, expireTime, TimeUnit.SECONDS); return result != null && result; } /** * 解锁 * * @param lockKey 锁的key * @param requestId 锁的持有者标识符(如UUID) * @return 解锁成功返回true,否则返回false */ public boolean unlock(String lockKey, String requestId) { String lockKeyWithPrefix = LOCK_PREFIX + lockKey; // 使用Lua脚本来验证锁的持有者并解锁 Long result = (Long) redisTemplate.execute(UNLOCK_SCRIPT, Collections.singletonList(lockKeyWithPrefix), requestId); return result != null && result == 1L; } } ruoyi-system/src/main/java/com/ruoyi/system/dto/OfflinePayDto.java
New file @@ -0,0 +1,36 @@ package com.ruoyi.system.dto; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.io.Serializable; import java.util.List; @Data public class OfflinePayDto implements Serializable { /** * 用户ID */ @ApiModelProperty(value = "用户ID") private String userId; @ApiModelProperty(value = "支付金额,单位:分") @NotNull(message = "金额不能为空") private Long amount; /** * 账单列表 */ @ApiModelProperty(value = "账单列表") @NotEmpty(message = "账单ID不能为空") private List<String> billIds; /** * 凭证文件ID */ @ApiModelProperty(value = "凭证文件ID") @NotEmpty(message = "凭证文件不能为空") private String voucher; } ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java
@@ -16,4 +16,5 @@ private String houseName; } ruoyi-system/src/main/java/com/ruoyi/system/dto/TInvoiceDTO.java
New file @@ -0,0 +1,17 @@ package com.ruoyi.system.dto; import com.ruoyi.system.model.TInvoice; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; @Data @ApiModel(value = "开票DTO") public class TInvoiceDTO extends TInvoice { @ApiModelProperty(value = "账单id集合") private List<String> billIds; } ruoyi-system/src/main/java/com/ruoyi/system/dto/TbillSaveDto.java
New file @@ -0,0 +1,17 @@ package com.ruoyi.system.dto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillDetail; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; import java.util.List; @Data public class TbillSaveDto extends TBill implements Serializable { @ApiModelProperty(value = "水单费列表") private List<TBillDetail> details; } ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillConfirmMapper.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.system.model.TBillConfirm; /** * <p> * 账单线下缴费关联表 Mapper 接口 * </p> * * @author xiaochen * @since 2025-02-10 */ public interface TBillConfirmMapper extends BaseMapper<TBillConfirm> { } ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillDetailMapper.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.system.model.TBillDetail; /** * <p> * 账单水电费子表 Mapper 接口 * </p> * * @author xiaochen * @since 2025-02-10 */ public interface TBillDetailMapper extends BaseMapper<TBillDetail> { } ruoyi-system/src/main/java/com/ruoyi/system/mapper/TInvoiceToBillMapper.java
@@ -1,7 +1,7 @@ package com.ruoyi.system.mapper; import com.ruoyi.system.model.TInvoiceToBill; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.system.model.TInvoiceToBill; /** * <p> ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java
@@ -8,6 +8,7 @@ import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableField; import java.io.Serializable; import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.domain.BaseModel; @@ -16,6 +17,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.data.annotation.Transient; /** * <p> ruoyi-system/src/main/java/com/ruoyi/system/model/TBillConfirm.java
New file @@ -0,0 +1,46 @@ package com.ruoyi.system.model; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; /** * <p> * 账单线下缴费关联表 * </p> * * @author xiaochen * @since 2025-02-10 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_bill_confirm") @ApiModel(value="TBillConfirm对象", description="账单线下缴费关联表") public class TBillConfirm implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.ASSIGN_ID) private String id; @ApiModelProperty(value = "账单id,逗号分隔") @TableField("bill_id") private String billId; @ApiModelProperty(value = "缴费金额") @TableField("pay_fees_money") private Double payFeesMoney; @ApiModelProperty(value = "凭证上传") @TableField("voucher") private String voucher; } ruoyi-system/src/main/java/com/ruoyi/system/model/TBillDetail.java
New file @@ -0,0 +1,64 @@ package com.ruoyi.system.model; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.domain.BaseModel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; /** * <p> * 账单水电费子表 * </p> * * @author xiaochen * @since 2025-02-10 */ @Data @EqualsAndHashCode(callSuper = false) @TableName("t_bill_detail") @ApiModel(value="TBillDetail对象", description="账单水电费子表") public class TBillDetail extends BaseModel { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.ASSIGN_ID) private String id; @ApiModelProperty(value = "账单id") @TableField("bill_id") private String billId; @ApiModelProperty(value = "初始读数") @TableField("start_reading") private BigDecimal startReading; @ApiModelProperty(value = "结束读数") @TableField("end_reading") private BigDecimal endReading; @ApiModelProperty(value = "使用量") @TableField("usage_measure") private BigDecimal usageMeasure; @ApiModelProperty(value = "单价") @TableField("unit_price") private BigDecimal unitPrice; @ApiModelProperty(value = "总金额") @TableField("total_amount") private BigDecimal totalAmount; @ApiModelProperty(value = "费用类型 1=水费 2=电费") @TableField("live_type") private Integer liveType; } ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java
@@ -52,6 +52,10 @@ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("end_time") private LocalDateTime endTime; @ApiModelProperty(value = "开始计费时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("start_pay_time") private LocalDateTime startPayTime; @ApiModelProperty(value = "每月租金") @TableField("month_rent") @@ -65,7 +69,7 @@ @TableField("pay_type") private String payType; @ApiModelProperty(value = "第一次支付日期") @ApiModelProperty(value = "账单第一次支付日期 合同生效日期+10天 (不是真正的支付日期)生成第一次帐单后存值") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("first_pay_time") private LocalDateTime firstPayTime; ruoyi-system/src/main/java/com/ruoyi/system/model/TInvoiceToBill.java
@@ -1,13 +1,15 @@ package com.ruoyi.system.model; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import java.io.Serializable; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; /** * <p> @@ -25,7 +27,7 @@ private static final long serialVersionUID = 1L; @TableId("id") @TableId(value = "id", type = IdType.ASSIGN_ID) private String id; @ApiModelProperty(value = "开票id") ruoyi-system/src/main/java/com/ruoyi/system/service/TBillConfirmService.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.model.TBillConfirm; /** * <p> * 账单线下缴费关联表 服务类 * </p> * * @author xiaochen * @since 2025-02-10 */ public interface TBillConfirmService extends IService<TBillConfirm> { } ruoyi-system/src/main/java/com/ruoyi/system/service/TBillDetailService.java
New file @@ -0,0 +1,16 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.model.TBillDetail; /** * <p> * 账单水电费子表 服务类 * </p> * * @author xiaochen * @since 2025-02-10 */ public interface TBillDetailService extends IService<TBillDetail> { } ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; @@ -18,4 +19,7 @@ PageInfo<TBillDto> queryPage(TBillQuery query); Boolean lockAndUpdateInfo(TBill save); void saveBill(TbillSaveDto bill); } ruoyi-system/src/main/java/com/ruoyi/system/service/TDeptService.java
@@ -1,7 +1,6 @@ package com.ruoyi.system.service; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.dto.TDeptUpAndDownDTO; import com.ruoyi.system.model.TDept; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.query.TDeptQuery; ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceToBillService.java
@@ -1,5 +1,7 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.model.TInvoiceToBill; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TInvoice; import com.ruoyi.system.model.TInvoiceToBill; @@ -18,6 +20,7 @@ * @since 2025-02-10 */ public interface TInvoiceToBillService extends IService<TInvoiceToBill> { List<TInvoiceToBill> makeQuery(TInvoiceToBillQuery query); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillConfirmServiceImpl.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.mapper.TBillConfirmMapper; import com.ruoyi.system.model.TBillConfirm; import com.ruoyi.system.service.TBillConfirmService; import org.springframework.stereotype.Service; /** * <p> * 账单线下缴费关联表 服务实现类 * </p> * * @author xiaochen * @since 2025-02-10 */ @Service public class TBillConfirmServiceImpl extends ServiceImpl<TBillConfirmMapper, TBillConfirm> implements TBillConfirmService { } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillDetailServiceImpl.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.mapper.TBillDetailMapper; import com.ruoyi.system.model.TBillDetail; import com.ruoyi.system.service.TBillDetailService; import org.springframework.stereotype.Service; /** * <p> * 账单水电费子表 服务实现类 * </p> * * @author xiaochen * @since 2025-02-10 */ @Service public class TBillDetailServiceImpl extends ServiceImpl<TBillDetailMapper, TBillDetail> implements TBillDetailService { } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java
@@ -4,17 +4,23 @@ import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.mapper.TBillMapper; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillDetail; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.THouse; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.service.TBillDetailService; import com.ruoyi.system.service.TBillService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import io.jsonwebtoken.lang.Assert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; @@ -35,6 +41,10 @@ @Autowired TBillMapper tBillMapper; @Autowired TBillDetailService tBillDetailService; public PageInfo<TBillDto> queryPage(TBillQuery query){ PageInfo<TBill> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); PageInfo<TBillDto> info = tBillMapper.page(pageInfo, query); @@ -42,17 +52,32 @@ } /** * 传的金额 * @param tBill * @return */ public Boolean checkAndUpdateBill(TBill tBill){ public Boolean lockAndUpdateInfo(TBill tBill){ if (StringUtils.isEmpty(tBill.getId())){ throw new ServiceException("账单主键ID不能为空"); } return true; } @Override @Transactional(rollbackFor = Exception.class) public void saveBill(TbillSaveDto bill) { save(bill); if (bill.getBillType().equals("3")){ if (bill.getDetails()==null || bill.getDetails().size()==0){ throw new ServiceException("生活费用列表不能为空"); } for (TBillDetail detail : bill.getDetails()) { detail.setBillId(bill.getId()); tBillDetailService.save(detail); } } } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TDeptServiceImpl.java
@@ -3,7 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.TDeptUpAndDownDTO; import com.ruoyi.system.mapper.SysMenuMapper; import com.ruoyi.system.model.TDept; import com.ruoyi.system.mapper.TDeptMapper; import com.ruoyi.system.query.TDeptQuery; @@ -13,7 +13,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.List; /** @@ -27,6 +26,8 @@ @Service public class TDeptServiceImpl extends ServiceImpl<TDeptMapper, TDept> implements TDeptService { @Autowired private SysMenuMapper sysMenuMapper; @Override public boolean isExit(TDept dto) { if(StringUtils.isNotEmpty(dto.getDeptId())){ @@ -46,4 +47,5 @@ return pageInfo; } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceToBillServiceImpl.java
@@ -12,6 +12,12 @@ import java.util.List; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.mapper.TInvoiceToBillMapper; import com.ruoyi.system.model.TInvoiceToBill; import com.ruoyi.system.service.TInvoiceToBillService; import org.springframework.stereotype.Service; /** * <p> * 账单开票中间表 服务实现类 ruoyi-system/src/main/java/com/ruoyi/system/vo/TBillVO.java
New file @@ -0,0 +1,18 @@ package com.ruoyi.system.vo; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TBillDetail; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; @Data @ApiModel(value = "缴费账单VO") public class TBillVO extends TBill { @ApiModelProperty(value = "水电费明细") private List<TBillDetail> billDetailList; } ruoyi-system/src/main/resources/mapper/system/TBillConfirmMapper.xml
New file @@ -0,0 +1,18 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.system.mapper.TBillConfirmMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TBillConfirm"> <id column="id" property="id" /> <result column="bill_id" property="billId" /> <result column="pay_fees_money" property="payFeesMoney" /> <result column="voucher" property="voucher" /> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> id, bill_id, pay_fees_money, voucher </sql> </mapper> ruoyi-system/src/main/resources/mapper/system/TBillDetailMapper.xml
New file @@ -0,0 +1,27 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.system.mapper.TBillDetailMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TBillDetail"> <id column="id" property="id" /> <result column="bill_id" property="billId" /> <result column="start_reading" property="startReading" /> <result column="end_reading" property="endReading" /> <result column="usage_measure" property="usageMeasure" /> <result column="unit_price" property="unitPrice" /> <result column="total_amount" property="totalAmount" /> <result column="live_type" property="liveType" /> <result column="create_time" property="createTime" /> <result column="update_time" property="updateTime" /> <result column="create_by" property="createBy" /> <result column="update_by" property="updateBy" /> <result column="disabled" property="disabled" /> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> id, bill_id, start_reading, end_reading, usage_measure, unit_price, total_amount,live_type, create_time, update_time, create_by, update_by, disabled </sql> </mapper> ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml
@@ -42,10 +42,11 @@ h.house_name as houseName FROM t_bill b LEFT JOIN t_contract c ON c.contract_number = b.contract_number LEFT JOIN t_house h ON h.id = c.house_id LEFT JOIN t_tenant t ON t.id = c.tenant_id LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0 LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0 LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0 <where> b.disabled=0 <if test="query.payFeesStatus != null"> and b.pay_fees_status = #{query.payFeesStatus} </if> ruoyi-system/src/main/resources/mapper/system/TInvoiceToBillMapper.xml
New file @@ -0,0 +1,17 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.system.mapper.TInvoiceToBillMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TInvoiceToBill"> <id column="id" property="id" /> <result column="invoice_id" property="invoiceId" /> <result column="bill_id" property="billId" /> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> id, invoice_id, bill_id </sql> </mapper>