Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
17614d4265
13
README.md
13
README.md
@ -30,19 +30,26 @@
|
||||
|
||||
# 演示
|
||||
|
||||
> 艿艿:目前的开发者,都是后端出身。所以,一帮没有审美自觉的人,撸出来的前端界面,可能是东半球倒数第二难看。
|
||||
>
|
||||
> 迫切希望,有前端能力不错的小伙伴,加入我们,一起来完善「一个商城」。
|
||||
>
|
||||
> 啊啊啊!我好像做店铺装修功能。
|
||||
|
||||
## H5 商城
|
||||
|
||||
[体验传送门](http://h5.shop.iocoder.cn:18099)
|
||||
|
||||
TODO 此处应有一个演示的装逼 GIF 图。
|
||||
![GIF 图-耐心等待](https://raw.githubusercontent.com/YunaiV/Blog/master/Mall/onemall-h5-min.gif)
|
||||
|
||||
## 管理后台
|
||||
|
||||
[体验传送门](http://admin.shop.iocoder.cn:18099)
|
||||
|
||||
TODO 暂时不提供管理后台的账号密码,等后面提供。
|
||||
* 账号:yudaoyuanma
|
||||
* 密码:yudaoyuanma
|
||||
|
||||
TODO 此处应有一个演示的装逼 GIF 图。
|
||||
![GIF 图-耐心等待](https://raw.githubusercontent.com/YunaiV/Blog/master/Mall/onemall-admin-min.gif)
|
||||
|
||||
## 其它演示
|
||||
|
||||
|
@ -35,4 +35,8 @@ public class StringUtil {
|
||||
return org.apache.commons.lang3.StringUtils.substring(str, start);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(StringUtil.split("cn.iocoder.mall.order.api.OrderService#updatePaySuccess#1.0.0", "#").size());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
package cn.iocoder.mall.spring.boot;
|
@ -2,6 +2,7 @@ package cn.iocoder.mall.spring.boot.web;
|
||||
|
||||
import cn.iocoder.common.framework.constant.MallConstants;
|
||||
import cn.iocoder.common.framework.servlet.CorsFilter;
|
||||
import cn.iocoder.mall.admin.sdk.interceptor.AdminDemoInterceptor;
|
||||
import cn.iocoder.mall.spring.boot.web.interceptor.AccessLogInterceptor;
|
||||
import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor;
|
||||
import cn.iocoder.mall.spring.boot.web.handler.GlobalExceptionHandler;
|
||||
@ -34,6 +35,12 @@ public class AdminMVCAutoConfiguration implements WebMvcConfigurer {
|
||||
return new AdminSecurityInterceptor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(AdminDemoInterceptor.class)
|
||||
public AdminDemoInterceptor adminDemoInterceptor() {
|
||||
return new AdminDemoInterceptor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(GlobalResponseBodyHandler.class)
|
||||
public GlobalResponseBodyHandler globalReturnValueHandler() {
|
||||
@ -50,6 +57,7 @@ public class AdminMVCAutoConfiguration implements WebMvcConfigurer {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(adminAccessLogInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_ADMIN + "/**");
|
||||
registry.addInterceptor(adminSecurityInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_ADMIN + "/**");
|
||||
registry.addInterceptor(adminDemoInterceptor()).addPathPatterns(MallConstants.ROOT_PATH_ADMIN + "/**");
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -29,4 +29,6 @@
|
||||
- 用户相关
|
||||
- [x] 登陆
|
||||
- [x] 注册
|
||||
- [ ] 个人信息
|
||||
- [x] 个人信息
|
||||
- [ ] 手机改绑
|
||||
- [ ] 微信登陆
|
||||
|
@ -10,31 +10,48 @@
|
||||
- [ ] 支付单 20% 【待认领】
|
||||
- [ ] 退款单 20% 【待认领】
|
||||
- TODO 需要补充
|
||||
- [ ] 店铺装修【迫切需要靠谱前端一起做】
|
||||
- [ ] H5 装修
|
||||
- [ ] 小程序装修
|
||||
- [ ] 自定义页面
|
||||
- [ ] 商品管理
|
||||
- [x] 发布商品
|
||||
- [x] 商品列表
|
||||
- [x] 展示类目
|
||||
- [ ] 品牌管理【待认领】
|
||||
- [ ] 品牌管理【开发中 @黑子】
|
||||
- [ ] 商品标签
|
||||
- [ ] 订单管理
|
||||
- [ ] 销售单 开发中
|
||||
- [ ] 售后单 开发中
|
||||
- [ ] 订单评价【开发中】
|
||||
- [x] 销售单
|
||||
- [x] 售后单
|
||||
- [ ] 订单评价【开发中 @wang171776704】
|
||||
- [ ] 会员管理
|
||||
- [ ] 会员资料 20%【待认领】
|
||||
- [ ] 会员等级
|
||||
- [ ] 会员积分
|
||||
- [ ] 用户标签
|
||||
- TODO 需要补充
|
||||
- [ ] 营销管理
|
||||
- [x] 首页广告
|
||||
- [x] 商品推荐
|
||||
- [x] 优惠劵
|
||||
- [ ] 优惠码【待认领】
|
||||
- [ ] 优惠码【开发中 @native8623 2019-05-17】
|
||||
- [ ] 满减送 20% 【待认领】
|
||||
- [ ] 限制折扣 20% 【待认领】
|
||||
- [ ] 多人拼团【待认领】
|
||||
- [ ] 积分商城
|
||||
- [ ] 问卷调查
|
||||
- [ ] 幸运大转盘
|
||||
- [ ] 分销管理
|
||||
- [ ] 分销设置
|
||||
- [ ] 分销员管理
|
||||
- [ ] 提现管理
|
||||
- [ ] 系统管理
|
||||
- [x] 员工管理
|
||||
- [x] 角色管理 <!--【前端页面需要细化下】-->
|
||||
- [ ] 权限管理
|
||||
- [ ] 短信管理
|
||||
- [x] 权限管理 <!--【前端页面需要细化下】-->
|
||||
- [ ] 部门管理【待认领】
|
||||
- [x] 数据字典
|
||||
- [ ] 短信管理【开发中 @小范】
|
||||
- [ ] 短信模板
|
||||
- [ ] 发送日志
|
||||
- [ ] 员工操作日志
|
||||
|
@ -229,11 +229,11 @@ service.interceptors.response.use(
|
||||
|
||||
// TODO token 过期
|
||||
// TODO 需要拿 refresh token 置换
|
||||
if (code === 1001001011 // 访问令牌不存在
|
||||
|| code === 1001001013 // 访问令牌已失效
|
||||
|| code === 1001001021 // 刷新令牌不存在
|
||||
|| code === 1001001022 // 刷新令牌已过期
|
||||
|| code === 1001001023) { // 刷新令牌已失效
|
||||
if (code === 1002001011 // 访问令牌不存在
|
||||
|| code === 1002001013 // 访问令牌已失效
|
||||
|| code === 1002001017 // 刷新令牌不存在
|
||||
|| code === 1002001018 // 刷新令牌已过期
|
||||
|| code === 1002001019) { // 刷新令牌已失效
|
||||
Dialog.confirm({
|
||||
title: '系统提示',
|
||||
message: res.message,
|
||||
@ -249,7 +249,7 @@ service.interceptors.response.use(
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (code === 1001001012) { // 访问令牌已过期
|
||||
} else if (code === 1002001012) { // 访问令牌已过期
|
||||
return refreshToken(response);
|
||||
} else {
|
||||
Dialog.alert({
|
||||
|
@ -69,7 +69,7 @@ export default {
|
||||
let that = this;
|
||||
let response = doPassportMobileRegister(this.mobile, this.code);
|
||||
response.then(data => {
|
||||
setLoginToken(data.accessToken, data.refreshToken);
|
||||
setLoginToken(data.token.accessToken, data.token.refreshToken);
|
||||
Dialog.alert({
|
||||
title: '系统提示',
|
||||
message: '登陆成功',
|
||||
|
@ -50,21 +50,6 @@
|
||||
<div class="category-div">
|
||||
<!--<h4>热门分类</h4>-->
|
||||
<ul>
|
||||
<!--<li><a ><img src="//img11.360buyimg.com/focus/s140x140_jfs/t21388/146/237407622/26923/221da1b3/5b054fedN2ba90518.jpg"><span>手机</span></a></li>-->
|
||||
<!--<li><a ><img src="//img20.360buyimg.com/focus/s140x140_jfs/t20128/208/216721929/9242/472993da/5b05522dNa2aae1bb.png"><span>耳机</span></a></li>-->
|
||||
<!--<li><a ><img src="//img30.360buyimg.com/focus/s140x140_jfs/t21655/83/2186874549/15932/c273d29b/5b48802aN13fe73de.png"><span>剃须刀</span></a></li>-->
|
||||
<!--<li><a ><img src="//img20.360buyimg.com/focus/s140x140_jfs/t21715/149/246679831/16257/ddbf2036/5b0565a7N8dbc0017.png"><span>路由器</span></a></li>-->
|
||||
<!--<li><a ><img src="//img14.360buyimg.com/focus/s140x140_jfs/t1/4478/16/633/36008/5b923503E39b9dfa9/13b099f187576d8c.png"><span>月饼</span></a></li>-->
|
||||
<!--<li><a ><img src="//img10.360buyimg.com/focus/s140x140_jfs/t1/1410/32/643/38009/5b9236b2Eb02fbf02/1e7de6987578dcdd.jpg" ><span>牛奶</span></a></li>-->
|
||||
<!--<li><a ><img src="//img20.360buyimg.com/focus/s140x140_jfs/t1/4674/14/665/25245/5b9236bbE088d5efb/6c7c2f9857736c65.jpg"><span>男士内裤</span></a></li>-->
|
||||
<!--<li><a ><img src="//img20.360buyimg.com/focus/s140x140_jfs/t1/1710/26/666/26147/5b9236c3E5fd1cd42/86c6bca8f4fe1efa.png"><span>小米8</span></a></li>-->
|
||||
<!--<li><a ><img src="//img11.360buyimg.com/focus/s140x140_jfs/t1/3653/6/655/42593/5b9236caEfef6235b/9e118f12705f52bb.png"><span>大闸蟹</span></a></li>-->
|
||||
<!--<li><a ><img src="//img20.360buyimg.com/focus/s140x140_jfs/t23881/349/2204372862/9923/4c62864a/5b7693eeNf6883734.png"><span>三只松鼠</span></a></li>-->
|
||||
<!--<li><a ><img src="//img20.360buyimg.com/focus/s140x140_jfs/t24253/294/2182777138/4059/429945c9/5b76990bNde226fbc.png"><span>充电宝</span></a></li>-->
|
||||
<!--<li><a ><img src="//img30.360buyimg.com/focus/s140x140_jfs/t22051/318/235303191/9297/c5ea2761/5b055000N410a7553.png"><span>空调</span></a></li>-->
|
||||
<!--<li><a ><img src="//img10.360buyimg.com/focus/s140x140_jfs/t19960/243/653029866/38879/91bb398b/5b055555N9245f8aa.jpg"><span>电饭煲</span></a></li>-->
|
||||
<!--<li><a ><img src="//img12.360buyimg.com/focus/s140x140_jfs/t1/345/33/944/5582/5b9236d2E62d8da2e/99f72d51b8f195ed.jpg"><span>电话手表</span></a></li>-->
|
||||
<!--<li><a ><img src="//img30.360buyimg.com/focus/s140x140_jfs/t1/1446/14/631/8500/5b9237e5E0d1f9e16/b1a627b92323b5ed.png"><span>华为</span></a></li>-->
|
||||
<li v-for="category in childCategories">
|
||||
<router-link :to="'/products/list?title=' + activeCategory.name + '&cidFirst=' + activeCategory.id + '&cidSecond=' + category.id">
|
||||
<img :src="category.picUrl" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<headerNav title="个人信息"/>
|
||||
<van-cell-group>
|
||||
<van-cell-group title="基础资料">
|
||||
<!--<van-cell title="修改个人信息" is-link />-->
|
||||
<!--<van-cell title="修改登录密码" is-link />-->
|
||||
<!--<van-cell title="修改绑定手机" is-link />-->
|
||||
@ -14,6 +14,10 @@
|
||||
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="密保资料">
|
||||
<van-cell title="手机号" :value="user.mobile" />
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 昵称修改弹出 -->
|
||||
<van-dialog
|
||||
v-model="showNicknameDialog"
|
||||
@ -83,4 +87,4 @@ export default {
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
@ -9,7 +9,6 @@ import cn.iocoder.mall.order.application.convert.OrderReturnConvert;
|
||||
import cn.iocoder.mall.order.application.po.admin.OrderReturnQueryPO;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -26,8 +25,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
@Api("订单退货(admins api)")
|
||||
public class AdminOrderReturnController {
|
||||
|
||||
@Autowired
|
||||
@Reference(validation = "true")
|
||||
@Reference(validation = "true", version = "${dubbo.provider.OrderReturnService.version}")
|
||||
private OrderReturnService orderReturnService;
|
||||
|
||||
@GetMapping("list")
|
||||
|
@ -5,7 +5,9 @@ import cn.iocoder.mall.order.api.OrderService;
|
||||
import cn.iocoder.mall.order.api.bo.OrderItemBO;
|
||||
import cn.iocoder.mall.order.api.bo.OrderPageBO;
|
||||
import cn.iocoder.mall.order.api.bo.OrderRecipientBO;
|
||||
import cn.iocoder.mall.order.api.dto.*;
|
||||
import cn.iocoder.mall.order.api.dto.OrderItemUpdateDTO;
|
||||
import cn.iocoder.mall.order.api.dto.OrderLogisticsUpdateDTO;
|
||||
import cn.iocoder.mall.order.api.dto.OrderQueryDTO;
|
||||
import cn.iocoder.mall.order.application.convert.OrderConvertAPP;
|
||||
import cn.iocoder.mall.order.application.convert.OrderDeliveryConvert;
|
||||
import cn.iocoder.mall.order.application.po.admin.OrderDeliverPO;
|
||||
@ -15,7 +17,6 @@ import cn.iocoder.mall.order.application.po.admin.OrderPageQueryPO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -29,10 +30,10 @@ import java.util.List;
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("admins/order")
|
||||
@Api(value = "订单API(admins)")
|
||||
@Api(value = "订单 API(admins)")
|
||||
public class AdminsOrderController {
|
||||
|
||||
@Reference(validation = "true")
|
||||
@Reference(validation = "true", version = "${dubbo.provider.OrderService.version}")
|
||||
private OrderService orderService;
|
||||
|
||||
@GetMapping("page")
|
||||
|
@ -19,6 +19,7 @@ import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
|
||||
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
|
||||
import cn.iocoder.mall.promotion.api.CouponService;
|
||||
import cn.iocoder.mall.promotion.api.bo.CouponCardAvailableBO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.RequiresLogin;
|
||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -41,19 +42,23 @@ import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("users/order")
|
||||
@Api(description = "用户订单")
|
||||
@Api(description = "用户订单") // TODO FROM 芋艿 to 小范,description 已经废弃啦
|
||||
public class OrderController {
|
||||
|
||||
@Reference(validation = "true")
|
||||
@Reference(validation = "true", version = "${dubbo.provider.OrderReturnService.version}")
|
||||
private OrderService orderService;
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.CartService.version}")
|
||||
private CartService cartService;
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.DataDictService.version}")
|
||||
private DataDictService dataDictService;
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.CouponService.version}")
|
||||
private CouponService couponService;
|
||||
|
||||
@GetMapping("order_page")
|
||||
@RequiresLogin
|
||||
@ApiOperation("订单分页")
|
||||
public CommonResult<OrderPageBO> getOrderPage(@Validated OrderQueryDTO orderQueryDTO) {
|
||||
Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
@ -62,6 +67,7 @@ public class OrderController {
|
||||
}
|
||||
|
||||
@PostMapping("create_order")
|
||||
@RequiresLogin
|
||||
@ApiOperation("创建订单")
|
||||
public CommonResult<OrderCreateBO> createOrder(@RequestBody @Validated OrderCreatePO orderCreatePO,
|
||||
HttpServletRequest request) {
|
||||
@ -72,6 +78,7 @@ public class OrderController {
|
||||
}
|
||||
|
||||
@PostMapping("create_order_from_cart")
|
||||
@RequiresLogin
|
||||
@ApiOperation("创建订单购物车")
|
||||
public CommonResult<OrderCreateBO> createOrderFromCart(@RequestParam("userAddressId") Integer userAddressId,
|
||||
@RequestParam(value = "couponCardId", required = false) Integer couponCardId,
|
||||
@ -99,6 +106,7 @@ public class OrderController {
|
||||
}
|
||||
|
||||
@GetMapping("confirm_create_order")
|
||||
@RequiresLogin
|
||||
@ApiOperation("确认创建订单")
|
||||
public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder(@RequestParam("skuId") Integer skuId,
|
||||
@RequestParam("quantity") Integer quantity,
|
||||
@ -118,6 +126,7 @@ public class OrderController {
|
||||
}
|
||||
|
||||
@PostMapping("confirm_receiving")
|
||||
@RequiresLogin
|
||||
@ApiOperation("确认收货")
|
||||
public CommonResult confirmReceiving(@RequestParam("orderId") Integer orderId) {
|
||||
Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
@ -125,6 +134,7 @@ public class OrderController {
|
||||
}
|
||||
|
||||
@GetMapping("info")
|
||||
@RequiresLogin
|
||||
@ApiOperation("订单详情")
|
||||
public CommonResult<OrderInfoBO> orderInfo(@RequestParam("orderId") Integer orderId) {
|
||||
Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
|
@ -35,8 +35,9 @@ import java.util.stream.Collectors;
|
||||
@Api(description = "订单物流信息")
|
||||
public class OrderLogisticsController {
|
||||
|
||||
@Reference(validation = "true")
|
||||
@Reference(validation = "true", version = "${dubbo.provider.OrderLogisticsService.version}")
|
||||
private OrderLogisticsService orderLogisticsService;
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.DataDictService.version}")
|
||||
private DataDictService dataDictService;
|
||||
|
||||
|
@ -25,8 +25,9 @@ import java.util.List;
|
||||
@RequestMapping("users/order_return")
|
||||
public class OrderReturnController {
|
||||
|
||||
@Reference(validation = "true")
|
||||
@Reference(validation = "true", version = "${dubbo.provider.OrderReturnService.version}")
|
||||
private OrderReturnService orderReturnService;
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.DataDictService.version}")
|
||||
private DataDictService dataDictService;
|
||||
|
||||
|
@ -13,7 +13,6 @@ import cn.iocoder.mall.order.application.vo.UsersCartDetailVO;
|
||||
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
|
||||
import cn.iocoder.mall.promotion.api.CouponService;
|
||||
import cn.iocoder.mall.promotion.api.bo.CouponCardAvailableBO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -31,8 +30,10 @@ public class UsersCartController {
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.CartService.version}")
|
||||
private CartService cartService;
|
||||
@Reference(validation = "true")
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.OrderService.version}")
|
||||
private OrderService orderService;
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.CouponService.version}")
|
||||
private CouponService couponService;
|
||||
|
||||
@ -125,7 +126,6 @@ public class UsersCartController {
|
||||
}
|
||||
|
||||
@GetMapping("/calc_sku_price")
|
||||
@PermitAll
|
||||
public CommonResult<UsersCalcSkuPriceVO> calcSkuPrice(@RequestParam("skuId") Integer skuId) {
|
||||
// 计算 sku 的价格
|
||||
CalcSkuPriceBO calcSkuPrice = cartService.calcSkuPrice(skuId);
|
||||
|
@ -127,7 +127,7 @@ public interface OrderService {
|
||||
CommonResult updateLogistics(OrderLogisticsUpdateDTO orderLogisticsDTO);
|
||||
|
||||
/**
|
||||
* 删除订单
|
||||
* 删除订单 // TODO FROM 芋艿 to 小范。删除订单,不要使用 deleted 字段,对于用户是删除,实际是隐藏。
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
|
@ -12,7 +12,7 @@ import lombok.experimental.Accessors;
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OrderRecipientBO extends BaseDO {
|
||||
public class OrderRecipientBO extends BaseDO { // TODO FROM 芋艿 TO 小范,不要继承 BaseDO
|
||||
|
||||
/**
|
||||
* 编号
|
||||
|
@ -15,10 +15,12 @@ public class CalcOrderPriceDTO {
|
||||
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
|
||||
/**
|
||||
* 优惠劵编号
|
||||
*/
|
||||
private Integer couponCardId;
|
||||
|
||||
@NotNull(message = "商品数组不能为空")
|
||||
private List<Item> items;
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* 订单 api
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019-03-16 13:15
|
||||
*/
|
||||
package cn.iocoder.mall.order.api;
|
@ -16,5 +16,5 @@ public class ServiceExceptionConfiguration {
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
}
|
||||
}
|
||||
} // TODO FROM 芋艿 to 小范,这里记得配置下,不然错误提示不出去呀。
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* 定义常量,以及枚举信息
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019-03-20 21:16
|
||||
*/
|
||||
package cn.iocoder.mall.order.biz.constants;
|
@ -18,7 +18,7 @@ import lombok.experimental.Accessors;
|
||||
public class OrderCommentDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 评论id
|
||||
* 评论id // TODO FROM 芋艿 TO wtz 中英文之间,要有空格
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
@ -103,7 +103,7 @@ public class OrderCommentDO extends BaseDO {
|
||||
private Integer replayCount;
|
||||
|
||||
/**
|
||||
* 点赞数
|
||||
* 点赞数 // TODO FROM 芋艿 TO wtz collect 是收藏的意思,最好换个单词噢。
|
||||
*/
|
||||
private Integer collectCount;
|
||||
|
||||
|
@ -8,6 +8,8 @@ import lombok.experimental.Accessors;
|
||||
/**
|
||||
* 商品评价回复表
|
||||
*
|
||||
* // TODO FROM 芋艿 TO wtz 商品评价回复表 =》订单评论回复表
|
||||
*
|
||||
* @author wtz
|
||||
* @time 2019-05-14 21:00
|
||||
*
|
||||
@ -28,7 +30,7 @@ public class OrderCommentReplayDO extends BaseDO {
|
||||
private Integer commentId;
|
||||
|
||||
/**
|
||||
* 回复的类型
|
||||
* 回复的类型 // TODO FROM 芋艿 TO wtz 记得加下枚举类
|
||||
*/
|
||||
private Integer replyType;
|
||||
|
||||
@ -73,7 +75,7 @@ public class OrderCommentReplayDO extends BaseDO {
|
||||
private String replyUserAvatar;
|
||||
|
||||
/**
|
||||
* 回复用户身份
|
||||
* 回复用户身份 // TODO FROM 芋艿 TO wtz 【提示】userType 和 UserTypeEnum 记录保持一致。
|
||||
*/
|
||||
private Integer replyUserType;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.mall.order.biz.dataobject;
|
||||
|
||||
import cn.iocoder.common.framework.dataobject.BaseDO;
|
||||
import cn.iocoder.common.framework.dataobject.DeletableDO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -17,6 +16,8 @@ import java.util.Date;
|
||||
@Accessors(chain = true)
|
||||
public class OrderReturnDO extends BaseDO {
|
||||
|
||||
// TODO FROM 芋艿 TO 小范,存储下支付中心的退款单号
|
||||
|
||||
/**
|
||||
* 编号自动增长
|
||||
*/
|
||||
@ -24,6 +25,7 @@ public class OrderReturnDO extends BaseDO {
|
||||
/**
|
||||
* 服务号
|
||||
*/
|
||||
// TODO FROM 芋艿 to 小范,换个名字,看着怪怪的 哈哈哈哈。
|
||||
private String serviceNumber;
|
||||
/**
|
||||
* 订单编号
|
||||
@ -54,6 +56,7 @@ public class OrderReturnDO extends BaseDO {
|
||||
/**
|
||||
* 问题描述
|
||||
*/
|
||||
// TODO FROM 芋艿 to 小范,describe 是动词,换成名词 description
|
||||
private String describe;
|
||||
|
||||
///
|
||||
|
@ -21,7 +21,7 @@ import cn.iocoder.mall.order.biz.dataobject.OrderDO;
|
||||
import cn.iocoder.mall.order.biz.dataobject.OrderItemDO;
|
||||
import cn.iocoder.mall.order.biz.dataobject.OrderReturnDO;
|
||||
import cn.iocoder.mall.pay.api.PayRefundService;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundSubmitDTO;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -14,8 +14,8 @@ import cn.iocoder.mall.order.biz.convert.*;
|
||||
import cn.iocoder.mall.order.biz.dao.*;
|
||||
import cn.iocoder.mall.order.biz.dataobject.*;
|
||||
import cn.iocoder.mall.pay.api.PayTransactionService;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||
import cn.iocoder.mall.promotion.api.CouponService;
|
||||
@ -79,7 +79,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
public CommonResult<OrderPageBO> getOrderPage(OrderQueryDTO orderQueryDTO) {
|
||||
|
||||
int totalCount = orderMapper.selectPageCount(orderQueryDTO);
|
||||
if (totalCount == 0) {
|
||||
if (totalCount == 0) { // TODO FROM 芋艿 TO 小范 Collections.EMPTY_LIST 改成 Collections.emptyList()
|
||||
return CommonResult.success(new OrderPageBO().setOrders(Collections.EMPTY_LIST).setTotal(0));
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
|
||||
// 获取订单 id
|
||||
Set<Integer> orderIds = orderDOList.stream()
|
||||
.map(orderDO -> orderDO.getId())
|
||||
.map(orderDO -> orderDO.getId()) // TODO FROM 芋艿 to 小范,记得用 Lambda
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 获取配送信息
|
||||
@ -231,10 +231,10 @@ public class OrderServiceImpl implements OrderService {
|
||||
// 设置 orderItem
|
||||
Map<Integer, ProductSkuDetailBO> productSpuBOMap = productList
|
||||
.stream().collect(Collectors.toMap(ProductSkuDetailBO::getId, o -> o)); // 商品 SKU 信息的集合
|
||||
Map<Integer, CalcOrderPriceBO.Item> priceItemMap = new HashMap<>();
|
||||
Map<Integer, CalcOrderPriceBO.Item> priceItemMap = new HashMap<>(); // 商品 SKU 价格的映射
|
||||
calcOrderPrice.getItemGroups().forEach(itemGroup ->
|
||||
itemGroup.getItems().forEach(item -> priceItemMap.put(item.getId(), item)));
|
||||
|
||||
// 遍历 orderItemDOList 数组,将商品信息、商品价格,设置到其中
|
||||
for (OrderItemDO orderItemDO : orderItemDOList) {
|
||||
ProductSkuDetailBO productSkuDetailBO = productSpuBOMap.get(orderItemDO.getSkuId());
|
||||
if (productSkuDetailBO.getQuantity() <= 0) {
|
||||
@ -267,6 +267,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
// order
|
||||
|
||||
// TODO: 2019-04-11 Sin 订单号需要生成规则
|
||||
// TODO FROM 芋艿 to 小范:可以考虑抽象成一个方法,下面几个也是。
|
||||
String orderNo = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
|
||||
// Integer totalAmount = orderCommon.calculatedAmount(orderItemDOList);
|
||||
// Integer totalPrice = orderCommon.calculatedPrice(orderItemDOList);
|
||||
@ -323,10 +324,6 @@ public class OrderServiceImpl implements OrderService {
|
||||
// 一次性插入
|
||||
orderItemMapper.insert(orderItemDOList);
|
||||
|
||||
if (true) {
|
||||
throw new RuntimeException("测试 seata 事务回滚");
|
||||
}
|
||||
|
||||
// 创建预订单
|
||||
createPayTransaction(orderDO, orderItemDOList, orderCreateDTO.getIp());
|
||||
|
||||
@ -358,7 +355,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
return cartService.calcOrderPrice(calcOrderPriceDTO);
|
||||
}
|
||||
|
||||
private CommonResult<PayTransactionBO> createPayTransaction(OrderDO order, List<OrderItemDO> orderItems, String ip) {
|
||||
private PayTransactionBO createPayTransaction(OrderDO order, List<OrderItemDO> orderItems, String ip) {
|
||||
// TODO sin 支付订单 orderSubject 暂时取第一个子订单商品信息
|
||||
String orderSubject = orderItems.get(0).getSkuName();
|
||||
Date expireTime = DateUtil.addDate(Calendar.MINUTE, PAY_EXPIRE_TIME);
|
||||
@ -441,6 +438,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
.setUpdateTime(null);
|
||||
|
||||
// 关闭订单,修改状态 item
|
||||
// TODO FROM 芋艿 TO 小范,更新的时候,where 里面带下 status 避免并发的问题
|
||||
orderItemMapper.updateByOrderId(
|
||||
orderId,
|
||||
new OrderItemDO().setStatus(OrderStatusEnum.CLOSED.getValue())
|
||||
@ -454,18 +452,18 @@ public class OrderServiceImpl implements OrderService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional // TODO FROM 芋艿 TO 小范:泛型,一定要明确哈。
|
||||
public CommonResult orderDelivery(OrderDeliveryDTO orderDelivery) {
|
||||
List<Integer> orderItemIds = orderDelivery.getOrderItemIds();
|
||||
|
||||
// 获取所有订单 items
|
||||
// 获取所有订单 items // TODO FROM 芋艿 TO 小范,deleted 是默认条件,所以 by 里面可以不带哈
|
||||
List<OrderItemDO> allOrderItems = orderItemMapper.selectByDeletedAndOrderId(orderDelivery.getOrderId(), DeletedStatusEnum.DELETED_NO.getValue());
|
||||
|
||||
// 当前需要发货订单,检查 id 和 status
|
||||
List<OrderItemDO> needDeliveryOrderItems = allOrderItems.stream()
|
||||
.filter(orderItemDO -> orderItemIds.contains(orderItemDO.getId())
|
||||
&& OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus())
|
||||
.collect(Collectors.toList());
|
||||
.collect(Collectors.toList()); // TODO 芋艿,如果这里只是比对数字,可以用 Lambda 求和,不需要弄成一个集合的
|
||||
// 发货订单,检查
|
||||
if (needDeliveryOrderItems.size() != orderItemIds.size()) {
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_DELIVERY_INCORRECT_DATA.getCode());
|
||||
@ -482,6 +480,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
orderLogisticsMapper.insert(orderLogisticsDO);
|
||||
|
||||
// 关联订单item 和 物流信息
|
||||
// TODO FROM 芋艿 TO 小范,更新的时候,where 里面带下 status 避免并发的问题,然后判断下更新数量,不对,就抛出异常。
|
||||
orderItemMapper.updateByIds(
|
||||
orderItemIds,
|
||||
new OrderItemDO()
|
||||
@ -495,6 +494,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
&& !orderItemIds.contains(orderItemDO.getId()))
|
||||
.collect(Collectors.toList());
|
||||
if (unShippedOrderItems.size() <= 0) {
|
||||
// TODO FROM 芋艿 TO 小范,更新的时候,where 里面带下 status 避免并发的问题
|
||||
orderMapper.updateById(
|
||||
new OrderDO()
|
||||
.setId(orderDelivery.getOrderId())
|
||||
@ -513,7 +513,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional // TODO FROM 芋艿 to 小范,先不做这个功能,电商一班不存在这个功能哈。
|
||||
public CommonResult deleteOrderItem(OrderItemDeletedDTO orderItemDeletedDTO) {
|
||||
Integer orderId = orderItemDeletedDTO.getOrderId();
|
||||
List<Integer> orderItemIds = orderItemDeletedDTO.getOrderItemIds();
|
||||
@ -562,6 +562,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_UNABLE_CONFIRM_ORDER.getCode());
|
||||
}
|
||||
|
||||
// TODO FROM 芋艿 TO 小范,更新的时候,where 里面带下 status 避免并发的问题
|
||||
orderMapper.updateById(
|
||||
new OrderDO()
|
||||
.setId(orderId)
|
||||
@ -617,7 +618,7 @@ public class OrderServiceImpl implements OrderService {
|
||||
if (updateCount <= 0) {
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
|
||||
}
|
||||
// TODO 芋艿 更新 OrderItemDO
|
||||
// TODO FROM 芋艿 to 小范,把更新 OrderItem 给补全。
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ mybatis-plus:
|
||||
id-type: auto
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
type-aliases-package: cn.iocoder.mall.order.biz.dataobject
|
||||
config-location: classpath:mybatis-config.xml
|
||||
|
||||
# dubbo
|
||||
dubbo:
|
||||
|
@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
|
||||
<settings>
|
||||
<!-- 使用驼峰命名法转换字段。 -->
|
||||
<setting name="mapUnderscoreToCamelCase" value="true"/>
|
||||
</settings>
|
||||
|
||||
<typeAliases>
|
||||
<typeAlias alias="Integer" type="java.lang.Integer"/>
|
||||
<typeAlias alias="Long" type="java.lang.Long"/>
|
||||
<typeAlias alias="HashMap" type="java.util.HashMap"/>
|
||||
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
|
||||
<typeAlias alias="ArrayList" type="java.util.ArrayList"/>
|
||||
<typeAlias alias="LinkedList" type="java.util.LinkedList"/>
|
||||
</typeAliases>
|
||||
|
||||
</configuration>
|
@ -3,8 +3,6 @@ package cn.iocoder.mall.order.biz.mapper;
|
||||
import cn.iocoder.mall.order.biz.OrderApplicationTest;
|
||||
import cn.iocoder.mall.order.biz.dao.OrderMapper;
|
||||
import cn.iocoder.mall.order.biz.dataobject.OrderDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -3,10 +3,10 @@ package cn.iocoder.mall.pay.application.controller.admins;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.PayRefundService;
|
||||
import cn.iocoder.mall.pay.api.PayTransactionService;
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundPageDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundPageDTO;
|
||||
import cn.iocoder.mall.pay.application.convert.PayRefundConvert;
|
||||
import cn.iocoder.mall.pay.application.vo.admins.AdminsPayRefundPageVO;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
|
@ -2,8 +2,8 @@ package cn.iocoder.mall.pay.application.controller.admins;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.PayTransactionService;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionPageBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionPageDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionPageBO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionPageDTO;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -3,11 +3,14 @@ package cn.iocoder.mall.pay.application.controller.users;
|
||||
import cn.iocoder.common.framework.util.HttpUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.PayTransactionService;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.constant.PayChannelEnum;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionGetDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -18,8 +21,11 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("users/transaction") // TODO 芋艿,理论来说,是用户无关的。这里先酱紫先~
|
||||
@RequestMapping("users/transaction")
|
||||
@Api("【用户】支付交易 API")
|
||||
public class UsersPayTransactionController {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
@ -28,23 +34,19 @@ public class UsersPayTransactionController {
|
||||
private PayTransactionService payTransactionService;
|
||||
|
||||
@GetMapping("/get")
|
||||
// TODO result 后面改下
|
||||
public CommonResult<PayTransactionBO> get(@RequestParam("appId") String appId,
|
||||
@RequestParam("orderId") String orderId) {
|
||||
return payTransactionService.getTransaction(UserSecurityContextHolder.getContext().getUserId(), appId, orderId);
|
||||
@ApiOperation("获得支付交易")
|
||||
public CommonResult<PayTransactionBO> get(PayTransactionGetDTO payTransactionGetDTO) {
|
||||
payTransactionGetDTO.setUserId(UserSecurityContextHolder.getContext().getUserId());
|
||||
return success(payTransactionService.getTransaction(payTransactionGetDTO));
|
||||
}
|
||||
|
||||
@PostMapping("/submit") // TODO api 注释
|
||||
// TODO result 后面改下
|
||||
@PostMapping("/submit")
|
||||
@ApiOperation("提交支付交易")
|
||||
public CommonResult<PayTransactionSubmitBO> submit(HttpServletRequest request,
|
||||
@RequestParam("appId") String appId,
|
||||
@RequestParam("orderId") String orderId,
|
||||
@RequestParam("payChannel") Integer payChannel) {
|
||||
PayTransactionSubmitDTO payTransactionSubmitDTO = new PayTransactionSubmitDTO()
|
||||
.setAppId(appId).setOrderId(orderId).setPayChannel(payChannel)
|
||||
.setCreateIp(HttpUtil.getIp(request));
|
||||
PayTransactionSubmitDTO payTransactionSubmitDTO) {
|
||||
payTransactionSubmitDTO.setCreateIp(HttpUtil.getIp(request));
|
||||
// 提交支付提交
|
||||
return payTransactionService.submitTransaction(payTransactionSubmitDTO);
|
||||
return success(payTransactionService.submitTransaction(payTransactionSubmitDTO));
|
||||
}
|
||||
|
||||
@PostMapping(value = "pingxx_pay_success", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ -63,11 +65,7 @@ public class UsersPayTransactionController {
|
||||
// JSONObject bodyObj = JSON.parseObject(sb.toString());
|
||||
// bodyObj.put("webhookId", bodyObj.remove("id"));
|
||||
// String body = bodyObj.toString();
|
||||
CommonResult<Boolean> result = payTransactionService.updateTransactionPaySuccess(PayChannelEnum.PINGXX.getId(), sb.toString());
|
||||
if (result.isError()) {
|
||||
logger.error("[pingxxPaySuccess][message({}) result({})]", sb, result);
|
||||
return "failure";
|
||||
}
|
||||
payTransactionService.updateTransactionPaySuccess(PayChannelEnum.PINGXX.getId(), sb.toString());
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.iocoder.mall.pay.application.convert;
|
||||
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.application.vo.admins.AdminsPayRefundDetailVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.mall.pay.application.vo.admins;
|
||||
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
package cn.iocoder.mall.pay.api;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundSubmitDTO;
|
||||
|
||||
public interface PayRefundService {
|
||||
|
||||
|
@ -1,23 +1,24 @@
|
||||
package cn.iocoder.mall.pay.api;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionGetDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionSubmitDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface PayTransactionService {
|
||||
|
||||
CommonResult<PayTransactionBO> getTransaction(Integer userId, String appId, String orderId);
|
||||
PayTransactionBO getTransaction(PayTransactionGetDTO payTransactionGetDTO);
|
||||
|
||||
CommonResult<PayTransactionBO> createTransaction(PayTransactionCreateDTO payTransactionCreateDTO);
|
||||
PayTransactionBO createTransaction(PayTransactionCreateDTO payTransactionCreateDTO);
|
||||
|
||||
CommonResult<PayTransactionSubmitBO> submitTransaction(PayTransactionSubmitDTO payTransactionSubmitDTO);
|
||||
PayTransactionSubmitBO submitTransaction(PayTransactionSubmitDTO payTransactionSubmitDTO);
|
||||
|
||||
/**
|
||||
* 更新交易支付成功
|
||||
@ -29,7 +30,7 @@ public interface PayTransactionService {
|
||||
* 因为不同平台,能够提供的参数不同,所以使用 String 类型统一接收,然后在使用不同的 AbstractPaySDK 进行处理。
|
||||
* @return 是否支付成功
|
||||
*/
|
||||
CommonResult<Boolean> updateTransactionPaySuccess(Integer payChannel, String params);
|
||||
Boolean updateTransactionPaySuccess(Integer payChannel, String params);
|
||||
|
||||
List<PayTransactionBO> getTransactionList(Collection<Integer> ids);
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
package cn.iocoder.mall.pay.api.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 支付交易提交结果 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionSubmitBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 支付交易拓展单编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 调用三方平台的响应结果
|
||||
*/
|
||||
private String invokeResponse;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.bo;
|
||||
package cn.iocoder.mall.pay.api.bo.refund;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.bo;
|
||||
package cn.iocoder.mall.pay.api.bo.refund;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.bo;
|
||||
package cn.iocoder.mall.pay.api.bo.refund;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -1,63 +1,48 @@
|
||||
package cn.iocoder.mall.pay.api.bo;
|
||||
package cn.iocoder.mall.pay.api.bo.transaction;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 支付交易 BO
|
||||
*/
|
||||
@ApiModel("支付交易 BO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 编号,自增
|
||||
*/
|
||||
@ApiModelProperty(value = "交易编号", required = true, example = "POd4RC6a")
|
||||
private Integer id;
|
||||
/**
|
||||
* 应用编号
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "POd4RC6a")
|
||||
private String appId;
|
||||
/**
|
||||
* 发起交易的 IP
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "发起交易的 IP", required = true, example = "192.168.10.1")
|
||||
private String createIp;
|
||||
/**
|
||||
* 业务线的订单编号
|
||||
*
|
||||
* 1. 使用 String 的原因是,业务线可能使用 String 做为编号
|
||||
* 2. 每个 appId 下,orderId 唯一
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "订单号不能为空", required = true, example = "1024")
|
||||
private String orderId;
|
||||
/**
|
||||
* 订单商品名
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "商品名", required = true, example = "芋道源码")
|
||||
private String orderSubject;
|
||||
/**
|
||||
* 订单商品描述
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "订单商品描述", required = true, example = "绵啾啾的")
|
||||
private String orderDescription;
|
||||
/**
|
||||
* 订单备注
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "订单商品备注", example = "绵啾啾的")
|
||||
private String orderMemo;
|
||||
/**
|
||||
* 支付金额,单位:分。
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "支付金额,单位:分。", required = true, example = "10")
|
||||
private Integer price;
|
||||
/**
|
||||
* 订单状态
|
||||
*
|
||||
* @see cn.iocoder.mall.pay.api.constant.PayTransactionStatusEnum
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "订单状态", required = true, example = "1", notes = "参见 PayTransactionStatusEnum 枚举")
|
||||
private Integer status;
|
||||
/**
|
||||
* 交易过期时间
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "交易过期时间", required = true)
|
||||
private Date expireTime;
|
||||
|
||||
/**
|
||||
* 回调业务线完成时间
|
||||
*/
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.bo;
|
||||
package cn.iocoder.mall.pay.api.bo.transaction;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.mall.pay.api.bo.transaction;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("支付交易提交结果 BO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionSubmitBO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "支付交易拓展单编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty(value = "调用三方平台的响应结果", required = true)
|
||||
private String invokeResponse;
|
||||
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
package cn.iocoder.mall.pay.api.constant;
|
||||
|
||||
import cn.iocoder.common.framework.core.IntArrayValuable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 支付通道
|
||||
*/
|
||||
public enum PayChannelEnum {
|
||||
public enum PayChannelEnum implements IntArrayValuable {
|
||||
|
||||
WEIXIN_APP(100, "wx", "微信 App 支付"),
|
||||
WEIXIN_PUB(101, "wxjs", "微信 JS API 支付"),
|
||||
@ -13,6 +17,8 @@ public enum PayChannelEnum {
|
||||
PINGXX(9999, "ping++", "ping++ 支付"),
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayChannelEnum::getId).toArray();
|
||||
|
||||
/**
|
||||
* 渠道编号
|
||||
*/
|
||||
@ -44,4 +50,9 @@ public enum PayChannelEnum {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package cn.iocoder.mall.pay.api.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 支付交易提交 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionSubmitDTO {
|
||||
|
||||
/**
|
||||
* 应用编号
|
||||
*/
|
||||
@NotEmpty(message = "应用编号不能为空")
|
||||
private String appId;
|
||||
/**
|
||||
* 发起交易的 IP
|
||||
*/
|
||||
@NotEmpty(message = "IP 不能为空")
|
||||
private String createIp;
|
||||
/**
|
||||
* 业务线的订单编号
|
||||
*/
|
||||
@NotEmpty(message = "订单号不能为空")
|
||||
private String orderId;
|
||||
/**
|
||||
* 支付渠道
|
||||
*/
|
||||
@NotNull(message = "支付渠道")
|
||||
private Integer payChannel;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.dto;
|
||||
package cn.iocoder.mall.pay.api.dto.refund;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.dto;
|
||||
package cn.iocoder.mall.pay.api.dto.refund;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.mall.pay.api.dto;
|
||||
package cn.iocoder.mall.pay.api.dto.transaction;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
@ -10,54 +12,43 @@ import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 支付交易创建 DTO
|
||||
*/
|
||||
@ApiModel("支付交易创建 DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionCreateDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 应用编号
|
||||
*/
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "POd4RC6a")
|
||||
@NotEmpty(message = "应用编号不能为空")
|
||||
private String appId;
|
||||
/**
|
||||
* 发起交易的 IP
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "发起交易的 IP", required = true, example = "192.168.10.1")
|
||||
@NotEmpty(message = "IP 不能为空")
|
||||
private String createIp;
|
||||
/**
|
||||
* 业务线的订单编号
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "订单号不能为空", required = true, example = "1024")
|
||||
@NotEmpty(message = "订单号不能为空")
|
||||
private String orderId;
|
||||
/**
|
||||
* 订单商品名
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "商品名", required = true, example = "芋道源码")
|
||||
@NotEmpty(message = "商品名不能为空")
|
||||
@Length(max = 32, message = "商品名不能超过32")
|
||||
private String orderSubject;
|
||||
/**
|
||||
* 订单商品描述
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "订单商品描述", required = true, example = "绵啾啾的")
|
||||
@NotEmpty(message = "商品描述不能为空")
|
||||
@Length(max = 128, message = "商品描述长度不能超过128")
|
||||
private String orderDescription;
|
||||
/**
|
||||
* 订单备注
|
||||
*/
|
||||
@Length(max = 256, message = "商品描述长度不能超过256")
|
||||
|
||||
@ApiModelProperty(value = "订单商品备注", example = "绵啾啾的")
|
||||
@Length(max = 256, message = "商品备注长度不能超过256")
|
||||
private String orderMemo;
|
||||
/**
|
||||
* 支付金额,单位:分。
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "支付金额,单位:分。", required = true, example = "10")
|
||||
@NotNull(message = "金额不能为空")
|
||||
@DecimalMin(value = "0", inclusive = false, message = "金额必须大于零")
|
||||
private Integer price;
|
||||
/**
|
||||
* 交易过期时间
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "交易过期时间", required = true)
|
||||
@NotNull(message = "交易过期时间不能为空")
|
||||
private Date expireTime;
|
||||
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.mall.pay.api.dto.transaction;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("支付交易获得 DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionGetDTO {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1", hidden = true) // hidden 的原因是,Service DTO 自己传入,无需暴露的 Controller API 里
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "POd4RC6a")
|
||||
@NotEmpty(message = "应用编号不能为空")
|
||||
private String appId;
|
||||
|
||||
@ApiModelProperty(value = "订单号不能为空", required = true, example = "1024")
|
||||
@NotEmpty(message = "订单号不能为空")
|
||||
private String orderId;
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.mall.pay.api.dto;
|
||||
package cn.iocoder.mall.pay.api.dto.transaction;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.mall.pay.api.dto.transaction;
|
||||
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.mall.pay.api.constant.PayChannelEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("支付交易提交 DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PayTransactionSubmitDTO {
|
||||
|
||||
@ApiModelProperty(value = "应用编号", required = true, example = "POd4RC6a")
|
||||
@NotEmpty(message = "应用编号不能为空")
|
||||
private String appId;
|
||||
|
||||
@ApiModelProperty(value = "发起交易的 IP", required = true, example = "192.168.10.1", hidden = true) // hidden 的原因是,Service DTO 自己传入,无需暴露的 Controller API 里
|
||||
@NotEmpty(message = "IP 不能为空")
|
||||
private String createIp;
|
||||
|
||||
@ApiModelProperty(value = "订单号", required = true, example = "1024")
|
||||
@NotEmpty(message = "订单号不能为空")
|
||||
private String orderId;
|
||||
|
||||
@ApiModelProperty(value = "支付渠道", required = true, example = "1", notes = "参见 PayChannelEnum 枚举")
|
||||
@InEnum(value = PayChannelEnum.class, message = "支付渠道必须是 {value}")
|
||||
@NotNull(message = "支付渠道")
|
||||
private Integer payChannel;
|
||||
|
||||
}
|
@ -1,17 +1,20 @@
|
||||
package cn.iocoder.mall.pay.biz.component;
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.Data;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DubboReferencePool {
|
||||
|
||||
@ -44,7 +47,8 @@ public class DubboReferencePool {
|
||||
private String dubboApplicationName;
|
||||
|
||||
private ReferenceMeta createGenericService(String notifyUrl) {
|
||||
String[] notifyUrlParts = notifyUrl.split("#");
|
||||
// 使用 # 号分隔,格式为 服务名#方法名#版本号
|
||||
List<String> notifyUrlParts = StringUtil.split(notifyUrl, "#");
|
||||
// 创建 ApplicationConfig 对象
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName(dubboApplicationName);
|
||||
@ -55,14 +59,14 @@ public class DubboReferencePool {
|
||||
application.setRegistry(registry);
|
||||
// 创建 ReferenceConfig 对象
|
||||
ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
|
||||
reference.setInterface(notifyUrlParts[0]); // 弱类型接口名
|
||||
reference.setInterface(notifyUrlParts.get(0)); // 弱类型接口名
|
||||
reference.setGeneric(true); // 声明为泛化接口
|
||||
reference.setApplication(application);
|
||||
// reference.setVersion("*"); // TODO 芋艿,后面要优化下。
|
||||
reference.setVersion(notifyUrlParts.size() > 2 ? notifyUrlParts.get(2) : "1.0.0"); // 如果未配置服务的版本号,则默认使用 1.0.0
|
||||
// 获得 GenericService 对象
|
||||
GenericService genericService = reference.get();
|
||||
// 构建最终的 ReferenceMeta 对象
|
||||
return new ReferenceMeta(reference, genericService, notifyUrlParts[1]);
|
||||
return new ReferenceMeta(reference, genericService, notifyUrlParts.get(1));
|
||||
}
|
||||
|
||||
public ReferenceMeta getReferenceMeta(String notifyUrl) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.mall.pay.biz.convert;
|
||||
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundBO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayRefundDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
|
@ -1,8 +1,8 @@
|
||||
package cn.iocoder.mall.pay.biz.convert;
|
||||
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayTransactionDO;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayTransactionExtensionDO;
|
||||
import org.mapstruct.Mapper;
|
||||
|
@ -18,6 +18,7 @@ import java.util.Date;
|
||||
topic = PayRefundSuccessMessage.TOPIC,
|
||||
consumerGroup = "pay-consumer-group-" + PayRefundSuccessMessage.TOPIC
|
||||
)
|
||||
@Deprecated // 艿艿:突然发现,业务方实际无需回调。参考了 https://help.youzan.com/displaylist/detail_4_998 的文章。业务方,只要记录下退款单号,进行关联即可。
|
||||
public class PayRefundSuccessConsumer extends AbstractPayNotifySuccessConsumer<PayRefundSuccessMessage>
|
||||
implements RocketMQListener<PayRefundSuccessMessage> {
|
||||
|
||||
|
@ -2,7 +2,6 @@ package cn.iocoder.mall.pay.biz.service;
|
||||
|
||||
import cn.iocoder.common.framework.constant.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.constant.PayErrorCodeEnum;
|
||||
import cn.iocoder.mall.pay.biz.dao.PayAppMapper;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayAppDO;
|
||||
@ -15,17 +14,17 @@ public class PayAppServiceImpl {
|
||||
@Autowired
|
||||
private PayAppMapper payAppMapper;
|
||||
|
||||
public CommonResult<PayAppDO> validPayApp(String appId) {
|
||||
public PayAppDO validPayApp(String appId) {
|
||||
PayAppDO payAppDO = payAppMapper.selectById(appId);
|
||||
// 校验是否存在
|
||||
if (payAppDO == null) {
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_APP_NOT_FOUND.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_APP_NOT_FOUND.getCode());
|
||||
}
|
||||
// 校验是否禁用
|
||||
if (CommonStatusEnum.DISABLE.getValue().equals(payAppDO.getStatus())) {
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_APP_IS_DISABLE.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_APP_IS_DISABLE.getCode());
|
||||
}
|
||||
return CommonResult.success(payAppDO);
|
||||
return payAppDO;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ public class PayNotifyServiceImpl {
|
||||
@Resource
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
@Deprecated // 参见 PayRefundSuccessConsumer 类的说明
|
||||
public void addRefundNotifyTask(PayRefundDO refund) {
|
||||
PayNotifyTaskDO payTransactionNotifyTask = this.createBasePayNotifyTaskDO(refund.getAppId(), refund.getNotifyUrl())
|
||||
.setType(PayNotifyType.REFUND.getValue());
|
||||
|
@ -5,13 +5,13 @@ import cn.iocoder.common.framework.util.MathUtil;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.PayRefundService;
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayRefundSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.refund.PayRefundSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.constant.PayErrorCodeEnum;
|
||||
import cn.iocoder.mall.pay.api.constant.PayRefundStatus;
|
||||
import cn.iocoder.mall.pay.api.constant.PayTransactionStatusEnum;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.biz.client.AbstractPaySDK;
|
||||
import cn.iocoder.mall.pay.biz.client.PaySDKFactory;
|
||||
import cn.iocoder.mall.pay.biz.client.RefundSuccessBO;
|
||||
@ -51,13 +51,9 @@ public class PayRefundServiceImpl implements PayRefundService {
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
public CommonResult<PayRefundSubmitBO> submitRefund(PayRefundSubmitDTO payRefundSubmitDTO) {
|
||||
// 校验 App 是否有效
|
||||
CommonResult<PayAppDO> appResult = payAppService.validPayApp(payRefundSubmitDTO.getAppId());
|
||||
if (appResult.isError()) {
|
||||
return CommonResult.error(appResult);
|
||||
}
|
||||
PayAppDO payAppDO = payAppService.validPayApp(payRefundSubmitDTO.getAppId());
|
||||
// 获得 PayTransactionDO ,并校验其是否存在
|
||||
PayTransactionDO payTransaction = payTransactionService.getTransaction(payRefundSubmitDTO.getAppId(), payRefundSubmitDTO.getOrderId());
|
||||
if (payTransaction == null) { // 是否存在
|
||||
@ -82,7 +78,7 @@ public class PayRefundServiceImpl implements PayRefundService {
|
||||
.setTransactionId(payTransaction.getId())
|
||||
.setRefundCode(generateTransactionCode()) // TODO 芋艿,后续调整
|
||||
.setStatus(PayRefundStatus.WAITING.getValue())
|
||||
.setNotifyUrl(appResult.getData().getRefundNotifyUrl())
|
||||
.setNotifyUrl(payAppDO.getRefundNotifyUrl())
|
||||
.setRefundChannel(payTransaction.getPayChannel());
|
||||
payRefundDO.setCreateTime(new Date());
|
||||
payRefundMapper.insert(payRefundDO);
|
||||
|
@ -5,14 +5,15 @@ import cn.iocoder.common.framework.util.MathUtil;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.pay.api.PayTransactionService;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.PayTransactionSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionPageBO;
|
||||
import cn.iocoder.mall.pay.api.bo.transaction.PayTransactionSubmitBO;
|
||||
import cn.iocoder.mall.pay.api.constant.PayErrorCodeEnum;
|
||||
import cn.iocoder.mall.pay.api.constant.PayTransactionStatusEnum;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionCreateDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionGetDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionPageDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.transaction.PayTransactionSubmitDTO;
|
||||
import cn.iocoder.mall.pay.biz.client.AbstractPaySDK;
|
||||
import cn.iocoder.mall.pay.biz.client.PaySDKFactory;
|
||||
import cn.iocoder.mall.pay.biz.client.TransactionSuccessBO;
|
||||
@ -68,23 +69,21 @@ public class PayTransactionServiceImpl implements PayTransactionService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<PayTransactionBO> getTransaction(Integer userId, String appId, String orderId) {
|
||||
PayTransactionDO payTransaction = payTransactionMapper.selectByAppIdAndOrderId(appId, orderId);
|
||||
public PayTransactionBO getTransaction(PayTransactionGetDTO payTransactionGetDTO) {
|
||||
PayTransactionDO payTransaction = payTransactionMapper.selectByAppIdAndOrderId(payTransactionGetDTO.getAppId(),
|
||||
payTransactionGetDTO.getOrderId());
|
||||
if (payTransaction == null) {
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
|
||||
}
|
||||
// TODO 芋艿 userId 的校验
|
||||
return CommonResult.success(PayTransactionConvert.INSTANCE.convert(payTransaction));
|
||||
return PayTransactionConvert.INSTANCE.convert(payTransaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
public CommonResult<PayTransactionBO> createTransaction(PayTransactionCreateDTO payTransactionCreateDTO) {
|
||||
public PayTransactionBO createTransaction(PayTransactionCreateDTO payTransactionCreateDTO) {
|
||||
// 校验 App
|
||||
CommonResult<PayAppDO> appResult = payAppService.validPayApp(payTransactionCreateDTO.getAppId());
|
||||
if (appResult.isError()) {
|
||||
return CommonResult.error(appResult);
|
||||
}
|
||||
PayAppDO payAppDO = payAppService.validPayApp(payTransactionCreateDTO.getAppId());
|
||||
// 插入 PayTransactionDO
|
||||
PayTransactionDO payTransaction = payTransactionMapper.selectByAppIdAndOrderId(
|
||||
payTransactionCreateDTO.getAppId(), payTransactionCreateDTO.getOrderId());
|
||||
@ -95,31 +94,28 @@ public class PayTransactionServiceImpl implements PayTransactionService {
|
||||
} else {
|
||||
payTransaction = PayTransactionConvert.INSTANCE.convert(payTransactionCreateDTO);
|
||||
payTransaction.setStatus(PayTransactionStatusEnum.WAITING.getValue())
|
||||
.setNotifyUrl(appResult.getData().getNotifyUrl());
|
||||
.setNotifyUrl(payAppDO.getNotifyUrl());
|
||||
payTransaction.setCreateTime(new Date());
|
||||
payTransactionMapper.insert(payTransaction);
|
||||
}
|
||||
// 返回成功
|
||||
return CommonResult.success(PayTransactionConvert.INSTANCE.convert(payTransaction));
|
||||
return PayTransactionConvert.INSTANCE.convert(payTransaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
public CommonResult<PayTransactionSubmitBO> submitTransaction(PayTransactionSubmitDTO payTransactionSubmitDTO) {
|
||||
public PayTransactionSubmitBO submitTransaction(PayTransactionSubmitDTO payTransactionSubmitDTO) {
|
||||
// TODO 校验支付渠道是否有效
|
||||
// 校验 App 是否有效
|
||||
CommonResult<PayAppDO> appResult = payAppService.validPayApp(payTransactionSubmitDTO.getAppId());
|
||||
if (appResult.isError()) {
|
||||
return CommonResult.error(appResult);
|
||||
}
|
||||
payAppService.validPayApp(payTransactionSubmitDTO.getAppId());
|
||||
// 获得 PayTransactionDO ,并校验其是否存在
|
||||
PayTransactionDO payTransaction = payTransactionMapper.selectByAppIdAndOrderId(
|
||||
payTransactionSubmitDTO.getAppId(), payTransactionSubmitDTO.getOrderId());
|
||||
if (payTransaction == null) { // 是否存在
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
|
||||
}
|
||||
if (!PayTransactionStatusEnum.WAITING.getValue().equals(payTransaction.getStatus())) { // 校验状态,必须是待支付
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_STATUS_IS_NOT_WAITING.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_STATUS_IS_NOT_WAITING.getCode());
|
||||
}
|
||||
// 插入 PayTransactionExtensionDO
|
||||
PayTransactionExtensionDO payTransactionExtensionDO = PayTransactionConvert.INSTANCE.convert(payTransactionSubmitDTO)
|
||||
@ -131,33 +127,32 @@ public class PayTransactionServiceImpl implements PayTransactionService {
|
||||
AbstractPaySDK paySDK = PaySDKFactory.getSDK(payTransactionSubmitDTO.getPayChannel());
|
||||
CommonResult<String> invokeResult = paySDK.submitTransaction(payTransaction, payTransactionExtensionDO, null); // TODO 暂时传入 extra = null
|
||||
if (invokeResult.isError()) {
|
||||
return CommonResult.error(invokeResult);
|
||||
throw ServiceExceptionUtil.exception(invokeResult.getCode(), invokeResult.getMessage());
|
||||
}
|
||||
// TODO 轮询三方接口,是否已经支付的任务
|
||||
// 返回成功
|
||||
PayTransactionSubmitBO payTransactionSubmitBO = new PayTransactionSubmitBO()
|
||||
.setId(payTransactionExtensionDO.getId()).setInvokeResponse(invokeResult.getData());
|
||||
return CommonResult.success(payTransactionSubmitBO);
|
||||
return new PayTransactionSubmitBO().setId(payTransactionExtensionDO.getId())
|
||||
.setInvokeResponse(invokeResult.getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult<Boolean> updateTransactionPaySuccess(Integer payChannel, String params) {
|
||||
public Boolean updateTransactionPaySuccess(Integer payChannel, String params) {
|
||||
// TODO 芋艿,记录回调日志
|
||||
// 解析传入的参数,成 TransactionSuccessBO 对象
|
||||
AbstractPaySDK paySDK = PaySDKFactory.getSDK(payChannel);
|
||||
CommonResult<TransactionSuccessBO> paySuccessResult = paySDK.parseTransactionSuccessParams(params);
|
||||
if (paySuccessResult.isError()) {
|
||||
return CommonResult.error(paySuccessResult);
|
||||
throw ServiceExceptionUtil.exception(paySuccessResult.getCode(), paySuccessResult.getMessage());
|
||||
}
|
||||
// TODO 芋艿,先最严格的校验。即使调用方重复调用,实际哪个订单已经被重复回调的支付,也返回 false 。也没问题,因为实际已经回调成功了。
|
||||
// 1.1 查询 PayTransactionExtensionDO
|
||||
PayTransactionExtensionDO extension = payTransactionExtensionMapper.selectByTransactionCode(paySuccessResult.getData().getTransactionCode());
|
||||
if (extension == null) {
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_EXTENSION_NOT_FOUND.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_EXTENSION_NOT_FOUND.getCode());
|
||||
}
|
||||
if (!PayTransactionStatusEnum.WAITING.getValue().equals(extension.getStatus())) { // 校验状态,必须是待支付
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_EXTENSION_STATUS_IS_NOT_WAITING.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_EXTENSION_STATUS_IS_NOT_WAITING.getCode());
|
||||
}
|
||||
// 1.2 更新 PayTransactionExtensionDO
|
||||
PayTransactionExtensionDO updatePayTransactionExtension = new PayTransactionExtensionDO()
|
||||
@ -172,7 +167,7 @@ public class PayTransactionServiceImpl implements PayTransactionService {
|
||||
// 2.1 判断 PayTransactionDO 是否处于待支付
|
||||
PayTransactionDO transaction = payTransactionMapper.selectById(extension.getTransactionId());
|
||||
if (transaction == null) {
|
||||
return ServiceExceptionUtil.error(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_NOT_FOUND.getCode());
|
||||
}
|
||||
if (!PayTransactionStatusEnum.WAITING.getValue().equals(transaction.getStatus())) { // 校验状态,必须是待支付
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_STATUS_IS_NOT_WAITING.getCode());
|
||||
@ -191,10 +186,10 @@ public class PayTransactionServiceImpl implements PayTransactionService {
|
||||
throw ServiceExceptionUtil.exception(PayErrorCodeEnum.PAY_TRANSACTION_STATUS_IS_NOT_WAITING.getCode());
|
||||
}
|
||||
logger.info("[updateTransactionPaySuccess][PayTransactionDO({}) 更新为已支付]", transaction.getId());
|
||||
// 3 新增 PayNotifyTaskDO
|
||||
payNotifyService.addTransactionNotifyTask(transaction, extension);
|
||||
// 3 新增 PayNotifyTaskDO 注释原因,参见 PayRefundSuccessConsumer 类。
|
||||
// payNotifyService.addTransactionNotifyTask(transaction, extension);
|
||||
// 返回结果
|
||||
return CommonResult.success(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.mall.pay.biz.service;
|
||||
|
||||
import cn.iocoder.mall.pay.api.PayRefundService;
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundSubmitDTO;
|
||||
import cn.iocoder.mall.pay.api.dto.refund.PayRefundSubmitDTO;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -1,10 +1,6 @@
|
||||
package cn.iocoder.mall.pay.biz.service;
|
||||
|
||||
import cn.iocoder.mall.pay.api.dto.PayRefundSubmitDTO;
|
||||
import org.junit.Ignore;
|
||||
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.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
|
@ -5,11 +5,10 @@ import cn.iocoder.mall.product.api.ProductCategoryService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductCategoryBO;
|
||||
import cn.iocoder.mall.product.application.convert.ProductCategoryConvert;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductCategoryVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -30,7 +29,6 @@ public class UsersProductCategoryController {
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得指定编号下的子分类的数组")
|
||||
@ApiImplicitParam(name = "pid", value = "指定分类编号", required = true, example = "0")
|
||||
@PermitAll
|
||||
public CommonResult<List<UsersProductCategoryVO>> list(@RequestParam("pid") Integer pid) {
|
||||
List<ProductCategoryBO> result = productCategoryService.getListByPid(pid);
|
||||
return CommonResult.success(ProductCategoryConvert.Users.INSTANCE.convertToVO(result));
|
||||
|
@ -7,7 +7,6 @@ import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
||||
import cn.iocoder.mall.product.application.convert.ProductSpuConvert;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductSpuDetailVO;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductSpuPageVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
@ -31,7 +30,6 @@ public class UsersProductSpuController {
|
||||
@GetMapping("/info")
|
||||
@ApiOperation("商品 SPU 明细")
|
||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||
@PermitAll
|
||||
public CommonResult<UsersProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
||||
return success(ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id)));
|
||||
}
|
||||
@ -43,7 +41,6 @@ public class UsersProductSpuController {
|
||||
@ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
|
||||
})
|
||||
@PermitAll
|
||||
@Deprecated // 使用商品搜索接口
|
||||
public CommonResult<UsersProductSpuPageVO> page(@RequestParam(value = "cid", required = false) Integer cid,
|
||||
@RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo,
|
||||
|
@ -6,7 +6,6 @@ import cn.iocoder.mall.promotion.api.BannerService;
|
||||
import cn.iocoder.mall.promotion.api.bo.BannerBO;
|
||||
import cn.iocoder.mall.promotion.application.convert.BannerConvert;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersBannerVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
@ -27,7 +26,6 @@ public class UsersBannerController {
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得所有 Banner 列表")
|
||||
@PermitAll
|
||||
public CommonResult<List<UsersBannerVO>> list() {
|
||||
// 查询 Banner 列表
|
||||
List<BannerBO> result = bannerService.getBannerListByStatus(CommonStatusEnum.ENABLE.getValue());
|
||||
|
@ -11,7 +11,6 @@ import cn.iocoder.mall.promotion.application.convert.CouponTemplateConvert;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersCouponCardPageVO;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersCouponCardVO;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersCouponTemplateVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@ -35,7 +34,6 @@ public class UsersCouponController {
|
||||
@GetMapping("/template/get")
|
||||
@ApiOperation(value = "优惠劵(码)模板信息")
|
||||
@ApiImplicitParam(name = "id", value = "优惠劵(码)模板编号", required = true, example = "10")
|
||||
@PermitAll
|
||||
public CommonResult<UsersCouponTemplateVO> templateGet(@RequestParam("id") Integer id) {
|
||||
CouponTemplateBO template = couponService.getCouponTemplate(id);
|
||||
return success(CouponTemplateConvert.USERS.convert2(template));
|
||||
|
@ -8,7 +8,6 @@ import cn.iocoder.mall.promotion.api.ProductRecommendService;
|
||||
import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
|
||||
import cn.iocoder.mall.promotion.application.convert.ProductRecommendConvert;
|
||||
import cn.iocoder.mall.promotion.application.vo.users.UsersProductRecommendVO;
|
||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import io.swagger.annotations.Api;
|
||||
@ -36,7 +35,6 @@ public class UsersProductRecommendController {
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得所有 Banner 列表")
|
||||
@PermitAll
|
||||
public CommonResult<Map<Integer, Collection<UsersProductRecommendVO>>> list() {
|
||||
// 查询商品推荐列表
|
||||
List<ProductRecommendBO> productRecommends = productRecommendService.getProductRecommendList(
|
||||
|
@ -12,11 +12,6 @@ spring:
|
||||
max-active: 5
|
||||
max-wait: 10000
|
||||
|
||||
# mybatis
|
||||
#mybatis:
|
||||
# config-location: classpath:mybatis-config.xml
|
||||
# mapper-locations: classpath:mapper/*.xml
|
||||
# type-aliases-package: cn.iocoder.mall.promotion.biz.dataobject
|
||||
# mybatis-plus
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
@ -26,7 +21,7 @@ mybatis-plus:
|
||||
id-type: auto
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
type-aliases-package: cn.iocoder.mall.promotion.biz.dataobject
|
||||
config-location: classpath:mybatis-config.xml
|
||||
|
||||
# dubbo
|
||||
dubbo:
|
||||
application:
|
||||
|
@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
|
||||
<settings>
|
||||
<!-- 使用驼峰命名法转换字段。 -->
|
||||
<setting name="mapUnderscoreToCamelCase" value="true"/>
|
||||
</settings>
|
||||
|
||||
<typeAliases>
|
||||
<typeAlias alias="Integer" type="java.lang.Integer"/>
|
||||
<typeAlias alias="Long" type="java.lang.Long"/>
|
||||
<typeAlias alias="HashMap" type="java.util.HashMap"/>
|
||||
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
|
||||
<typeAlias alias="ArrayList" type="java.util.ArrayList"/>
|
||||
<typeAlias alias="LinkedList" type="java.util.LinkedList"/>
|
||||
</typeAliases>
|
||||
|
||||
</configuration>
|
BIN
sessionStore/root.data
Normal file
BIN
sessionStore/root.data
Normal file
Binary file not shown.
@ -2,7 +2,6 @@ package cn.iocoder.mall.admin.application;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.admin"})
|
||||
@ -10,14 +9,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
||||
public class SystemApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext ctx = SpringApplication.run(SystemApplication.class, args);
|
||||
// Object bean = ctx.getBean("test");
|
||||
// System.out.println(AopUtils.getTargetClass(bean));
|
||||
|
||||
// System.out.println(bean);
|
||||
|
||||
// ConfigurableApplicationContext ctx =
|
||||
// System.out.println(); // TODO 后面去掉,这里是临时的
|
||||
SpringApplication.run(SystemApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,14 +7,12 @@ import cn.iocoder.mall.admin.api.dto.datadict.DataDictAddDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.datadict.DataDictUpdateDTO;
|
||||
import cn.iocoder.mall.admin.application.convert.DataDictConvert;
|
||||
import cn.iocoder.mall.admin.application.vo.datadict.DataDictEnumVO;
|
||||
import cn.iocoder.mall.admin.application.vo.datadict.DataDictVO;
|
||||
import cn.iocoder.mall.admin.sdk.annotation.RequiresPermissions;
|
||||
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -22,6 +20,8 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("admins/data_dict")
|
||||
@Api("数据字典模块")
|
||||
@ -33,9 +33,8 @@ public class DataDictController {
|
||||
@GetMapping("/list")
|
||||
@ApiOperation(value = "数据字典全列表")
|
||||
@RequiresPermissions("system.dataDict.list")
|
||||
public CommonResult<List<DataDictVO>> list() {
|
||||
CommonResult<List<DataDictBO>> result = dataDictService.selectDataDictList();
|
||||
return DataDictConvert.INSTANCE.convert(result);
|
||||
public CommonResult<List<DataDictBO>> list() {
|
||||
return success( dataDictService.selectDataDictList());
|
||||
}
|
||||
|
||||
@GetMapping("/tree")
|
||||
@ -43,12 +42,9 @@ public class DataDictController {
|
||||
@ApiOperation(value = "数据字典树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
|
||||
public CommonResult<List<DataDictEnumVO>> tree() {
|
||||
// 查询数据字典全列表
|
||||
CommonResult<List<DataDictBO>> result = dataDictService.selectDataDictList();
|
||||
if (result.isError()) {
|
||||
return CommonResult.error(result);
|
||||
}
|
||||
List<DataDictBO> dataDicts = dataDictService.selectDataDictList();
|
||||
// 构建基于 enumValue 聚合的 Multimap
|
||||
ImmutableListMultimap<String, DataDictBO> dataDictMap = Multimaps.index(result.getData(), DataDictBO::getEnumValue); // KEY 是 enumValue ,VALUE 是 DataDictBO 数组
|
||||
ImmutableListMultimap<String, DataDictBO> dataDictMap = Multimaps.index(dataDicts, DataDictBO::getEnumValue); // KEY 是 enumValue ,VALUE 是 DataDictBO 数组
|
||||
// 构建返回结果
|
||||
List<DataDictEnumVO> dataDictEnumVOs = new ArrayList<>(dataDictMap.size());
|
||||
dataDictMap.keys().forEach(enumValue -> {
|
||||
@ -56,53 +52,21 @@ public class DataDictController {
|
||||
.setValues(DataDictConvert.INSTANCE.convert2(dataDictMap.get(enumValue)));
|
||||
dataDictEnumVOs.add(dataDictEnumVO);
|
||||
});
|
||||
return CommonResult.success(dataDictEnumVOs);
|
||||
return success(dataDictEnumVOs);
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@RequiresPermissions("system.dataDict.add")
|
||||
@ApiOperation(value = "创建数据字典")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "enumValue", value = "大类枚举值", required = true, example = "gender"),
|
||||
@ApiImplicitParam(name = "value", value = "小类数值", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "displayName", value = "展示名", required = true, example = "男"),
|
||||
@ApiImplicitParam(name = "sort", required = true, value = "排序值", defaultValue = "10"),
|
||||
@ApiImplicitParam(name = "memo", value = "备注", example = "你猜我猜不猜"),
|
||||
})
|
||||
public CommonResult<DataDictVO> add(@RequestParam("enumValue") String enumValue,
|
||||
@RequestParam("value") String value,
|
||||
@RequestParam("displayName") String displayName,
|
||||
@RequestParam("sort") Integer sort,
|
||||
@RequestParam(value = "memo", required = false) String memo) {
|
||||
// 创建 DataDictAddDTO 对象
|
||||
DataDictAddDTO dataDictAddDTO = new DataDictAddDTO().setEnumValue(enumValue).setValue(value).setDisplayName(displayName)
|
||||
.setSort(sort).setMemo(memo);
|
||||
// 保存数据字典
|
||||
CommonResult<DataDictBO> result = dataDictService.addDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictAddDTO);
|
||||
// 返回结果
|
||||
return DataDictConvert.INSTANCE.convert2(result);
|
||||
public CommonResult<DataDictBO> add(DataDictAddDTO dataDictAddDTO) {
|
||||
return success(dataDictService.addDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictAddDTO));
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@RequiresPermissions("system.dataDict.update")
|
||||
@ApiOperation(value = "更新数据字典")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "100"),
|
||||
@ApiImplicitParam(name = "value", value = "小类数值", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "displayName", value = "展示名", required = true, example = "男"),
|
||||
@ApiImplicitParam(name = "sort", required = true, value = "排序值", defaultValue = "10"),
|
||||
@ApiImplicitParam(name = "memo", value = "备注", example = "你猜我猜不猜"),
|
||||
})
|
||||
public CommonResult<Boolean> update(@RequestParam("id") Integer id,
|
||||
@RequestParam("value") String value,
|
||||
@RequestParam("displayName") String displayName,
|
||||
@RequestParam("sort") Integer sort,
|
||||
@RequestParam(value = "memo", required = false) String memo) {
|
||||
// 创建 DataDictAddDTO 对象
|
||||
DataDictUpdateDTO dataDictUpdateDTO = new DataDictUpdateDTO().setId(id).setValue(value).setDisplayName(displayName)
|
||||
.setSort(sort).setMemo(memo);
|
||||
// 更新数据字典
|
||||
return dataDictService.updateDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictUpdateDTO);
|
||||
public CommonResult<Boolean> update(DataDictUpdateDTO dataDictUpdateDTO) {
|
||||
return success(dataDictService.updateDataDict(AdminSecurityContextHolder.getContext().getAdminId(), dataDictUpdateDTO));
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@ -110,7 +74,7 @@ public class DataDictController {
|
||||
@ApiOperation(value = "删除数据字典")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "100")
|
||||
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
|
||||
return dataDictService.deleteDataDict(AdminSecurityContextHolder.getContext().getAdminId(), id);
|
||||
return success(dataDictService.deleteDataDict(AdminSecurityContextHolder.getContext().getAdminId(), id));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
package cn.iocoder.mall.admin.application.convert;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.admin.api.bo.datadict.DataDictBO;
|
||||
import cn.iocoder.mall.admin.application.vo.datadict.DataDictVO;
|
||||
import cn.iocoder.mall.admin.application.vo.datadict.DataDictValueVO;
|
||||
import cn.iocoder.mall.admin.application.vo.datadict.DataDictEnumVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
@ -16,18 +14,6 @@ public interface DataDictConvert {
|
||||
DataDictConvert INSTANCE = Mappers.getMapper(DataDictConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
DataDictVO convert(DataDictBO dataDictBO);
|
||||
|
||||
@Mappings({})
|
||||
List<DataDictVO> convert(List<DataDictBO> dataDictBOs);
|
||||
|
||||
@Mappings({})
|
||||
CommonResult<List<DataDictVO>> convert(CommonResult<List<DataDictBO>> result);
|
||||
|
||||
@Mappings({})
|
||||
CommonResult<DataDictVO> convert2(CommonResult<DataDictBO> result);
|
||||
|
||||
@Mappings({})
|
||||
List<DataDictValueVO> convert2(List<DataDictBO> dataDictBOs);
|
||||
List<DataDictEnumVO.Value> convert2(List<DataDictBO> dataDictBOs);
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,21 @@ public class DataDictEnumVO {
|
||||
|
||||
@ApiModelProperty(value = "大类枚举值", required = true, example = "gender")
|
||||
private String enumValue;
|
||||
|
||||
@ApiModelProperty(value = "小类数值数组", required = true)
|
||||
private List<DataDictValueVO> values;
|
||||
private List<Value> values;
|
||||
|
||||
@ApiModel("数据字典枚举值 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Value {
|
||||
|
||||
@ApiModelProperty(value = "小类数值", required = true, example = "1")
|
||||
private String value;
|
||||
|
||||
@ApiModelProperty(value = "展示名", required = true, example = "男")
|
||||
private String displayName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
package cn.iocoder.mall.admin.application.vo.datadict;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel("数据字典 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DataDictVO {
|
||||
|
||||
@ApiModelProperty(value = "编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "大类枚举值", required = true, example = "gender")
|
||||
private String enumValue;
|
||||
@ApiModelProperty(value = "小类数值", required = true, example = "1")
|
||||
private String value;
|
||||
@ApiModelProperty(value = "展示名", required = true, example = "男")
|
||||
private String displayName;
|
||||
@ApiModelProperty(value = "排序值", required = true, example = "10")
|
||||
private Integer sort;
|
||||
@ApiModelProperty(value = "备注", example = "你猜")
|
||||
private String memo;
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package cn.iocoder.mall.admin.application.vo.datadict;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel("数据字典枚举值 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DataDictValueVO {
|
||||
|
||||
@ApiModelProperty(value = "小类数值", required = true, example = "1")
|
||||
private String value;
|
||||
@ApiModelProperty(value = "展示名", required = true, example = "男")
|
||||
private String displayName;
|
||||
|
||||
}
|
@ -12,7 +12,17 @@ import java.util.Set;
|
||||
@Accessors(chain = true)
|
||||
public class AdminSecurityContext {
|
||||
|
||||
/**
|
||||
* 管理员编号
|
||||
*/
|
||||
private Integer adminId;
|
||||
/**
|
||||
* 管理员账号
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 拥有的角色编号
|
||||
*/
|
||||
private Set<Integer> roleIds;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.mall.admin.sdk.interceptor;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminConstants;
|
||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Admin 演示拦截器
|
||||
*
|
||||
* 这是个比较“奇怪”的拦截器,用于演示的管理员账号,禁止使用 POST 请求,从而实现即达到阉割版的演示的效果,又避免影响了数据
|
||||
*/
|
||||
@Component
|
||||
public class AdminDemoInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
if (AdminConstants.USERNAME_DEMO.equals(AdminSecurityContextHolder.getContext().getUsername())
|
||||
&& request.getMethod().equalsIgnoreCase(HttpMethod.POST.toString())) {
|
||||
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.ADMIN_DEMO_CAN_NOT_WRITE.getCode());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -89,6 +89,7 @@ public class AdminSecurityInterceptor extends HandlerInterceptorAdapter {
|
||||
context.setAdminId(authentication.getUserId());
|
||||
MallUtil.setUserId(request, authentication.getUserId()); // 记录到 request 中,避免 AdminSecurityContext 后续清理掉后,其它地方需要用到 userId
|
||||
if (authorization != null) {
|
||||
context.setUsername(authorization.getUsername());
|
||||
context.setRoleIds(authorization.getRoleIds());
|
||||
}
|
||||
}
|
||||
@ -113,8 +114,4 @@ public class AdminSecurityInterceptor extends HandlerInterceptorAdapter {
|
||||
requiresPermissions != null ? Arrays.asList(requiresPermissions.value()) : null);
|
||||
}
|
||||
|
||||
private void checkPermission() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 提供 SDK 给其它服务,使用如下功能:
|
||||
*
|
||||
* 1. 通过 {@link cn.iocoder.mall.admin.sdk.interceptor.UserSecurityInterceptor} 拦截器,实现需要登陆 URL 的鉴权
|
||||
* 1. 通过 {@link cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor} 拦截器,实现需要登陆 URL 的鉴权
|
||||
*/
|
||||
package cn.iocoder.mall.admin.sdk;
|
||||
package cn.iocoder.mall.admin.sdk;
|
||||
|
@ -17,7 +17,7 @@ import java.util.Map;
|
||||
public interface AdminService {
|
||||
|
||||
/**
|
||||
* 用户认证。认证成功后,返回认证信息
|
||||
* 管理员认证。认证成功后,返回认证信息
|
||||
*
|
||||
* 实际上,就是用户名 + 密码登陆
|
||||
*
|
||||
|
@ -10,13 +10,13 @@ import java.util.List;
|
||||
|
||||
public interface DataDictService {
|
||||
|
||||
CommonResult<List<DataDictBO>> selectDataDictList();
|
||||
List<DataDictBO> selectDataDictList();
|
||||
|
||||
CommonResult<DataDictBO> addDataDict(Integer adminId, DataDictAddDTO dataDictAddDTO);
|
||||
DataDictBO addDataDict(Integer adminId, DataDictAddDTO dataDictAddDTO);
|
||||
|
||||
CommonResult<Boolean> updateDataDict(Integer adminId, DataDictUpdateDTO dataDictUpdateDTO);
|
||||
Boolean updateDataDict(Integer adminId, DataDictUpdateDTO dataDictUpdateDTO);
|
||||
|
||||
CommonResult<Boolean> deleteDataDict(Integer adminId, Integer dataDictId);
|
||||
Boolean deleteDataDict(Integer adminId, Integer dataDictId);
|
||||
|
||||
/**
|
||||
* 获取字典值 - 单个
|
||||
@ -28,6 +28,7 @@ public interface DataDictService {
|
||||
* @return
|
||||
*/
|
||||
CommonResult<DataDictBO> getDataDict(String dictKey, Object dictValue);
|
||||
|
||||
CommonResult<List<DataDictBO>> getDataDict(String dictKey);
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,8 @@ import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AccessTokenBO;
|
||||
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AuthenticationBO;
|
||||
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2CreateTokenDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2GetTokenDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2RefreshTokenDTO;
|
||||
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2RemoveTokenByUserDTO;
|
||||
|
||||
/**
|
||||
* Oauth2 服务接口
|
||||
@ -18,7 +20,20 @@ public interface OAuth2Service {
|
||||
*/
|
||||
OAuth2AccessTokenBO createToken(OAuth2CreateTokenDTO oauth2CreateTokenDTO);
|
||||
|
||||
// TODO @see 刷新 token
|
||||
/**
|
||||
* 基于用户移除 accessToken
|
||||
*
|
||||
* @param oauth2RemoveTokenDTO accessToken 信息
|
||||
*/
|
||||
void removeToken(OAuth2RemoveTokenByUserDTO oauth2RemoveTokenDTO);
|
||||
|
||||
/**
|
||||
* 刷新令牌,获得新的 accessToken 信息
|
||||
*
|
||||
* @param oauth2RefreshTokenDTO refreshToken 信息
|
||||
* @return accessToken 信息
|
||||
*/
|
||||
OAuth2AccessTokenBO refreshToken(OAuth2RefreshTokenDTO oauth2RefreshTokenDTO);
|
||||
|
||||
/**
|
||||
* 通过 accessToken 获得身份信息
|
||||
|
@ -0,0 +1,84 @@
|
||||
package cn.iocoder.mall.admin.api;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 短信平台
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019/5/16 6:33 PM
|
||||
*/
|
||||
public interface SmsPlatform {
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
class Result {
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 审核状态
|
||||
*/
|
||||
private Integer applyStatus;
|
||||
/**
|
||||
* 审核内容
|
||||
*/
|
||||
private String applyMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名 - 创建
|
||||
*
|
||||
* @param sign
|
||||
*/
|
||||
Result createSign(String sign);
|
||||
|
||||
/**
|
||||
* 签名 - 获取
|
||||
*
|
||||
* @param sign
|
||||
*/
|
||||
Result getSign(String sign);
|
||||
|
||||
/**
|
||||
* 签名 - 更新
|
||||
*
|
||||
* @param oldSign
|
||||
* @param sign
|
||||
*/
|
||||
Result updateSign(String oldSign, String sign);
|
||||
|
||||
/**
|
||||
* 模板 - 创建
|
||||
*
|
||||
* @param template 模板内容
|
||||
* @param tplType 1 为验证码类型,其他为 null
|
||||
*/
|
||||
Result createTemplate(String template, Integer tplType);
|
||||
|
||||
/**
|
||||
* 模板 - 获取
|
||||
*
|
||||
* @param tplId
|
||||
*/
|
||||
Result getTemplate(String tplId);
|
||||
|
||||
/**
|
||||
* 模板 - 更新
|
||||
*
|
||||
* @param tplId 选用的哪个签名
|
||||
* @param template 模板内容
|
||||
* @param tplType 1 为验证码类型,其他为 null
|
||||
*/
|
||||
Result updateTemplate(String tplId, String template, Integer tplType);
|
||||
|
||||
/**
|
||||
* 模板 - 删除
|
||||
*
|
||||
* @param tplId
|
||||
* @return
|
||||
*/
|
||||
Result deleteTemplate(String tplId);
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package cn.iocoder.mall.admin.api;
|
||||
|
||||
import cn.iocoder.mall.admin.api.bo.sms.SmsSignBO;
|
||||
import cn.iocoder.mall.admin.api.bo.sms.SmsTemplateBO;
|
||||
|
||||
/**
|
||||
* 短信服务
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019/5/16 9:54 AM
|
||||
*/
|
||||
public interface SmsService {
|
||||
|
||||
/**
|
||||
* 签名 - 创建
|
||||
*
|
||||
* @param sign
|
||||
*/
|
||||
void createSign(String sign);
|
||||
|
||||
/**
|
||||
* 签名 - 获取
|
||||
*
|
||||
* @param sign
|
||||
*/
|
||||
SmsSignBO getSign(String sign);
|
||||
|
||||
/**
|
||||
* 签名 - 更新
|
||||
*
|
||||
* @param oldSign
|
||||
* @param sign
|
||||
*/
|
||||
void updateSign(String oldSign, String sign);
|
||||
|
||||
/**
|
||||
* 模板 - 创建
|
||||
*
|
||||
* @param smsSignId 选用的哪个签名
|
||||
* @param template 模板内容
|
||||
* @param tplType 1 为验证码类型,其他为 null
|
||||
*/
|
||||
void createTemplate(Integer smsSignId, String template, Integer tplType);
|
||||
|
||||
/**
|
||||
* 模板 - 获取
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
SmsTemplateBO getTemplate(Integer id);
|
||||
|
||||
/**
|
||||
* 模板 - 更新
|
||||
*
|
||||
* @param id 模板id
|
||||
* @param template 模板内容
|
||||
* @param tplType 1 为验证码类型,其他为 null
|
||||
*/
|
||||
void updateTemplate(Integer id, String template, Integer tplType);
|
||||
|
||||
/**
|
||||
* 模板 - 删除
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void deleteTemplate(Integer id);
|
||||
}
|
@ -5,16 +5,20 @@ import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
@ApiModel("管理员授权 BO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminAuthorizationBO {
|
||||
public class AdminAuthorizationBO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "管理员编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty(value = "登陆账号", required = true, example = "1")
|
||||
private String username;
|
||||
|
||||
@ApiModelProperty(value = "角色编号数组", required = true, example = "1")
|
||||
private Set<Integer> roleIds;
|
||||
|
||||
|
@ -5,10 +5,12 @@ import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("OAUTH2 认证 BO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2AuthenticationBO {
|
||||
public class OAuth2AuthenticationBO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||
private Integer userId;
|
||||
|
@ -1,27 +0,0 @@
|
||||
package cn.iocoder.mall.admin.api.bo.oauth2;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* OAUTH2 认证 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2AuthenticationOldBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 管理员编号
|
||||
*/
|
||||
private Integer adminId;
|
||||
/**
|
||||
* 角色编号数组
|
||||
*/
|
||||
private Set<Integer> roleIds;
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package cn.iocoder.mall.admin.api.bo.sms;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 短信签名
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019/5/16 6:30 PM
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class SmsSignBO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 签名id 这个是第三方的
|
||||
*/
|
||||
private Integer signId;
|
||||
/**
|
||||
* 签名名称
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 审核状态
|
||||
*
|
||||
* - 1、审核中
|
||||
* - 2、审核成功
|
||||
* - 3、审核失败
|
||||
*/
|
||||
private Integer applyStatus;
|
||||
/**
|
||||
* 审核信息
|
||||
*/
|
||||
private String applyMessage;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.mall.admin.api.bo.sms;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 短信 template
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019/5/16 7:41 PM
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class SmsTemplateBO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 模板编号 (第三方的)
|
||||
*/
|
||||
private Integer smsSignId;
|
||||
/**
|
||||
* 短信签名 id
|
||||
*/
|
||||
private String platformId;
|
||||
/**
|
||||
* 短信模板
|
||||
*/
|
||||
private String template;
|
||||
/**
|
||||
* 审核状态
|
||||
*
|
||||
* 1、审核中
|
||||
* 2、审核成功
|
||||
* 3、审核失败
|
||||
*/
|
||||
private Integer applyStatus;
|
||||
/**
|
||||
* 审核信息
|
||||
*/
|
||||
private String applyMessage;
|
||||
}
|
@ -2,6 +2,14 @@ package cn.iocoder.mall.admin.api.constant;
|
||||
|
||||
public class AdminConstants {
|
||||
|
||||
/**
|
||||
* 账号 - 管理员
|
||||
*/
|
||||
public static final String USERNAME_ADMIN = "admin";
|
||||
|
||||
}
|
||||
/**
|
||||
* 账号 - 演示账号
|
||||
*/
|
||||
public static final String USERNAME_DEMO = "yudaoyuanma";
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,9 @@ public enum AdminErrorCodeEnum {
|
||||
OAUTH2_INVALID_TOKEN_INVALID(1002001013, "访问令牌已失效"),
|
||||
OAUTH2_NOT_LOGIN(1002001015, "账号未登陆"),
|
||||
OAUTH2_INVALID_TOKEN_ERROR_USER_TYPE(1002001016, "访问令牌用户类型不正确"),
|
||||
|
||||
OAUTH_INVALID_TOKEN(1002001020, ""), // 预留
|
||||
OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND(1002001017, "刷新令牌不存在"),
|
||||
OAUTH_INVALID_REFRESH_TOKEN_EXPIRED(1002001018, "访问令牌已过期"),
|
||||
OAUTH_INVALID_REFRESH_TOKEN_INVALID(1002001019, "刷新令牌已失效"),
|
||||
|
||||
// ========== 管理员模块 1002002000 ==========
|
||||
ADMIN_USERNAME_NOT_REGISTERED(1002002000, "账号不存在"),
|
||||
@ -30,6 +31,8 @@ public enum AdminErrorCodeEnum {
|
||||
ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE(1002002005, "管理员的账号状态不允许变更"),
|
||||
ADMIN_ASSIGN_ROLE_NOT_EXISTS(1002002006, "分配员工角色时,有角色不存在"),
|
||||
ADMIN_INVALID_PERMISSION(1002002007, "没有该操作权限"),
|
||||
ADMIN_ADMIN_CAN_NOT_UPDATE(1002002008, "管理员的账号不允许变更"),
|
||||
ADMIN_DEMO_CAN_NOT_WRITE(1002002009, "演示账号,暂不允许写操作。欢迎加入我们的交流群:http://t.cn/EKEr5WE"),
|
||||
|
||||
// ========== 资源模块 1002003000 ==========
|
||||
RESOURCE_NAME_DUPLICATE(1002003000, "已经存在该名字的资源"),
|
||||
@ -47,6 +50,12 @@ public enum AdminErrorCodeEnum {
|
||||
DATA_DICT_EXISTS(1002005000, "该数据字典已经存在"),
|
||||
DATA_DICT_NOT_EXISTS(1002005001, "该数据字典不存在"),
|
||||
|
||||
// ========== 短信模板 1002006000 ==========
|
||||
SMS_PLATFORM_FAIL(1002006000, "短信模板添加失败"),
|
||||
SMS_SIGN_NOT_EXISTENT(1002006001, "短信签名不存在"),
|
||||
SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"),
|
||||
SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"),
|
||||
SMS_TEMPLATE_IS_EXISTENT(1002006021, "短信签名不存在"),
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
@ -0,0 +1,31 @@
|
||||
package cn.iocoder.mall.admin.api.constant;
|
||||
|
||||
/**
|
||||
* 短信审核状态
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019/5/16 12:48 PM
|
||||
*/
|
||||
public enum SmsApplyStatusEnum {
|
||||
|
||||
CHECKING(1, "审核中"),
|
||||
SUCCESS(2, "审核成功"),
|
||||
FAIL(3, "审核失败"),
|
||||
;
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
|
||||
SmsApplyStatusEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.mall.admin.api.dto.datadict;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -7,36 +9,28 @@ import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 数据字典添加 DTO
|
||||
*/
|
||||
@ApiModel("数据字典添加 DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DataDictAddDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 大类枚举值
|
||||
*/
|
||||
@ApiModelProperty(value = "大类枚举值", required = true, example = "gender")
|
||||
@NotEmpty(message = "大类枚举值不能为空")
|
||||
private String enumValue;
|
||||
/**
|
||||
* 小类数值
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "小类数值", required = true, example = "1")
|
||||
@NotEmpty(message = "小类数值不能为空")
|
||||
private String value;
|
||||
/**
|
||||
* 展示名
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "展示名", required = true, example = "男")
|
||||
@NotEmpty(message = "展示名不能为空")
|
||||
private String displayName;
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
|
||||
@ApiModelProperty(required = true, value = "排序值", example = "123")
|
||||
@NotNull(message = "排序值不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "你猜我猜不猜")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.mall.admin.api.dto.datadict;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ -14,29 +15,27 @@ import java.io.Serializable;
|
||||
@Accessors(chain = true)
|
||||
public class DataDictUpdateDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@NotNull(message = "编号不能为空")
|
||||
@ApiModelProperty(value = "数据字典编号", required = true, example = "1")
|
||||
@NotNull(message = "数据字典编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 小类数值
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "大类枚举值", required = true, example = "gender")
|
||||
@NotEmpty(message = "大类枚举值不能为空")
|
||||
private String enumValue;
|
||||
|
||||
@ApiModelProperty(value = "小类数值", required = true, example = "1")
|
||||
@NotEmpty(message = "小类数值不能为空")
|
||||
private String value;
|
||||
/**
|
||||
* 展示名
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "展示名", required = true, example = "男")
|
||||
@NotEmpty(message = "展示名不能为空")
|
||||
private String displayName;
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
|
||||
@ApiModelProperty(required = true, value = "排序值", example = "123")
|
||||
@NotNull(message = "排序值不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "你猜我猜不猜")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
|
@ -8,11 +8,12 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("OAuth2 创建 Token DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2CreateTokenDTO {
|
||||
public class OAuth2CreateTokenDTO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
|
@ -9,11 +9,12 @@ import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("OAuth2 身份验证 DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2GetTokenDTO {
|
||||
public class OAuth2GetTokenDTO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "accessToken", required = true, example = "001e8f49b20e47f7b3a2de774497cd50")
|
||||
@NotEmpty(message = "accessToken 不能为空")
|
||||
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.mall.admin.api.dto.oauth2;
|
||||
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.mall.admin.api.constant.ResourceTypeEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("OAuth2 刷新 Token DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2RefreshTokenDTO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "refreshToken", required = true, example = "001e8f49b20e47f7b3a2de774497cd50")
|
||||
@NotEmpty(message = "refreshToken 不能为空")
|
||||
private String refreshToken;
|
||||
|
||||
@ApiModelProperty(value = "用户类型", required = true, example = "1", notes = "参见 ResourceTypeEnum 枚举")
|
||||
@NotNull(message = "用户类型不能为空")
|
||||
@InEnum(value = ResourceTypeEnum.class, message = "用户类型必须是 {value}")
|
||||
private Integer userType;
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package cn.iocoder.mall.admin.api.dto.oauth2;
|
||||
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.mall.admin.api.constant.ResourceTypeEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
@ApiModel("OAuth2 移除 Token DTO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2RemoveTokenByUserDTO implements Serializable {
|
||||
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Integer userId;
|
||||
|
||||
@ApiModelProperty(value = "用户类型", required = true, example = "1", notes = "参见 ResourceTypeEnum 枚举")
|
||||
@NotNull(message = "用户类型不能为空")
|
||||
@InEnum(value = ResourceTypeEnum.class, message = "用户类型必须是 {value}")
|
||||
private Integer userType;
|
||||
|
||||
}
|
@ -67,7 +67,17 @@
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunpian.sdk</groupId>
|
||||
<artifactId>yunpian-java-sdk</artifactId>
|
||||
<version>1.2.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user