From 1e1d0497cc600cc10c22c217b35fb3c43a1e024f Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期五, 21 三月 2025 14:08:06 +0800 Subject: [PATCH] Merge branch 'master' of https://gitee.com/xiaochen991015/xizang --- ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java | 30 ++ ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java | 66 ++-- ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml | 5 ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml | 11 ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java | 17 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java | 16 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java | 50 +++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java | 129 ++++++++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java | 2 ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java | 22 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java | 78 +++++ ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java | 41 ++ ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java | 1 ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java | 19 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java | 5 ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml | 14 ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java | 38 ++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java | 43 ++ ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java | 54 +++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java | 20 + ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java | 23 + ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java | 22 + ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java | 5 ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java | 16 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java | 18 + ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java | 3 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java | 31 + ruoyi-system/src/main/java/com/ruoyi/system/model/TTenant.java | 18 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java | 7 ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java | 9 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java | 63 ---- ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java | 21 + 32 files changed, 759 insertions(+), 138 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java new file mode 100644 index 0000000..86431c2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ScreenController.java @@ -0,0 +1,78 @@ +package com.ruoyi.web.controller.api; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.service.TContractService; +import com.ruoyi.system.service.impl.ScreenService; +import com.ruoyi.system.vo.ScreenRentIncomeTrendVO; +import com.ruoyi.system.vo.ScreenRentRankVO; +import com.ruoyi.system.vo.ScreenTopStaticsDataVO; +import com.ruoyi.system.vo.TenantCountTrendVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author mitao + * @date 2025/3/19 + */ +@Api(tags = {"大屏相关接口"}) +@RestController +@RequestMapping("/screen") +@RequiredArgsConstructor(onConstructor_ = {@Lazy}) +public class ScreenController { + private final ScreenService screenService; + @GetMapping("/statics-data") + @ApiOperation(value = "获取顶部统计数据") + public R<ScreenTopStaticsDataVO> getTopStaticsData() { + return R.ok(screenService.getTopStaticsData()); + } + @GetMapping("/rent-rank") + @ApiOperation("区域租金排名") + public R<List<ScreenRentRankVO>> rentRank() { + return R.ok(screenService.streetRentRank()); + } + @GetMapping("/rent-income-trend") + @ApiOperation("租金收入趋势") + public R<ScreenRentIncomeTrendVO> rentIncomeTrend() { + return R.ok(screenService.rentIncomeTrend()); + } + private final TContractService contractService; + + + @GetMapping("/getTenantCountTrend") + @ApiModelProperty(value = "租户数量趋势统计") + public R<?> getTenantCountTrend() { + // 获取所有签约时间不为空的合同 + List<TContract> contracts = contractService.list(new LambdaQueryWrapper<TContract>() + .isNotNull(TContract::getSignTime)); + + // 使用年-月格式化日期,并按此分组计算每个时间段的合同数量 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy-M"); + + List<TenantCountTrendVO> trendData = contracts.stream() + .collect(Collectors.groupingBy(contract -> contract.getSignTime().toLocalDate() + .withDayOfMonth(1) // 将日期调整为该月的第一天,以便正确分组 + .atStartOfDay())) + .entrySet().stream() + .map(entry -> { + String period = entry.getKey().format(formatter); + long count = entry.getValue().size(); + return new TenantCountTrendVO(period, count); + }) + .collect(Collectors.toList()); + + return R.ok(trendData); + } + +} 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 8a363c6..514ee6f 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 @@ -80,6 +80,8 @@ private StateProcessTemplateService stateProcessTemplateService; @Autowired private FlwTaskMapper flwTaskMapper; + @Autowired + private TTenantService tenantService; @ApiOperation(value = "获取合同分页列表") @PostMapping(value = "/contractList") @@ -295,13 +297,25 @@ List<TContract> list = contractService.lambdaQuery().in(TContract::getId, dto.getIds()).list(); List<String> res = new ArrayList<>(); for (TContract contract : list) { + String templateFileName = "1_yzj_租赁合同_个人.docx"; TBill firstBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()) .orderByDesc(TBill::getStartTime).last("limit 1").one(); - + TTenant tenant = tenantService.getById(contract.getTenantId()); THouse tHouse = houseService.getById(contract.getHouseId()); Map<String, Object> templateParam = new HashMap<>(5); + templateParam.put("${contractNumber}", contract.getContractNumber()); templateParam.put("${partyOneName}", contract.getPartyOneName()); templateParam.put("${partyTwoName}", contract.getPartyTwoName()); + if (Objects.nonNull(tenant)) { + templateParam.put("${mailAddress}", StringUtils.isNotBlank(tenant.getMailAddress()) ? tenant.getMailAddress() : ""); + templateParam.put("${idCard}", StringUtils.isNotBlank(tenant.getIdCard()) ? tenant.getIdCard() : ""); + //企业、政府机构、国有企业 + if (tenant.getTenantType().equals("2") || tenant.getTenantType().equals("5") || tenant.getTenantType().equals("7")){ + templateParam.put("${creditCode}", StringUtils.isNotBlank(tenant.getCreditCode()) ? tenant.getCreditCode() : ""); + templateParam.put("${legalPerson}", StringUtils.isNotBlank(tenant.getLegalPerson()) ? tenant.getLegalPerson() : ""); + templateFileName = "1_yzj_租赁合同_企业.docx"; + } + } templateParam.put("${houseAddress}", tHouse.getHouseAddress()); templateParam.put("${houseArea}", tHouse.getHouseArea()+"m²"); long between = ChronoUnit.DAYS.between(contract.getStartTime(), contract.getStartPayTime())+1; @@ -339,7 +353,7 @@ templateParam.put("${checkTime}", ""); } - String url = wordUtil.generatePdf("/usr/local/project/file/", "1_yzj_租赁合同.docx", templateParam, "租赁合同", "/usr/local/project/file/"); + String url = wordUtil.generatePdf("/usr/local/project/file/", templateFileName, templateParam, "租赁合同", "/usr/local/project/file/"); res.add(url); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java index 157d180..02fb59c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java @@ -12,10 +12,16 @@ import com.ruoyi.system.query.TInvoiceQuery; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TInvoiceService; +import com.ruoyi.web.controller.tool.TencentCosUtil; 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.*; + +import javax.servlet.http.HttpServletResponse; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; /** @@ -33,6 +39,8 @@ private TInvoiceService invoiceService; @Autowired TBillService tBillService; + @Autowired + TencentCosUtil tencentCosUtil; @PreAuthorize("@ss.hasPermi('invoice:list')") @ApiOperation(value = "获取开票列表") @PostMapping("/list") @@ -58,7 +66,51 @@ @PostMapping("/uploadVoucher") @PreAuthorize("@ss.hasPermi('invoice:list:payment')") public R<Boolean> uploadVoucher(@RequestBody TInvoiceQuery query) { - return R.ok(invoiceService.uploadVoucher(query)); + String invoiceVoucher = query.getInvoiceVoucher(); + String invoiceVoucherName = query.getInvoiceVoucherName(); + if (invoiceVoucher == null || invoiceVoucherName == null) { + return R.fail("请上传发票文件"); + } + String[] voucherUrls = invoiceVoucher.split(","); + String[] voucherNames = invoiceVoucherName.split(","); + + // 确保两个数组长度一致 + int length = Math.min(voucherUrls.length, voucherNames.length); + if (length == 0) { + return R.fail("请上传发票文件"); + } + // 构建附件列表 + List<Map<String, String>> attachments = new ArrayList<>(length); + for (int i = 0; i < length; i++) { + String voucherUrl = voucherUrls[i]; + String fileName = voucherNames[i]; + Map<String, String> attachment = new HashMap<>(2); // 初始容量为2,避免扩容 + String tempDir = System.getProperty("java.io.tmpdir"); + Path filePath = Paths.get(tempDir, fileName); + // 保存到临时目录 + tencentCosUtil.download(voucherUrl,filePath.toString(),fileName); + + attachment.put("filePath", filePath.toString()); + attachment.put("fileName", fileName); + attachments.add(attachment); + } + return R.ok(invoiceService.uploadVoucher(query,attachments)); } } + + + + + + + + + + + + + + + + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java new file mode 100644 index 0000000..3f34a19 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TStreetController.java @@ -0,0 +1,50 @@ +package com.ruoyi.web.controller.api; + + +import com.google.common.collect.Lists; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.model.TStreet; +import com.ruoyi.system.service.ITStreetService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +/** + * <p> + * 街道 前端控制器 + * </p> + * + * @author mitao + * @since 2025-03-19 + */ +@Api(tags = {"街道相关接口"}) +@RestController +@RequestMapping("/t-street") +@RequiredArgsConstructor(onConstructor_ = {@Lazy}) +public class TStreetController { + private final ITStreetService tStreetService; + + @GetMapping("/list") + @ApiOperation(value = "获取街道列表") + public R<List<TStreet>> list() { + return R.ok(tStreetService.list()); + } + @GetMapping("/init") + @ApiOperation(value = "初始化街道列表") + public R<?> init(){ + ArrayList<String> strings = Lists.newArrayList("八廓街道", "吉日街道", "布达拉宫广场街道", "公德林街道", "扎细街道", "纳金街道", "娘热街道", "金珠西路街道", "堆龙德庆区东嘎街道", "两岛街道", "柳梧新区柳梧乡", "色拉街道", "蔡公堂街道", "娘热路街道", "夺底街道", "纳如街道"); + strings.forEach(streetName->{ + TStreet tStreet = new TStreet(); + tStreet.setStreetName(streetName); + tStreetService.save(tStreet); + }); + return R.ok(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java index 3133f3a..9a9ac21 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TencentCosUtil.java @@ -27,6 +27,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.Base64; import java.util.Date; import java.util.UUID; @@ -256,4 +261,29 @@ } + /** + * 将文件下载到指定目录 + * @param fileUrl + * @param saveDir + * @param fileName + * @throws IOException + */ + public void download(String fileUrl, String saveDir, String fileName){ + fileUrl = fileUrl.replace(cosConfig.getRootSrc(), ""); + // 下载文件并获取输入流 + COSObject object = cosClient.getObject(cosConfig.getBucketName(),fileUrl); + try ( + InputStream in = object.getObjectContent(); + ){ + Path targetPath = Paths.get(saveDir, fileName); + // 确保目录存在 + Files.createDirectories(targetPath.getParent()); + // 将文件保存到目标路径 + Files.copy(in, targetPath, StandardCopyOption.REPLACE_EXISTING); + }catch (IOException e){ + log.error("读取cos图片发生异常", e); + } + } + + } \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 3df99a9..cd58196 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -1,16 +1,21 @@ package com.ruoyi.common.utils; +import org.apache.commons.lang3.time.DateFormatUtils; + import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.time.*; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; - -import org.apache.commons.lang3.time.DateFormatUtils; /** * 时间工具类 @@ -267,7 +272,7 @@ cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, startMonth); cal.set(Calendar.DAY_OF_MONTH, 1); - cal.set(Calendar.HOUR, 0); + cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); Date first = cal.getTime(); @@ -279,9 +284,9 @@ cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, lastMonth); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); - cal.set(Calendar.HOUR, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); + cal.set(Calendar.HOUR_OF_DAY, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); Date last = cal.getTime(); map.put("last", last); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java index a6e40ba..64d39bb 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TencentMailUtil.java @@ -8,16 +8,18 @@ import javax.activation.DataHandler; import javax.activation.FileDataSource; -import java.net.URLEncoder; -import javax.activation.URLDataSource; +import javax.annotation.Resource; import javax.mail.*; import javax.mail.internet.*; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; -import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Properties; import java.util.concurrent.CompletableFuture; @@ -132,14 +134,43 @@ // 设置邮件标题 message.setSubject("发票"); // 创建邮件内容 - Multipart multipart = createMultipart(list); + Multipart multipart = new MimeMultipart(); + // 添加文本消息部分 + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setHeader("Content-Type", "text/plain;charset=utf-8"); + messageBodyPart.setContent("您在小程序提交的开票申请已开票成功,请查看附件内容","text/html;charset=UTF-8"); + multipart.addBodyPart(messageBodyPart); + List<Path> tempFilePath = new ArrayList<>(); + // 添加附件部分 + for (Map<String, String> map : list) { + messageBodyPart = new MimeBodyPart(); + String filePath = map.get("filePath"); + String fileName = map.get("fileName"); + tempFilePath.add(Paths.get(filePath)); + FileDataSource source = new FileDataSource(filePath); + messageBodyPart.setDataHandler(new DataHandler(source)); + String filenameEncode = MimeUtility.encodeText(fileName, "UTF-8", "base64"); + // String encodedFileName = Base64.getEncoder().encodeToString(fileName.getBytes(StandardCharsets.UTF_8)); + // String filenameEncode = MimeUtility.encodeText(encodedFileName); + messageBodyPart.setFileName(filenameEncode); + messageBodyPart.setHeader("Content-Transfer-Encoding", "base64"); + messageBodyPart.setHeader("Content-Disposition", "attachment"); + messageBodyPart.setHeader("Content-Type", "application/octet-stream;name=\"" + filenameEncode + "\""); + multipart.addBodyPart(messageBodyPart); + } // 设置邮件内容 message.setContent(multipart); // 发送邮件 Transport.send(message); + // 删除临时目录里面的文件 + for (Path path : tempFilePath) { + Files.deleteIfExists(path); + } } catch (MessagingException | UnsupportedEncodingException | MalformedURLException e) { log.error("发送邮件发生异常", e); throw new ServiceException("发送邮件失败, 请检查"); + } catch (IOException e) { + throw new RuntimeException("文件下载发生异常"); } } @@ -167,31 +198,6 @@ return new PasswordAuthentication(userName, password); } }; - } - - private Multipart createMultipart(List<Map<String, String>> list) throws MessagingException, UnsupportedEncodingException, MalformedURLException { - Multipart multipart = new MimeMultipart(); - // 添加文本消息部分 - BodyPart messageBodyPart = new MimeBodyPart(); - messageBodyPart.setHeader("Content-Type", "text/plain;charset=utf-8"); - messageBodyPart.setContent("您在小程序提交的开票申请已开票成功,请查看附件内容","text/html;charset=UTF-8"); - multipart.addBodyPart(messageBodyPart); - // 添加附件部分 - for (Map<String, String> map : list) { - messageBodyPart = new MimeBodyPart(); - String url = map.get("url"); - String fileName = map.get("fileName"); - URLDataSource source = new URLDataSource(new URL(url)); - messageBodyPart.setDataHandler(new DataHandler(source)); - String filenameEncode = MimeUtility.encodeText(fileName, "UTF-8", "base64"); - messageBodyPart.setFileName(filenameEncode); - messageBodyPart.setHeader("Content-Transfer-Encoding", "base64"); - messageBodyPart.setHeader("Content-Disposition", "attachment"); - messageBodyPart.setHeader("Content-Type", "application/octet-stream;name=\"" + filenameEncode + "\""); - multipart.addBodyPart(messageBodyPart); - } - - return multipart; } // public static void main(String[] args) throws UnsupportedEncodingException { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java index 357d516..d2e012a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java @@ -5,9 +5,9 @@ import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; +import com.ruoyi.system.vo.ScreenRentRankVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Select; import java.math.BigDecimal; import java.util.List; @@ -46,4 +46,9 @@ BigDecimal statisticsOverdue(); Integer batchBillCount(@Param("userId")String userId, @Param("billIds")List<String> billIds); + /** + * 街道租金排行 + * @return + */ + List<ScreenRentRankVO> getStreetRentRank(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java index 4be10f7..5a36e89 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java @@ -28,4 +28,9 @@ List<BillVO> contractBillList(@Param("query") TContractBillQuery query, @Param("pageInfo") PageInfo<BillVO> pageInfo); List<TContract> contractExportList(@Param("query")TContractQuery query); + /** + * 本月新增租户数 + * @return + */ + Integer getCurrentMonthRentCount(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java index 1cafeac..5c9afe1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/THouseMapper.java @@ -24,4 +24,5 @@ List<HouseVO> userHistoryList(@Param("req")TUserHistoryQuery query, @Param("pageInfo")PageInfo<HouseVO> pageInfo); + Double getHouseRentedArea(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java new file mode 100644 index 0000000..5b6275f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TStreetMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.model.TStreet; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * <p> + * 街道 Mapper 接口 + * </p> + * + * @author mitao + * @since 2025-03-19 + */ +public interface TStreetMapper extends BaseMapper<TStreet> { + +} 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 14257ff..39db30b 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 @@ -149,6 +149,15 @@ @ApiModelProperty(value = "合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算 9 = 签订待审核") @TableField("status") private String status; + + /** + * 签订时间 + */ + @ApiModelProperty(value = "签订时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @TableField("sign_time") + private LocalDateTime signTime; + @ApiModelProperty(value = "内存大小多个文件逗号拼接") @TableField("memory") private String memory; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java index 9a03ab2..eeffb53 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java @@ -1,18 +1,18 @@ package com.ruoyi.system.model; import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableId; -import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableField; -import java.io.Serializable; - +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; 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 java.math.BigDecimal; +import java.time.LocalDateTime; /** * <p> @@ -94,4 +94,16 @@ @ApiModelProperty(value = "住户类型 1月租 2季租 3年租") @TableField(exist = false) private String tenantType; + + @ApiModelProperty(value = "所属街道id") + @TableField("street_id") + private String streetId; + + @ApiModelProperty(value = "经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + @TableField("latitude") + private BigDecimal latitude; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java new file mode 100644 index 0000000..7a86d29 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TStreet.java @@ -0,0 +1,38 @@ +package com.ruoyi.system.model; + +import com.baomidou.mybatisplus.annotation.IdType; +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 lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * <p> + * 街道 + * </p> + * + * @author mitao + * @since 2025-03-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("t_street") +@ApiModel(value="TStreet对象", description="街道") +public class TStreet extends BaseModel implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + @ApiModelProperty(value = "物品名称") + private String streetName; + +} 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 cca42c8..f9e80a7 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 @@ -1,14 +1,9 @@ package com.ruoyi.system.model; import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableId; - -import java.time.LocalDate; -import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableField; -import java.io.Serializable; - +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.domain.BaseModel; import io.swagger.annotations.ApiModel; @@ -18,6 +13,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.time.LocalDate; /** * <p> @@ -92,4 +88,12 @@ @TableField("open_id") private String openId; + @ApiModelProperty(value = "法人") + @TableField("legal_person") + private String legalPerson; + + @ApiModelProperty(value = "社会统一信用代码") + @TableField("credit_code") + private String creditCode; + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java new file mode 100644 index 0000000..f677154 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ITStreetService.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.model.TStreet; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * <p> + * 街道 服务类 + * </p> + * + * @author mitao + * @since 2025-03-19 + */ +public interface ITStreetService extends IService<TStreet> { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java index 0015ee5..abf30a2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java @@ -2,18 +2,21 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; -import com.ruoyi.system.dto.*; +import com.ruoyi.system.dto.BillStatisticsDto; +import com.ruoyi.system.dto.CachPayDto; +import com.ruoyi.system.dto.OfflinePayCheckDto; +import com.ruoyi.system.dto.SmsByBillDto; +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.vo.ScreenRentRankVO; import com.taxi591.bankapi.dto.ChargeBillRequest; import javax.validation.constraints.NotEmpty; import java.math.BigDecimal; import java.util.List; import java.util.function.Consumer; -import java.util.function.Function; - -import java.util.List; /** * <p> @@ -87,4 +90,10 @@ BillStatisticsDto statistics(); Integer batchBillCount(String userId, List<String> billIds); + + /** + * 查询街道租金排行 + * @return + */ + List<ScreenRentRankVO> getStreetRentRank(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java index 00b2a31..3bd61b1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java @@ -43,4 +43,9 @@ Boolean updateContractAuditStatus(String projectId, Integer submitStatus); + /** + * 本月新增租户数 + * @return + */ + Integer getCurrentMonthRentCount(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java index 62a2e34..4b27c65 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java @@ -7,6 +7,7 @@ import com.ruoyi.system.query.TInvoiceQuery; import java.util.List; +import java.util.Map; /** * <p> @@ -19,5 +20,5 @@ public interface TInvoiceService extends IService<TInvoice> { PageInfo<TInvoice> pageList(TInvoiceQuery query); List<TInvoice> makeQuery(TInvoiceQuery query); - Boolean uploadVoucher(TInvoiceQuery query); + Boolean uploadVoucher(TInvoiceQuery query, List<Map<String, String>> map); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java new file mode 100644 index 0000000..28d1853 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ScreenService.java @@ -0,0 +1,129 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.system.model.TBill; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.model.THouse; +import com.ruoyi.system.service.ITStreetService; +import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TContractService; +import com.ruoyi.system.service.THouseService; +import com.ruoyi.system.vo.ScreenRentIncomeTrendVO; +import com.ruoyi.system.vo.ScreenRentRankVO; +import com.ruoyi.system.vo.ScreenTopStaticsDataVO; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Calendar; +import java.util.ArrayList; + +/** + * @author mitao + * @date 2025/3/19 + */ +@Service +@RequiredArgsConstructor(onConstructor_ = {@Lazy}) +public class ScreenService { + private final THouseService tHouseService; + private final TContractService tContractService; + private final TBillService tBillService; + private final ITStreetService tStreetService; + /** + * 获取顶部统计数据 + * @return + */ + public ScreenTopStaticsDataVO getTopStaticsData() { + ScreenTopStaticsDataVO vo = new ScreenTopStaticsDataVO(); + //房屋总面积 + List<THouse> houseList = tHouseService.list(); + Double totalArea = houseList.stream().map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum); + vo.setHouseTotalArea(totalArea); + //已出租面积 + Double totalRentedArea = houseList.stream().filter(item -> !item.getLeaseStatus().equals("1")) + .map(item -> Double.parseDouble(item.getHouseArea())).reduce(0D, Double::sum); + vo.setHouseRentedArea(totalRentedArea); + //总计应收租金 + List<TBill> billList = tBillService.list(); + BigDecimal totalReceivableRent = billList.stream().filter(item -> !item.getPayFeesStatus().equals("5")) + .map(TBill::getPayableFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + vo.setTotalReceivableRent(totalReceivableRent); + //总计已收租金 + BigDecimal totalReceivedRent = billList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + vo.setTotalReceivedRent(totalReceivedRent); + //本月新增租户数 + Integer newTenantCount = tContractService.getCurrentMonthRentCount(); + vo.setNewTenantCount(newTenantCount); + //总计租户数 系统租户列表里有生效合同绑定的租户总数。 + Long count = tContractService.lambdaQuery().in(TContract::getStatus, "4", "5", "6", "7", "8", "9").groupBy(TContract::getTenantId).count(); + vo.setTotalTenantCount(count.intValue()); + Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date()); + Date first = quarterDate.get("first"); + Date last = quarterDate.get("last"); + List<TBill> currentQuarterBillList = tBillService.lambdaQuery().between(TBill::getPayableFeesTime, first, last).list(); + //本季度已交租金 + BigDecimal totalRentPaid = currentQuarterBillList.stream().map(TBill::getPayFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + vo.setTotalRentPaid(totalRentPaid); + //本季度应交租金 + BigDecimal totalRentShould = currentQuarterBillList.stream().filter(item -> !item.getPayFeesStatus().equals("5")) + .map(TBill::getPayableFeesMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + vo.setTotalRentShould(totalRentShould); + return vo; + } + + /** + * 区域租金排名 + * @return + */ + public List<ScreenRentRankVO> streetRentRank() { + return tBillService.getStreetRentRank(); + } + + /** + * 租金收入趋势 + * @return + */ + public ScreenRentIncomeTrendVO rentIncomeTrend() { + ScreenRentIncomeTrendVO vo = new ScreenRentIncomeTrendVO(); + + // 获取当前日期 + Date currentDate = new Date(); + List<String> quarterLabels = new ArrayList<>(); + List<BigDecimal> incomeData = new ArrayList<>(); + + // 获取最近7个季度的数据 + for (int i = 6; i >= 0; i--) { + // 计算对应季度的起止时间 + Date targetDate = DateUtils.addMonths(currentDate, -3 * i); + Map<String, Date> quarterDate = DateUtils.getQuarterDate(targetDate); + Date quarterStart = quarterDate.get("first"); + Date quarterEnd = quarterDate.get("last"); + + // 获取该季度的账单数据并计算总和 + BigDecimal quarterIncome = tBillService.lambdaQuery() + .between(TBill::getPayableFeesTime, quarterStart, quarterEnd) + .list() + .stream() + .map(TBill::getPayFeesMoney) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 生成季度标签 (格式: YY-MM月) + Calendar cal = Calendar.getInstance(); + cal.setTime(quarterEnd); + String label = String.format("%02d-%d月", + cal.get(Calendar.YEAR) % 100, + cal.get(Calendar.MONTH) + 1); + + quarterLabels.add(label); + incomeData.add(quarterIncome); + } + + vo.setQuarters(quarterLabels); + vo.setIncomeData(incomeData); + return vo; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java index 0376220..05bbd56 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java @@ -1,21 +1,42 @@ package com.ruoyi.system.service.impl; -import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; -import com.ruoyi.common.config.SmsProperties; import com.ruoyi.common.constant.AmountConstant; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.*; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.OrderNos; +import com.ruoyi.common.utils.SmsUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.TencentMailUtil; import com.ruoyi.common.utils.uuid.UUID; -import com.ruoyi.system.dto.*; +import com.ruoyi.system.dto.BillStatisticsDto; +import com.ruoyi.system.dto.CachPayDto; +import com.ruoyi.system.dto.OfflinePayCheckDto; +import com.ruoyi.system.dto.SmsByBillDto; +import com.ruoyi.system.dto.TBillDto; +import com.ruoyi.system.dto.TbillSaveDto; import com.ruoyi.system.mapper.TBillMapper; -import com.ruoyi.system.model.*; +import com.ruoyi.system.model.TBankFlow; +import com.ruoyi.system.model.TBill; +import com.ruoyi.system.model.TBillDetail; +import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.model.TInvoiceToBill; +import com.ruoyi.system.model.TOrderBill; +import com.ruoyi.system.model.TPayOrder; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.query.TInvoiceToBillQuery; -import com.ruoyi.system.service.*; +import com.ruoyi.system.service.TBankFlowService; +import com.ruoyi.system.service.TBillConfirmService; +import com.ruoyi.system.service.TBillDetailService; +import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TFlowManagementService; +import com.ruoyi.system.service.TInvoiceToBillService; +import com.ruoyi.system.service.TOrderBillService; +import com.ruoyi.system.service.TPayOrderService; +import com.ruoyi.system.vo.ScreenRentRankVO; import com.taxi591.bankapi.dto.ChargeBillRequest; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; @@ -28,7 +49,6 @@ import javax.validation.constraints.NotEmpty; import java.math.BigDecimal; import java.text.ParseException; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; @@ -552,5 +572,12 @@ return this.baseMapper.batchBillCount(userId,billIds); } - + /** + * 街道租金排行 + * @return + */ + @Override + public List<ScreenRentRankVO> getStreetRentRank() { + return baseMapper.getStreetRentRank(); + } } 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 30368c2..26dcba0 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 @@ -4,6 +4,7 @@ import com.aizuda.bpm.mybatisplus.mapper.FlwHisTaskMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.R; @@ -17,7 +18,9 @@ import com.ruoyi.system.mapper.TCheckAcceptRecordMapper; import com.ruoyi.system.mapper.TContractMapper; import com.ruoyi.system.mapper.THouseMapper; -import com.ruoyi.system.model.*; +import com.ruoyi.system.model.TCheckAcceptRecord; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.model.THouse; import com.ruoyi.system.query.TContractAppletQuery; import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; @@ -25,21 +28,17 @@ 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 org.springframework.util.CollectionUtils; 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.*; -import java.util.stream.Collectors; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; /** * <p> @@ -195,7 +194,19 @@ @Override public Boolean updateContractAuditStatus(String projectId, Integer status) { LambdaUpdateWrapper<TContract> contractLambdaUpdateWrapper = new LambdaUpdateWrapper<>(); - contractLambdaUpdateWrapper.eq(TContract::getId, projectId).set(TContract::getStatus, status); + contractLambdaUpdateWrapper + .eq(TContract::getId, projectId) + .set(TContract::getStatus, status) + .set(TContract::getSignTime, LocalDateTime.now()); return this.update(contractLambdaUpdateWrapper); } + + /** + * 本月新增租户数 + * @return + */ + @Override + public Integer getCurrentMonthRentCount() { + return baseMapper.getCurrentMonthRentCount(); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java index 8d14440..d6f8b6d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java @@ -1,6 +1,7 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.utils.DictUtils; @@ -12,7 +13,6 @@ import com.ruoyi.system.query.THouseQuery; import com.ruoyi.system.query.TUserHistoryQuery; import com.ruoyi.system.service.THouseService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.vo.HouseVO; import org.springframework.stereotype.Service; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java index c0be87b..20e23e5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java @@ -58,7 +58,7 @@ } @Override - public Boolean uploadVoucher(TInvoiceQuery query) { + public Boolean uploadVoucher(TInvoiceQuery query, List<Map<String, String>> map) { // 检查是否存在对应的发票记录 TInvoice preexist = getById(query.getId()); if (preexist == null) { @@ -74,17 +74,11 @@ tInvoice.setInvoiceTime(query.getInvoiceTime()); tInvoice.setStatus(2); - // 处理附件信息 - List<Map<String, String>> attachments = buildAttachments(query.getInvoiceVoucher(), query.getInvoiceVoucherName()); - if (attachments.isEmpty()) { - log.warn("未找到有效的附件信息"); - return updateById(tInvoice); - } // 异步发送邮件 CompletableFuture.runAsync(() -> { try { - mailUtil.sendInvoice(preexist.getEmail(), attachments); + mailUtil.sendInvoice(preexist.getEmail(), map); } catch (ServiceException e) { log.error("邮件发送失败", e); } @@ -93,57 +87,4 @@ // 更新数据库 return updateById(tInvoice); } - - private List<Map<String, String>> buildAttachments(String invoiceVoucher, String invoiceVoucherName) { - if (invoiceVoucher == null || invoiceVoucherName == null) { - return Collections.emptyList(); - } - - String[] voucherUrls = invoiceVoucher.split(","); - String[] voucherNames = invoiceVoucherName.split(","); - - // 确保两个数组长度一致 - int length = Math.min(voucherUrls.length, voucherNames.length); - if (length == 0) { - return Collections.emptyList(); - } - - // 构建附件列表 - List<Map<String, String>> attachments = new ArrayList<>(length); - for (int i = 0; i < length; i++) { - Map<String, String> attachment = new HashMap<>(2); // 初始容量为2,避免扩容 - attachment.put("url", voucherUrls[i]); - attachment.put("fileName", voucherNames[i]); - attachments.add(attachment); - } - - return attachments; - } - - // @Override - // public Boolean uploadVoucher(TInvoiceQuery query) { - // TInvoice preexist = getById(query.getId()); - // if (preexist == null){ - // return false; - // } - // TInvoice tInvoice = new TInvoice(); - // tInvoice.setId(query.getId()); - // tInvoice.setInvoiceVoucher(query.getInvoiceVoucher()); - // tInvoice.setInvoiceVoucherName(query.getInvoiceVoucherName()); - // tInvoice.setInvoiceTime(query.getInvoiceTime()); - // tInvoice.setStatus(2); - // List<Map<String, String>> mapArrayList = new ArrayList<>(); - // String invoiceVoucher = query.getInvoiceVoucher(); - // String invoiceVoucherName = query.getInvoiceVoucherName(); - // - // List<String> list = Arrays.stream(invoiceVoucher.split(",")).collect(Collectors.toList()); - // for (int i = 0; i < list.size()-1; i++) { - // Map<String, String> map = new HashMap<>(); - // map.put("url", list.get(i)); - // map.put("fileName",invoiceVoucherName.split(",")[i]); - // mapArrayList.add(map); - // } - // mailUtil.sendInvoice(preexist.getEmail(),mapArrayList); - // return updateById(tInvoice); - // } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java new file mode 100644 index 0000000..b303626 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TStreetServiceImpl.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.system.model.TStreet; +import com.ruoyi.system.mapper.TStreetMapper; +import com.ruoyi.system.service.ITStreetService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * <p> + * 街道 服务实现类 + * </p> + * + * @author mitao + * @since 2025-03-19 + */ +@Service +public class TStreetServiceImpl extends ServiceImpl<TStreetMapper, TStreet> implements ITStreetService { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java new file mode 100644 index 0000000..bfda473 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentIncomeTrendVO.java @@ -0,0 +1,23 @@ +package com.ruoyi.system.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author mitao + * @date 2025/3/20 + */ +@Data +@ApiModel("租金收入区域视图对象") +public class ScreenRentIncomeTrendVO { + + @ApiModelProperty("x轴 时间列表") + private List<String> quarters; + + @ApiModelProperty("y轴 收入列表") + private List<BigDecimal> incomeData; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java new file mode 100644 index 0000000..4b1f3f1 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenRentRankVO.java @@ -0,0 +1,21 @@ +package com.ruoyi.system.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author mitao + * @date 2025/3/19 + */ +@Data +@ApiModel("区域租金排名") +public class ScreenRentRankVO { + @ApiModelProperty("街道名称") + private String streetName; + + @ApiModelProperty("租金") + private BigDecimal rentAmount; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java new file mode 100644 index 0000000..87cabfb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ScreenTopStaticsDataVO.java @@ -0,0 +1,41 @@ +package com.ruoyi.system.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author mitao + * @date 2025/3/19 + */ +@Data +@ApiModel("顶部统计数据") +public class ScreenTopStaticsDataVO { + + @ApiModelProperty("房屋总面积") + private Double houseTotalArea; + + @ApiModelProperty("已出租面积") + private Double houseRentedArea; + + @ApiModelProperty("总计应收租金") + private BigDecimal totalReceivableRent; + + @ApiModelProperty("总计已收租金") + private BigDecimal totalReceivedRent; + + @ApiModelProperty("本月新增租户数") + private Integer newTenantCount; + + @ApiModelProperty("总计租户数") + private Integer totalTenantCount; + + @ApiModelProperty("本季度已交租金") + private BigDecimal totalRentPaid; + + @ApiModelProperty("本季度应交租金") + private BigDecimal totalRentShould; +} + diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java new file mode 100644 index 0000000..75684bc --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TenantCountTrendVO.java @@ -0,0 +1,22 @@ +package com.ruoyi.system.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("租户数量趋势统计") +public class TenantCountTrendVO { + @ApiModelProperty(value = "日期") + private String date; + @ApiModelProperty(value = "租户数量") + private Long count; + + public TenantCountTrendVO(String date, Long count) { + this.date = date; + this.count = count; + } + + public TenantCountTrendVO() { + } +} diff --git a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml index 81d281c..e024b7e 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml @@ -186,4 +186,15 @@ AND b.bill_type = 3 </where> </select> + <select id="getStreetRentRank" resultType="com.ruoyi.system.vo.ScreenRentRankVO"> + SELECT + ts.street_name,ROUND(COALESCE(SUM(tb.pay_fees_money),0) /10000,2) AS rentAmount + FROM + t_street ts + LEFT JOIN t_house th ON ts.id = th.street_id + LEFT JOIN t_contract tc ON tc.house_id = th.id + LEFT JOIN t_bill tb ON tc.id = tb.contract_id + GROUP BY ts.id + ORDER BY rentAmount 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 66ccabf..92a83f9 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml @@ -124,5 +124,19 @@ </where> </select> + <select id="getCurrentMonthRentCount" resultType="java.lang.Integer"> + SELECT COUNT(DISTINCT tc.tenant_id) AS new_tenant_count + FROM t_contract tc + WHERE + -- 筛选本月签订的合同 + DATE_FORMAT(tc.sign_time, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m') AND tc.status IN ("4", "5", "6", "7", "8", "9") + -- 且租户在本月前从未签订过任何合同 + AND NOT EXISTS ( + SELECT 1 + FROM t_contract tc_hist + WHERE tc_hist.tenant_id = tc.tenant_id + AND tc_hist.sign_time <![CDATA[ < ]]> DATE_FORMAT(CURDATE(), '%Y-%m-01') AND tc_hist.status IN ("4", "5", "6", "7", "8", "9") + ) + </select> </mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml new file mode 100644 index 0000000..296a7b9 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/TStreetMapper.xml @@ -0,0 +1,5 @@ +<?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.TStreetMapper"> + +</mapper> -- Gitblit v1.7.1