diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..afa4cd3 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Zeppelin 忽略的文件 +/ZeppelinRemoteNotebooks/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..c9e76b9 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..7e9cd36 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..132404b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/video-member.iml b/.idea/video-member.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/video-member.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ddafe38 --- /dev/null +++ b/pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + com.cyjd.rights + parent + 0.0.1 + pom + + rights-server + rights-admin-controller + rights-client-controller + rights-interface + rights-entity + + + rights + rights + + + 8 + 8 + UTF-8 + + + org.springframework.boot + spring-boot-starter-parent + 2.5.6 + + + + + org.apache.logging.log4j + log4j-to-slf4j + 2.10.0 + + + org.slf4j + jul-to-slf4j + 1.7.25 + + + org.projectlombok + lombok + 1.16.22 + + + + org.springframework.boot + spring-boot-starter-web-services + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.alibaba + fastjson + 1.2.83 + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + com.squareup.okhttp3 + okhttp + 3.14.9 + + + commons-httpclient + commons-httpclient + 3.1 + + + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + com.baomidou + mybatis-plus-boot-starter + 3.0.5 + + + + + + + + mysql + mysql-connector-java + 8.0.11 + + + + com.alipay.sdk + alipay-sdk-java + 4.35.132.ALL + + + + org.apache.commons + commons-lang3 + 3.7 + + + + com.google.code.gson + gson + 2.8.8 + + + + + cn.hutool + hutool-all + 5.3.3 + + + + org.springframework.boot + spring-boot-starter-validation + + + + + + \ No newline at end of file diff --git a/rights-admin-controller/.gitignore b/rights-admin-controller/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/rights-admin-controller/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/rights-admin-controller/pom.xml b/rights-admin-controller/pom.xml new file mode 100644 index 0000000..1154f6c --- /dev/null +++ b/rights-admin-controller/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + com.cyjd.rights + parent + 0.0.1 + + + rights-admin-controller + jar + + + 8 + 8 + UTF-8 + + + + + com.cyjd.rights + rights-interface + 0.0.1 + + + com.cyjd.rights + rights-server + 0.0.1 + + + org.junit.jupiter + junit-jupiter + RELEASE + compile + + + org.mockito + mockito-core + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/rights-admin-controller/src/main/java/com/cyjd/rights/AdminApiApplication.java b/rights-admin-controller/src/main/java/com/cyjd/rights/AdminApiApplication.java new file mode 100644 index 0000000..92c8754 --- /dev/null +++ b/rights-admin-controller/src/main/java/com/cyjd/rights/AdminApiApplication.java @@ -0,0 +1,20 @@ +package com.cyjd.rights; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +import java.util.TimeZone; + +@SpringBootApplication(exclude = TransactionAutoConfiguration.class) +@EnableScheduling +@EnableAsync +public class AdminApiApplication { + public static void main(String[] args) + { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); + SpringApplication.run(AdminApiApplication.class, args); + } +} diff --git a/rights-client-controller/.gitignore b/rights-client-controller/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/rights-client-controller/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/rights-client-controller/pom.xml b/rights-client-controller/pom.xml new file mode 100644 index 0000000..69fed8e --- /dev/null +++ b/rights-client-controller/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + com.cyjd.rights + parent + 0.0.1 + + + rights-client-controller + + + 8 + 8 + UTF-8 + + jar + + + + com.cyjd.rights + rights-interface + 0.0.1 + + + com.cyjd.rights + rights-server + 0.0.1 + + + cn.hutool + hutool-all + 5.4.1 + + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.httpcomponents + httpclient + 4.5.2 + + + + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + \ No newline at end of file diff --git a/rights-client-controller/src/main/java/com/cyjd/rights/ClientApiApplication.java b/rights-client-controller/src/main/java/com/cyjd/rights/ClientApiApplication.java new file mode 100644 index 0000000..ace1c07 --- /dev/null +++ b/rights-client-controller/src/main/java/com/cyjd/rights/ClientApiApplication.java @@ -0,0 +1,25 @@ +package com.cyjd.rights; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +import java.util.TimeZone; + +@SpringBootApplication +@EnableScheduling +@EnableAsync +@ServletComponentScan +@MapperScan(basePackages = {"com.cyjd.rights.business.mapper"}) +public class ClientApiApplication { + public static void main(String[] args) + { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); + SpringApplication.run(ClientApiApplication.class, args); + System.out.println("=========加载完毕========"); + } +} diff --git a/rights-client-controller/src/main/java/com/cyjd/rights/config/SwaggerConfig.java b/rights-client-controller/src/main/java/com/cyjd/rights/config/SwaggerConfig.java new file mode 100644 index 0000000..4393d5a --- /dev/null +++ b/rights-client-controller/src/main/java/com/cyjd/rights/config/SwaggerConfig.java @@ -0,0 +1,9 @@ +package com.cyjd.rights.config; + +import org.springframework.context.annotation.Configuration; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { +} diff --git a/rights-client-controller/src/main/java/com/cyjd/rights/config/WebMvcConfig.java b/rights-client-controller/src/main/java/com/cyjd/rights/config/WebMvcConfig.java new file mode 100644 index 0000000..557d325 --- /dev/null +++ b/rights-client-controller/src/main/java/com/cyjd/rights/config/WebMvcConfig.java @@ -0,0 +1,34 @@ +package com.cyjd.rights.config; + +import com.cyjd.rights.handle.IpRoleAuthorizationInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * MVC配置 + * + * @author yz + */ +@Configuration +public class WebMvcConfig implements WebMvcConfigurer +{ + + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOriginPatterns("*") // 允许所有来源 + .allowCredentials(true) + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("Header-1"); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new IpRoleAuthorizationInterceptor()); + } + +} diff --git a/rights-client-controller/src/main/java/com/cyjd/rights/controller/AliPayController.java b/rights-client-controller/src/main/java/com/cyjd/rights/controller/AliPayController.java new file mode 100644 index 0000000..2f22cd1 --- /dev/null +++ b/rights-client-controller/src/main/java/com/cyjd/rights/controller/AliPayController.java @@ -0,0 +1,505 @@ +package com.cyjd.rights.controller; + +import com.alibaba.fastjson.JSON; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayConstants; +import com.alipay.api.CertAlipayRequest; +import com.alipay.api.internal.util.AlipaySignature; +import com.alipay.api.response.AlipayTradePayResponse; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.cyjd.rights.beans.AliPayProperties; +import com.cyjd.rights.beans.R; +import com.cyjd.rights.business.service.AliPayOrderService; +import com.cyjd.rights.business.service.AliPayService; +import com.cyjd.rights.business.service.AliPaySigningOrderService; +import com.cyjd.rights.constant.AliPayConstant; +import com.cyjd.rights.constant.EnumPeriodType; +import com.cyjd.rights.dto.AliPayInOrderByAgreementDto; +import com.cyjd.rights.dto.AliPaySignUpDto; +import com.cyjd.rights.entity.AliPayOrderEntity; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; +import com.cyjd.rights.result.FResult; +import com.cyjd.rights.utils.EntityConvertUtil; +import com.cyjd.rights.utils.OrderUtil; +import com.cyjd.rights.vo.AliPayInOrderByAgreementReq; +import com.cyjd.rights.vo.AliPayQueryPageSignReq; +import com.cyjd.rights.vo.AliPayTradeQueryReq; +import com.cyjd.rights.vo.AliPayUserPageSignReq; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.java.Log; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@Log +@Component +@Api(tags = "阿里支付测试") +@RestController +@RequestMapping("/alipay") +public class AliPayController { + + + @Autowired + private AliPayService aliPayService; + + @Autowired + private AliPayOrderService aliPayOrderService; + + @Autowired + private AliPaySigningOrderService aliPaySigningOrderService; + /** + * 支付配置 + */ + @Resource + private AliPayProperties aliPayProperties; + + + private CertAlipayRequest certAlipayRequest; + + private static String[] unicom = {"130", "131", "132", "140", "155", "156", "185", "186", "145", "171", "176", "175", "166"}; + private static String[] mobileArray = {"134", "135", "136", "137", "138", "139", "147", "150", "151", "152", "157", "158", "159", "178", "182", "183", "184", "187", "188", "195", "198"}; + private static String[] tel = {"133", "153", "177", "180", "181", "189", "173", "149", "199"}; + + + @PostConstruct + public void init() { + CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); + //设置文件地址 +// if (isSkipSign) { +// aliPayProperties.setCertPath("D:\\daima\\hy\\ringback-q\\02Ypcl\\01Code\\01Plantform\\Server\\vrbt-client-controller\\src\\main\\resources\\config\\"); +// } else { +// aliPayProperties.setCertPath("/home/ypcl/server-client/config/"); +// } + certAlipayRequest.setServerUrl(AliPayConstant.serverUrl); + certAlipayRequest.setAppId(aliPayProperties.getAppId()); + certAlipayRequest.setPrivateKey(aliPayProperties.getPrivateKey()); + certAlipayRequest.setFormat(AlipayConstants.FORMAT_JSON); + certAlipayRequest.setCharset(AlipayConstants.CHARSET_UTF8); + certAlipayRequest.setSignType(AlipayConstants.SIGN_TYPE_RSA2); + certAlipayRequest.setCertPath(aliPayProperties.getCertPath() + "appCertPublicKey_" + aliPayProperties.getAppId() + ".crt"); + certAlipayRequest.setAlipayPublicCertPath(aliPayProperties.getCertPath() + "alipayCertPublicKey_RSA2.crt"); + certAlipayRequest.setRootCertPath(aliPayProperties.getCertPath() + "alipayRootCert.crt"); + this.certAlipayRequest = certAlipayRequest; + } + + + @ApiOperation(value = "支付宝签约", notes = "前端先调用此接口,由服务端请求支付宝组装scheme地址,之后前端通过该地址唤起支付宝进行签约") + @PostMapping("/signUp") + public R signUp(@RequestBody AliPaySignUpDto signUpDto) { + String price="0.1"; + //查询数据库用户签约记录 + + AliPayUserPageSignReq signReq = new AliPayUserPageSignReq(); + signUpDto.setIsPage(true); + signUpDto.setPeriod("31"); //设置天数 + signUpDto.setSingleAmount(price); //设置金额 + signReq.setBusinessType(2); + signReq.setType(0); + String agreementNo = OrderUtil.getAgreementNo(); + int i = checkFrom(signUpDto.getMobile()); + //如果未签约,调用支付宝接口获取支付宝签约跳转地址 + signReq.setExternalAgreementNo(agreementNo); + signReq.setIsPage(signUpDto.getIsPage()); + AliPayUserPageSignReq.PeriodRuleParams periodRuleParams = new AliPayUserPageSignReq.PeriodRuleParams(); + periodRuleParams.setPeriod(signUpDto.getPeriod()); + periodRuleParams.setPeriodType(EnumPeriodType.DAY); + periodRuleParams.setSingleAmount(signUpDto.getSingleAmount()); + signReq.setPeriodRuleParams(periodRuleParams); + //aliPayUserPageSignReq.setSignScene("INDUSTRY|DIGITAL_MEDIA"); + String signUrl = aliPayService.signUp(signReq); + //保存签约订单 + AliPaySigningOrderEntity aliPaySigningOrderEntity = new AliPaySigningOrderEntity(); + aliPaySigningOrderEntity.setOrderId(agreementNo); + aliPaySigningOrderEntity.setOrderTime(LocalDateTime.now()); + aliPaySigningOrderEntity.setMobile(signUpDto.getMobile()); + aliPaySigningOrderEntity.setLinkId(signUpDto.getLinkId()); + aliPaySigningOrderEntity.setLinkName("推广名字"); //先定死 + aliPaySigningOrderEntity.setOperatorsId(1); //先定死可能不要这个参数 + aliPaySigningOrderEntity.setIsPage(signUpDto.getIsPage()?1:0); + aliPaySigningOrderEntity.setOrderName("优爱腾三方权益业务"); + aliPaySigningOrderEntity.setPrice(price); + aliPaySigningOrderEntity.setBusinessType(1); + if (StringUtils.isBlank(signUrl)) { + aliPaySigningOrderEntity.setStatus(0); + aliPaySigningOrderService.save(aliPaySigningOrderEntity); + return R.error("签约失败,请重试"); + } + aliPaySigningOrderEntity.setStatus(2); + aliPaySigningOrderEntity.setOpenAddress(signUrl); + aliPaySigningOrderService.save(aliPaySigningOrderEntity); + return R.ok().put("result", signUrl).put("signOrderId", agreementNo); + + } + + @ApiOperation(value = "支付宝签约状态查询", notes = "签约成功以后前端可调用此接口查询是否签约成功") + @PostMapping("/querySign") + public FResult querySign(@RequestParam String externalAgreementNo) { + AliPayQueryPageSignReq aliPayQueryPageSignReq = new AliPayQueryPageSignReq(); + aliPayQueryPageSignReq.setExternalAgreementNo(externalAgreementNo); + boolean querySign = aliPayService.querySign(aliPayQueryPageSignReq); + return FResult.ok(querySign); + } + + @ApiOperation(value = "支付宝支付状态查询", notes = "代扣以后可调用此接口查询是否成功") + @PostMapping("/queryOrder") + public FResult queryOrder(@RequestParam String outTradeNo) { + AliPayTradeQueryReq aliPayTradeQueryReq = new AliPayTradeQueryReq(); + aliPayTradeQueryReq.setOutTradeNo(outTradeNo); + boolean queryOrder = aliPayService.queryOrder(aliPayTradeQueryReq); + return FResult.ok(queryOrder); + } + +// @ApiOperation(value = "支付宝代扣", notes = "签约完成以后,通过支付宝签约号进行代扣操作,签约号需要在签约回调中获取并保存到数据库中,之后通过定时任务轮询扫描数据库进行代扣") +// @PostMapping("/agreementPay") +// public FResult agreementPay(@RequestBody AliPayInOrderByAgreementDto inOrderByAgreementDto) { +// //AliPayEntity aliPayEntity = aliPayService.getOne(new QueryWrapper().eq("mobile", inOrderByAgreementDto.getMobile()).eq("type", 1).eq("status", 1).orderByDesc("order_time")); +// inOrderByAgreementDto.setAuthCode("签约号"); +// inOrderByAgreementDto.setSubject("会员随心选"); +// inOrderByAgreementDto.setTotalAmount("19.90"); +// String outTradeNo = OrderUtil.getOutTradeNo(); +// inOrderByAgreementDto.setOutTradeNo(outTradeNo); +// AliPayInOrderByAgreementReq payInOrderByAgreementReq = EntityConvertUtil.copy(inOrderByAgreementDto, AliPayInOrderByAgreementReq.class); +// AlipayTradePayResponse alipayTradePayResponse = aliPayService.aliPayTradePayByAgreement(payInOrderByAgreementReq); +// return FResult.ok(alipayTradePayResponse); +// } + + @ApiOperation(value = "支付宝签约回调", notes = "签约完成后由支付宝发起,服务端根据回调的数据入库") + @PostMapping("/signNotify") + public String signNotify(HttpServletRequest request) { + // 获取支付宝的请求信息 + Map inMap = getNotifyMap(request); + if (inMap == null) { + return "fail"; + } + return signNotify(inMap); + } + + @ApiOperation(value = "代扣回调", notes = "定时周期任务代扣结果通知") + @PostMapping("/agreementNotify") + public String agreementNotify(HttpServletRequest request) { + // 获取支付宝的请求信息 + Map inMap = getNotifyMap(request); + if (inMap == null) { + return "fail"; + } + String result = agreementNotify(inMap); + return result; + + } + + + //@Scheduled(cron = "0 0 8,20 * * ?") + + /** + * 获取请求参数转为map + * + * @param request + * @return + */ + private static Map getNotifyMap(HttpServletRequest request) { + // 获取支付宝的请求信息 + Map map = new HashMap<>(); + Map requestParams = request.getParameterMap(); + if (requestParams.isEmpty()) { + return null; + } + //将 Map 转为 Map + for (String name : requestParams.keySet()) { + String[] values = requestParams.get(name); + String valueStr = ""; + for (int i = 0; i < values.length; i++) { + valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; + } + map.put(name, valueStr); + } + return map; + } + + + /** + * 签约 + * { + * "external_agreement_no":"Y2023052217492063821000", + * "product_code":"CYCLE_PAY_AUTH", + * "personal_product_code":"CYCLE_PAY_AUTH_P", + * "sign_scene":"INDUSTRY|MOBILE", + * "access_params":{ + * "channel":"ALIPAYAPP" + * }, + * "period_rule_params":{ + * "period":"7", + * "period_type":"DAY", + * "execute_time":"2023-05-22", + * "single_amount":"0.01" + * } + * } + * + * @param aliPayUserPageSignReq + * @return + */ + public String signUp(AliPayUserPageSignReq aliPayUserPageSignReq) { + return null; + } + + + /** + * 签约回调通知 + * { + * "charset":"UTF-8", + * "notify_time":"2023-05-22 17:50:02", + * "alipay_user_id":"2088722249554680", + * "sign":"SbhJupeGzltbiNwbiZJd8u6+V9RXrQYfSo5b0kZYW5ayfmF+7eVCSlB+hhZTa0rzhNQMy0eiYxjCZG9NSq0V8E72Q5IT2vqPiL3BIIo49/zP8fW1PSoJyrH6wwJ45oOV05kOyMc9XbhMSnCxkvzJmVX4VunsKtDh7SJYuVLSmzlW1Afk12L45KSAIzebTIbSJX4RxxpRRZz3XpMAYT2wovqJCBL59boMv0ze+6yO/lPuq5Fl1K+uCU9mSvd2LvwC0rBDluE9i6Ri5s/23t7KGoKvKZRZbzVx6Z1EC+8q0qWVlh4urMMKnttBfTiSAsdp09zZUlQWFj4lP1gw8ckREQ==", + * "external_agreement_no":"Y2023052217492063821000", + * "version":"1.0", + * "sign_time":"2023-05-22 17:50:02", + * "notify_id":"2023052201222175002009751491422699", + * "notify_type":"dut_user_sign", + * "agreement_no":"20235322942117682668", + * "invalid_time":"2115-02-01 00:00:00", + * "auth_app_id":"2021003127667792", + * "personal_product_code":"CYCLE_PAY_AUTH_P", + * "valid_time":"2023-05-22 17:50:02", + * "//login_token":"a8c9583559c99df56f59d6ae1f8b9580_68", + * "app_id":"2021003127667792", + * "sign_type":"RSA2", + * "sign_scene":"INDUSTRY|MOBILE", + * "status":"NORMAL", + * "alipay_//logon_id":"151******06" + * }external_agreement_no -> Y2023052220155843561000 + * + * @param inMap + * @return + */ + public String signNotify(Map inMap) { + System.out.println("===========================我是签约回调============================"); + //log.info("支付宝签约回调开始:request{}", JSON.toJSONString(inMap)); + try { + //验签 + boolean signVerified = AlipaySignature.certVerifyV1(inMap, certAlipayRequest.getAlipayPublicCertPath(), AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2); + if (signVerified) { + //按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success + //协议状态,NORMAL:正常。UNSIGN:解约。 + String status = inMap.get("status"); + //代扣协议中标示用户的唯一签约号,商家自定义。仅签约接口传入时返回。 + String externalAgreementNo = inMap.get("external_agreement_no"); + //支付宝系统中用以唯一标识用户签约记录的编号。 + String agreementNo = inMap.get("agreement_no"); + //异步通知类型,dut_user_sign:当 status = NORMAL 表示签约成功。dut_user_unsign:当 status = UNSIGN 表示解约成功。 + String notifyType = inMap.get("notify_type"); + //签约协议场景。 + String signScene = inMap.get("sign_scene"); + //协议产品码。 + String personalProductCode = inMap.get("personal_product_code"); + //用户的支付宝账号对应的支付宝唯一用户号。 + String alipayUserId = inMap.get("alipay_user_id"); + //用户的支付宝登录账号。 + String alipayLogonId = inMap.get("alipay_//logon_id"); + log.info("支付宝签约回调通知:" + inMap.toString()); + + //更新订单签约信息 + AliPaySigningOrderEntity aliPaySigningOrder = aliPaySigningOrderService.getOne(new QueryWrapper().eq("order_id", externalAgreementNo)); + if (aliPaySigningOrder==null){ + return "fail"; + } + aliPaySigningOrder.setAliUserId(alipayUserId); + aliPaySigningOrder.setSignCode(agreementNo); + //处理签约成功的回调 + if ("NORMAL".equals(status)) { + //修改订单状态为成功 + aliPaySigningOrder.setStatus(1); + //aliPaySigningOrderService.update(new AliPaySigningOrderEntity(), updateWrapper); + AliPayInOrderByAgreementReq payInOrderByAgreementReq = new AliPayInOrderByAgreementReq(); + payInOrderByAgreementReq.setAuthCode(agreementNo); + payInOrderByAgreementReq.setSubject("会员随心选"); + String price = "0.1"; + payInOrderByAgreementReq.setTotalAmount(price); + String outTradeNo = OrderUtil.getOutTradeNo(); + //保存支付的订单号 + aliPaySigningOrder.setOtherOrderId(outTradeNo); + payInOrderByAgreementReq.setOutTradeNo(outTradeNo); + aliPaySigningOrder.setStatus(1); + System.out.println("修改成功订单"+aliPaySigningOrder+"================================"); + boolean b = aliPaySigningOrderService.updateById(aliPaySigningOrder); + System.out.println("修改结果:=========================================================="+b); + + //进行扣款 + aliPayService.aliPayTradePayByAgreement(payInOrderByAgreementReq,aliPaySigningOrder); + }else { + //修改订单状态为失败 + aliPaySigningOrder.setStatus(0); + aliPaySigningOrderService.updateById(aliPaySigningOrder); + + } + + + } + + return "success"; + } catch (AlipayApiException e) { + //log.info("支付宝签约回调:处理过程异常,error:{}",e.getMessage()); + } + return "fail"; + } + + /** + * 代扣支付回调 + * { + * "gmt_create":"2023-05-22 18:04:31", + * "charset":"UTF-8", + * "seller_email":"heyuwangluo2020@163.com", + * "subject":"测试扣款", + * "sign":"sTtiNS55mONsj2w54+llyqhmDjW9VsxqzI6omvbS6WaWLsCz4yTUMqebESl/S1q9IWsC3o1iJnG/fSax/YXtSldNAzKAKeTU/2zzcGp4o/9nUu9kKIRR92H51otgjK6ja5/4vfAwZ96LwnaJn0BWVYx0YE7kHtGtd84MsvVJ+rGEuWv8TsWJEjey3bcKQRPE3TJwuflwZbfG7Com+U+6H2zQ93O351To0H/oqG3exAXGBdbv5Tw2Rc63Jg4rospSw3f8qUSNq+B8nXcUKfto5RMgehg4yA9GlyzXPmC4eDLDPQ+qsTCja9sWVbz70rVsme4M9V2SB8vEozPKCK6mIQ==", + * "buyer_id":"2088722249554680", + * "invoice_amount":"0.01", + * "notify_id":"2023052201222180433054681491186225", + * "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]", + * "notify_type":"trade_status_sync", + * "trade_status":"TRADE_SUCCESS", + * "receipt_amount":"0.01", + * "app_id":"2021003127667792", + * "buyer_pay_amount":"0.01", + * "sign_type":"RSA2", + * "seller_id":"2088441130447941", + * "gmt_payment":"2023-05-22 18:04:32", + * "notify_time":"2023-05-22 18:07:19", + * "version":"1.0", + * "out_trade_no":"Y2023052218043074501000", + * "total_amount":"0.01", + * "trade_no":"2023052222001454681455191308", + * "auth_app_id":"2021003127667792", + * "buyer_//logon_id":"151****4506", + * "point_amount":"0.00" + * } + * + * @param inMap + * @return + */ + @ApiOperation(value = "ces", notes = "cs") + @PostMapping("/ces") + public String agreementNotify(@RequestBody Map inMap) { + log.info("支付宝代扣回调开始:request{}"+JSON.toJSONString(inMap)); + try { + //验签 + boolean signVerified = AlipaySignature.certVerifyV1(inMap, certAlipayRequest.getAlipayPublicCertPath(), AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2); + if (signVerified) { + //支付宝交易号。支付宝交易凭证号。 + String tradeNo = inMap.get("trade_no"); + //商户订单号 + String outTradeNo = inMap.get("out_trade_no"); + //卖家支付宝账号。 + String sellerEmail = inMap.get("seller_email"); + //订单标题。商品的标题/交易标题/订单标题/订单关键字等,是请求时对应的参数,原样通知回来。 + String subject = inMap.get("subject"); + //买家支付宝用户号。买家支付宝账号对应的支付宝唯一用户号。 + String buyerId = inMap.get("buyer_id"); + //开票金额。用户在交易中支付的可开发票的金额。支持小数点后两位。 + String invoiceAmount = inMap.get("invoice_amount"); + //支付金额信息。支付成功的各个渠道金额信息,详请可查看下表 资金明细信息说明 。 + String fundBillList = inMap.get("fund_bill_list"); + //通知类型。枚举值:trade_status_sync。 + String notifyType = inMap.get("notify_type"); + //交易状态。咨询目前所处的状态。 TRADE_CLOSED + String tradeStatus = inMap.get("trade_status"); + //实收金额。商家在交易中实际收到的款项,单位为人民币(元)。支持小数点后两位。 + String receiptAmount = inMap.get("receipt_amount"); + //开发者的 app_id。支付宝分配给开发者的应用 APPID。 + String appId = inMap.get("app_id"); + //付款金额。用户在咨询中支付的金额。支持小数点后两位。 + String buyerPayAmount = inMap.get("buyer_pay_amount"); + //卖家支付宝用户号。 + String sellerId = inMap.get("seller_id"); + //订单金额。本次交易支付的订单金额,单位为人民币(元)。支持小数点后两位。 + String totalAmount = inMap.get("total_amount"); + //交易创建时间。该笔交易创建的时间。格式 为 yyyy-MM-dd HH:mm:ss。 + String gmtCreate = inMap.get("gmt_create"); + //交易 付款时间。该笔交易的买家付款时间。格式为 yyyy-MM-dd HH:mm:ss。 + String gmtPayment = inMap.get("gmt_payment"); + //通知时间。通知的发送时间。格式为 yyyy-MM-dd HH:mm:ss。 + String notifyTime = inMap.get("notify_time"); + log.info("支付宝支付回调:" + inMap.toString()); + System.out.println("outTradeNo====================="+outTradeNo); + AliPaySigningOrderEntity aliPaySigningOrderEntity = aliPaySigningOrderService.getOne(new QueryWrapper().eq("other_order_id", outTradeNo)); +// for (AliPayOrderEntity aliPayOrderEntity : aliPayOrderService.list(new QueryWrapper<>())) { +// System.out.println("======================================"); +// System.out.println(aliPayOrderEntity); +// } + + if (aliPaySigningOrderEntity==null){ + log.info("未查询到订单"); + return "success"; + } + AliPayOrderEntity aliPayOrderEntity = new AliPayOrderEntity(); + aliPayOrderEntity.setOrderId(System.currentTimeMillis()+""); + aliPayOrderEntity.setOrderTime(LocalDateTime.now()); + aliPayOrderEntity.setPrice(aliPaySigningOrderEntity.getPrice()); + aliPayOrderEntity.setIsPage(aliPaySigningOrderEntity.getIsPage()); + aliPayOrderEntity.setAliUserId(aliPaySigningOrderEntity.getAliUserId()); + aliPayOrderEntity.setOtherOrderId(aliPaySigningOrderEntity.getOtherOrderId()); + aliPayOrderEntity.setMobile(aliPaySigningOrderEntity.getMobile()); + aliPayOrderEntity.setSignCode(aliPaySigningOrderEntity.getSignCode()); + aliPayOrderEntity.setBusinessType(aliPaySigningOrderEntity.getBusinessType()); + aliPayOrderEntity.setLinkId(aliPaySigningOrderEntity.getLinkId()); + aliPayOrderEntity.setLinkName(aliPaySigningOrderEntity.getLinkName()); + aliPayOrderEntity.setOrderName("会员随心选"); + if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) { + // TODO: 2023/05/22 1.处理业务 + aliPayOrderEntity.setStatus(1); + aliPayOrderService.save(aliPayOrderEntity); + log.info("支付订单保存成功"+aliPayOrderEntity); +// if (b){ +// log.info("支付订单保存成功"+aliPayEntity.getOrderId()+"=====status:"+aliPayEntity.getStatus()); +// +// } + + return "success"; + } + aliPayOrderEntity.setStatus(0); + aliPayOrderService.save(aliPayOrderEntity); + log.info("支付开通失败订单保存成功"+aliPayOrderEntity); + + } + } catch (AlipayApiException e) { + log.info("支付宝代扣支付回调:处理过程异常,error:{}" + e.getMessage()); + } + return "fail"; + } + + + private int checkFrom(String mobile) { + mobile = mobile.substring(0, 3); + List uniList = Arrays.asList(unicom); + List mobileList = Arrays.asList(mobileArray); + List telList = Arrays.asList(tel); + int operatorsId = 0; + if (mobileList.contains(mobile)) { + operatorsId = 1; + } else if (uniList.contains(mobile)) { + operatorsId = 2; + } else if (telList.contains(mobile)) { + operatorsId = 3; + } else { + operatorsId = 0; + } + return operatorsId; + } + + +} diff --git a/rights-client-controller/src/main/java/com/cyjd/rights/controller/YunmeiController.java b/rights-client-controller/src/main/java/com/cyjd/rights/controller/YunmeiController.java new file mode 100644 index 0000000..7b3a8f3 --- /dev/null +++ b/rights-client-controller/src/main/java/com/cyjd/rights/controller/YunmeiController.java @@ -0,0 +1,72 @@ +package com.cyjd.rights.controller; + +import com.cyjd.rights.beans.R; +import com.cyjd.rights.business.service.YunmeiService; +import com.cyjd.rights.dto.DirectBuyOrderDto; +import com.cyjd.rights.dto.OrderNotifyDto; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Api(value = "【小程序】云媒影视接口",tags = "【小程序】云媒影视接口") +@RestController +@RequestMapping("/yunmei") +@Slf4j +public class YunmeiController { + + @Autowired + private YunmeiService yunmeiService; + + //@RequiresPermissions("system:config:list") + @ApiOperation(value="查询云媒影视产品列表") + @PostMapping("/list") + public R getProductList(){ + return R.ok().put("res",yunmeiService.getProductList()); + } + + //@RequiresPermissions("system:config:list") +// @ApiOperation(value="查询云媒影视产品详情") +// @PostMapping("/details/{skuId}") +// public AjaxResult getProductDetails(@ApiParam("商品id") @PathVariable("skuId") Long skuId){ +// return AjaxResult.success(yunmeiService.getProductDetails(skuId)); +// } +// + @ApiOperation(value="直充下单") + @PostMapping("/directBuy") + public R directBuy(@RequestBody DirectBuyOrderDto params){ + return R.ok().put("res",yunmeiService.directBuyOrder(params)); + } +// +// //@RequiresPermissions("system:config:list") +// @ApiOperation(value="卡密下单") +// @PostMapping("/cardBuy") +// public AjaxResult cardBuy(@ApiParam("卡密下单参数") @RequestBody CardBuyOrderDto params){ +// return AjaxResult.success(yunmeiService.cardBuyOrder(params)); +// } +// +// //@RequiresPermissions("system:config:list") +// @ApiOperation(value="查询订单详情") +// @PostMapping("/order/details") +// public AjaxResult getProductDetails(@ApiParam("订单id对象") @RequestBody OrderDetailsDto params){ +// return AjaxResult.success(yunmeiService.getOrderDetails(params.getOrderNo())); +// } +// + @ApiOperation(value="查询商户余额") + @PostMapping("/balance") + public R getBalance(){ + return R.ok().put("res",yunmeiService.getBalance()); + } + + @ApiOperation(value="云媒订单回调") + @PostMapping("/notifyOrder") + public String notifyOrder(@ApiParam("云媒回调参数") @RequestBody OrderNotifyDto params){ + yunmeiService.orderNotify(params); + return "success"; + } +} diff --git a/rights-client-controller/src/main/java/com/cyjd/rights/handle/IpRoleAuthorizationInterceptor.java b/rights-client-controller/src/main/java/com/cyjd/rights/handle/IpRoleAuthorizationInterceptor.java new file mode 100644 index 0000000..11f9363 --- /dev/null +++ b/rights-client-controller/src/main/java/com/cyjd/rights/handle/IpRoleAuthorizationInterceptor.java @@ -0,0 +1,94 @@ +package com.cyjd.rights.handle; + +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.sql.SQLException; + +@Component +public class IpRoleAuthorizationInterceptor extends HandlerInterceptorAdapter { + /* public static final String URL = "jdbc:mysql://121.40.211.118:3306/vrbt_test?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"; + public static final String USER = "root"; + public static final String PASSWORD = "root123"; + private Boolean testts(String ips) throws ClassNotFoundException, SQLException { + //1.加载驱动程序 + Class.forName("com.mysql.jdbc.Driver"); + //2. 获得数据库连接 + Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); + //3.操作数据库,实现增删改查 + Statement stmt = conn.createStatement(); + String ip1='"'+ips+'"'; + ResultSet rs = stmt.executeQuery("SELECT * FROM tb_ip where ip="+ip1); + //如果有数据,rs.next()返回true + return rs.next(); +l + }*/ + private String getIpAddr(HttpServletRequest request) throws ClassNotFoundException, SQLException { + + String ip = request.getHeader("x-forwarded-for"); + // System.out.println("x-forwarded-for ip: " + ip); + if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { + // 多次反向代理后会有多个ip值,第一个ip才是真实ip + if (ip.indexOf(",") != -1) { + ip = ip.split(",")[0]; + } + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + //System.out.println("Proxy-Client-IP ip: " + ip); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + //System.out.println("WL-Proxy-Client-IP ip: " + ip); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + //System.out.println("HTTP_CLIENT_IP ip: " + ip); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + //System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + //System.out.println("X-Real-IP ip: " + ip); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + //System.out.println("getRemoteAddr ip: " + ip); + } + //System.out.println("获取客户端ip: " + ip); + return ip; + } + + @Override + public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws ServletException, IOException, SQLException, ClassNotFoundException { + //List list = baseMapper.selectList(new QueryWrapper()); + /* for (MailWarnEntity mailWarnEntity : list) { + System.out.println(mailWarnEntity); + }*/ + String ipAddr = getIpAddr(request); + + //System.out.println(ipAddr); + //System.out.println("22222222222222222222222222222222222"); + if (ipAddr.equals("14.152.90.114")||ipAddr.equals("47.97.80.112")){ + handleNotAuthorized(request,response,handler); + return false; + }else { + return true; + } + // handleNotAuthorized(request, response, handler); + //return true; + } + protected void handleNotAuthorized(HttpServletRequest request, HttpServletResponse response, Object handler) + throws ServletException, IOException{ + // 403表示资源不可用。服务器理解用户的请求,但是拒绝处理它,通常是由于权限的问题 + response.sendError(403); + } + +} diff --git a/rights-client-controller/src/main/resources/application-test.yml b/rights-client-controller/src/main/resources/application-test.yml new file mode 100644 index 0000000..e318b29 --- /dev/null +++ b/rights-client-controller/src/main/resources/application-test.yml @@ -0,0 +1,47 @@ +server: + port: 8086 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://203.104.38.186:6002/rights?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false&rewriteBatchedStatements=true + username: bnyer_cloud + password: CIYUANjiedian2021. + hikari: + maximum-pool-size: 2 + redis: + host: 203.104.38.232 + port: 6003 + password: CIYUANjiedian2021. + database: 0 + timeout: 5000s # 数据库连接超时时间,2.0 中该参数的类型为Duration,这里在配置的时候需要指明单位 + # 连接池配置,2.0中直接使用jedis或者lettuce配置连接池 + block-when-exhausted: true + test-while-idle: true + test-on-borrow: true + jedis: + pool: + # 最大空闲连接数 + max-idle: 500 + # 最小空闲连接数 + min-idle: 50 + # 等待可用连接的最大时间,负数为不限制 + max-wait: -1 + # 最大活跃连接数,负数为不限制 + max-active: -1 + cache: + redis: + #毫秒 + time-to-live: -1 +payment: + ali: + appId: 2021003135690045 + privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCGq3UKNbNuIazHbD9slLNJsStw2347rYwR1NmFLCi/d62yNLeTZvmrY4aW3GsDsQiK5vFdLRxaT8tIkGO11GilBRn00xkNKnwPkMA8GUdtr7GaudH+YBqk2snDeBhtdlYLq1V79USGZKdnpsPoUIXVIpyhnBlULzcJP7hf7NSauRVBnDf+MuEQOjhRAc6i8RN7nY2Oz5x6ZuIPhJ8qWjbZQoN6sJ00KU5oYZaN34/NGmPIfpR4QwbZbABm0Y0dCwkXzzNoV3cPYsFqKWNN8gxY7mI7YQqYsVb25fvALDjOl0XUGv1D7lMOC4mX3iz4q8b13ZNK+Tb3y4atwO6jK0EdAgMBAAECggEAUb4ZGM1n0F2YZqQKC3pnKT/lQme4w7if4OL19aPMSAv43sao90v2GFYdB81bF66JpOZxc0FCiH8OwUkDfQclTaU/ECBigF9dVoViahheBvIyN9y63lCvW4mCFqf7C9ZcfFDPXqKNqZXHF19eYtEdqzWLJX1+0l6mZXLME03J7u+tPX+OOnjf/K3wBp90RzoS02Ofp8fxiRyiDwFwlcxfRVbffLPVIW8JMqyOuI95U0l90F3N48+twJj8UeZlWHQeTGSDZ5jgfC6T5SXkDxOi6e7ZemZUG43rqsEHyb84fBfpr4ZFh9SkjXSnRih5w0VRws50dE2u1wAeCLG8K5KD8QKBgQDX/rpHjIJl0aD2LsI1kcUW82Yzm7qOJWApRCTe/+mZtrNGotzz/Mc2S0xV8s95ahgsH9AYqytu58UdM0CQhJ5+57fPDQcYWq9QvHB741ljAd1371qTLvRsMQg6E/nmObFvAON7ynNuh+TfkM9e7HQS6dpA0FkVqrREdD7hgUeUewKBgQCfnL3GKdMdH5FTTMBJgiLwHYBpgFQxDPzD5DEvz9lgCgosk76k4jQGi/3/raJWxkAED5K4O2J90IE/VnRXV4Uhi4h54D3ceO9dtXWBN1IxqEuO7pw9ldiRjFrlTo4aSgnq2wrjiVKn92Fm2YXIcAyhibUs7hamWt6LGAULbM5JRwKBgG11jXlM35gxz9xyfcEgCj1DQ/vLY5M9panD+tt33S4kxF17k3WiGGKPbjPwROxGs9FInfCibfRaSC4wFvwl+Rxe2Wt4MqxI6KeFl4tw/4+JFm79QW1tUjix8HVeQjpF6oFSdfX59t2AyJ/zhuOX+IrNL+nArCSqyYgXUPZ+yYOZAoGATbLAkxnDInc+iF1hcac/GMJTw4fr9CDNXxLTeuHkgKMChua5NIzFJLa7Q96jmzhQ62klVDfcX0DD2jBc3DPHpCfHnQSzOINKisSN2gQzJ+c0OPUg673pOhkoGl5eQJ/wKfrNVyx/JzL+oFGdlZAuJejiYGfacMrlcLKVqhUiansCgYEAtPCz8J3fYipscjdWKQIXsejr110KF0zsh8X7ZYKxhAgRZ5ck3wbMbffYIfa7wCm5nIJMY640P3Jh6Rb5W5/4/i04gHbE1Loi714aGCXoY6gm5oVoKIFP8h3g3MyQl7mZ2huAA/KnLsThlmfQ0l0n6Pd8xEcqJ+Ggi/GS2MQQrIw= + publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhqt1CjWzbiGsx2w/bJSzSbErcNt+O62MEdTZhSwov3etsjS3k2b5q2OGltxrA7EIiubxXS0cWk/LSJBjtdRopQUZ9NMZDSp8D5DAPBlHba+xmrnR/mAapNrJw3gYbXZWC6tVe/VEhmSnZ6bD6FCF1SKcoZwZVC83CT+4X+zUmrkVQZw3/jLhEDo4UQHOovETe52Njs+cembiD4SfKlo22UKDerCdNClOaGGWjd+PzRpjyH6UeEMG2WwAZtGNHQsJF88zaFd3D2LBailjTfIMWO5iO2EKmLFW9uX7wCw4zpdF1Br9Q+5TDguJl94s+KvG9d2TSvk298uGrcDuoytBHQIDAQAB + certPath: /opt/ + signNotifyUrl: http://47.114.139.101:8086/alipay/signNotify + agreementNotifyUrl: http://47.114.139.101:8086/alipay/agreementNotify + signReturnUrl: https://vediocnd.corpring.com/hotVIP/paybackImg.png + +logging: + level: + com.cyjd.rights.business.mapper: debug \ No newline at end of file diff --git a/rights-client-controller/src/main/resources/application.yml b/rights-client-controller/src/main/resources/application.yml new file mode 100644 index 0000000..041f84e --- /dev/null +++ b/rights-client-controller/src/main/resources/application.yml @@ -0,0 +1,49 @@ +server: + port: 8086 +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://203.104.38.186:6002/rights?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false&rewriteBatchedStatements=true + username: bnyer_cloud + password: CIYUANjiedian2021. + hikari: + maximum-pool-size: 2 + redis: + host: 203.104.38.232 + port: 6003 + password: CIYUANjiedian2021. + database: 0 + timeout: 5000s # 数据库连接超时时间,2.0 中该参数的类型为Duration,这里在配置的时候需要指明单位 + # 连接池配置,2.0中直接使用jedis或者lettuce配置连接池 + block-when-exhausted: true + test-while-idle: true + test-on-borrow: true + jedis: + pool: + # 最大空闲连接数 + max-idle: 500 + # 最小空闲连接数 + min-idle: 50 + # 等待可用连接的最大时间,负数为不限制 + max-wait: -1 + # 最大活跃连接数,负数为不限制 + max-active: -1 + cache: + redis: + #毫秒 + time-to-live: -1 +payment: + ali: + appId: 2021003135690045 + privateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCGq3UKNbNuIazHbD9slLNJsStw2347rYwR1NmFLCi/d62yNLeTZvmrY4aW3GsDsQiK5vFdLRxaT8tIkGO11GilBRn00xkNKnwPkMA8GUdtr7GaudH+YBqk2snDeBhtdlYLq1V79USGZKdnpsPoUIXVIpyhnBlULzcJP7hf7NSauRVBnDf+MuEQOjhRAc6i8RN7nY2Oz5x6ZuIPhJ8qWjbZQoN6sJ00KU5oYZaN34/NGmPIfpR4QwbZbABm0Y0dCwkXzzNoV3cPYsFqKWNN8gxY7mI7YQqYsVb25fvALDjOl0XUGv1D7lMOC4mX3iz4q8b13ZNK+Tb3y4atwO6jK0EdAgMBAAECggEAUb4ZGM1n0F2YZqQKC3pnKT/lQme4w7if4OL19aPMSAv43sao90v2GFYdB81bF66JpOZxc0FCiH8OwUkDfQclTaU/ECBigF9dVoViahheBvIyN9y63lCvW4mCFqf7C9ZcfFDPXqKNqZXHF19eYtEdqzWLJX1+0l6mZXLME03J7u+tPX+OOnjf/K3wBp90RzoS02Ofp8fxiRyiDwFwlcxfRVbffLPVIW8JMqyOuI95U0l90F3N48+twJj8UeZlWHQeTGSDZ5jgfC6T5SXkDxOi6e7ZemZUG43rqsEHyb84fBfpr4ZFh9SkjXSnRih5w0VRws50dE2u1wAeCLG8K5KD8QKBgQDX/rpHjIJl0aD2LsI1kcUW82Yzm7qOJWApRCTe/+mZtrNGotzz/Mc2S0xV8s95ahgsH9AYqytu58UdM0CQhJ5+57fPDQcYWq9QvHB741ljAd1371qTLvRsMQg6E/nmObFvAON7ynNuh+TfkM9e7HQS6dpA0FkVqrREdD7hgUeUewKBgQCfnL3GKdMdH5FTTMBJgiLwHYBpgFQxDPzD5DEvz9lgCgosk76k4jQGi/3/raJWxkAED5K4O2J90IE/VnRXV4Uhi4h54D3ceO9dtXWBN1IxqEuO7pw9ldiRjFrlTo4aSgnq2wrjiVKn92Fm2YXIcAyhibUs7hamWt6LGAULbM5JRwKBgG11jXlM35gxz9xyfcEgCj1DQ/vLY5M9panD+tt33S4kxF17k3WiGGKPbjPwROxGs9FInfCibfRaSC4wFvwl+Rxe2Wt4MqxI6KeFl4tw/4+JFm79QW1tUjix8HVeQjpF6oFSdfX59t2AyJ/zhuOX+IrNL+nArCSqyYgXUPZ+yYOZAoGATbLAkxnDInc+iF1hcac/GMJTw4fr9CDNXxLTeuHkgKMChua5NIzFJLa7Q96jmzhQ62klVDfcX0DD2jBc3DPHpCfHnQSzOINKisSN2gQzJ+c0OPUg673pOhkoGl5eQJ/wKfrNVyx/JzL+oFGdlZAuJejiYGfacMrlcLKVqhUiansCgYEAtPCz8J3fYipscjdWKQIXsejr110KF0zsh8X7ZYKxhAgRZ5ck3wbMbffYIfa7wCm5nIJMY640P3Jh6Rb5W5/4/i04gHbE1Loi714aGCXoY6gm5oVoKIFP8h3g3MyQl7mZ2huAA/KnLsThlmfQ0l0n6Pd8xEcqJ+Ggi/GS2MQQrIw= + publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhqt1CjWzbiGsx2w/bJSzSbErcNt+O62MEdTZhSwov3etsjS3k2b5q2OGltxrA7EIiubxXS0cWk/LSJBjtdRopQUZ9NMZDSp8D5DAPBlHba+xmrnR/mAapNrJw3gYbXZWC6tVe/VEhmSnZ6bD6FCF1SKcoZwZVC83CT+4X+zUmrkVQZw3/jLhEDo4UQHOovETe52Njs+cembiD4SfKlo22UKDerCdNClOaGGWjd+PzRpjyH6UeEMG2WwAZtGNHQsJF88zaFd3D2LBailjTfIMWO5iO2EKmLFW9uX7wCw4zpdF1Br9Q+5TDguJl94s+KvG9d2TSvk298uGrcDuoytBHQIDAQAB + certPath: D:/firefox/rights/ + signNotifyUrl: http://47.114.139.101:8086/alipay/signNotify + agreementNotifyUrl: http://47.114.139.101:8086/alipay/agreementNotify + signReturnUrl: https://vediocnd.corpring.com/hotVIP/paybackImg.png +yunmei: + url: https://yh.yunemei.com + +logging: + level: + com.cyjd.rights.business.mapper: debug diff --git a/rights-entity/.gitignore b/rights-entity/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/rights-entity/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/rights-entity/pom.xml b/rights-entity/pom.xml new file mode 100644 index 0000000..08f393a --- /dev/null +++ b/rights-entity/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + com.cyjd.rights + parent + 0.0.1 + + + rights-entity + + + 8 + 8 + UTF-8 + + + \ No newline at end of file diff --git a/rights-entity/src/main/java/com/cyjd/rights/beans/AliPayProperties.java b/rights-entity/src/main/java/com/cyjd/rights/beans/AliPayProperties.java new file mode 100644 index 0000000..ab3c822 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/beans/AliPayProperties.java @@ -0,0 +1,49 @@ +package com.cyjd.rights.beans; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :阿里支付配置类 + */ +@Component +@ConfigurationProperties(prefix = "payment.ali") +@Data +public class AliPayProperties { + /** + * 应用id + */ + private String appId; + /** + * 私钥 + */ + private String privateKey; + /** + * 公钥 + */ + private String publicKey; + /** + * 证书路径 + */ + private String certPath; + /** + * 支付回调地址 + */ + private String payNotifyUrl; + /** + * 签约回调地址 + */ + private String signNotifyUrl; + /** + * 签约完成跳转地址:如果不传,签约成功以后会直接回到支付宝客户端首页 + */ + private String signReturnUrl; + /** + * 代扣回调地址 + */ + private String agreementNotifyUrl; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/beans/R.java b/rights-entity/src/main/java/com/cyjd/rights/beans/R.java new file mode 100644 index 0000000..703cdfc --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/beans/R.java @@ -0,0 +1,64 @@ +package com.cyjd.rights.beans; + + +import lombok.Getter; + +import java.io.Serializable; +import java.util.HashMap; + +@Getter +public class R extends HashMap implements Serializable +{ + private static final long serialVersionUID = -8544019625615246677L; + + + public static R error(ResultCodeEnum errCode) { + R r = new R(); + r.put("code", errCode.getCode()); + r.put("message", errCode.getDesc()); + return r; + } + public static R errorSd(ResultCodeEnum errCode) { + R r = new R(); + r.put("code", errCode.getCode()); + r.put("msg", errCode.getDesc()); + return r; + } + public static R error(){ + return error(ResultCodeEnum.error); + } + public static R error(String errCode){ + R r = new R(); + r.put("code", ResultCodeEnum.error.getCode()); + r.put("message", errCode); + return r; + } + public static R ok(){ + R r = new R(); + r.put("code", ResultCodeEnum.success.getCode()); + r.put("message", ResultCodeEnum.success.getDesc()); + return r; + } + public static R ok(String key,Object obj){ + R r = new R(); + r.put("code", ResultCodeEnum.success.getCode()); + r.put("message", ResultCodeEnum.success.getDesc()); + r.put(key, obj); + return r; + } + + @Override + public R put(String key, Object value) + { + super.put(key, value); + return this; + } + + public static R ok(String message){ + R r = new R(); + r.put("code", 0); + r.put("message", message); + return r; + } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/beans/ResultCodeEnum.java b/rights-entity/src/main/java/com/cyjd/rights/beans/ResultCodeEnum.java new file mode 100644 index 0000000..4c9c8d2 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/beans/ResultCodeEnum.java @@ -0,0 +1,104 @@ +package com.cyjd.rights.beans; + +public enum ResultCodeEnum +{ + /** + * + */ + success(0, "成功"),// + error(500, "服务器错误"),// + data_not_exist(50000, "记录不存在"),// + param_is_null(10001, "参数为空"),// + account_not_exist(10002, "用户不存在"),// + account_passwd_error(10003, "用户或密码错误"),// + not_login(10004, "未登录或登陆已过期"),// + can_not_del_role_has_user(10005, "不能删除此角色,因为关联了用户"),// + accout_name_repeat(10007, "登陆账号已被占用,请重新选择一个"),// + + passwd_too_short(20006, "密码不可少于6位"),// + account_hast_role(20007, "后台用户至少需要一个角色"),// + passwd_not_simple(20013, "原密码不一致"),// + date_format_error(20017, "时间格式不正确"), + excel_format_error(20018, "时间格式不正确"), + //zym + verify_code_error(1000001, "验证码错误"), + + repeat_order_error(100008, "重复订单"), + + LinkIdNotExit(60026,"linkId不存在"), + + agent_num_error(10009,"代理商最多配置两个或者至少配置一个"), + + black_user_error(100026,"黑名单用户"), + + cost_error(20019,"成本比格式不对"), + + frequent_operation(100009,"操作频繁"), + user_region_not_exit(10027,"未查询到用户归属地请联系运营人员查看"), + + user_region_not_open(10028,"用户归属地非可开通省份"), + + user_is_open(10029,"用户已是包月状态"), + + order_status_error(10030,"订单已经过期或者请求非法"), + + user_month_repeat_open(10031,"该用户本月已经成功订购过,请勿重复订购"), + + rights_status_error(10032,"暂无领取资格"), + + type_error(10011,"type参数有误"), + + user_is_open_or_black(10033,"用户已是包月状态或是黑名单用户"), + + third_party_services_error(10034,"调用第三方服务失败,请联系管理人员"), + + mgc_check_fail(10035,"敏感词校验失败"), + + order_select_error(10036,"未查询到相关订单"), + + rights_this_month_is_receive(10037,"用户当月已经领取过权益"), + + channel_id_error(10038,"渠道id有误"), + + today_is_send(10039,"该用户今天已经发送过验证码了"), + + video_is_not_exit(10040,"视频信息不存在请联系运营查看"), + + province_down(10041,"省份已下线"), + + address_is_not_defined(10042,"缺少推广链接参数"), + + music_name_deficiency(10043,"铃音参数缺失") + ; + + + + private int code; + private String desc; + + ResultCodeEnum(int code, String desc) + { + this.code = code; + this.desc = desc; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getDesc() + { + return desc; + } + + public void setDesc(String desc) + { + this.desc = desc; + } +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/constant/AliPayConstant.java b/rights-entity/src/main/java/com/cyjd/rights/constant/AliPayConstant.java new file mode 100644 index 0000000..1c304c4 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/constant/AliPayConstant.java @@ -0,0 +1,42 @@ +package com.cyjd.rights.constant; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :阿里支付常量池 + */ +public class AliPayConstant { + /** + * 正式环境网关地址 + */ + public static final String serverUrl = "https://openapi.alipay.com/gateway.do"; + /** + * 沙箱环境网关地址 + */ +// public static final String serverUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do"; + /** + * 签名场景 旧 + */ + public static final String CYCLE_SIGN_SCENE = "INDUSTRY|MOBILE"; + /** + * 签名场景 新 + */ + public static final String INDUSTRY_DEFAULT_SCENE="INDUSTRY|DEFAULT_SCENE"; + + /** + * 周期扣款 + */ + public static final String CYCLE_PAY_AUTH_P = "CYCLE_PAY_AUTH_P"; + + /** + * 支付宝产品码 + */ + public static class ProductCode{ + /** + * 周期扣款销售 + */ + public static final String CYCLE_PAY_AUTH = "CYCLE_PAY_AUTH"; + + public static final String GENERAL_WITHHOLDING="GENERAL_WITHHOLDING"; + } +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/constant/EnumPeriodType.java b/rights-entity/src/main/java/com/cyjd/rights/constant/EnumPeriodType.java new file mode 100644 index 0000000..b1953ba --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/constant/EnumPeriodType.java @@ -0,0 +1,16 @@ +package com.cyjd.rights.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@Getter +@AllArgsConstructor +public enum EnumPeriodType { + DAY, + MONTH +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/constant/YunmeiConstant.java b/rights-entity/src/main/java/com/cyjd/rights/constant/YunmeiConstant.java new file mode 100644 index 0000000..9982063 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/constant/YunmeiConstant.java @@ -0,0 +1,33 @@ +package com.cyjd.rights.constant; + +/** + * 云媒敞亮类 + */ +public class YunmeiConstant { + + + /** + * 商品列表 + */ + public static final String PRODUCT_LIST = "/api/goods/list"; + + /** + * 商品详情 + */ + public static final String PRODUCT_DETAILS = "/api/goods/get"; + + /** + * 直充/卡密下单 + */ + public static final String CREATE_ORDER = "/api/order/create"; + + /** + * 订单查询 + */ + public static final String ORDER_DETAILS = "/api/order/get"; + + /** + * 余额查询 + */ + public static final String AMOUNT = "/api/account/balance"; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderByAgreementDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderByAgreementDto.java new file mode 100644 index 0000000..99fd0de --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderByAgreementDto.java @@ -0,0 +1,37 @@ +package com.cyjd.rights.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :支付宝代扣下单实体类 + */ +@Data +public class AliPayInOrderByAgreementDto { + /** + * 用户支付宝签约号 + */ + @ApiModelProperty(value = "用户支付宝签约号") + private String authCode; + /** + * 商户订单号 + */ + @ApiModelProperty(value = "商户订单号") + private String outTradeNo; + /** + * 订单标题 + */ + @ApiModelProperty(value = "订单标题") + private String subject; + /** + * 扣款金额 + */ + @ApiModelProperty(value = "扣款金额") + private String totalAmount; + + @ApiModelProperty(value = "用户手机号") + private String mobile; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderDto.java new file mode 100644 index 0000000..3e47483 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderDto.java @@ -0,0 +1,25 @@ +package com.cyjd.rights.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@ApiModel(value = "支付签约请求") +@Data +public class AliPayInOrderDto { + + @ApiModelProperty(value = "订单号") + private String outTradeNo; + + @ApiModelProperty(value = "订单金额") + private String totalAmount; + + @ApiModelProperty(value = "订单标题") + private String subject; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderSignUpDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderSignUpDto.java new file mode 100644 index 0000000..bf0fc1f --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPayInOrderSignUpDto.java @@ -0,0 +1,45 @@ +package com.cyjd.rights.dto; + +import com.cyjd.rights.constant.EnumPeriodType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@ApiModel(value = "支付签约请求") +@Data +public class AliPayInOrderSignUpDto { + + @ApiModelProperty(value = "订单号") + private String outTradeNo; + + @ApiModelProperty(value = "订单金额") + private String totalAmount; + + @ApiModelProperty(value = "订单标题") + private String subject; + + /** + * 单次扣款最大金额single_amount是周期扣款产品必填,即每次发起扣款时限制的最大金额, + * 单位为元。商户每次发起扣款都不允许大于此金额 + */ + @ApiModelProperty(value = "单次扣款最大金额single_amount是周期扣款产品必填,即每次发起扣款时限制的最大金额,单位为元。商户每次发起扣款都不允许大于此金额") + private String singleAmount; + /** + * 扣款周期数: + * 如果周期类型为DAY,支付宝限制不能超过28天,所以代码处理成超过28统一成下月第1天 + * 如果周期类型为MONTH,支付宝限制必须大于7 + */ + @ApiModelProperty(value = "扣款周期数") + private String period; + /** + * 周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH + */ + @ApiModelProperty(value = "周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH") + private EnumPeriodType periodType; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/AliPaySignUpDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPaySignUpDto.java new file mode 100644 index 0000000..b0c13fc --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/AliPaySignUpDto.java @@ -0,0 +1,49 @@ +package com.cyjd.rights.dto; + +import com.cyjd.rights.constant.EnumPeriodType; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@ApiModel(value = "支付签约请求") +@Data +public class AliPaySignUpDto { + /** + * 单次扣款最大金额single_amount是周期扣款产品必填,即每次发起扣款时限制的最大金额, + * 单位为元。商户每次发起扣款都不允许大于此金额 + */ + @ApiModelProperty(value = "单次扣款最大金额single_amount是周期扣款产品必填,即每次发起扣款时限制的最大金额,单位为元。商户每次发起扣款都不允许大于此金额") + private String singleAmount; + /** + * 扣款周期数: + * 如果周期类型为MONTH,支付宝限制不能超过28天,所以代码处理成超过28统一成下月第1天 + * 如果周期类型为DAY,支付宝限制必须大于7 + */ + @ApiModelProperty(value = "扣款周期数") + private String period; + /** + * 周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH + */ + @ApiModelProperty(value = "周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH") + private EnumPeriodType periodType; + /** + * 是否是页面签约: + * 页面签约:H5/PC + */ + @ApiModelProperty(value = "是否是页面签约:页面签约:H5/PC") + private Boolean isPage; + + private String mobile; + + private String type; + + private Integer linkId; + + + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/CardBuyOrderDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/CardBuyOrderDto.java new file mode 100644 index 0000000..10f2d57 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/CardBuyOrderDto.java @@ -0,0 +1,26 @@ +package com.cyjd.rights.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + + +@Getter +@Setter +@ApiModel("卡密下单接收类") +public class CardBuyOrderDto implements Serializable { + + @NotNull(message = "商品id不能为空!") + @ApiModelProperty(value="商品id") + private Integer skuId; + + @NotNull(message = "购买数量不能为空!") + @ApiModelProperty(value="购买数量") + private Integer buyQuantity; + + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/DirectBuyOrderDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/DirectBuyOrderDto.java new file mode 100644 index 0000000..8626463 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/DirectBuyOrderDto.java @@ -0,0 +1,31 @@ +package com.cyjd.rights.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + + +@Getter +@Setter +@ApiModel("直充下单接收类") +public class DirectBuyOrderDto implements Serializable { + + @NotBlank(message = "商品id不能为空!") + @ApiModelProperty(value="商品id") + private Integer skuId; + + @NotNull(message = "直充账号类型不能为空!") + @ApiModelProperty(value="直充账号类型,10:手机号;20:QQ号,30:邮箱;40:用户ID") + private Integer chargeAccountType; + + @NotBlank(message = "直充账号不能为空!") + @ApiModelProperty(value="直充账号") + private String chargeAccountNumber; + + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/dto/OrderNotifyDto.java b/rights-entity/src/main/java/com/cyjd/rights/dto/OrderNotifyDto.java new file mode 100644 index 0000000..da8626c --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/dto/OrderNotifyDto.java @@ -0,0 +1,43 @@ +package com.cyjd.rights.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + + +@Getter +@Setter +@ApiModel("订单回调接收类") +public class OrderNotifyDto implements Serializable { + + @NotBlank(message = "商户id不能为空!") + @ApiModelProperty(value="商户id") + private String app_id; + + @NotNull(message = "时间戳不能为空!") + @ApiModelProperty(value="时间戳") + private long timestamp; + + @NotBlank(message = "签名值不能为空!") + @ApiModelProperty(value="签名值") + private String sign; + + @NotBlank(message = "商户侧订单号不能为空!") + @ApiModelProperty(value="商户侧订单号") + private String customer_order_no; + + @NotBlank(message = "订单状态不能为空!") + @ApiModelProperty(value="订单状态(SUCCESS-成功;FAIL-失败)") + private String trade_state; + + @NotBlank(message = "描述信息不能为空!") + @ApiModelProperty(value="描述信息") + private String description; + + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/entity/AliPayOrderEntity.java b/rights-entity/src/main/java/com/cyjd/rights/entity/AliPayOrderEntity.java new file mode 100644 index 0000000..c345e08 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/entity/AliPayOrderEntity.java @@ -0,0 +1,49 @@ +package com.cyjd.rights.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("tb_ali_pay_order") +public class AliPayOrderEntity { + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private String orderId; + + private String mobile; + + + private LocalDateTime orderTime;//订单创建时间 + + private Integer status;//1 成功 0失败 2试用 4退订 + + private String signCode;//支付宝签约号 + + private String orderName;//订单名称 + + private String price;//支付 价格 + + private String otherOrderId; + + private Integer isPage;//是否是页面签约:页面签约:H5/PC + + private String aliUserId;//用户支付宝唯一id + + private LocalDateTime unsubTime; + + private Integer businessType; + + private Integer linkId; + + + private String linkName; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/entity/AliPaySigningOrderEntity.java b/rights-entity/src/main/java/com/cyjd/rights/entity/AliPaySigningOrderEntity.java new file mode 100644 index 0000000..7d7cc45 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/entity/AliPaySigningOrderEntity.java @@ -0,0 +1,60 @@ +package com.cyjd.rights.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("tb_ali_pay_signing_order") +public class AliPaySigningOrderEntity { + + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private String orderId; + + private String mobile; + + private Integer operatorsId; + + private LocalDateTime orderTime;//订单创建时间 + + private Integer status;//1 成功 0失败 2试用 4退订 + + private String signCode;//支付宝签约号 + + private String orderName;//订单名称 + + private String price;//支付 价格 + + private String otherOrderId; + + private Integer isPage;//是否是页面签约:页面签约:H5/PC + + private String aliUserId;//用户支付宝唯一id + + private LocalDateTime unsubTime; + + + private Integer businessType; + + private Integer linkId; + /** + * 开通链接 + */ + private String openAddress; + + private String linkName; + + + +} + diff --git a/rights-entity/src/main/java/com/cyjd/rights/entity/RightsOrderEntity.java b/rights-entity/src/main/java/com/cyjd/rights/entity/RightsOrderEntity.java new file mode 100644 index 0000000..2b2cb88 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/entity/RightsOrderEntity.java @@ -0,0 +1,45 @@ +package com.cyjd.rights.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("tb_rights_order") +public class RightsOrderEntity { + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + private String orderId; + + private String mobile; + + + private LocalDateTime orderTime;//订单创建时间 + + private Integer linkId; + + + private String linkName; + + private Integer status; + + private String code; + + private String reason; + + private String otherOrderId; + + private String rightsType; + + private String productNumber; + + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/enums/YunmeiCallbackEnum.java b/rights-entity/src/main/java/com/cyjd/rights/enums/YunmeiCallbackEnum.java new file mode 100644 index 0000000..b17657c --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/enums/YunmeiCallbackEnum.java @@ -0,0 +1,19 @@ +package com.cyjd.rights.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author chengkun + * @date 2022/4/19 17:46 + */ +@Getter +@AllArgsConstructor +public enum YunmeiCallbackEnum { + SUCCESS("SUCCESS","ok"), + FAIL("FAIL","fail"); + + private String value; + + private String msg; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/enums/YunmeiEnum.java b/rights-entity/src/main/java/com/cyjd/rights/enums/YunmeiEnum.java new file mode 100644 index 0000000..d9c8212 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/enums/YunmeiEnum.java @@ -0,0 +1,18 @@ +package com.cyjd.rights.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author chengkun + * @date 2022/4/19 17:46 + */ +@Getter +@AllArgsConstructor +public enum YunmeiEnum { + SUCCESS(0,"接口调用成功"); + + private Integer code; + + private String msg; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/result/FResult.java b/rights-entity/src/main/java/com/cyjd/rights/result/FResult.java new file mode 100644 index 0000000..df326e8 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/result/FResult.java @@ -0,0 +1,118 @@ +package com.cyjd.rights.result; + +import io.swagger.annotations.ApiModelProperty; +import lombok.ToString; + +import java.io.Serializable; + +/** + * 操作消息提醒 + * + */ +@ToString +public class FResult implements Serializable { + + private static final long serialVersionUID = -1025071089054808361L; + + @ApiModelProperty("响应码") + private Integer code; + + @ApiModelProperty("响应信息") + private String message; + + @ApiModelProperty("响应数据") + private T data; + + + public FResult(Integer code, String message + , T data) { + this.code = code; + this.message = message; + this.data = data; + } + + public FResult(T data) { + this.code = 0; + this.message = "成功"; + this.data = data; + } + + public FResult() { + this.code = 0; + this.message = "成功"; + this.data = null; + } + + + public FResult(Integer code, String message + ) { + this.code = code; + this.message = message; + } + + public static FResult build(Integer code, String message) { + + return new FResult<>(code, message); + + } + + public static FResult ok() { + + return new FResult<>(); + + } + + public static FResult ok(T data) { + + return new FResult<>(data); + + } + + public static FResult error() { + + return new FResult<>(10001,"失败"); + + } + + public static FResult error(String message) { + + return new FResult<>(10001,message); + + } + + public static FResult error(int code, String message) { + + return new FResult<>(code,message); + + } + + public static FResult error(int code, String message, T data) { + + return new FResult<>(code, message, data); + + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMsg() { + return message; + } + + public void setMsg(String message) { + this.message = message; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/utils/AlipayRequestBuilderUtil.java b/rights-entity/src/main/java/com/cyjd/rights/utils/AlipayRequestBuilderUtil.java new file mode 100644 index 0000000..3cce3fd --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/utils/AlipayRequestBuilderUtil.java @@ -0,0 +1,152 @@ +package com.cyjd.rights.utils; + +import com.alipay.api.request.*; +import com.cyjd.rights.beans.AliPayProperties; +import com.cyjd.rights.constant.AliPayConstant; +import com.cyjd.rights.vo.*; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDate; + +/** + * @author :WXC + * @Date :2023/05/22 + * @description :支付宝请求构建工具类 + */ +@Component +public class AlipayRequestBuilderUtil { + + /** + * 支付配置 + */ + @Resource + private AliPayProperties aliPayProperties; + + private static final Gson GSON = new GsonBuilder().create(); + + /** + * 构建用户签约请求基本信息 + * + * @param aliPayUserPageSignReq + */ + public AlipayUserAgreementPageSignRequest buildAlipayUserAgreementPageSignRequest(AliPayUserPageSignReq aliPayUserPageSignReq) { + AlipayUserAgreementPageSignRequest request = new AlipayUserAgreementPageSignRequest(); + if (StringUtils.isNotBlank(aliPayUserPageSignReq.getReturnUrl())){ + request.setReturnUrl(aliPayUserPageSignReq.getReturnUrl()); + }else { + request.setReturnUrl(this.aliPayProperties.getSignReturnUrl()); + } + if (StringUtils.isNotBlank(aliPayUserPageSignReq.getNotifyUrl())){ + request.setNotifyUrl(aliPayUserPageSignReq.getNotifyUrl()); + }else { + request.setNotifyUrl(this.aliPayProperties.getSignNotifyUrl()); + } + AliPayUserPageSignContentReq contentReq = EntityConvertUtil.convertBean(aliPayUserPageSignReq, AliPayUserPageSignContentReq.class); + //周期扣款个人签约产品码固定为CYCLE_PAY_AUTH_P + contentReq.setPersonalProductCode(AliPayConstant.CYCLE_PAY_AUTH_P); + //周期扣款销售产品码固定为CYCLE_PAY_AUTH。 + contentReq.setProductCode(AliPayConstant.ProductCode.GENERAL_WITHHOLDING); + //协议签约场景,参见下文sign_scene参数说明 + contentReq.setSignScene(AliPayConstant.INDUSTRY_DEFAULT_SCENE); + //1. ALIPAYAPP (钱包h5页面签约) + AliPayUserPageSignContentReq.AccessParams accessParams = new AliPayUserPageSignContentReq.AccessParams(); + accessParams.setChannel("ALIPAYAPP"); + contentReq.setAccessParams(accessParams); +// 首次执行时间execute_time是周期扣款产品必填,即商户发起首次扣款的时间。精确到日,格式为yyyy-MM-dd +// 结合其他必填的扣款周期参数,会确定商户以后的扣款计划。发起扣款的时间需符合这里的扣款计划 +// 首次扣款日期:当前时间+30 ; 目前允许商户在约定日期之前5天(不含扣款日当天)开始扣款 + AliPayUserPageSignContentReq.PeriodRuleParams periodRuleParams = contentReq.getPeriodRuleParams(); + LocalDate date = LocalDate.now().plusDays(aliPayUserPageSignReq.getType()); +/* String dd = DateUtil.format(date, "dd"); + //如果当天大于28号 修改到下月1号 + if (Integer.parseInt(dd) > 28){ + date = DateUtil.beginOfMonth(DateUtil.nextMonth()); + }*/ + periodRuleParams.setExecuteTime(date.toString()); + request.setBizContent(GSON.toJson(contentReq)); + return request; + } + + /** + * 构建支付宝签约查询请求 + * @return + */ + public AlipayUserAgreementQueryRequest buildAlipayUserAgreementQueryRequest(AliPayQueryPageSignReq aliPayQueryPageSignReq){ + AlipayUserAgreementQueryRequest request = new AlipayUserAgreementQueryRequest(); + AliPayQueryPageSignContentReq aliPayQueryPageSignContentReq = EntityConvertUtil.convertBean(aliPayQueryPageSignReq, AliPayQueryPageSignContentReq.class); + aliPayQueryPageSignContentReq.setSignScene(AliPayConstant.INDUSTRY_DEFAULT_SCENE); + aliPayQueryPageSignContentReq.setPersonalProductCode(AliPayConstant.CYCLE_PAY_AUTH_P); + request.setBizContent(GSON.toJson(aliPayQueryPageSignContentReq)); + return request; + } + + + /** + * 构建支付宝代扣请求 + * @param aliPayInOrderByAgreementReq + * @return + */ + public AlipayTradePayRequest buildAlipayTradePayAgreementRequest(AliPayInOrderByAgreementReq aliPayInOrderByAgreementReq){ + AlipayTradePayRequest request = new AlipayTradePayRequest(); + if (StringUtils.isNotBlank(aliPayInOrderByAgreementReq.getNotifyUrl())){ + request.setNotifyUrl(aliPayInOrderByAgreementReq.getNotifyUrl()); + }else { + request.setNotifyUrl(this.aliPayProperties.getAgreementNotifyUrl()); + } + AliPayInOrderByAgreementContentReq aliPayInOrderByAgreementContentReq = EntityConvertUtil.convertBean(aliPayInOrderByAgreementReq, AliPayInOrderByAgreementContentReq.class); + //必填,周期扣款代扣场景固定值 + aliPayInOrderByAgreementContentReq.setScene("deduct_pay"); + aliPayInOrderByAgreementContentReq.setProductCode(AliPayConstant.ProductCode.GENERAL_WITHHOLDING); + request.setBizContent(GSON.toJson(aliPayInOrderByAgreementContentReq)); + return request; + } + + /** + * 构建支付宝签约变更请求 + * @param aliPayModifyPlanReq + * @return + */ + public AlipayUserAgreementExecutionplanModifyRequest buildAlipayUserAgreementExecutionplanModifyRequest(AliPayModifyPlanReq aliPayModifyPlanReq){ + AlipayUserAgreementExecutionplanModifyRequest request = new AlipayUserAgreementExecutionplanModifyRequest(); + AliPayModifyPlanContentReq aliPayModifyPlanContentReq = EntityConvertUtil.convertBean(aliPayModifyPlanReq, AliPayModifyPlanContentReq.class); + request.setBizContent(GSON.toJson(aliPayModifyPlanContentReq)); + return request; + } + + /** + * 构建支付宝解约请求 + * @return + */ + public AlipayUserAgreementUnsignRequest buildAlipayUserAgreementUnsignRequest(AliPayUnSignReq aliPayUnSignReq){ + AlipayUserAgreementUnsignRequest request = new AlipayUserAgreementUnsignRequest(); + AliPayUnSignContentReq aliPayUnSignContentReq = EntityConvertUtil.convertBean(aliPayUnSignReq, AliPayUnSignContentReq.class); + aliPayUnSignContentReq.setPersonalProductCode(AliPayConstant.CYCLE_PAY_AUTH_P); + aliPayUnSignContentReq.setSignScene(AliPayConstant.CYCLE_SIGN_SCENE); + request.setBizContent(GSON.toJson(aliPayUnSignContentReq)); + return request; + } + + /** + * 构建支付宝交易查询请求 + * @return + */ + public AlipayTradeQueryRequest buildAlipayTradeQueryRequest(AliPayTradeQueryReq aliPayTradeQueryReq){ + AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); + request.setBizContent(GSON.toJson(aliPayTradeQueryReq)); + return request; + } + /** + * 构建支付宝交易撤销请求 + * @return + */ + public AlipayTradeCancelRequest buildAlipayTradeCancelRequest(AliPayTradeCancelReq aliPayTradeCancelReq){ + AlipayTradeCancelRequest request = new AlipayTradeCancelRequest(); + request.setBizContent(GSON.toJson(aliPayTradeCancelReq)); + return request; + } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/utils/EntityConvertUtil.java b/rights-entity/src/main/java/com/cyjd/rights/utils/EntityConvertUtil.java new file mode 100644 index 0000000..dd793a6 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/utils/EntityConvertUtil.java @@ -0,0 +1,203 @@ +package com.cyjd.rights.utils; + +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.util.CollectionUtils; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.*; +import java.util.*; + +@Slf4j +public class EntityConvertUtil { + + /** + * 数组集合转化为指定对象集合 + * 指定的实体对象必须包含所以字段的构造方法,数组的元素的顺序将和构造方法顺序和类型一一对应 + * + * @param list 集合 + * @param clazz c + * @param 类型 + * @return List + * @description 用于jpa查询自定义vo用的 + */ + public static List castEntity(List list, Class clazz) { + List returnList = new ArrayList<>(); + if (list.size() == 0) { + return returnList; + } + Class[] c2 = null; + Constructor[] constructors = clazz.getConstructors(); + for (Constructor constructor : constructors) { + Class[] tClass = constructor.getParameterTypes(); + if (tClass.length == list.get(0).length) { + c2 = tClass; + break; + } + } + //构造方法实例化对象 + for (Object[] o : list) { + Constructor constructor = null; + try { + constructor = clazz.getConstructor(c2); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + try { + assert constructor != null; + returnList.add(constructor.newInstance(o)); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + return returnList; + } + + + /** + * @param object 要强转的对象 , entityClass 强转后的类型 + */ + public static T convertBean(Object object, Class entityClass) { + if (null == object) { + return null; + } + return JSON.parseObject(JSON.toJSONString(object), entityClass); + } + + + /** + * @param object 要转话的对象 + */ + public static Map objectToMap(Object object) { + return convertBean(object, Map.class); + } + + + /** + * @param map map集合, t 对象 + */ + public static T mapToObject(Map map, Class beanClass) throws InstantiationException, IllegalAccessException, InvocationTargetException { + T t = beanClass.newInstance(); + Field[] declaredFields = t.getClass().getDeclaredFields(); + for(Field field:declaredFields){ + int mod = field.getModifiers(); + if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){ + continue; + } + field.setAccessible(true); + field.set(t, map.get(field.getName())); + } + return t; + } + + + /** + * @param source 资源对象, target 目标对象, ignoreProperties 赋值new String[]{} + * @return T target对象 + */ + public static T copy(Object source, Class target, String... ignoreProperties) { + T targetInstance = null; + try { + targetInstance = target.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + if (ArrayUtils.isEmpty(ignoreProperties)) { + assert targetInstance != null; + BeanUtils.copyProperties(source, targetInstance); + } else { + assert targetInstance != null; + BeanUtils.copyProperties(source, targetInstance, ignoreProperties); + } + return targetInstance; + + } + + /** + * 从List copy到List + * @param list List + * @param clazz B + * @return List + */ + public static List copy(List list,Class clazz){ + String oldOb = JSON.toJSONString(list); + return JSON.parseArray(oldOb, clazz); + } + + public static List copyList(List list, Class target, String... ignoreProperties) { + List targetList = new ArrayList<>(); + if (CollectionUtils.isEmpty(list)) { + return targetList; + } + for (E e : list) { + targetList.add(copy(e, target, ignoreProperties)); + } + return targetList; + } + + + /** + * 功能描述: Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map + * + */ + public static Map transBean2Map(Object obj) { + if (obj == null) { + return null; + } + Map map = new HashMap(); + try { + BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor property : propertyDescriptors) { + String key = property.getName(); + // 过滤class属性 + if (!"class".equals(key)) { + // 得到property对应的getter方法 + Method getter = property.getReadMethod(); + Object value = getter.invoke(obj); + map.put(key, value.toString()); + } + } + } catch (Exception e) { + log.error("transBean2Map Error " + e); + } + return map; + } + + /** + * 属性复制,跳过为null的值 + * @param source 提供值的obj + * @param target 接收值的obj + * @param + * @return target + */ + public static T copyNotNullProperties(T source, T target){ + BeanUtils.copyProperties(source, target, getNullPropertyNames(source)); + return target; + } + + /** + * 获取值为Null的字段名称 + * @param source + * @return + */ + public static String[] getNullPropertyNames (Object source) { + final BeanWrapper src = new BeanWrapperImpl(source); + PropertyDescriptor[] pds = src.getPropertyDescriptors(); + + Set emptyNames = new HashSet<>(); + for(PropertyDescriptor pd : pds) { + Object srcValue = src.getPropertyValue(pd.getName()); + if (srcValue == null) emptyNames.add(pd.getName()); + } + String[] result = new String[emptyNames.size()]; + return emptyNames.toArray(result); + } +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/utils/HttpUtils.java b/rights-entity/src/main/java/com/cyjd/rights/utils/HttpUtils.java new file mode 100644 index 0000000..5ae1199 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/utils/HttpUtils.java @@ -0,0 +1,617 @@ +package com.cyjd.rights.utils; + +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.ParseException; +import org.apache.http.util.EntityUtils; + +import javax.net.ssl.*; +import java.io.*; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; + +@Slf4j +public class HttpUtils { + + private static OkHttpClient client = new OkHttpClient(); + + private static final String sign_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCfNNNAUdIQHji6oWYTLogbLjT8rOdPPtUhb1a8fqucRcDA4lQmQw7AZD4gDlEq1tRyVU8nJTPTWS8hwfAC3G55d/Sgux8GRaMUuUrMJ0GcNrOo56Bwyh9cJP+n66pQoLo/2xVbE/dYKUKhM32JnmdrP8vjP0jFuCxw4MCZWVJmjohZ72nu+EYtFmef+0mKRFQqm7/2g3lYr93ICZfWE5F75WqT0PNLB6rWEiNM+r7V5+7fJfA35DmFVbb0cDzyiZ3pRdpGBplv54jTns1hk3yunE/Nlj+xvrz2/rsRFeWfyfPx2Bd95LkCxiJrpK7Ui9Fwg0GNVrJmA5pcqWut1mEpAgMBAAECggEAEGNFo4dIkjQqLrvSYAMYK4QUHDZIERYspiZpzTlUvN9JOhGSC+Y3LIKlCnOu0zQN5j71yNfBf+3cNiNaa1D5ZjN80NayGNkuMkHoex9HV6ch0y8Uisejdr6wOj6951LEGTKZ/igN+9szaph8QaA2kQmeGSQ4f3G30V6xNJfHLZswcQT0D7qDA/bpcdaJ0/6BDObklQx/lD5kWuUmW7TUp7Hp8eEt0z0XCsgzem5+z4rzMhnyIIXle1YqRklnZKWAYbUplBx+RVTyQdLVoSREfGo8/BUDBY7Da5SihMKtVMj0CP1B+nZDE2fWjUOW28L/xZp1IiG9r/QqpvDPhATQAQKBgQDlvHpqAIEnc03WjYgbpbF1bW6qoyj+KYTWhjAB5frOomLd2uPn0br9YSlMn8q/7i9nOQEzLWAuKrQjRc49w9cbFdgj78FxUH7V9ntRZUeZraEGvOG2z9U4JTdTp9JI/cXWPwA6iv/RPKJR7q1Cfz12NQZ78DyQs01e3gjUZkBcKQKBgQCxaDNO1pypJLmPwNyJZ3uukSh5IdPkbMwidJFcOUrDb9cJWlDcQAngsR/amWEhNYYuqHP3T+J1tu9iyZaf2qVEFtedi9m/iyLjouJitnmqqZjLSsQ0FYe6ApQYC8osZuG0INg0sjiPq54CicmnGhypYhw0BW1SSJ0WajtAWKZ9AQKBgDpwcndKf5AofZFpWUknIfgsCS2w6XmV2Cu14Lpq5RzxI9MpnjXXHQjdUWMjdrDSBw7r6kk5brDvvfkHBcqiabKDIQMrNvr7LfiBhacT613FVCPhok0dmzB4DxXhp9VXcJ7qUcWSnDZ+hQ/wdfRnZ5wNKwQV/WIVqkXKl1ZoWFDZAoGBAKoS5v0xqUZOOsahccsYNe4IovBdibF2y8xMS/5Jvm7WDSSePN6pVc7ef1clq4QWt+iK/YGeR8/p7FycPZZKGh3IeDRFGh8S2AO656USolkF9cEOkEIOUev1BNx4kP04NDBnPF5obOju8bAlP/i+g7OuprMIcOFtU4tllB//3LwBAoGAOY9xTmyYACLC3kYYb+iBnzq/h6cywEUjsPSfy3XeDyFXfDM2h41O2Le7UdNpEljCQdTTYTPqzhywm1/AOgdMv0vWcUZKZmklC1atAFhZnVQ8fVRgv5ZhhmXzGXjlflUTuYlr99v7Csz8q+Tu0/AbLCeAqEFgvEDS/WS3tdTmnHA="; + + + public static String postJson(String url, String json) { + + + log.info("http util post:" + url + "param:" + json); + Request request = new Request.Builder().url(url). + post(RequestBody.create(MediaType.parse("application/json"), json)).build(); + String string = null; + try { + + + Response response = client.newCall(request).execute(); + + + if (!response.isSuccessful()) { + throw new IOException("Unexpected code " + response); + } + + string = response.body().string(); + + + log.info("http util post result:" + string); + + } catch (Exception e) { + log.info(e.getMessage()); + } + return string; + } + + public static ResponseBody postFile(String url, String json) { + log.info("http util post:" + url); + Request request = new Request.Builder().url(url). + post(RequestBody.create(MediaType.parse("application/json"), json)).build(); + String string = null; + ResponseBody body = null; + try { + Response response = client.newCall(request).execute(); + if (!response.isSuccessful()) { + throw new IOException("Unexpected code " + response); + } + body = response.body(); + log.info("http util post result:" + string); + + } catch (Exception e) { + log.info(e.getMessage()); + } + return body; + } + + public static String postJsonHeBei(String url, String json) { + + + log.info("http util post:" + url + "param:" + json); + Request request = new Request.Builder().url(url). + post(RequestBody.create(MediaType.parse("application/json"), json)).addHeader("charset", "GBK").build(); + String string = null; + Response response = null; + System.out.println(request.headers()); + try { + + + response = client.newCall(request).execute(); + ; + + if (!response.isSuccessful()) { + throw new IOException("Unexpected code " + response); + } + + string = response.body().string(); + + System.out.println(string); + + log.info("http util post result:" + string); + + } catch (Exception e) { + log.info(e.getMessage()); + } + return string; + } + + public static String get(String url) { + + log.info("http util get:" + url); + Request request = new Request.Builder().url(url).get().build(); + String result = ""; + try { + Response response = client.newCall(request).execute(); + if (!response.isSuccessful()) { + throw new IOException("Unexpected code " + response); + } + result = response.body().string(); + log.info("http util get result:" + result); + } catch (IOException e) { + log.info("request error" + e.getMessage()); + } + + return result; + } + + + /** + * @param url + * @return + * @throws IOException + * @Description get请求 + */ + public static String sendGet(String url) { + + System.out.println(url); + // 输入流 + InputStream is = null; + BufferedReader br = null; + String result = null; + // 创建httpClient实例 + HttpClient httpClient = new HttpClient(); + // 设置http连接主机服务超时时间:15000毫秒 + // 先获取连接管理器对象,再获取参数对象,再进行参数的赋值 + httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(15000); + // 创建一个Get方法实例对象 + GetMethod getMethod = new GetMethod(url); + // 设置get请求超时为15000毫秒 + getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 15000); + // 设置请求重试机制,默认重试次数:3次,参数设置为true,重试机制可用,false相反 + getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, true)); + try { + // 执行Get方法 + int statusCode = httpClient.executeMethod(getMethod); + // 判断返回码 + if (statusCode != HttpStatus.SC_OK) { + // 如果状态码返回的不是ok,说明失败了,打印错误信息 + log.error("Method faild: " + getMethod.getStatusLine()); + } else { + // 通过getMethod实例,获取远程的一个输入流 + is = getMethod.getResponseBodyAsStream(); + // 包装输入流 + br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + + StringBuffer sbf = new StringBuffer(); + // 读取封装的输入流 + String temp = null; + while ((temp = br.readLine()) != null) { + sbf.append(temp).append("\r\n"); + } + + result = sbf.toString(); + System.out.println(result); + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != is) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + // 释放连接 + getMethod.releaseConnection(); + } + return result; + } + + + /** + * @param url + * @return + * @throws IOException + * @Description get请求 GB2312编码 + */ + public static String sendGetGB(String url) { + // 输入流 + InputStream is = null; + BufferedReader br = null; + String result = null; + // 创建httpClient实例 + HttpClient httpClient = new HttpClient(); + // 设置http连接主机服务超时时间:15000毫秒 + // 先获取连接管理器对象,再获取参数对象,再进行参数的赋值 + httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(15000); + // 创建一个Get方法实例对象 + GetMethod getMethod = new GetMethod(url); + // 设置get请求超时为15000毫秒 + getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 15000); + // 设置请求重试机制,默认重试次数:3次,参数设置为true,重试机制可用,false相反 + getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, true)); + try { + // 执行Get方法 + int statusCode = httpClient.executeMethod(getMethod); + // 判断返回码 + if (statusCode != HttpStatus.SC_OK) { + // 如果状态码返回的不是ok,说明失败了,打印错误信息 + log.error("Method faild: " + getMethod.getStatusLine()); + } else { + // 通过getMethod实例,获取远程的一个输入流 + is = getMethod.getResponseBodyAsStream(); + // 包装输入流 + br = new BufferedReader(new InputStreamReader(is, "GB2312")); + + StringBuffer sbf = new StringBuffer(); + // 读取封装的输入流 + String temp = null; + while ((temp = br.readLine()) != null) { + sbf.append(temp).append("\r\n"); + } + + result = sbf.toString(); + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != is) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + // 释放连接 + getMethod.releaseConnection(); + } + return result; + } + + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendPost(String url, String param) { + + PrintWriter out = null; + BufferedReader in = null; + String result = ""; + try { + URL realUrl = new URL(url); + + log.info("post" + url + param); + // 打开和URL之间的连接 + URLConnection conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); + // 发送POST请求必须设置如下两行 + + conn.setDoOutput(true); + conn.setDoInput(true); + + // 获取URLConnection对象对应的输出流 + out = new PrintWriter(conn.getOutputStream()); + // 发送请求参数 + out.print(param); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( + new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + log.info("发送 POST 请求出现异常!" + e); + e.printStackTrace(); + } + //使用finally块来关闭输出流、输入流 + finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + log.info(result); + return result; + } + + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数 + * @return 所代表远程资源的响应结果 + */ + public static String sendPostJSON(String url, String param) { + System.out.println(url); + System.out.println(param); + PrintWriter out = null; + BufferedReader in = null; + String result = ""; + try { + URL realUrl = new URL(url); + + log.info("post" + url + param); + // 打开和URL之间的连接 + URLConnection conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("content-type", "application/json"); + // 发送POST请求必须设置如下两行 + + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setReadTimeout(30000); + conn.setConnectTimeout(30000); + // 获取URLConnection对象对应的输出流 + out = new PrintWriter(conn.getOutputStream()); + // 发送请求参数 + out.print(param); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( + new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + log.info("发送 POST 请求出现异常!" + e); + e.printStackTrace(); + } + //使用finally块来关闭输出流、输入流 + finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + log.info(result); + return result; + } + + public static String sendGetParam(String url, String param) { + + PrintWriter out = null; + BufferedReader in = null; + String result = ""; + try { + URL realUrl = new URL(url); + + // 打开和URL之间的连接 + URLConnection conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); + // 发送POST请求必须设置如下两行 + + conn.setDoOutput(true); + conn.setDoInput(true); + + // 获取URLConnection对象对应的输出流 + out = new PrintWriter(conn.getOutputStream()); + // 发送请求参数 + out.print(param); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( + new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + log.info("发送 POST 请求出现异常!" + e); + e.printStackTrace(); + } + //使用finally块来关闭输出流、输入流 + finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return result; + } + + //url编码 + public static String getURLEncoderString(String str) { + String result = ""; + if (null == str) { + return ""; + } + try { + result = URLEncoder.encode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return result; + } + + //url解码 + public static String URLDecoderString(String str) { + String result = ""; + if (null == str) { + return ""; + } + try { + result = URLDecoder.decode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return result; + } + + + public static String readHttpResponse(HttpResponse httpResponse) throws ParseException, IOException { + StringBuilder builder = new StringBuilder(); + // 获取响应消息实体 + HttpEntity entity = httpResponse.getEntity(); + // 响应状态 + builder.append("status:" + httpResponse.getStatusLine()); + builder.append("headers:"); + HeaderIterator iterator = httpResponse.headerIterator(); + while (iterator.hasNext()) { + builder.append("\t" + iterator.next()); + } + // 判断响应实体是否为空 + if (entity != null) { + String responseString = EntityUtils.toString(entity); + builder.append("response length:" + responseString.length()); + builder.append("response content:" + responseString.replace("\r\n", "")); + } + return builder.toString(); + } + + /** + * @param url + * @return + * @throws IOException + * @Description get请求 + */ + public static String sendGetAddHead(String url, String head) throws HttpException, IOException { + + System.out.println(url); + // 输入流 + InputStream is = null; + BufferedReader br = null; + String result = null; + // 创建httpClient实例 + HttpClient httpClient = new HttpClient(); + // 设置http连接主机服务超时时间:15000毫秒 + // 先获取连接管理器对象,再获取参数对象,再进行参数的赋值 + httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(10000); + // 创建一个Get方法实例对象 + GetMethod getMethod = new GetMethod(url); + getMethod.addRequestHeader("Access-Token", head); + // 设置get请求超时为15000毫秒 + getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 10000); + // 设置请求重试机制,默认重试次数:3次,参数设置为true,重试机制可用,false相反 + getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, true)); + try { + // 执行Get方法 + int statusCode = httpClient.executeMethod(getMethod); + // 判断返回码 + if (statusCode != HttpStatus.SC_OK) { + // 如果状态码返回的不是ok,说明失败了,打印错误信息 + log.error("Method faild: " + getMethod.getStatusLine()); + } else { + // 通过getMethod实例,获取远程的一个输入流 + is = getMethod.getResponseBodyAsStream(); + // 包装输入流 + br = new BufferedReader(new InputStreamReader(is, "UTF-8")); + + StringBuffer sbf = new StringBuffer(); + // 读取封装的输入流 + String temp = null; + while ((temp = br.readLine()) != null) { + sbf.append(temp).append("\r\n"); + } + + result = sbf.toString(); + System.out.println(result); + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + // 关闭资源 + if (null != br) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != is) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + // 释放连接 + getMethod.releaseConnection(); + } + return result; + } + + + /** + * description 忽略https证书验证 + * + * @author yanzy + * @version 1.0 + * @date 2021/9/8 14:42 + */ + public static HostnameVerifier getHostnameVerifier() { + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }; + return hostnameVerifier; + } + + public static SSLSocketFactory getSSLSocketFactory() { + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, getTrustManager(), new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static TrustManager[] getTrustManager() { + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[]{}; + } + } + }; + return trustAllCerts; + } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/utils/OrderUtil.java b/rights-entity/src/main/java/com/cyjd/rights/utils/OrderUtil.java new file mode 100644 index 0000000..b34a404 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/utils/OrderUtil.java @@ -0,0 +1,28 @@ +package com.cyjd.rights.utils; + +import cn.hutool.core.date.DateUtil; + +import java.util.Date; +import java.util.Random; + +public class OrderUtil { + + /** + * 商户签约号 + * + * @return + */ + public static String getAgreementNo() { + return "A" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + new Random().nextInt(8999) + 1000; + } + + /** + * 商户订单号 + * + * @return + */ + public static String getOutTradeNo() { + return "Y" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + new Random().nextInt(8999) + 1000; + } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayInOrderByAgreementContentReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayInOrderByAgreementContentReq.java new file mode 100644 index 0000000..7b83e42 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayInOrderByAgreementContentReq.java @@ -0,0 +1,67 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :支付宝代扣下单实体类 + */ +@Data +public class AliPayInOrderByAgreementContentReq implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 商户订单号,商家自定义,保持唯一性 + */ + @SerializedName(value = "out_trade_no") + private String outTradeNo; + /** + * 订单标题,不可使用特殊符号 + */ + @SerializedName(value = "subject") + private String subject; + /** + * 本期扣款金额:金额只能小于等于签约时的金额,最小值0.01元 + */ + @SerializedName(value = "total_amount") + private String totalAmount; + + /** + * 协议信息 + */ + @SerializedName(value = "agreement_params") + private AgreementParams agreementParams; + + /** + * 周期扣款代扣场景固定值 + * 是否必填:是 + */ + @SerializedName("scene") + private String scene; + + /** + * 授权码:周期扣款场景需传入签约成功后返回的协议号agreement_no + */ + @SerializedName("auth_code") + private String authCode; + + /** + * 周期扣款固定:CYCLE_PAY_AUTH + */ + @SerializedName(value = "product_code") + private String productCode; + + @Data + public static class AgreementParams{ + /** + * 周期扣款签约协议后返回的agreement_no + * 是否必填:是 + */ + @SerializedName(value = "agreement_no") + private String agreementNo; + } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayInOrderByAgreementReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayInOrderByAgreementReq.java new file mode 100644 index 0000000..4ea6e25 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayInOrderByAgreementReq.java @@ -0,0 +1,51 @@ +package com.cyjd.rights.vo; + +import lombok.Data; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :支付宝代扣下单实体类 + */ +@Data +public class AliPayInOrderByAgreementReq { + /** + * 商户订单号,商家自定义,保持唯一性 + */ + private String outTradeNo; + /** + * 订单标题,不可使用特殊符号 + */ + private String subject; + /** + * 本期扣款金额:金额只能小于等于签约时的金额,最小值0.01元 + */ + private String totalAmount; + + /** + * 授权码:周期扣款场景需传入签约成功后返回的协议号agreement_no + */ + private String authCode; + +// /** +// * 协议信息 +// */ +// private AgreementParams agreementParams; + + /** + * 异步通知地址 + * 是否必填:否 + */ + private String notifyUrl; + +// @Data +// public static class AgreementParams{ +// /** +// * 周期扣款签约协议后返回的agreement_no +// * 是否必填:是 +// */ +// @SerializedName(value = "agreement_no") +// private String agreementNo; +// } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayModifyPlanContentReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayModifyPlanContentReq.java new file mode 100644 index 0000000..fa4b66e --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayModifyPlanContentReq.java @@ -0,0 +1,32 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/17 + * @description :支付宝签约计划变更 + */ +@Data +public class AliPayModifyPlanContentReq implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 支付宝签约号:必选 + */ + @SerializedName(value = "agreement_no") + private String aliAgreementNo; + /** + * 下一次扣款时间:必选 + */ + @SerializedName(value = "deduct_time") + private String deductTime; + + /** + * 修改原因:可选 + */ + @SerializedName(value = "memo") + private String memo; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayModifyPlanReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayModifyPlanReq.java new file mode 100644 index 0000000..5d3b4fe --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayModifyPlanReq.java @@ -0,0 +1,32 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/17 + * @description :支付宝签约计划变更 + */ +@Data +public class AliPayModifyPlanReq implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 支付宝签约号:必选 + */ + @SerializedName(value = "agreement_no") + private String aliAgreementNo; + /** + * 下一次扣款时间:必选 + */ + @SerializedName(value = "deduct_time") + private String deductTime; + + /** + * 修改原因:可选 + */ + @SerializedName(value = "memo") + private String memo; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayQueryPageSignContentReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayQueryPageSignContentReq.java new file mode 100644 index 0000000..cd6d981 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayQueryPageSignContentReq.java @@ -0,0 +1,36 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@Getter +@Setter +@NoArgsConstructor +public class AliPayQueryPageSignContentReq { + + /** + * 协议产品码 + */ + @SerializedName(value = "personal_product_code") + private String personalProductCode; + + /** + * 商户签约号 + */ + @SerializedName(value = "external_agreement_no") + private String externalAgreementNo; + + /** + * 签名场景 + */ + @SerializedName(value = "sign_scene") + private String signScene; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayQueryPageSignReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayQueryPageSignReq.java new file mode 100644 index 0000000..d83cef6 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayQueryPageSignReq.java @@ -0,0 +1,24 @@ +package com.cyjd.rights.vo; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description : + */ +@Getter +@Setter +@NoArgsConstructor +public class AliPayQueryPageSignReq { + private static final long serialVersionUID = 1L; + + /** + * 商户签约号 + */ + private String externalAgreementNo; + + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayTradeCancelReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayTradeCancelReq.java new file mode 100644 index 0000000..c535992 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayTradeCancelReq.java @@ -0,0 +1,29 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/17 + * @description :支付宝收单交易撤销入参 + */ +@Data +public class AliPayTradeCancelReq implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 原支付请求的商户订单号,和支付宝交易号不能同时为空 + */ + @SerializedName(value = "out_trade_no") + private String outTradeNo; + + /** + * 支付宝交易号,和商户订单号不能同时为空 + */ + @SerializedName(value = "trade_no") + private String tradeNo; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayTradeQueryReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayTradeQueryReq.java new file mode 100644 index 0000000..1fea767 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayTradeQueryReq.java @@ -0,0 +1,29 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/17 + * @description :支付宝收单交易撤销入参 + */ +@Data +public class AliPayTradeQueryReq implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 原支付请求的商户订单号,和支付宝交易号不能同时为空 + */ + @SerializedName(value = "out_trade_no") + private String outTradeNo; + + /** + * 支付宝交易号,和商户订单号不能同时为空 + */ + @SerializedName(value = "trade_no") + private String tradeNo; + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUnSignContentReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUnSignContentReq.java new file mode 100644 index 0000000..13581c8 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUnSignContentReq.java @@ -0,0 +1,32 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/17 + * @description :支付宝签约计划变更 + */ +@Data +public class AliPayUnSignContentReq implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 商户签约号:必选 + */ + @SerializedName(value = "external_agreement_no") + private String externalAgreementNo; + /** + * + */ + @SerializedName(value = "personal_product_code") + private String personalProductCode; + + /** + * 签名场景 + */ + @SerializedName(value = "sign_scene") + private String signScene; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUnSignReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUnSignReq.java new file mode 100644 index 0000000..04af484 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUnSignReq.java @@ -0,0 +1,18 @@ +package com.cyjd.rights.vo; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +/** + * @author :WXC + * @Date :2023/05/17 + * @description :支付宝签约计划变更 + */ +@Data +public class AliPayUnSignReq { + /** + * 商户签约号:必选 + */ + @SerializedName(value = "external_agreement_no") + private String externalAgreementNo; +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUserPageSignContentReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUserPageSignContentReq.java new file mode 100644 index 0000000..0085f1b --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUserPageSignContentReq.java @@ -0,0 +1,164 @@ +package com.cyjd.rights.vo; + +import com.cyjd.rights.constant.EnumPeriodType; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :支付宝个人协议页面签约入参 + */ +@Data +public class AliPayUserPageSignContentReq implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 商户签约号:代扣协议中标示用户的唯一签约号(确保在商家系统中唯一)。用户支持一对多,即同一个商家下, + * 同一个用户可以有多套签约关系。通过商家外部签约号和场景参数来区分签约协议。若签约时传入了签约号及场景参数,后续查询协议和解约时也必须传入 + */ + @SerializedName(value = "external_agreement_no") + private String externalAgreementNo; + + /** + * 周期扣款产品码固定为 CYCLE_PAY_AUTH + * 是否必填:是 + * 示例值:CYCLE_PAY_AUTH + */ + @SerializedName(value = "product_code") + private String productCode; + + /** + * 周期扣款个人签约产品码固定为 CYCLE_PAY_AUTH_P。 + * 是否必填:是 + * 示例值:CYCLE_PAY_AUTH_P + */ + @SerializedName(value = "personal_product_code") + private String personalProductCode; + + /** + * 签约场景,具体参数请商家接入时根据自身行业进行判断,点击查看全部 常见场景值。 + * 是否必填:是 + * 示例值:INDUSTRY|MOBILE (移动支付) + */ + @SerializedName(value = "sign_scene") + private String signScene; + + /** + * 当前用户签约请求的协议有效周期。 + * 是否必填:否 + * 示例值:2m + */ + @SerializedName(value = "sign_validity_period") + private String signValidityPeriod; + + /** + * 接入渠道:H5 页面签约可直接拼接 schema 的请求地址。 + * 是否必填:是 + */ + @SerializedName(value = "access_params") + private AccessParams accessParams; + + /** + * 周期管控规则 + * 是否必填:是 + */ + @SerializedName(value = "period_rule_params") + private PeriodRuleParams periodRuleParams; + + /** + * 实名用户信息 + * 是否必填:否 + */ + @SerializedName(value = "identity_params") + private identityParams identityParams; + + /** + * 接入渠道 + */ + @Data + @NoArgsConstructor + public static class AccessParams implements Serializable{ + private static final long serialVersionUID = 1L; + /** + * ALIPAYAPP :支付宝客户端 H5 页面签约。 + * 是否必填:是 + */ + @SerializedName(value = "channel") + private String channel; + } + + /** + * 周期管控规则 + */ + @Data + @NoArgsConstructor + public static class PeriodRuleParams implements Serializable{ + private static final long serialVersionUID = 1L; + /** + * 扣款周期数: + * 周期数,与 period_type 组合使用确定扣款周期,例如 period_type 为 DAY,period = 90,则扣款周期为 90 天。 + * 如果 period_type 为 DAY,period不能小于7 + * 是否必填:是 + * 示例值:7 + */ + @SerializedName(value = "period") + private String period; + /** + * 周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH + * 是否必填:是 + * 示例值:DAY + */ + @SerializedName(value = "period_type") + private EnumPeriodType periodType; + /** + * 商户发起首次扣款的时间:如果 period_type 为 MONTH,execute_time默认重置到下月一日 + * 是否必填:是 + * 示例值:2022-05-22 + */ + @SerializedName(value = "execute_time") + private String executeTime; + /** + * 单次扣款最大金额,必填,即每次发起扣款时限制的最大金额,单位为元。商家每次发起扣款都不允许大于此金额 + * 是否必填:是 + * 示例值:0.01 + */ + @SerializedName(value = "single_amount") + private String singleAmount; + /** + * 周期内允许扣款的总金额 + * 是否必填:否 + * 示例值:0.02 + */ + @SerializedName(value = "total_amount") + private String totalAmount; + /** + * 总扣款次数 + * 是否必填:否 + * 示例值:2022-05-22 + */ + @SerializedName(value = "total_payments") + private String totalPayments; + } + + /** + * 用户实名信息参数 + */ + @Data + @NoArgsConstructor + public static class identityParams implements Serializable{ + private static final long serialVersionUID = 1L; + @SerializedName(value = "user_name") + private String userName; + @SerializedName(value = "cert_no") + private String certNo; + @SerializedName(value = "identity_hash") + private String identityHash; + @SerializedName(value = "sign_user_id") + private String signUserId; + } + +} diff --git a/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUserPageSignReq.java b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUserPageSignReq.java new file mode 100644 index 0000000..d414cc8 --- /dev/null +++ b/rights-entity/src/main/java/com/cyjd/rights/vo/AliPayUserPageSignReq.java @@ -0,0 +1,144 @@ +package com.cyjd.rights.vo; + +import com.cyjd.rights.constant.EnumPeriodType; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author :WXC + * @Date :2023/05/16 + * @description :支付宝个人协议页面签约入参 + */ +@Data +public class AliPayUserPageSignReq implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 商户签约号:代扣协议中标示用户的唯一签约号(确保在商家系统中唯一)。用户支持一对多,即同一个商家下, + * 同一个用户可以有多套签约关系。通过商家外部签约号和场景参数来区分签约协议。若签约时传入了签约号及场景参数,后续查询协议和解约时也必须传入 + */ + @SerializedName(value = "external_agreement_no") + private String externalAgreementNo; + + + /** + * 签约场景,具体参数请商家接入时根据自身行业进行判断,点击查看全部 常见场景值。 + * 是否必填:是 + * 示例值:INDUSTRY|MOBILE (移动支付) + */ + @SerializedName(value = "sign_scene") + private String signScene; + + /** + * 当前用户签约请求的协议有效周期。 + * 是否必填:否 + * 示例值:2m + */ + @SerializedName(value = "sign_validity_period") + private String signValidityPeriod; + + /** + * 周期管控规则 + * 是否必填:是 + */ + @SerializedName(value = "period_rule_params") + private PeriodRuleParams periodRuleParams; + + /** + * 实名用户信息 + * 是否必填:否 + */ + @SerializedName(value = "identity_params") + private identityParams identityParams; + + /** + * 跳转商家处理地址。则签约流程中会在签约完成后跳转至此地址,没有传这个参数则不跳转,会停留在支付宝客户端首页。 + * 是否必填:否 + */ + private String returnUrl; + + /** + * 异步通知地址 + * 是否必填:否 + */ + private String notifyUrl; + + /** + * 是否是页面签约:页面签约:H5/PC + */ + private Boolean isPage = true; + + private Integer type; + + private Integer businessType; + + + + /** + * 周期管控规则 + */ + @Data + @NoArgsConstructor + public static class PeriodRuleParams implements Serializable{ + private static final long serialVersionUID = 1L; + /** + * 扣款周期数: + * 周期数,与 period_type 组合使用确定扣款周期,例如 period_type 为 DAY,period = 90,则扣款周期为 90 天。 + * 如果 period_type 为 DAY,period不能小于7 + * 是否必填:是 + * 示例值:7 + */ + @SerializedName(value = "period") + private String period; + /** + * 周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH + * 是否必填:是 + * 示例值:DAY + */ + @SerializedName(value = "period_type") + private EnumPeriodType periodType; + /** + * 单次扣款最大金额,必填,即每次发起扣款时限制的最大金额,单位为元。商家每次发起扣款都不允许大于此金额 + * 是否必填:是 + * 示例值:0.01 + */ + @SerializedName(value = "single_amount") + private String singleAmount; + /** + * 周期内允许扣款的总金额 + * 是否必填:否 + * 示例值:0.02 + */ + @SerializedName(value = "total_amount") + private String totalAmount; + /** + * 总扣款次数 + * 是否必填:否 + * 示例值:2022-05-22 + */ + @SerializedName(value = "total_payments") + private String totalPayments; + } + + + /** + * 用户实名信息参数 + */ + @Data + @NoArgsConstructor + public static class identityParams implements Serializable{ + private static final long serialVersionUID = 1L; + @SerializedName(value = "user_name") + private String userName; + @SerializedName(value = "cert_no") + private String certNo; + @SerializedName(value = "identity_hash") + private String identityHash; + @SerializedName(value = "sign_user_id") + private String signUserId; + } + +} diff --git a/rights-interface/.gitignore b/rights-interface/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/rights-interface/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/rights-interface/pom.xml b/rights-interface/pom.xml new file mode 100644 index 0000000..692a8e5 --- /dev/null +++ b/rights-interface/pom.xml @@ -0,0 +1,27 @@ + + + + + com.cyjd.rights + parent + 0.0.1 + + 4.0.0 + 接口层 + rights-interface + + + 8 + 8 + UTF-8 + + + + com.cyjd.rights + rights-entity + 0.0.1 + + + \ No newline at end of file diff --git a/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPayOrderService.java b/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPayOrderService.java new file mode 100644 index 0000000..c884b3c --- /dev/null +++ b/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPayOrderService.java @@ -0,0 +1,7 @@ +package com.cyjd.rights.business.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.cyjd.rights.entity.AliPayOrderEntity; + +public interface AliPayOrderService extends IService { +} diff --git a/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPayService.java b/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPayService.java new file mode 100644 index 0000000..a29bee1 --- /dev/null +++ b/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPayService.java @@ -0,0 +1,62 @@ +package com.cyjd.rights.business.service; + + +import com.alipay.api.response.AlipayTradeCancelResponse; +import com.alipay.api.response.AlipayTradePayResponse; +import com.alipay.api.response.AlipayUserAgreementExecutionplanModifyResponse; +import com.alipay.api.response.AlipayUserAgreementUnsignResponse; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; +import com.cyjd.rights.vo.*; + +/** + * 描述: + * 创建人 白王 + * on 2023/05/18 0018 15:15 + * Version 1.0 + */ + +public interface AliPayService { + /** + * 签约 + * @return + */ + String signUp(AliPayUserPageSignReq aliPayUserPageSignReq); + /** + * 查询签约结果 + * @param aliPayQueryPageSignReq + * @return + */ + public boolean querySign(AliPayQueryPageSignReq aliPayQueryPageSignReq); + /** + * 根据签约协议号,发起主动扣款 + * @param inOrderByAgreementReq + * @return + */ + public AlipayTradePayResponse aliPayTradePayByAgreement(AliPayInOrderByAgreementReq inOrderByAgreementReq, AliPaySigningOrderEntity aliPaySigningOrderEntity); + + /** + * 根据商户订单号/支付宝交易号查询 支付状态 + * @param aliPayTradeQueryReq + * @return + */ + boolean queryOrder(AliPayTradeQueryReq aliPayTradeQueryReq); + /** + * 交易撤销 + * @param tradeCancelReq + * @return + */ + AlipayTradeCancelResponse aliPayTradeCancel(AliPayTradeCancelReq tradeCancelReq); + /** + * 变更签约 + * @param modifyPlanReq + * @return + */ + public AlipayUserAgreementExecutionplanModifyResponse aliPayModifyPlan(AliPayModifyPlanReq modifyPlanReq); + /** + * 解除签约 + * @return + */ + public AlipayUserAgreementUnsignResponse aliPayUnSign(AliPayUnSignReq aliPayUnSignReq); + + +} diff --git a/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPaySigningOrderService.java b/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPaySigningOrderService.java new file mode 100644 index 0000000..fcc31b0 --- /dev/null +++ b/rights-interface/src/main/java/com/cyjd/rights/business/service/AliPaySigningOrderService.java @@ -0,0 +1,13 @@ +package com.cyjd.rights.business.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; + +public interface AliPaySigningOrderService extends IService { + /** + * 检查签约状态 + * @param mobile + * @return + */ + Boolean checkSigningStatus(String mobile); +} diff --git a/rights-interface/src/main/java/com/cyjd/rights/business/service/RightsOrderService.java b/rights-interface/src/main/java/com/cyjd/rights/business/service/RightsOrderService.java new file mode 100644 index 0000000..0e2c6fb --- /dev/null +++ b/rights-interface/src/main/java/com/cyjd/rights/business/service/RightsOrderService.java @@ -0,0 +1,7 @@ +package com.cyjd.rights.business.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.cyjd.rights.entity.RightsOrderEntity; + +public interface RightsOrderService extends IService { +} diff --git a/rights-interface/src/main/java/com/cyjd/rights/business/service/YunmeiService.java b/rights-interface/src/main/java/com/cyjd/rights/business/service/YunmeiService.java new file mode 100644 index 0000000..588dae2 --- /dev/null +++ b/rights-interface/src/main/java/com/cyjd/rights/business/service/YunmeiService.java @@ -0,0 +1,56 @@ +package com.cyjd.rights.business.service; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.cyjd.rights.dto.DirectBuyOrderDto; +import com.cyjd.rights.dto.OrderNotifyDto; + +public interface YunmeiService { + + /** + * 获取产品列表 + * @return - + */ + JSONArray getProductList(); + + /** + * 根据商品id获取商品详情 + * @param skuId 商品Id + * @return - + */ + //JSONObject getProductDetails(Long skuId); + + /** + * 直充下单 + * @param params 下单参数 + * @return - + */ + JSONObject directBuyOrder(DirectBuyOrderDto params); + + /** + * 卡密下单 + * @param params + * @return + */ + //JSONObject cardBuyOrder(CardBuyOrderDto params); + + /** + * 查询订单详情 + * @param orderNo 订单id + * @return - + */ + //JSONObject getOrderDetails(String orderNo); + + /** + * 查询商户余额 + * @return - + */ + JSONObject getBalance(); + + /** + * 订单通知回调 + * @param params 回调参数 + * @return - + */ + String orderNotify(OrderNotifyDto params); +} diff --git a/rights-server/.gitignore b/rights-server/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/rights-server/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/rights-server/pom.xml b/rights-server/pom.xml new file mode 100644 index 0000000..960a8ed --- /dev/null +++ b/rights-server/pom.xml @@ -0,0 +1,29 @@ + + + + + parent + com.cyjd.rights + 0.0.1 + + + 4.0.0 + 服务类 + rights-server + + + + com.cyjd.rights + rights-interface + 0.0.1 + + + + 8 + 8 + UTF-8 + + + \ No newline at end of file diff --git a/rights-server/src/main/java/com/cyjd/rights/business/mapper/AliPayOrderMapper.java b/rights-server/src/main/java/com/cyjd/rights/business/mapper/AliPayOrderMapper.java new file mode 100644 index 0000000..7aa8139 --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/mapper/AliPayOrderMapper.java @@ -0,0 +1,7 @@ +package com.cyjd.rights.business.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cyjd.rights.entity.AliPayOrderEntity; + +public interface AliPayOrderMapper extends BaseMapper { +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/mapper/AliPaySigningOrderMapper.java b/rights-server/src/main/java/com/cyjd/rights/business/mapper/AliPaySigningOrderMapper.java new file mode 100644 index 0000000..7c4d784 --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/mapper/AliPaySigningOrderMapper.java @@ -0,0 +1,7 @@ +package com.cyjd.rights.business.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; + +public interface AliPaySigningOrderMapper extends BaseMapper { +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/mapper/RightsOrderMapper.java b/rights-server/src/main/java/com/cyjd/rights/business/mapper/RightsOrderMapper.java new file mode 100644 index 0000000..8c31a6d --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/mapper/RightsOrderMapper.java @@ -0,0 +1,8 @@ +package com.cyjd.rights.business.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cyjd.rights.entity.AliPayOrderEntity; +import com.cyjd.rights.entity.RightsOrderEntity; + +public interface RightsOrderMapper extends BaseMapper { +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPayOrderServiceImpl.java b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPayOrderServiceImpl.java new file mode 100644 index 0000000..72a3ada --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPayOrderServiceImpl.java @@ -0,0 +1,13 @@ +package com.cyjd.rights.business.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cyjd.rights.business.mapper.AliPayOrderMapper; +import com.cyjd.rights.business.service.AliPayOrderService; +import com.cyjd.rights.entity.AliPayOrderEntity; +import lombok.extern.java.Log; +import org.springframework.stereotype.Service; + +@Service +@Log +public class AliPayOrderServiceImpl extends ServiceImpl implements AliPayOrderService { +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPayServiceImpl.java b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPayServiceImpl.java new file mode 100644 index 0000000..57b6a67 --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPayServiceImpl.java @@ -0,0 +1,283 @@ +package com.cyjd.rights.business.service.impl; + +import com.alipay.api.*; +import com.alipay.api.request.*; +import com.alipay.api.response.*; +import com.cyjd.rights.beans.AliPayProperties; +import com.cyjd.rights.business.service.AliPayOrderService; +import com.cyjd.rights.business.service.AliPayService; +import com.cyjd.rights.constant.AliPayConstant; +import com.cyjd.rights.entity.AliPayOrderEntity; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; +import com.cyjd.rights.utils.AlipayRequestBuilderUtil; +import com.cyjd.rights.vo.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * 描述: + * 创建人 白王 + * on 2023/05/18 0018 15:16 + * Version 1.0 + */ +@Service +@Slf4j +public class AliPayServiceImpl implements AliPayService { + + + /** + * 支付配置 + */ + @Resource + private AliPayProperties aliPayProperties; + @Resource + private AlipayRequestBuilderUtil alipayRequestBuilderUtil; + + @Autowired + private AliPayOrderService aliPayOrderService; + + private CertAlipayRequest certAlipayRequest; + + + @PostConstruct + public void init() { + CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); + //设置文件地址 +// if (isSkipSign){ +// aliPayProperties.setCertPath("D:\\daima\\hy\\ringback-q\\02Ypcl\\01Code\\01Plantform\\Server\\vrbt-client-controller\\src\\main\\resources\\config\\"); +// }else { +// aliPayProperties.setCertPath("/home/ypcl/server-client/config/"); +// } + certAlipayRequest.setServerUrl(AliPayConstant.serverUrl); + certAlipayRequest.setAppId(aliPayProperties.getAppId()); + certAlipayRequest.setPrivateKey(aliPayProperties.getPrivateKey()); + certAlipayRequest.setFormat(AlipayConstants.FORMAT_JSON); + certAlipayRequest.setCharset(AlipayConstants.CHARSET_UTF8); + certAlipayRequest.setSignType(AlipayConstants.SIGN_TYPE_RSA2); + certAlipayRequest.setCertPath(aliPayProperties.getCertPath() + "appCertPublicKey_" + aliPayProperties.getAppId() + ".crt"); + certAlipayRequest.setAlipayPublicCertPath(aliPayProperties.getCertPath() + "alipayCertPublicKey_RSA2.crt"); + certAlipayRequest.setRootCertPath(aliPayProperties.getCertPath() + "alipayRootCert.crt"); + this.certAlipayRequest = certAlipayRequest; + } + + + /* + * 签约 + */ + @Override + public String signUp(AliPayUserPageSignReq aliPayUserPageSignReq) { + Assert.isTrue(StringUtils.isNotBlank(aliPayUserPageSignReq.getExternalAgreementNo()), "商户签约号不能为空"); + Assert.isTrue(Objects.nonNull(aliPayUserPageSignReq.getPeriodRuleParams()), "周期管控规则不能为空"); + AliPayUserPageSignReq.PeriodRuleParams periodRuleParams = aliPayUserPageSignReq.getPeriodRuleParams(); + Assert.isTrue(StringUtils.isNotBlank(periodRuleParams.getPeriod()), "签约规则周期数不能为空"); + Assert.isTrue(Objects.nonNull(periodRuleParams.getPeriodType()), "签约规则周期类型不能为空"); + Assert.isTrue(StringUtils.isNotBlank(periodRuleParams.getSingleAmount()), "单次扣款最大金额不能为空"); + try { + + + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayUserAgreementPageSignRequest request = + alipayRequestBuilderUtil.buildAlipayUserAgreementPageSignRequest(aliPayUserPageSignReq); + System.out.println(request.getBizContent()); + request.setReturnUrl("https://m.miguring.cn/#/hotVIPpayback"); + //周期扣款协议信息 + //签约参数。如果希望在sdk中支付并签约,需要在这里传入签约信息。周期扣款场景 product_code 为 CYCLE_PAY_AUTH 时必填 + log.info("发起周期扣款签约请求,入参:{}", request.getBizContent()); + AlipayUserAgreementPageSignResponse response; + //是否页面 + if (aliPayUserPageSignReq.getIsPage()) { + response = alipayClient.pageExecute(request, "get"); + } else { + response = alipayClient.sdkExecute(request); + } + if (response.isSuccess()) { + log.info("用户内部系统签约号{}:周期扣款,发起签约成功", aliPayUserPageSignReq.getExternalAgreementNo()); + //组装签约地址,前端通过scheme唤醒支付宝app进行签约 + String body = response.getBody(); +// body = body.replaceAll("https://openapi.alipay.com/gateway.do?", body); +// body = "alipays://platformapi/startapp?appId=60000157&appClearTop=false&startMultApp=YES&sign_params="+body; + return body; + } + log.info("用户内部系统签约号{}:周期扣款,发起签约失败:{}", aliPayUserPageSignReq.getExternalAgreementNo(), response.getSubMsg()); + } catch (AlipayApiException e) { + e.printStackTrace(); + log.error("用户内部系统签约号{}:周期扣款,发起签约异常:{}", aliPayUserPageSignReq.getExternalAgreementNo(), e.getMessage()); + } + return null; + } + + /* + * 查询签约状态 + */ + @Override + public boolean querySign(AliPayQueryPageSignReq aliPayQueryPageSignReq) { + Assert.isTrue(StringUtils.isNotBlank(aliPayQueryPageSignReq.getExternalAgreementNo()), "商户签约号不能为空"); + try { + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayUserAgreementQueryRequest request = alipayRequestBuilderUtil.buildAlipayUserAgreementQueryRequest(aliPayQueryPageSignReq); + String externalAgreementNo = aliPayQueryPageSignReq.getExternalAgreementNo(); + //log.info("用户内部系统签约号{}:查询周期扣款签约结果入参:{}", externalAgreementNo, request.getBizContent()); + AlipayUserAgreementQueryResponse response = null; + System.out.println("=========================="); + System.out.println(request.getBizContent()); + response = alipayClient.certificateExecute(request); + if (response.isSuccess()) { + //log.info("用户内部系统签约号{}:查询周期扣款签约结果,调用成功", externalAgreementNo); + + return "NORMAL".equals(response.getStatus()); + } else { + //log.info("用户内部系统签约号{}:查询周期扣款签约结果,调用失败:{}", externalAgreementNo, response.getSubMsg()); + } + } catch (AlipayApiException e) { + e.printStackTrace(); + } + return false; + } + + /* + * 扣款 + */ + @Override + public AlipayTradePayResponse aliPayTradePayByAgreement(AliPayInOrderByAgreementReq inOrderByAgreementReq, AliPaySigningOrderEntity aliPaySigningOrderEntity) { + System.out.println("=========================================走到这里了=========================================="); + Assert.isTrue(StringUtils.isNotBlank(inOrderByAgreementReq.getOutTradeNo()), "订单号不能为空"); + Assert.isTrue(StringUtils.isNotBlank(inOrderByAgreementReq.getTotalAmount()), "本次扣款金额不能为空"); + Assert.isTrue(StringUtils.isNotBlank(inOrderByAgreementReq.getAuthCode()), "支付宝签约号不能为空"); + Assert.isTrue(StringUtils.isNotBlank(inOrderByAgreementReq.getSubject()), "订单标题不能为空"); + try { + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayTradePayRequest request = alipayRequestBuilderUtil.buildAlipayTradePayAgreementRequest(inOrderByAgreementReq); + System.out.println("=========================="); + System.out.println(request.getBizContent()); + log.info("支付宝用户签约号{}:查询签约用户,进行自动续期扣费:{}", inOrderByAgreementReq.getAuthCode(), request.getBizContent()); + //保存代扣结果 + AlipayTradePayResponse response = alipayClient.certificateExecute(request); + AliPayOrderEntity aliPayOrderEntity = new AliPayOrderEntity(); + aliPayOrderEntity.setAliUserId(aliPaySigningOrderEntity.getAliUserId()); + aliPayOrderEntity.setOrderId(System.currentTimeMillis()+""); + aliPayOrderEntity.setMobile(aliPaySigningOrderEntity.getMobile()); + aliPayOrderEntity.setLinkId(aliPaySigningOrderEntity.getLinkId()); + aliPayOrderEntity.setLinkName(aliPaySigningOrderEntity.getLinkName()); + aliPayOrderEntity.setBusinessType(1); + aliPayOrderEntity.setIsPage(aliPaySigningOrderEntity.getIsPage()); + aliPayOrderEntity.setOrderTime(LocalDateTime.now()); + aliPayOrderEntity.setPrice(aliPaySigningOrderEntity.getPrice()); + aliPayOrderEntity.setSignCode(inOrderByAgreementReq.getAuthCode()); + System.out.println(aliPaySigningOrderEntity.getOtherOrderId()+"======================"); + aliPayOrderEntity.setOtherOrderId(aliPaySigningOrderEntity.getOtherOrderId()); + if (response.isSuccess()) { + aliPayOrderEntity.setStatus(2); //最终结果要看代扣回调,这个返回值可能被篡改 + log.info("支付宝用户签约号{}:周期扣款,主动扣费成功", inOrderByAgreementReq.getAuthCode()); + } else { + aliPayOrderEntity.setStatus(0); //扣费失败 + log.info("支付宝用户签约号{}:周期扣款,主动扣费失败:{}", inOrderByAgreementReq.getAuthCode(), response.getSubMsg()); + } + System.out.println("支付订单保存============================================="+aliPayOrderEntity); + aliPayOrderService.save(aliPayOrderEntity); + return response; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /* + * 查询支付状态 + */ + @Override + public boolean queryOrder(AliPayTradeQueryReq aliPayTradeQueryReq) { + Assert.isTrue(!((StringUtils.isBlank(aliPayTradeQueryReq.getTradeNo()) && StringUtils.isBlank(aliPayTradeQueryReq.getOutTradeNo()))), "支付宝交易号,和商户订单号不能同时为空!"); + try { + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayTradeQueryRequest alipayTradeQueryRequest = alipayRequestBuilderUtil.buildAlipayTradeQueryRequest(aliPayTradeQueryReq); + System.out.println("=========================="); + System.out.println(alipayTradeQueryRequest); + AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.certificateExecute(alipayTradeQueryRequest); + return "TRADE_SUCCESS".equals(alipayTradeQueryResponse.getTradeStatus()); + } catch (AlipayApiException e) { + e.printStackTrace(); + } + return false; + } + + /* + * 交易撤销 + */ + @Override + public AlipayTradeCancelResponse aliPayTradeCancel(AliPayTradeCancelReq tradeCancelReq) { + Assert.isTrue(!((StringUtils.isBlank(tradeCancelReq.getTradeNo()) && StringUtils.isBlank(tradeCancelReq.getOutTradeNo()))), "支付宝交易号,和商户订单号不能同时为空!"); + try { + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayTradeCancelRequest request = alipayRequestBuilderUtil.buildAlipayTradeCancelRequest(tradeCancelReq); + //log.info("支付宝统一收单撤销接口调用:request{}", request.getBizContent()); + AlipayTradeCancelResponse response = alipayClient.certificateExecute(request); + return response; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /* + * 变更签约 + */ + @Override + public AlipayUserAgreementExecutionplanModifyResponse aliPayModifyPlan(AliPayModifyPlanReq modifyPlanReq) { + Assert.isTrue(StringUtils.isNotBlank(modifyPlanReq.getAliAgreementNo()), "支付宝签约号必填!"); + Assert.isTrue(StringUtils.isNotBlank(modifyPlanReq.getDeductTime()), "下一次扣款时间必填!"); + String agreementNo = modifyPlanReq.getAliAgreementNo(); + try { + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayUserAgreementExecutionplanModifyRequest request = alipayRequestBuilderUtil.buildAlipayUserAgreementExecutionplanModifyRequest(modifyPlanReq); + //log.info("用户签约号{}:周期扣款-修改协议执行计划入参:{}", agreementNo, request.getBizContent()); + AlipayUserAgreementExecutionplanModifyResponse response = alipayClient.certificateExecute(request); + if (response.isSuccess()) { + //log.info("用户签约号{}:周期扣款-修改协议执行计划,调用成功", agreementNo); + return response; + } else { + //log.info("用户签约号{}:周期扣款-修改协议执行计划,调用失败:{}", agreementNo, response.getSubMsg()); + } + } catch (AlipayApiException e) { + e.printStackTrace(); + //log.error("用户签约号{}:周期扣款-修改协议执行计划,调用异常:{}", agreementNo, e); + } + return null; + } + + /* + * 解除签约 + */ + @Override + public AlipayUserAgreementUnsignResponse aliPayUnSign(AliPayUnSignReq aliPayUnSignReq) { + Assert.isTrue(StringUtils.isNotBlank(aliPayUnSignReq.getExternalAgreementNo()), "签约号必填!"); + try { + AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); + AlipayUserAgreementUnsignRequest request = alipayRequestBuilderUtil.buildAlipayUserAgreementUnsignRequest(aliPayUnSignReq); + //log.info("签约号{}:周期扣款-解除签约入参:{}", aliPayUnSignReq.getExternalAgreementNo(), request.getBizContent()); + AlipayUserAgreementUnsignResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + //log.info("用户内部系统签约号{}:周期扣款-解除签约,调用成功", aliPayUnSignReq.getExternalAgreementNo()); + return response; + } else { + //log.info("用户内部系统签约号{}:周期扣款-解除签约,调用失败:{}", aliPayUnSignReq.getExternalAgreementNo(), response.getSubMsg()); + } + } catch (AlipayApiException e) { + e.printStackTrace(); + //log.error("用户内部系统签约号{}:周期扣款-解除签约,调用异常:{}", aliPayUnSignReq.getExternalAgreementNo(), e); + } + return null; + } + + + + +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPaySigningOrderImpl.java b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPaySigningOrderImpl.java new file mode 100644 index 0000000..47fed1a --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/AliPaySigningOrderImpl.java @@ -0,0 +1,21 @@ +package com.cyjd.rights.business.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cyjd.rights.business.mapper.AliPaySigningOrderMapper; +import com.cyjd.rights.business.service.AliPaySigningOrderService; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; +import lombok.extern.java.Log; +import org.springframework.stereotype.Service; + +@Service +@Log +public class AliPaySigningOrderImpl extends ServiceImpl implements AliPaySigningOrderService { + @Override + public Boolean checkSigningStatus(String mobile) { + AliPaySigningOrderEntity paySigningOrderEntity = this.getOne(new QueryWrapper().eq("mobile", mobile).orderByDesc("order_time")); + //paySigningOrderEntity.get + return null; + } +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/service/impl/RightsOrderServiceImpl.java b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/RightsOrderServiceImpl.java new file mode 100644 index 0000000..dd33f43 --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/RightsOrderServiceImpl.java @@ -0,0 +1,14 @@ +package com.cyjd.rights.business.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cyjd.rights.business.mapper.RightsOrderMapper; +import com.cyjd.rights.business.service.RightsOrderService; +import com.cyjd.rights.entity.RightsOrderEntity; +import lombok.extern.java.Log; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Log +public class RightsOrderServiceImpl extends ServiceImpl implements RightsOrderService { +} diff --git a/rights-server/src/main/java/com/cyjd/rights/business/service/impl/YunmeiServiceImpl.java b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/YunmeiServiceImpl.java new file mode 100644 index 0000000..8b59daa --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/business/service/impl/YunmeiServiceImpl.java @@ -0,0 +1,356 @@ +package com.cyjd.rights.business.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.cyjd.rights.business.service.AliPayOrderService; +import com.cyjd.rights.business.service.AliPaySigningOrderService; +import com.cyjd.rights.business.service.RightsOrderService; +import com.cyjd.rights.business.service.YunmeiService; +import com.cyjd.rights.config.YunmeiConfig; +import com.cyjd.rights.constant.YunmeiConstant; +import com.cyjd.rights.dto.DirectBuyOrderDto; +import com.cyjd.rights.dto.OrderNotifyDto; +import com.cyjd.rights.entity.AliPayOrderEntity; +import com.cyjd.rights.entity.AliPaySigningOrderEntity; +import com.cyjd.rights.entity.RightsOrderEntity; +import com.cyjd.rights.enums.YunmeiCallbackEnum; +import com.cyjd.rights.enums.YunmeiEnum; +import com.cyjd.rights.utils.HttpUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +@Service +@Slf4j +public class YunmeiServiceImpl implements YunmeiService { + + + @Autowired + private YunmeiConfig yunmeiConfig; + @Autowired + private AliPayOrderService aliPayOrderService; + @Autowired + private AliPaySigningOrderService aliPaySigningOrderService; + @Autowired + private RightsOrderService rightsOrderService; + + @Override + public JSONArray getProductList() { + long timeMillis = System.currentTimeMillis(); + String signContent = "app_id=" + yunmeiConfig.getAppId() + "×tamp=" + timeMillis + + "&version=" + yunmeiConfig.getVersion() + "&app_secret=" + yunmeiConfig.getAppSecret(); + log.debug("签名明文为:{}", signContent); + String sign = DigestUtils.md5Hex(signContent).toUpperCase(); + Map map = new HashMap<>(); + map.put("app_id", yunmeiConfig.getAppId()); + map.put("timestamp", timeMillis); + map.put("version", yunmeiConfig.getVersion()); + map.put("biz_content", ""); + map.put("sign", sign); + //JSONObject result = restTemplate.postForObject(yunmeiConfig.getUrl() + YunmeiConstant.PRODUCT_LIST,map, JSONObject.class); + String res = HttpUtils.sendPostJSON(yunmeiConfig.getUrl() + YunmeiConstant.PRODUCT_LIST, JSON.toJSONString(map)); + JSONObject resJSON = JSONObject.parseObject(res); + if (resJSON != null && !resJSON.getString("retcode").equals(YunmeiEnum.SUCCESS.getCode().toString())) { + log.error("###获取云媒产品列表失败!错误码为:{},错误信息为:{}", resJSON.getString("retcode"), resJSON.getString("retmsg")); + //throw new ServiceException(result.getString("retmsg"),Integer.parseInt(result.getString("retcode"))); + } + return resJSON.getJSONArray("data"); + } + +// @Override +// public JSONObject getProductDetails(Long skuId) { +// long timeMillis = System.currentTimeMillis(); +// Map bizMap = new HashMap<>(); +// bizMap.put("sku_id",skuId); +// String bizContent = JSON.toJSONString(bizMap); +// String signContent = "app_id="+yunmeiConfig.getAppId()+"&biz_content="+ bizContent +"×tamp="+timeMillis +// +"&version="+yunmeiConfig.getVersion()+"&app_secret="+yunmeiConfig.getAppSecret(); +// log.debug("签名明文为:{}",signContent); +// String sign = DigestUtils.md5Hex(signContent).toUpperCase(); +// Map map = new HashMap<>(); +// map.put("app_id",yunmeiConfig.getAppId()); +// map.put("timestamp", timeMillis); +// map.put("version", yunmeiConfig.getVersion()); +// map.put("biz_content", bizContent); +// map.put("sign",sign); +// JSONObject result = restTemplate.postForObject(yunmeiConfig.getUrl() + YunmeiConstant.PRODUCT_DETAILS, map, JSONObject.class); +// if(result != null){ +// if(!result.getString("retcode").equals(YunmeiEnum.SUCCESS.getCode().toString())){ +// log.error("###获取云媒产品【{}】详情失败!错误码为:{},错误信息为:{}",skuId,result.getString("retcode"),result.getString("retmsg")); +// //throw new ServiceException(result.getString("retmsg"),Integer.parseInt(result.getString("retcode"))); +// } +// if(result.getJSONObject("data") != null){ +// return result.getJSONObject("data"); +// }else{ +// return null; +// } +// } +// return null; +// } + + @Override + public JSONObject directBuyOrder(DirectBuyOrderDto params) { + JSONObject resJSON = checkQualification(params.getChargeAccountNumber()); + if (resJSON.getString("code").equals("000000")) { + long timeMillis = System.currentTimeMillis(); + String orderId = System.currentTimeMillis() + ""; + Map bizMap = new HashMap<>(); + bizMap.put("customer_order_no", orderId); + bizMap.put("sku_id", params.getSkuId()); + bizMap.put("order_type", 10); + bizMap.put("charge_acount_type", params.getChargeAccountType()); + bizMap.put("charge_acount_number", params.getChargeAccountNumber()); + String bizContent = JSON.toJSONString(bizMap); + String signContent = "app_id=" + yunmeiConfig.getAppId() + "&biz_content=" + bizContent + "¬ify_url=" + yunmeiConfig.getNotifyUrl() + + "×tamp=" + timeMillis + "&version=" + yunmeiConfig.getVersion() + "&app_secret=" + yunmeiConfig.getAppSecret(); + log.debug("签名明文为:{}", signContent); + String sign = DigestUtils.md5Hex(signContent).toUpperCase(); + Map map = new HashMap<>(); + map.put("app_id", yunmeiConfig.getAppId()); + map.put("timestamp", timeMillis); + map.put("version", yunmeiConfig.getVersion()); + map.put("notify_url", yunmeiConfig.getNotifyUrl()); + map.put("biz_content", bizContent); + map.put("sign", sign); + String res = HttpUtils.sendPostJSON(yunmeiConfig.getUrl() + YunmeiConstant.CREATE_ORDER, JSONObject.toJSONString(map)); + JSONObject result = null; + RightsOrderEntity rightsOrderEntity = new RightsOrderEntity(); + rightsOrderEntity.setOrderId(orderId); + rightsOrderEntity.setOrderTime(LocalDateTime.now()); + rightsOrderEntity.setLinkId(1059); + rightsOrderEntity.setLinkName("推广链接"); + rightsOrderEntity.setProductNumber(params.getSkuId().toString()); + rightsOrderEntity.setRightsType("会员权益"); + rightsOrderEntity.setStatus(0); + rightsOrderEntity.setMobile(params.getChargeAccountNumber()); + if (!Objects.equals(res, "")) { + result = JSONObject.parseObject(res); + } + if (result != null) { + if (!result.getString("retcode").equals(YunmeiEnum.SUCCESS.getCode().toString())) { + log.error("###账号【{}】订单id【{}】直充下单产品【{}】失败!错误码为:{},错误信息为:{}", params.getChargeAccountNumber(), orderId, params.getSkuId(), result.getString("retcode"), result.getString("retmsg")); + rightsOrderEntity.setCode(result.getString("retcode")); + rightsOrderEntity.setReason(result.getString("retmsg")); + rightsOrderService.save(rightsOrderEntity); + //throw new ServiceException(result.getString("retmsg"),Integer.parseInt(result.getString("retcode"))); + } + JSONObject data = result.getJSONObject("data"); + if (data != null) { + rightsOrderEntity.setCode(result.getString("retcode")); + rightsOrderEntity.setReason(result.getString("retmsg")); + rightsOrderEntity.setOtherOrderId(data.getString("order_id")); + rightsOrderEntity.setStatus(2); //只是下单成功最后以回调为准 + rightsOrderService.save(rightsOrderEntity); + JSONObject dataJSON = result.getJSONObject("data"); + dataJSON.put("code","000000"); + return dataJSON; + + } else { + return null; + } + + } + + rightsOrderEntity.setCode("500"); + rightsOrderEntity.setReason("未获取到远端服务信息"); + rightsOrderService.save(rightsOrderEntity); + } + + return resJSON; + } + + //检查是否有领取资格 + private JSONObject checkQualification(String mobile) { + JSONObject resJSON = new JSONObject(); + String code = "10026"; + String reason = "暂无领取资格"; + AliPayOrderEntity aliPayOrderEntity = aliPayOrderService.getOne(new QueryWrapper().eq("mobile", mobile).eq("status",1).select("mobile,order_time").orderByDesc("order_time")); + if (aliPayOrderEntity == null) { //如果没有支付记录说明没有领取资格 + code = "10024"; + reason = "暂无支付订单"; + resJSON.put("code", code); + resJSON.put("reason", reason); + return resJSON; + } + if (isWithin31Days(aliPayOrderEntity.getOrderTime())) { //如果支付记录在31天内说明满足条件 + //如果有支付记录查询是否31天内有过领取记录 + RightsOrderEntity rightsOrder = rightsOrderService.getOne(new QueryWrapper().eq("mobile", mobile).select("mobile,order_time").orderByDesc("order_time")); + if (rightsOrder == null) { //如果有领取记录说明可以领取 + code = "000000"; + reason = "可以领取"; + resJSON.put("code", code); + resJSON.put("reason", reason); + return resJSON; + } + if (isWithin31Days(rightsOrder.getOrderTime())) { //如果在31天已经领取过就不能再次领取 + code = "10025"; + reason = "已经领取过了"; + resJSON.put("code", code); + resJSON.put("reason", reason); + return resJSON; + }else { + code = "000000"; + reason = "可以领取"; + resJSON.put("code", code); + resJSON.put("reason", reason); + return resJSON; + } + } + resJSON.put("code", code); + resJSON.put("reason", reason); + return resJSON; + + + } + + public static boolean isWithin31Days(LocalDateTime date) { + LocalDateTime today = LocalDateTime.now(); + long days = ChronoUnit.DAYS.between(date, today); + return days <= 31; + } + + public static void main(String[] args) { + boolean within31Days = isWithin31Days(LocalDateTime.now().plusDays(-2)); + System.out.println(within31Days); + } +// @Override +// public JSONObject cardBuyOrder(CardBuyOrderDto params) { +// String orderId = System.currentTimeMillis()+""; +// long timeMillis = System.currentTimeMillis(); +// Map bizMap = new HashMap<>(); +// bizMap.put("customer_order_no", orderId); +// bizMap.put("sku_id", params.getSkuId()); +// bizMap.put("order_type", 20); +// bizMap.put("buy_quantity", params.getBuyQuantity()); +// String bizContent = JSON.toJSONString(bizMap); +// String signContent = "app_id="+yunmeiConfig.getAppId()+"&biz_content="+ bizContent +"¬ify_url="+yunmeiConfig.getNotifyUrl() +// +"×tamp="+timeMillis+"&version="+yunmeiConfig.getVersion()+"&app_secret="+yunmeiConfig.getAppSecret(); +// log.debug("签名明文为:{}",signContent); +// String sign = DigestUtils.md5Hex(signContent).toUpperCase(); +// Map map = new HashMap<>(); +// map.put("app_id",yunmeiConfig.getAppId()); +// map.put("timestamp", timeMillis); +// map.put("version", yunmeiConfig.getVersion()); +// map.put("notify_url", yunmeiConfig.getNotifyUrl()); +// map.put("biz_content", bizContent); +// map.put("sign",sign); +// JSONObject result = restTemplate.postForObject(yunmeiConfig.getUrl() + YunmeiConstant.CREATE_ORDER, map, JSONObject.class); +// if(result != null){ +// if(!result.getString("retcode").equals(YunmeiEnum.SUCCESS.getCode().toString())){ +// log.error("###订单id【{}】卡密下单产品【{}】失败!错误码为:{},错误信息为:{}",orderId,params.getSkuId(),result.getString("retcode"),result.getString("retmsg")); +// //throw new ServiceException(result.getString("retmsg"),Integer.parseInt(result.getString("retcode"))); +// } +// if(result.getJSONObject("data") != null){ +// return result.getJSONObject("data"); +// }else{ +// return null; +// } +// } +// return null; +// } + +// @Override +// public JSONObject getOrderDetails(String orderNo) { +// long timeMillis = System.currentTimeMillis(); +// Map bizMap = new HashMap<>(); +// bizMap.put("customer_order_no",orderNo); +// String bizContent = JSON.toJSONString(bizMap); +// String signContent = "app_id="+yunmeiConfig.getAppId()+"&biz_content="+ bizContent +"×tamp="+timeMillis +// +"&version="+yunmeiConfig.getVersion()+"&app_secret="+yunmeiConfig.getAppSecret(); +// log.debug("签名明文为:{}",signContent); +// String sign = DigestUtils.md5Hex(signContent).toUpperCase(); +// Map map = new HashMap<>(); +// map.put("app_id",yunmeiConfig.getAppId()); +// map.put("timestamp", timeMillis); +// map.put("version", yunmeiConfig.getVersion()); +// map.put("biz_content", bizContent); +// map.put("sign",sign); +// JSONObject result = restTemplate.postForObject(yunmeiConfig.getUrl() + YunmeiConstant.ORDER_DETAILS, map, JSONObject.class); +// if(result != null){ +// if(!result.getString("retcode").equals(YunmeiEnum.SUCCESS.getCode().toString())){ +// log.error("###订单id【{}】查询订单详情失败!错误码为:{},错误信息为:{}",orderNo,result.getString("retcode"),result.getString("retmsg")); +// //throw new ServiceException(result.getString("retmsg"),Integer.parseInt(result.getString("retcode"))); +// } +// if(result.getJSONObject("data") != null){ +// return result.getJSONObject("data"); +// }else{ +// return null; +// } +// } +// return null; +// } + + @Override + public JSONObject getBalance() { + long timeMillis = System.currentTimeMillis(); + String signContent = "app_id=" + yunmeiConfig.getAppId() + "×tamp=" + timeMillis + + "&version=" + yunmeiConfig.getVersion() + "&app_secret=" + yunmeiConfig.getAppSecret(); + log.debug("签名明文为:{}", signContent); + String sign = DigestUtils.md5Hex(signContent).toUpperCase(); + Map map = new HashMap<>(); + map.put("app_id", yunmeiConfig.getAppId()); + map.put("timestamp", timeMillis); + map.put("version", yunmeiConfig.getVersion()); + map.put("biz_content", ""); + map.put("sign", sign); + String res = HttpUtils.sendPostJSON(yunmeiConfig.getUrl() + YunmeiConstant.AMOUNT, JSONObject.toJSONString(map)); + JSONObject result = null; + if (!Objects.equals(res, "")) { + result = JSONObject.parseObject(res); + } + if (result != null) { + if (!result.getString("retcode").equals(YunmeiEnum.SUCCESS.getCode().toString())) { + log.error("###查询商户余额失败!错误码为:{},错误信息为:{}", result.getString("retcode"), result.getString("retmsg")); + //throw new ServiceException(result.getString("retmsg"),Integer.parseInt(result.getString("retcode"))); + } + if (result.getJSONObject("data") != null) { + return result.getJSONObject("data"); + } else { + return null; + } + } + return null; + } + + @Override + public String orderNotify(OrderNotifyDto params) { + //验证商户id + if (!params.getApp_id().equals(yunmeiConfig.getAppId())) { + log.error("###云媒订单【{}】回调失败!商户id【{}】不匹配!", params.getCustomer_order_no(), params.getApp_id()); + //return YunmeiCallbackEnum.FAIL.getValue(); + } + //验证签名 + String signContent = "app_id=" + params.getApp_id() + "&customer_order_no=" + params.getCustomer_order_no() + + "&description=" + params.getDescription() + "×tamp=" + params.getTimestamp() + + "&trade_state=" + params.getTrade_state() + "&app_secret=" + yunmeiConfig.getAppSecret(); + log.debug("签名明文为:{}", signContent); + String sign = DigestUtils.md5Hex(signContent).toUpperCase(); + if (!sign.equals(params.getSign())) { + log.error("###云媒订单【{}】回调失败!签名参数【{}】不匹配!", params.getCustomer_order_no(), JSON.toJSONString(params)); + return YunmeiCallbackEnum.FAIL.getValue(); + } + //验证订单状态 + if (!params.getTrade_state().equals(YunmeiCallbackEnum.SUCCESS.getValue())) { + log.error("###云媒回调订单【{}】失败!错误信息为【{}】", params.getCustomer_order_no(), params.getDescription()); + return YunmeiCallbackEnum.FAIL.getValue(); + } + //TODO 回调成功,修改订单状态 + log.info("###云媒订单【{}】回调成功!", params.getCustomer_order_no()); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("order_id", params.getCustomer_order_no()); + updateWrapper.set("status", 1); + rightsOrderService.update(new RightsOrderEntity(), updateWrapper); + return YunmeiCallbackEnum.SUCCESS.getValue(); + } +} diff --git a/rights-server/src/main/java/com/cyjd/rights/config/YunmeiConfig.java b/rights-server/src/main/java/com/cyjd/rights/config/YunmeiConfig.java new file mode 100644 index 0000000..a839cd0 --- /dev/null +++ b/rights-server/src/main/java/com/cyjd/rights/config/YunmeiConfig.java @@ -0,0 +1,29 @@ +package com.cyjd.rights.config; + +import lombok.Data; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * 云媒配置类 + * @author chengkun + * @date 2022/4/21 17:43 + */ +@Configuration +@ConfigurationProperties(prefix = "yunmei") +@Data +public class YunmeiConfig { + + + public String appId="MifkuIESHZkHZgHKmpy=CVAxJg=jDuJL"; + + public String appSecret="mst2l9s9fmmgtevbajtkuir3lqgmx6h5"; + + public String url; + + public String version="1.0"; + + public String notifyUrl="http://47.114.139.101:8086/yunmei/notifyOrder"; +}