| @@ -0,0 +1,16 @@ | |||||
| package com.simple.annotation; | |||||
| import java.lang.annotation.*; | |||||
| /** | |||||
| * api接口,忽略Token验证 | |||||
| * @author stormeye.wu | |||||
| * @email wuguoqiang@iformall.com | |||||
| * @date 2017-03-23 15:44 | |||||
| */ | |||||
| @Target(ElementType.METHOD) | |||||
| @Retention(RetentionPolicy.RUNTIME) | |||||
| @Documented | |||||
| public @interface AuthIgnore { | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package com.simple.annotation; | |||||
| import java.lang.annotation.ElementType; | |||||
| import java.lang.annotation.Retention; | |||||
| import java.lang.annotation.RetentionPolicy; | |||||
| import java.lang.annotation.Target; | |||||
| /** | |||||
| * 登录用户信息 | |||||
| * | |||||
| * @author stormeye.wu | |||||
| * @email wuguoqiang@iformall.com | |||||
| * @date 2017-03-23 20:39 | |||||
| */ | |||||
| @Target(ElementType.PARAMETER) | |||||
| @Retention(RetentionPolicy.RUNTIME) | |||||
| public @interface LoginUser { | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| package com.simple.config; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.web.servlet.config.annotation.CorsRegistry; | |||||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; | |||||
| /** | |||||
| * Created by Administrator on 2017/8/9. | |||||
| */ | |||||
| @Configuration | |||||
| public class CorsConfig extends WebMvcConfigurerAdapter { | |||||
| @Override | |||||
| public void addCorsMappings(CorsRegistry registry) { | |||||
| registry.addMapping("/api/**") | |||||
| .allowedOrigins("*") | |||||
| .allowCredentials(true) | |||||
| .allowedMethods("GET", "POST", "DELETE", "PUT") | |||||
| .maxAge(3600); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,49 @@ | |||||
| package com.simple.config; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import springfox.documentation.builders.ApiInfoBuilder; | |||||
| import springfox.documentation.builders.ParameterBuilder; | |||||
| import springfox.documentation.builders.PathSelectors; | |||||
| import springfox.documentation.builders.RequestHandlerSelectors; | |||||
| import springfox.documentation.schema.ModelRef; | |||||
| import springfox.documentation.service.ApiInfo; | |||||
| import springfox.documentation.service.Parameter; | |||||
| import springfox.documentation.spi.DocumentationType; | |||||
| import springfox.documentation.spring.web.plugins.Docket; | |||||
| import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| //参考:http://blog.csdn.net/catoop/article/details/50668896 | |||||
| @Configuration | |||||
| @EnableSwagger2 | |||||
| public class Swagger2Config { | |||||
| @Bean | |||||
| public Docket createRestApi() { | |||||
| ParameterBuilder tokenPar = new ParameterBuilder(); | |||||
| List<Parameter> pars = new ArrayList<Parameter>(); | |||||
| //增加一个request的header参数 | |||||
| tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); | |||||
| pars.add(tokenPar.build()); | |||||
| return new Docket(DocumentationType.SWAGGER_2) | |||||
| .apiInfo(apiInfo()) | |||||
| .select() | |||||
| .apis(RequestHandlerSelectors.basePackage("com.simple.controller")) | |||||
| .paths(PathSelectors.any()) | |||||
| .build() | |||||
| .globalOperationParameters(pars); | |||||
| } | |||||
| private ApiInfo apiInfo() { | |||||
| return new ApiInfoBuilder() | |||||
| .title("c端 api") | |||||
| .description("c api") | |||||
| .termsOfServiceUrl("http://localhost:9000") | |||||
| .version("2.0") | |||||
| .build(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,47 @@ | |||||
| package com.simple.config; | |||||
| import com.simple.interceptor.AuthorizationInterceptor; | |||||
| import com.simple.resolver.LoginUserHandlerMethodArgumentResolver; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.web.method.support.HandlerMethodArgumentResolver; | |||||
| import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | |||||
| import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | |||||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; | |||||
| import java.util.List; | |||||
| /** | |||||
| * MVC配置 | |||||
| * | |||||
| * @author stormeye.wu | |||||
| * @email wugq@mippoint.com | |||||
| * @date 2017-04-20 22:30 | |||||
| */ | |||||
| @Configuration | |||||
| public class WebMvcConfig extends WebMvcConfigurerAdapter { | |||||
| @Autowired | |||||
| private AuthorizationInterceptor authorizationInterceptor; | |||||
| @Autowired | |||||
| private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver; | |||||
| @Override | |||||
| public void addInterceptors(InterceptorRegistry registry) { | |||||
| registry.addInterceptor(authorizationInterceptor).addPathPatterns("/api/**"); | |||||
| } | |||||
| @Override | |||||
| public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { | |||||
| argumentResolvers.add(loginUserHandlerMethodArgumentResolver); | |||||
| } | |||||
| @Override | |||||
| public void addResourceHandlers(ResourceHandlerRegistry registry) { | |||||
| registry.addResourceHandler("swagger-ui.html") | |||||
| .addResourceLocations("classpath:/META-INF/resources/"); | |||||
| registry.addResourceHandler("/webjars/**") | |||||
| .addResourceLocations("classpath:/META-INF/resources/webjars/"); | |||||
| //registry.addResourceHandler("/app/**").addResourceLocations("classpath:/app/"); | |||||
| } | |||||
| } | |||||
| @@ -5,31 +5,85 @@ import java.text.ParseException; | |||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; | |||||
| import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig; | |||||
| import com.simple.domain.po.WxAppinfo; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.interceptor.AuthorizationInterceptor; | |||||
| import com.simple.service.WxAppinfoService; | |||||
| import com.simple.service.WxCUserService; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.web.bind.WebDataBinder; | import org.springframework.web.bind.WebDataBinder; | ||||
| import org.springframework.web.bind.annotation.InitBinder; | import org.springframework.web.bind.annotation.InitBinder; | ||||
| import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||
| import org.springframework.web.context.request.RequestContextHolder; | |||||
| import org.springframework.web.context.request.ServletRequestAttributes; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| @RestController | @RestController | ||||
| public class BaseController { | public class BaseController { | ||||
| @InitBinder | |||||
| public void InitBinder(WebDataBinder dataBinder) { | |||||
| dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() { | |||||
| public void setAsText(String value) { | |||||
| try { | |||||
| setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value)); | |||||
| } catch(ParseException e) { | |||||
| try { | |||||
| setValue(new SimpleDateFormat("yyyy-MM-dd ").parse(value)); | |||||
| } catch (ParseException e1) { | |||||
| setValue(null); | |||||
| } | |||||
| } | |||||
| } | |||||
| public String getAsText() { | |||||
| return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) getValue()); | |||||
| } | |||||
| }); | |||||
| } | |||||
| @Autowired | |||||
| private WxCUserService wxCUserService; | |||||
| @Autowired | |||||
| private WxAppinfoService wxAppinfoService; | |||||
| @InitBinder | |||||
| public void InitBinder(WebDataBinder dataBinder) { | |||||
| dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() { | |||||
| public void setAsText(String value) { | |||||
| try { | |||||
| setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value)); | |||||
| } catch (ParseException e) { | |||||
| try { | |||||
| setValue(new SimpleDateFormat("yyyy-MM-dd ").parse(value)); | |||||
| } catch (ParseException e1) { | |||||
| setValue(null); | |||||
| } | |||||
| } | |||||
| } | |||||
| public String getAsText() { | |||||
| return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) getValue()); | |||||
| } | |||||
| }); | |||||
| } | |||||
| public WxCUser getUser() { | |||||
| HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); | |||||
| Long cUserId = (Long) request.getAttribute(AuthorizationInterceptor.LOGIN_USER_KEY); | |||||
| WxCUser user = wxCUserService.getById(cUserId); | |||||
| return user; | |||||
| } | |||||
| public String getTenantId() { | |||||
| HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); | |||||
| Long cUserId = (Long) request.getAttribute(AuthorizationInterceptor.LOGIN_USER_KEY); | |||||
| WxCUser user = wxCUserService.getById(cUserId); | |||||
| return user.getTenantId(); | |||||
| } | |||||
| public WxAppinfo getAppInfo(String appId) { | |||||
| return wxAppinfoService.getByAppId(appId); | |||||
| } | |||||
| public WxMaService getWeappService(String appId) { | |||||
| WxAppinfo appinfo = wxAppinfoService.getByAppId(appId); | |||||
| WxMaInMemoryConfig config = new WxMaInMemoryConfig(); | |||||
| config.setAppid(appinfo.getAppId()); | |||||
| config.setSecret(appinfo.getSecret()); | |||||
| config.setToken(appinfo.getToken()); | |||||
| config.setAesKey(appinfo.getAesKey()); | |||||
| config.setMsgDataFormat(appinfo.getMsgDataFormat()); | |||||
| WxMaService service = new WxMaServiceImpl(); | |||||
| service.setWxMaConfig(config); | |||||
| return service; | |||||
| } | |||||
| } | } | ||||
| @@ -1,6 +1,8 @@ | |||||
| package com.simple.controller; | package com.simple.controller; | ||||
| import com.simple.common.ErrorCode; | import com.simple.common.ErrorCode; | ||||
| import com.simple.domain.po.WxAppinfo; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.enums.EnumPayStatus; | import com.simple.enums.EnumPayStatus; | ||||
| import com.simple.enums.EnumPayWay; | import com.simple.enums.EnumPayWay; | ||||
| import com.simple.exception.BizMessageException; | import com.simple.exception.BizMessageException; | ||||
| @@ -37,31 +39,6 @@ public class WxPayOrderController extends BaseController { | |||||
| @Autowired | @Autowired | ||||
| private WxPayOrderService wxPayOrderService; | private WxPayOrderService wxPayOrderService; | ||||
| @ApiOperation(value = "发起微信小程序支付订单") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "cUserId", value = "用户id", required = true, dataType = "Long"), | |||||
| @ApiImplicitParam(name = "orderId", value = "订单ID", required = true, dataType = "Long"), | |||||
| @ApiImplicitParam(name = "payVendor", value = "支付发起渠道:0-微信小程序", defaultValue = "0",required = false, dataType = "Integer") | |||||
| }) | |||||
| @RequestMapping(value = "/create", method = RequestMethod.POST) | |||||
| public ResultData _create(WxPayOrder record, HttpServletRequest request) throws Exception { | |||||
| // 1. get openId by cUserId | |||||
| // 2. check total fee is not null | |||||
| // 3. check body is not null | |||||
| // | |||||
| logger.info("payment wechat, order create, param : " + record.toString()); | |||||
| try { | |||||
| record.setIp(IPUtil.getIpAddr(request)); | |||||
| return wxPayOrderService.createPayOrder(record, EnumPayWay.PAY_WAY_WECHAT); | |||||
| } catch (MallinkException e) { | |||||
| logger.error("payment wechat, order create error, req 2: " + record.toString() + ", e:" + e.getMessage()); | |||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||||
| } catch (Exception e) { | |||||
| logger.error("payment wechat, order create error, req 3: " + record.toString() + ", e:" + e.getMessage()); | |||||
| } | |||||
| return new ResultData(ErrorCode.PAYORDER_ERROR.getCode(), ErrorCode.PAYORDER_ERROR.getMessage()); | |||||
| } | |||||
| /** | /** | ||||
| * | * | ||||
| * @return 接收微信异步通知 | * @return 接收微信异步通知 | ||||
| @@ -0,0 +1,69 @@ | |||||
| package com.simple.interceptor; | |||||
| import com.simple.annotation.AuthIgnore; | |||||
| import com.simple.common.ErrorCode; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.exception.MallinkException; | |||||
| import com.simple.service.WxCUserService; | |||||
| import org.apache.commons.lang.StringUtils; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Component; | |||||
| import org.springframework.web.method.HandlerMethod; | |||||
| import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| /** | |||||
| * 权限(Token)验证 | |||||
| * @author stormeye.wu | |||||
| * @email wuguoqiang@iformall.com | |||||
| * @date 2017-03-23 15:38 | |||||
| */ | |||||
| @Component | |||||
| public class AuthorizationInterceptor extends HandlerInterceptorAdapter { | |||||
| @Autowired | |||||
| private WxCUserService wxCUserService; | |||||
| public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY"; | |||||
| @Override | |||||
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |||||
| AuthIgnore annotation; | |||||
| if(handler instanceof HandlerMethod) { | |||||
| annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class); | |||||
| }else{ | |||||
| return true; | |||||
| } | |||||
| //如果有@IgnoreAuth注解,则不验证token | |||||
| if(annotation != null){ | |||||
| return true; | |||||
| } | |||||
| //从header中获取token | |||||
| String token = request.getHeader("token"); | |||||
| //如果header中不存在token,则从参数中获取token | |||||
| if(StringUtils.isBlank(token)){ | |||||
| token = request.getParameter("token"); | |||||
| } | |||||
| //token为空 | |||||
| if(StringUtils.isBlank(token)){ | |||||
| throw new MallinkException(ErrorCode.TOKEN_EMPTY); | |||||
| } | |||||
| ///// TODO use b端用户表 | |||||
| // 查询token信息 | |||||
| WxCUser wxCUser = wxCUserService.getByToken(token); | |||||
| if(wxCUser == null || wxCUser.getExpireTime().getTime() < System.currentTimeMillis()){ | |||||
| throw new MallinkException(ErrorCode.TOKEN_INVALID.getCode(), "URL:" + request.getRequestURL() + " token失效,请重新登录"); | |||||
| } | |||||
| //设置userId到request里,后续根据userId,获取用户信息 | |||||
| request.setAttribute(LOGIN_USER_KEY, wxCUser.getId()); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,46 @@ | |||||
| package com.simple.resolver; | |||||
| import com.simple.annotation.LoginUser; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.interceptor.AuthorizationInterceptor; | |||||
| import com.simple.service.WxCUserService; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.core.MethodParameter; | |||||
| import org.springframework.stereotype.Component; | |||||
| import org.springframework.web.bind.support.WebDataBinderFactory; | |||||
| import org.springframework.web.context.request.NativeWebRequest; | |||||
| import org.springframework.web.context.request.RequestAttributes; | |||||
| import org.springframework.web.method.support.HandlerMethodArgumentResolver; | |||||
| import org.springframework.web.method.support.ModelAndViewContainer; | |||||
| /** | |||||
| * 有@LoginUser注解的方法参数,注入当前登录用户 | |||||
| * @author stormeye.wu | |||||
| * @email wugq@mippoint.com | |||||
| * @date 2017-03-23 22:02 | |||||
| */ | |||||
| @Component | |||||
| public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { | |||||
| @Autowired | |||||
| private WxCUserService wxCUserService; | |||||
| @Override | |||||
| public boolean supportsParameter(MethodParameter parameter) { | |||||
| return parameter.getParameterType().isAssignableFrom(WxCUser.class) && parameter.hasParameterAnnotation(LoginUser.class); | |||||
| } | |||||
| @Override | |||||
| public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, | |||||
| NativeWebRequest request, WebDataBinderFactory factory) throws Exception { | |||||
| //获取用户ID | |||||
| Object object = request.getAttribute(AuthorizationInterceptor.LOGIN_USER_KEY, RequestAttributes.SCOPE_REQUEST); | |||||
| if(object == null){ | |||||
| return null; | |||||
| } | |||||
| //获取用户信息 | |||||
| WxCUser user = wxCUserService.getByToken((String)object); | |||||
| return user; | |||||
| } | |||||
| } | |||||
| @@ -11,15 +11,7 @@ | |||||
| <artifactId>mallinkCApi</artifactId> | <artifactId>mallinkCApi</artifactId> | ||||
| <properties> | |||||
| <weixin-java-miniapp.version>3.1.0</weixin-java-miniapp.version> | |||||
| </properties> | |||||
| <dependencies> | <dependencies> | ||||
| <dependency> | |||||
| <groupId>com.github.binarywang</groupId> | |||||
| <artifactId>weixin-java-miniapp</artifactId> | |||||
| <version>${weixin-java-miniapp.version}</version> | |||||
| </dependency> | |||||
| <dependency> | <dependency> | ||||
| <groupId>com.simple</groupId> | <groupId>com.simple</groupId> | ||||
| <artifactId>mallinkService</artifactId> | <artifactId>mallinkService</artifactId> | ||||
| @@ -5,8 +5,14 @@ import java.text.ParseException; | |||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; | |||||
| import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig; | |||||
| import com.simple.annotation.AuthIgnore; | |||||
| import com.simple.domain.po.WxAppinfo; | |||||
| import com.simple.domain.po.WxCUser; | import com.simple.domain.po.WxCUser; | ||||
| import com.simple.interceptor.AuthorizationInterceptor; | import com.simple.interceptor.AuthorizationInterceptor; | ||||
| import com.simple.service.WxAppinfoService; | |||||
| import com.simple.service.WxCUserService; | import com.simple.service.WxCUserService; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.web.bind.WebDataBinder; | import org.springframework.web.bind.WebDataBinder; | ||||
| @@ -22,6 +28,9 @@ public class BaseController { | |||||
| @Autowired | @Autowired | ||||
| private WxCUserService wxCUserService; | private WxCUserService wxCUserService; | ||||
| @Autowired | |||||
| private WxAppinfoService wxAppinfoService; | |||||
| @InitBinder | @InitBinder | ||||
| public void InitBinder(WebDataBinder dataBinder) { | public void InitBinder(WebDataBinder dataBinder) { | ||||
| dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() { | dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() { | ||||
| @@ -57,4 +66,24 @@ public class BaseController { | |||||
| WxCUser user = wxCUserService.getById(cUserId); | WxCUser user = wxCUserService.getById(cUserId); | ||||
| return user.getTenantId(); | return user.getTenantId(); | ||||
| } | } | ||||
| public WxAppinfo getAppInfo(String appId) { | |||||
| return wxAppinfoService.getByAppId(appId); | |||||
| } | |||||
| public WxMaService getWeappService(String appId) { | |||||
| WxAppinfo appinfo = wxAppinfoService.getByAppId(appId); | |||||
| WxMaInMemoryConfig config = new WxMaInMemoryConfig(); | |||||
| config.setAppid(appinfo.getAppId()); | |||||
| config.setSecret(appinfo.getSecret()); | |||||
| config.setToken(appinfo.getToken()); | |||||
| config.setAesKey(appinfo.getAesKey()); | |||||
| config.setMsgDataFormat(appinfo.getMsgDataFormat()); | |||||
| WxMaService service = new WxMaServiceImpl(); | |||||
| service.setWxMaConfig(config); | |||||
| return service; | |||||
| } | |||||
| } | } | ||||
| @@ -1,6 +1,9 @@ | |||||
| package com.simple.controller; | package com.simple.controller; | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import com.simple.common.ErrorCode; | import com.simple.common.ErrorCode; | ||||
| import com.simple.domain.po.WxAppinfo; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.enums.EnumPayStatus; | import com.simple.enums.EnumPayStatus; | ||||
| import com.simple.enums.EnumPayWay; | import com.simple.enums.EnumPayWay; | ||||
| import com.simple.exception.BizMessageException; | import com.simple.exception.BizMessageException; | ||||
| @@ -38,23 +41,24 @@ public class WxPayOrderController extends BaseController { | |||||
| @ApiOperation(value = "发起微信小程序支付订单") | @ApiOperation(value = "发起微信小程序支付订单") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @ApiImplicitParam(name = "cUserId", value = "用户id", required = true, dataType = "Long"), | |||||
| @ApiImplicitParam(name = "orderId", value = "订单ID", required = true, dataType = "Long"), | @ApiImplicitParam(name = "orderId", value = "订单ID", required = true, dataType = "Long"), | ||||
| @ApiImplicitParam(name = "payVendor", value = "支付发起渠道:0-微信小程序", defaultValue = "0",required = false, dataType = "Integer") | @ApiImplicitParam(name = "payVendor", value = "支付发起渠道:0-微信小程序", defaultValue = "0",required = false, dataType = "Integer") | ||||
| }) | }) | ||||
| @RequestMapping(value = "/create", method = RequestMethod.POST) | @RequestMapping(value = "/create", method = RequestMethod.POST) | ||||
| public ResultData _create(WxPayOrder record, HttpServletRequest request) throws Exception { | public ResultData _create(WxPayOrder record, HttpServletRequest request) throws Exception { | ||||
| logger.info("payment wechat, order create, param : " + record.toString()); | logger.info("payment wechat, order create, param : " + record.toString()); | ||||
| WxCUser user = getUser(); | |||||
| WxAppinfo appInfo = getAppInfo(user.getAppId()); | |||||
| try { | try { | ||||
| record.setIp(IPUtil.getIpAddr(request)); | record.setIp(IPUtil.getIpAddr(request)); | ||||
| return wxPayOrderService.createPayOrder(record, EnumPayWay.PAY_WAY_WECHAT); | |||||
| return wxPayOrderService.createPayOrder(appInfo, user, record, EnumPayWay.PAY_WAY_WECHAT); | |||||
| } catch (MallinkException e) { | } catch (MallinkException e) { | ||||
| logger.error("payment wechat, order create error, req 2: " + record.toString() + ", e:" + e.getMessage()); | logger.error("payment wechat, order create error, req 2: " + record.toString() + ", e:" + e.getMessage()); | ||||
| return new ResultData(e.getErrorCode(), e.getMessage()); | return new ResultData(e.getErrorCode(), e.getMessage()); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("payment wechat, order create error, req 3: " + record.toString() + ", e:" + e.getMessage()); | logger.error("payment wechat, order create error, req 3: " + record.toString() + ", e:" + e.getMessage()); | ||||
| } | } | ||||
| return new ResultData(ErrorCode.PAYORDER_ERROR.getCode(), ErrorCode.PAYORDER_ERROR.getMessage()); | |||||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -39,27 +39,9 @@ import java.util.Map; | |||||
| public class WxUserGrantController extends BaseController { | public class WxUserGrantController extends BaseController { | ||||
| private final static Logger logger = LoggerFactory.getLogger(WxUserGrantController.class); | private final static Logger logger = LoggerFactory.getLogger(WxUserGrantController.class); | ||||
| @Autowired | |||||
| private WxAppinfoService wxAppinfoService; | |||||
| @Autowired | @Autowired | ||||
| private WxCUserService wxCUserService; | private WxCUserService wxCUserService; | ||||
| private WxMaService createFromId(String appId) { | |||||
| WxAppinfo appinfo = wxAppinfoService.getByAppId(appId); | |||||
| WxMaInMemoryConfig config = new WxMaInMemoryConfig(); | |||||
| config.setAppid(appinfo.getAppId()); | |||||
| config.setSecret(appinfo.getSecret()); | |||||
| config.setToken(appinfo.getToken()); | |||||
| config.setAesKey(appinfo.getAesKey()); | |||||
| config.setMsgDataFormat(appinfo.getMsgDataFormat()); | |||||
| WxMaService service = new WxMaServiceImpl(); | |||||
| service.setWxMaConfig(config); | |||||
| return service; | |||||
| } | |||||
| /** | /** | ||||
| * 用户登录 | * 用户登录 | ||||
| * @param map | * @param map | ||||
| @@ -74,7 +56,7 @@ public class WxUserGrantController extends BaseController { | |||||
| Map resultMap = new HashMap(); | Map resultMap = new HashMap(); | ||||
| String appId = map.get("appId"); | String appId = map.get("appId"); | ||||
| WxMaService wxMaService = createFromId(appId); | |||||
| WxMaService wxMaService = getWeappService(appId); | |||||
| String code = map.get("code"); | String code = map.get("code"); | ||||
| String scene = map.get("scene"); | String scene = map.get("scene"); | ||||
| @@ -163,7 +145,7 @@ public class WxUserGrantController extends BaseController { | |||||
| WxCUser user = getUser(); | WxCUser user = getUser(); | ||||
| if (user != null) { | if (user != null) { | ||||
| WxMaService wxMaService = createFromId(user.getAppId()); | |||||
| WxMaService wxMaService = getWeappService(user.getAppId()); | |||||
| logger.debug(user.toString()); | logger.debug(user.toString()); | ||||
| String session_key = user.getSessionKey(); | String session_key = user.getSessionKey(); | ||||
| @@ -221,7 +203,7 @@ public class WxUserGrantController extends BaseController { | |||||
| WxCUser user = getUser(); | WxCUser user = getUser(); | ||||
| WxMaService wxMaService = createFromId(user.getAppId()); | |||||
| WxMaService wxMaService = getWeappService(user.getAppId()); | |||||
| String session_key = user.getSessionKey(); | String session_key = user.getSessionKey(); | ||||
| try { | try { | ||||
| @@ -87,8 +87,9 @@ public enum ErrorCode{ | |||||
| /** | /** | ||||
| * 支付 | * 支付 | ||||
| */ | */ | ||||
| PAYORDER_ERROR(12004, "支付订单异常"), | |||||
| PAYORDER_NOTIFY_CHECK_SIGN_ERROR(12005 , "验签失败"); | |||||
| PAY_ORDER_EXIST(12001, "支付订单已存在"), | |||||
| PAY_ORDER_ERROR(12004, "支付订单异常"), | |||||
| PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR(12005 , "验签失败"); | |||||
| @@ -16,7 +16,7 @@ public class WxAppinfo implements Serializable { | |||||
| protected Long id; | protected Long id; | ||||
| @Transient | @Transient | ||||
| protected List<String> ids; | |||||
| protected List<Long> ids; | |||||
| @Transient | @Transient | ||||
| protected String sortColumns; | protected String sortColumns; | ||||
| @@ -32,10 +32,11 @@ public class WxAppinfo implements Serializable { | |||||
| return sortColumns; | return sortColumns; | ||||
| } | } | ||||
| public List<String> getIds() { | |||||
| public List<Long> getIds() { | |||||
| return ids; | return ids; | ||||
| } | } | ||||
| public void setIds(List<String> ids) { | |||||
| public void setIds(List<Long> ids) { | |||||
| this.ids = ids; | this.ids = ids; | ||||
| } | } | ||||
| @@ -62,6 +63,12 @@ public class WxAppinfo implements Serializable { | |||||
| /*消息类型**/ | /*消息类型**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="消息类型",name="msgDataFormat") | @io.swagger.annotations.ApiModelProperty(value="消息类型",name="msgDataFormat") | ||||
| private String msgDataFormat; | private String msgDataFormat; | ||||
| /*微信商户ID**/ | |||||
| @io.swagger.annotations.ApiModelProperty(value="微信商户ID",name="mchId") | |||||
| private String mchId; | |||||
| /*微信支付回调**/ | |||||
| @io.swagger.annotations.ApiModelProperty(value="微信支付回调",name="notifyUrl") | |||||
| private String notifyUrl; | |||||
| /*微信访问token**/ | /*微信访问token**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="微信访问token",name="accessToken") | @io.swagger.annotations.ApiModelProperty(value="微信访问token",name="accessToken") | ||||
| private String accessToken; | private String accessToken; | ||||
| @@ -113,6 +120,18 @@ public class WxAppinfo implements Serializable { | |||||
| public void setMsgDataFormat(String _msgDataFormat) { | public void setMsgDataFormat(String _msgDataFormat) { | ||||
| msgDataFormat = _msgDataFormat; | msgDataFormat = _msgDataFormat; | ||||
| } | } | ||||
| public String getMchId() { | |||||
| return mchId; | |||||
| } | |||||
| public void setMchId(String _mchId) { | |||||
| mchId = _mchId; | |||||
| } | |||||
| public String getNotifyUrl() { | |||||
| return notifyUrl; | |||||
| } | |||||
| public void setNotifyUrl(String _notifyUrl) { | |||||
| notifyUrl = _notifyUrl; | |||||
| } | |||||
| public String getAccessToken() { | public String getAccessToken() { | ||||
| return accessToken; | return accessToken; | ||||
| } | } | ||||
| @@ -144,6 +163,8 @@ public class WxAppinfo implements Serializable { | |||||
| ,Token_ASC("`token` ASC"),Token_DESC("`token` DESC") | ,Token_ASC("`token` ASC"),Token_DESC("`token` DESC") | ||||
| ,AesKey_ASC("`aesKey` ASC"),AesKey_DESC("`aesKey` DESC") | ,AesKey_ASC("`aesKey` ASC"),AesKey_DESC("`aesKey` DESC") | ||||
| ,MsgDataFormat_ASC("`msgDataFormat` ASC"),MsgDataFormat_DESC("`msgDataFormat` DESC") | ,MsgDataFormat_ASC("`msgDataFormat` ASC"),MsgDataFormat_DESC("`msgDataFormat` DESC") | ||||
| ,MchId_ASC("`mchId` ASC"),MchId_DESC("`mchId` DESC") | |||||
| ,NotifyUrl_ASC("`notifyUrl` ASC"),NotifyUrl_DESC("`notifyUrl` DESC") | |||||
| ,AccessToken_ASC("`accessToken` ASC"),AccessToken_DESC("`accessToken` DESC") | ,AccessToken_ASC("`accessToken` ASC"),AccessToken_DESC("`accessToken` DESC") | ||||
| ,LastTokenTime_ASC("`lastTokenTime` ASC"),LastTokenTime_DESC("`lastTokenTime` DESC") | ,LastTokenTime_ASC("`lastTokenTime` ASC"),LastTokenTime_DESC("`lastTokenTime` DESC") | ||||
| ,ExpiresIn_ASC("`expiresIn` ASC"),ExpiresIn_DESC("`expiresIn` DESC") | ,ExpiresIn_ASC("`expiresIn` ASC"),ExpiresIn_DESC("`expiresIn` DESC") | ||||
| @@ -16,7 +16,7 @@ public class WxCoupon implements Serializable { | |||||
| protected Long id; | protected Long id; | ||||
| @Transient | @Transient | ||||
| protected List<String> ids; | |||||
| protected List<Long> ids; | |||||
| @Transient | @Transient | ||||
| protected String sortColumns; | protected String sortColumns; | ||||
| @@ -32,10 +32,11 @@ public class WxCoupon implements Serializable { | |||||
| return sortColumns; | return sortColumns; | ||||
| } | } | ||||
| public List<String> getIds() { | |||||
| public List<Long> getIds() { | |||||
| return ids; | return ids; | ||||
| } | } | ||||
| public void setIds(List<String> ids) { | |||||
| public void setIds(List<Long> ids) { | |||||
| this.ids = ids; | this.ids = ids; | ||||
| } | } | ||||
| @@ -61,10 +62,10 @@ public class WxCoupon implements Serializable { | |||||
| private String subTitle; | private String subTitle; | ||||
| /*售价(适用于类型2,3,4,5)**/ | /*售价(适用于类型2,3,4,5)**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="售价(适用于类型2,3,4,5)",name="salePrice") | @io.swagger.annotations.ApiModelProperty(value="售价(适用于类型2,3,4,5)",name="salePrice") | ||||
| private BigDecimal salePrice; | |||||
| private Integer salePrice; | |||||
| /*使用条件金额(适用于类型1,2,3,4)**/ | /*使用条件金额(适用于类型1,2,3,4)**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="使用条件金额(适用于类型1,2,3,4)",name="usePrice") | @io.swagger.annotations.ApiModelProperty(value="使用条件金额(适用于类型1,2,3,4)",name="usePrice") | ||||
| private BigDecimal usePrice; | |||||
| private Integer usePrice; | |||||
| /*限领张数**/ | /*限领张数**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="限领张数",name="useLimitQuantity") | @io.swagger.annotations.ApiModelProperty(value="限领张数",name="useLimitQuantity") | ||||
| private Integer useLimitQuantity; | private Integer useLimitQuantity; | ||||
| @@ -97,7 +98,7 @@ public class WxCoupon implements Serializable { | |||||
| private String detail; | private String detail; | ||||
| /*面额**/ | /*面额**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="面额",name="price") | @io.swagger.annotations.ApiModelProperty(value="面额",name="price") | ||||
| private BigDecimal price; | |||||
| private Integer price; | |||||
| /*剩余库存**/ | /*剩余库存**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="剩余库存",name="remainInventory") | @io.swagger.annotations.ApiModelProperty(value="剩余库存",name="remainInventory") | ||||
| private Integer remainInventory; | private Integer remainInventory; | ||||
| @@ -107,8 +108,8 @@ public class WxCoupon implements Serializable { | |||||
| /*购买须知**/ | /*购买须知**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="购买须知",name="remark") | @io.swagger.annotations.ApiModelProperty(value="购买须知",name="remark") | ||||
| private String remark; | private String remark; | ||||
| /*状态(0:草稿,1:待生效,2:已生效,3:已失效,4:已作废)**/ | |||||
| @io.swagger.annotations.ApiModelProperty(value="状态(0:草稿,1:待生效,2:已生效,3:已失效,4:已作废)",name="status") | |||||
| /*状态(-1:全部,0:草稿/待生效,1:已生效,2:已失效,3:已作废)**/ | |||||
| @io.swagger.annotations.ApiModelProperty(value="状态(-1:全部,0:草稿/待生效,1:已生效,2:已失效,3:已作废)",name="status") | |||||
| private Integer status; | private Integer status; | ||||
| /*创建时间**/ | /*创建时间**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createDate") | @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createDate") | ||||
| @@ -119,7 +120,6 @@ public class WxCoupon implements Serializable { | |||||
| /*业态**/ | /*业态**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value="业态",name="business") | @io.swagger.annotations.ApiModelProperty(value="业态",name="business") | ||||
| private String business; | private String business; | ||||
| public String getTenantId() { | public String getTenantId() { | ||||
| return tenantId; | return tenantId; | ||||
| } | } | ||||
| @@ -156,16 +156,16 @@ public class WxCoupon implements Serializable { | |||||
| public void setSubTitle(String _subTitle) { | public void setSubTitle(String _subTitle) { | ||||
| subTitle = _subTitle; | subTitle = _subTitle; | ||||
| } | } | ||||
| public BigDecimal getSalePrice() { | |||||
| public Integer getSalePrice() { | |||||
| return salePrice; | return salePrice; | ||||
| } | } | ||||
| public void setSalePrice(BigDecimal _salePrice) { | |||||
| public void setSalePrice(Integer _salePrice) { | |||||
| salePrice = _salePrice; | salePrice = _salePrice; | ||||
| } | } | ||||
| public BigDecimal getUsePrice() { | |||||
| public Integer getUsePrice() { | |||||
| return usePrice; | return usePrice; | ||||
| } | } | ||||
| public void setUsePrice(BigDecimal _usePrice) { | |||||
| public void setUsePrice(Integer _usePrice) { | |||||
| usePrice = _usePrice; | usePrice = _usePrice; | ||||
| } | } | ||||
| public Integer getUseLimitQuantity() { | public Integer getUseLimitQuantity() { | ||||
| @@ -228,10 +228,10 @@ public class WxCoupon implements Serializable { | |||||
| public void setDetail(String _detail) { | public void setDetail(String _detail) { | ||||
| detail = _detail; | detail = _detail; | ||||
| } | } | ||||
| public BigDecimal getPrice() { | |||||
| public Integer getPrice() { | |||||
| return price; | return price; | ||||
| } | } | ||||
| public void setPrice(BigDecimal _price) { | |||||
| public void setPrice(Integer _price) { | |||||
| price = _price; | price = _price; | ||||
| } | } | ||||
| public Integer getRemainInventory() { | public Integer getRemainInventory() { | ||||
| @@ -325,7 +325,7 @@ public class WxCoupon implements Serializable { | |||||
| } | } | ||||
| } | } | ||||
| public void setSortColumns(Field... fields) | |||||
| public void setSortColumns(WxCoupon.Field... fields) | |||||
| { | { | ||||
| if (fields == null || fields.length == 0) { | if (fields == null || fields.length == 0) { | ||||
| return; | return; | ||||
| @@ -350,7 +350,7 @@ public class WxCoupon implements Serializable { | |||||
| } | } | ||||
| if (sortColumns.contains(",")) { | if (sortColumns.contains(",")) { | ||||
| String[] cols = sortColumns.split(","); | String[] cols = sortColumns.split(","); | ||||
| List<Field> fList = new ArrayList(); | |||||
| java.util.List<Field> fList = new java.util.ArrayList(); | |||||
| for (int k = 0; k < cols.length; k++) { | for (int k = 0; k < cols.length; k++) { | ||||
| fList.add(Field.valueOf(cols[k])); | fList.add(Field.valueOf(cols[k])); | ||||
| } | } | ||||
| @@ -69,7 +69,7 @@ public class WxCouponOrder implements Serializable { | |||||
| private Date updateDate; | private Date updateDate; | ||||
| /*单券实际购买价格**/ | /*单券实际购买价格**/ | ||||
| @io.swagger.annotations.ApiModelProperty(value = "单券实际购买价格", name = "couponPrice") | @io.swagger.annotations.ApiModelProperty(value = "单券实际购买价格", name = "couponPrice") | ||||
| private BigDecimal couponPrice; | |||||
| private Integer couponPrice; | |||||
| public Long getTenantId() { | public Long getTenantId() { | ||||
| return tenantId; | return tenantId; | ||||
| @@ -143,89 +143,78 @@ public class WxCouponOrder implements Serializable { | |||||
| updateDate = _updateDate; | updateDate = _updateDate; | ||||
| } | } | ||||
| public BigDecimal getCouponPrice() { | |||||
| public Integer getCouponPrice() { | |||||
| return couponPrice; | return couponPrice; | ||||
| } | } | ||||
| public void setCouponPrice(BigDecimal _couponPrice) { | |||||
| public void setCouponPrice(Integer _couponPrice) { | |||||
| couponPrice = _couponPrice; | couponPrice = _couponPrice; | ||||
| } | } | ||||
| public static enum Field { | |||||
| CouponOrderId_ASC("`couponOrderId` ASC"), | |||||
| CouponOrderId_DESC("`couponOrderId` DESC"), | |||||
| TenantId_ASC("`tenantId` ASC"), | |||||
| TenantId_DESC("`tenantId` DESC"), | |||||
| CouponId_ASC("`couponId` ASC"), | |||||
| CouponId_DESC("`couponId` DESC"), | |||||
| CUserId_ASC("`cUserId` ASC"), | |||||
| CUserId_DESC("`cUserId` DESC"), | |||||
| BUserId_ASC("`bUserId` ASC"), | |||||
| BUserId_DESC("`bUserId` DESC"), | |||||
| OrderId_ASC("`orderId` ASC"), | |||||
| OrderId_DESC("`orderId` DESC"), | |||||
| ExpiredTime_ASC("`expiredTime` ASC"), | |||||
| ExpiredTime_DESC("`expiredTime` DESC"), | |||||
| CouponOrderStatus_ASC("`couponOrderStatus` ASC"), | |||||
| CouponOrderStatus_DESC("`couponOrderStatus` DESC"), | |||||
| CreateDate_ASC("`createDate` ASC"), | |||||
| CreateDate_DESC("`createDate` DESC"), | |||||
| UpdateDate_ASC("`updateDate` ASC"), | |||||
| UpdateDate_DESC("`updateDate` DESC"), | |||||
| CouponPrice_ASC("`couponPrice` ASC"), | |||||
| CouponPrice_DESC("`couponPrice` DESC"); | |||||
| private String value; | |||||
| Field(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| public String getValue() { | |||||
| return value; | |||||
| } | |||||
| public void setCol(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return this.getValue(); | |||||
| } | |||||
| } | |||||
| public void setSortColumns(WxCouponOrder.Field... fields) { | |||||
| if (fields == null || fields.length == 0) { | |||||
| return; | |||||
| } | |||||
| for (int k = 0; k < fields.length; k++) { | |||||
| if (fields[k] == null) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| StringBuilder sb = new StringBuilder(fields[0].toString()); | |||||
| for (int k = 1; k < fields.length; k++) { | |||||
| sb.append(","); | |||||
| sb.append(fields[k].toString()); | |||||
| } | |||||
| } | |||||
| public void setSortColumns(String sortColumns) { | |||||
| if (sortColumns == null || "".equals(sortColumns.trim())) { | |||||
| return; | |||||
| } | |||||
| if (sortColumns.contains(",")) { | |||||
| String[] cols = sortColumns.split(","); | |||||
| java.util.List<Field> fList = new java.util.ArrayList(); | |||||
| for (int k = 0; k < cols.length; k++) { | |||||
| fList.add(Field.valueOf(cols[k])); | |||||
| } | |||||
| this.setSortColumns(fList.toArray(new Field[fList.size()])); | |||||
| } else { | |||||
| this.setSortColumns(Field.valueOf(sortColumns)); | |||||
| } | |||||
| } | |||||
| public static enum Field | |||||
| { | |||||
| Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | |||||
| ,TenantId_ASC("`tenantId` ASC"),TenantId_DESC("`tenantId` DESC") | |||||
| ,CouponId_ASC("`couponId` ASC"),CouponId_DESC("`couponId` DESC") | |||||
| ,CUserId_ASC("`cUserId` ASC"),CUserId_DESC("`cUserId` DESC") | |||||
| ,BUserId_ASC("`bUserId` ASC"),BUserId_DESC("`bUserId` DESC") | |||||
| ,OrderId_ASC("`orderId` ASC"),OrderId_DESC("`orderId` DESC") | |||||
| ,ExpiredTime_ASC("`expiredTime` ASC"),ExpiredTime_DESC("`expiredTime` DESC") | |||||
| ,CouponOrderStatus_ASC("`couponOrderStatus` ASC"),CouponOrderStatus_DESC("`couponOrderStatus` DESC") | |||||
| ,CreateDate_ASC("`createDate` ASC"),CreateDate_DESC("`createDate` DESC") | |||||
| ,UpdateDate_ASC("`updateDate` ASC"),UpdateDate_DESC("`updateDate` DESC") | |||||
| ,CouponPrice_ASC("`couponPrice` ASC"),CouponPrice_DESC("`couponPrice` DESC") | |||||
| ; | |||||
| private String value; | |||||
| Field(String value){ | |||||
| this.value = value; | |||||
| } | |||||
| public String getValue() { | |||||
| return value; | |||||
| } | |||||
| public void setCol(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return this.getValue(); | |||||
| } | |||||
| } | |||||
| public void setSortColumns(WxCouponOrder.Field... fields) | |||||
| { | |||||
| if (fields == null || fields.length == 0) { | |||||
| return; | |||||
| } | |||||
| for (int k = 0; k < fields.length; k++) { | |||||
| if (fields[k] == null) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| StringBuilder sb = new StringBuilder(fields[0].toString()); | |||||
| for (int k = 1; k < fields.length; k++) { | |||||
| sb.append(","); | |||||
| sb.append(fields[k].toString()); | |||||
| } | |||||
| } | |||||
| public void setSortColumns(String sortColumns) | |||||
| { | |||||
| if (sortColumns == null || "".equals(sortColumns.trim())) { | |||||
| return; | |||||
| } | |||||
| if (sortColumns.contains(",")) { | |||||
| String[] cols = sortColumns.split(","); | |||||
| java.util.List<Field> fList = new java.util.ArrayList(); | |||||
| for (int k = 0; k < cols.length; k++) { | |||||
| fList.add(Field.valueOf(cols[k])); | |||||
| } | |||||
| this.setSortColumns(fList.toArray(new Field[fList.size()])); | |||||
| } else { | |||||
| this.setSortColumns(Field.valueOf(sortColumns)); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,48 @@ | |||||
| package com.simple.service; | |||||
| import java.util.*; | |||||
| import com.github.pagehelper.PageInfo; | |||||
| import com.simple.domain.po.WxCouponOrder; | |||||
| public interface WxCouponOrderService { | |||||
| /** | |||||
| * 根据实体查询分页列表 | |||||
| * | |||||
| * @param record | |||||
| * @param offset | |||||
| * @param limit | |||||
| * @return | |||||
| */ | |||||
| PageInfo<WxCouponOrder> listAsPage(WxCouponOrder record, Integer pageIndex, Integer pageSize); | |||||
| /** | |||||
| * 根据Id获得实体 | |||||
| * | |||||
| * @param id | |||||
| * @return | |||||
| */ | |||||
| WxCouponOrder getById(Long id); | |||||
| /** | |||||
| * 保存或更新实体 | |||||
| * | |||||
| * @param record | |||||
| */ | |||||
| void saveOrUpdate(WxCouponOrder record); | |||||
| /** | |||||
| * 根据Id删除实体 | |||||
| * | |||||
| * @param id | |||||
| */ | |||||
| void deleteById(Long id); | |||||
| } | |||||
| @@ -1,8 +1,11 @@ | |||||
| package com.simple.service; | package com.simple.service; | ||||
| import java.util.*; | import java.util.*; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.simple.common.ResultData; | import com.simple.common.ResultData; | ||||
| import com.simple.domain.po.WxAppinfo; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.domain.po.WxPayOrder; | import com.simple.domain.po.WxPayOrder; | ||||
| import com.simple.enums.EnumPayWay; | import com.simple.enums.EnumPayWay; | ||||
| @@ -14,7 +17,7 @@ public interface WxPayOrderService { | |||||
| * @param payWay | * @param payWay | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| ResultData createPayOrder(WxPayOrder record, EnumPayWay payWay); | |||||
| ResultData createPayOrder(WxAppinfo appInfo, WxCUser user, WxPayOrder record, EnumPayWay payWay); | |||||
| void handleOrderPaySuccess(WxPayOrder record, String transactionId); | void handleOrderPaySuccess(WxPayOrder record, String transactionId); | ||||
| @@ -81,7 +81,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| throw new MallinkException(ErrorCode.TOO_MANY_REQUEST); | throw new MallinkException(ErrorCode.TOO_MANY_REQUEST); | ||||
| } | } | ||||
| BigDecimal payPrice = null; | |||||
| int payPrice = 0; | |||||
| int payment = 0; | int payment = 0; | ||||
| Date curr = new Date(); | Date curr = new Date(); | ||||
| @@ -108,9 +108,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||||
| } | } | ||||
| payPrice = coupon.getSalePrice(); | payPrice = coupon.getSalePrice(); | ||||
| BigDecimal ll = coupon.getSalePrice().multiply(new BigDecimal(100)); | |||||
| payment = ll.intValue(); | |||||
| payment = coupon.getSalePrice(); | |||||
| valid_date = (coupon.getValidType() == EnumValidStatus.VALID_RANGE.getCode())?coupon.getValidEndDate(): new Date((curr.getTime()/1000+coupon.getValidDays()*24*60*60)*1000); | valid_date = (coupon.getValidType() == EnumValidStatus.VALID_RANGE.getCode())?coupon.getValidEndDate(): new Date((curr.getTime()/1000+coupon.getValidDays()*24*60*60)*1000); | ||||
| @@ -3,12 +3,15 @@ package com.simple.service.impl; | |||||
| import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
| import java.util.*; | import java.util.*; | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
| import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
| import com.github.pagehelper.PageHelper; | import com.github.pagehelper.PageHelper; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.simple.common.ErrorCode; | import com.simple.common.ErrorCode; | ||||
| import com.simple.common.ResultData; | import com.simple.common.ResultData; | ||||
| import com.simple.domain.po.WxAppinfo; | |||||
| import com.simple.domain.po.WxCUser; | |||||
| import com.simple.domain.po.WxOrder; | import com.simple.domain.po.WxOrder; | ||||
| import com.simple.domain.po.WxPayOrder; | import com.simple.domain.po.WxPayOrder; | ||||
| import com.simple.enums.EnumOrderStatus; | import com.simple.enums.EnumOrderStatus; | ||||
| @@ -46,11 +49,6 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| @Autowired | @Autowired | ||||
| WxOrderService wxOrderService; | WxOrderService wxOrderService; | ||||
| String weappId = ""; | |||||
| String wechatMchId = ""; | |||||
| String partnerKey = ""; | |||||
| String wxpayNotifyUrl = ""; | |||||
| JSONObject errorMap = JSON.parseObject("{\"NOAUTH\":{\"detail\":\"商户无此接口权限\",\"reason\":\"商户未开通此接口权限\",\"resolution\":\"请商户前往申请此接口权限\"}," + | JSONObject errorMap = JSON.parseObject("{\"NOAUTH\":{\"detail\":\"商户无此接口权限\",\"reason\":\"商户未开通此接口权限\",\"resolution\":\"请商户前往申请此接口权限\"}," + | ||||
| "\"NOTENOUGH\":{\"detail\":\"余额不足\",\"reason\":\"用户帐号余额不足\",\"resolution\":\"用户帐号余额不足,请用户充值或更换支付卡后再支付\"}," + | "\"NOTENOUGH\":{\"detail\":\"余额不足\",\"reason\":\"用户帐号余额不足\",\"resolution\":\"用户帐号余额不足,请用户充值或更换支付卡后再支付\"}," + | ||||
| "\"ORDERPAID\":{\"detail\":\"商户订单已支付\",\"reason\":\"商户订单已支付,无需重复操作\",\"resolution\":\"商户订单已支付,无需更多操作\"}," + | "\"ORDERPAID\":{\"detail\":\"商户订单已支付\",\"reason\":\"商户订单已支付,无需重复操作\",\"resolution\":\"商户订单已支付,无需更多操作\"}," + | ||||
| @@ -68,7 +66,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| "\"NOT_UTF8\":{\"detail\":\"编码格式错误\",\"reason\":\"未使用指定编码格式\",\"resolution\":\"请使用UTF-8编码格式\"}}"); | "\"NOT_UTF8\":{\"detail\":\"编码格式错误\",\"reason\":\"未使用指定编码格式\",\"resolution\":\"请使用UTF-8编码格式\"}}"); | ||||
| @Override | @Override | ||||
| public ResultData createPayOrder(WxPayOrder record, EnumPayWay payWay) { | |||||
| public ResultData createPayOrder(WxAppinfo appInfo, WxCUser user, WxPayOrder record, EnumPayWay payWay) { | |||||
| final IdWorker idworker = IdWorker.get(); | final IdWorker idworker = IdWorker.get(); | ||||
| try { | try { | ||||
| @@ -83,8 +81,12 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_PAY); | throw new MallinkException(ErrorCode.ORDER_IS_NOT_PAY); | ||||
| } | } | ||||
| // TODO body | // TODO body | ||||
| String body = ""; | |||||
| String body = "test"; | |||||
| // 2. check 是否有支付订单 | // 2. check 是否有支付订单 | ||||
| List<WxPayOrder> list = wxPayOrderMapper.findList(record); | |||||
| if (list.size() > 0) { | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_EXIST); | |||||
| } | |||||
| // 3. 创建支付订单 | // 3. 创建支付订单 | ||||
| Date currentDate = new Date(); | Date currentDate = new Date(); | ||||
| @@ -103,27 +105,25 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| int sqlRow = wxPayOrderMapper.insertSelective(record); | int sqlRow = wxPayOrderMapper.insertSelective(record); | ||||
| if(sqlRow == 1) { | if(sqlRow == 1) { | ||||
| return new ResultData(); | |||||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||||
| } | } | ||||
| /* | |||||
| { | { | ||||
| // 统一下单 | // 统一下单 | ||||
| String noncestr = Utility.generate32UUID(); | String noncestr = Utility.generate32UUID(); | ||||
| WxPayOrderP wxPayOrderP = new WxPayOrderP(); | WxPayOrderP wxPayOrderP = new WxPayOrderP(); | ||||
| wxPayOrderP.setAppid(weappId); | |||||
| wxPayOrderP.setMch_id(wechatMchId); | |||||
| wxPayOrderP.setAppid(appInfo.getAppId()); | |||||
| wxPayOrderP.setMch_id(appInfo.getMchId()); | |||||
| wxPayOrderP.setNonce_str(noncestr); | wxPayOrderP.setNonce_str(noncestr); | ||||
| wxPayOrderP.setBody(body); | wxPayOrderP.setBody(body); | ||||
| wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); | wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); | ||||
| BigDecimal llp = order.getPayment().multiply(new BigDecimal(100)); | |||||
| wxPayOrderP.setTotal_fee(llp.intValue()); | |||||
| wxPayOrderP.setTotal_fee(order.getPayment()); | |||||
| wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP | wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP | ||||
| wxPayOrderP.setNotify_url(wxpayNotifyUrl); | |||||
| wxPayOrderP.setNotify_url(appInfo.getNotifyUrl()); | |||||
| wxPayOrderP.setTrade_type(WxPay.TradeType.APP.name()); // 终端类型 | wxPayOrderP.setTrade_type(WxPay.TradeType.APP.name()); // 终端类型 | ||||
| wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID | wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID | ||||
| wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentTime)); | wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentTime)); | ||||
| wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentTime + 15 * 60)); // 15分钟结束 | wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentTime + 15 * 60)); // 15分钟结束 | ||||
| wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), partnerKey)); | |||||
| wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), appInfo.getSecret())); | |||||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); | String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); | ||||
| logger.info("pay order, wechat pushOrder, wxPayOrder:" + wxPayOrderP.toString() + ", response: " + response.toString()); | logger.info("pay order, wechat pushOrder, wxPayOrder:" + wxPayOrderP.toString() + ", response: " + response.toString()); | ||||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | Map<String, String> returnMap = WxPayment.xmlToMap(response); | ||||
| @@ -136,7 +136,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| sighMap.put("timeStamp", timestamp); | sighMap.put("timeStamp", timestamp); | ||||
| sighMap.put("nonceStr", noncestr); | sighMap.put("nonceStr", noncestr); | ||||
| sighMap.put("package", "prepay_id="+prepay_id); | sighMap.put("package", "prepay_id="+prepay_id); | ||||
| String signAgent = WxPayment.createSign(sighMap, partnerKey); | |||||
| String signAgent = WxPayment.createSign(sighMap, appInfo.getSecret()); | |||||
| returnMap.put("timeStamp", timestamp); | returnMap.put("timeStamp", timestamp); | ||||
| returnMap.put("nonceStr", noncestr); | returnMap.put("nonceStr", noncestr); | ||||
| returnMap.put("package", "prepay_id="+prepay_id); | returnMap.put("package", "prepay_id="+prepay_id); | ||||
| @@ -144,15 +144,13 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| return new ResultData(200, "创建支付订单成功", returnMap); | return new ResultData(200, "创建支付订单成功", returnMap); | ||||
| } else { | } else { | ||||
| JSONObject errObj = errorMap.getJSONObject(result_no); | JSONObject errObj = errorMap.getJSONObject(result_no); | ||||
| return new ResultData(ErrorCode.PAYORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); | |||||
| return new ResultData(ErrorCode.PAY_ORDER_ERROR.getCode(), errObj.toJSONString(), returnMap); | |||||
| } | } | ||||
| } | } | ||||
| */ | |||||
| return new ResultData(); | |||||
| } catch (RuntimeException e) { | } catch (RuntimeException e) { | ||||
| throw new MallinkException(ErrorCode.PAYORDER_ERROR); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| throw new MallinkException(ErrorCode.PAYORDER_ERROR); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -171,7 +169,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| } | } | ||||
| if (!signVerified) { | if (!signVerified) { | ||||
| logger.warn("notify order, wxpay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); | logger.warn("notify order, wxpay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); | ||||
| throw new MallinkException(ErrorCode.PAYORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| } | } | ||||
| if (!"SUCCESS".equals(paramMap.get("return_code"))) { | if (!"SUCCESS".equals(paramMap.get("return_code"))) { | ||||
| logger.warn("notify order, wxpay status not success, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); | logger.warn("notify order, wxpay status not success, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString()); | ||||
| @@ -231,7 +229,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||||
| } | } | ||||
| } catch (RuntimeException e) { | } catch (RuntimeException e) { | ||||
| logger.warn("notify order, alipay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | logger.warn("notify order, alipay checksign error, paramMap: "+paramMap.toString()+ ", payWay:" + payWay.toString() + ", e:" + e.getMessage()); | ||||
| throw new MallinkException(ErrorCode.PAYORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| throw new MallinkException(ErrorCode.PAY_ORDER_NOTIFY_CHECK_SIGN_ERROR); | |||||
| } | } | ||||
| return ""; | return ""; | ||||
| } | } | ||||
| @@ -10,13 +10,15 @@ | |||||
| <result column="token" jdbcType="VARCHAR" property="token" /> | <result column="token" jdbcType="VARCHAR" property="token" /> | ||||
| <result column="aes_key" jdbcType="VARCHAR" property="aesKey" /> | <result column="aes_key" jdbcType="VARCHAR" property="aesKey" /> | ||||
| <result column="msg_data_format" jdbcType="VARCHAR" property="msgDataFormat" /> | <result column="msg_data_format" jdbcType="VARCHAR" property="msgDataFormat" /> | ||||
| <result column="mch_id" jdbcType="VARCHAR" property="mchId" /> | |||||
| <result column="notify_url" jdbcType="VARCHAR" property="notifyUrl" /> | |||||
| <result column="access_token" jdbcType="VARCHAR" property="accessToken" /> | <result column="access_token" jdbcType="VARCHAR" property="accessToken" /> | ||||
| <result column="last_token_time" jdbcType="TIMESTAMP" property="lastTokenTime" /> | <result column="last_token_time" jdbcType="TIMESTAMP" property="lastTokenTime" /> | ||||
| <result column="expires_in" jdbcType="INTEGER" property="expiresIn" /> | <result column="expires_in" jdbcType="INTEGER" property="expiresIn" /> | ||||
| </resultMap> | </resultMap> | ||||
| <sql id="allColumns"> | <sql id="allColumns"> | ||||
| `id`,`tenant_id`,`app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in` | |||||
| `id`,`tenant_id`,`app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`mch_id`,`notify_url`,`access_token`,`last_token_time`,`expires_in` | |||||
| </sql> | </sql> | ||||
| <sql id="dynamicWhereConditions"> | <sql id="dynamicWhereConditions"> | ||||
| @@ -59,6 +61,15 @@ | |||||
| <if test=" null != msgDataFormat "> | <if test=" null != msgDataFormat "> | ||||
| and `msg_data_format` like concat('%', #{msgDataFormat},'%') | and `msg_data_format` like concat('%', #{msgDataFormat},'%') | ||||
| </if> | |||||
| <if test=" null != mchId "> | |||||
| and `mch_id` like concat('%', #{mchId},'%') | |||||
| </if> | |||||
| <if test=" null != notifyUrl "> | |||||
| and `notify_url` like concat('%', #{notifyUrl},'%') | |||||
| </if> | </if> | ||||
| @@ -9,8 +9,8 @@ | |||||
| <result column="cover_img" jdbcType="VARCHAR" property="coverImg" /> | <result column="cover_img" jdbcType="VARCHAR" property="coverImg" /> | ||||
| <result column="title" jdbcType="VARCHAR" property="title" /> | <result column="title" jdbcType="VARCHAR" property="title" /> | ||||
| <result column="sub_title" jdbcType="VARCHAR" property="subTitle" /> | <result column="sub_title" jdbcType="VARCHAR" property="subTitle" /> | ||||
| <result column="sale_price" jdbcType="DECIMAL" property="salePrice" /> | |||||
| <result column="use_price" jdbcType="DECIMAL" property="usePrice" /> | |||||
| <result column="sale_price" jdbcType="INTEGER" property="salePrice" /> | |||||
| <result column="use_price" jdbcType="INTEGER" property="usePrice" /> | |||||
| <result column="use_limit_quantity" jdbcType="INTEGER" property="useLimitQuantity" /> | <result column="use_limit_quantity" jdbcType="INTEGER" property="useLimitQuantity" /> | ||||
| <result column="target_ad" jdbcType="INTEGER" property="targetAd" /> | <result column="target_ad" jdbcType="INTEGER" property="targetAd" /> | ||||
| <result column="send_type" jdbcType="INTEGER" property="sendType" /> | <result column="send_type" jdbcType="INTEGER" property="sendType" /> | ||||
| @@ -21,7 +21,7 @@ | |||||
| <result column="valid_end_date" jdbcType="TIMESTAMP" property="validEndDate" /> | <result column="valid_end_date" jdbcType="TIMESTAMP" property="validEndDate" /> | ||||
| <result column="valid_days" jdbcType="INTEGER" property="validDays" /> | <result column="valid_days" jdbcType="INTEGER" property="validDays" /> | ||||
| <result column="detail" jdbcType="VARCHAR" property="detail" /> | <result column="detail" jdbcType="VARCHAR" property="detail" /> | ||||
| <result column="price" jdbcType="DECIMAL" property="price" /> | |||||
| <result column="price" jdbcType="INTEGER" property="price" /> | |||||
| <result column="remain_inventory" jdbcType="INTEGER" property="remainInventory" /> | <result column="remain_inventory" jdbcType="INTEGER" property="remainInventory" /> | ||||
| <result column="inventory" jdbcType="INTEGER" property="inventory" /> | <result column="inventory" jdbcType="INTEGER" property="inventory" /> | ||||
| <result column="remark" jdbcType="VARCHAR" property="remark" /> | <result column="remark" jdbcType="VARCHAR" property="remark" /> | ||||
| @@ -12,7 +12,7 @@ | |||||
| <result column="coupon_order_status" jdbcType="INTEGER" property="couponOrderStatus" /> | <result column="coupon_order_status" jdbcType="INTEGER" property="couponOrderStatus" /> | ||||
| <result column="create_date" jdbcType="TIMESTAMP" property="createDate" /> | <result column="create_date" jdbcType="TIMESTAMP" property="createDate" /> | ||||
| <result column="update_date" jdbcType="TIMESTAMP" property="updateDate" /> | <result column="update_date" jdbcType="TIMESTAMP" property="updateDate" /> | ||||
| <result column="coupon_price" jdbcType="DECIMAL" property="couponPrice" /> | |||||
| <result column="coupon_price" jdbcType="INTEGER" property="couponPrice" /> | |||||
| </resultMap> | </resultMap> | ||||
| <sql id="allColumns"> | <sql id="allColumns"> | ||||
| @@ -24,6 +24,10 @@ | |||||
| <relativePath/> | <relativePath/> | ||||
| </parent> | </parent> | ||||
| <properties> | |||||
| <weixin-java-miniapp.version>3.1.0</weixin-java-miniapp.version> | |||||
| </properties> | |||||
| <dependencies> | <dependencies> | ||||
| <dependency> | <dependency> | ||||
| <groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
| @@ -208,6 +212,12 @@ | |||||
| <version>2.8.5</version> | <version>2.8.5</version> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>com.github.binarywang</groupId> | |||||
| <artifactId>weixin-java-miniapp</artifactId> | |||||
| <version>${weixin-java-miniapp.version}</version> | |||||
| </dependency> | |||||