diff --git a/pom.xml b/pom.xml index a202be4..4c6096b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,13 +3,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + com.ruoyi ruoyi 3.7.0 ruoyi - + 3.7.0 UTF-8 @@ -36,7 +36,7 @@ 2.0.23 - + @@ -268,6 +268,25 @@ mybatis-plus-boot-starter ${mybatis.plus.version} + + + com.squareup.okhttp3 + okhttp + 4.8.1 + compile + + + io.minio + minio + 8.2.1 + + + + net.coobird + thumbnailator + 0.4.8 + + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java index 3e4555a..561404e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -1,10 +1,8 @@ package com.ruoyi; -import com.cyl.wechat.WechatPayData; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.scheduling.annotation.EnableScheduling; /** @@ -14,9 +12,8 @@ import org.springframework.scheduling.annotation.EnableScheduling; */ @SpringBootApplication( exclude = {DataSourceAutoConfiguration.class}, - scanBasePackages = {"com.ruoyi", "com.cyl"} + scanBasePackages = {"com.ruoyi"} ) -@EnableConfigurationProperties(WechatPayData.class) @EnableScheduling public class RuoYiApplication { public static void main(String[] args) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java index d79108d..f1ce3ad 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java @@ -1,183 +1,52 @@ package com.ruoyi.web.controller.common; -import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.cyl.manager.ums.domain.entity.Address; -import com.cyl.manager.ums.mapper.AddressMapper; -import com.cyl.manager.ums.domain.dto.AddressDTO; -import com.ruoyi.common.config.RuoYiConfig; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.redis.RedisService; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.file.FileUploadUtils; -import com.ruoyi.common.utils.file.FileUtils; -import com.ruoyi.common.utils.file.MimeTypeUtils; -import com.ruoyi.framework.config.ServerConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; +import com.ruoyi.common.core.domain.RestResponse; +import com.ruoyi.system.service.FileService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.*; -import java.util.stream.Collectors; - /** * 通用请求处理 - * + * * @author ruoyi */ +@Slf4j @RestController +@Tag(name = "文件上传") +@RequiredArgsConstructor +@RequestMapping("/com") public class CommonController { - private static final Logger log = LoggerFactory.getLogger(CommonController.class); - - @Autowired - private ServerConfig serverConfig; - @Autowired - private RedisService redisService; - @Autowired - private AddressMapper addressMapper; - /** - * 通用下载请求 - * - * @param fileName 文件名称 - * @param delete 是否删除 - */ - @GetMapping("common/download") - public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) - { - try - { - if (!FileUtils.checkAllowDownload(fileName)) - { - throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); - } - String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); - String filePath = RuoYiConfig.getDownloadPath() + fileName; + private final FileService fileService; - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - FileUtils.setAttachmentResponseHeader(response, realFileName); - FileUtils.writeBytes(filePath, response.getOutputStream()); - if (delete) - { - FileUtils.deleteFile(filePath); - } - } - catch (Exception e) - { - log.error("下载文件失败", e); - } + @Operation(summary = "上传课程相关图片", description = "上传图片,上传后返回原图和缩略图的url") + @PostMapping("/courseImage/upload") + public RestResponse uploadCourseImage(@RequestParam("file") MultipartFile file) { + return new RestResponse().setData(fileService.uploadCourseImage(file)); } - /** - * 通用上传请求 - */ - @PostMapping("/common/upload") - public AjaxResult uploadFile(MultipartFile file) throws Exception - { - try - { - // 上传文件路径 - String filePath = RuoYiConfig.getUploadPath(); - // 上传并返回新文件名称 - String fileName = FileUploadUtils.upload(filePath, file, MimeTypeUtils.isImg(file.getContentType())); - String url = serverConfig.getUrl() + fileName; - AjaxResult ajax = AjaxResult.success(); - ajax.put("fileName", fileName); - ajax.put("url", url); - return ajax; - } - catch (Exception e) - { - return AjaxResult.error(e.getMessage()); - } + @Operation(summary = "上传商城相关图片", description = "上传图片,上传后返回原图和缩略图的url") + @PostMapping("/productImage/upload") + public RestResponse uploadProductImage(@RequestParam("file") MultipartFile file) { + return new RestResponse().setData(fileService.uploadProductImage(file)); } - /** - * 本地资源通用下载 - */ - @GetMapping("/common/download/resource") - public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) - throws Exception - { - try - { - if (!FileUtils.checkAllowDownload(resource)) - { - throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); - } - // 本地资源路径 - String localPath = RuoYiConfig.getProfile(); - // 数据库资源地址 - String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); - // 下载名称 - String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); - FileUtils.setAttachmentResponseHeader(response, downloadName); - FileUtils.writeBytes(downloadPath, response.getOutputStream()); - } - catch (Exception e) - { - log.error("下载文件失败", e); - } + @Operation(summary = "上传文件", description = "上传文件,上传后返回文件url") + @PostMapping("/file/upload") + public RestResponse uploadFile(@RequestParam("file") MultipartFile file) { + return new RestResponse().setData(fileService.uploadFile(file)); } - @GetMapping("/common/area") - public AjaxResult getAddressList() { - String addresses = redisService.getAddressList(); - if (org.apache.commons.lang3.StringUtils.isNotEmpty(addresses)) { - List addressDTOList = JSON.parseArray(addresses, AddressDTO.class); - if(addressDTOList.size()>0){ - return AjaxResult.success(addressDTOList); - } - } - QueryWrapper
addressQueryWrapper = new QueryWrapper<>(); - addressQueryWrapper.in("level", Arrays.asList(0,1,2)); - List
addressList = addressMapper.selectList(addressQueryWrapper); - Map> cityMap = addressList.stream().filter(it -> it.getLevel() == 1).collect(Collectors.groupingBy(it -> it.getParentCode())); - Map> districtMap = addressList.stream().filter(it -> it.getLevel() == 2).collect(Collectors.groupingBy(it -> it.getParentCode())); - List result = new ArrayList<>(); - addressList.stream().filter(it -> it.getLevel() == 0).forEach(it -> { - AddressDTO dto = new AddressDTO(); - dto.setId(it.getCode()); - dto.setLevel("province"); - dto.setName(it.getName()); - dto.setPid(0L); - //获取城市列表 - List child = new ArrayList<>(); - if (cityMap.containsKey(it.getCode())) { - cityMap.get(it.getCode()).forEach(city -> { - AddressDTO cityDto = new AddressDTO(); - cityDto.setId(city.getCode()); - cityDto.setLevel("city"); - cityDto.setName(city.getName()); - cityDto.setPid(city.getParentCode()); - cityDto.setChildren(districtMap.containsKey(city.getCode()) ? - districtMap.get(city.getCode()).stream().map(district -> { - AddressDTO districtDto = new AddressDTO(); - districtDto.setId(district.getCode()); - districtDto.setLevel("district"); - districtDto.setName(district.getName()); - districtDto.setPid(district.getParentCode()); - return districtDto; - }).collect(Collectors.toList()) : Collections.EMPTY_LIST); - child.add(cityDto); - }); - } - dto.setChildren(child); - result.add(dto); - }); - redisService.setAddressList(JSON.toJSONString(result)); - return AjaxResult.success(result); - } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/OssController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/OssController.java deleted file mode 100644 index aa2bafa..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/OssController.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ruoyi.web.controller.common; - -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.OssUtils; -import io.swagger.annotations.Api; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -@RestController -@Api(tags = "OSS对象存储Controller") -@RequestMapping("/oss") -public class OssController { - @Autowired - OssUtils ossUtils; - - @PostMapping("upload") - public AjaxResult uploadFile(MultipartFile file) { - //返回上传oss的url - String url = ossUtils.uploadOneFile(file); - AjaxResult ajax = AjaxResult.success(); - ajax.put("fileName", file.getOriginalFilename()); - ajax.put("url", url); - return ajax; - } - - @PostMapping("uploadArrayFile") - public List uploadArrayFile(MultipartFile[] files) { - //返回上传oss的url - return ossUtils.uploadArrayFile(files); - } - - @PostMapping("deleteFile") - public boolean deleteFile(@RequestBody String fileUrl) { - //返回是否删除成功 - return ossUtils.deleteFile(fileUrl); - } -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/H5MemberInterceptor.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/H5MemberInterceptor.java deleted file mode 100644 index 0aa5c46..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/H5MemberInterceptor.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ruoyi.web.core.config; - -import com.cyl.manager.ums.domain.entity.Member; -import com.cyl.manager.ums.service.MemberService; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.HttpStatus; -import com.ruoyi.common.core.domain.model.LoginMember; -import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.framework.config.LocalDataUtil; -import com.ruoyi.framework.web.service.TokenService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@Configuration -public class H5MemberInterceptor extends HandlerInterceptorAdapter { - - @Autowired - private TokenService tokenService; - @Autowired - private MemberService memberService; - - private static String[] WHITE_PATHS = { - "/h5/sms/login", - "/h5/wechat/login", - "/h5/account/login", - "/h5/register", - "/h5/validate" - }; - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - String requestUri = request.getRequestURI(); - boolean flag = true; - if (!requestUri.startsWith("/h5/")) { - return super.preHandle(request, response, handler); - } - - for (String s : WHITE_PATHS) { - if (requestUri.startsWith(s)) { - flag = false; - break; - } - } - if (!flag) { - return super.preHandle(request, response, handler); - } - LoginMember loginMember = tokenService.getLoginMember(request); - if (loginMember == null) { - throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); - } - tokenService.verifyMemberToken(loginMember); - //获取会员信息 - Member member = memberService.selectById(loginMember.getMemberId()); - if (member == null || member.getStatus() == 0) { - throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); - } - //将会员信息存放至全局 - LocalDataUtil.setVar(Constants.MEMBER_INFO, member); - - return super.preHandle(request, response, handler); - } - - - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MvcConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MvcConfig.java deleted file mode 100644 index dc8ca76..0000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/MvcConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.ruoyi.web.core.config; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -@Slf4j -public class MvcConfig extends WebMvcConfigurerAdapter { - - @Bean - public H5MemberInterceptor memberInterceptor() { - return new H5MemberInterceptor(); - } - - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(memberInterceptor()); - } -} diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index c9cbdbc..59a31c5 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -6,9 +6,9 @@ spring: druid: # 主库数据源 master: - url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true + url: jdbc:mysql://localhost:3306/yj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true username: root - password: password + password: 123456 # 从库数据源 slave: # 从数据源开关/默认关闭 @@ -23,46 +23,24 @@ spring: # redis 配置 redis: # 地址 - host: + host: localhost # 端口,默认为6379 - port: + port: 6379 # 数据库索引 - database: + database: 0 # 密码 password: -ruoyi: - # 文件路径 示例( Windows配置C:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) - profile: C:/ruoyi/uploadPath + scheduling: enabled: false -#操作oss需要的一些参数 -aliyun: - accessKeyId: 你的accessKeyId # 阿里云的accessKeyId - secretAccessKey: 你的accessKey密码 # accessKey 密码 - oss: - endPoint: 你的endpoint # Endpoint:在阿里云oss控制台查看自己使用的endpoint - bucketName: 你的bucketName # bucket 名称 -wechat: - enabled: false - appId: 你的微信服务号信息(h5的时候需要,小程序的时候不需要) - secret: 你的微信服务号信息(h5的时候需要,小程序的时候不需要) - merchantId: 微信支付商户号 - privateKeyPath: 微信支付密钥地址相对地址 - merchantSerialNumber: 微信支付密钥对应的序列号 - apiV3key: 微信支付apiV3key - notifyUrl: 微信支付回调地址 - miniProgramAppId: 小程序apppid(h5的时候不需要) - miniProgramSecret: 小程序Secret(h5的时候不需要) -sms: - enabled: true - # 阿里云 dysmsapi.aliyuncs.com - endpoint: dysmsapi.aliyuncs.com - accessKeyId: 你的accessKeyId #阿里云短信服务控制台查看 - accessKeySecret: 你的accessKeySecret #同上 - signName: 签名 - templateId: 模板id - # 腾讯专用 - sdkAppId: -aes: - # aes的密钥(长度只能是16或24或32位) - key: 1111111111111111 + +minio: + endpoint: http://62.234.183.14:9000 + accessKey: IvostdowO3hTkXuaa392 + secretKey: wZCLColkVlNMYrxczzdvEC2VyK3lLh5DCb8yrFhE + bucketName: yoga-mall + productImagePath: mall-product-image + courseImagePath: mall-course-image + filePath: file + videoPath: video + expireIn: 180 # 文件过期时间,单位:天 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index ecf1495..10f88dd 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -9,7 +9,7 @@ ruoyi: # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) - profile: C:/ruoyi/uploadPath + profile: /workspace/project/yoga/uploadPath # 获取ip地址开关 addressEnabled: true # 验证码类型 math 数组计算 char 字符验证 @@ -44,7 +44,7 @@ spring: messages: # 国际化资源文件路径 basename: i18n/messages - profiles: + profiles: active: druid # 文件上传 servlet: @@ -118,7 +118,7 @@ token: # 令牌自定义标识 header: Authorization # 令牌密钥 - secret: abcdefghijkomnopqrstuvwxyx + secret: 4b5c4d8cc1a5d54afac74291c8f43dc6 # 令牌有效期(默认30分钟) expireTime: 30 memberExpireTime: 30 @@ -137,7 +137,7 @@ mybatis-plus: pagehelper: helperDialect: mysql supportMethodsArguments: true - params: count=countSql + params: count=countSql # Swagger配置 swagger: @@ -147,7 +147,7 @@ swagger: pathMapping: /dev-api # 防止XSS攻击 -xss: +xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/common/CommonTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/common/CommonTest.java deleted file mode 100644 index 1d2b384..0000000 --- a/ruoyi-admin/src/test/java/com/fjp/lc/test/common/CommonTest.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.fjp.lc.test.common; - -import cn.hutool.core.img.Img; -import cn.hutool.core.img.ImgUtil; -import cn.hutool.core.io.FileUtil; -import com.alibaba.fastjson.JSON; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.Test; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.web.client.RestTemplate; - -import java.io.File; -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; - -@Slf4j -public class CommonTest { - /* @Test - public void test3() throws IOException { - Long start = System.currentTimeMillis(); - log.info("start {}", start); - Thumbnails.of("D:/build/tt.jpg") - .scale(1f) - .outputQuality(0.5f) - .toFile("D:/build/tt1.jpg"); - log.info("end {}", System.currentTimeMillis() - start); - }*/ - - @Test - public void testEquals(){ - Integer num1 = 100; - Integer num2 = 100; - - System.out.println(num1 == num2); // true,因为对于 Integer 类型,-128 到 127 之间的值会被缓存 - System.out.println(num1.equals(num2)); // true,因为它们的值相同 - - Integer num3 = 200; - Integer num4 = 200; - - System.out.println(num3 == num4); // false,因为超出了缓存范围,会创建新的对象实例 - System.out.println(num3.equals(num4)); // true,因为它们的值相同 - } - - @Test - public void test4() throws IOException { - String f1 = "D:/build/tt.jpg"; - String f2 = "D:/build/tt2.jpg"; - Long start = System.currentTimeMillis(); - log.info("start {}", start); - ImgUtil.scale(new File(f1), new File(f2), .1f); - log.info("end {}", System.currentTimeMillis() - start); - } - @Test - public void test5() throws IOException { - String f1 = "D:/build/tt.jpg"; - String f2 = "D:/build/tt3.jpg"; - Long start = System.currentTimeMillis(); - log.info("start {}", start); - Img.from(FileUtil.file(f1)) - .setQuality(1)//压缩比率 - .write(FileUtil.file(f2)); - log.info("end {}", System.currentTimeMillis() - start); - } - - @Test - public void testTimestampt(){ - Instant tsObj = Instant.now(); - - long secs = tsObj.getEpochSecond(); - - System.out.println(secs); - } - - @Test - public void test() throws NoSuchAlgorithmException { - RestTemplate restTemplate = new RestTemplate(); - - String url = "http://bmfw.www.gov.cn/bjww/interface/interfaceJson"; - - String key = "3C502C97ABDA40D0A60FBEE50FAAD1DA"; - Long timestamp = Instant.now().getEpochSecond(); - String token = "23y0ufFl5YxIyGrI8hWRUZmKkvtSjLQA"; - String nonce ="123456789abcdefg"; - String passid = "zdww"; - String tempString = timestamp + token + nonce + timestamp; - - String signatureHeader = DigestUtils.sha256Hex(tempString).toUpperCase(); - System.out.println(signatureHeader); - tempString = timestamp + "fTN2pfuisxTavbTuYVSsNJHetwq5bJvC" + "QkjjtiLM2dCratiA" + timestamp; - String zdwwsignature = DigestUtils.sha256Hex(tempString).toUpperCase(); - System.out.println(zdwwsignature); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.set("x-wif-nonce","QkjjtiLM2dCratiA"); - headers.set("x-wif-paasid","smt-application"); - headers.set("x-wif-signature",zdwwsignature); - headers.set("x-wif-timestamp",timestamp.toString()); - headers.set("Origin","http://bmfw.www.gov.cn"); - headers.set("Referer","http://bmfw.www.gov.cn/yqfxdjcx/risk.html"); - - Map map = new HashMap(); - map.put("appId","NcApplication"); - map.put("paasHeader",passid); - map.put("timestampHeader",timestamp.toString()); - map.put("nonceHeader",nonce); - map.put("signatureHeader",signatureHeader); - map.put("key",key); - - String json= JSON.toJSONString(map); - System.out.println(json); - HttpEntity entity = new HttpEntity(json,headers); - - String ans = restTemplate.postForObject(url, entity, String.class); - System.out.println(ans); - - } -} diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ControllerTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ControllerTest.java deleted file mode 100644 index a688858..0000000 --- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ControllerTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.fjp.lc.test.service; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.cyl.h5.controller.H5OrderController; -import com.cyl.h5.domain.form.ApplyRefundForm; -import com.cyl.manager.oms.domain.entity.Order; -import com.cyl.manager.oms.domain.entity.OrderItem; -import com.cyl.manager.oms.mapper.OrderMapper; -import com.cyl.manager.oms.service.OrderService; -import com.ruoyi.RuoYiApplication; -import lombok.extern.slf4j.Slf4j; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -import java.math.BigDecimal; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RuoYiApplication.class) -@ActiveProfiles("dev") -@Slf4j -public class ControllerTest { - @Autowired - private H5OrderController h5OrderController; - - @Autowired - private OrderMapper orderMapper; - - @Test - public void test() { - ApplyRefundForm applyRefundForm = new ApplyRefundForm(); - QueryWrapper queryWrapper = new QueryWrapper(); - queryWrapper.eq("pay_id", 6226229322123265l); - Order order = orderMapper.selectOne(queryWrapper); - applyRefundForm.setOrderId(order.getId()); - applyRefundForm.setApplyRefundType(1); - applyRefundForm.setReason("不要了"); - applyRefundForm.setQuantity(1); - applyRefundForm.setRefundAmount(new BigDecimal(0.01)); - h5OrderController.applyRefund(applyRefundForm); - } - -} diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/OssTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/OssTest.java deleted file mode 100644 index 2d1b3ba..0000000 --- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/OssTest.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.fjp.lc.test.service; - -import com.ruoyi.RuoYiApplication; -import com.ruoyi.common.utils.OssUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = RuoYiApplication.class) -@ActiveProfiles("dev") -public class OssTest { - - @Autowired - private OssUtils ossUtils; - @Test - public void download() { - ossUtils.downloadFile("2022/12/306da8f7f6491046ba86633e4de8240b84微信图片_20220606114231.jpg"); - ossUtils.downloadFile("2022/12/29543652b023af4caeb5d9d74c2f98bdfb微信图片_20220606114231.jpg"); - ossUtils.downloadFile("2022/12/30237d83af8f8e494f98caff9ac87d8eed微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/03/119682c2bb40d54639b51f9819cb127f44400x400.png"); - ossUtils.downloadFile("2023/03/11a67b86d4dd6b4fc687f9044155c34083400x400blue.png"); - ossUtils.downloadFile("2023/07/26975a5546e4e14baca40ffde696ee3ffb微信图片_202304151221202.jpg"); - ossUtils.downloadFile("2023/07/26e89dd1d370b74598aba6dd7cced81f72微信图片_20230415121747.jpg"); - ossUtils.downloadFile("2023/07/2625f4fc4576974035990f35ffae4cbe89微信图片_202305311200104.jpg"); - ossUtils.downloadFile("2023/07/269436b74dd01f45a09e0d63c02bc2bc20微信图片_202207241638361.jpg"); - ossUtils.downloadFile("2023/07/2609fb7c7b52f04b29893fb7034d5488eb微信图片_20220822144529.jpg"); - ossUtils.downloadFile("2023/07/26561982918fbd4269abc1a87ea7c2f09b微信图片_20230518014301.jpg"); - ossUtils.downloadFile("2023/05/26572ddcb26dd64ea9aef1615c518311f2main.jpg"); - ossUtils.downloadFile("2023/07/26b0e6d79409c047afbf435c2e45b2864e微信图片_202305070430094.jpg"); - ossUtils.downloadFile("2023/07/268673a92f29ea4ed9a3503587c658fb7d微信图片_20230304190516.jpg"); - ossUtils.downloadFile("2023/08/14ff4bde97153a416e9cdde8035bc7e0f326db1efa38167a4cd5ab392cd7bb6b8fc9ed5b46ef3e460fe27f73aa280993004.jpg.png"); - ossUtils.downloadFile("2023/07/269922ae58ef074304a907f6524d13401c微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/12/03847a4833090f40de9c6b49f7d553608a微信图片_202303082336274.jpg"); - ossUtils.downloadFile("2023/12/034459c85e71e3402aba5eb7e0531201fd微信图片_202303082336273.jpg"); - ossUtils.downloadFile("2023/12/03d3e5fc569e7d42529c8a3b504ae4d92c微信图片_202303082336271.jpg"); - ossUtils.downloadFile("2023/12/0383e8c4d2be284355a07233bc1c38e6d7微信图片_202303082336272.jpg"); - ossUtils.downloadFile("2023/06/12539d8d04c72247c4bd4ac3820ae939a3227ddfae236d5a4adca97541f7937488dc033fc965331ca74b3a9d6daa9fd0e48225sy_content_good_stuff@2x.png"); - ossUtils.downloadFile("2023/03/113d7ab00580e44f9ab2d274c0e3f9cd89400x400.png"); - ossUtils.downloadFile("2023/03/11a1e8bc35653044d2a2012ef1a30dc5d9blue.png"); - ossUtils.downloadFile("2023/03/11ca202adcbef54a97879e3b6ca9214729red.png"); - ossUtils.downloadFile("2023/03/113be968d872ca4a0bb0d8fc08e13bb81fgrey.png"); - ossUtils.downloadFile("2023/03/112f186945ad444e71a6fdaf5a634577d0yellow.png"); - ossUtils.downloadFile("2023/03/11703d301ec87448a8ad8c754ca7c043e5blue.png"); - ossUtils.downloadFile("2023/06/126850de7100594b2cbe67ba10ac30315e227ddfae236d5a4adca97541f7937488dc033fc965331ca74b3a9d6daa9fd0e48225sy_content_good_stuff@2x.png"); - ossUtils.downloadFile("2023/06/1297a4dd69e5b14fe0bc8da968c0b2043f22dea3ccb9cd45412da6300c5ac7d8f68903bae3d53cef7f4dfeb38bbafe109a3755sy_content_digital@2x.png"); - ossUtils.downloadFile("2023/06/1261979f808cb04d108727cf3709ffa355226569ab1688ec4eb8a7a2d879f3cd36b303df12b214f50f49928b53ad113e11170bsy_content_apparel@2x.png"); - ossUtils.downloadFile("2023/06/123c2915e18c604f3290ff4876954f6aa32213fbf4b69d9041d68da50fdd71aa6b5403afbad6ea2bce46db8108e48eb2bed9d3sy_content_care@2x.png"); - ossUtils.downloadFile("2023/06/12beec9af7400c44deb3951fa5be95b0ae22e0ce080252874dd4b22e7559ac1478bf036ce7046f48eb4faba7f43849d2d7814dsy_content_rice@2x.png"); - ossUtils.downloadFile("2023/06/12cbeee94461d44d13bba3503682286e382231e1747caf7a4f9f9d54af5789d1d538033d7aaef21b2b4984abd8a07a2b97c49csy_content_drinks@2x.png"); - ossUtils.downloadFile("2023/06/121dde34bbb8024ac99e09af20e380d78822b62a9a9f2e8349cc9e0321a53e27bf780322d4a84f6c334c7d984484f04e87dbb1sy_content_sports@2x.png"); - ossUtils.downloadFile("2023/06/129a33a0881f4e4d279cc067e592b588612253d01aa5f365420e8b96cd93ee1893f6035a69224ec7904e2b94047f22ddfb5d19sy_content_other@2x.png"); - ossUtils.downloadFile("2023/03/119682c2bb40d54639b51f9819cb127f44400x400.png"); - ossUtils.downloadFile("2023/03/11a67b86d4dd6b4fc687f9044155c34083400x400blue.png"); - ossUtils.downloadFile("2023/07/26975a5546e4e14baca40ffde696ee3ffb微信图片_202304151221202.jpg"); - ossUtils.downloadFile("2023/07/26e89dd1d370b74598aba6dd7cced81f72微信图片_20230415121747.jpg"); - ossUtils.downloadFile("2023/07/2625f4fc4576974035990f35ffae4cbe89微信图片_202305311200104.jpg"); - ossUtils.downloadFile("2023/07/269436b74dd01f45a09e0d63c02bc2bc20微信图片_202207241638361.jpg"); - ossUtils.downloadFile("2023/07/2609fb7c7b52f04b29893fb7034d5488eb微信图片_20220822144529.jpg"); - ossUtils.downloadFile("2023/07/26561982918fbd4269abc1a87ea7c2f09b微信图片_20230518014301.jpg"); - ossUtils.downloadFile("2023/05/26572ddcb26dd64ea9aef1615c518311f2main.jpg"); - ossUtils.downloadFile("2023/07/26b0e6d79409c047afbf435c2e45b2864e微信图片_202305070430094.jpg"); - ossUtils.downloadFile("2023/07/268673a92f29ea4ed9a3503587c658fb7d微信图片_20230304190516.jpg"); - ossUtils.downloadFile("2023/08/14ff4bde97153a416e9cdde8035bc7e0f326db1efa38167a4cd5ab392cd7bb6b8fc9ed5b46ef3e460fe27f73aa280993004.jpg.png"); - ossUtils.downloadFile("2023/07/269922ae58ef074304a907f6524d13401c微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/26ecce066aa266490b9462dd6326ad1718微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/264d37c9c96f464a3c9a25cca77312e2a6微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/07/263ab3be7a6bb24ad7b809f550e0948939微信图片_20220801215429.png"); - ossUtils.downloadFile("2023/06/16f6c3727142d4486089a09dbd19762c39266fb233a90ba449bf9c082ebd592078dd1679204678mm5.jpg"); - ossUtils.downloadFile("2023/06/1654b558f7bbc241a8aecd5f017227a3e4266fb233a90ba449bf9c082ebd592078dd1679204678mm5.jpg"); - ossUtils.downloadFile("2023/06/1638b241a1b12d4a4ebf8c5eb08bc9986d266fb233a90ba449bf9c082ebd592078dd1679204678mm5.jpg"); - ossUtils.downloadFile("2023/06/16da593a9165834cabb4ab5ed2ba580cbd266fb233a90ba449bf9c082ebd592078dd1679204678mm5.jpg"); - ossUtils.downloadFile("2023/12/03847a4833090f40de9c6b49f7d553608a微信图片_202303082336274.jpg"); - ossUtils.downloadFile("2023/12/034459c85e71e3402aba5eb7e0531201fd微信图片_202303082336273.jpg"); - ossUtils.downloadFile("2023/12/03d3e5fc569e7d42529c8a3b504ae4d92c微信图片_202303082336271.jpg"); - ossUtils.downloadFile("2023/12/0383e8c4d2be284355a07233bc1c38e6d7微信图片_202303082336272.jpg"); - ossUtils.downloadFile("2023/08/148a3892f617f04af3ab2da2dbf50b2219269922ae58ef074304a907f6524d13401c微信图片_20220801215429.png.png"); - ossUtils.downloadFile("2023/05/266fb233a90ba449bf9c082ebd592078dd1679204678mm5.jpg"); - ossUtils.downloadFile("2023/05/2602dc3dc1e02f44289c89a5426b3922femain.jpg"); - ossUtils.downloadFile("2023/05/2688e9a4a5a22847eda09c555a0f16f3a52222.png"); - ossUtils.downloadFile("2023/07/26db1efa38167a4cd5ab392cd7bb6b8fc9ed5b46ef3e460fe27f73aa280993004.jpg"); - ossUtils.downloadFile("2023/07/26079a8b93ec924d44b11915cc17dfd53e微信图片_20230415122120.jpg"); - ossUtils.downloadFile("2023/07/267eaa27402fd44f2ea12801cd263b6a41微信图片_20230507043009.jpg"); - ossUtils.downloadFile("2023/07/26d9a42d98a1a244d094b39516be0241c9微信图片_20230415121747.jpg"); - ossUtils.downloadFile("2023/07/263c45b789fb254c2fbc6bb639357b3f5f微信图片_202305311200104.jpg"); - ossUtils.downloadFile("2023/07/269436b74dd01f45a09e0d63c02bc2bc20微信图片_202207241638361.jpg"); - ossUtils.downloadFile("2023/07/2609fb7c7b52f04b29893fb7034d5488eb微信图片_20220822144529.jpg"); - ossUtils.downloadFile("2023/07/268673a92f29ea4ed9a3503587c658fb7d微信图片_20230304190516.jpg"); - ossUtils.downloadFile("2023/07/26561982918fbd4269abc1a87ea7c2f09b微信图片_20230518014301.jpg"); - ossUtils.downloadFile("2023/12/187be2528584434a488b4580c363bc559d作品.jpg"); - ossUtils.downloadFile("2023/07/26f73d933b547a4574979ee7ae3ede47f4微信图片_202304151217474.jpg"); - ossUtils.downloadFile("2023/05/26972c7a98b6df49dab1fe839232bff5c31679204678mm5.jpg"); - ossUtils.downloadFile("2023/05/267c68f6226f2a443485699c8411e299d4main.jpg"); - ossUtils.downloadFile("2023/05/26db36f518447d4df98957285931c83d7c1r.jpg"); - ossUtils.downloadFile("2023/05/2629464fb14f79418985a99ba3238b8db624.jpg"); - ossUtils.downloadFile("2023/05/267c89e30b8f8c45d58161a4e78800d4813.jpg"); - ossUtils.downloadFile("2023/05/263a48cd980e5546f8b2db583f1753c6f64.jpg"); - ossUtils.downloadFile("2023/05/263252d6187d1647c186b5c3e703615e352222.png"); - ossUtils.downloadFile("2023/07/26fb45128fd4e44b049148db359ff53c01a82772585ab081455e14bbe92afbc64.jpg"); - ossUtils.downloadFile("2023/07/2619a2b65b4ac54d10a8ccd1078d800a7bc46ad9eba9cd72a0995a1ea0c3f06dd.jpg"); - ossUtils.downloadFile("2023/07/26d43585cc52dd43e7b33d29a8812bf766微信图片_202303292142191.jpg"); - ossUtils.downloadFile("2023/07/2636761e811dfb4c1192cf3aeaf6c32a78微信图片_20230329214219.jpg"); - ossUtils.downloadFile("2023/07/26af858c07e28044baabf4670f0a18d759微信图片_202303292142192.jpg"); - ossUtils.downloadFile("2023/07/2681376357d7ae42a5b78f318c23d57e14微信图片_202304151221203.jpg"); - ossUtils.downloadFile("2023/07/261e8252d98a2f46698ca78f15107cc49f微信图片_202304151221204.jpg"); - ossUtils.downloadFile("2023/07/26abbd8208878349669e0fb7ea6df11350微信图片_202304151221201.jpg"); - ossUtils.downloadFile("2023/07/267008c38e1fd54ea593693eed573963f7微信图片_20230415122120.jpg"); - ossUtils.downloadFile("2023/07/2635b63ed15d1345d08e6a685701cc58f1微信图片_202304151221202.jpg"); - ossUtils.downloadFile("2023/07/260c209bf387f6490db6505aee72e620f5微信图片_20230507043009.jpg"); - ossUtils.downloadFile("2023/07/268dcb6126ad73407eabb54baa2fb0ec80微信图片_202305070430091.jpg"); - ossUtils.downloadFile("2023/07/262df759a436784bc481080e25a2d9d708微信图片_202305070430092.jpg"); - ossUtils.downloadFile("2023/07/26666593a296a64088af4eb0647a4e2f20微信图片_202305070430094.jpg"); - ossUtils.downloadFile("2023/07/26e1c4d225037746bea54766d2d947aae2微信图片_202305070430093.jpg"); - ossUtils.downloadFile("2023/07/265d82761866ec44a1891a03dc079951de微信图片_20230415121747.jpg"); - ossUtils.downloadFile("2023/07/266b3a6d093bc344409937958a83422c4e微信图片_202304151217471.jpg"); - ossUtils.downloadFile("2023/07/26c681b61d879d48a8a50f219bf0b45423微信图片_202304151217474.jpg"); - ossUtils.downloadFile("2023/07/26c92bd48e55634ed18ce7a49f3488a5e5微信图片_202304151217472.jpg"); - ossUtils.downloadFile("2023/07/26160d66ecfa6d4e4480936c0627ab6168微信图片_202304151217473.jpg"); - ossUtils.downloadFile("2023/07/26e91ff64478f8405a817964730d35f645微信图片_20230531120010.jpg"); - ossUtils.downloadFile("2023/07/262d7e659fc9044a35a00717d927eb6201微信图片_202305311200101.jpg"); - ossUtils.downloadFile("2023/07/26b6d799a3e30e43c4900bd726f1d87c39微信图片_202305311200103.jpg"); - ossUtils.downloadFile("2023/07/26555fabd98cdf46a58c391898c63f62f2微信图片_202305311200102.jpg"); - ossUtils.downloadFile("2023/07/26f44d84cea13f4276b92c75d072aabeea微信图片_202305311200104.jpg"); - ossUtils.downloadFile("2023/07/2627916262b7c442a08c04f1b3738a1ccc微信图片_20220724163836.jpg"); - ossUtils.downloadFile("2023/07/26ef9876f509e14e0985fb045ea4f8d02f微信图片_202207241638361.jpg"); - ossUtils.downloadFile("2023/07/26f2ac39fef9d7491a8a3908df9695ab51微信图片_202207241638362.jpg"); - ossUtils.downloadFile("2023/07/2676b97cc6b45a43ba96756e9b21dcf2cb微信图片_202207241638363.jpg"); - ossUtils.downloadFile("2023/07/263867f3bf67f248ce9c31fe0985f40523微信图片_202208221445291.jpg"); - ossUtils.downloadFile("2023/07/26feafa3cc0e584620855759538098bc4f微信图片_202208221445292.jpg"); - ossUtils.downloadFile("2023/07/268699fd3e13bb42c5a941784fe85ff366微信图片_202208221445294.jpg"); - ossUtils.downloadFile("2023/07/26b717d87954914c60893fdff0bc6eb83d微信图片_202208221445293.jpg"); - ossUtils.downloadFile("2023/07/267af6e46a2119467ab7baf569f57e0136微信图片_202303041905163.jpg"); - ossUtils.downloadFile("2023/07/26386743e26a594bdcaaf4d481d5d34b0a微信图片_202303041905164.jpg"); - ossUtils.downloadFile("2023/07/26e258e26755474d12967277e16281c0f6微信图片_202303041905165.jpg"); - ossUtils.downloadFile("2023/07/267a9d29bb17a3403e84edc968fb2a5133微信图片_202305180143012.jpg"); - ossUtils.downloadFile("2023/07/26a1f38481c8784e2782f1857b35dfacc1微信图片_202305180143014.jpg"); - ossUtils.downloadFile("2023/07/267bc956e7bb97441e98af9d07aee71f1c微信图片_202305180143013.jpg"); - ossUtils.downloadFile("2023/07/26ee7b2f3365a848c6a952a7b9c4582023微信图片_2022080121"); - ossUtils.downloadFile("2023/05/268ee9e13df1fb499697550eec576b08af1.png"); - ossUtils.downloadFile("2023/05/26795e6f86285a4cc99c21d79f3ad06e1e2.jpg"); - ossUtils.downloadFile("2023/05/26772b2920bfd04a1faf85fe6a9ff5bb953.jpg"); - ossUtils.downloadFile("2023/05/2600944930702a442583d92c3bd6ba6af94.jpg"); - ossUtils.downloadFile("2023/05/26b6ba13ad4ade4ba881466c58cb21bfd8main.jpg"); - ossUtils.downloadFile("2023/05/262961530966aa48c5a5f13860b446a0df24.jpg"); - ossUtils.downloadFile("2023/05/26d678b548b96b437cb1ca4402771525c23.jpg"); - ossUtils.downloadFile("2023/05/264d31c21f18924e02bd386dd7be61809e4.jpg"); - ossUtils.downloadFile("2023/05/26ba2304c124294ff6b47e3b7bb9faa900a.jpg"); - ossUtils.downloadFile("2023/05/26dcc01da95cb7466095ee4be3e8e57943b.jpg"); - ossUtils.downloadFile("2023/05/266a1c5e16e05b45cfbe152af9ca558b70c.png"); - ossUtils.downloadFile("2023/07/2665647ec5442d4e72960fa1772b5a2befa82772585ab081455e14bbe92afbc64.jpg"); - ossUtils.downloadFile("2023/07/26759113e01b5f4230be78447d733de531微信图片_202304151221205.jpg"); - ossUtils.downloadFile("2023/07/264e6e7ee82cb144b498757c8c2b65bf83微信图片_20230507043009.jpg"); - ossUtils.downloadFile("2023/07/26898650b538c34de399e831417c4bb69a微信图片_202304151217474.jpg"); - ossUtils.downloadFile("2023/07/269e8efd18c2784fe29898d8f0885cc688微信图片_202305311200101.jpg"); - ossUtils.downloadFile("2023/07/2688d0c5787ae54b158b88a03a3f874c68微信图片_202305311200102.jpg"); - ossUtils.downloadFile("2023/07/26596a8e6b207a474fa4e7cf5560da251d微信图片_202207241638366.jpg"); - ossUtils.downloadFile("2023/07/26832713b49dd4488eaf3c3d46b9dfe83d微信图片_202207241638367.jpg"); - ossUtils.downloadFile("2023/07/26e9928d05666e47e488491e63d8d4c7d5微信图片_20220822144529.jpg"); - ossUtils.downloadFile("2023/07/26c442b5df35c140228dde498ef4b6c1d2微信图片_202303041905161.jpg"); - ossUtils.downloadFile("2023/07/26779b5452701140d9927c698825eb93e0微信图片_202305180143011.jpg"); - ossUtils.downloadFile("2023/07/26405414f3d4134af1a786585c6780f88c微信图片_202305180143014.jpg"); - } -} diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java deleted file mode 100644 index 65a4940..0000000 --- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.fjp.lc.test.service; - -import cn.hutool.core.lang.Snowflake; -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.core.util.IdUtil; -import cn.hutool.crypto.SecureUtil; -import cn.hutool.crypto.symmetric.AES; -import com.alibaba.fastjson.JSON; -import com.cyl.h5.domain.dto.PayNotifyMessageDTO; -import com.cyl.h5.service.H5OrderService; -import com.cyl.job.OrderJob; -import com.cyl.manager.act.service.IntegralHistoryService; -import com.cyl.manager.oms.service.AftersaleService; -import com.cyl.manager.ums.service.MemberCartService; -import com.ruoyi.RuoYiApplication; -import com.ruoyi.common.config.properties.SmsProperties; -import com.ruoyi.common.core.sms.AliyunSmsTemplate; -import com.ruoyi.common.core.sms.SmsTemplate; -import com.ruoyi.common.utils.SecurityUtils; -import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; -import com.wechat.pay.java.service.refund.model.RefundNotification; -import lombok.extern.slf4j.Slf4j; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -import java.math.BigDecimal; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = RuoYiApplication.class) -@ActiveProfiles("dev") -@Slf4j -public class ServiceTest { - - @Autowired - private AftersaleService aftersaleService; - - @Autowired - private MemberCartService memberCartService; - - @Autowired - private SmsProperties smsProperties; - - @Value("${aes.key}") - private String key; - - @Autowired - private IntegralHistoryService integralHistoryService; - @Autowired - private OrderJob orderJob; - - @Test - public void testOrderJob(){ - orderJob.batchCompleteOrder(); - } - - @Test - public void test12(){ - integralHistoryService.handleIntegral(5405053175810048L,new BigDecimal("2.89"),29L); - } - - - @Test - public void t(){ - String a = "{\"amount\":{\"currency\":\"CNY\",\"discountRefund\":0,\"from\":[],\"payerRefund\":2,\"payerTotal\":2,\"refund\":2,\"refundFee\":0,\"settlementRefund\":2,\"settlementTotal\":2,\"total\":2},\"channel\":\"ORIGINAL\",\"createTime\":\"2024-04-26T18:17:56+08:00\",\"fundsAccount\":\"UNAVAILABLE\",\"outRefundNo\":\"5773276988819456\",\"outTradeNo\":\"5773274485622785\",\"promotionDetail\":[],\"refundId\":\"50303909472024042683046217485\",\"refundStatus\":\"SUCCESS\",\"transactionId\":\"4200002186202404266125196354\",\"userReceivedAccount\":\"支付用户零钱通\"}"; - RefundNotification params = JSON.parseObject(a,RefundNotification.class); - aftersaleService.refundOrderExc(params); - } - @Test - public void test1() { - memberCartService.mineCartNum(); - } - - @Test - public void encryptPassword() { - String newPwd = "admin123"; - System.out.println("新密码:"+ SecurityUtils.encryptPassword(newPwd)); - } - - @Test - public void test2(){ - System.out.println(smsProperties); - if (!smsProperties.getEnabled()) { - throw new RuntimeException("没有开启短信服务"); - } - Map map = new HashMap<>(1); - map.put("code", "1234"); - SmsTemplate smsTemplate = new AliyunSmsTemplate(smsProperties); - Object send = smsTemplate.send("15706259078", "SMS_146125046", map); - log.info("短信发送结果:" + send); - } - - @Test - public void test3(){ - String content = "test中文"; - AES aes = SecureUtil.aes(key.getBytes()); - byte[] encrypt = aes.encrypt(content); - byte[] decrypt = aes.decrypt(encrypt); - String encryptHex = aes.encryptHex(content); - System.out.println("加密后16进制:" + encryptHex); - String decryptStr = aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8); - System.out.println("解密:" + decryptStr); - } - - @Test - public void test4(){ - //参数1为终端ID -//参数2为数据中心ID - Snowflake snowflake = IdUtil.createSnowflake(1, 1); - long id = snowflake.nextId(); - System.out.println("id:" + id); - } - - @Autowired - private H5OrderService h5OrderService; - - @Test - public void test6(){ - PayNotifyMessageDTO messageDTO = new PayNotifyMessageDTO(); - messageDTO.setPayTime(new Date()); - messageDTO.setOutTradeNo(5365581195495425L); - messageDTO.setMemberId(22L); - messageDTO.setTradeStatus(Transaction.TradeStateEnum.SUCCESS); - messageDTO.setTradeNo(""); - ResponseEntity stringResponseEntity = h5OrderService.payCallBack(messageDTO); - System.out.println(stringResponseEntity.getBody()); - } -} diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java deleted file mode 100644 index f28a168..0000000 --- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.fjp.lc.test.service; - -import com.cyl.h5.domain.form.WechatLoginForm; -import com.cyl.manager.ums.service.MemberWechatService; -import com.ruoyi.RuoYiApplication; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = RuoYiApplication.class) -@ActiveProfiles("dev") -public class WechatTest { - @Autowired - private MemberWechatService memberWechatService; - @Test - public void testAuth() { - WechatLoginForm f = new WechatLoginForm(); - f.setCode("081zPgHa1FbRQE0wGIIa1lgb1C1zPgHi"); - memberWechatService.login(f); - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/RestResponse.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/RestResponse.java new file mode 100644 index 0000000..89895c0 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/RestResponse.java @@ -0,0 +1,76 @@ +package com.ruoyi.common.core.domain; + +import cn.hutool.json.JSONUtil; + +import java.util.HashMap; + +public class RestResponse extends HashMap { + public static RestResponse success(){ + return success("成功"); + } + public static RestResponse success(String message){ + RestResponse restResponse = new RestResponse(); + restResponse.setSuccess(true); + restResponse.setMessage(message); + return restResponse; + } + + public static RestResponse failure(String message){ + RestResponse restResponse = new RestResponse(); + restResponse.setSuccess(false); + restResponse.setMessage(message); + return restResponse; + } + + + public RestResponse setSuccess(Boolean success) { + if (success != null) put("success", success); + return this; + } + + public RestResponse setMessage(String message) { + if (message != null) put("message", message); + return this; + } + + public RestResponse setData(Object data) { + if (data != null) put("data", data); + return this; + } + + public RestResponse setPage(Integer page) { + if (page != null) put("page", page); + return this; + } + + public RestResponse setCurrentPage(Integer currentPage){ + if (currentPage != null) put("currentPage", currentPage); + return this; + } + + public RestResponse setLimit(Integer limit) { + if (limit != null) put("limit", limit); + return this; + } + + public RestResponse setTotal(Long total) { + if (total != null) put("total", total); + return this; + } + + public RestResponse setAny(String key, Object value) { + if (key != null && value != null) put(key, value); + return this; + } + + public Boolean getSuccess(){ + return (Boolean) get("success"); + } + public String getMessage(){ + return (String) get("message"); + } + public String toString(){ +// return JSONObject.toJSONString(this); + return JSONUtil.toJsonStr(this); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java index c9238e2..abb9cf4 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java @@ -1,17 +1,18 @@ package com.ruoyi.common.core.domain.entity; -import java.util.ArrayList; -import java.util.List; +import com.ruoyi.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; -import com.ruoyi.common.core.domain.BaseEntity; +import java.util.ArrayList; +import java.util.List; /** * 部门表 sys_dept - * + * * @author ruoyi */ public class SysDept extends BaseEntity @@ -35,6 +36,7 @@ public class SysDept extends BaseEntity /** 负责人 */ private String leader; + private Long leaderId; /** 联系电话 */ private String phone; @@ -50,7 +52,7 @@ public class SysDept extends BaseEntity /** 父部门名称 */ private String parentName; - + /** 子部门 */ private List children = new ArrayList(); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ImageUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ImageUtil.java new file mode 100644 index 0000000..d68c6ea --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ImageUtil.java @@ -0,0 +1,78 @@ +package com.ruoyi.common.utils; + +import lombok.extern.slf4j.Slf4j; +import net.coobird.thumbnailator.Thumbnails; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +@Slf4j +public final class ImageUtil { + + //以下是常量,按照阿里代码开发规范,不允许代码中出现魔法值 + private static final Integer ZERO = 0; + private static final Integer ONE_ZERO_TWO_FOUR = 1024; + private static final Integer NINE_ZERO_ZERO = 900; + private static final Integer THREE_TWO_SEVEN_FIVE = 3275; + private static final Integer TWO_ZERO_FOUR_SEVEN = 2047; + private static final Double ZERO_EIGHT_FIVE = 0.85; + private static final Double ZERO_SIX = 0.6; + private static final Double ZERO_FOUR_FOUR = 0.44; + private static final Double ZERO_FOUR = 0.4; + + /** + * 根据指定大小压缩图片 + * + * @param imageBytes 源图片字节数组 + * @param desFileSize 指定图片大小,单位kb + * @return 压缩质量后的图片字节数组 + */ + public static byte[] compressForScale(byte[] imageBytes, long desFileSize) { + if (imageBytes == null || imageBytes.length <= ZERO || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) { + return imageBytes; + } + long srcSize = imageBytes.length; + double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR); + try { + while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) { + ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length); + Thumbnails.of(inputStream) + .scale(accuracy) + .outputQuality(accuracy) + .toOutputStream(outputStream); + imageBytes = outputStream.toByteArray(); + } + log.info("图片原大小={}kb | 压缩后大小={}kb", + srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR); + } catch (Exception e) { + log.error("【图片压缩】msg=图片压缩失败!", e); + } + return imageBytes; + } + + + /** + * 自动调节精度(经验数值) + * + * @param size 源图片大小 + * @return 图片压缩质量比 + */ + private static double getAccuracy(long size) { + double accuracy; + if (size < NINE_ZERO_ZERO) { + accuracy = ZERO_EIGHT_FIVE; + } else if (size < TWO_ZERO_FOUR_SEVEN) { + accuracy = ZERO_SIX; + } else if (size < THREE_TWO_SEVEN_FIVE) { + accuracy = ZERO_FOUR_FOUR; + } else { + accuracy = ZERO_FOUR; + } + return accuracy; + } + +} + + + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/OssUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/OssUtils.java deleted file mode 100644 index f1f8541..0000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/OssUtils.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.ruoyi.common.utils; - -import cn.hutool.core.date.DateTime; -import com.aliyun.oss.OSS; -import com.aliyun.oss.OSSClientBuilder; -import com.aliyun.oss.model.DownloadFileRequest; -import com.aliyun.oss.model.GetObjectRequest; -import com.ruoyi.common.utils.uuid.UUID; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -@Slf4j -@Component -public class OssUtils { - - @Value("${aliyun.accessKeyId}") - private String accessKeyId; - - @Value("${aliyun.secretAccessKey}") - private String secretAccessKey; - - @Value("${aliyun.oss.endPoint}") - private String endPoint; - - @Value("${aliyun.oss.bucketName}") - private String bucketName; - - public void downloadFile(String objectName){ - // 创建OSSClient实例。 - OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey); - //截取objectName的第二个/之后的内容作为pathName - String pathName = objectName.substring(objectName.lastIndexOf("/")); - try{ - ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File("D:\\oss\\"+pathName)); - }catch (Exception e){ - log.error(pathName); - } - - - } - - public String uploadOneFile(MultipartFile file) { - - // 创建OSSClient实例。 - OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey); - //设置文件名 - String fileName = new DateTime().toString("yyyy/MM/dd") - + UUID.randomUUID().toString().replace("-", "") - + file.getOriginalFilename(); - - try { - // 创建PutObject请求。 - ossClient.putObject(bucketName, fileName, file.getInputStream()); - - String url = "https://" + bucketName + "." + endPoint + "/" + fileName; - return url; - } catch (Exception e) { - e.printStackTrace(); - return null; - } finally { - if (ossClient != null) { - ossClient.shutdown(); - } - } - } - - public List uploadArrayFile(MultipartFile[] files) { - // 创建OSSClient实例。 - OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey); - List list = new ArrayList<>(); - - try { - //设置文件名 - for (MultipartFile file : files) { - String fileName = new DateTime().toString("yyyy/MM/dd") - + UUID.randomUUID().toString().replace("-", "") - + file.getOriginalFilename(); - // 创建PutObject请求。 - ossClient.putObject(bucketName, fileName, file.getInputStream()); - - String url = "http://" + bucketName + "." + endPoint + "/" + fileName; -// System.out.println(url); - list.add(url); - } - - } catch (Exception e) { - e.printStackTrace(); - return null; - } finally { - if (ossClient != null) { - ossClient.shutdown(); - } - } - return list; - - } - - public boolean deleteFile(String fileUrl) { - - // 创建OSSClient实例。 - OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey); - /** oss删除文件是根据文件完成路径删除的,但文件完整路径中不能包含Bucket名称。 - * 比如文件路径为:http://edu-czf.oss-cn-guangzhou.aliyuncs.com/2022/08/abc.jpg", - * 则完整路径就是:2022/08/abc.jpg - */ - int begin = ("http://" + bucketName + "." + endPoint + "/").length(); //找到文件路径的开始下标 - String deleteUrl = fileUrl.substring(begin); - - try { - // 删除文件请求 - ossClient.deleteObject(bucketName, deleteUrl); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } finally { - if (ossClient != null) { - ossClient.shutdown(); - } - } - } - -} - diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index ec958b5..31b03fc 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -20,7 +20,7 @@ import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; /** * spring security配置 - * + * * @author ruoyi */ @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @@ -31,7 +31,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter */ @Autowired private UserDetailsService userDetailsService; - + /** * 认证失败处理类 */ @@ -49,13 +49,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter */ @Autowired private JwtAuthenticationTokenFilter authenticationTokenFilter; - + /** * 跨域过滤器 */ @Autowired private CorsFilter corsFilter; - + /** * 解决 无法直接注入 AuthenticationManager * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/FileInfo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/FileInfo.java new file mode 100644 index 0000000..f4e3069 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/FileInfo.java @@ -0,0 +1,67 @@ +package com.ruoyi.system.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * @author Blue + * @version 1.0 + */ +@Data +@TableName("im_file_info") +public class FileInfo { + + /** + * 文件ID + */ + @TableId + private Long id; + + /** + * 文件名 + */ + private String fileName; + + /** + * 原始文件存储路径 + */ + private String filePath; + + /** + * 压缩文件存储路径 + */ + private String compressedPath; + + /** + * 封面文件路径 + */ + private String coverPath; + + /** + * 原始文件大小(字节) + */ + private Long fileSize; + + /** + * 上传时间 + */ + private Date uploadTime; + + /** + * 文件类型,枚举: FileType + */ + private Integer fileType; + + /** + * 是否永久存储 + */ + private Boolean isPermanent; + + /** + * 文件MD5哈希值 + */ + private String md5; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UploadImageVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UploadImageVO.java new file mode 100644 index 0000000..6e82134 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UploadImageVO.java @@ -0,0 +1,13 @@ +package com.ruoyi.system.domain.vo; + +import lombok.Data; + +@Data +public class UploadImageVO { + + + private String originUrl;//*"原图" + + + private String thumbUrl;//缩略图 +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/FileInfoMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/FileInfoMapper.java new file mode 100644 index 0000000..f78c0d4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/FileInfoMapper.java @@ -0,0 +1,9 @@ +package com.ruoyi.system.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.system.domain.FileInfo; + +public interface FileInfoMapper extends BaseMapper { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/minioConfig/MinIoClientConfig.java b/ruoyi-system/src/main/java/com/ruoyi/system/minioConfig/MinIoClientConfig.java new file mode 100644 index 0000000..1a26faf --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/minioConfig/MinIoClientConfig.java @@ -0,0 +1,19 @@ +package com.ruoyi.system.minioConfig; + +import com.ruoyi.system.thirdparty.MinioProperties; +import io.minio.MinioClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MinIoClientConfig { + + @Bean + public MinioClient minioClient(MinioProperties minioProps) { + // 注入minio 客户端 + return MinioClient.builder() + .endpoint(minioProps.getEndpoint()) + .credentials(minioProps.getAccessKey(), minioProps.getSecretKey()) + .build(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/FileService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/FileService.java new file mode 100644 index 0000000..099eb06 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/FileService.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.system.domain.FileInfo; +import com.ruoyi.system.domain.vo.UploadImageVO; +import org.springframework.web.multipart.MultipartFile; + +public interface FileService extends IService { + + String uploadFile(MultipartFile file); + + UploadImageVO uploadProductImage(MultipartFile file); + UploadImageVO uploadCourseImage(MultipartFile file); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FileServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..4bd8db2 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FileServiceImpl.java @@ -0,0 +1,310 @@ +package com.ruoyi.system.service.impl; + + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.ImageUtil; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.system.domain.FileInfo; +import com.ruoyi.system.domain.vo.UploadImageVO; +import com.ruoyi.system.mapper.FileInfoMapper; +import com.ruoyi.system.service.FileService; +import com.ruoyi.system.thirdparty.MinioProperties; +import com.ruoyi.system.thirdparty.MinioService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.DigestUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.util.Date; +import java.util.Objects; + +/** + * 文件上传服务 + * + * author: Blue date: 2024-09-28 version: 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class FileServiceImpl extends ServiceImpl implements FileService { + + private final MinioService minioSerivce; + + private final MinioProperties minioProps; + + /** + * 最大图片上传大小 + */ + public static final Long MAX_IMAGE_SIZE = 20 * 1024 * 1024L; + /** + * 最大上传文件大小 + */ + public static final Long MAX_FILE_SIZE = 20 * 1024 * 1024L; + public static final int FILE = 0;//文件 + public static final int PRODUCTIMAGE = 1;//商品图片 + public static final int COURSEIMAGE = 2;//课程图片 + public static final Boolean isPermanent = true;//课程图片 + + + + @PostConstruct + public void init() { + if (!minioSerivce.bucketExists(minioProps.getBucketName())) { + // 创建bucket + minioSerivce.makeBucket(minioProps.getBucketName()); + // 公开bucket + minioSerivce.setBucketPublic(minioProps.getBucketName()); + } + } + + + @Override + public String uploadFile(MultipartFile file) { + try { + Long userId = SecurityUtils.getUserId(); + // 大小校验 + if (file.getSize() > MAX_FILE_SIZE) { + throw new GlobalException("文件大小不能超过20M"); + } + // 如果文件已存在,直接复用 + String md5 = DigestUtils.md5DigestAsHex(file.getInputStream()); + FileInfo fileInfo = findByMd5(md5); + if (!Objects.isNull(fileInfo)) { + // 更新上传时间 + fileInfo.setUploadTime(new Date()); + this.updateById(fileInfo); + // 返回 + return fileInfo.getFilePath(); + } + // 上传 + String fileName = minioSerivce.upload(minioProps.getBucketName(), minioProps.getFilePath(), file); + if (StringUtils.isEmpty(fileName)) { + throw new GlobalException( "文件上传失败"); + } + String url = generUrl(FILE, fileName); + // 保存文件 + saveFileInfo(file, md5, url); + log.info("文件文件成功,用户id:{},url:{}", userId, url); + return url; + } catch (IOException e) { + log.error("上传图片失败,{}", e.getMessage(), e); + throw new GlobalException( "上传图片失败"); + } + } + + /** + * 上传商城相关图片 + * @param file + * @return + */ + @Transactional + @Override + public UploadImageVO uploadProductImage(MultipartFile file) { + try { + Long userId = SecurityUtils.getUserId(); + // 大小校验 + if (file.getSize() > MAX_IMAGE_SIZE) { + throw new GlobalException("图片大小不能超过20M"); + } + // 图片格式校验 + if (!isImage(file.getOriginalFilename())) { + throw new GlobalException("图片格式不合法"); + } + UploadImageVO vo = new UploadImageVO(); + // 如果文件已存在,直接复用 + String md5 = DigestUtils.md5DigestAsHex(file.getInputStream()); + FileInfo fileInfo = findByMd5(md5); + if (!Objects.isNull(fileInfo)) { + // 更新上传时间和持久化标记 + fileInfo.setIsPermanent(isPermanent || fileInfo.getIsPermanent()); + fileInfo.setUploadTime(new Date()); + this.updateById(fileInfo); + // 返回 + vo.setOriginUrl(fileInfo.getFilePath()); + vo.setThumbUrl(fileInfo.getCompressedPath()); + return vo; + } + // 上传原图 + String fileName=minioSerivce.upload(minioProps.getBucketName(), minioProps.getProductImagePath(), file); + + + + if (StringUtils.isEmpty(fileName)) { + throw new GlobalException("图片上传失败"); + } + vo.setOriginUrl(generUrl(PRODUCTIMAGE, fileName)); + if (file.getSize() > 50 * 1024) { + // 大于50K的文件需上传缩略图 + byte[] imageByte = ImageUtil.compressForScale(file.getBytes(), 30); + String thumbFileName= minioSerivce.upload(minioProps.getBucketName(), minioProps.getProductImagePath(), + file.getOriginalFilename(), imageByte, file.getContentType()); + + + if (StringUtils.isEmpty(thumbFileName)) { + throw new GlobalException( "图片上传失败"); + } + vo.setThumbUrl(generUrl(PRODUCTIMAGE, thumbFileName)); + // 保存文件信息 + saveImageFileInfo(file, md5, vo.getOriginUrl(), vo.getThumbUrl(), isPermanent,PRODUCTIMAGE); + }else{ + // 小于50k,用原图充当缩略图 + vo.setThumbUrl(generUrl(PRODUCTIMAGE, fileName)); + // 保存文件信息,由于缩略图不允许删除,此时原图也不允许删除 + saveImageFileInfo(file, md5, vo.getOriginUrl(), vo.getThumbUrl(), true,PRODUCTIMAGE); + } + log.info("文件图片成功,用户id:{},url:{}", userId, vo.getOriginUrl()); + return vo; + } catch (IOException e) { + log.error("上传图片失败,{}", e.getMessage(), e); + throw new GlobalException( "图片上传失败"); + } + } + + /** + * 上传课程相关图片 + * @param file + * @return + */ + @Transactional + @Override + public UploadImageVO uploadCourseImage(MultipartFile file) { + try { + Long userId = SecurityUtils.getUserId(); + // 大小校验 + if (file.getSize() > MAX_IMAGE_SIZE) { + throw new GlobalException("图片大小不能超过20M"); + } + // 图片格式校验 + if (!isImage(file.getOriginalFilename())) { + throw new GlobalException("图片格式不合法"); + } + UploadImageVO vo = new UploadImageVO(); + // 如果文件已存在,直接复用 + String md5 = DigestUtils.md5DigestAsHex(file.getInputStream()); + FileInfo fileInfo = findByMd5(md5); + if (!Objects.isNull(fileInfo)) { + // 更新上传时间和持久化标记 + fileInfo.setIsPermanent(isPermanent || fileInfo.getIsPermanent()); + fileInfo.setUploadTime(new Date()); + this.updateById(fileInfo); + // 返回 + vo.setOriginUrl(fileInfo.getFilePath()); + vo.setThumbUrl(fileInfo.getCompressedPath()); + return vo; + } + // 上传原图 + String fileName=minioSerivce.upload(minioProps.getBucketName(), minioProps.getCourseImagePath(), file); + + + + if (StringUtils.isEmpty(fileName)) { + throw new GlobalException("图片上传失败"); + } + vo.setOriginUrl(generUrl(COURSEIMAGE, fileName)); + if (file.getSize() > 50 * 1024) { + // 大于50K的文件需上传缩略图 + byte[] imageByte = ImageUtil.compressForScale(file.getBytes(), 30); + String thumbFileName= minioSerivce.upload(minioProps.getBucketName(), minioProps.getCourseImagePath(), + file.getOriginalFilename(), imageByte, file.getContentType()); + + + if (StringUtils.isEmpty(thumbFileName)) { + throw new GlobalException( "图片上传失败"); + } + vo.setThumbUrl(generUrl(COURSEIMAGE, thumbFileName)); + // 保存文件信息 + saveImageFileInfo(file, md5, vo.getOriginUrl(), vo.getThumbUrl(), isPermanent,COURSEIMAGE); + }else{ + // 小于50k,用原图充当缩略图 + vo.setThumbUrl(generUrl(COURSEIMAGE, fileName)); + // 保存文件信息,由于缩略图不允许删除,此时原图也不允许删除 + saveImageFileInfo(file, md5, vo.getOriginUrl(), vo.getThumbUrl(), true,COURSEIMAGE); + } + log.info("文件图片成功,用户id:{},url:{}", userId, vo.getOriginUrl()); + return vo; + } catch (IOException e) { + log.error("上传图片失败,{}", e.getMessage(), e); + throw new GlobalException( "图片上传失败"); + } + } + private String generUrl(int fileType, String fileName) { + return StrUtil.join("/", minioProps.getEndpoint(), minioProps.getBucketName(), getBucketPath(fileType), fileName); + } + + private String getBucketPath(int fileType) { + switch (fileType) { + case FILE : return minioProps.getFilePath(); + case COURSEIMAGE : return minioProps.getCourseImagePath(); + case PRODUCTIMAGE: return minioProps.getProductImagePath(); + default:return null; + } + } + + private FileInfo findByMd5(String md5) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(FileInfo::getMd5, md5); + return getOne(wrapper); + } + + private void saveImageFileInfo(MultipartFile file, String md5, String filePath, String compressedPath, + Boolean isPermanent,int fileType) throws IOException { + FileInfo fileInfo = new FileInfo(); + fileInfo.setFileName(file.getOriginalFilename()); + fileInfo.setFileSize(file.getSize()); + fileInfo.setFileType(fileType); + fileInfo.setFilePath(filePath); + fileInfo.setCompressedPath(compressedPath); + fileInfo.setMd5(md5); + fileInfo.setIsPermanent(isPermanent); + fileInfo.setUploadTime(new Date()); + this.save(fileInfo); + } + + private void saveFileInfo(MultipartFile file, String md5, String filePath) throws IOException { + FileInfo fileInfo = new FileInfo(); + fileInfo.setFileName(file.getOriginalFilename()); + fileInfo.setFileSize(file.getSize()); + fileInfo.setFileType(FILE); + fileInfo.setFilePath(filePath); + fileInfo.setMd5(md5); + fileInfo.setIsPermanent(false); + fileInfo.setUploadTime(new Date()); + this.save(fileInfo); + } + /** + * 获取文件后缀 + * + * @param fileName 文件名 + * @return boolean + */ + public static String getFileExtension(String fileName) { + return fileName.substring(fileName.lastIndexOf(".") + 1); + } + + /** + * 判断文件是否图片类型 + * + * @param fileName 文件名 + * @return boolean + */ + public static boolean isImage(String fileName) { + String extension = getFileExtension(fileName); + String[] imageExtension = new String[]{"jpeg", "jpg", "bmp", "png", "webp", "gif"}; + for (String e : imageExtension) { + if (extension.toLowerCase().equals(e)) { + return true; + } + } + + return false; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/thirdparty/MinioProperties.java b/ruoyi-system/src/main/java/com/ruoyi/system/thirdparty/MinioProperties.java new file mode 100644 index 0000000..0c04d40 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/thirdparty/MinioProperties.java @@ -0,0 +1,30 @@ +package com.ruoyi.system.thirdparty; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "minio") +public class MinioProperties { + + private String endpoint; + + private String accessKey; + + private String secretKey; + + private String domain; + + private String bucketName; + + private String productImagePath; + private String courseImagePath; + + private String filePath; + + private String videoPath; + + private Integer expireIn; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/thirdparty/MinioService.java b/ruoyi-system/src/main/java/com/ruoyi/system/thirdparty/MinioService.java new file mode 100644 index 0000000..69bf5ba --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/thirdparty/MinioService.java @@ -0,0 +1,167 @@ +package com.ruoyi.system.thirdparty; + +import com.ruoyi.common.utils.DateUtils; +import io.minio.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Date; + +@Slf4j +@Component +@RequiredArgsConstructor +public class MinioService { + + + private final MinioClient minioClient; + + /** + * 查看存储bucket是否存在 + * + * @return boolean + */ + public Boolean bucketExists(String bucketName) { + try { + return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + } catch (Exception e) { + log.error("查询bucket失败", e); + return false; + } + } + + /** + * 创建存储bucket + */ + public void makeBucket(String bucketName) { + try { + minioClient.makeBucket(MakeBucketArgs.builder() + .bucket(bucketName) + .build()); + } catch (Exception e) { + log.error("创建bucket失败,", e); + } + } + + /** + * 设置bucket权限为public + */ + public void setBucketPublic(String bucketName) { + try { + // 设置公开 + String sb = "{\"Version\":\"2012-10-17\"," + + "\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":" + + "{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"," + + "\"s3:GetBucketLocation\"],\"Resource\":[\"arn:aws:s3:::" + bucketName + + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\"],\"Resource\":[\"arn:aws:s3:::" + + bucketName + + "/*\"]}]}"; + minioClient.setBucketPolicy( + SetBucketPolicyArgs.builder() + .bucket(bucketName) + .config(sb) + .build()); + } catch (Exception e) { + log.error("创建bucket失败,", e); + } + } + + /** + * 文件上传 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param file 文件 + * @return Boolean + */ + public String upload(String bucketName, String path, MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + if (StringUtils.isBlank(originalFilename)) { + throw new RuntimeException(); + } + String fileName = System.currentTimeMillis() + ""; + if (originalFilename.lastIndexOf(".") >= 0) { + fileName += originalFilename.substring(originalFilename.lastIndexOf(".")); + } + String objectName = DateUtils.parseDateToStr("yyyyMMdd", new Date()) + "/" + fileName; + try { + InputStream stream = new ByteArrayInputStream(file.getBytes()); + PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(path + "/" + objectName) + .stream(stream, file.getSize(), -1).contentType(file.getContentType()).build(); + //文件名称相同会覆盖 + minioClient.putObject(objectArgs); + } catch (Exception e) { + log.error("上传图片失败,", e); + return null; + } + return objectName; + } + + /** + * 文件上传 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param name 文件名 + * @param fileByte 文件内容 + * @param contentType contentType + * @return objectName + */ + public String upload(String bucketName, String path, String name, byte[] fileByte, String contentType) { + + String fileName = System.currentTimeMillis() + name.substring(name.lastIndexOf(".")); + String objectName = DateUtils.parseDateToStr("yyyyMMdd", new Date()) + "/" + fileName; + try { + InputStream stream = new ByteArrayInputStream(fileByte); + PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(path + "/" + objectName) + .stream(stream, fileByte.length, -1).contentType(contentType).build(); + //文件名称相同会覆盖 + minioClient.putObject(objectArgs); + } catch (Exception e) { + log.error("上传文件失败,", e); + return null; + } + return objectName; + } + + + /** + * 删除 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param fileName 文件名 + * @return true/false + */ + public boolean remove(String bucketName, String path, String fileName) { + try { + minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(path + "/" + fileName).build()); + } catch (Exception e) { + log.error("删除文件失败,", e); + return false; + } + return true; + } + + /** + * 判断文件是否存在 + * + * @param bucketName bucket名称 + * @param path 路径 + * @param fileName 文件名 + * @return + */ + public Boolean isExist(String bucketName, String path, String fileName) { + try { + minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(path + "/" + fileName).build()); + } catch (Exception e) { + return false; + } + return true; + } + +}