diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/1.sql b/1.sql index 7a70481..baa7672 100644 --- a/1.sql +++ b/1.sql @@ -3,7 +3,7 @@ -- https://www.phpmyadmin.net/ -- -- 主机: localhost --- 生成日期: 2024-12-17 10:01:30 +-- 生成日期: 2024-12-27 11:01:34 -- 服务器版本: 8.0.35 -- PHP 版本: 8.0.26 @@ -18,7 +18,7 @@ SET time_zone = "+00:00"; /*!40101 SET NAMES utf8mb4 */; -- --- 数据库: `zjzwx3` +-- 数据库: `zjzwx1` -- -- -------------------------------------------------------- @@ -41,7 +41,7 @@ CREATE TABLE `admin` ( CREATE TABLE `app_set` ( `id` int NOT NULL COMMENT '探索中心设置表', - `type` int DEFAULT NULL COMMENT '类型:1鉴黄,2美颜,3智能证件照,4六寸排版照,5老照片上色,6智能抠图,7照片清晰增强,8新海诚动漫风', + `type` int DEFAULT NULL COMMENT '类型:1鉴黄,2美颜,3智能证件照,4六寸排版照,5老照片上色,6智能抠图,7图片编辑,8新海诚动漫风', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名字', `status` int DEFAULT '1' COMMENT '0关闭,1开启,2次数限制(status==2时type=1和2没用 | type==3时 0代表关闭下载高清证件照广告,1代表开启广告下载高清证件照广告,2没用)', `counts` int DEFAULT '0' COMMENT '用户每天免费次数(type=1,2,3没用)' @@ -56,7 +56,7 @@ INSERT INTO `app_set` (`id`, `type`, `name`, `status`, `counts`) VALUES (2, 4, '六寸排版照', 1, 0), (3, 5, '老照片上色', 1, 0), (4, 6, '智能抠图', 1, 0), -(5, 7, '照片清晰增强', 1, 0), +(5, 7, '图片编辑', 1, 0), (6, 8, '新海诚动漫风', 1, 0), (7, 1, '鉴黄', 0, 0), (8, 2, '美颜', 1, 0); @@ -888,7 +888,7 @@ CREATE TABLE `photo` ( CREATE TABLE `photo_record` ( `id` int NOT NULL COMMENT '用户行为记录', - `type` int DEFAULT '0' COMMENT '类型:0旧数据,1生成证件照,2生成高清证件照,3换背景,4下载证件照,5老照片上色,6智能抠图,7六寸排版照,8动漫风照,9照片清晰增强,10上传图片', + `type` int DEFAULT '0' COMMENT '类型:0旧数据,1生成证件照,2生成高清证件照,3换背景,4下载证件照,5老照片上色,6智能抠图,7六寸排版照,8动漫风照,9图片编辑,10上传图片', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名字', `user_id` int DEFAULT NULL COMMENT '用户id', `create_time` datetime DEFAULT NULL COMMENT '创建时间' diff --git a/README.md b/README.md index 9873659..e5c5cc2 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ uniapp多端兼容版:https://github.com/wmlcjj/AI-IDPhoto # ⭐最近更新 版本更新教程:https://www.bilibili.com/video/BV1xNUvYTEjo -- 2024.12.17:跟上HivisionIDPhotos(2024.11.20),增加美颜,探索功能增加每日免费次数,功能可以管理员后台自由开关控制,修复90%的历史遗留包裹,sql更新教程:https://www.0po.cn/archives/50 ,以后如果有更新计划将会在周五/六/日的某一天进行更新 +- 2024.END: 2024年最后一个版本,感谢有你🙏,2025年我们一起加油💪! 修复所有的历史遗留包裹,增加图片编辑,增加物理删除图片,增强管理员后台 +- 2024.12.17:跟上HivisionIDPhotos(2024.11.20),增加美颜,探索功能增加每日免费次数,功能可以管理员后台自由开关控制,修复90%的历史遗留包裹,升级到此版本的sql更新教程:https://www.0po.cn/archives/50 - 2024.12.11:紧急修复图片动漫风功能图片太大导致无法生成的问题 - 2024.12.06:增加图片动漫风功能 - 2024.11.29:优化加快itemList和photoList接口,修正六寸排版照存储库名不规范 @@ -91,7 +92,7 @@ uniapp多端兼容版:https://github.com/wmlcjj/AI-IDPhoto - 无需单独购买API - 本地0成本处理 - 无限免费调用API -- 自带759+尺寸 +- 自带700+尺寸 - 不保存用户图片,仅保存生成后的最新一张 - 支持水印 - 支持流量主 @@ -103,8 +104,10 @@ uniapp多端兼容版:https://github.com/wmlcjj/AI-IDPhoto - 支持相机拍摄和相册选择 - 支持管理员网页后台 - 黑白图片上色 -- 通用抠图 +- 智能抠图 - 动漫图片 +- 图片编辑 +- 六寸排版 - 无感登录 @@ -201,12 +204,23 @@ uniapp多端兼容版:https://github.com/wmlcjj/AI-IDPhoto # ⚡️注意 +1. 如果因为动漫风图片导致小程序不过审核,解决办法:管理员后台关闭这个功能,然后去提交审核,等审核通过后再开启 +2. 本项目使用IDEA打包后,会自动把打包后的jar包放入D:\jar2 +3. 鉴黄模型目前不怎么精准,建议在小程序过审时打开,其它时间关闭 +4. 部署自已鉴黄和证件照APi时,不建议开设外网,防止被抓接口后滥用,yml里面配置127.0.0.1即可本地链接,速度还快,还安全 +5. 为什么不把APi地址等参数放入数据库来配置?答:频繁使用的值,不建议与Mysql频繁握手 +6. 当你部署到云上(服务器)时,别忘记配置你的小程序域名(如图)

+ +
+
+ +# 🌟🤝🌟给二开作者的一些话 +目前整个项目已完结,除了发生漏洞基本不会再去更新,后端和前端注释都有写,代码没有使用很复杂的拆分,很适合编程初学者,所以你可以放心大胆的去二开创作 +
+在这个项目里,完全由本人一人完工,产品,UI,前端,后端,测试,运维很费心,一些地方做的不够好,十分抱歉 +
+我是初中开始接触编程,本人02年,见过互联网全民站长的时代,也见过当时互联网猪都能起飞的时代,本次也特别感谢HivisionIDPhotos让我找回当年的热爱,目前我已辞去程序员工作,已经彻底转行 -1. 本项目使用IDEA打包后,会自动把打包后的jar包放入D:\jar2 -2. 鉴黄模型目前不怎么精准,建议在小程序过审时打开,其它时间关闭 -3. 部署自已鉴黄和证件照APi时,不建议开设外网,防止被抓接口后滥用,yml里面配置127.0.0.1即可本地链接,速度还快,还安全 -4. 为什么不把APi地址等参数放入数据库来配置?答:频繁使用的值,不建议与Mysql频繁握手 -5. 当你部署到云上(服务器)时,别忘记配置你的小程序域名(如图)



@@ -214,23 +228,6 @@ uniapp多端兼容版:https://github.com/wmlcjj/AI-IDPhoto # 📧其它 -如您在部署过程中遇到问题,双方空闲时间可远程一对一给予帮助(不收费) -
-

-但 -
-拒绝科普任何小程序知识点,拒绝从来没接触过互联网行业的人(指电脑不会使用,就想搞个小程序) -
-如果您属于已上拒绝点的人,但仍然不想自已研究 -
-那么,请知识付费100人民币 -
-或 -
-去使用鹧应证件照:https://zjzapi.com/software/index.html -


-
-

您可以通过以下方式联系我:
@@ -239,6 +236,6 @@ QQ: 24677102 微信:webxuan



-目前本人属于负债状态,如本项目对您有帮助,希望能得到您的赏赐,祝您生活愉快 +目前本人属于负债状态,如本项目对您有帮助,希望能得到您的赞赏。祝您2025年财源滚滚,运气爆棚!

diff --git a/pom.xml b/pom.xml index 2d7c60e..de92ec4 100644 --- a/pom.xml +++ b/pom.xml @@ -63,10 +63,6 @@ org.apache.commons commons-pool2 - - org.apache.httpcomponents - httpclient - org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/org/zjzWx/App.java b/src/main/java/org/zjzWx/App.java index 38dad2e..58cd438 100644 --- a/src/main/java/org/zjzWx/App.java +++ b/src/main/java/org/zjzWx/App.java @@ -2,6 +2,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @@ -10,6 +11,6 @@ public class App { public static void main(String[] args) { System.out.println("欢迎使用证件照伴侣服务"); SpringApplication.run(App.class, args); - System.out.println("服务启动成功-当前版本:v2024.12.17"); + System.out.println("服务启动成功-当前版本:2024年最后一个版本,祝您2025年财源滚滚,运气爆棚!"); } } diff --git a/src/main/java/org/zjzWx/controller/AdminController.java b/src/main/java/org/zjzWx/controller/AdminController.java index b1a3ce6..96a874a 100644 --- a/src/main/java/org/zjzWx/controller/AdminController.java +++ b/src/main/java/org/zjzWx/controller/AdminController.java @@ -80,31 +80,31 @@ public R getItemPage(int pageNum, int pageSize, String name){ } - //管理员用户定制规格列表 + //定制列表 @PostMapping("/getCustomPage") - public R getCustomPage(int pageNum, int pageSize, String name){ + public R getCustomPage(int pageNum, int pageSize, int userId){ int id = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()); if(id!=1){ return R.no("非法请求"); } - return R.ok(adminService.getCustomPage(pageNum, pageSize, name)); + return R.ok(adminService.getCustomPage(pageNum, pageSize, userId)); } //保存列表 @PostMapping("/getPhotoPage") - public R getPhotoPage(int pageNum, int pageSize, String name){ + public R getPhotoPage(int pageNum, int pageSize,int userId,String name){ int id = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()); if(id!=1){ return R.no("非法请求"); } - return R.ok(adminService.getPhotoPage(pageNum,pageSize,name)); + return R.ok(adminService.getPhotoPage(pageNum,pageSize,userId,name)); } //行为记录 @PostMapping("/getPhotoRecordPage") - public R getPhotoRecordPage(int pageNum, int pageSize, Integer userId){ + public R getPhotoRecordPage(int pageNum, int pageSize, int userId){ int id = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()); if(id!=1){ return R.no("非法请求"); @@ -114,12 +114,12 @@ public R getPhotoRecordPage(int pageNum, int pageSize, Integer userId){ //用户列表 @PostMapping("/getUserPage") - public R getUserPage(int pageNum, int pageSize, String name){ + public R getUserPage(int pageNum, int pageSize,int userId,String name){ int id = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()); if(id!=1){ return R.no("非法请求"); } - return R.ok(adminService.getUserPage(pageNum,pageSize,name)); + return R.ok(adminService.getUserPage(pageNum,pageSize,userId,name)); } @@ -192,20 +192,24 @@ public R updateExploreSet(@RequestBody AppSet appSet){ return R.ok(null); } - //操作用户状态 + + //用户列表面板:type=1踢掉登录状态,2删除定制记录,3删除保存记录,4删除行为记录,5禁止登录并踢掉登录,6恢复登录 @PostMapping("/updateUserStatus") public R updateUserStatus(Integer userId,Integer type){ int id = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()); if(id!=1){ return R.no("非法请求"); } - if(type<1 || type>2){ - return R.no("非法请求"); + if(1==userId && 1==type){ + return R.no("您不能踢掉自已的登录状态"); } - adminService.updateUserStatus(userId,type); - return R.ok(null); + if(1==userId && 5==type){ + return R.no("您不能禁止自已登录"); + } + return R.ok(adminService.updateUserStatus(userId,type)); } + //使用量统计 @PostMapping("/exploreIndexAdmin") public R exploreIndexAdmin(){ diff --git a/src/main/java/org/zjzWx/controller/ItemController.java b/src/main/java/org/zjzWx/controller/ItemController.java index ed7fe5a..a0d0a0a 100644 --- a/src/main/java/org/zjzWx/controller/ItemController.java +++ b/src/main/java/org/zjzWx/controller/ItemController.java @@ -58,13 +58,10 @@ public R photoList(int pageNum, int pageSize){ return R.ok(photoService.photoList(pageNum, pageSize, StpUtil.getTokenInfo().getLoginId().toString())); } - //删除作品(下个版本更新物理删除) + //删除作品 @GetMapping("/deletePhotoId") public R deletePhotoId(int id){ - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("id",id); - qw.eq("user_id",StpUtil.getTokenInfo().getLoginId()); - photoService.remove(qw); + photoService.deletePhotoId(id,StpUtil.getTokenInfo().getLoginId().toString()); return R.ok(null); } diff --git a/src/main/java/org/zjzWx/controller/OtherApiController.java b/src/main/java/org/zjzWx/controller/OtherApiController.java index 612bd0e..217cbc7 100644 --- a/src/main/java/org/zjzWx/controller/OtherApiController.java +++ b/src/main/java/org/zjzWx/controller/OtherApiController.java @@ -20,6 +20,12 @@ public R exploreCount(){ return R.ok(otherApiService.exploreDtoCount()); } + @GetMapping("/checkTheFreeQuota") + public R checkTheFreeQuota(Integer type,Integer type2) { + long count = otherApiService.checkTheFreeQuota(type, type2, Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString())); + return R.ok(count); + } + @PostMapping("/colourize") public R colourize(@RequestBody ExploreDto exploreDto) { @@ -62,10 +68,14 @@ public R cartoon(@RequestBody ExploreDto exploreDto) { return R.ok(cartoon); } - @GetMapping("/checkTheFreeQuota") - public R checkTheFreeQuota(Integer type,Integer type2) { - long count = otherApiService.checkTheFreeQuota(type, type2, Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString())); - return R.ok(count); + @PostMapping("/editImage") + public R editImage(@RequestBody ExploreDto exploreDto) { + exploreDto.setUserId(Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString())); + String editImage = otherApiService.editImage(exploreDto); + if(null==editImage){ + return R.no("图片编辑失败,请重试"); + } + return R.ok(editImage); } diff --git a/src/main/java/org/zjzWx/entity/AppSet.java b/src/main/java/org/zjzWx/entity/AppSet.java index 58d476d..1a37afa 100644 --- a/src/main/java/org/zjzWx/entity/AppSet.java +++ b/src/main/java/org/zjzWx/entity/AppSet.java @@ -17,7 +17,7 @@ public class AppSet { @TableId(type = IdType.AUTO) private Integer id; /** - * 类型:1鉴黄,2美颜,3智能证件照,4六寸排版照,5老照片上色,6智能抠图,7照片清晰增强,8新海诚动漫风 + * 类型:1鉴黄,2美颜,3智能证件照,4六寸排版照,5老照片上色,6智能抠图,7图片编辑,8新海诚动漫风 */ private Integer type; /** diff --git a/src/main/java/org/zjzWx/entity/PhotoRecord.java b/src/main/java/org/zjzWx/entity/PhotoRecord.java index 002b05e..e546d07 100644 --- a/src/main/java/org/zjzWx/entity/PhotoRecord.java +++ b/src/main/java/org/zjzWx/entity/PhotoRecord.java @@ -22,7 +22,7 @@ public class PhotoRecord { /** * 类型: * 0旧数据,1生成证件照,2生成高清证件照,3换背景,4下载证件照,5老照片上色 - * 6智能抠图,7六寸排版照,8动漫风照,9照片清晰增强,10上传图片 + * 6智能抠图,7六寸排版照,8动漫风照,9图片编辑,10上传图片 */ private Integer type; /** diff --git a/src/main/java/org/zjzWx/model/dto/ExploreDto.java b/src/main/java/org/zjzWx/model/dto/ExploreDto.java index 132c52a..975470b 100644 --- a/src/main/java/org/zjzWx/model/dto/ExploreDto.java +++ b/src/main/java/org/zjzWx/model/dto/ExploreDto.java @@ -8,6 +8,7 @@ @AllArgsConstructor @NoArgsConstructor public class ExploreDto { + //用户id,由控制器解密token传入 private Integer userId; //图片分辨率,抠图/六寸排版用到 private Integer dpi; diff --git a/src/main/java/org/zjzWx/model/dto/ExploreIndexAdminDto.java b/src/main/java/org/zjzWx/model/dto/ExploreIndexAdminDto.java index 68e026a..a5c7b9d 100644 --- a/src/main/java/org/zjzWx/model/dto/ExploreIndexAdminDto.java +++ b/src/main/java/org/zjzWx/model/dto/ExploreIndexAdminDto.java @@ -19,7 +19,7 @@ public class ExploreIndexAdminDto { //动漫数量 private long cartoonCount; //清晰度数量 - private long imageDefinitionEnhanceCount; + private long editImageCount; //上传图片数量 private long imageuploadCount; //总计 diff --git a/src/main/java/org/zjzWx/model/dto/ExploreIndexDto.java b/src/main/java/org/zjzWx/model/dto/ExploreIndexDto.java index 9e9e6d1..ace87bb 100644 --- a/src/main/java/org/zjzWx/model/dto/ExploreIndexDto.java +++ b/src/main/java/org/zjzWx/model/dto/ExploreIndexDto.java @@ -18,6 +18,6 @@ public class ExploreIndexDto { private long mattingCount; //动漫数量 private long cartoonCount; - //清晰度数量 - private long imageDefinitionEnhanceCount; + //图片编辑数量 + private long editImageCount; } diff --git a/src/main/java/org/zjzWx/service/AdminService.java b/src/main/java/org/zjzWx/service/AdminService.java index 4fffbaf..c10ccb7 100644 --- a/src/main/java/org/zjzWx/service/AdminService.java +++ b/src/main/java/org/zjzWx/service/AdminService.java @@ -28,16 +28,16 @@ public interface AdminService extends IService { IPage getItemPage(int pageNum, int pageSize, String name); //用户自定义分页 - IPage getCustomPage(int pageNum, int pageSize, String name); + IPage getCustomPage(int pageNum, int pageSize, int userId); //保存列表 - IPage getPhotoPage(int pageNum, int pageSize, String name); + IPage getPhotoPage(int pageNum, int pageSize, int userId,String name); //行为记录 - IPage getPhotoRecordPage(int pageNum, int pageSize, Integer userId); + IPage getPhotoRecordPage(int pageNum, int pageSize,int userId); //用户列表 - IPage getUserPage(int pageNum, int pageSize, String name); + IPage getUserPage(int pageNum, int pageSize,int userId,String name); //读取系统设置 WebSet getWebSet(); @@ -57,8 +57,8 @@ public interface AdminService extends IService { //修改探索中心设置 void updateExploreSet(AppSet appSet); - //操作用户状态 - void updateUserStatus(Integer userId,Integer type); + //用户列表面板:type=1踢掉登录状态,2删除定制记录,3删除保存记录,4删除行为记录,5禁止登录并踢掉登录,6恢复登录 + String updateUserStatus(Integer userId,Integer type); //使用量统计 ExploreIndexAdminDto exploreIndexAdmin(); diff --git a/src/main/java/org/zjzWx/service/OtherApiService.java b/src/main/java/org/zjzWx/service/OtherApiService.java index 5e7a2de..bc8180c 100644 --- a/src/main/java/org/zjzWx/service/OtherApiService.java +++ b/src/main/java/org/zjzWx/service/OtherApiService.java @@ -9,18 +9,23 @@ public interface OtherApiService { //页面统计数据 ExploreIndexDto exploreDtoCount(); + //返回用户今日剩余次数,type对应explore_set表,type2对应photo_record + long checkTheFreeQuota(Integer type,Integer type2,Integer userId); + //黑白图片上色 String colourize(ExploreDto exploreDto); //智能抠图 String matting(ExploreDto exploreDto); - //生成六寸排版照 + //六寸排版照 String generateLayoutPhotos(ExploreDto exploreDto); - //生成动漫风滤镜(新海诚画风) + //动漫风滤镜(新海诚画风) String cartoon(ExploreDto exploreDto); - //返回用户剩余次数,type对应explore_set表,type2对应photo_record - long checkTheFreeQuota(Integer type,Integer type2,Integer userId); + //图片编辑 + String editImage(ExploreDto exploreDto); + + } diff --git a/src/main/java/org/zjzWx/service/PhotoService.java b/src/main/java/org/zjzWx/service/PhotoService.java index 3fb831d..effa79b 100644 --- a/src/main/java/org/zjzWx/service/PhotoService.java +++ b/src/main/java/org/zjzWx/service/PhotoService.java @@ -10,4 +10,6 @@ public interface PhotoService extends IService { Page photoList(int pageNum, int pageSize, String userId); + void deletePhotoId(Integer id,String userId); + } diff --git a/src/main/java/org/zjzWx/service/impl/AdminServiceImpl.java b/src/main/java/org/zjzWx/service/impl/AdminServiceImpl.java index cafc4e2..05e771f 100644 --- a/src/main/java/org/zjzWx/service/impl/AdminServiceImpl.java +++ b/src/main/java/org/zjzWx/service/impl/AdminServiceImpl.java @@ -1,7 +1,6 @@ package org.zjzWx.service.impl; import cn.dev33.satoken.stp.StpUtil; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -9,25 +8,21 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.zjzWx.dao.AdminDao; import org.zjzWx.entity.*; import org.zjzWx.model.dto.ExploreIndexAdminDto; -import org.zjzWx.model.dto.ExploreIndexDto; import org.zjzWx.model.vo.AdminIndexVo; import org.zjzWx.model.vo.AdminLoginVo; import org.zjzWx.model.vo.ChartDataVo; import org.zjzWx.service.*; -import org.zjzWx.util.HttpClient; +import org.zjzWx.util.PicUtil; import org.zjzWx.util.R; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.PrintWriter; -import java.net.HttpURLConnection; -import java.net.URL; import java.time.*; import java.util.*; @@ -36,6 +31,8 @@ public class AdminServiceImpl extends ServiceImpl implements Ad @Value("${webset.envVersion}") private String envVersion; + @Value("${webset.directory}") + private String directory; @Autowired private WebSetService webSetService; @@ -66,58 +63,38 @@ public AdminLoginVo login() { mp.put("scene", code); mp.put("page", "pages/admin/index"); mp.put("check_path", false); - // 要打开的小程序版本。正式版为 "release",体验版为 "release",开发版为 "develop"。默认是正式版 - mp.put("env_version", envVersion); + mp.put("env_version", envVersion); //要打开的小程序版本。正式版为 "release",体验版为 "release",开发版为 "develop" + + //获取access_token String url1 = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + webSet.getAppId() + "&secret=" + webSet.getAppSecret(); - HttpClient http1 = new HttpClient(url1); - http1.setHttps(true); - http1.post(); - // 格式化微信官方返回 - JSONObject jsonopenid = JSONObject.parseObject(http1.getContent()); + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.exchange(url1, HttpMethod.GET, null, String.class); + JSONObject jsonopenid = JSONObject.parseObject(response.getBody()); String accessToken = jsonopenid.getString("access_token"); - // 调用微信接口生成小程序码 - URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken); - HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); - httpURLConnection.setRequestMethod("POST"); - httpURLConnection.setConnectTimeout(10000); - httpURLConnection.setReadTimeout(10000); - httpURLConnection.setDoOutput(true); - httpURLConnection.setDoInput(true); - - PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream()); - printWriter.write(JSON.toJSONString(mp)); - printWriter.flush(); - printWriter.close(); - - // 读取响应 - InputStream inputStream = httpURLConnection.getInputStream(); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len; - while ((len = inputStream.read(buffer)) != -1) { - byteArrayOutputStream.write(buffer, 0, len); - } - // 关闭流 - inputStream.close(); - byteArrayOutputStream.close(); + // 获取小程序码 + String url2 = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity<>(JSONObject.toJSONString(mp), headers); + ResponseEntity byteResponse = restTemplate.exchange(url2, HttpMethod.POST, entity, byte[].class); + - // 将响应字节数组转换为MultipartFile - byte[] imageBytes = byteArrayOutputStream.toByteArray(); - MultipartFile multipartFile = new MockMultipartFile("file", "qrcode.png", "image/jpg", imageBytes); + //将响应字节数组转换为 MultipartFile 再转 base64 + MultipartFile multipartFile = new MockMultipartFile("file", "qrcode.png", "image/jpg", byteResponse.getBody()); + R data = uploadService.uploadPhoto(multipartFile, "qrcode.png"); - // 转换成base64 - R r = uploadService.uploadPhoto(multipartFile, "qrcode.png"); - //无论成功失败,清理所有记录,防止网页多次生成导致离奇bug + //无论成功失败,清理所有记录,防止打开多个网页标签而导致多次生成的问题 baseMapper.delete(null); - if (r.getCode() == 200) { + + if (data.getCode() == 200) { Admin admin = new Admin(); admin.setCode(code); baseMapper.insert(admin); AdminLoginVo adminLoginVo = new AdminLoginVo(); - adminLoginVo.setPic(r.getData().toString()); + adminLoginVo.setPic(data.getData().toString()); adminLoginVo.setCode(code); return adminLoginVo; } @@ -127,6 +104,8 @@ public AdminLoginVo login() { return null; } + + @Override public String checkLogin(String code) { QueryWrapper qw = new QueryWrapper<>(); @@ -155,24 +134,31 @@ public String okLogin(String code1, String code2) { } WebSet webSet = webSetService.getById(1); - //发起登录请求 String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+webSet.getAppId() +"&secret="+webSet.getAppSecret()+"&js_code=" + code1 + "&grant_type=authorization_code"; - HttpClient http = new HttpClient(url); - http.setHttps(true); - http.post(); - String content = http.getContent(); - //格式化微信官方返回 - JSONObject jsonopenid = JSONObject.parseObject(content); + + //发起请求 + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.getForEntity(url, String.class); + JSONObject jsonopenid = JSONObject.parseObject(response.getBody()); + if(null==jsonopenid){ + return "与微信通讯失败,请重试"; + } + String openid = jsonopenid.getString("openid"); - if(null==openid){ //高风险的微信用户/数据库配置错误/安全域名没有添加会存在openid没有的情况 - return "与微信通讯失败"; + // 高风险的微信用户/数据库配置错误/安全域名没有添加会存在openid没有的情况 + if (null==openid) { + return jsonopenid.toString(); } QueryWrapper qwuser = new QueryWrapper<>(); qwuser.eq("openid",openid); User user = userService.getOne(qwuser); - if(null!=user && 1==user.getId()){ + if(null==user){ + return "您未注册,无法检查您是否为管理员"; + } + + if(1==user.getId()){ admin.setStatus(1); baseMapper.updateById(admin); return null; @@ -280,20 +266,23 @@ public IPage getItemPage(int pageNum, int pageSize, String name) { } @Override - public IPage getCustomPage(int pageNum, int pageSize, String name) { + public IPage getCustomPage(int pageNum, int pageSize, int userId) { Page page = new Page<>(pageNum, pageSize); QueryWrapper qw = new QueryWrapper<>(); - if(null!=name && !"".equals(name)){ - qw.like("name",name); + if(0!=userId){ + qw.eq("user_id",userId); } qw.orderByDesc("create_time"); return customService.page(page, qw); } @Override - public IPage getPhotoPage(int pageNum, int pageSize, String name) { + public IPage getPhotoPage(int pageNum, int pageSize, int userId,String name) { Page page = new Page<>(pageNum, pageSize); QueryWrapper qw = new QueryWrapper<>(); + if(0!=userId){ + qw.eq("user_id",userId); + } if(null!=name && !"".equals(name)){ qw.like("name",name); } @@ -303,10 +292,10 @@ public IPage getPhotoPage(int pageNum, int pageSize, String name) { } @Override - public IPage getPhotoRecordPage(int pageNum, int pageSize, Integer userId) { + public IPage getPhotoRecordPage(int pageNum, int pageSize, int userId) { Page page = new Page<>(pageNum, pageSize); QueryWrapper qw = new QueryWrapper<>(); - if(null!=userId && 0!=userId){ + if(0!=userId){ qw.eq("user_id",userId); } qw.orderByDesc("create_time"); @@ -314,9 +303,12 @@ public IPage getPhotoRecordPage(int pageNum, int pageSize, Integer } @Override - public IPage getUserPage(int pageNum, int pageSize, String name) { + public IPage getUserPage(int pageNum, int pageSize,int userId,String name) { Page page = new Page<>(pageNum, pageSize); QueryWrapper qw = new QueryWrapper<>(); + if(0!=userId){ + qw.eq("id",userId); + } if(null!=name && !"".equals(name)){ qw.like("nickname",name); } @@ -326,7 +318,7 @@ public IPage getUserPage(int pageNum, int pageSize, String name) { @Override public WebSet getWebSet() { - return webSetService.getOne(null); + return webSetService.getById(1); } @Override @@ -358,11 +350,49 @@ public void updateExploreSet(AppSet appSet) { } @Override - public void updateUserStatus(Integer userId, Integer type) { - User user = new User(); - user.setId(userId); - user.setStatus(type); - userService.updateById(user); + public String updateUserStatus(Integer userId, Integer type) { + //type=1踢掉登录状态,2删除定制记录,3删除保存记录,4删除行为记录,5禁止登录并踢掉登录,6恢复登录 + if(type==1){ + StpUtil.kickout(userId); + return "踢掉成功"; + }else if(type==2){ + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("user_id",userId); + customService.remove(qw); + return "删除成功"; + }else if(type==3){ + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("user_id",userId); + List list = photoService.list(qw); + if(null!=list && list.size()>0){ + for (Photo photo : list) { + PicUtil.deleteImage(photo.getNImg(),directory); + photoService.removeById(photo); + } + } + return "删除成功"; + }else if(type==4){ + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("user_id",userId); + photoRecordService.remove(qw); + return "删除成功"; + }else if(type==5){ + User user = new User(); + user.setId(userId); + user.setStatus(2); + userService.updateById(user); + StpUtil.kickout(userId); + return "已禁止并踢掉登录"; + }else if(type==6){ + User user = new User(); + user.setId(userId); + user.setStatus(1); + userService.updateById(user); + return "已恢复"; + }else { + return "非法请求"; + } + } @Override @@ -397,7 +427,7 @@ public ExploreIndexAdminDto exploreIndexAdmin() { if(appSet.getType()==7){ QueryWrapper qw5 = new QueryWrapper<>(); qw5.eq("type",9); - exploreIndexAdmin.setImageDefinitionEnhanceCount(photoRecordService.count(qw5)); + exploreIndexAdmin.setEditImageCount(photoRecordService.count(qw5)); } if(appSet.getType()==8){ diff --git a/src/main/java/org/zjzWx/service/impl/OtherApiServiceImpl.java b/src/main/java/org/zjzWx/service/impl/OtherApiServiceImpl.java index be2a314..ceea051 100644 --- a/src/main/java/org/zjzWx/service/impl/OtherApiServiceImpl.java +++ b/src/main/java/org/zjzWx/service/impl/OtherApiServiceImpl.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.zjzWx.entity.AppSet; @@ -16,6 +17,7 @@ import org.zjzWx.model.dto.*; import org.zjzWx.service.*; import org.zjzWx.util.PicUtil; +import org.zjzWx.util.R; import java.time.*; import java.util.Date; @@ -49,6 +51,8 @@ public class OtherApiServiceImpl implements OtherApiService { private PhotoRecordService photoRecordService; @Autowired private AppSetService appSetService; + @Autowired + private UploadService uploadService; @@ -95,11 +99,11 @@ public ExploreIndexDto exploreDtoCount() { } if(appSet.getType()==7){ if(appSet.getStatus()==0){ - exploreIndexDto.setImageDefinitionEnhanceCount(-1L);; + exploreIndexDto.setEditImageCount(-1L);; }else { QueryWrapper qw5 = new QueryWrapper<>(); qw5.eq("type",9); - exploreIndexDto.setImageDefinitionEnhanceCount(photoRecordService.count(qw5)); + exploreIndexDto.setEditImageCount(photoRecordService.count(qw5)); } } @@ -372,7 +376,70 @@ public String cartoon(ExploreDto exploreDto) { record.setUserId(exploreDto.getUserId()); record.setCreateTime(new Date()); photoRecordService.save(record); - ; + + return imagePath; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + + @Override + public String editImage(ExploreDto exploreDto) { + + try { + //base64转MultipartFile,进行保存文件并返回url + MultipartFile file = PicUtil.base64ToMultipartFile(exploreDto.getProcessedImage()); + + //危险接口,必须再一次检查,防止数据伪造,如:被劫持数据包上传黄色,木马什么的 + // 检查文件类型 + String originalFilename = file.getOriginalFilename(); + if (!StringUtils.hasText(originalFilename) || (!originalFilename.toLowerCase().endsWith(".png") + && !originalFilename.toLowerCase().endsWith(".jpg")) && !originalFilename.toLowerCase().endsWith(".jpeg")) { + // 文件类型不合法 + return null; + } + + // 防止被当图床 + if (file.getSize() > 15 * 1024 * 1024) { + return null; + } + + + QueryWrapper qwapp = new QueryWrapper<>(); + qwapp.eq("type",1); + AppSet appSet = appSetService.getOne(qwapp); + //如果开启鉴黄 + if(appSet.getStatus()==1){ + String s = uploadService.checkNsfw(file); + if(s!=null){ + return null; + } + } + + String filename = PicUtil.filesCopy("editImage", directory, originalFilename, file); + + String imagePath = picDomain + "editImage" + "/" + filename; + + + Photo photo = new Photo(); + photo.setUserId(exploreDto.getUserId()); + photo.setName("图片编辑"); + photo.setNImg(imagePath); + photo.setSize("无规格"); + photo.setCreateTime(new Date()); + photoService.save(photo); + + + //保存用户行为记录 + PhotoRecord record = new PhotoRecord(); + record.setType(9); + record.setName("生成图片编辑"); + record.setUserId(exploreDto.getUserId()); + record.setCreateTime(new Date()); + photoRecordService.save(record); + return imagePath; } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/org/zjzWx/service/impl/PhotoServiceImpl.java b/src/main/java/org/zjzWx/service/impl/PhotoServiceImpl.java index a1bdcc9..87614a1 100644 --- a/src/main/java/org/zjzWx/service/impl/PhotoServiceImpl.java +++ b/src/main/java/org/zjzWx/service/impl/PhotoServiceImpl.java @@ -1,12 +1,15 @@ package org.zjzWx.service.impl; +import cn.dev33.satoken.stp.StpUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Value; import org.zjzWx.dao.PhotoDao; import org.zjzWx.entity.Photo; import org.zjzWx.service.PhotoService; import org.springframework.stereotype.Service; +import org.zjzWx.util.PicUtil; import java.util.List; @@ -14,6 +17,8 @@ @Service public class PhotoServiceImpl extends ServiceImpl implements PhotoService { + @Value("${webset.directory}") + private String directory; @Override public Page photoList(int pageNum, int pageSize, String userId) { @@ -25,4 +30,18 @@ public Page photoList(int pageNum, int pageSize, String userId) { qw.orderByDesc("create_time"); return baseMapper.selectPage(page, qw); } + + @Override + public void deletePhotoId(Integer id, String userId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("id",id); + qw.eq("user_id",userId); + Photo photo = baseMapper.selectOne(qw); + if(null!=photo){ + PicUtil.deleteImage(photo.getNImg(),directory); + baseMapper.deleteById(photo); + } + } + + } diff --git a/src/main/java/org/zjzWx/service/impl/UserServiceImpl.java b/src/main/java/org/zjzWx/service/impl/UserServiceImpl.java index 9fd8260..a513efb 100644 --- a/src/main/java/org/zjzWx/service/impl/UserServiceImpl.java +++ b/src/main/java/org/zjzWx/service/impl/UserServiceImpl.java @@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; +import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.zjzWx.dao.UserDao; import org.zjzWx.entity.User; @@ -15,14 +17,7 @@ import org.zjzWx.service.UserService; import org.springframework.stereotype.Service; import org.zjzWx.service.WebSetService; -import org.zjzWx.util.HttpClient; import org.zjzWx.util.PicUtil; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -47,21 +42,26 @@ public WxLoginVo wxlogin(String code) { WxLoginVo wxlogin = new WxLoginVo(); try { WebSet webSet = webSetService.getById(1); - //发起登录请求 String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+webSet.getAppId() +"&secret="+webSet.getAppSecret()+"&js_code=" + code + "&grant_type=authorization_code"; - HttpClient http = new HttpClient(url); - http.setHttps(true); - http.post(); - String content = http.getContent(); - //格式化微信官方返回 - JSONObject jsonopenid = JSONObject.parseObject(content); + + //发起请求 + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.getForEntity(url, String.class); + JSONObject jsonopenid = JSONObject.parseObject(response.getBody()); + if(null==jsonopenid){ + wxlogin.setMsg("与微信通讯失败,请重试"); + return wxlogin; + } + String openid = jsonopenid.getString("openid"); - if(null==openid){ //高风险的微信用户/数据库配置错误/安全域名没有添加会存在openid没有的情况 + // 高风险的微信用户/数据库配置错误/安全域名没有添加会存在openid没有的情况 + if (null==openid) { wxlogin.setMsg(jsonopenid.toString()); return wxlogin; } + //获取openid成功 QueryWrapper qw = new QueryWrapper<>(); qw.eq("openid",openid); User user = baseMapper.selectOne(qw); diff --git a/src/main/java/org/zjzWx/task/PhotoTask.java b/src/main/java/org/zjzWx/task/PhotoTask.java index 8d62226..3d2f692 100644 --- a/src/main/java/org/zjzWx/task/PhotoTask.java +++ b/src/main/java/org/zjzWx/task/PhotoTask.java @@ -2,13 +2,21 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.zjzWx.entity.Photo; import org.zjzWx.service.PhotoService; +import org.zjzWx.util.PicUtil; + +import java.util.List; @Component public class PhotoTask { + + + @Value("${webset.directory}") + private String directory; @Autowired private PhotoService photoService; @@ -17,7 +25,12 @@ public class PhotoTask { public void executeTask() { QueryWrapper qw = new QueryWrapper<>(); qw.isNull("n_img"); - photoService.remove(qw); + List list = photoService.list(qw); + for (Photo photo : list) { + PicUtil.deleteImage(photo.getNImg(),directory); + photoService.removeById(photo); + } + } diff --git a/src/main/java/org/zjzWx/util/HttpClient.java b/src/main/java/org/zjzWx/util/HttpClient.java deleted file mode 100644 index 4e594a3..0000000 --- a/src/main/java/org/zjzWx/util/HttpClient.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.zjzWx.util; - -import org.apache.http.Consts; -import org.apache.http.HttpEntity; -import org.apache.http.NameValuePair; -import org.apache.http.ParseException; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.*; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.util.EntityUtils; - -import javax.net.ssl.SSLContext; -import java.io.IOException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class HttpClient { - private String url; - private Map param; - private int statusCode; - private String content; - private String xmlParam; - private boolean isHttps; - - public boolean isHttps() { - return isHttps; - } - - public void setHttps(boolean isHttps) { - this.isHttps = isHttps; - } - - public String getXmlParam() { - return xmlParam; - } - - public void setXmlParam(String xmlParam) { - this.xmlParam = xmlParam; - } - - public HttpClient(String url, Map param) { - this.url = url; - this.param = param; - } - - public HttpClient(String url) { - this.url = url; - } - - public void setParameter(Map map) { - param = map; - } - - public void addParameter(String key, String value) { - if (param == null) - param = new HashMap(); - param.put(key, value); - } - - public void post() throws ClientProtocolException, IOException { - HttpPost http = new HttpPost(url); - setEntity(http); - execute(http); - } - - public void put() throws ClientProtocolException, IOException { - HttpPut http = new HttpPut(url); - setEntity(http); - execute(http); - } - - public void get() throws ClientProtocolException, IOException { - if (param != null) { - StringBuilder url = new StringBuilder(this.url); - boolean isFirst = true; - for (String key : param.keySet()) { - if (isFirst) { - url.append("?"); - }else { - url.append("&"); - } - url.append(key).append("=").append(param.get(key)); - } - this.url = url.toString(); - } - HttpGet http = new HttpGet(url); - execute(http); - } - - /** - * set http post,put param - */ - private void setEntity(HttpEntityEnclosingRequestBase http) { - if (param != null) { - List nvps = new LinkedList(); - for (String key : param.keySet()) { - nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数 - } - http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数 - } - if (xmlParam != null) { - http.setEntity(new StringEntity(xmlParam, Consts.UTF_8)); - } - } - - private void execute(HttpUriRequest http) throws ClientProtocolException, - IOException { - CloseableHttpClient httpClient = null; - try { - if (isHttps) { - SSLContext sslContext = new SSLContextBuilder() - .loadTrustMaterial(null, new TrustStrategy() { - // 信任所有 - @Override - public boolean isTrusted(X509Certificate[] chain, - String authType) - throws CertificateException { - return true; - } - }).build(); - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( - sslContext); - httpClient = HttpClients.custom().setSSLSocketFactory(sslsf) - .build(); - } else { - httpClient = HttpClients.createDefault(); - } - CloseableHttpResponse response = httpClient.execute(http); - try { - if (response != null) { - if (response.getStatusLine() != null) { - statusCode = response.getStatusLine().getStatusCode(); - } - HttpEntity entity = response.getEntity(); - // 响应内容 - content = EntityUtils.toString(entity, Consts.UTF_8); - } - } finally { - response.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - httpClient.close(); - } - } - - public int getStatusCode() { - return statusCode; - } - - public String getContent() throws ParseException, IOException { - return content; - } -} diff --git a/src/main/java/org/zjzWx/util/PicUtil.java b/src/main/java/org/zjzWx/util/PicUtil.java index f3d528e..6756080 100644 --- a/src/main/java/org/zjzWx/util/PicUtil.java +++ b/src/main/java/org/zjzWx/util/PicUtil.java @@ -18,12 +18,13 @@ //图片工具类 public class PicUtil { + + //图片上传 //folderName 文件夹目录 //directory 图片路径 //originalFilename 原始图片名 //file 前端传过来的图片 public static String filesCopy(String folderName,String directory,String originalFilename,MultipartFile file) throws IOException { - String filename = null; File uploadFolder = new File(directory, folderName); if (!uploadFolder.exists()) { @@ -31,7 +32,7 @@ public static String filesCopy(String folderName,String directory,String origina } // 生成新的文件名 - filename = generateUniqueFilename(originalFilename, file); + String filename = generateUniqueFilename(originalFilename, file); Path filePath = uploadFolder.toPath().resolve(filename); // 保存文件 Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING); @@ -39,6 +40,25 @@ public static String filesCopy(String folderName,String directory,String origina return filename; } + //图片删除 + public static void deleteImage(String picUrl,String directory) { + + String[] parts = picUrl.split("/"); + + File uploadFolder = new File(directory, parts[3]); + // 检查文件夹是否存在 + if (uploadFolder.exists()) { + File fileToDelete = new File(uploadFolder, parts[4]); + // 判断文件是否存在 + if (fileToDelete.exists()) { + fileToDelete.delete(); + } + } + + } + + + public static String generateUniqueFilename(String originalFilename, MultipartFile file) {