From 743a373edb2768f7e6acbcd530de51be66c7fe3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E4=B8=B6=E8=A8=80?= Date: Mon, 23 May 2022 00:48:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E5=9B=BE=E5=BA=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 69 +++---- jieyue.sql | 100 +++------- pom.xml | 42 ++-- .../com/example/jieyue/JieyueApplication.java | 33 +++- .../admin/service/AdminMerchantService.java | 11 +- .../jieyue/admin/service/AdminUiService.java | 32 +-- .../admin/service/AdminUserService.java | 7 +- .../jieyue/common/task/SchedulerTask.java | 38 ++-- .../example/jieyue/common/utils/DateUtil.java | 22 +++ .../example/jieyue/common/utils/FileUtil.java | 78 ++++++++ .../jieyue/common/utils/GiteeImgBedUtils.java | 186 ------------------ .../example/jieyue/common/utils/JsonUtil.java | 21 ++ .../jieyue/common/utils/QRCodeUtil.java | 27 ++- .../jieyue/common/utils/StringUtil.java | 20 ++ .../controller/MerchantGoodsController.java | 4 +- .../controller/MerchantLoginController.java | 6 +- .../controller/MerchantUiController.java | 6 +- .../service/MerchantGoodsService.java | 44 +++-- .../merchant/service/MerchantUiService.java | 44 +++-- .../merchant/service/MerchantUserService.java | 7 +- .../user/controller/UserLoginController.java | 4 +- .../user/controller/UserPayController.java | 11 +- .../jieyue/user/service/UserCartService.java | 5 +- .../jieyue/user/service/UserHomeService.java | 77 +++----- .../jieyue/user/service/UserInfoService.java | 27 +-- .../jieyue/user/service/UserOrderService.java | 5 +- .../user/service/UserProductService.java | 17 +- .../user/service/UserSearchService.java | 7 +- .../jieyue/user/service/UserShopService.java | 34 ++-- .../jieyue/user/service/WxPayService.java | 24 +-- src/main/resources/application.yml | 6 +- .../resources/static/data/header/user/2.jpg | Bin 24457 -> 0 bytes 32 files changed, 455 insertions(+), 559 deletions(-) create mode 100644 src/main/java/com/example/jieyue/common/utils/DateUtil.java create mode 100644 src/main/java/com/example/jieyue/common/utils/FileUtil.java delete mode 100644 src/main/java/com/example/jieyue/common/utils/GiteeImgBedUtils.java create mode 100644 src/main/java/com/example/jieyue/common/utils/JsonUtil.java create mode 100644 src/main/java/com/example/jieyue/common/utils/StringUtil.java delete mode 100644 src/main/resources/static/data/header/user/2.jpg diff --git a/README.md b/README.md index b1ebfac..eb1ca99 100644 --- a/README.md +++ b/README.md @@ -130,92 +130,81 @@ # 如何部署? --- -### 1.下载源码 +### 下载源码 将源码下载下来,使用Idea选择open的方式打开项目(第一次打开需要下载项目对应的第三方依赖,需要等待2~3分钟) ![](https://img-blog.csdnimg.cn/e5e5f9f23bb24fc286caa56564df7857.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_20,color_FFFFFF,t_70,g_se,x_16) -### 2.配置文件 +### 配置文件 修改项目配置文件application.yml,主要将服务器ip地址、MySQL、Redis连接信息按照自己的需求进行修改即可。 ![](https://img-blog.csdnimg.cn/1281208680ff4461a48202f71629a285.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_20,color_FFFFFF,t_70,g_se,x_16) ![](https://img-blog.csdnimg.cn/0c0547bf787c4877b62557cd2d17e729.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_20,color_FFFFFF,t_70,g_se,x_16) -### 3.打包项目 -填写好项目配置信息后,就可以开始打包项目了:按照下图所示的步骤依次执行,最后打包好的 **`jieyue.jar`** 将会存放在 **`target`** 目录中。 -![](https://img-blog.csdnimg.cn/11e170bd1863418d99b38caebcb12c10.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_20,color_FFFFFF,t_70,g_se,x_16) +### 打包项目 +填写好项目配置信息后,就可以开始打包项目了:按照下图所示的步骤依次执行,最后打包好的 **`ROOT.war`** 将会存放在 **`target`** 目录中。 + +![在这里插入图片描述](https://img-blog.csdnimg.cn/12fa198275c14466804d553efd8b17a7.png) -### 4.安装Docker + +### 安装Docker docker的安装流程可参考下面这篇文章,笔者在这里就不再赘述了:**[https://www.runoob.com/docker/centos-docker-install.html](https://www.runoob.com/docker/centos-docker-install.html)**
-### 5.安装MySQL -5.1:执行如下命令拉取MySQL的Docker镜像 +### 安装MySQL +1:执行如下命令拉取MySQL的Docker镜像 ```bash docker pull hub.c.163.com/library/mysql:latest ``` -5.2:镜像拉取后,执行如下命令运行MySQL(注意:MYSQL_ROOT_PASSWORD中的密码需要与项目配置文件中的MySQL密码保持一致) +2:镜像拉取后,执行如下命令运行MySQL(注意:MYSQL_ROOT_PASSWORD中的密码需要与项目配置文件中的MySQL密码保持一致) ```bash docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d hub.c.163.com/library/mysql:latest ``` -5.3:MySQL运行成功后,需要对MySQL的数据进行初始化,这里笔者推荐使用可视化工具Navicat,填入对应的信息即可成功连接 +3:MySQL运行成功后,需要对MySQL的数据进行初始化,这里笔者推荐使用可视化工具Navicat,填入对应的信息即可成功连接 ![](https://img-blog.csdnimg.cn/3bc392ebdbf249dd93a765bcf8d41733.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_20,color_FFFFFF,t_70,g_se,x_16) -5.4:新建一个名为jieyue的数据库,创建成功后双击该数据库创立连接,接着右击,选择**运行SQL文件**,运行项目根目录下的 **`jieyue.sql`** 文件即可。 +4:新建一个名为jieyue的数据库,创建成功后双击该数据库创立连接,接着右击,选择**运行SQL文件**,运行项目根目录下的 **`jieyue.sql`** 文件即可。 ![](https://img-blog.csdnimg.cn/be8eccc8a0084db8a087d8287034cfc3.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_19,color_FFFFFF,t_70,g_se,x_16) -### 6.安装Redis -6.1:执行如下命令拉取Redis的Docker镜像 +### 安装Redis +1:执行如下命令拉取Redis的Docker镜像 ```bash docker pull hub.c.163.com/library/redis:latest ``` -6.2:执行如下命令运行Redis +2:执行如下命令运行Redis ```bash docker run -d -p 6379:6379 --name redis hub.c.163.com/library/redis:latest ```
-### 7.安装OpenJDK -7.1:执行如下命令拉取OpenJDK的Docker镜像 +### 安装Tomcat +1:执行如下命令拉取Tomcat的Docker镜像 ```bash -docker pull hub.c.163.com/cloudndp/library/openjdk:8-jessie +docker pull hub.c.163.com/library/tomcat:8.5 ``` -7.2:在 **`jieyue.jar`** 包同一目录下创建 **`Dockerfile`** 文件,具体内容如下 - +2:执行如下命令运行Tomcat ```bash -FROM hub.c.163.com/cloudndp/library/openjdk:8-jessie - -COPY jieyue.jar /jieyue.jar - -CMD java -jar /jieyue.jar - -EXPOSE 80 +docker run -d -p 80:8080 -e LANG=C.UTF-8 -e TZ="Asia/Shanghai" --name tomcat hub.c.163.com/library/tomcat:8.5 ``` -7.3:在 **`jieyue.jar`** 包同一目录下执行如下命令,创建镜像 - +3:使用如下命令进入tomcat容器内,将`/usr/local/tomcat/webapps`路径下的`ROOT`文件夹删除 ```bash -docker build -t jieyue-image . +docker exec -it tomcat bash ``` -7.4:最后运行容器即可 +4:退出容器,来到存放 **`ROOT.war`** 的目录,执行如下命令,将项目文件拷贝进容器tomcat容器中 ```bash -docker run -d -p 80:80 -e LANG=C.UTF-8 -e TZ="Asia/Shanghai" --name jieyue jieyue-image +docker cp ROOT.war tomcat:/usr/local/tomcat/webapps ``` -7.5:使用如下命令可查看项目运行日志(若有如下字眼出现,则表明容器运行成功) +4:最后重启Tomcat ```bash -docker logs jieyue +docker restart tomcat ``` -![](https://img-blog.csdnimg.cn/1be4eb72a24a449d893a9d973310b073.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_20,color_FFFFFF,t_70,g_se,x_16) -7.6:成功运行后,访问配置文件中填写的服务器ip地址即可(如:笔者这里填写的是199.91.222.184,访问[http://119.91.222.184/](http://119.91.222.184/),就可以看到网站的主页)至此,捷阅网已成功部署~~!! +5:成功运行后,访问配置文件中填写的服务器ip地址即可(如:笔者这里填写的是199.91.222.184,访问 **[http://119.91.222.184/](http://119.91.222.184/)**,就可以看到网站的主页)至此,捷阅网已成功部署~~!! +
# 有关网站制作者 --- -**个 人 主 页: [云丶言](https://bosen-once.gitee.io/)** -![](https://img-blog.csdnimg.cn/c3f49c6533dc401b9d00bb3655f7e5fb.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_15,color_FFFFFF,t_70,g_se,x_16#pic_center) - ---- - **CSDN博客:[云丶言](https://blog.csdn.net/weixin_47600880)** ![](https://img-blog.csdnimg.cn/45557a1b39054cc6ae793079c8e4f178.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LqR5Li26KiA,size_15,color_FFFFFF,t_70,g_se,x_16#pic_center) diff --git a/jieyue.sql b/jieyue.sql index 905cfad..176f6c7 100644 --- a/jieyue.sql +++ b/jieyue.sql @@ -11,7 +11,7 @@ Target Server Version : 50716 File Encoding : 65001 - Date: 28/03/2022 20:07:01 + Date: 23/05/2022 00:43:13 */ SET NAMES utf8mb4; @@ -98,9 +98,9 @@ INSERT INTO `sys_cart` VALUES (10, 70, 1, 1); INSERT INTO `sys_cart` VALUES (11, 51, 1, 1); INSERT INTO `sys_cart` VALUES (12, 73, 1, 1); INSERT INTO `sys_cart` VALUES (13, 47, 1, 1); -INSERT INTO `sys_cart` VALUES (14, 47, 3, 1); -INSERT INTO `sys_cart` VALUES (15, 48, 3, 1); -INSERT INTO `sys_cart` VALUES (16, 46, 3, 1); +INSERT INTO `sys_cart` VALUES (14, 47, 2, 1); +INSERT INTO `sys_cart` VALUES (15, 48, 2, 1); +INSERT INTO `sys_cart` VALUES (16, 46, 2, 1); INSERT INTO `sys_cart` VALUES (17, 45, 3, 1); -- ---------------------------- @@ -171,7 +171,7 @@ CREATE TABLE `sys_goods` ( `merchant` int(11) NOT NULL COMMENT '商品所属的商户id', `stock` int(11) NOT NULL DEFAULT 0 COMMENT '商品库存', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 75 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 76 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_goods @@ -232,6 +232,7 @@ INSERT INTO `sys_goods` VALUES (71, '安踏官方旗舰老爹鞋女鞋', '安踏 INSERT INTO `sys_goods` VALUES (72, '安踏脉冲2代男鞋', '安踏脉冲2代男鞋男2021春季新款男士户外休闲鞋旅游鞋官方旗舰网店912118852 浅米白/墨水蓝-1 8.5(男42)', '/data/goods/14/20210330213810878030.jpg', 0.01, 1, 14, 9); INSERT INTO `sys_goods` VALUES (73, '安踏女休闲鞋2021春季新款', '安踏女休闲鞋2021春季新款轻便跑步鞋子潮流时尚女鞋老爹鞋女运动鞋子百搭猫爪鞋官方旗舰网店 象牙白/迷雾紫/浅雾灰-5 6.5(女37.5)', '/data/goods/14/20210330213829639750.jpg', 0.01, 1, 14, 10); INSERT INTO `sys_goods` VALUES (74, '测试商品(勿拍)', '这是一只用于测试的海绵宝宝,勿拍!!!', '/data/goods/11/20210330220346963836.jpg', 0.01, 0, 11, 4); +INSERT INTO `sys_goods` VALUES (75, '1', '1', '/data/goods/13/20220522235640383480.jpg', 1.00, 0, 13, 1); -- ---------------------------- -- Table structure for sys_mt @@ -309,15 +310,9 @@ CREATE TABLE `sys_notice` ( -- Records of sys_notice -- ---------------------------- INSERT INTO `sys_notice` VALUES (30, '系统群发消息测试', '系统群发消息测试(无需理会)', '2', 1, 1648468781372); -INSERT INTO `sys_notice` VALUES (31, '系统群发消息测试', '系统群发消息测试(无需理会)', '2', 3, 1648468781375); -INSERT INTO `sys_notice` VALUES (32, '系统群发消息测试', '系统群发消息测试(无需理会)', '2', 4, 1648468781376); -INSERT INTO `sys_notice` VALUES (33, '系统群发消息测试', '系统群发消息测试(无需理会)', '2', 5, 1648468781377); -INSERT INTO `sys_notice` VALUES (34, '系统群发消息测试', '系统群发消息测试(无需理会)', '2', 7, 1648468781378); +INSERT INTO `sys_notice` VALUES (31, '系统群发消息测试', '系统群发消息测试(无需理会)', '2', 2, 1648468781375); INSERT INTO `sys_notice` VALUES (35, '欢迎访问捷阅网~!!', '欢迎访问捷阅网~!!', '2', 1, 1648468890462); -INSERT INTO `sys_notice` VALUES (36, '欢迎访问捷阅网~!!', '欢迎访问捷阅网~!!', '2', 3, 1648468890464); -INSERT INTO `sys_notice` VALUES (37, '欢迎访问捷阅网~!!', '欢迎访问捷阅网~!!', '2', 4, 1648468890466); -INSERT INTO `sys_notice` VALUES (38, '欢迎访问捷阅网~!!', '欢迎访问捷阅网~!!', '2', 5, 1648468890467); -INSERT INTO `sys_notice` VALUES (39, '欢迎访问捷阅网~!!', '欢迎访问捷阅网~!!', '2', 7, 1648468890468); +INSERT INTO `sys_notice` VALUES (36, '欢迎访问捷阅网~!!', '欢迎访问捷阅网~!!', '2', 2, 1648468890464); -- ---------------------------- -- Table structure for sys_order @@ -346,7 +341,7 @@ CREATE TABLE `sys_order` ( `merchant_ratio` float(11, 1) NOT NULL DEFAULT 1.0 COMMENT '订单创建时商户的费率', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `order_id`(`order_id`) USING BTREE COMMENT '订单号唯一' -) ENGINE = InnoDB AUTO_INCREMENT = 113 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 112 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_order @@ -362,17 +357,17 @@ INSERT INTO `sys_order` VALUES (90, 'WVW202012341002151359796', 1607185311336, 1 INSERT INTO `sys_order` VALUES (91, 'QAK202012341002151746672', 1607185311336, 1607185323819, 1, 1, 'SDW202012341002151596097', 1, 5, 0.01, 19, '', '测试', '测试', '测试', '', 0, '/data/pay/SDW202012341002151596097.jpg', '1', 0.1); INSERT INTO `sys_order` VALUES (92, 'YYT202012341004300490850', 1607186580573, 1607186595850, 1, 1, 'NFF202012341004300926613', 1, 8, 0.01, 34, '', '测试', '测试', '测试', '', 0, '/data/pay/NFF202012341004300926613.jpg', '13', 0.1); INSERT INTO `sys_order` VALUES (93, 'LID202012341004300509122', 1607186580573, 1607186595850, 1, 1, 'NFF202012341004300926613', 1, 5, 0.01, 19, '', '测试', '测试', '测试', '', 0, '/data/pay/NFF202012341004300926613.jpg', '10', 0.1); -INSERT INTO `sys_order` VALUES (101, 'GKJ202112340211010176213', 1638796210886, 1638796384928, 1, 1, 'GAU202112340211010908695', 3, 13, 0.01, 45, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/11f3333f-6d68-4adb-9cf6-035a39a4a551.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (102, 'ZSS202112340211024283551', 1638796224161, 1638796384928, 1, 1, 'ELN202112340211024324951', 3, 13, 0.01, 46, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/147fb8b1-18ac-480a-8d57-2c21635d9519.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (103, 'ZDK202112340211037495045', 1638796237222, 1638796384928, 1, 1, 'IJD202112340211037974203', 3, 13, 0.01, 47, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/4801e190-5640-4f14-a593-66029aa2d0ea.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (104, 'UWU202112340211051689881', 1638796251864, 1638796384928, 1, 1, 'NTP202112340211051560839', 3, 13, 0.01, 48, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/896bd6fa-e609-405c-b601-caa56d71659f.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (105, 'LAW202112340211111244316', 1638796271424, 1638796384928, 1, 1, 'EVM202112340211111457150', 3, 13, 0.01, 49, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/814b7cf6-3e81-4356-aa27-023bf2eb0609.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (106, 'QZG202112340211127932176', 1638796287661, 1638796384928, 1, 1, 'CKX202112340211127838508', 3, 13, 0.01, 50, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/2a3ecc4c-62e4-4964-aa75-1c2a3d082ba1.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (107, 'MVF202112340211155962656', 1638796315927, 1638796384928, 1, 1, 'GXI202112340211155762974', 3, 13, 0.01, 51, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/175a4dc6-1077-46ef-b64e-0e2a9ae66ee0.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (108, 'GYV202112340211210918392', 1638796330108, 1638796384928, 1, 1, 'NJY202112340211210411460', 3, 13, 0.01, 52, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/b7e61e0a-fea6-4022-b9bb-a3949220c085.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (109, 'XAB202112340211229316121', 1638796349401, 1638796384928, 1, 1, 'BGA202112340211229992111', 3, 13, 0.01, 53, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/9d358e5a-638e-4437-8a00-d9f942e5f58f.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (110, 'YUL202112340211250396901', 1638796370482, 1638796384928, 1, 1, 'OAX202112340211250369042', 3, 13, 0.01, 54, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/3db2f150-1b6d-41fa-8b6d-eca59c5f39cc.jpg', NULL, 0.0); -INSERT INTO `sys_order` VALUES (111, 'BHY202112340211304317807', 1638796384928, 1638796384928, 1, 1, 'ETZ202112340211304214293', 3, 13, 0.01, 55, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/87b2e60d-464c-499a-90be-b93e1ea58911.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (101, 'GKJ202112340211010176213', 1638796210886, 1638796384928, 1, 1, 'GAU202112340211010908695', 2, 13, 0.01, 45, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/11f3333f-6d68-4adb-9cf6-035a39a4a551.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (102, 'ZSS202112340211024283551', 1638796224161, 1638796384928, 1, 1, 'ELN202112340211024324951', 2, 13, 0.01, 46, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/147fb8b1-18ac-480a-8d57-2c21635d9519.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (103, 'ZDK202112340211037495045', 1638796237222, 1638796384928, 1, 1, 'IJD202112340211037974203', 2, 13, 0.01, 47, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/4801e190-5640-4f14-a593-66029aa2d0ea.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (104, 'UWU202112340211051689881', 1638796251864, 1638796384928, 1, 1, 'NTP202112340211051560839', 2, 13, 0.01, 48, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/896bd6fa-e609-405c-b601-caa56d71659f.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (105, 'LAW202112340211111244316', 1638796271424, 1638796384928, 1, 1, 'EVM202112340211111457150', 2, 13, 0.01, 49, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/814b7cf6-3e81-4356-aa27-023bf2eb0609.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (106, 'QZG202112340211127932176', 1638796287661, 1638796384928, 1, 1, 'CKX202112340211127838508', 2, 13, 0.01, 50, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/2a3ecc4c-62e4-4964-aa75-1c2a3d082ba1.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (107, 'MVF202112340211155962656', 1638796315927, 1638796384928, 1, 1, 'GXI202112340211155762974', 2, 13, 0.01, 51, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/175a4dc6-1077-46ef-b64e-0e2a9ae66ee0.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (108, 'GYV202112340211210918392', 1638796330108, 1638796384928, 1, 1, 'NJY202112340211210411460', 2, 13, 0.01, 52, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/b7e61e0a-fea6-4022-b9bb-a3949220c085.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (109, 'XAB202112340211229316121', 1638796349401, 1638796384928, 1, 1, 'BGA202112340211229992111', 2, 13, 0.01, 53, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/9d358e5a-638e-4437-8a00-d9f942e5f58f.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (110, 'YUL202112340211250396901', 1638796370482, 1638796384928, 1, 1, 'OAX202112340211250369042', 2, 13, 0.01, 54, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/3db2f150-1b6d-41fa-8b6d-eca59c5f39cc.jpg', NULL, 0.0); +INSERT INTO `sys_order` VALUES (111, 'BHY202112340211304317807', 1638796384928, 1638796384928, 1, 1, 'ETZ202112340211304214293', 2, 13, 0.01, 55, '', 'xxxxxxxxxxxxx', 'Bosen', '123456', '', 0, 'data/pay/87b2e60d-464c-499a-90be-b93e1ea58911.jpg', NULL, 0.0); -- ---------------------------- -- Table structure for sys_role @@ -439,53 +434,9 @@ CREATE TABLE `sys_ui` ( INSERT INTO `sys_ui` VALUES (18, '/data/library/20210328110354280473.jpg', 1230, 535); INSERT INTO `sys_ui` VALUES (19, '/data/library/20210330181647732986.jpg', 3151, 282); INSERT INTO `sys_ui` VALUES (20, '/data/library/20210330181628569458.jpeg', 3152, 282); -INSERT INTO `sys_ui` VALUES (21, 'data/library/1f9be131-5b1b-4c29-a172-2f34b757fe77.jpeg', 475, 570); +INSERT INTO `sys_ui` VALUES (21, '/data/library/20210330190628805198.jpeg', 475, 570); INSERT INTO `sys_ui` VALUES (22, '/data/library/20210330185815215536.jpg', 674, 264); -INSERT INTO `sys_ui` VALUES (23, 'data/library/22f506db-2960-4756-b339-25760fe4dc40.jpg', 1920, 737); - --- ---------------------------- --- Table structure for sys_ui_copy1 --- ---------------------------- -DROP TABLE IF EXISTS `sys_ui_copy1`; -CREATE TABLE `sys_ui_copy1` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, - `width` int(7) NOT NULL, - `height` int(7) NOT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; - --- ---------------------------- --- Records of sys_ui_copy1 --- ---------------------------- -INSERT INTO `sys_ui_copy1` VALUES (18, '/data/library/20210328110354280473.jpg', 1230, 535); -INSERT INTO `sys_ui_copy1` VALUES (19, '/data/library/20210330181647732986.jpg', 3151, 282); -INSERT INTO `sys_ui_copy1` VALUES (20, '/data/library/20210330181628569458.jpeg', 3152, 282); -INSERT INTO `sys_ui_copy1` VALUES (21, '/data/library/20210330190628805198.jpeg', 475, 570); -INSERT INTO `sys_ui_copy1` VALUES (22, '/data/library/20210330185815215536.jpg', 674, 264); -INSERT INTO `sys_ui_copy1` VALUES (23, '/data/library/20210322125308458944.jpg', 1920, 737); - --- ---------------------------- --- Table structure for sys_ui_copy2 --- ---------------------------- -DROP TABLE IF EXISTS `sys_ui_copy2`; -CREATE TABLE `sys_ui_copy2` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, - `width` int(7) NOT NULL, - `height` int(7) NOT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; - --- ---------------------------- --- Records of sys_ui_copy2 --- ---------------------------- -INSERT INTO `sys_ui_copy2` VALUES (18, '/data/library/20210328110354280473.jpg', 1230, 535); -INSERT INTO `sys_ui_copy2` VALUES (19, '/data/library/20210330181647732986.jpg', 3151, 282); -INSERT INTO `sys_ui_copy2` VALUES (20, '/data/library/20210330181628569458.jpeg', 3152, 282); -INSERT INTO `sys_ui_copy2` VALUES (21, '/data/library/20210330190628805198.jpeg', 475, 570); -INSERT INTO `sys_ui_copy2` VALUES (22, '/data/library/20210330185815215536.jpg', 674, 264); -INSERT INTO `sys_ui_copy2` VALUES (23, '/data/library/20210322125308458944.jpg', 1920, 737); +INSERT INTO `sys_ui` VALUES (23, '/data/library/20210322125308458944.jpg', 1920, 737); -- ---------------------------- -- Table structure for sys_user @@ -505,10 +456,7 @@ CREATE TABLE `sys_user` ( -- ---------------------------- -- Records of sys_user -- ---------------------------- -INSERT INTO `sys_user` VALUES (1, 'Bosen', 'b9e1115fb6e950878b08e2433b53ed47', 'bosen_once@163.com', 1, 'data/header/user/5123ceb0-7f02-4a03-a6a8-32b70ddcbe08.jpg'); -INSERT INTO `sys_user` VALUES (3, 'guest', 'e10adc3949ba59abbe56e057f20f883e', 'guest@qq.com', 1, 'data/header/user/45bd348b-ba84-42ce-80b3-c4f852c943df.itc.cn_images01_20210825_919e1fbb709a4336b52c1cc4f3b8ef17.jpeg&refer=http___p9.itc.jfif'); -INSERT INTO `sys_user` VALUES (4, 'test111', 'e10adc3949ba59abbe56e057f20f883e', '806317173@qq.com', 0, '/data/header/user/default.jpg'); -INSERT INTO `sys_user` VALUES (5, 'lalalal', 'e10adc3949ba59abbe56e057f20f883e', '2390025288@qq.com', 0, '/data/header/user/default.jpg'); -INSERT INTO `sys_user` VALUES (7, '2390025289@qq.com', 'e10adc3949ba59abbe56e057f20f883e', '2390025289@qq.com', 1, '/data/header/user/default.jpg'); +INSERT INTO `sys_user` VALUES (1, 'Bosen', 'b9e1115fb6e950878b08e2433b53ed47', 'bosen_once@163.com', 1, '/data/header/user/1.jpg'); +INSERT INTO `sys_user` VALUES (2, 'guest', 'e10adc3949ba59abbe56e057f20f883e', 'guest@qq.com', 1, '/data/header/user/default.jpg'); SET FOREIGN_KEY_CHECKS = 1; diff --git a/pom.xml b/pom.xml index 767713b..28de8c1 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.example jieyue 0.0.1-SNAPSHOT - jar + war jieyue Demo project for Spring Boot @@ -19,6 +19,7 @@ UTF-8 UTF-8 1.8 + 8.5.29 @@ -59,32 +60,34 @@ org.springframework.boot spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + + - org.springframework.boot spring-boot-devtools true - mysql mysql-connector-java runtime - org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3 - org.projectlombok lombok true - org.springframework.boot spring-boot-starter-test @@ -124,13 +127,11 @@ qrgen 1.4 - com.alibaba fastjson 1.2.47 - org.springframework.data spring-data-redis @@ -139,10 +140,12 @@ org.springframework.boot spring-boot-starter-tomcat + provided org.apache.tomcat.embed tomcat-embed-jasper + provided @@ -155,27 +158,15 @@ org.springframework.boot spring-boot-starter-amqp - - - cn.hutool - hutool-all - 5.5.8 - - - org.springframework - spring-test - 5.3.12 - compile - - jieyue + ROOT - + org.apache.maven.plugins maven-compiler-plugin @@ -188,11 +179,6 @@ - - org.apache.maven.plugins - maven-javadoc-plugin - 3.0.0 - diff --git a/src/main/java/com/example/jieyue/JieyueApplication.java b/src/main/java/com/example/jieyue/JieyueApplication.java index bbb3e5e..d724c34 100644 --- a/src/main/java/com/example/jieyue/JieyueApplication.java +++ b/src/main/java/com/example/jieyue/JieyueApplication.java @@ -1,9 +1,15 @@ package com.example.jieyue; +import org.apache.catalina.connector.Connector; +import org.apache.coyote.http11.AbstractHttp11Protocol; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.EnableScheduling; /** @@ -15,10 +21,35 @@ import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @ServletComponentScan @EnableScheduling -public class JieyueApplication { +public class JieyueApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(JieyueApplication.class, args); } + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { + return builder.sources(JieyueApplication.class); + } + + /** + *

处理文件过大上传失败的问题

+ */ + @Bean + public TomcatServletWebServerFactory containerFactory() { + return new TomcatServletWebServerFactory() { + protected void customizeConnector(Connector connector) { + int maxSize = 50000000; + super.customizeConnector(connector); + connector.setMaxPostSize(maxSize); + connector.setMaxSavePostSize(maxSize); + if (connector.getProtocolHandler() instanceof AbstractHttp11Protocol) { + + ((AbstractHttp11Protocol ) connector.getProtocolHandler()).setMaxSwallowSize(maxSize); + logger.info("Set MaxSwallowSize "+ maxSize); + } + } + }; + + } } diff --git a/src/main/java/com/example/jieyue/admin/service/AdminMerchantService.java b/src/main/java/com/example/jieyue/admin/service/AdminMerchantService.java index 65ab1f7..06db5c3 100644 --- a/src/main/java/com/example/jieyue/admin/service/AdminMerchantService.java +++ b/src/main/java/com/example/jieyue/admin/service/AdminMerchantService.java @@ -2,7 +2,6 @@ package com.example.jieyue.admin.service; import com.example.jieyue.common.entity.SysMt; import com.example.jieyue.common.mapper.SysMtMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -20,13 +19,9 @@ public class AdminMerchantService { */ public List getMtInfo(int curPage,int pageSize){ int curRow = (curPage-1)*pageSize; - List list = mtMapper.findPage(curRow,pageSize); - for (SysMt sysMt : list) { - sysMt.setHeader(GiteeImgBedUtils.PRE + sysMt.getHeader()); - } - return list; + return mtMapper.findPage(curRow,pageSize); } - + /** *

删除商户

*/ @@ -46,7 +41,7 @@ public class AdminMerchantService { } return -1; } - + /** *

获取商户列表总页数

*/ diff --git a/src/main/java/com/example/jieyue/admin/service/AdminUiService.java b/src/main/java/com/example/jieyue/admin/service/AdminUiService.java index bcd5ae9..2349d23 100644 --- a/src/main/java/com/example/jieyue/admin/service/AdminUiService.java +++ b/src/main/java/com/example/jieyue/admin/service/AdminUiService.java @@ -1,16 +1,22 @@ package com.example.jieyue.admin.service; import com.example.jieyue.common.mapper.SysUiMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; +import com.example.jieyue.common.utils.DateUtil; +import com.example.jieyue.common.utils.FileUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.thymeleaf.util.StringUtils; import javax.servlet.http.HttpServletRequest; @Service public class AdminUiService { + @Autowired + FileUtil fileUtil; + @Autowired + DateUtil dateUtil; @Autowired SysUiMapper uiMapper; @@ -21,31 +27,33 @@ public class AdminUiService { * 文件名 上传成功 */ public String upImage(MultipartFile file, RedirectAttributes redirectAttributes, - HttpServletRequest request, String url,int weight,int height) { + HttpServletRequest request, String url,int weight,int height) { + // 设置filename 文件名由年月日时分秒以及六位随机数组成 + String filename = dateUtil.getNMDHIS()+Math.round(Math.random()*(999999-100000)+100000); // 接收文件工具类返回的文件位置 - String result = GiteeImgBedUtils.upload(url, file); - if (result == null){ + String result = fileUtil.upFile(file,redirectAttributes,request,url,filename); + if (result==null){ return null; }else{ if (uiMapper.findByMark(weight,height) == null) { int insertRes = uiMapper.insert(result, weight, height); if (insertRes == 1) { - return result; + return filename; } else { // sql语句执行失败,将已上传的图片移除 - GiteeImgBedUtils.delete(result); + fileUtil.deleteFile(result); return null; } }else{ // 删除旧图片 - GiteeImgBedUtils.delete(uiMapper.findByMark(weight,height).getUrl()); + fileUtil.deleteFile(uiMapper.findByMark(weight,height).getUrl()); // 更改图片 int updateRes = uiMapper.updateUrl(result,weight,height); if (updateRes == 1) { - return result; + return filename; } else { // sql语句执行失败,将已上传的图片移除 - GiteeImgBedUtils.delete(result); + fileUtil.deleteFile(result); return null; } } @@ -56,11 +64,11 @@ public class AdminUiService { *

删除海报逻辑处理

*/ public boolean delImg(int width,int height){ - if (uiMapper.findByMark(width,height) == null){ + if (uiMapper.findByMark(width,height)==null){ return false; }else{ - GiteeImgBedUtils.delete(uiMapper.findByMark(width, height).getUrl()); - int delResult = uiMapper.deleteByMark(width, height); + fileUtil.deleteFile(uiMapper.findByMark(width,height).getUrl()); + int delResult = uiMapper.deleteByMark(width,height); if (delResult == 1) { return true; } diff --git a/src/main/java/com/example/jieyue/admin/service/AdminUserService.java b/src/main/java/com/example/jieyue/admin/service/AdminUserService.java index 7379a3d..b491c84 100644 --- a/src/main/java/com/example/jieyue/admin/service/AdminUserService.java +++ b/src/main/java/com/example/jieyue/admin/service/AdminUserService.java @@ -2,7 +2,6 @@ package com.example.jieyue.admin.service; import com.example.jieyue.common.entity.SysUser; import com.example.jieyue.common.mapper.SysUserMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -17,11 +16,7 @@ public class AdminUserService { *

获取用户信息

*/ public List getUserList(int page, int num){ - List list = userMapper.findLimit((page-1)*num,num); - for (SysUser user : list) { - user.setHeader(GiteeImgBedUtils.PRE + user.getHeader()); - } - return list; + return userMapper.findLimit((page-1)*num,num); } /** diff --git a/src/main/java/com/example/jieyue/common/task/SchedulerTask.java b/src/main/java/com/example/jieyue/common/task/SchedulerTask.java index 3d78cdd..942d665 100644 --- a/src/main/java/com/example/jieyue/common/task/SchedulerTask.java +++ b/src/main/java/com/example/jieyue/common/task/SchedulerTask.java @@ -5,7 +5,7 @@ import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.mapper.SysNoticeMapper; import com.example.jieyue.common.mapper.SysOrderMapper; import com.example.jieyue.common.service.MailService; -import com.example.jieyue.common.utils.GiteeImgBedUtils; +import com.example.jieyue.common.utils.FileUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; @@ -13,6 +13,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,6 +29,8 @@ public class SchedulerTask { @Autowired SysGoodsMapper goodsMapper; @Autowired + FileUtil fileUtil; + @Autowired RedisTemplate redisTemplate; @Autowired SysNoticeMapper noticeMapper; @@ -40,15 +43,15 @@ public class SchedulerTask { @Scheduled(cron="0 0/1 * * * ?") @Transactional public void delOverOrder(){ - // 订单过期时间,两小时 - long time = 2*60*60*1000; + long time = 2*60*60*1000;// 订单过期时间,两小时 List list = orderMapper.findByState(0); for (SysOrder sysOrder : list) { - if (System.currentTimeMillis() > sysOrder.getCreateTime() + time - && sysOrder.getOrderState() == 0){ - if (orderMapper.deleteById(sysOrder.getId()) != 1 || + if (System.currentTimeMillis() > sysOrder.getCreateTime()+time){ + if (orderMapper.deleteById(sysOrder.getId())!=1 || goodsMapper.addStock(sysOrder.getGoodsId(),sysOrder.getGoodsNum()) != 1){ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + }else{ + fileUtil.deleteFile(sysOrder.getPayCodeUrl()); } } } @@ -59,13 +62,11 @@ public class SchedulerTask { */ @Scheduled(cron="0 0/1 * * * ?") public void delQRCode(){ - // 订单过期时间,两小时 - long time = 2*60*60*1000; + long time = 2*60*60*1000;// 订单过期时间,两小时 List list = orderMapper.findAll(); for (SysOrder sysOrder : list) { - if (System.currentTimeMillis() > sysOrder.getCreateTime() + time - && sysOrder.getOrderState() == 0){ - GiteeImgBedUtils.delete(sysOrder.getPayCodeUrl()); + if (System.currentTimeMillis() > sysOrder.getCreateTime()+time){ + fileUtil.deleteFile(sysOrder.getPayCodeUrl()); } } } @@ -82,8 +83,19 @@ public class SchedulerTask { int type = Integer.valueOf(map.get("type")); int receive = Integer.valueOf(map.get("receive")); long createTime = Long.valueOf(map.get("createTime")); - - noticeMapper.insert(title,context,type,receive,createTime); + switch (type){ + case 0: + noticeMapper.insert(title,context,type,receive,createTime); + break; + case 1: + noticeMapper.insert(title,context,type,receive,createTime); + break; + case 2: + noticeMapper.insert(title,context,type,receive,createTime); + break; + default: + break; + } } } diff --git a/src/main/java/com/example/jieyue/common/utils/DateUtil.java b/src/main/java/com/example/jieyue/common/utils/DateUtil.java new file mode 100644 index 0000000..d9d9e99 --- /dev/null +++ b/src/main/java/com/example/jieyue/common/utils/DateUtil.java @@ -0,0 +1,22 @@ +package com.example.jieyue.common.utils; + +import org.springframework.stereotype.Component; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + *

时间工具类

+ * @author Bosen + * 2020/11/6 10:36 + */ +@Component +public class DateUtil { + /** + *

获取纯年月日时分秒的字符串

+ */ + public String getNMDHIS(){ + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + return sdf.format(new Date()); + } +} diff --git a/src/main/java/com/example/jieyue/common/utils/FileUtil.java b/src/main/java/com/example/jieyue/common/utils/FileUtil.java new file mode 100644 index 0000000..5e4e5d5 --- /dev/null +++ b/src/main/java/com/example/jieyue/common/utils/FileUtil.java @@ -0,0 +1,78 @@ +package com.example.jieyue.common.utils; + +import org.apache.commons.io.FileUtils; +import org.springframework.stereotype.Component; +import org.springframework.util.ResourceUtils; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + *

文件操作工具类

+ * @author Bosen + * 2020/11/5 22:55 + */ +@Component +public class FileUtil { + + String classpath; + public FileUtil() throws FileNotFoundException { + this.classpath = ResourceUtils.getFile("classpath:/static").getPath()+"\\"; + } + + /** + *

文件上传逻辑处理

+ * @return + * null 上传失败 + * 文件名 上传成功 + */ + public String upFile(MultipartFile file, RedirectAttributes redirectAttributes, + HttpServletRequest request,String url,String filename) { + // MultipartFile是对当前上传的文件的封装,当要同时上传多个文件时,可以给定多个MultipartFile参数(数组) + if (file.isEmpty()) { + redirectAttributes.addFlashAttribute("message", "Please select a file to upload"); + return null; + } + // 取文件格式后缀名 + // String type = file.getOriginalFilename().substring(file.getOriginalFilename().indexOf(".")); + + File savefile1 = new File(classpath+url); + //判断上传文件的保存目录是否存在 + if (!savefile1.exists() && !savefile1.isDirectory()) { + System.out.println(classpath+"目录不存在,需要创建"); + //创建目录 + savefile1.mkdir(); + } + String suffix = this.getSuffixName(file.getOriginalFilename()); + try { + // FileUtils.copyInputStreamToFile()这个方法里对IO进行了自动操作,不需要额外的再去关闭IO流 + // 加入原工程static目录 + FileUtils.copyInputStreamToFile(file.getInputStream(), new File(savefile1+"/"+filename+"."+suffix));// 复制临时文件到指定目录下 + } catch (IOException e) { + e.printStackTrace(); + } + return url+filename+"."+suffix; + } + + /** + *

获取文件后缀名

+ */ + public String getSuffixName(String filename){ + String[] strArray = filename.split("\\."); + int suffixIndex = strArray.length -1; + return strArray[suffixIndex]; + } + + /** + *

删除文件

+ */ + public void deleteFile(String url){ + File file1 = new File(classpath+url); + file1.delete(); + } + +} diff --git a/src/main/java/com/example/jieyue/common/utils/GiteeImgBedUtils.java b/src/main/java/com/example/jieyue/common/utils/GiteeImgBedUtils.java deleted file mode 100644 index 70b21d4..0000000 --- a/src/main/java/com/example/jieyue/common/utils/GiteeImgBedUtils.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.example.jieyue.common.utils; - -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; -import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class GiteeImgBedUtils { - /** - * 码云私人令牌 - */ - private static final String ACCESS_TOKEN = "24a30786da41fe96ec7ee86daea78ee2"; - - /** - * 码云个人空间名 - */ - private static final String OWNER = "bosen-once"; - - /** - * 上传指定仓库 - */ - private static final String REPO = "cloud-disk"; - - /** - * 图片访问前缀 - */ - public static final String PRE = - "https://gitee.com/" + OWNER + "/" + REPO + "/raw/master/"; - - /** - * 新建(POST)、获取(GET)、删除(DELETE)文件:()中指的是使用对应的请求方式 - * %s =>仓库所属空间地址(企业、组织或个人的地址path) (owner) - * %s => 仓库路径(repo) - * %s => 文件的路径(path) - */ - private static final String API_CREATE_POST = - "https://gitee.com/api/v5/repos/%s/%s/contents/%s"; - - /** - * 用于提交描述 - */ - private static final String ADD_MESSAGE = "add file"; - private static final String DEL_MESSAGE = "del file"; - - /** - *

上传文件

- * @param multipartFile 文件 - * @return 返回文件下载路径后缀 - */ - public static String upload(String path, MultipartFile multipartFile) { - String originalFilename = multipartFile.getOriginalFilename(); - if(originalFilename == null){ - return null; - } - String targetUrl = GiteeImgBedUtils.createUploadFileUrl(path, originalFilename); - // 请求体封装 - Map map = null; - try { - map = GiteeImgBedUtils.getUploadBodyMap(multipartFile.getBytes()); - } catch (IOException e) { - return null; - } - // 借助HttpUtil工具类发送POST请求 - String jsonResult = HttpUtil.post(targetUrl, map); - // 解析响应JSON字符串 - JSONObject jsonObj = JSONUtil.parseObj(jsonResult); - // 请求失败 - if(jsonObj.getObj("commit") == null){ - return null; - } - //请求成功:返回下载地址 - JSONObject content = JSONUtil.parseObj(jsonObj.getObj("content")); - return content.getObj("path").toString(); - } - - /** - *

删除

- */ - public static boolean delete(String path) { - if(path.contains("default")) { - return true; - } - try { - String targetUrl = GiteeImgBedUtils.deleteFileUrl(path); - Map map = getDeleteBodyMap(path); - // 发送delete请求 - String jsonResult = HttpRequest.delete(targetUrl).form(map).execute().body(); - // 解析响应JSON字符串 - JSONObject jsonObj = JSONUtil.parseObj(jsonResult); - return jsonObj.getObj("commit") != null; - } catch (Exception e) { - return false; - } - } - - /** - *

获取sha信息

- */ - private static String getShaInfo(String path) { - String targetUrl = GiteeImgBedUtils.deleteFileUrl(path); - Map map = getFileInfoBodyMap(); - // 借助HttpUtil工具类发送get请求 - String jsonResult = HttpUtil.get(targetUrl, map); - // 解析响应JSON字符串 - JSONObject jsonObj = JSONUtil.parseObj(jsonResult); - if (jsonObj.getObj("sha") == null) { - return null; - } - return jsonObj.getObj("sha").toString(); - } - - /** - * 生成创建(获取、删除)的指定文件路径 - */ - private static String createUploadFileUrl(String path, String originalFilename){ - //获取文件后缀 - String suffix = getFileSuffix(originalFilename); - //拼接存储的图片名称 - String fileName = UUID.randomUUID().toString() + suffix; - //填充请求路径 - return String.format(GiteeImgBedUtils.API_CREATE_POST, - GiteeImgBedUtils.OWNER, - GiteeImgBedUtils.REPO, - path + "/" + fileName); - } - - /** - *

生成删除链接

- */ - private static String deleteFileUrl(String path) { - return String.format(GiteeImgBedUtils.API_CREATE_POST, - GiteeImgBedUtils.OWNER, - GiteeImgBedUtils.REPO, - path); - } - - /** - * 获取创建文件的请求体map集合:access_token、message、content - * @param multipartFile 文件字节数组 - * @return 封装成map的请求体集合 - */ - private static Map getUploadBodyMap(byte[] multipartFile){ - HashMap bodyMap = new HashMap<>(3); - bodyMap.put("access_token", GiteeImgBedUtils.ACCESS_TOKEN); - bodyMap.put("message", GiteeImgBedUtils.ADD_MESSAGE); - bodyMap.put("content", Base64.encode(multipartFile)); - return bodyMap; - } - - /** - * 获取删除文件的请求体map集合:access_token、path、sha、message - * @return 封装成map的请求体集合 - */ - private static Map getDeleteBodyMap(String path){ - HashMap bodyMap = new HashMap<>(3); - bodyMap.put("access_token", GiteeImgBedUtils.ACCESS_TOKEN); - bodyMap.put("message", GiteeImgBedUtils.DEL_MESSAGE); - bodyMap.put("sha", getShaInfo(path)); - return bodyMap; - } - - /** - * 获取sha的请求体map集合:access_token - * @return 封装成map的请求体集合 - */ - private static Map getFileInfoBodyMap(){ - HashMap bodyMap = new HashMap<>(3); - bodyMap.put("access_token", GiteeImgBedUtils.ACCESS_TOKEN); - return bodyMap; - } - - /** - * 获取文件名的后缀,如:changlu.jpg => .jpg - * @return 文件后缀名 - */ - private static String getFileSuffix(String fileName) { - return fileName.contains(".") ? fileName.substring(fileName.indexOf('.')) : null; - } -} \ No newline at end of file diff --git a/src/main/java/com/example/jieyue/common/utils/JsonUtil.java b/src/main/java/com/example/jieyue/common/utils/JsonUtil.java new file mode 100644 index 0000000..fb56850 --- /dev/null +++ b/src/main/java/com/example/jieyue/common/utils/JsonUtil.java @@ -0,0 +1,21 @@ +package com.example.jieyue.common.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import org.springframework.stereotype.Component; + +@Component +public class JsonUtil { + + /** + * 字符串转整数型数组 + */ + public int[] jsonToIntArray(String json){ + JSONArray jsonArray = JSON.parseArray(json); + int[] array = new int[jsonArray.size()]; + for (int i = 0;i < jsonArray.size();i++){ + array[i] = (Integer) jsonArray.get(i); + } + return array; + } +} diff --git a/src/main/java/com/example/jieyue/common/utils/QRCodeUtil.java b/src/main/java/com/example/jieyue/common/utils/QRCodeUtil.java index 8ee11e4..8a865bb 100644 --- a/src/main/java/com/example/jieyue/common/utils/QRCodeUtil.java +++ b/src/main/java/com/example/jieyue/common/utils/QRCodeUtil.java @@ -4,7 +4,8 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.util.*; import javax.imageio.ImageIO; import com.google.zxing.BarcodeFormat; @@ -21,8 +22,6 @@ import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.web.multipart.MultipartFile; /** * 二维码生成解析工具类 @@ -52,27 +51,27 @@ public class QRCodeUtil { * * @param content 二维码包含的内容,文本或网址 * @param path 生成的二维码图片存放位置 + * @param filename 生成的二维码图片存放位置 * @param size 生成的二维码图片尺寸 可以自定义或者默认(250) * @param logoPath logo的存放位置 */ - public static String zxingCodeCreate(String content, String path, Integer size, String logoPath) { + public static boolean zxingCodeCreate(String content, String path, String filename,Integer size, String logoPath) { try { //图片类型 String imageType = "jpg"; //获取二维码流的形式,写入到目录文件中 BufferedImage image = getBufferedImage(content, size, logoPath); - //创建一个ByteArrayOutputStream - ByteArrayOutputStream os = new ByteArrayOutputStream(); - //把BufferedImage写入ByteArrayOutputStream - ImageIO.write(image, imageType, os); - //ByteArrayOutputStream转成InputStream - InputStream input = new ByteArrayInputStream(os.toByteArray()); - //InputStream转成MultipartFile - MultipartFile multipartFile = new MockMultipartFile("file", "file.jpg", "text/plain", input); - return GiteeImgBedUtils.upload(path, multipartFile); + + //生成二维码存放文件 + File file = new File(path+filename+".jpg"); + if (!file.exists()) { + file.mkdirs(); + } + ImageIO.write(image, imageType, file); + return true; } catch (IOException e) { e.printStackTrace(); - return null; + return false; } } diff --git a/src/main/java/com/example/jieyue/common/utils/StringUtil.java b/src/main/java/com/example/jieyue/common/utils/StringUtil.java new file mode 100644 index 0000000..270a52c --- /dev/null +++ b/src/main/java/com/example/jieyue/common/utils/StringUtil.java @@ -0,0 +1,20 @@ +package com.example.jieyue.common.utils; + +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +public class StringUtil { + public static String GetMapToXML(Map param){ + StringBuffer sb = new StringBuffer(); + sb.append(""); + for (Map.Entry entry : param.entrySet()) { + sb.append("<"+ entry.getKey() +">"); + sb.append(entry.getValue()); + sb.append(""); + } + sb.append(""); + return sb.toString(); + } +} diff --git a/src/main/java/com/example/jieyue/merchant/controller/MerchantGoodsController.java b/src/main/java/com/example/jieyue/merchant/controller/MerchantGoodsController.java index 3bd8e0e..8102d95 100644 --- a/src/main/java/com/example/jieyue/merchant/controller/MerchantGoodsController.java +++ b/src/main/java/com/example/jieyue/merchant/controller/MerchantGoodsController.java @@ -92,7 +92,7 @@ public class MerchantGoodsController { modelAndView.setViewName("redirect:goods"); return modelAndView; } - + /** *

通过id值删除商品

*/ @@ -108,7 +108,7 @@ public class MerchantGoodsController { modelAndView.setViewName("redirect:goods"); return modelAndView; } - + /** *

上架商品

*/ diff --git a/src/main/java/com/example/jieyue/merchant/controller/MerchantLoginController.java b/src/main/java/com/example/jieyue/merchant/controller/MerchantLoginController.java index b345e19..d2e1c94 100644 --- a/src/main/java/com/example/jieyue/merchant/controller/MerchantLoginController.java +++ b/src/main/java/com/example/jieyue/merchant/controller/MerchantLoginController.java @@ -1,7 +1,6 @@ package com.example.jieyue.merchant.controller; import com.example.jieyue.common.entity.SysMt; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import com.example.jieyue.merchant.service.MerchantLoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; @@ -28,7 +27,7 @@ public class MerchantLoginController { modelAndView.setViewName("merchant/login/index"); return modelAndView; } - + /** *

登录

*/ @@ -51,8 +50,7 @@ public class MerchantLoginController { modelAndView.addObject("msg","您的账号处于停用状态,请等待管理员处理"); break; } - merchant.setHeader(GiteeImgBedUtils.PRE + merchant.getHeader()); - session.setAttribute("merchant", merchant); + session.setAttribute("merchant",merchant); break; default: break; diff --git a/src/main/java/com/example/jieyue/merchant/controller/MerchantUiController.java b/src/main/java/com/example/jieyue/merchant/controller/MerchantUiController.java index 805d0b3..ca8fb55 100644 --- a/src/main/java/com/example/jieyue/merchant/controller/MerchantUiController.java +++ b/src/main/java/com/example/jieyue/merchant/controller/MerchantUiController.java @@ -36,7 +36,7 @@ public class MerchantUiController { return modelAndView; } - + /** *

删除

*/ @@ -57,7 +57,7 @@ public class MerchantUiController { modelAndView.setViewName("redirect:ui"); return modelAndView; } - + /** *

修改或添加商户在商城主页的宣传海报

*/ @@ -79,7 +79,7 @@ public class MerchantUiController { modelAndView.setViewName("redirect:ui"); return modelAndView; } - + /** *

修改用户头像

*/ diff --git a/src/main/java/com/example/jieyue/merchant/service/MerchantGoodsService.java b/src/main/java/com/example/jieyue/merchant/service/MerchantGoodsService.java index 53c2760..46d69ba 100644 --- a/src/main/java/com/example/jieyue/merchant/service/MerchantGoodsService.java +++ b/src/main/java/com/example/jieyue/merchant/service/MerchantGoodsService.java @@ -3,7 +3,8 @@ package com.example.jieyue.merchant.service; import com.example.jieyue.common.entity.SysGoods; import com.example.jieyue.common.entity.SysMt; import com.example.jieyue.common.mapper.SysGoodsMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; +import com.example.jieyue.common.utils.DateUtil; +import com.example.jieyue.common.utils.FileUtil; import com.example.jieyue.common.utils.IsEmptyUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -20,8 +21,12 @@ public class MerchantGoodsService { @Autowired SysGoodsMapper goodsMapper; @Autowired + FileUtil fileUtil; + @Autowired + DateUtil dateUtil; + @Autowired IsEmptyUtil isEmptyUtil = new IsEmptyUtil(); - + /** *

获取全部商品

*/ @@ -35,19 +40,15 @@ public class MerchantGoodsService { public SysGoods getGoodsById(int id){ return goodsMapper.findById(id); } - + /** *

获取当前商户的商品列表

*/ public List getMtGoods(HttpSession session,int page,int num){ SysMt sysMt = (SysMt) session.getAttribute("merchant"); - List list = goodsMapper.findByMtLimit(sysMt.getId(),(page-1)*num,num); - for (SysGoods sysGoods : list) { - sysGoods.setImg(GiteeImgBedUtils.PRE + sysGoods.getImg()); - } - return list; + return goodsMapper.findByMtLimit(sysMt.getId(),(page-1)*num,num); } - + /** *

添加商品

* @return @@ -70,17 +71,20 @@ public class MerchantGoodsService { SysMt sysMt = (SysMt)request.getSession().getAttribute("merchant"); int merchant = sysMt.getId(); - if ("".equals(img.getOriginalFilename())){ + if (img.getOriginalFilename().equals("")){ // 执行插入 goodsMapperResult = goodsMapper.insert1(name,describe,price,merchant,stock); if(goodsMapperResult != 1){ return 0; } }else{ + // 设置filename 文件名由年月日时分秒以及六位随机数组成 + String filename = dateUtil.getNMDHIS()+Math.round(Math.random()*(999999-100000)+100000); // 获取商户id,一个商户对应一个文件夹 int id = ((SysMt) request.getSession().getAttribute("merchant")).getId(); // 接收文件工具类返回的文件位置 - String imgUrl = GiteeImgBedUtils.upload("/data/goods/" + id, img); + String imgUrl = fileUtil.upFile(img,redirectAttributes,request, + "/data/goods/"+id+"/",filename); // 文件上传失败 if (imgUrl == null){ return -1; @@ -89,7 +93,7 @@ public class MerchantGoodsService { goodsMapperResult = goodsMapper.insert2(name,describe,price,merchant,stock,imgUrl); if (goodsMapperResult != 1){ // sql语句执行失败,将已上传的图片移除 - GiteeImgBedUtils.delete(imgUrl); + fileUtil.deleteFile(imgUrl); return 0; } } @@ -110,8 +114,11 @@ public class MerchantGoodsService { if (sql!=1){ return -1; }else{ - // 删除源文件,与编译文件中对应的goods图片信息 - GiteeImgBedUtils.delete(imgUrl); + // 当文件路径在/data下时,才执行文件的删除 + if (imgUrl.indexOf("/data") == 0){ + // 删除源文件,与编译文件中对应的goods图片信息 + fileUtil.deleteFile(imgUrl); + } return 1; } } @@ -166,10 +173,13 @@ public class MerchantGoodsService { return 0; } }else{ + // 设置filename 文件名由年月日时分秒以及六位随机数组成 + String filename = dateUtil.getNMDHIS()+Math.round(Math.random()*(999999-100000)+100000); // 获取商户id,一个商户对应一个文件夹 int id = ((SysMt) request.getSession().getAttribute("merchant")).getId(); // 接收文件工具类返回的文件位置 - String imgUrl = GiteeImgBedUtils.upload("/data/goods/" + id, img); + String imgUrl = fileUtil.upFile(img,redirectAttributes,request, + "/data/goods/"+id+"/",filename); // 文件上传失败 if (imgUrl == null){ return -1; @@ -179,11 +189,11 @@ public class MerchantGoodsService { goodsMapperResult = goodsMapper.updateGoods2(name,describe,price,merchant,stock,goodsId,imgUrl); if (goodsMapperResult != 1){ // sql语句执行失败,将已上传的图片移除 - GiteeImgBedUtils.delete(imgUrl); + fileUtil.deleteFile(imgUrl); return 0; }else{ // 新图片已插入,将旧图删除 - GiteeImgBedUtils.delete(tempGoods.getImg()); + fileUtil.deleteFile(tempGoods.getImg()); } } return 1; diff --git a/src/main/java/com/example/jieyue/merchant/service/MerchantUiService.java b/src/main/java/com/example/jieyue/merchant/service/MerchantUiService.java index 559d74d..9a7664c 100644 --- a/src/main/java/com/example/jieyue/merchant/service/MerchantUiService.java +++ b/src/main/java/com/example/jieyue/merchant/service/MerchantUiService.java @@ -4,7 +4,8 @@ import com.example.jieyue.common.entity.SysMt; import com.example.jieyue.common.entity.SysMtUi; import com.example.jieyue.common.mapper.SysMtMapper; import com.example.jieyue.common.mapper.SysMtUiMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; +import com.example.jieyue.common.utils.DateUtil; +import com.example.jieyue.common.utils.FileUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -18,6 +19,10 @@ public class MerchantUiService { @Autowired SysMtUiMapper mtUiMapper; @Autowired + FileUtil fileUtil; + @Autowired + DateUtil dateUtil; + @Autowired SysMtMapper merchantMapper; /** @@ -37,21 +42,17 @@ public class MerchantUiService { *

获取商户用于商城首页宣传的海报图片对象

*/ public SysMtUi getHomeImg(int width,int height,HttpSession session){ - SysMtUi ui = mtUiMapper.findByMark(width,height,getMtId(session)); - if (ui != null) { - ui.setUrl(GiteeImgBedUtils.PRE + ui.getUrl()); - } - return ui; + return mtUiMapper.findByMark(width,height,getMtId(session)); } - + /** *

删除

*/ public int delHomeImg(int id){ String url = mtUiMapper.findById(id).getUrl(); int sql = mtUiMapper.deleteById(id); - if (sql == 1){ - GiteeImgBedUtils.delete(url); + if (sql==1){ + fileUtil.deleteFile(url); return 1; }else{ return 0; @@ -67,8 +68,11 @@ public class MerchantUiService { int id = ((SysMt)request.getSession().getAttribute("merchant")).getId(); SysMtUi sysMtUi = mtUiMapper.findByMark(width,height,id); + // 设置filename 文件名由年月日时分秒以及六位随机数组成 + String filename = dateUtil.getNMDHIS()+Math.round(Math.random()*(999999-100000)+100000); // 接收文件工具类返回的文件位置 - String imgUrl = GiteeImgBedUtils.upload("/data/mtui/" + id, img); + String imgUrl = fileUtil.upFile(img,redirectAttributes,request, + "/data/mtui/"+id+"/",filename); if (imgUrl==null){ // 上传图片失败 return 0; @@ -79,15 +83,15 @@ public class MerchantUiService { int sql = mtUiMapper.updateUrl(imgUrl,width,height,id); if (sql==1){ // sql语句执行成功,将旧图删除,加入新图 - GiteeImgBedUtils.delete(sysMtUi.getUrl()); + fileUtil.deleteFile(sysMtUi.getUrl()); }else{ // sql语句执行失败,将已上传的新图删除 - GiteeImgBedUtils.delete(imgUrl); + fileUtil.deleteFile(imgUrl); } return sql; } } - + /** *

增加商户商城首页的宣传海报

*/ @@ -101,15 +105,19 @@ public class MerchantUiService { public int updateHeard(RedirectAttributes redirectAttributes,HttpServletRequest request, MultipartFile img){ // 获取商户信息 SysMt merchant = (SysMt) request.getSession().getAttribute("merchant"); - String headerUrl = GiteeImgBedUtils.upload("/data/header/merchant/", img); + // 设置filename 文件名由年月日时分秒以及六位随机数组成 + String filename = dateUtil.getNMDHIS()+Math.round(Math.random()*(999999-100000)+100000); + String headerUrl = fileUtil.upFile(img,redirectAttributes,request,"/data/header/merchant/",filename); int sql = merchantMapper.updateHeader(merchant.getId(),headerUrl); - if (sql != 1){ - GiteeImgBedUtils.delete(headerUrl); + if (sql!=1){ + fileUtil.deleteFile(headerUrl); return -1; }else{ - GiteeImgBedUtils.delete(merchant.getHeader()); + if (!merchant.getHeader().equals("/lib/merchant/images/2.png")){ + fileUtil.deleteFile(merchant.getHeader()); + } // 修改会话信息 - merchant.setHeader(GiteeImgBedUtils.PRE + headerUrl); + merchant.setHeader(headerUrl); request.getSession().setAttribute("merchant",merchant); } return 1; diff --git a/src/main/java/com/example/jieyue/merchant/service/MerchantUserService.java b/src/main/java/com/example/jieyue/merchant/service/MerchantUserService.java index 5b3d29e..90d2bbb 100644 --- a/src/main/java/com/example/jieyue/merchant/service/MerchantUserService.java +++ b/src/main/java/com/example/jieyue/merchant/service/MerchantUserService.java @@ -2,7 +2,6 @@ package com.example.jieyue.merchant.service; import com.example.jieyue.common.entity.SysUser; import com.example.jieyue.common.mapper.SysUserMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -17,11 +16,7 @@ public class MerchantUserService { *

获取用户信息

*/ public List getUserList(int page, int num){ - List list = userMapper.findLimit((page-1)*num,num); - for (SysUser user : list) { - user.setHeader(GiteeImgBedUtils.PRE + user.getHeader()); - } - return list; + return userMapper.findLimit((page-1)*num,num); } /** diff --git a/src/main/java/com/example/jieyue/user/controller/UserLoginController.java b/src/main/java/com/example/jieyue/user/controller/UserLoginController.java index 1bb827c..5727fc9 100644 --- a/src/main/java/com/example/jieyue/user/controller/UserLoginController.java +++ b/src/main/java/com/example/jieyue/user/controller/UserLoginController.java @@ -1,7 +1,6 @@ package com.example.jieyue.user.controller; import com.example.jieyue.common.entity.SysUser; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import com.example.jieyue.user.service.UserLoginService; import org.apache.ibatis.annotations.Param; import org.springframework.beans.factory.annotation.Autowired; @@ -32,7 +31,7 @@ public class UserLoginController { modelAndView.setViewName("user/login/index"); return modelAndView; } - + /** *

退出登陆

*/ @@ -52,7 +51,6 @@ public class UserLoginController { if (result==1){ // 登陆成功 SysUser user = service.userInfo(email); - user.setHeader(GiteeImgBedUtils.PRE + user.getHeader()); session.setAttribute("user",user); modelAndView.setViewName("redirect:/"); }else if (result==-1){ diff --git a/src/main/java/com/example/jieyue/user/controller/UserPayController.java b/src/main/java/com/example/jieyue/user/controller/UserPayController.java index df7cecc..c0f46f2 100644 --- a/src/main/java/com/example/jieyue/user/controller/UserPayController.java +++ b/src/main/java/com/example/jieyue/user/controller/UserPayController.java @@ -6,7 +6,6 @@ import com.example.jieyue.common.entity.SysOrder; import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.mapper.SysMtMapper; import com.example.jieyue.common.mapper.SysOrderMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import com.example.jieyue.user.service.WxPayService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -35,8 +34,8 @@ public class UserPayController { String orderMark = wxPayService.getOrderId(); // 添加订单 String res = wxPayService.addOrder(nums,orderMark,users,merchants,prices,notes,goods,address,name,phone,code,0,carts); - if(!"-1".equals(res) && !"0".equals(res) && !"".equals(res)){ - modelAndView.addObject("orderMark", orderMark); + if(!res.equals("-1") && !res.equals("0") && !res.equals("")){ + modelAndView.addObject("orderMark",orderMark); modelAndView.setViewName("redirect:/user/wxpay/index?mark="+orderMark); } return modelAndView; @@ -75,10 +74,10 @@ public class UserPayController { */ @RequestMapping("/user/wxpay/index") public ModelAndView wxNotify(ModelAndView modelAndView,String mark) { - String codeUrl = GiteeImgBedUtils.PRE + orderMapper.findByOrderMark(mark).get(0).getPayCodeUrl(); + String codeUrl = orderMapper.findByOrderMark(mark).get(0).getPayCodeUrl(); - modelAndView.addObject("codeUrl", codeUrl); - modelAndView.addObject("orderMark", mark); + modelAndView.addObject("codeUrl",codeUrl); + modelAndView.addObject("orderMark",mark); modelAndView.setViewName("user/pay/wx"); return modelAndView; diff --git a/src/main/java/com/example/jieyue/user/service/UserCartService.java b/src/main/java/com/example/jieyue/user/service/UserCartService.java index 5699f68..5b3715d 100644 --- a/src/main/java/com/example/jieyue/user/service/UserCartService.java +++ b/src/main/java/com/example/jieyue/user/service/UserCartService.java @@ -7,7 +7,6 @@ import com.example.jieyue.common.entity.SysUser; import com.example.jieyue.common.mapper.SysCartMapper; import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.mapper.SysMtMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -51,7 +50,7 @@ public class UserCartService { } return -1; } - + /** *

整合购物车完整信息

*/ @@ -64,7 +63,7 @@ public class UserCartService { SysGoods goods = goodsMapper.findById(cart.getGoodsId()); SysMt merchant = merchantMapper.findById(goods.getMerchant()); Map map = new HashMap<>(); - map.put("goodsImg", GiteeImgBedUtils.PRE + goods.getImg()); + map.put("goodsImg",goods.getImg()); map.put("cartId",cart.getId()+""); map.put("goodsId",goods.getId()+""); map.put("goodsPrice",goods.getPrice().toPlainString()); diff --git a/src/main/java/com/example/jieyue/user/service/UserHomeService.java b/src/main/java/com/example/jieyue/user/service/UserHomeService.java index 6477d15..d1ba00a 100644 --- a/src/main/java/com/example/jieyue/user/service/UserHomeService.java +++ b/src/main/java/com/example/jieyue/user/service/UserHomeService.java @@ -6,7 +6,6 @@ import com.example.jieyue.common.entity.SysUi; import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.mapper.SysMtUiMapper; import com.example.jieyue.common.mapper.SysUiMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -43,7 +42,7 @@ public class UserHomeService { redisTemplate.expire("homePageCache",10, TimeUnit.MINUTES); } - /** + /* * 获取商城网页的宣传海报 */ public Map getImage(){ @@ -56,25 +55,6 @@ public class UserHomeService { SysUi img3151 = uiMapper.findByMark(3151,282); SysUi img3152 = uiMapper.findByMark(3152,282); - if(img1920 != null) { - img1920.setUrl(GiteeImgBedUtils.PRE + img1920.getUrl()); - } - if(img1230 != null) { - img1230.setUrl(GiteeImgBedUtils.PRE + img1230.getUrl()); - } - if(img475 != null) { - img475.setUrl(GiteeImgBedUtils.PRE + img475.getUrl()); - } - if(img674 != null) { - img674.setUrl(GiteeImgBedUtils.PRE + img674.getUrl()); - } - if(img3151 != null) { - img3151.setUrl(GiteeImgBedUtils.PRE + img3151.getUrl()); - } - if(img3152 != null) { - img3152.setUrl(GiteeImgBedUtils.PRE + img3152.getUrl()); - } - map.put(1920+"",img1920); map.put(1230+"",img1230); map.put(475+"",img475); @@ -84,46 +64,51 @@ public class UserHomeService { return map; } - - /** + + /* * 获取热卖商品 */ public Map getEsc(int num){ - return common(goodsMapper.findAllEsc(num)); - } - - /** - * 获取新出商品 - */ - public Map getDesc(int num){ - return common(goodsMapper.findAllDesc(num)); - } - - /** - * 随机获取商品 - */ - public Map getRand(int num){ - return common(goodsMapper.findRand(num)); - } - - public Map common(List list) { + List list = goodsMapper.findAllEsc(num); Map map = new HashMap<>(); for (int i=0;i < list.size();i++) { - list.get(i).setImg(GiteeImgBedUtils.PRE + list.get(i).getImg()); - map.put(i+"", list.get(i)); + map.put(i+"",list.get(i)); } return map; } - /** + /* + * 获取新出商品 + */ + public Map getDesc(int num){ + List list = goodsMapper.findAllDesc(num); + Map map = new HashMap<>(); + for (int i=0;i < list.size();i++) { + map.put(i+"",list.get(i)); + } + return map; + } + + /* + * 随机获取商品 + */ + public Map getRand(int num){ + List list = goodsMapper.findRand(num); + Map map = new HashMap<>(); + for (int i=0;i < list.size();i++) { + map.put(i+"",list.get(i)); + } + return map; + } + + /* * 获取商户宣传店铺的海报 */ public Map getMtImg(int width,int height,int num){ Map map = new HashMap<>(); List list = mtUiMapper.findLimit(width,height,num); for (int i=0;i getGoodsList(List orderList){ List list = new ArrayList<>(); for (SysOrder order : orderList) { - SysGoods goods = goodsMapper.findById(order.getGoodsId()); - goods.setImg(GiteeImgBedUtils.PRE + goods.getImg()); - list.add(goods); + list.add(goodsMapper.findById(order.getGoodsId())); } return list; } diff --git a/src/main/java/com/example/jieyue/user/service/UserProductService.java b/src/main/java/com/example/jieyue/user/service/UserProductService.java index 81302ef..9f5483d 100644 --- a/src/main/java/com/example/jieyue/user/service/UserProductService.java +++ b/src/main/java/com/example/jieyue/user/service/UserProductService.java @@ -6,7 +6,6 @@ import com.example.jieyue.common.entity.SysUser; import com.example.jieyue.common.mapper.SysCommentMapper; import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.mapper.SysUserMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,7 +21,7 @@ public class UserProductService { SysCommentMapper commentMapper; @Autowired SysUserMapper userMapper; - + /** *

整合用户信息和评论信息

*/ @@ -33,7 +32,7 @@ public class UserProductService { for (SysComment comment : commentInfo) { Map commentMap = new HashMap<>(); SysUser user = getUserInfo(comment.getUser()); - commentMap.put("userHeader",GiteeImgBedUtils.PRE + user.getHeader()); + commentMap.put("userHeader",user.getHeader()); commentMap.put("userId",user.getId()+""); commentMap.put("commentId",comment.getId()+""); commentMap.put("userName",user.getUsername()); @@ -44,7 +43,7 @@ public class UserProductService { } return list; } - + /** *

获取当前商品总评论页数

*/ @@ -52,14 +51,12 @@ public class UserProductService { int count = commentMapper.getAllCountByGoods(goods); return (int)Math.ceil((double)count/(double)num); } - + /** *

通过id值获取商品对象

*/ public SysGoods getGoods(int id){ - SysGoods goods = goodsMapper.findById(id); - goods.setImg(GiteeImgBedUtils.PRE + goods.getImg()); - return goods; + return goodsMapper.findById(id); } /** @@ -71,14 +68,14 @@ public class UserProductService { public List getCommentInfo(int goods, int page, int num){ return commentMapper.findByGoodsLimit(goods,(page-1)*num,page*num); } - + /** *

获取评论对应的商户信息

*/ public SysUser getUserInfo(int userId){ return userMapper.selectById(userId); } - + /** *

添加商品评论

* @return diff --git a/src/main/java/com/example/jieyue/user/service/UserSearchService.java b/src/main/java/com/example/jieyue/user/service/UserSearchService.java index c83fc24..b8ed25f 100644 --- a/src/main/java/com/example/jieyue/user/service/UserSearchService.java +++ b/src/main/java/com/example/jieyue/user/service/UserSearchService.java @@ -4,7 +4,6 @@ import com.example.jieyue.common.entity.SysGoods; import com.example.jieyue.common.index.GoodsIndex; import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.repository.GoodsIndexRepository; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,11 +21,7 @@ public class UserSearchService { *

mysql通过关键字模糊查找商品

*/ public List mysqlSearchGoods(String keyword){ - List list = goodsMapper.search(keyword); - for (SysGoods goods : list) { - goods.setImg(GiteeImgBedUtils.PRE + goods.getImg()); - } - return list; + return goodsMapper.search(keyword); } /** diff --git a/src/main/java/com/example/jieyue/user/service/UserShopService.java b/src/main/java/com/example/jieyue/user/service/UserShopService.java index 88ac7da..5e27f92 100644 --- a/src/main/java/com/example/jieyue/user/service/UserShopService.java +++ b/src/main/java/com/example/jieyue/user/service/UserShopService.java @@ -4,7 +4,6 @@ import com.example.jieyue.common.entity.SysGoods; import com.example.jieyue.common.entity.SysMt; import com.example.jieyue.common.mapper.SysGoodsMapper; import com.example.jieyue.common.mapper.SysMtMapper; -import com.example.jieyue.common.utils.GiteeImgBedUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -23,34 +22,33 @@ public class UserShopService { *

获取商户信息

*/ public SysMt getMerchantInfo(int merchantId){ - SysMt merchant = merchantMapper.findById(merchantId); - merchant.setHeader(GiteeImgBedUtils.PRE + merchant.getHeader()); - return merchant; + return merchantMapper.findById(merchantId); } /** *

获取商户商品信息

*/ public Map getGoodsList(int merchantId, int page, int num){ - return common(goodsMapper.findByMtLimit(merchantId,(page-1)*num,page*num)); - } - - /** - *

随机获取商品

- */ - public Map getRandGoodsMap(int merchant,int num){ - return common(goodsMapper.findMerchantRand(merchant,num)); - } - - public Map common(List list) { + List list = goodsMapper.findByMtLimit(merchantId,(page-1)*num,page*num); Map map = new HashMap<>(); - for (int i = 0;i < list.size();i++) { - list.get(i).setImg(GiteeImgBedUtils.PRE + list.get(i).getImg()); + for (int i = 0;i < list.size();i++){ map.put(i,list.get(i)); } return map; } - + + /** + *

随机获取商品

+ */ + public Map getRandGoodsMap(int merchant,int num){ + List list = goodsMapper.findMerchantRand(merchant,num); + Map map = new HashMap<>(); + for (int i = 0;i < list.size();i++) { + map.put(i,list.get(i)); + } + return map; + } + /** *

获取总页数

*/ diff --git a/src/main/java/com/example/jieyue/user/service/WxPayService.java b/src/main/java/com/example/jieyue/user/service/WxPayService.java index 018a469..c6002a0 100644 --- a/src/main/java/com/example/jieyue/user/service/WxPayService.java +++ b/src/main/java/com/example/jieyue/user/service/WxPayService.java @@ -8,6 +8,7 @@ import com.example.jieyue.common.mapper.SysMtMapper; import com.example.jieyue.common.mapper.SysOrderMapper; import com.example.jieyue.common.utils.IsEmptyUtil; import com.example.jieyue.common.utils.QRCodeUtil; +import com.example.jieyue.common.utils.StringUtil; import com.example.jieyue.wxpay.config.MyWXPayConfig; import com.example.jieyue.wxpay.sdk.WXPay; import com.example.jieyue.wxpay.sdk.WXPayConstants; @@ -27,10 +28,7 @@ import java.io.InputStreamReader; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.SimpleDateFormat; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; +import java.util.*; /** *

微信支付服务类

@@ -39,6 +37,8 @@ import java.util.Random; */ @Service public class WxPayService { + @Autowired + StringUtil stringUtil; @Autowired SysOrderMapper orderMapper; @Autowired @@ -91,7 +91,7 @@ public class WxPayService { SysMt merchant = merchantMapper.findById(Integer.valueOf(merchantsArr[i])); // 执行sql语句 int sql = -1; - if ("0".equals(cartArr[i])){ + if (cartArr[i].equals("0")){ sql = orderMapper.insert1(orderId,createTime,Integer.valueOf(numArr[i]),mark,Integer.valueOf(userArr[i]), Integer.valueOf(merchantsArr[i]),new BigDecimal(dfPrice.format(Double.valueOf(pricesArr[i]))), Integer.valueOf(goodsArr[i]),notes,address,name,phone,code,way,merchant.getRatio()); @@ -117,9 +117,10 @@ public class WxPayService { *

分割js传递的数组

*/ public String[] getStringArray(String array){ + List list = new ArrayList<>(); return array.split(","); } - + /** *

总金额运算

*/ @@ -144,20 +145,21 @@ public class WxPayService { data.put("body", "捷阅网商品"); data.put("out_trade_no", orderMark); data.put("device_info", orderMark); + BigDecimal temp = new BigDecimal(100); data.put("total_fee", price); data.put("spbill_create_ip", "123.12.12.123"); - data.put("notify_url", siteUrl + "/user/wxpay/notify"); + data.put("notify_url", siteUrl+"/user/wxpay/notify"); data.put("trade_type", "NATIVE"); // 此处指定为扫码支付 data.put("product_id", orderMark); - String codeUrl = ""; try { Map resp = wxPay.unifiedOrder(data); System.out.println(resp); - codeUrl = QRCodeUtil.zxingCodeCreate(resp.get("code_url"), "/data/pay/", 500, ""); + QRCodeUtil.zxingCodeCreate(resp.get("code_url"),classPath+"/data/pay/",orderMark,500,""); } catch (Exception e) { e.printStackTrace(); } - orderMapper.updateCodeUrl(codeUrl, orderMark); + String codeUrl = "/data/pay/"+orderMark+".jpg"; + orderMapper.updateCodeUrl(codeUrl,orderMark); return codeUrl; } @@ -179,7 +181,7 @@ public class WxPayService { return result; } - + /** *

回调处理

*/ diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 20279fd..9fb9d90 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,10 +11,6 @@ server: error: include-exception: true spring: - servlet: - multipart: - max-file-size: 50MB - max-request-size: 100MB jmx: enabled: false application: @@ -26,7 +22,7 @@ spring: url: jdbc:mysql://${site-url}:3306/jieyue?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC data: elasticsearch: - cluster-nodes: ${site-url}:9200 + cluster-nodes: 127.0.0.1:9200 cluster-name: elasticsearch repositories: enabled: true diff --git a/src/main/resources/static/data/header/user/2.jpg b/src/main/resources/static/data/header/user/2.jpg deleted file mode 100644 index 42078da74e829be4f2ff3f1ef02ddd786f657b32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24457 zcmbTcWmH>T6fGKx7ATY!ij(42C=}N~DehjRv`B&AkYYgsrC5qP!QI{6y|@-D?ozx+ z!p(Q@9rup$e!cfj#`%$P_Bh!yd(E}xo@+lYJgxzrE6FL!0WdHy0RMdek4pd<01g&5 z4mK7J4mJ)hE)E|4bA0@#Pw`2KhzXyQlTuKSlfHUIMavANqGqId_3HJT*NiNz>>TWr zKrS9GHXdd+cDDasf`N;Ri;su@5+DC18`Uc+w*Sx9V<&(F52Fa95EFv|@Pq^dlLX_j z7XSnRFtE|H{cpnm`@(pFiJmVm-cx)6^nkkOfF~H3m`|`Uv9YnR(4&3O&jDB@*e~dL zrEy+rn&L7zlfLth&cb7SU)4pXHTjo`&&=ifQ~X!t6qHoVEUawo9Q*=;Lc$`VG9P5+ z5!pGpdHDr} zMa9)MwRQCkjZMwnJ-vPX1A{}uQ`0lEbMp(o7uPp7x3+h7_x2CY&Mz*nu5bR`-u;IQ z1AzIzVErFt{|{UwXk1UQurRT3|HFmx#2tNOl3-!e^Wwaa*2Fb+e#!98ACL5XbXHZ@ zQ${|mzhq`EllZTg_}7`w{)6^Ek^R2|_Wl1Cvi}3@|KeH%5MpAW7Y~yJ00Jc9gtyl| zXkh!yj*q|LCjvW<3gc_k8oN=vO0*ZpH-^X#S9bC#ks~||HQ0^a7#S&8_pi#{Vi)`_ zUu2gyuxLbRlz7RYSw9XFnHY9YdHxK6##byet(irvsE+mJx~Ji)Scg6 zzqKK-HF*U12G9RJAsU*8iY=}hiiJ%+0yZzS=@LaA0RyjUxJZeg9*R(6pFVvAw5Qiz zen#BuNhS*a_pI2k;6V#f*tNBi4*CPV9R$BcNT$OGF0Hug!|T`#1?TtK_k4|~n_jUk zX$2OQ9kVt%Rmw1hL9wt9A~WvTIM=cgwJo-J)qjI3zDZkSvB|kBbvhqLfGdGD0mUCU$4zNW-l7t)V>lW&MxPG(Xul>R+BgSr=L*EXlH}5!-(E zQ_*4f-@!4q6Nb+cG(H*)#4HPL5LcGAH*Y@(gVKXCbTt2MwHv0o)&~@Sf)!OZitH(o zJRH6U;o1atrkVLcTP`0;-tYEajQLx1L=oXEFcKhbIaF1~4xTnfw^12m{v%?)S5c{( zd@Fw!v;JPS9F~^?KubpXtoiCGi;U6Sx8*}ycz%;XBNk0`R+)8>arpyI2{W!ILl zO`a02F?|H6=05@^!#{ELHqyA3Tgi&lINqHKp~7uu|0HUG4Nv-ic=JeJ$xBmA9))ft zJI1bE3eL7Do9|0T*<0;nT z_Y6PlR%|&oi%ITu43$r(?LR&ONR?npK7g9lrnWDz-fKGxo6d)#lEo?w)lL!;I{d$Wp; z{r!bH!6+L=_BIorJ=-&YDeJ3Kuot~-}mw3@v@_}lU%PK}b3OmG4e?)_)moVa) zcfM<2m_@O)fx(}dd+}g$cI|6zclYUug};AC$0{;z9~_a`HqGVY%tc3s^;;+ro0hC1 zqcZ)8<=96+1eabgO4dh*sCx^xr@J;_@Ocy{&3sa~^(#e!K(po3#G-Nyz8=Uh zy3xD6Z>yh!Yd3ottUhlfU)&K+I&TbahRA}S^tZv>8n?ccYcON5zj!6vMgOEw6pXZ+@pBHxZVL zb=9%<_P@+FbbqV;AWNnojOv`(<}~WQW_K^j7A?X|x8cyy_!*0*?GghQb$phS{cdz{ zOa?mt*|N*;^%h-F=1-N6$G^>}Jq~39OP1JZ;!$kr1Fz|7U(KQmYo;8qSy?=WN}XM)rmA9*%KB=IJc&1yH{*Cpx>=?bI0&ilJzssU zM#Nt7ZM4VNRn^nMMiw{Eb};7Mt{oFd2v?-^(@T_i3aVxF5s+h8uar6`8U6^ML*Jiv z(5xv_@?x};JWAAo(8WVHi@T3N*aDVVzX@%TvzV8~i17!%E8yMQnlFc~RD>;KUUWol zK$!>>MLKhO#UF%aL2|$m5d_=N{u+6^5pY?un`gCWPGv!W>|45ZmX~@PQ8#)xlBW1{ zzq(m;_i7DPn|TxV2;hB>^R<$aqHx8JLVyqMAM1`a%b=v980+6hW}kye%U0mTBRE-K zu%w{ZzPj6e9%Y}qr0qYdh~3)oB4jOe3o^m6HL(-ZV!rKYp|d1q0@YWvUr(+CYBUB- zN#^o-&zg@<)YkXaKJyVCTt(vE-susOk>|cl%>U!r+%se=n0U3&Su@Rjigz#2(kO04 z0Zc9{Y!xA^7%egBc@Ch3FK1j_7QXeCg}DaGy*l&vt0FW%D~)YRdD9nqpvrpuwKU^x z!EO9~p}Z<>F%KiRChlH$eazuiB#+FVyZ%hdI&BGz8RdH(5805&S)At(Wu z43@21Hj-!S|2jh+ z7AvgHk(}C(fC@DAGRt%$cmB4Q!w&a+%RbYSojy!nU;G2+h-|BY*CmQIYS-d#9u|RV zE(bEzen~~$5TzFprY`Z<2ttqJzEAZHd@9cgcM*r*(y&dI>?UIh#OKJWc(N-PZ9aPH zF08w0w~w#_>38#>Pdp44*`NMyndTq7^e6oH_0~&|m^UBwQr-`-yrHj@8n#LM*XAS| zyDxm%CHnkicd@1Lvh(o9Hx6cbYlm4bZ@8N-p(%!Sr7z3p%HL^y~`>W@M1?Ab{@7f&ghsTgv=VH0#bO;E(b+*p3<}ZB~ ziqMc2kUP;z4d~OUX<_+P3Y{yCwb|>Muc@k0@tt9`z<1s~G@$yE{CrSS9h$#@H9Igy zWb-4#W3G}XnOaErSPjb@5!h8Yr$xl+U{prvS=KltoCrtY>>?^SEq2N98ovq~&L`}R zBYw?)Se1p`Y4o)QOl`oBRI^1^-b?k3K*N!#riR%6O`*zE!^yO7RM4!&22tJaM*z$Q z_D2QVn&d*4R#Uo4^ALiI3OAf!EVG(e4)j8@7xQKm6=beWVML<|^Ftsb=ghiiN*?&{ ztPHcOm`eSwDLA*{VU&kkAGARdE;sWCm=;2rHB;?+EB9?@JpxPz&hvl#+8I35+=$OW zgf;N@67tE?i^JI(!@BFBJ@Ty`jDvyScN1Z8#N!p~MrJ;Y%AmaoWVLgY!JRKzvRBFK z%2&frRq2APG*HX-ip80XE^5z?b4l&r+QI#&TOGfeoAu)J6GYP%(!V|e5_ls(G_b2; z&Wh*uVKRA(1K{TpQrO{Ul|xKd{8O#dIxpvPn=;mKp3Z>{5sJPb594u(>C?veZAU$k zLO1A4i_gB>yi&Cxh2ecP_U`9g#08}~zU2foI0L-4|u@h2(anz_GR13qk z(7YmJ9Qn5{#ahV2)5+}9fXF0FM;xus*rvpRF?qfi$uXN?fVwgJ;1 zY^EyB`^@(nFv`qvu_8DX6v!YEbpu+jMA^sR_sQ~Sd0l*L?g%~lRw?@n9vRuPBcCx? zDKMydMl_n-G5^;C^c7SvK0cStd+@t8ZmVs^4e}~F62zr12x%#il44A^9gmExa2K!4 zPkX~AM6u-UVt%0Z^v<%jHUnNCSicIc=7`+*F0~7ifltnB>dDz+YC&tEs*M(5PjQ}o z91|%Ash^z$!o;1CS;t!ryrS_MK0@Ds;Wo>M_1Er|ORJbq6OqP0EQPLD7S1M6l%=2B zin*tPn@6osu1c~!UfS&wgq9Fr&E49`4#j3T!Qas)TGCOkit9N`j%fQD(hOi`8S z^XD<@S8rjo)nwdIWonKZPV1vsu2~~!n;!x5LgnJN$X+DnpTvsm5NM9A{P>c9$|GQW z05x2vHmc%FJ?lL0GlVp(t?ldE$%?o@tKbNDDULX(*ne6GcrW1n1K8%s?~{uH#_~@3 zn(DpcxnL-u>=OX2pnvCh)hMYO=Ar*v$a?u-JkVpWc0}(>P9fQhQFj%?ny#|4CXIs5 z#cD-FfWXDo0i@U7e?pZ90k^Ta84k z;SWmI6i-XR_~nqqs0`a1r7*KvEeRwpUF`)pqq%in%>KmvH*;3#7LUl2BrfSMO6$RL zw6>6=dyfMf8g@GetccF3rWaq?GCL`E8ZO%uH>+b++g2pg7@|m1YvpU+=JWp3C5t5O zLn{R+o=TyMF*-OeAmYrj{=f6D#is((8AAyQmlS6szY$1?I=JC2�Tk& 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 M>qToFi;l