yshop1.8.3,H5注册新增阿里云短信功能,修复移动springsecurity 权限拦截验证问题,解决后台修改价格之后不能重复发起微信支付的问题
This commit is contained in:
2
sql/1.8.2升级1.8.3sql.txt
Normal file
2
sql/1.8.2升级1.8.3sql.txt
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `yxshop`.`yx_store_order`
|
||||
ADD COLUMN `extend_order_id` varchar(32) NULL COMMENT '额外订单号' AFTER `order_id`
|
@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
@ -33,6 +34,8 @@ public class YxStoreOrder extends BaseEntity {
|
||||
@ApiModelProperty(value = "订单号")
|
||||
private String orderId;
|
||||
|
||||
private String extendOrderId;
|
||||
|
||||
@ApiModelProperty(value = "用户id")
|
||||
private Integer uid;
|
||||
|
||||
|
@ -350,6 +350,15 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
storeOrder.setId(orderQueryVo.getId());
|
||||
storeOrder.setPayPrice(BigDecimal.valueOf(param.getPrice()));
|
||||
|
||||
//判断金额是否有变动,生成一个额外订单号去支付
|
||||
|
||||
int res = NumberUtil.compare(orderQueryVo.getPayPrice().doubleValue(),param.getPrice());
|
||||
if(res != 0){
|
||||
String orderSn = IdUtil.getSnowflake(0,0).nextIdStr();
|
||||
storeOrder.setExtendOrderId(orderSn);
|
||||
}
|
||||
|
||||
|
||||
yxStoreOrderMapper.updateById(storeOrder);
|
||||
|
||||
//增加状态
|
||||
@ -1058,6 +1067,9 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
if(ObjectUtil.isNull(wechatUser)) throw new ErrorRequestException("用户错误");
|
||||
orderRequest.setTradeType("MWEB");
|
||||
orderRequest.setBody("商品购买");
|
||||
if(StrUtil.isNotEmpty(orderInfo.getExtendOrderId())){
|
||||
orderId = orderInfo.getExtendOrderId();
|
||||
}
|
||||
orderRequest.setOutTradeNo(orderId);
|
||||
BigDecimal bigDecimal = new BigDecimal(100);
|
||||
orderRequest.setTotalFee(bigDecimal.multiply(orderInfo.getPayPrice()).intValue());//元转成分
|
||||
@ -1106,6 +1118,9 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
orderRequest.setTradeType("JSAPI");
|
||||
orderRequest.setOpenid(wechatUser.getRoutineOpenid());
|
||||
orderRequest.setBody("商品购买");
|
||||
if(StrUtil.isNotEmpty(orderInfo.getExtendOrderId())){
|
||||
orderId = orderInfo.getExtendOrderId();
|
||||
}
|
||||
orderRequest.setOutTradeNo(orderId);
|
||||
BigDecimal bigDecimal = new BigDecimal(100);
|
||||
orderRequest.setTotalFee(bigDecimal.multiply(orderInfo.getPayPrice()).intValue());//元转成分
|
||||
@ -1152,6 +1167,9 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
orderRequest.setTradeType("JSAPI");
|
||||
orderRequest.setOpenid(wechatUser.getOpenid());
|
||||
orderRequest.setBody("商品购买");
|
||||
if(StrUtil.isNotEmpty(orderInfo.getExtendOrderId())){
|
||||
orderId = orderInfo.getExtendOrderId();
|
||||
}
|
||||
orderRequest.setOutTradeNo(orderId);
|
||||
BigDecimal bigDecimal = new BigDecimal(100);
|
||||
orderRequest.setTotalFee(bigDecimal.multiply(orderInfo.getPayPrice()).intValue());//元转成分
|
||||
@ -1407,8 +1425,8 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
|
||||
|
||||
//使用MQ延时消息
|
||||
mqProducer.sendMsg("yshop-topic",storeOrder.getId().toString());
|
||||
log.info("投递延时订单id: [{}]:", storeOrder.getId());
|
||||
//mqProducer.sendMsg("yshop-topic",storeOrder.getId().toString());
|
||||
//log.info("投递延时订单id: [{}]:", storeOrder.getId());
|
||||
|
||||
return storeOrder;
|
||||
}
|
||||
@ -1499,7 +1517,8 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
|
||||
public YxStoreOrderQueryVo getOrderInfo(String unique,int uid) {
|
||||
QueryWrapper<YxStoreOrder> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("is_del",0).and(
|
||||
i->i.eq("order_id",unique).or().eq("`unique`",unique));
|
||||
i->i.eq("order_id",unique).or().eq("`unique`",unique).or()
|
||||
.eq("extend_order_id",unique));
|
||||
if(uid > 0) wrapper.eq("uid",uid);
|
||||
|
||||
return orderMap.toDto(yxStoreOrderMapper.selectOne(wrapper));
|
||||
|
@ -308,8 +308,6 @@ public class StoreOrderController extends BaseController {
|
||||
|
||||
if(storeOrder.getPaid() == 1) return ApiResult.fail("该订单已支付");
|
||||
|
||||
//todo 砍价
|
||||
//todo 拼团
|
||||
|
||||
String orderId = storeOrder.getOrderId();
|
||||
|
||||
|
@ -29,6 +29,9 @@ public class YxStoreOrderQueryVo implements Serializable {
|
||||
@ApiModelProperty(value = "订单号")
|
||||
private String orderId;
|
||||
|
||||
|
||||
private String extendOrderId;
|
||||
|
||||
@ApiModelProperty(value = "用户id")
|
||||
private Integer uid;
|
||||
|
||||
|
@ -18,14 +18,13 @@ import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author hupeng
|
||||
@ -65,15 +64,33 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
||||
// 搜寻匿名标记 url: @AnonymousAccess
|
||||
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
|
||||
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext
|
||||
.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
|
||||
|
||||
Set<String> anonymousUrls = new HashSet<>();
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
|
||||
HandlerMethod handlerMethod = infoEntry.getValue();
|
||||
RequestMappingInfo requestMappingInfo = infoEntry.getKey();
|
||||
|
||||
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
|
||||
if (null != anonymousAccess) {
|
||||
Set<String> strings = infoEntry.getKey()
|
||||
.getPatternsCondition().getPatterns();
|
||||
if(strings.size() == 1){
|
||||
String[] arr = strings.toArray((new String[0]));
|
||||
if(requestMappingInfo.getMethodsCondition().getMethods().contains(RequestMethod.GET)){
|
||||
String newUrl = arr[0]+"/**";
|
||||
List<String> list = Arrays.asList(new String[]{newUrl});
|
||||
Set<String> sSet = new HashSet<>(list);
|
||||
anonymousUrls.addAll(sSet);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
anonymousUrls.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||
}
|
||||
}
|
||||
|
||||
httpSecurity
|
||||
// 禁用 CSRF
|
||||
.csrf().disable()
|
||||
|
@ -13,7 +13,11 @@ import co.yixiang.aop.log.Log;
|
||||
import co.yixiang.common.api.ApiCode;
|
||||
import co.yixiang.common.api.ApiResult;
|
||||
import co.yixiang.exception.ErrorRequestException;
|
||||
import co.yixiang.modules.notify.NotifyService;
|
||||
import co.yixiang.modules.notify.NotifyType;
|
||||
import co.yixiang.modules.notify.SmsResult;
|
||||
import co.yixiang.modules.security.config.SecurityProperties;
|
||||
import co.yixiang.modules.security.rest.param.LoginParam;
|
||||
import co.yixiang.modules.security.rest.param.RegParam;
|
||||
import co.yixiang.modules.security.rest.param.VerityParam;
|
||||
import co.yixiang.modules.security.security.TokenProvider;
|
||||
@ -29,6 +33,9 @@ import co.yixiang.utils.OrderUtil;
|
||||
import co.yixiang.utils.RedisUtil;
|
||||
import co.yixiang.utils.RedisUtils;
|
||||
import co.yixiang.utils.SecurityUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.CommonResponse;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -49,6 +56,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.sound.midi.SoundbankResource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@ -66,6 +74,9 @@ public class AuthController {
|
||||
|
||||
@Value("${single.login:false}")
|
||||
private Boolean singleLogin;
|
||||
@Value("${yshop.notify.sms.enable}")
|
||||
private Boolean enableSms;
|
||||
|
||||
private final SecurityProperties properties;
|
||||
private final RedisUtils redisUtils;
|
||||
private final UserDetailsService userDetailsService;
|
||||
@ -77,6 +88,7 @@ public class AuthController {
|
||||
private final WxMpService wxService;
|
||||
private final YxWechatUserService wechatUserService;
|
||||
private final WxMaService wxMaService;
|
||||
private final NotifyService notifyService;
|
||||
|
||||
public AuthController(SecurityProperties properties, RedisUtils redisUtils,
|
||||
UserDetailsService userDetailsService,
|
||||
@ -84,7 +96,7 @@ public class AuthController {
|
||||
AuthenticationManagerBuilder authenticationManagerBuilder,
|
||||
YxUserService userService, PasswordEncoder passwordEncoder,
|
||||
WxMpService wxService, YxWechatUserService wechatUserService,
|
||||
WxMaService wxMaService) {
|
||||
WxMaService wxMaService,NotifyService notifyService) {
|
||||
this.properties = properties;
|
||||
this.redisUtils = redisUtils;
|
||||
this.userDetailsService = userDetailsService;
|
||||
@ -96,6 +108,7 @@ public class AuthController {
|
||||
this.wxService = wxService;
|
||||
this.wechatUserService = wechatUserService;
|
||||
this.wxMaService = wxMaService;
|
||||
this.notifyService = notifyService;
|
||||
}
|
||||
|
||||
@Log("H5用户登录")
|
||||
@ -265,14 +278,12 @@ public class AuthController {
|
||||
@AnonymousAccess
|
||||
@PostMapping("/wxapp/auth")
|
||||
@ApiOperation(value = "小程序登陆", notes = "小程序登陆")
|
||||
public ApiResult<Object> login(@RequestParam(value = "code") String code,
|
||||
@RequestParam(value = "spread") String spread,
|
||||
@RequestParam(value = "encryptedData") String encryptedData,
|
||||
@RequestParam(value = "iv") String iv,
|
||||
public ApiResult<Object> login(@Validated @RequestBody LoginParam loginParam,
|
||||
HttpServletRequest request) {
|
||||
if (StringUtils.isBlank(code)) {
|
||||
return ApiResult.fail("请传code");
|
||||
}
|
||||
String code = loginParam.getCode();
|
||||
String encryptedData = loginParam.getEncryptedData();
|
||||
String iv = loginParam.getIv();
|
||||
String spread = loginParam.getSpread();
|
||||
try {
|
||||
//读取redis配置
|
||||
String appId = RedisUtil.get("wxapp_appId");
|
||||
@ -401,15 +412,36 @@ public class AuthController {
|
||||
if (param.getType().equals("login") && ObjectUtil.isNull(yxUser)) {
|
||||
return ApiResult.fail("账号不存在");
|
||||
}
|
||||
if (ObjectUtil.isNotNull(redisUtils.get("code_" + param.getPhone()))) {
|
||||
return ApiResult.fail("10分钟内有效:" + redisUtils.get("code_" + param.getPhone()).toString());
|
||||
String codeKey = "code_" + param.getPhone();
|
||||
if (ObjectUtil.isNotNull(redisUtils.get(codeKey))) {
|
||||
if(!enableSms){
|
||||
return ApiResult.fail("10分钟内有效:" + redisUtils.get(codeKey).toString());
|
||||
}
|
||||
return ApiResult.fail("验证码10分钟内有效,请查看手机短信" );
|
||||
|
||||
}
|
||||
String code = RandomUtil.randomNumbers(6);
|
||||
redisUtils.set("code_" + param.getPhone(), code, 600L);
|
||||
if (isTest) {
|
||||
|
||||
redisUtils.set(codeKey, code, 600L);
|
||||
if (!enableSms) {
|
||||
return ApiResult.fail("测试阶段验证码:" + code);
|
||||
}
|
||||
return ApiResult.ok("发送成功");
|
||||
//发送阿里云短信
|
||||
SmsResult smsResult = notifyService.notifySmsTemplateSync(param.getPhone(),
|
||||
NotifyType.CAPTCHA,new String[]{code});
|
||||
CommonResponse commonResponse = (CommonResponse)smsResult.getResult();
|
||||
if(smsResult.isSuccessful()){
|
||||
log.info("详情:{}",commonResponse.getData());
|
||||
return ApiResult.ok("发送成功,请注意查收");
|
||||
}else{
|
||||
JSONObject jsonObject = JSON.parseObject(commonResponse.getData());
|
||||
log.info("错误详情:{}",commonResponse.getData());
|
||||
//删除redis存储
|
||||
redisUtils.del(codeKey);
|
||||
return ApiResult.ok("发送失败:"+jsonObject.getString("Message"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@AnonymousAccess
|
||||
|
@ -0,0 +1,22 @@
|
||||
package co.yixiang.modules.security.rest.param;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @ClassName LoginParam
|
||||
* @Author hupeng <610796224@qq.com>
|
||||
* @Date 2020/02/15
|
||||
**/
|
||||
@Data
|
||||
public class LoginParam {
|
||||
@NotBlank(message = "code参数缺失")
|
||||
private String code;
|
||||
|
||||
private String spread;
|
||||
|
||||
private String encryptedData;
|
||||
|
||||
private String iv;
|
||||
}
|
@ -112,7 +112,7 @@ public class WechatController extends BaseController {
|
||||
return WxPayNotifyResponse.success("处理成功!");
|
||||
}
|
||||
|
||||
orderService.paySuccess(orderId,"weixin");
|
||||
orderService.paySuccess(orderInfo.getOrderId(),"weixin");
|
||||
|
||||
return WxPayNotifyResponse.success("处理成功!");
|
||||
} catch (WxPayException e) {
|
||||
|
@ -81,38 +81,5 @@ file:
|
||||
maxSize: 100
|
||||
avatarMaxSize: 5
|
||||
localUrl: http://localhost:8009/api
|
||||
yshop:
|
||||
#通知相关配置
|
||||
notify:
|
||||
|
||||
# 短消息模版通知配置
|
||||
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
sms:
|
||||
enable: false
|
||||
# 如果是腾讯云短信,则设置active的值tencent
|
||||
# 如果是阿里云短信,则设置active的值aliyun
|
||||
active: tencent
|
||||
sign: yshop
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: 156349
|
||||
- name: captcha
|
||||
templateId: 156433
|
||||
- name: ship
|
||||
templateId: 158002
|
||||
- name: refund
|
||||
templateId: 159447
|
||||
tencent:
|
||||
appid: 111111111
|
||||
appkey: xxxxxxxxxxxxxx
|
||||
aliyun:
|
||||
regionId: xxx
|
||||
accessKeyId: xxx
|
||||
accessKeySecret: xxx
|
||||
|
||||
|
||||
# 快鸟物流查询配置
|
||||
express:
|
||||
enable: true
|
||||
appId:
|
||||
appKey:
|
||||
|
@ -81,7 +81,7 @@ swagger:
|
||||
enabled: true
|
||||
title: yshop商城移动端API
|
||||
serverUrl: http://localhost:8009
|
||||
version: 1.7
|
||||
version: 1.8
|
||||
|
||||
# 文件存储路径
|
||||
file:
|
||||
@ -92,37 +92,4 @@ file:
|
||||
avatarMaxSize: 5
|
||||
localUrl:
|
||||
|
||||
yshop:
|
||||
#通知相关配置
|
||||
notify:
|
||||
# 短消息模版通知配置
|
||||
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
sms:
|
||||
enable: false
|
||||
# 如果是腾讯云短信,则设置active的值tencent
|
||||
# 如果是阿里云短信,则设置active的值aliyun
|
||||
active: tencent
|
||||
sign: yshop
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: 156349
|
||||
- name: captcha
|
||||
templateId: 156433
|
||||
- name: ship
|
||||
templateId: 158002
|
||||
- name: refund
|
||||
templateId: 159447
|
||||
tencent:
|
||||
appid: 111111111
|
||||
appkey: xxxxxxxxxxxxxx
|
||||
aliyun:
|
||||
regionId: xxx
|
||||
accessKeyId: xxx
|
||||
accessKeySecret: xxx
|
||||
|
||||
|
||||
# 快鸟物流查询配置
|
||||
express:
|
||||
enable: true
|
||||
appId: 1607734
|
||||
appKey: 81f43a2e-f504-45c4-9b54-2637d59f8190
|
||||
|
@ -74,3 +74,38 @@ logging:
|
||||
smms:
|
||||
token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlyl
|
||||
|
||||
yshop:
|
||||
#通知相关配置
|
||||
notify:
|
||||
# 短消息模版通知配置
|
||||
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
|
||||
sms:
|
||||
enable: false
|
||||
# 如果是腾讯云短信,则设置active的值tencent
|
||||
# 如果是阿里云短信,则设置active的值aliyun
|
||||
active: aliyun
|
||||
sign: yshop
|
||||
template:
|
||||
- name: paySucceed
|
||||
templateId: 156349
|
||||
- name: captcha
|
||||
templateId: SMS_182680588
|
||||
- name: ship
|
||||
templateId: 158002
|
||||
- name: refund
|
||||
templateId: 159447
|
||||
tencent:
|
||||
appid: 111111111
|
||||
appkey: xxxxxxxxxxxxxx
|
||||
aliyun:
|
||||
regionId: cn-hangzhou
|
||||
accessKeyId:
|
||||
accessKeySecret:
|
||||
|
||||
|
||||
# 快鸟物流查询配置
|
||||
express:
|
||||
enable: true
|
||||
appId: 1607734
|
||||
appKey: 81f43a2e-f504-45c4-9b54-2637d59f8190
|
||||
|
||||
|
@ -27,6 +27,11 @@ public class YxStoreOrder implements Serializable {
|
||||
@Column(name = "order_id",nullable = false)
|
||||
private String orderId;
|
||||
|
||||
// 订单号
|
||||
@Column(name = "extend_order_id",nullable = true)
|
||||
private String extendOrderId;
|
||||
|
||||
|
||||
// 用户id
|
||||
@Column(name = "uid",nullable = false)
|
||||
private Integer uid;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package co.yixiang.modules.shop.rest;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.aop.log.Log;
|
||||
@ -10,6 +12,7 @@ import co.yixiang.modules.shop.service.YxExpressService;
|
||||
import co.yixiang.modules.shop.service.YxStoreOrderService;
|
||||
import co.yixiang.modules.shop.service.YxStoreOrderStatusService;
|
||||
import co.yixiang.modules.shop.service.dto.YxExpressDTO;
|
||||
import co.yixiang.modules.shop.service.dto.YxStoreOrderDTO;
|
||||
import co.yixiang.modules.shop.service.dto.YxStoreOrderQueryCriteria;
|
||||
import co.yixiang.modules.wechat.service.YxWechatUserService;
|
||||
import co.yixiang.modules.wechat.service.dto.YxWechatUserDTO;
|
||||
@ -236,6 +239,17 @@ public class YxStoreOrderController {
|
||||
public ResponseEntity editOrder(@RequestBody YxStoreOrder resources){
|
||||
if(ObjectUtil.isNull(resources.getPayPrice())) throw new BadRequestException("请输入支付金额");
|
||||
if(resources.getPayPrice().doubleValue() < 0) throw new BadRequestException("金额不能低于0");
|
||||
|
||||
YxStoreOrderDTO storeOrder = yxStoreOrderService.findById(resources.getId());
|
||||
//判断金额是否有变动,生成一个额外订单号去支付
|
||||
|
||||
int res = NumberUtil.compare(storeOrder.getPayPrice().doubleValue(),resources.getPayPrice().doubleValue());
|
||||
if(res != 0){
|
||||
String orderSn = IdUtil.getSnowflake(0,0).nextIdStr();
|
||||
resources.setExtendOrderId(orderSn);
|
||||
}
|
||||
|
||||
|
||||
yxStoreOrderService.update(resources);
|
||||
|
||||
YxStoreOrderStatus storeOrderStatus = new YxStoreOrderStatus();
|
||||
|
Reference in New Issue
Block a user