package com.jilongda.manage.controller; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.model.MatchMode; import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.PolicyConditions; import com.aliyun.oss.model.PutObjectResult; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.jilongda.common.basic.ApiResult; import com.jilongda.common.basic.PageInfo; import com.jilongda.common.utils.UUIDUtil; import com.jilongda.manage.component.AliOssMange; import com.jilongda.manage.dto.TModelDTO; import com.jilongda.manage.model.TAppUser; import com.jilongda.manage.model.TCoupon; import com.jilongda.manage.model.TCouponReceive; import com.jilongda.manage.model.TModel; import com.jilongda.manage.query.TAppUserQuery; import com.jilongda.manage.query.TCouponQuery; import com.jilongda.manage.service.TAppUserService; import com.jilongda.manage.service.TCouponReceiveService; import com.jilongda.manage.service.TCouponService; import com.jilongda.manage.utils.OssUploadUtil; import com.jilongda.manage.utils.QRCodeUtil; import com.jilongda.manage.vo.TAppUserVO; import com.jilongda.manage.vo.TCouponInfoVO; import com.jilongda.manage.vo.TCouponVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream; import org.springframework.beans.BeanUtils; import org.springframework.core.io.ByteArrayResource; import org.springframework.mock.web.MockMultipartFile; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; /** *

* 优惠券领取记录 前端控制器 *

* * @author 无关风月 * @since 2024-12-09 */ @RestController @Api(tags = "优惠券管理") @RequestMapping("/t-coupon") public class TCouponController { @Resource private TCouponService couponService; @Resource private TCouponReceiveService couponReceiveService; @Resource private TAppUserService appUserService; @ApiOperation(value = "优惠券列表") @PostMapping(value = "/pageList") public ApiResult> pageList(@RequestBody TCouponQuery query) { PageInfo appUserVOPageInfo = couponService.pageList(query); return ApiResult.success(appUserVOPageInfo); } @ApiOperation(value = "添加优惠券") @PostMapping(value = "/add") public ApiResult add( @RequestBody TCoupon dto) throws Exception { if (dto.getTime()!=null && dto.getTime()>365){ return ApiResult.failed("优惠券有效期不能大于365天"); } if (dto.getType()==1||dto.getType()==4)dto.setGrantStatus(1); couponService.save(dto); switch (dto.getType()){ case 2: // 全局发放 List collect = appUserService.lambdaQuery().list().stream() .map(TAppUser::getId).collect(Collectors.toList()); List tCouponReceives = new ArrayList<>(); for (Integer i : collect) { TCouponReceive tCouponReceive = new TCouponReceive(); tCouponReceive.setCouponId(dto.getId()); tCouponReceive.setUserId(i); tCouponReceive.setType(2); tCouponReceive.setAmount(dto.getAmount()); tCouponReceive.setStoreId(dto.getStoreId()); if (dto.getTime()!=0){ tCouponReceive.setEndTime(LocalDateTime.now().plusDays(dto.getTime())); } tCouponReceive.setAmountCondition(dto.getAmountCondition()); tCouponReceive.setStatus(1); tCouponReceive.setCouponName(dto.getName()); tCouponReceives.add(tCouponReceive); } couponReceiveService.saveBatch(tCouponReceives); break; case 3: List tCouponReceives1 = new ArrayList<>(); for (Integer userId : dto.getUserIds()) { TCouponReceive tCouponReceive = new TCouponReceive(); tCouponReceive.setCouponId(dto.getId()); tCouponReceive.setUserId(userId); tCouponReceive.setType(3); tCouponReceive.setAmount(dto.getAmount()); tCouponReceive.setStoreId(dto.getStoreId()); if (dto.getTime()!=0){ tCouponReceive.setEndTime(LocalDateTime.now().plusDays(dto.getTime())); } tCouponReceive.setAmountCondition(dto.getAmountCondition()); tCouponReceive.setStatus(1); tCouponReceive.setCouponName(dto.getName()); tCouponReceives1.add(tCouponReceive); } couponReceiveService.saveBatch(tCouponReceives1); break; case 4: String code = "{\"id\": "+dto.getId()+ "}"; BufferedImage blueImage = QRCodeUtil.createImage(code); MultipartFile blueFile = convert(blueImage, new Date().getTime() + UUIDUtil.getRandomCode(3) + ".PNG"); String s = OssUploadUtil.ossUpload("eyes/", blueFile); dto.setQrCode(s); couponService.updateById(dto); return ApiResult.success(s); } return ApiResult.success(); } @ApiOperation(value = "暂停发放 只有type为1和4的时候") @PostMapping(value = "/stop") public ApiResult stop(Integer id) throws Exception { TCoupon byId = couponService.getById(id); byId.setGrantStatus(2); couponService.updateById(byId); return ApiResult.success(); } @ApiOperation(value = "修改优惠券") @PostMapping(value = "/update") public ApiResult update( @RequestBody TCoupon dto) throws Exception { couponService.updateById(dto); return ApiResult.success(); } @ApiOperation(value = "优惠券详情") @PostMapping(value = "/getDetail") public ApiResult getDetail(Integer id) { TCouponInfoVO tCouponInfoVO = new TCouponInfoVO(); TCoupon byId = couponService.getById(id); BeanUtils.copyProperties(byId, tCouponInfoVO); int size = couponReceiveService.list(new LambdaQueryWrapper() .eq(TCouponReceive::getCouponId, id)).size(); tCouponInfoVO.setGrantCout(size); List list = couponReceiveService.list(new LambdaQueryWrapper() .eq(TCouponReceive::getCouponId, id) .eq(TCouponReceive::getStatus, 2)); list.stream().map(TCouponReceive::getAmount).reduce(BigDecimal::add).ifPresent(tCouponInfoVO::setUseMoney); tCouponInfoVO.setUseCount(list.size()); if (byId.getType()==3){ // 查询领取人 List collect = couponReceiveService.lambdaQuery() .eq(TCouponReceive::getCouponId, id).list() .stream().map(TCouponReceive::getUserId) .distinct() .collect(Collectors.toList()); tCouponInfoVO.setUserIds(collect); } return ApiResult.success(tCouponInfoVO); } public static MultipartFile convert(BufferedImage bufferedImage, String fileName) throws IOException { // 将 BufferedImage 转换为字节数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "png", baos); byte[] bytes = baos.toByteArray(); // 创建 ByteArrayResource ByteArrayResource resource = new ByteArrayResource(bytes); // 创建 MockMultipartFile MockMultipartFile multipartFile = new MockMultipartFile( "file", fileName, "image/png", resource.getInputStream() ); return multipartFile; } @ApiOperation(value = "服务端上传", notes = "服务端上传") @PostMapping(value = "upload") public ApiResult fileUpload(@RequestParam(value = "file") MultipartFile file) throws IOException { InputStream inputStream = file.getInputStream(); String filename = System.currentTimeMillis() + file.getOriginalFilename(); // Endpoint以杭州为例,其它Region请按实际情况填写。 final String endpoint = AliOssMange.endpoint; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。 final String accessKeyId = AliOssMange.accessKeyId; final String accessKeySecret = AliOssMange.accessKeySecret; final String bucketName = AliOssMange.bucketName; // 上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = AliOssMange.dir + filename; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。 // InputStream inputStream = new FileInputStream("D:\\localpath\\examplefile.txt"); // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。 PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream); OSSObject ossObject = ossClient.getObject(bucketName, objectName); String uri = ossObject.getResponse().getUri(); // 关闭OSSClient。 ossClient.shutdown(); // uri = uri.replace("http://nn-bucket.oss-cn-shanghai.aliyuncs.com",FILE_CDN); return ApiResult.okmsg(uri); } @ApiOperation(value = "服务端签名后直传", notes = "服务端签名后直传") @PostMapping("signature") public ApiResult> signature() { OSS builder = new OSSClientBuilder().build(AliOssMange.endpoint, AliOssMange.accessKeyId, AliOssMange.accessKeySecret); long expireTime = 30; long expireEndTime = System.currentTimeMillis() + expireTime * 1000; Date expiration = new Date(expireEndTime); PolicyConditions policyConds = new PolicyConditions(); policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, AliOssMange.dir); String postPolicy = builder.generatePostPolicy(expiration, policyConds); byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8); String encodedPolicy = BinaryUtil.toBase64String(binaryData); String postSignature = builder.calculatePostSignature(postPolicy); Map respMap = new LinkedHashMap<>(6); respMap.put("accessid", AliOssMange.accessKeyId); respMap.put("policy", encodedPolicy); respMap.put("signature", postSignature); // 示例为dir respMap.put("dir", AliOssMange.dir); // 前端为key // respMap.put("key", AliOssMange.dir); respMap.put("host", AliOssMange.host); // respMap.put("cdn", AliOssMange.cdn); respMap.put("expire", String.valueOf(expireEndTime / 1000)); // // 回调 // if (StringUtils.hasLength(AliOssMange.callbackUrl)) { // JSONObject jasonCallback = new JSONObject(); // jasonCallback.put("callbackUrl", AliOssMange.callbackUrl); // String callbackBody = "{\"filename\":${object},\"size\":${size},\"mimeType\":${mimeType}}"; // jasonCallback.put("callbackBody", callbackBody); // jasonCallback.put("callbackBodyType", "application/json"); // String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes()); // respMap.put("callback", base64CallbackBody); // } // HttpServletResponse response = WebUtils.response(); // assert response != null; // response.setHeader("Access-Control-Allow-Origin", "*"); // response.setHeader("Access-Control-Allow-Methods", "GET, POST"); // 关闭OSSClient。 builder.shutdown(); return ApiResult.success(respMap); } @ApiOperation(value = "服务端上传(二进制字符串)", notes = "服务端上传") @PostMapping(value = "str/upload") public String strUpload(InputStream inputStream, String filename) throws IOException { //String filename = System.currentTimeMillis() + CodeGenerateUtils.generateVolumeSn()+".jpg"; // Endpoint以杭州为例,其它Region请按实际情况填写。 final String endpoint = AliOssMange.endpoint; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。 final String accessKeyId = AliOssMange.accessKeyId; final String accessKeySecret = AliOssMange.accessKeySecret; final String bucketName = AliOssMange.bucketName; // 上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。 String objectName = AliOssMange.dir + filename; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。 // InputStream inputStream = new FileInputStream("D:\\localpath\\examplefile.txt"); // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。 PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream); OSSObject ossObject = ossClient.getObject(bucketName, objectName); String uri = ossObject.getResponse().getUri(); // 关闭OSSClient。 ossClient.shutdown(); return uri; } /** * oss上传成功回调 * * @param callback * @return */ @ApiOperation(value = "oss回调", notes = "oss回调") @PostMapping(value = "/callback") public ApiResult callback(@RequestBody Map callback) { String filename = "http://".concat(AliOssMange.bucketName).concat(".").concat(AliOssMange.endpoint).concat("/").concat(callback.get("filename").toString()); return ApiResult.okmsg(filename); } }