diff --git a/Cpop-Core/src/main/java/com/cpop/core/handler/TencentCosHandler.java b/Cpop-Core/src/main/java/com/cpop/core/handler/TencentCosHandler.java index 63c65be..48ff246 100644 --- a/Cpop-Core/src/main/java/com/cpop/core/handler/TencentCosHandler.java +++ b/Cpop-Core/src/main/java/com/cpop/core/handler/TencentCosHandler.java @@ -2,7 +2,7 @@ package com.cpop.core.handler; import com.cpop.core.base.exception.UtilException; import com.cpop.core.config.TencentCosProperties; -import com.qcloud.cos.COS; +import com.cpop.core.utils.uuid.IdUtils; import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.auth.BasicCOSCredentials; @@ -131,10 +131,10 @@ public class TencentCosHandler { objectMetadata.setContentLength(file.getSize()); objectMetadata.setContentType(file.getContentType()); InputStream inputStream = file.getInputStream(); - PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), properties.getSecretKey(),inputStream , objectMetadata); + PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), IdUtils.fastSimpleUUID(), inputStream, objectMetadata); // 设置存储类型(如有需要,不需要请忽略此行代码), 默认是标准(Standard), 低频(standard_ia) // 更多存储类型请参见 https://cloud.tencent.com/document/product/436/33417 - putObjectRequest.setStorageClass(StorageClass.Standard_IA); + putObjectRequest.setStorageClass(StorageClass.Standard); Upload upload = transferManager.upload(putObjectRequest); UploadResult uploadResult = upload.waitForUploadResult(); inputStream.close(); diff --git a/Cpop-Core/src/main/java/com/cpop/core/utils/SecurityUtils.java b/Cpop-Core/src/main/java/com/cpop/core/utils/SecurityUtils.java index f8ca5ce..3b3ebf4 100644 --- a/Cpop-Core/src/main/java/com/cpop/core/utils/SecurityUtils.java +++ b/Cpop-Core/src/main/java/com/cpop/core/utils/SecurityUtils.java @@ -39,6 +39,9 @@ public class SecurityUtils { **/ public LoginUser getLoginUser() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null){ + return null; + } //匿名用户 if (authentication.getPrincipal() == "anonymousUser") { return null; diff --git a/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application-dev.yml b/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application-dev.yml index 9058f48..eb72a9a 100644 --- a/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application-dev.yml +++ b/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application-dev.yml @@ -4,7 +4,7 @@ cpop: profile: E:/Cpop/uploadPath jwt: #白名单 - whiteList: /login,/miniLogin,/wxPay/callback/notify/**,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources + whiteList: /login,/miniLogin,/wxPay/callback/notify/**,/mini/brand/jamboxBrandIsInMall/*,/profile/**,/doc.html,/webjars/**,/favicon.ico,/v2/api-docs/**,/swagger-resources gateway: rsa-keypair: # 公钥文件 diff --git a/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application.yml b/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application.yml index b2aa4c8..6e00e49 100644 --- a/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application.yml +++ b/Cpop-Mall/Cpop-Mall-Web/src/main/resources/application.yml @@ -137,3 +137,5 @@ wx: #微信支付商户密钥 mchKey: JamBox20230919174000000000000002 apiV3Key: JamBox20230919174000000000000002 + #服务商账号 + sharingAccount: 1618436087 diff --git a/Cpop-Mall/Cpop-Mall-Web/src/main/resources/logback.xml b/Cpop-Mall/Cpop-Mall-Web/src/main/resources/logback.xml index 63c0cbf..bb740c3 100644 --- a/Cpop-Mall/Cpop-Mall-Web/src/main/resources/logback.xml +++ b/Cpop-Mall/Cpop-Mall-Web/src/main/resources/logback.xml @@ -58,9 +58,7 @@ - - - + diff --git a/Cpop-Mall/Cpop-Mall-Web/src/test/java/com/cpop/mall/web/CpopWxPayTests.java b/Cpop-Mall/Cpop-Mall-Web/src/test/java/com/cpop/mall/web/CpopWxPayTests.java new file mode 100644 index 0000000..1884f5b --- /dev/null +++ b/Cpop-Mall/Cpop-Mall-Web/src/test/java/com/cpop/mall/web/CpopWxPayTests.java @@ -0,0 +1,60 @@ +package com.cpop.mall.web; + +import com.cpop.core.utils.SpringUtils; +import com.cpop.core.utils.uuid.IdUtils; +import com.cpop.mall.business.entity.Order; +import com.cpop.mall.business.service.OrderService; +import com.cpop.mall.framework.config.wxPay.WxPayProperties; +import com.cpop.system.business.entity.Brand; +import com.cpop.system.business.service.BrandService; +import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request; +import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * @author DB + * @createTime 2023/11/01 18:15 + * @description 微信支付 + */ +@SpringBootTest +public class CpopWxPayTests { + + @Autowired + private WxPayService wxPayService; + + @Autowired + private WxPayProperties wxPayProperties; + + /** + * @descriptions 微信支付退款 + * @author DB + * @date 2023/11/01 18:20 + * @return: void + */ + @Test + public void refund() throws WxPayException { + Brand brand = SpringUtils.getBean(BrandService.class).getById("75140168047210496"); + Order order = SpringUtils.getBean(OrderService.class).getById("77257142464598016"); + WxPayRefundV3Request request = new WxPayRefundV3Request(); + WxPayRefundV3Request.Amount amount = new WxPayRefundV3Request.Amount(); + //退款金额(单位分) + int refund = order.getTotalAmount().scaleByPowerOfTen(2).intValue(); + amount.setRefund(refund) + .setTotal(refund) + .setCurrency("CNY"); + request.setTransactionId(order.getOutOrderNo()) + .setSubMchid(wxPayService.getConfig().getSubMchId()) + .setNotifyUrl(wxPayProperties.getNotifyRefund()) + .setOutRefundNo(IdUtils.fastSimpleUUID()) + .setOutTradeNo(order.getId()) + .setSubMchid(brand.getWxMchId()) + .setReason("接口测试退款") + .setAmount(amount); + WxPayRefundV3Result result = wxPayService.refundV3(request); + System.out.println(result); + } +} diff --git a/Cpop-Mall/Cpop-Mall-Web/src/test/java/com/cpop/mall/web/OrderTests.java b/Cpop-Mall/Cpop-Mall-Web/src/test/java/com/cpop/mall/web/OrderTests.java deleted file mode 100644 index a2bef6a..0000000 --- a/Cpop-Mall/Cpop-Mall-Web/src/test/java/com/cpop/mall/web/OrderTests.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.cpop.mall.web; - -import com.cpop.mall.business.service.ProductRecordService; -import org.checkerframework.checker.units.qual.A; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * @author DB - * @createTime 2023/11/01 12:25 - * @description 订单测试 - */ -@SpringBootTest -public class OrderTests { - - @Autowired - private ProductRecordService productRecordService; - - /** - * @descriptions 并发更新库存 - * @author DB - * @date 2023/11/01 12:26 - * @return: void - */ - @Test - public void concurrencyUpdateStock(){ - ExecutorService threadPool = Executors.newFixedThreadPool(10); - for (int i = 0; i < 100; i++) { - threadPool.submit(new Runnable() { - @Override - public void run() { - System.out.println(Thread.currentThread().getName() + "正在执行任务"); - } - }); - } - } -} diff --git a/Cpop-Mall/src/main/java/com/cpop/mall/business/bo/ProductBo.java b/Cpop-Mall/src/main/java/com/cpop/mall/business/bo/ProductBo.java index 98b00be..dcb9c90 100644 --- a/Cpop-Mall/src/main/java/com/cpop/mall/business/bo/ProductBo.java +++ b/Cpop-Mall/src/main/java/com/cpop/mall/business/bo/ProductBo.java @@ -93,7 +93,7 @@ public class ProductBo implements Serializable { * 限制数量 */ @ApiModelProperty("限制数量") - private Long limitNum; + private Integer limitNum; /** * 规格集合 diff --git a/Cpop-Mall/src/main/java/com/cpop/mall/business/controller/mini/MiniBrandController.java b/Cpop-Mall/src/main/java/com/cpop/mall/business/controller/mini/MiniBrandController.java new file mode 100644 index 0000000..836c874 --- /dev/null +++ b/Cpop-Mall/src/main/java/com/cpop/mall/business/controller/mini/MiniBrandController.java @@ -0,0 +1,44 @@ +package com.cpop.mall.business.controller.mini; + +import com.cpop.core.base.R; +import com.cpop.jambox.business.service.BrandExtendService; +import com.cpop.mall.business.vo.OrderPageVo; +import com.cpop.system.business.service.BrandService; +import com.mybatisflex.core.paginate.Page; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static com.cpop.jambox.business.entity.table.BrandExtendTableDef.BRAND_EXTEND; + +/** + * @author DB + * @createTime 2023/11/01 16:36 + * @description + */ +@RestController +@Api(tags = "小程序商城-品牌相关接口") +@RequestMapping("/mini/brand") +public class MiniBrandController { + + @Autowired + private BrandExtendService brandExtendService; + + /** + * @descriptions 分页查询商城-商品 + * @author DB + * @date 2023/10/23 11:56 + * @param cloudBrandId 云品牌id + * @return: com.cpop.core.base.R> + */ + @GetMapping("/jamboxBrandIsInMall/{cloudBrandId}") + @ApiOperation("小程序-果酱品牌是否在商城内") + public R jamboxBrandIsInMall(@PathVariable String cloudBrandId) { + long count = brandExtendService.queryChain().where(BRAND_EXTEND.BRAND_CLOUD_ID.eq(cloudBrandId)).count(); + return R.ok(count > 0); + } +} diff --git a/Cpop-Mall/src/main/java/com/cpop/mall/business/service/impl/OrderRefundServiceImpl.java b/Cpop-Mall/src/main/java/com/cpop/mall/business/service/impl/OrderRefundServiceImpl.java index 973dfde..341580b 100644 --- a/Cpop-Mall/src/main/java/com/cpop/mall/business/service/impl/OrderRefundServiceImpl.java +++ b/Cpop-Mall/src/main/java/com/cpop/mall/business/service/impl/OrderRefundServiceImpl.java @@ -13,6 +13,7 @@ import com.cpop.mall.business.mapper.OrderRefundMapper; import com.cpop.mall.business.service.OrderRefundService; import com.cpop.mall.business.service.OrderService; import com.cpop.mall.business.vo.OrderRefundPageVo; +import com.cpop.mall.framework.config.wxPay.WxPayProperties; import com.cpop.mall.framework.handler.WxPayHandler; import com.cpop.system.business.entity.ProfitSharing; import com.cpop.system.business.service.ProfitSharingService; @@ -46,8 +47,8 @@ public class OrderRefundServiceImpl extends ServiceImpl implements @Autowired private WxPayHandler wxPayHandler; + @Autowired + private WxPayProperties wxPayProperties; + /** * @descriptions 分页查询商城-订单 * @author DB @@ -315,9 +323,10 @@ public class OrderServiceImpl extends ServiceImpl implements productRecords.forEach(item -> { item.setRecordNum(item.getRecordNum() - orderNumMap.get(item.getId())); }); - productRecordService.updateBatch(productRecords); + //异步更新 + asyncUpdateRecords(productRecords, orderNumMap); //TODO:分账先注释 - /*ProfitSharing profitSharing = new ProfitSharing(); + ProfitSharing profitSharing = new ProfitSharing(); profitSharing.setOrderId(orderId) .setProfitSharingStatus(0) .setOrderSource(OrderSource.MALL.toString()); @@ -325,21 +334,25 @@ public class OrderServiceImpl extends ServiceImpl implements profitSharingService.save(profitSharing); ProfitSharingRequest sharingRequest = new ProfitSharingRequest(); ProfitSharingReceiver profitSharingReceiver = new ProfitSharingReceiver(); + List profitSharingReceivers = new ArrayList<>(); Double ceil = Math.ceil(notifyResult.getTotalFee() * OrderSource.MALL.getRate()); profitSharingReceiver.setAmount(ceil.longValue()); profitSharingReceiver.setDescription("向服务商分账"); profitSharingReceiver.setType("MERCHANT_ID"); profitSharingReceiver.setRelationType("SERVICE_PROVIDER"); - profitSharingReceiver.setAccount("1618436087"); + profitSharingReceiver.setAccount(wxPayProperties.getSharingAccount()); + profitSharingReceivers.add(profitSharingReceiver); sharingRequest.setTransactionId(notifyResult.getTransactionId()); sharingRequest.setOutOrderNo(profitSharing.getOrderId()); //分账结束 sharingRequest.setUnfreezeUnsplit(true); + sharingRequest.setAppid(wxPayProperties.getAppId()); + sharingRequest.setReceivers(profitSharingReceivers); ProfitSharingResult profitSharingResult = wxPayService.getProfitSharingV3Service().profitSharing(sharingRequest); //更新分账订单 profitSharingService.updateChain().set(PROFIT_SHARING.OUT_PROFIT_SHARING_ID,profitSharingResult.getOrderId()) - .set(PROFIT_SHARING.AMOUNT,ceil.longValue()).set(PROFIT_SHARING.PROFIT_SHARING_STATUS,1).set(PROFIT_SHARING.PAY_ACCOUNT,"1618436087") - .where(PROFIT_SHARING.ID.eq(profitSharing.getId())).update();*/ + .set(PROFIT_SHARING.AMOUNT, ceil.longValue()).set(PROFIT_SHARING.PROFIT_SHARING_STATUS, 1).set(PROFIT_SHARING.PAY_ACCOUNT, wxPayProperties.getSharingAccount()) + .where(PROFIT_SHARING.ID.eq(profitSharing.getId())).update(); } catch (WxPayException e) { throw new ServiceException(e.getMessage()); } @@ -348,24 +361,40 @@ public class OrderServiceImpl extends ServiceImpl implements /** * @Description: 异步更新数据库 * @param productRecords 产品记录 - * @param flag 成功标志 * @Author DB * @Date: 2023/11/1 0:09 */ @Async("customAsyncThreadPool") - public void asyncUpdateRecords(List productRecords, Integer flag) { + public void asyncUpdateRecords(List productRecords,Map orderNumMap) { + loopUpdateStock(productRecords, orderNumMap); + } + + /** + * @descriptions 循环插入库存修改记录 + * @author DB + * @date 2023/11/01 17:01 + * @param productRecords 库存修改记录 + * @return: void + */ + private void loopUpdateStock(List productRecords,Map orderNumMap) { ProductRecordService productRecordService = SpringUtils.getBean(ProductRecordService.class); - if (flag > 5) { - //TODO:通知到系统库存减扣失败,需要人为操作 - throw new ServiceException("更新订单失败"); - } else { - boolean tx = Db.tx(() -> productRecordService.updateBatch(productRecords)); - if (!tx) { - //更新失败 - flag++; - asyncUpdateRecords(productRecords, flag); + //用迭代器 + Iterator iterator = productRecords.iterator(); + while (iterator.hasNext()) { + ProductRecord next = iterator.next(); + next.setRecordNum(next.getRecordNum() - orderNumMap.get(next.getId())); + boolean update = productRecordService.updateById(next); + //如果更新成功,移除 + if (update) { + iterator.remove(); } } + //存在更新失败,需要重新更新,直到全部成功 + if (!productRecords.isEmpty()){ + //获取最新数据进行下一次循环 + loopUpdateStock(productRecordService.listByIds(productRecords.stream().map(ProductRecord::getId).collect(Collectors.toSet())), + orderNumMap); + } } /** diff --git a/Cpop-Mall/src/main/java/com/cpop/mall/business/vo/ProductPageVo.java b/Cpop-Mall/src/main/java/com/cpop/mall/business/vo/ProductPageVo.java index 66e3e42..aae5b09 100644 --- a/Cpop-Mall/src/main/java/com/cpop/mall/business/vo/ProductPageVo.java +++ b/Cpop-Mall/src/main/java/com/cpop/mall/business/vo/ProductPageVo.java @@ -72,6 +72,12 @@ public class ProductPageVo implements Serializable { @ApiModelProperty("上下架") private Boolean isUp; + /** + * 是否置顶 + */ + @ApiModelProperty("是否置顶") + private Boolean isTop; + /** * 商品图地址 */ @@ -102,6 +108,12 @@ public class ProductPageVo implements Serializable { @ApiModelProperty("最低价") private BigDecimal minPrice; + /** + * 限购数量 + */ + @ApiModelProperty("限购数量") + private Integer limitNum; + /** * 支付方式(微信支付:0;积分支付:1) */ diff --git a/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayConfiguration.java b/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayConfiguration.java index 16a6fbe..52e4e90 100644 --- a/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayConfiguration.java +++ b/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayConfiguration.java @@ -45,4 +45,14 @@ public class WxPayConfiguration { return wxPayService; } + + /** + * @descriptions 读取微信支付配置文件 + * @author DB + * @date 2023/11/01 17:27 + * @return: com.cpop.mall.framework.config.wxPay.WxPayProperties + */ + public WxPayProperties getProperties() { + return properties; + } } diff --git a/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayProperties.java b/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayProperties.java index c912771..c997062 100644 --- a/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayProperties.java +++ b/Cpop-Mall/src/main/java/com/cpop/mall/framework/config/wxPay/WxPayProperties.java @@ -70,4 +70,9 @@ public class WxPayProperties { * 退款通知 */ private String notifyRefund; + + /** + * 分账账号 + */ + private String sharingAccount; }