master
杜函宇 5 days ago
parent 7a0e7e5b3d
commit c9cd4699a3

@ -1,95 +0,0 @@
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.9</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.9-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 平台简介
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 前端采用Vue、Element UI。
* 后端采用Spring Boot、Spring Security、Redis & Jwt。
* 权限认证使用Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast)Oracle版本[RuoYi-Vue-Oracle](https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存信息查询,命令统计等。
17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://vue.ruoyi.vip
文档地址http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr>
</table>
## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/已满-151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [![加入QQ群](https://img.shields.io/badge/已满-224622315-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [![加入QQ群](https://img.shields.io/badge/已满-287842588-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [![加入QQ群](https://img.shields.io/badge/187944233-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) 点击按钮入群。

@ -67,22 +67,22 @@
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!--富文本转pdfhtml转pdfitext转pdf-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.itextpdf</groupId>-->
<!-- <artifactId>itext-asian</artifactId>-->
<!-- <version>5.2.0</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash;富文本转pdfhtml转pdfitext转pdf&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.itextpdf</groupId>-->
<!-- <artifactId>itextpdf</artifactId>-->
<!-- <version>5.5.13</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.itextpdf.tool</groupId>-->
<!-- <artifactId>xmlworker</artifactId>-->
<!-- <version>5.5.13</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

@ -32,8 +32,8 @@ public class RuoYiApplication
path = path.isEmpty() ? "" : path;
System.out.println("\n----------------------------------------------------------\n\t"
+ "Application is running! Access URLs:\n\t"
+ "swagger-ui: http://localhost:" + port + path + "/doc.html\n\t"
+ "swagger-ui: http://" + ip + ":" + port + path + "/doc.html\n\t"
+ "swagger-ui: http://localhost:" + port + path + "doc.html\n\t"
+ "swagger-ui: http://" + ip + ":" + port + path + "doc.html\n\t"
+ "----------------------------------------------------------");
}
}

@ -1,44 +0,0 @@
package com.ruoyi.docking.controller;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.docking.service.ProjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* (Project)
*
* @author makejava
* @since 2025-03-25 14:47:53
*/
@Api(tags = "项目(对接数据)")
@RestController
@RequestMapping("/gysl/project")
public class ProjectController extends BaseController {
// /**
// * 服务对象
// */
// @Resource
// private ProjectService projectService;
//
// /**
// * 查询所有数据
// * @return 所有数据
// */
// @ApiOperation("查询所有数据")
// @GetMapping("/list")
// @DataSource(value = DataSourceType.SLAVE)
// public AjaxResult selectAll() {
// return success(projectService.list());
// }
}

@ -1,10 +1,8 @@
package com.ruoyi.docking.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.docking.entity.ProjectProgress;
import com.ruoyi.docking.service.ProjectProgressService;
import com.ruoyi.gysl.entity.request.ZwIdPageReq;
@ -13,9 +11,7 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.List;
/**
@ -36,16 +32,15 @@ public class ProjectProgressController extends BaseController {
/**
*
*
*
* @param page
* @param zwIdPageReq
* @return
*/
@ApiOperation(value = "分页查询所有数据", response = ProjectProgress.class)
@ApiOperation(value = "查询所有数据", response = ProjectProgress.class)
@GetMapping("/page")
public AjaxResult selectAll(Page<ProjectProgress> page, @Valid ZwIdPageReq zwIdPageReq) {
return success(projectProgressService.page(page, zwIdPageReq));
public AjaxResult selectAll(ZwIdPageReq zwIdPageReq) {
return success(projectProgressService.page( zwIdPageReq));
}
@ -57,32 +52,10 @@ public class ProjectProgressController extends BaseController {
*/
@ApiOperation("新增数据")
@PostMapping("/add")
public AjaxResult insert(@RequestBody ProjectProgress projectMonthInfo) {
public AjaxResult insert(@RequestBody @Valid ProjectProgress projectMonthInfo) {
return success(projectProgressService.save(projectMonthInfo));
}
// /**
// * 测试
// */
// @GetMapping("/test")
// @ApiOperation(value = "测试", response = ProjectProgress.class)
// public AjaxResult test() {
// return success(projectProgressService.djList());
// }
/**
*
*
* @param id
* @return
*/
@GetMapping("/{id}")
@ApiOperation(value = "通过主键查询单条数据", response = ProjectProgress.class)
public AjaxResult selectOne(@PathVariable Serializable id) {
return success(projectProgressService.getById(id));
}
/**
*
@ -93,7 +66,11 @@ public class ProjectProgressController extends BaseController {
@ApiOperation("修改数据")
@PutMapping("/edit")
public AjaxResult update(@RequestBody ProjectProgress projectProgress) {
return success(projectProgressService.updateById(projectProgress));
if(projectProgress.getId()!=null){
return AjaxResult.success(projectProgressService.updateById(projectProgress));
}else {
return AjaxResult.success(projectProgressService.save(projectProgress));
}
}
/**
@ -107,16 +84,5 @@ public class ProjectProgressController extends BaseController {
public AjaxResult delete(@RequestParam("idList") List<Long> idList) {
return success(projectProgressService.removeByIds(idList));
}
/**
*
*/
@ApiOperation(value = "根据条件导出月度进展详情")
@PostMapping(value = "/export")
public void export(HttpServletResponse response, ZwIdPageReq zwIdPageReq) throws Exception {
List<ProjectProgress> filteredList = projectProgressService.page(zwIdPageReq);
ExcelUtil<ProjectProgress> util = new ExcelUtil<>(ProjectProgress.class);
util.exportExcel(response, filteredList, "月度进展详情");
}
}

@ -9,6 +9,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
/**
* (ProjectProgress)
*
@ -18,10 +20,16 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("project_progress")
@ApiModel(value="项目月度进度",description = "对接数据")
@ApiModel(value="项目月度进度")
public class ProjectProgress {
@TableId(type = IdType.AUTO)
@ApiModelProperty(value ="项目进度ID" )
private Integer id;
@ApiModelProperty(value ="项目id" )
private Integer xmId;
@ApiModelProperty(value ="项目进度ID" )
private Integer progressId;
@ -31,6 +39,7 @@ public class ProjectProgress {
@ApiModelProperty(value ="月份" )
@NotBlank(message = "请填写月份")
private String month;
@ -124,5 +133,11 @@ public class ProjectProgress {
@ApiModelProperty(value ="下一年税收" )
private Float nextTax;
//---------------
@ApiModelProperty(value ="截止目前累计建成面积(平方米)" )
private String jzmqjc;
@ApiModelProperty(value ="项目进展详情" )
private String xmjzxq;
}

@ -1,15 +0,0 @@
package com.ruoyi.docking.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.docking.entity.Project;
/**
* (Project)访
*
* @author makejava
* @since 2025-03-25 14:47:57
*/
public interface ProjectMapper extends BaseMapper<Project> {
}

@ -2,6 +2,8 @@ package com.ruoyi.docking.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.docking.entity.ProjectProgress;
import com.ruoyi.gysl.entity.request.ZwIdPageReq;
import org.apache.ibatis.annotations.Param;
@ -20,11 +22,10 @@ public interface ProjectProgressMapper extends BaseMapper<ProjectProgress> {
/**
*
*
* @param page
* @param zwIdPageReq
* @param name
* @return
*/
Page<ProjectProgress> page(Page<ProjectProgress> page,@Param("req") ZwIdPageReq zwIdPageReq);
List<ProjectProgress> page( @Param("req") ZwIdPageReq zwIdPageReq);
@DataSource(value = DataSourceType.SLAVE)
List<ProjectProgress> page( @Param("name") String name);
}

@ -17,19 +17,11 @@ import java.util.List;
public interface ProjectProgressService extends IService<ProjectProgress> {
/**
*
*
*
* @param page
* @param zwIdPageReq
* @return
*/
Page<ProjectProgress> page(Page<ProjectProgress> page, ZwIdPageReq zwIdPageReq);
List<ProjectProgress> page( ZwIdPageReq zwIdPageReq);
/**
*
*/
List<ProjectProgress> djList();
}

@ -1,22 +0,0 @@
package com.ruoyi.docking.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.docking.entity.Project;
import java.util.List;
/**
* (Project)
*
* @author makejava
* @since 2025-03-25 14:47:59
*/
public interface ProjectService extends IService<Project> {
/**
*
*/
List<Project> djList();
}

@ -1,18 +1,23 @@
package com.ruoyi.docking.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.docking.entity.ProjectProgress;
import com.ruoyi.docking.mapper.ProjectProgressMapper;
import com.ruoyi.docking.service.ProjectProgressService;
import com.ruoyi.gysl.entity.BasicInformation;
import com.ruoyi.gysl.entity.request.ZwIdPageReq;
import com.ruoyi.gysl.service.BasicInformationService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* (ProjectProgress)
@ -23,41 +28,31 @@ import java.util.List;
@Service("projectProgressService")
public class ProjectProgressServiceImpl extends ServiceImpl<ProjectProgressMapper, ProjectProgress> implements ProjectProgressService {
@Resource
private BasicInformationService basicInformationService;
@Resource
private ProjectProgressMapper projectProgressMapper;
/**
*
*
*
* @param page
* @param zwIdPageReq
* @return
*/
@Override
public Page<ProjectProgress> page(Page<ProjectProgress> page, ZwIdPageReq zwIdPageReq) {
return baseMapper.page(page, zwIdPageReq);
}
@Override
public List<ProjectProgress> page(ZwIdPageReq zwIdPageReq) {
return baseMapper.page(zwIdPageReq);
}
/**
*
*/
@DataSource(value = DataSourceType.SLAVE)
@Override
public List<ProjectProgress> djList() {
//获取当前时间的上一个月的秒级时间戳
// 获取当前时间(带时区)
ZonedDateTime now = ZonedDateTime.now(ZoneId.systemDefault());
// 计算上个月同一时间(自动处理跨月边界)
ZonedDateTime lastMonth = now.minusMonths(1);
// 上个月的时间转换为秒级时间戳
long timestamp = lastMonth.toEpochSecond();
// 当前的时间转换为秒级时间戳
long nowTime = now.toEpochSecond();
return lambdaQuery().ge(ProjectProgress::getCreatedAt, timestamp)
.lt(ProjectProgress::getCreatedAt, nowTime).list();
//查询对应的项目基础信息数据
BasicInformation byId = basicInformationService.getById(zwIdPageReq.getXmId());
//获取对接的数据
List<ProjectProgress> page = projectProgressMapper.page(byId.getName());
List<ProjectProgress> list = lambdaQuery().eq(ProjectProgress::getXmId, byId.getId()).list();
return new ArrayList<>(Stream.concat(list.stream(), page.stream())
.collect(Collectors.toMap(
ProjectProgress::getMonth,
v -> v,
(existing, replacement) -> existing // 冲突时保留现有值即list中的值
))
.values());
}
}

@ -1,45 +0,0 @@
package com.ruoyi.docking.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.docking.entity.ProjectProgress;
import com.ruoyi.docking.mapper.ProjectMapper;
import com.ruoyi.docking.entity.Project;
import com.ruoyi.docking.service.ProjectService;
import org.springframework.stereotype.Service;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
/**
* (Project)
*
* @author makejava
* @since 2025-03-25 14:47:59
*/
@Service("projectService")
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements ProjectService {
/**
*
*/
@DataSource(value = DataSourceType.SLAVE)
@Override
public List<Project> djList() {
//获取当前时间的上一个月的秒级时间戳
// 获取当前时间(带时区)
ZonedDateTime now = ZonedDateTime.now(ZoneId.systemDefault());
// 计算上个月同一时间(自动处理跨月边界)
ZonedDateTime lastMonth = now.minusMonths(1);
// 上个月的时间转换为秒级时间戳
long timestamp = lastMonth.toEpochSecond();
// 当前的时间转换为秒级时间戳
long nowTime = now.toEpochSecond();
return lambdaQuery().ge(Project::getCreatedAt, timestamp)
.lt(Project::getCreatedAt, nowTime).list();
}
}

@ -7,7 +7,6 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.gysl.entity.Dpclgl;
import com.ruoyi.gysl.entity.request.DpclglPageReq;
import com.ruoyi.gysl.service.DpclglService;
import com.ruoyi.gysl.utils.HtmlToPdfConverter;
import com.ruoyi.web.controller.common.CommonController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -101,17 +100,6 @@ public class DpclglController extends BaseController {
}
/**
*
*
* @return
*/
@ApiOperation(value = "副编辑器内容生成pdf文件url")
@GetMapping("/unloadPdf")
public AjaxResult unloadPdf(@RequestParam(defaultValue = "文章标题") String htmlArticleTitle, @RequestParam(defaultValue = "文章内容") String htmlContent) throws Exception {
MultipartFile multipartFile = HtmlToPdfConverter.convertHtmlToPdf(htmlArticleTitle, htmlContent);
return AjaxResult.success(commonController.uploadFile(multipartFile));
}
}

@ -34,7 +34,6 @@ public class GyslProjectHandbook extends BaseModel {
private String name;
@ApiModelProperty(value ="副标题" )
@NotBlank(message = "副标题不能为空!")
private String subtitle;
@ -54,7 +53,6 @@ public class GyslProjectHandbook extends BaseModel {
@ApiModelProperty(value ="封尾标题" )
@NotBlank(message = "封尾图片不能为空!")
private String tail;
@ApiModelProperty(value ="项目名称数组" )

@ -46,7 +46,7 @@ public class Xmzsk extends BaseModel implements Serializable {
*
*/
@ApiModelProperty(value = "类型")
@Excel(name = "文件名称")
@Excel(name = "类型")
@TableField("lx")
private String lx;

@ -38,4 +38,7 @@ public class BasicInformationPageReq {
@ApiModelProperty("0非负面清单 1是负面清单")
private Integer isFmqd;
@ApiModelProperty("状态")
private Integer status;
}

@ -31,8 +31,7 @@ public class NoticeTiming {
@Resource
private ProjectProgressService projectProgressService;
@Resource
private ProjectService projectService;
@Resource
private SmartRemindersService smartRemindersService;

@ -11,6 +11,7 @@ import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.utils.PdfMerger;
import com.itextpdf.layout.font.FontProvider;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDictData;
@ -24,11 +25,13 @@ import com.ruoyi.gysl.mapper.ProjectHandBookMapper;
import com.ruoyi.gysl.service.BasicInformationService;
import com.ruoyi.gysl.service.GyslProjectHandbookService;
import com.ruoyi.system.mapper.SysDictDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.*;
@ -38,9 +41,12 @@ import java.util.*;
* @author makejava
* @since 2025-04-14 13:56:59
*/
@Slf4j
@Service("gyslProjectHandbookService")
public class GyslProjectHandbookServiceImpl extends ServiceImpl<ProjectHandBookMapper, GyslProjectHandbook> implements GyslProjectHandbookService {
@Resource
private BasicInformationMapper basicInformationMapper;
@ -109,13 +115,12 @@ public class GyslProjectHandbookServiceImpl extends ServiceImpl<ProjectHandBookM
String a = getHtml(htmlFoot);
a = a.replace("{{fwbt}}", handbook.getTail() != null ? handbook.getTail() : "/");
a = a.replace("{{fmimgurl}}", handbook.getTailingImg() != null ?
Paths.get(RuoYiConfig.getProfile() + handbook.getTailingImg()).toUri().toString()
Paths.get(RuoYiConfig.getProfile() + StringUtils.substringAfter(handbook.getTailingImg(), Constants.RESOURCE_PREFIX)).toUri().toString()
: Paths.get(RuoYiConfig.getProfile() + "/OIP-C.jpg").toUri().toString());
String foodPdf = RuoYiConfig.getProfile() + "/pdfml" + "/food" + ".pdf";
hbpdf.add(foodPdf);
FileUtil.touch(foodPdf);
try (PdfWriter writer = new PdfWriter(foodPdf);
PdfDocument pdf = new PdfDocument(writer)) {
try (PdfWriter writer = new PdfWriter(foodPdf); PdfDocument pdf = new PdfDocument(writer)) {
HtmlConverter.convertToPdf(a, pdf, props);
}
// 创建内存输出流替代写入ceshi.pdf文件
@ -132,7 +137,7 @@ public class GyslProjectHandbookServiceImpl extends ServiceImpl<ProjectHandBookM
}
merger.close();
mergedPdfDoc.close(); // 关闭合并的PDF文档
// 删除临时生成的pdfml文件夹及其内容
//删除临时生成的pdfml文件夹及其内容
String pdfmlDirPath = RuoYiConfig.getProfile() + "/pdfml";
try {
FileUtil.del(pdfmlDirPath); // Hutool工具类删除文件夹含内部文件
@ -156,15 +161,17 @@ public class GyslProjectHandbookServiceImpl extends ServiceImpl<ProjectHandBookM
* htmlstring
*/
public static String getHtml(String htmlUrl) {
//新建一个新的目录用来存储生成的所有pdf
StringBuilder html = new StringBuilder();
try (Scanner scanner = new Scanner(new File(htmlUrl))) {
try (Scanner scanner = new Scanner(
new File(htmlUrl),
StandardCharsets.UTF_8.name()) // 显式指定UTF-8
) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
html.append(line);
}
} catch (IOException e) {
throw new ServiceException("读取html文件失败!");
throw new ServiceException("读取HTML文件失败!");
}
return html.toString();
}

@ -1,232 +0,0 @@
package com.ruoyi.gysl.utils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.ruoyi.common.utils.http.HttpUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HtmlToPdfConverter {
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
public static MultipartFile convertHtmlToPdf(String htmlArticleTitle, String htmlContent) throws IOException {
String ht = content2Html(htmlContent);
String path = System.getProperty("user.dir");
// 根据日期建文件夹
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String[] split = format.split("-");
Path dirPath = Paths.get(path, "temporary", split[0], split[1], split[2]);
try {
// clearTemporaryDirectory(Paths.get(path, "temporary")); // 清理目录
Files.createDirectories(dirPath);
} catch (IOException e) {
throw new RuntimeException("创建文件夹失败: " + e.getMessage(), e);
}
File pdfFile = new File(dirPath.toFile(), "pdf-" + System.currentTimeMillis() + ".pdf");
// 创建PDF文档
Document document = new Document();
FileOutputStream fos = null;
InputStream is = null;
try {
fos = new FileOutputStream(pdfFile);
PdfWriter writer = PdfWriter.getInstance(document, fos);
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("C:/Windows/Fonts/simsun.ttc");
document.open();
// 添加标题
Paragraph paragraph = new Paragraph(htmlArticleTitle); // 设置你自定义的字体格式
document.add(paragraph);
String updatedHtmlContent = "";
if (htmlContent.contains("img")) {
updatedHtmlContent = replaceImgSrcWithBase64(ht);
if (updatedHtmlContent != null) {
is = new ByteArrayInputStream(updatedHtmlContent.getBytes(StandardCharsets.UTF_8));
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, StandardCharsets.UTF_8, fontProvider);
// 添加图片
Elements imgElements = Jsoup.parse(updatedHtmlContent).select("img");
for (Element img : imgElements) {
String imgSrc = img.attr("src");
if (imgSrc.startsWith("data:image/jpeg;base64,")) {
String base64Data = imgSrc.substring("data:image/jpeg;base64,".length());
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
Image image = Image.getInstance(imageBytes);
document.add(image); // 添加图片到 PDF
}
}
}
} else {
is = new ByteArrayInputStream(ht.getBytes(StandardCharsets.UTF_8));
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, StandardCharsets.UTF_8, fontProvider);
}
} catch (DocumentException | IOException e) {
throw new RuntimeException("转换PDF失败: " + e.getMessage(), e);
} finally {
if (document.isOpen()) {
document.close(); // 确保Document关闭
}
if (fos != null) {
try {
fos.close(); // 关闭文件输出流
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close(); // 关闭输入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
MultipartFile multipartFile = getMultipartFile(pdfFile);
// 在此处删除创建的 PDF 文件
boolean deleted = pdfFile.delete();
if (!deleted) {
log.error("删除文件失败: " + pdfFile.getAbsolutePath());
}
return multipartFile;
}
private static MultipartFile getMultipartFile(File file) throws IOException {
try (FileInputStream fileInputStream = new FileInputStream(file)) {
return new MockMultipartFile(file.getName(), file.getName(), "application/pdf", fileInputStream);
}
}
public static String content2Html(String htmlContent) {
String COMPLETE_CONTENT = "<html><head></head><body style=\"font-family: SimSun;\">" + htmlContent + "</body></html>";
return COMPLETE_CONTENT.replace("<br>", "<br/>");
}
private static String replaceImgSrcWithBase64(String htmlContent) {
List<String> imgSrcs = new ArrayList<>();
String regex = "<img[^>]+src=\"([^\"]+)\"[^>]*>"; // 正确的正则表达式
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(htmlContent);
String baseUrl = "http://39.101.188.84:7071";
// 使用 StringBuilder 来构建新的 HTML
StringBuilder updatedHtml = new StringBuilder(htmlContent);
// 定义要替换的起始位置
int offset = 0;
while (matcher.find()) {
String imgSrc = matcher.group(1); // 捕获组返回 img src 的值
String imgUrl = baseUrl + imgSrc;
// 将 URL 转化为 Base64
try {
URL url = new URL(imgUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0"); // 添加 User-Agent
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
byte[] imageBytes = outputStream.toByteArray();
String base64 = Base64.getEncoder().encodeToString(imageBytes);
// 替换 img 标签的 src 属性为 Base64 数据
String base64ImgTag = "<img src=\"data:image/jpeg;base64," + base64 + "\" />";
int start = matcher.start() + offset; // 累计偏移量
int end = matcher.end();
// 替换原来的 img 标签
updatedHtml.replace(start, end, base64ImgTag);
//System.out.println(updatedHtml.toString());
// 更新偏移量
offset += base64ImgTag.length() - (end - start);
} catch (Exception e) {
e.printStackTrace();
return null; // 处理异常或返回特定的错误值
}
}
return updatedHtml.toString();
}
public String convertImageToBase64(String imgUrl) {
try {
// String encodedImgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.toString());
URL url = new URL(imgUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0"); // 添加 User-Agent
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
byte[] imageBytes = outputStream.toByteArray();
String base64 = Base64.getEncoder().encodeToString(imageBytes);
return "data:image/jpeg;base64," + base64; // 根据实际情况修改 MIME 类型
} catch (Exception e) {
e.printStackTrace();
return null; // 处理异常或返回特定的错误值
}
}
private static void clearTemporaryDirectory(Path directory) {
File dir = directory.toFile();
if (dir.exists() && dir.isDirectory()) {
for (File file : dir.listFiles()) {
if (!file.isDirectory()) {
file.delete(); // 删除文件
}
}
}
}
}

@ -1,168 +0,0 @@
package com.ruoyi.gysl.utils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PdfUtils {
// 定义全局的字体静态变量
private static Font titlefont;
private static Font headfont;
private static Font keyfont;
private static Font textfont;
// 最大宽度
private static int maxWidth = 520;
// 静态代码块
static {
try {
// 不同字体这里定义为同一种字体包含不同字号、不同style
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
titlefont = new Font(bfChinese, 16, Font.BOLD);
headfont = new Font(bfChinese, 14, Font.BOLD);
keyfont = new Font(bfChinese, 10, Font.BOLD);
textfont = new Font(bfChinese, 10, Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* htmlpdf
*
* @param htmlContent
* @throws Exception
*/
public MultipartFile html2Pdf(String htmlArticleTitle, String htmlContent) throws Exception {
htmlContent = this.content2Html(htmlContent);
String path = System.getProperty("user.dir");
//根据日期建文件夹
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String format = formatter.format(date);
String[] split = format.split("-");
File dir = new File(path + "/temporary");
if (!dir.exists()) {
dir.mkdir();
}
File dir2 = new File(path + "/temporary" + "/" + split[0]);
if (!dir2.exists()) {
dir2.mkdir();
}
File dir3 = new File(path + "/temporary" + "/" + split[0] + "/" + split[1]);
if (!dir3.exists()) {
dir3.mkdir();
}
File dir4 = new File(path + "/temporary" + "/" + split[0] + "/" + split[1] + "/" + split[2]);
if (!dir4.exists()) {
dir4.mkdir();
}
File pdfFile = new File(dir4 + "/pdf" + "-" + System.currentTimeMillis() + ".pdf");
//1 打开文件流
Document document = new Document();
FileOutputStream fos = new FileOutputStream(pdfFile);
System.out.println(pdfFile);
InputStream is = new ByteArrayInputStream(htmlContent.getBytes(StandardCharsets.UTF_8));
//InputStream cssIs = new ByteArrayInputStream(getCssFile());
PdfWriter writer = null;
try {
writer = PdfWriter.getInstance(document, fos);
//3. 设置字体
XMLWorkerFontProvider fontProvider1 = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
//fontProvider1.register(path+"\\simsun.ttc");//本地
fontProvider1.register(path + "/simsun.ttc");//部署服务器
//3 打开文档
document.open();
// 段落
Paragraph paragraph = new Paragraph(htmlArticleTitle, titlefont);
paragraph.setAlignment(1); //设置文字居中 0靠左 1居中 2靠右
paragraph.setIndentationLeft(12); //设置左缩进
paragraph.setIndentationRight(12); //设置右缩进
paragraph.setFirstLineIndent(24); //设置首行缩进
paragraph.setLeading(20f); //行间距
paragraph.setSpacingBefore(5f); //设置段落上空白
paragraph.setSpacingAfter(10f); //设置段落下空白
document.add(paragraph);
//4 html转为pdf
//XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, cssIs, Charset.forName("UTF-8"), fontProvider1);
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, StandardCharsets.UTF_8, fontProvider1);
} catch (DocumentException | IOException e) {
throw new RuntimeException("转pdf失败罗~");
} finally {
if (null != writer) {
writer.flush();
}
//5 关闭文档
document.close();
fos.close();
//cssIs.close();
is.close();
writer.close();
MultipartFile multipartFile = getMulipartFiles2(pdfFile + "");
System.out.println("pdfFile = " + pdfFile);
return multipartFile;
}
}
public MultipartFile getMulipartFiles2(String filePath) throws IOException {
File file = new File(filePath);
FileInputStream fileInputStream = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
"application/sql", fileInputStream);
long size = multipartFile.getSize();
return multipartFile;
}
/**
* html
*
* @return
*/
public String content2Html(String htmlContent) {
String COMPLETE_CONTENT = "<html><head></head><body style=\"font-family: SimSun;\">" + htmlContent + "</body></html>";
String content = COMPLETE_CONTENT;
content = content.replace("<br>", "<br/>");
return content;
}
/**
*
*
* @return
* @throws Exception
*/
protected byte[] getCssFile() throws Exception {
FileInputStream fileInputStream = new FileInputStream("D:\\editor.css");
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1204];
int len = 0;
while ((len = fileInputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
fileInputStream.close();
return outStream.toByteArray();
}
}

@ -40,7 +40,7 @@ spring:
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
enabled: true
url: jdbc:mysql://172.25.227.3:3306/sip_data_gdzc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: gyslgl
password: ryw!@63@w%4

@ -336,6 +336,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="req.isFmqd != null">
AND a.is_fmqd = #{req.isFmqd}
</if>
<if test="req.status != null">
AND a.status = #{req.status}
</if>
</where>
order by create_time desc
</select>

@ -1,6 +0,0 @@
<?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.docking.mapper.ProjectMapper">
</mapper>

@ -7,8 +7,8 @@
FROM
project_progress a
LEFT JOIN project b ON a.project_id = b.project_id
LEFT JOIN gysl_basic_information c ON b.company_id = c.tyshxydm
where c.id = #{req.xmId}
where b.project_name = #{name}
order by a.month desc
</select>
</mapper>

Loading…
Cancel
Save