├── flow-framework-demo ├── src │ ├── main │ │ └── java │ │ │ └── cn │ │ │ └── yccoding │ │ │ └── demo │ │ │ ├── async │ │ │ ├── README.md │ │ │ └── future │ │ │ │ ├── RemoteLoader.java │ │ │ │ ├── AccountService.java │ │ │ │ ├── EmployeeService.java │ │ │ │ ├── MockUtils.java │ │ │ │ └── CompareMethodMain.java │ │ │ └── designpattern │ │ │ ├── create │ │ │ ├── factory │ │ │ │ ├── Legend.java │ │ │ │ ├── Teemo.java │ │ │ │ ├── XinZhao.java │ │ │ │ ├── ApLegendFactory.java │ │ │ │ ├── Garen.java │ │ │ │ ├── FactoryPatternDemo.java │ │ │ │ └── AdLegendFactory.java │ │ │ ├── simplefactory │ │ │ │ ├── Legend.java │ │ │ │ ├── Teemo.java │ │ │ │ ├── XinZhao.java │ │ │ │ ├── Garen.java │ │ │ │ ├── SimpleFactoryPatternDemo.java │ │ │ │ ├── LegendFactory.java │ │ │ │ └── README.md │ │ │ ├── abstractfactory │ │ │ │ ├── Legend.java │ │ │ │ ├── Item.java │ │ │ │ ├── SunFire.java │ │ │ │ ├── ZhonYa.java │ │ │ │ ├── Teemo.java │ │ │ │ ├── TriForce.java │ │ │ │ ├── XinZhao.java │ │ │ │ ├── AbstractFactory.java │ │ │ │ ├── Garen.java │ │ │ │ ├── FactoryProducer.java │ │ │ │ ├── AbstractFactoryPatternDemo.java │ │ │ │ ├── ItemFactory.java │ │ │ │ └── LegendFactory.java │ │ │ ├── builder │ │ │ │ ├── Equipment.java │ │ │ │ ├── Attack.java │ │ │ │ ├── Defense.java │ │ │ │ ├── AbilityPower.java │ │ │ │ ├── MagicResistance.java │ │ │ │ ├── LostChapter.java │ │ │ │ ├── LudensEcho.java │ │ │ │ ├── RelicShield.java │ │ │ │ ├── SpiritVisage.java │ │ │ │ ├── builder2 │ │ │ │ │ ├── BuilderPatternDemo.java │ │ │ │ │ └── Champ.java │ │ │ │ ├── Item.java │ │ │ │ ├── SuitBuilder.java │ │ │ │ ├── Suit.java │ │ │ │ └── BuilderPatternDemo.java │ │ │ ├── prototype │ │ │ │ ├── Garen.java │ │ │ │ ├── Teemo.java │ │ │ │ ├── XinZhao.java │ │ │ │ ├── Legend.java │ │ │ │ ├── Champ.java │ │ │ │ ├── PrototypePatternDemo.java │ │ │ │ └── LegendCache.java │ │ │ └── singleton │ │ │ │ ├── HungrySingleton.java │ │ │ │ ├── EnumSingleton.java │ │ │ │ ├── LazySingleton.java │ │ │ │ ├── README.md │ │ │ │ └── InnerClassSingleton.java │ │ │ └── struct │ │ │ └── adapter │ │ │ ├── classadapter │ │ │ ├── Target.java │ │ │ ├── Adaptee.java │ │ │ ├── ConcreteTarget.java │ │ │ ├── Adapter.java │ │ │ └── ClassAdapterDemo.java │ │ │ └── objadapter │ │ │ ├── ObjAdapterDemo.java │ │ │ └── Adapter.java │ └── README.md └── pom.xml ├── flow-microservice-product ├── src │ └── main │ │ ├── resources │ │ ├── bootstrap.yml │ │ └── application.yml │ │ └── java │ │ └── cn │ │ └── yccoding │ │ └── product │ │ ├── ProductApplication.java │ │ └── controller │ │ └── ProducerTestController.java └── pom.xml ├── flow-microservice-gateway ├── src │ └── main │ │ ├── resources │ │ ├── bootstrap.yml │ │ └── application.yml │ │ └── java │ │ └── cn │ │ └── yccoding │ │ └── gateway │ │ ├── common │ │ ├── MDA.java │ │ └── TokenInfo.java │ │ ├── GatewayApplication.java │ │ ├── config │ │ ├── RibbonConfig.java │ │ └── CorsConfig.java │ │ └── filter │ │ └── AuthenticationFilter.java └── pom.xml ├── flow-microservice-order └── src │ └── main │ ├── resources │ ├── bootstrap.yml │ └── application.yml │ └── java │ └── cn │ └── yccoding │ └── order │ ├── config │ ├── RibbonConfig.java │ └── ResourceConfig.java │ ├── OrderApplication.java │ ├── feignapi │ ├── ProducerTestFeignApi.java │ ├── fallback │ │ ├── ProducerTestFeignApiFallback.java │ │ └── AliPayFeignApiFallBack.java │ └── AliPayFeignApi.java │ ├── property │ └── AliPayTradeProperties.java │ ├── model │ └── TradePaySummary.java │ └── controller │ ├── ConsumerTestController.java │ └── OrderController.java ├── flow-microservice-authcenter ├── src │ └── main │ │ ├── resources │ │ ├── bootstrap.yml │ │ └── application.yml │ │ └── java │ │ └── cn │ │ └── yccoding │ │ └── authcenter │ │ ├── domain │ │ ├── Member.java │ │ └── MyUserDetails.java │ │ ├── AuthCenterApplication.java │ │ ├── property │ │ └── JwtCAProperties.java │ │ ├── component │ │ └── MyTokenEnhancer.java │ │ └── config │ │ ├── MyUserDetailService.java │ │ └── WebSecurityConfig.java └── pom.xml ├── flow-microservice-payment └── src │ └── main │ ├── resources │ ├── bootstrap.yml │ ├── payment │ │ ├── wxinfo.properties │ │ └── zfbinfo.properties │ └── application.yml │ └── java │ └── cn │ └── yccoding │ └── payment │ ├── alipay │ ├── sdk │ │ ├── model │ │ │ ├── hb │ │ │ │ ├── Product.java │ │ │ │ ├── ExceptionInfo.java │ │ │ │ ├── TradeInfo.java │ │ │ │ ├── Type.java │ │ │ │ ├── HbStatus.java │ │ │ │ ├── EquipStatus.java │ │ │ │ ├── EquipStatusAdapter.java │ │ │ │ ├── ExceptionInfoAdapter.java │ │ │ │ ├── TradeInfoAdapter.java │ │ │ │ ├── SysTradeInfo.java │ │ │ │ └── PosTradeInfo.java │ │ │ ├── result │ │ │ │ ├── Result.java │ │ │ │ ├── AlipayF2FPayResult.java │ │ │ │ ├── AlipayF2FQueryResult.java │ │ │ │ ├── AlipayF2FRefundResult.java │ │ │ │ └── AlipayF2FPrecreateResult.java │ │ │ ├── TradeStatus.java │ │ │ ├── ExtendParams.java │ │ │ └── builder │ │ │ │ ├── RequestBuilder.java │ │ │ │ ├── AlipayTradeCancelRequestBuilder.java │ │ │ │ └── AlipayTradeQueryRequestBuilder.java │ │ ├── config │ │ │ └── Constants.java │ │ ├── service │ │ │ ├── AlipayMonitorService.java │ │ │ ├── impl │ │ │ │ ├── hb │ │ │ │ │ ├── TradeListener.java │ │ │ │ │ ├── HbQueue.java │ │ │ │ │ └── HbListener.java │ │ │ │ └── AbsAlipayService.java │ │ │ └── AlipayTradeService.java │ │ ├── utils │ │ │ ├── GsonFactory.java │ │ │ ├── Utils.java │ │ │ └── ZxingUtils.java │ │ └── DemoHbRunner.java │ ├── service │ │ └── TradeService.java │ └── model │ │ └── TradePaySummary.java │ ├── wxpay │ ├── model │ │ ├── CloseOrder.java │ │ ├── SceneInfo.java │ │ ├── OrderQuery.java │ │ ├── DownloadBill.java │ │ ├── DownloadFundFlow.java │ │ ├── BatchQueryComment.java │ │ ├── RefundQuery.java │ │ ├── BaseWXPay.java │ │ ├── Refund.java │ │ └── Report.java │ ├── config │ │ └── WXPayConfigExt.java │ ├── sdk │ │ ├── IWXPayDomain.java │ │ ├── WXPayXmlUtil.java │ │ └── WXPayConfig.java │ ├── service │ │ └── WXPayTradeService.java │ └── util │ │ └── SignatureUtils.java │ ├── PaymentApplication.java │ ├── util │ └── PaymentUtils.java │ ├── property │ ├── RedisKeyProperties.java │ └── AliPayTradeProperties.java │ ├── config │ ├── ResourceConfig.java │ ├── WXPaymentConfig.java │ └── RedisConfig.java │ └── client │ └── RedisOpsClient.java ├── flow-microservice-member └── src │ └── main │ ├── java │ └── cn │ │ └── yccoding │ │ └── member │ │ ├── domain │ │ ├── mapper │ │ │ ├── xml │ │ │ │ └── MemberMapper.xml │ │ │ └── MemberMapper.java │ │ ├── service │ │ │ ├── MemberService.java │ │ │ └── impl │ │ │ │ └── MemberServiceImpl.java │ │ └── entity │ │ │ └── Member.java │ │ ├── config │ │ ├── RedisHttpSessionConfiguration.java │ │ ├── property │ │ │ ├── NoAuthUrlProperties.java │ │ │ ├── JwtProperties.java │ │ │ └── RedisKeyProperties.java │ │ ├── SecurityConfiguration.java │ │ ├── InterceptorConfiguration.java │ │ ├── RedisConfiguration.java │ │ ├── JwtKit.java │ │ └── interceptor │ │ │ └── AuthHandlerInterceptor.java │ │ ├── MemberApplication.java │ │ ├── service │ │ └── SsoService.java │ │ ├── controller │ │ ├── BaseController.java │ │ ├── OrderController.java │ │ └── SsoController.java │ │ └── object │ │ └── RegisterQo.java │ └── resources │ └── application.yml ├── SECURITY.md ├── flow-framework-common ├── src │ └── main │ │ └── java │ │ └── cn │ │ └── yccoding │ │ └── common │ │ ├── util │ │ ├── CurrencyUtils.java │ │ ├── ExceptionUtils.java │ │ ├── SecurityUtils.java │ │ └── XmlConvertUtils.java │ │ ├── async │ │ └── AsyncTask.java │ │ ├── exception │ │ └── CustomException.java │ │ ├── base │ │ ├── BaseEntity.java │ │ └── ResultCodeEnum.java │ │ ├── handler │ │ └── MyMetaObjectHandler.java │ │ └── config │ │ └── MyBatisPlusConfig.java └── pom.xml ├── .gitignore ├── flow-framework-mbg └── pom.xml └── README.md /flow-framework-demo/src/main/java/cn/yccoding/demo/async/README.md: -------------------------------------------------------------------------------- 1 | 多线程使用 -------------------------------------------------------------------------------- /flow-framework-demo/src/README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 该包不涉及业务或公共类。只作为开发中一些好的灵感积累,如设计模式,线程池使用,分布式锁等等 4 | 5 | 便于开发中从demo获取灵感 -------------------------------------------------------------------------------- /flow-microservice-product/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | nacos: 4 | config: 5 | server-addr: 127.0.0.1:8848 -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: flow-gateway 4 | cloud: 5 | nacos: 6 | config: 7 | server-addr: localhost:8848 -------------------------------------------------------------------------------- /flow-microservice-order/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: flow-order 4 | cloud: 5 | nacos: 6 | config: 7 | server-addr: 127.0.0.1:8848 8 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: flow-authcenter 4 | cloud: 5 | nacos: 6 | config: 7 | server-addr: localhost:8848 -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: flow-payment 4 | cloud: 5 | nacos: 6 | config: 7 | server-addr: 127.0.0.1:8848 8 | 9 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/Product.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/27. 5 | */ 6 | public enum Product { 7 | FP // 当面付产品 8 | 9 | ,MP // 医疗产品 10 | } 11 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/domain/mapper/xml/MemberMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/async/future/RemoteLoader.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.async.future; 2 | 3 | /** 4 | * 模拟远程接口 5 | * 6 | * @author YC 7 | * @since 2021/1/9 8 | */ 9 | public interface RemoteLoader { 10 | 11 | /** 12 | * 远程接口方法 13 | * @return 14 | */ 15 | String load(); 16 | } 17 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/Legend.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | /** 4 | * 英雄 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public interface Legend { 10 | 11 | /** 12 | * 大招 13 | */ 14 | String ult(); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/Legend.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.simplefactory; 2 | 3 | /** 4 | * 英雄 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public interface Legend { 10 | 11 | /** 12 | * 大招 13 | */ 14 | String ult(); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9999 3 | spring: 4 | cloud: 5 | nacos: 6 | discovery: 7 | server-addr: localhost:8848 8 | management: 9 | endpoints: 10 | web: 11 | exposure: 12 | include: '*' 13 | endpoint: 14 | health: 15 | show-details: always # 打开端点详情 -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/ExceptionInfo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/27. 5 | */ 6 | public enum ExceptionInfo { 7 | HE_PRINTER // 打印机异常; 8 | 9 | ,HE_SCANER // 扫描枪异常; 10 | 11 | ,HE_OTHER // 其他硬件异常 12 | } 13 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/Legend.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 英雄 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public interface Legend { 10 | 11 | /** 12 | * 大招 13 | */ 14 | String ult(); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/classadapter/Target.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.classadapter; 2 | 3 | /** 4 | * 目标接口 5 | * 6 | * @author YC 7 | * @since 2021/1/28 8 | */ 9 | public interface Target { 10 | 11 | /** 12 | * 目标方法 13 | */ 14 | void request(); 15 | } 16 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/TradeInfo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/9/28. 5 | */ 6 | public interface TradeInfo { 7 | // 获取交易状态 8 | public HbStatus getStatus(); 9 | 10 | // 获取交易时间 11 | public double getTimeConsume(); 12 | } 13 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/Equipment.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 装备 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public interface Equipment { 10 | /** 11 | * v 装备 12 | * 13 | * @return 14 | */ 15 | String equip(); 16 | } 17 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/result/Result.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.result; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/27. 5 | */ 6 | public interface Result { 7 | 8 | // 判断交易是否在业务上成功, 返回true说明一定成功,但是返回false并不代表业务不成功!因为还有unknown的状态可能业务已经成功了 9 | public boolean isTradeSuccess(); 10 | } 11 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/Item.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 装备 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public interface Item { 10 | /** 11 | * 装备属性 12 | * 13 | * @return 14 | */ 15 | String stat(); 16 | } 17 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/Attack.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 攻击装备 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class Attack implements Equipment { 10 | @Override 11 | public String equip() { 12 | return "attack"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/Defense.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 防御 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class Defense implements Equipment { 10 | @Override 11 | public String equip() { 12 | return "defense"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/Teemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | /** 4 | * 提莫 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class Teemo implements Legend{ 10 | @Override 11 | public String ult() { 12 | return "Noxious Trap(种蘑菇)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/XinZhao.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | /** 4 | * 赵信 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class XinZhao implements Legend{ 10 | @Override 11 | public String ult() { 12 | return "Crescent Sweep(新月横扫)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-microservice-product/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9120 3 | spring: 4 | cloud: 5 | nacos: 6 | discovery: 7 | server-addr: 127.0.0.1:8848 8 | sentinel: 9 | transport: 10 | dashboard: 127.0.0.1:8080 11 | #开启SpringBoot Admin的监控 12 | management: 13 | endpoints: 14 | web: 15 | exposure: 16 | include: '*' -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/SunFire.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 装备属性 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public class SunFire implements Item { 10 | @Override 11 | public String stat() { 12 | return "ar(护甲)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/ZhonYa.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 中亚 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public class ZhonYa implements Item { 10 | @Override 11 | public String stat() { 12 | return "AP,AR(法强,护甲)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/Teemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.simplefactory; 2 | 3 | /** 4 | * 提莫 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class Teemo implements Legend { 10 | @Override 11 | public String ult() { 12 | return "Noxious Trap(种蘑菇)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/classadapter/Adaptee.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.classadapter; 2 | 3 | /** 4 | * 被适配的对象 5 | * 6 | * @author YC 7 | * @since 2021/1/28 8 | */ 9 | public class Adaptee { 10 | 11 | public void adapteeRequest() { 12 | System.out.println("被适配者的方法"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/TradeStatus.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/29. 5 | */ 6 | public enum TradeStatus { 7 | SUCCESS // 业务交易明确成功,比如支付成功、退货成功 8 | 9 | ,FAILED // 业务交易明确失败,比如支付明确失败、退货明确失败 10 | 11 | ,UNKNOWN // 业务交易状态未知,此时不清楚该业务是否成功或者失败,需要商户自行确认 12 | } 13 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/XinZhao.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.simplefactory; 2 | 3 | /** 4 | * 赵信 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class XinZhao implements Legend { 10 | @Override 11 | public String ult() { 12 | return "Crescent Sweep(新月横扫)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/Teemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | 4 | /** 5 | * 提莫 6 | * 7 | * @author YC 8 | * @since 2020/11/15 9 | */ 10 | public class Teemo implements Legend { 11 | @Override 12 | public String ult() { 13 | return "Noxious Trap(种蘑菇)"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/TriForce.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 三项之力 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public class TriForce implements Item { 10 | @Override 11 | public String stat() { 12 | return "AS,Crit,AD(攻速,暴击,攻击力)"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/XinZhao.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | 4 | /** 5 | * 赵信 6 | * 7 | * @author YC 8 | * @since 2020/11/15 9 | */ 10 | public class XinZhao implements Legend { 11 | @Override 12 | public String ult() { 13 | return "Crescent Sweep(新月横扫)"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 抽象工厂 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public abstract class AbstractFactory { 10 | public abstract Legend getLegend(String legend); 11 | public abstract Item getItem(String item); 12 | } 13 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/Garen.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | /** 4 | * 盖伦 5 | * 6 | * @author YC 7 | * @since 2020/12/3 8 | */ 9 | public class Garen extends Legend{ 10 | public Garen() { 11 | type = "garen123"; 12 | } 13 | 14 | @Override 15 | String ult() { 16 | return "德玛西亚审判"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/java/cn/yccoding/gateway/common/MDA.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.gateway.common; 2 | 3 | /** 4 | * 常量 5 | * 6 | * @author YC 7 | * @since 2020/9/25 8 | */ 9 | public class MDA { 10 | public static final String clientId = "service-gateway"; 11 | 12 | public static final String clientSecret = "1234"; 13 | 14 | public static final String checkTokenUrl = "http://auth-server/oauth/check_token"; 15 | } 16 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/Type.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/27. 5 | */ 6 | public enum Type { 7 | CR // 收银机 8 | 9 | ,STORE // 门店 10 | 11 | ,VM // 售卖机 12 | 13 | ,MD // 医疗设备 14 | 15 | ,SOFT_POS // 软POS 16 | 17 | ,POS // POS终端 18 | 19 | ,ALI_POS // 支付宝POS 20 | } 21 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/async/future/AccountService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.async.future; 2 | 3 | /** 4 | * 账户服务 5 | * 6 | * @author YC 7 | * @since 2021/1/9 8 | */ 9 | public class AccountService implements RemoteLoader { 10 | 11 | /** 12 | * 获取账户金额 13 | */ 14 | @Override 15 | public String load() { 16 | MockUtils.delay(); 17 | return MockUtils.getData()+""; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/Teemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | 4 | /** 5 | * 提莫 6 | * 7 | * @author YC 8 | * @since 2020/11/15 9 | */ 10 | public class Teemo extends Legend{ 11 | public Teemo() { 12 | type = "teemo123"; 13 | } 14 | 15 | @Override 16 | public String ult() { 17 | return "Noxious Trap(种蘑菇)"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/classadapter/ConcreteTarget.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.classadapter; 2 | 3 | /** 4 | * 目标实现类 5 | * 6 | * @author YC 7 | * @since 2021/1/28 8 | */ 9 | public class ConcreteTarget implements Target{ 10 | 11 | @Override 12 | public void request() { 13 | System.out.println("ConcreteTarget.request method"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/AbilityPower.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 魔法伤害 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public abstract class AbilityPower implements Item { 10 | @Override 11 | public abstract double price(); 12 | 13 | @Override 14 | public Equipment equip() { 15 | return new Attack(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/XinZhao.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | /** 4 | * 赵信 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class XinZhao extends Legend { 10 | public XinZhao() { 11 | type = "xinzhao123"; 12 | } 13 | 14 | @Override 15 | public String ult() { 16 | return "Crescent Sweep(新月横扫)"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/classadapter/Adapter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.classadapter; 2 | 3 | /** 4 | * 类适配器 5 | * 6 | * @author YC 7 | * @since 2021/1/28 8 | */ 9 | public class Adapter extends Adaptee implements Target{ 10 | @Override 11 | public void request() { 12 | // do sth 13 | super.adapteeRequest(); 14 | // do sth 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/domain/Member.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 会员 7 | * 8 | * @author YC 9 | * @since 2020/9/26 10 | */ 11 | @Data 12 | public class Member { 13 | 14 | private String id; 15 | 16 | private String username; 17 | 18 | private String password; 19 | 20 | private String nickname; 21 | 22 | private String phone; 23 | } 24 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/MagicResistance.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 魔抗 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public abstract class MagicResistance implements Item { 10 | @Override 11 | public abstract double price(); 12 | 13 | @Override 14 | public Equipment equip() { 15 | return new Defense(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/LostChapter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 遗失的章节 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class LostChapter extends AbilityPower{ 10 | @Override 11 | public String name() { 12 | return "鬼书"; 13 | } 14 | 15 | @Override 16 | public double price() { 17 | return 2700.0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/LudensEcho.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 卢登的回升 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class LudensEcho extends AbilityPower{ 10 | @Override 11 | public String name() { 12 | return "卢登的回升"; 13 | } 14 | 15 | @Override 16 | public double price() { 17 | return 3100.0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/HbStatus.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/27. 5 | */ 6 | public enum HbStatus { 7 | S // 交易成功(包括支付宝返回“处理中”) 8 | 9 | ,I // 支付宝返回处理中 10 | 11 | ,F // 支付宝返回失败 12 | 13 | ,P // POSP返回失败,或商户系统失败 14 | 15 | ,X // 建立连接异常 16 | 17 | ,Y // 报文上送异常 18 | 19 | ,Z // 报文接收异常 20 | 21 | ,C // 收银员取消 22 | } 23 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/RelicShield.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 圣物之盾 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class RelicShield extends MagicResistance{ 10 | @Override 11 | public String name() { 12 | return "圣物之盾"; 13 | } 14 | 15 | @Override 16 | public double price() { 17 | return 2500.0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/SpiritVisage.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 振奋盔甲(绿甲) 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class SpiritVisage extends MagicResistance{ 10 | 11 | @Override 12 | public String name() { 13 | return "绿甲"; 14 | } 15 | 16 | @Override 17 | public double price() { 18 | return 2600.0; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/async/future/EmployeeService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.async.future; 2 | 3 | /** 4 | * 人员服务 5 | * 6 | * @author YC 7 | * @since 2021/1/9 8 | */ 9 | public class EmployeeService implements RemoteLoader { 10 | 11 | /** 12 | * 获取入职时间信息 13 | * 14 | * @return 15 | */ 16 | @Override 17 | public String load() { 18 | MockUtils.delay(); 19 | return MockUtils.getInfo(); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/builder2/BuilderPatternDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder.builder2; 2 | 3 | /** 4 | * 建造者模式--示例类 5 | * 6 | * @author YC 7 | * @since 2020/12/2 8 | */ 9 | public class BuilderPatternDemo { 10 | public static void main(String[] args) { 11 | Champ champ = Champ.builder().nickname("zhao xin").setPassive("fight").build(); 12 | System.out.println(champ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/Item.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 召唤师 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public interface Item { 10 | /** 11 | * 名称 12 | */ 13 | String name(); 14 | 15 | /** 16 | * 属性 17 | */ 18 | double price(); 19 | 20 | /** 21 | * 装备 22 | * 23 | * @return 24 | */ 25 | Equipment equip(); 26 | } 27 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/RedisHttpSessionConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config; 2 | 3 | 4 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 5 | 6 | /** 7 | * spring session redis配置 8 | * 引入分布式会话体系,会话内容存储在redis中 9 | * 10 | * @author YC 11 | * @since 2020/9/5 12 | */ 13 | //@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600) 14 | public class RedisHttpSessionConfiguration { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/CloseOrder.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 关闭订单的实体类 9 | * @date : 2019/10/29 10 | */ 11 | @Data 12 | public class CloseOrder extends BaseWXPay { 13 | 14 | /** 15 | * 商户订单号 16 | */ 17 | @JSONField(name = "out_trade_no") 18 | private String outTradeNo; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/PaymentApplication.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * 启动类 8 | * 9 | * @author YC 10 | * @since 2020/9/27 11 | */ 12 | @SpringBootApplication 13 | public class PaymentApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(PaymentApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/SceneInfo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 场景信息,统一下单使用 9 | * @date : 2019/10/29 10 | */ 11 | @Data 12 | public class SceneInfo { 13 | 14 | private String id; 15 | 16 | private String name; 17 | 18 | @JSONField(name = "area_code") 19 | private String areaCode; 20 | 21 | private String address; 22 | } 23 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/AuthCenterApplication.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * 启动器 8 | * 9 | * @author YC 10 | * @since 2020/9/25 11 | */ 12 | @SpringBootApplication 13 | public class AuthCenterApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(AuthCenterApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/classadapter/ClassAdapterDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.classadapter; 2 | 3 | /** 4 | * 测试类 5 | * 6 | * @author YC 7 | * @since 2021/1/28 8 | */ 9 | public class ClassAdapterDemo { 10 | 11 | public static void main(String[] args) { 12 | Target target = new ConcreteTarget(); 13 | target.request(); 14 | 15 | // 新接口使用旧类方法 16 | Target adapter = new Adapter(); 17 | adapter.request(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/config/RibbonConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.client.RestTemplate; 6 | 7 | /** 8 | * @author YC 9 | * @since 2020/9/23 10 | */ 11 | @Configuration 12 | public class RibbonConfig { 13 | 14 | //@LoadBalanced 15 | @Bean 16 | public RestTemplate restTemplate() { 17 | return new RestTemplate(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/resources/payment/wxinfo.properties: -------------------------------------------------------------------------------- 1 | # 微信分配的公众账号ID(企业号corpid即为此appId) 2 | appid = 3 | # 接口密钥 4 | app_secret = 5 | # 微信支付分配的商户号 6 | mch_id = 7 | # API密钥 8 | api_key = 9 | # 注册域名 10 | register_domain = 11 | # JSAPI支付授权目录 12 | jsapi_payment_auth_dir = 13 | # JS接口安全域名 14 | js_domain = 15 | # 网页授权域名 16 | web_auth_domain = 17 | # 证书路径 18 | apiclient_cert = 19 | # 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数 20 | notify_url = 21 | # 异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数,如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。 22 | notify_url_refund = -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/config/Constants.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.config; 2 | 3 | /** 4 | * Created by liuyangkly on 15/7/29. 5 | */ 6 | public class Constants { 7 | 8 | private Constants() { 9 | // No Constructor. 10 | } 11 | 12 | public static final String SUCCESS = "10000"; // 成功 13 | public static final String PAYING = "10003"; // 用户支付中 14 | public static final String FAILED = "40004"; // 失败 15 | public static final String ERROR = "20000"; // 系统异常 16 | } 17 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/java/cn/yccoding/gateway/common/TokenInfo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.gateway.common; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * token info 9 | * 10 | * @author YC 11 | * @since 2020/9/25 12 | */ 13 | @Data 14 | public class TokenInfo { 15 | private boolean active; 16 | 17 | private String client_id; 18 | 19 | private String[] scope; 20 | 21 | private String user_name; 22 | 23 | private String[] aud; 24 | 25 | private Date exp; 26 | 27 | private String[] authorities; 28 | } 29 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/ApLegendFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | /** 4 | * 英雄工厂,输入英雄名,返回对应ap类型英雄 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class ApLegendFactory { 10 | 11 | /** 12 | * 获取英雄的类 13 | * 14 | * @param name 15 | * @return 16 | */ 17 | public Legend getLegend(String name) { 18 | if ("teemo".equalsIgnoreCase(name)) { 19 | return new Teemo(); 20 | } 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/Garen.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | /** 4 | * 盖伦 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class Garen implements Legend{ 10 | private String garenParam; 11 | 12 | @Override 13 | public String ult() { 14 | return "Demacian Justice(德玛西亚正义)"; 15 | } 16 | 17 | public void setGarenMethod(String garenParam) { 18 | System.out.println("盖伦自有方法调用..."); 19 | this.garenParam = garenParam; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/Garen.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.simplefactory; 2 | 3 | /** 4 | * 盖伦 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class Garen implements Legend { 10 | private String garenParam; 11 | 12 | @Override 13 | public String ult() { 14 | return "Demacian Justice(德玛西亚正义)"; 15 | } 16 | 17 | public void setGarenMethod(String garenParam) { 18 | System.out.println("盖伦自有方法调用..."); 19 | this.garenParam = garenParam; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/Garen.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | 4 | /** 5 | * 盖伦 6 | * 7 | * @author YC 8 | * @since 2020/11/15 9 | */ 10 | public class Garen implements Legend { 11 | private String garenParam; 12 | 13 | @Override 14 | public String ult() { 15 | return "Demacian Justice(德玛西亚正义)"; 16 | } 17 | 18 | public void setGarenMethod(String garenParam) { 19 | System.out.println("盖伦自有方法调用..."); 20 | this.garenParam = garenParam; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/domain/mapper/MemberMapper.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.domain.mapper; 2 | 3 | import cn.yccoding.member.domain.entity.Member; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 会员表 Mapper 接口 13 | *

14 | * 15 | * @author yc 16 | * @since 2020-09-03 17 | */ 18 | @Mapper 19 | public interface MemberMapper extends BaseMapper { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/EquipStatus.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/8/27. 5 | */ 6 | public enum EquipStatus { 7 | ON("10") // 开机 8 | 9 | ,OFF("20") // 关机 10 | 11 | ,NORMAL("30") // 正常 12 | 13 | ,SLEEP("40") // 进入休眠 14 | 15 | ,AWAKE("41"); // 唤醒 16 | 17 | private String value; 18 | 19 | EquipStatus(String value) { 20 | this.value = value; 21 | } 22 | 23 | public String getValue() { 24 | return value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/objadapter/ObjAdapterDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.objadapter; 2 | 3 | import cn.yccoding.demo.designpattern.struct.adapter.classadapter.Adaptee; 4 | import cn.yccoding.demo.designpattern.struct.adapter.classadapter.Target; 5 | 6 | /** 7 | * 测试类 8 | * 9 | * @author YC 10 | * @since 2021/1/28 11 | */ 12 | public class ObjAdapterDemo { 13 | 14 | public static void main(String[] args) { 15 | Target target = new Adapter(new Adaptee()); 16 | target.request(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/singleton/HungrySingleton.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.singleton; 2 | 3 | /** 4 | * 单例模式--饿汉式 5 | * 6 | * @author YC 7 | * @since 2020/11/27 8 | */ 9 | public class HungrySingleton { 10 | 11 | /** 12 | * 类加载时就给静态变量赋值初始化 13 | */ 14 | private static final HungrySingleton instance = new HungrySingleton(); 15 | 16 | /** 17 | * 构造器私有 18 | */ 19 | private HungrySingleton() { 20 | } 21 | 22 | public static HungrySingleton getInstance() { 23 | return instance; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/property/NoAuthUrlProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.LinkedHashSet; 8 | 9 | /** 10 | * 不拦截的url参数 11 | * 12 | * @author YC 13 | * @since 2020/9/4 14 | */ 15 | @Data 16 | @Component 17 | @ConfigurationProperties(prefix = "member.auth") 18 | public class NoAuthUrlProperties { 19 | 20 | private LinkedHashSet shouldSkipUrls; 21 | } 22 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/FactoryProducer.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 工厂生成器,传入工厂名,返回工厂类 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public class FactoryProducer { 10 | 11 | public static AbstractFactory getFactory(String factory) { 12 | if ("legend".equalsIgnoreCase(factory)) { 13 | return new LegendFactory(); 14 | } else if ("item".equalsIgnoreCase(factory)) { 15 | return new ItemFactory(); 16 | } 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-microservice-product/src/main/java/cn/yccoding/product/ProductApplication.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.product; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | /** 8 | * 启动类 9 | * 10 | * @author YC 11 | * @since 2020/9/23 12 | */ 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | public class ProductApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(ProductApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/OrderQuery.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 查询订单的实体类 9 | * @date : 2019/10/29 10 | */ 11 | @Data 12 | public class OrderQuery extends BaseWXPay { 13 | 14 | /** 15 | * 微信订单号 16 | */ 17 | @JSONField(name = "transaction_id") 18 | private String transactionId; 19 | 20 | /** 21 | * 商户订单号 22 | */ 23 | @JSONField(name = "out_trade_no") 24 | private String outTradeNo; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/java/cn/yccoding/gateway/GatewayApplication.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | /** 8 | * 启动,gateway无注解 9 | * 10 | * @author YC 11 | * @since 2020/9/24 12 | */ 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | public class GatewayApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(GatewayApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/SimpleFactoryPatternDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.simplefactory; 2 | 3 | /** 4 | * 工厂模式--演示类 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class SimpleFactoryPatternDemo { 10 | 11 | public static void main(String[] args) { 12 | LegendFactory factory = new LegendFactory(); 13 | String garenUlt = factory.getLegend("garen").ult(); 14 | String teemoUlt = factory.getLegend("teemo").ult(); 15 | System.out.println(garenUlt); 16 | System.out.println(teemoUlt); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/java/cn/yccoding/gateway/config/RibbonConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.gateway.config; 2 | 3 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.client.RestTemplate; 7 | 8 | /** 9 | * 配置 10 | * 11 | * @author YC 12 | * @since 2020/9/25 13 | */ 14 | @Configuration 15 | public class RibbonConfig { 16 | 17 | @LoadBalanced 18 | @Bean 19 | public RestTemplate restTemplate() { 20 | return new RestTemplate(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/singleton/EnumSingleton.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.singleton; 2 | 3 | /** 4 | * 单例模式--枚举 5 | * 6 | * @author YC 7 | * @since 2020/11/27 8 | */ 9 | public enum EnumSingleton { 10 | /** 11 | * 天然不支持反射创建对应的实例,且有自己的反序列化机制 12 | * 利用类加载机制保证线程安全 13 | */ 14 | ENUM_INSTANCE("singleton","enum"), 15 | LAZY_INSTANCE("singleton","lazy"); 16 | 17 | private String name; 18 | private String type; 19 | 20 | EnumSingleton(String name, String type) { 21 | this.name = name; 22 | this.type = type; 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/service/AlipayMonitorService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.service; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.builder.AlipayHeartbeatSynRequestBuilder; 4 | import com.alipay.api.response.MonitorHeartbeatSynResponse; 5 | 6 | /** 7 | * Created by liuyangkly on 15/10/22. 8 | */ 9 | public interface AlipayMonitorService { 10 | 11 | // 交易保障接口 https://openhome.alipay.com/platform/document.htm#mobileApp-barcodePay-API-heartBeat 12 | 13 | // 可以提供给系统商/pos厂商使用 14 | public MonitorHeartbeatSynResponse heartbeatSyn(AlipayHeartbeatSynRequestBuilder builder); 15 | } 16 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/MemberApplication.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.context.annotation.ComponentScan; 6 | 7 | /** 8 | * 启动类 9 | * 10 | * @author YC 11 | * @since 2020/9/3 12 | */ 13 | @SpringBootApplication 14 | @ComponentScan(basePackages = {"cn.yccoding.common","cn.yccoding.member"}) 15 | public class MemberApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(MemberApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/SuitBuilder.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 装备建造者 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class SuitBuilder { 10 | 11 | public Suit equipA() { 12 | Suit suit = new Suit(); 13 | suit.addItem(new LostChapter()); 14 | suit.addItem(new RelicShield()); 15 | return suit; 16 | } 17 | 18 | public Suit equipB() { 19 | Suit suit = new Suit(); 20 | suit.addItem(new LudensEcho()); 21 | suit.addItem(new SpiritVisage()); 22 | return suit; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/util/PaymentUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.util; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.format.DateTimeFormatter; 5 | 6 | /** 7 | * util 8 | * 9 | * @author YC 10 | * @since 2020/9/28 11 | */ 12 | public class PaymentUtils { 13 | 14 | /** 15 | * 随机生成订单号 16 | * 17 | * @return 18 | */ 19 | public static String generateRandomOrderNo() { 20 | // 随机数 21 | int number = (int) ((Math.random() * 9) * 1000); 22 | String nowStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); 23 | return nowStr + number; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/FactoryPatternDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | /** 4 | * 工厂模式--演示类 5 | * 6 | * @author YC 7 | * @since 2020/11/15 8 | */ 9 | public class FactoryPatternDemo { 10 | 11 | public static void main(String[] args) { 12 | AdLegendFactory adFactory = new AdLegendFactory(); 13 | ApLegendFactory apFactory = new ApLegendFactory(); 14 | String garenUlt = adFactory.getLegend("garen").ult(); 15 | String teemoUlt = apFactory.getLegend("teemo").ult(); 16 | System.out.println(garenUlt); 17 | System.out.println(teemoUlt); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/OrderApplication.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | 8 | /** 9 | * @author YC 10 | * @since 2020/6/5 18:24 11 | */ 12 | @EnableFeignClients 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | public class OrderApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(OrderApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/Suit.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 套装 8 | * 9 | * @author YC 10 | * @since 2020/11/29 11 | */ 12 | public class Suit { 13 | private final List items = new ArrayList<>(); 14 | 15 | public void addItem(Item item) { 16 | items.add(item); 17 | } 18 | 19 | public double getMoney() { 20 | return items.stream().map(Item::price).reduce(Double::sum).orElse(0.0); 21 | } 22 | 23 | public void showItems() { 24 | items.forEach(System.out::println); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/feignapi/ProducerTestFeignApi.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.feignapi; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import cn.yccoding.order.feignapi.fallback.ProducerTestFeignApiFallback; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | /** 10 | * 远程调用 11 | * 12 | * @author YC 13 | * @since 2020/9/23 14 | */ 15 | @FeignClient(name = "flow-product", fallback = ProducerTestFeignApiFallback.class) 16 | public interface ProducerTestFeignApi { 17 | 18 | @GetMapping("/producer") 19 | ResponseEntity produce(); 20 | } 21 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/util/CurrencyUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.util; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * @author YC 7 | * @since 2020/6/3 18:23 8 | */ 9 | public class CurrencyUtils { 10 | 11 | /** 12 | * 元转分 13 | * 14 | * @param yuan 15 | * @return 16 | */ 17 | public static Integer Yuan2Fen(Double yuan) { 18 | return new BigDecimal(yuan).movePointRight(2).intValue(); 19 | } 20 | 21 | /** 22 | * 分转元 23 | * 24 | * @param fen 25 | * @return 26 | */ 27 | public static Double Fen2Yuan(Integer fen) { 28 | return new BigDecimal(fen).movePointLeft(2).doubleValue(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/BuilderPatternDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder; 2 | 3 | /** 4 | * 建造者模式--示例类 5 | * 6 | * @author YC 7 | * @since 2020/11/29 8 | */ 9 | public class BuilderPatternDemo { 10 | 11 | public static void main(String[] args) { 12 | SuitBuilder suitBuilder = new SuitBuilder(); 13 | 14 | Suit suit1 = suitBuilder.equipA(); 15 | suit1.showItems(); 16 | System.out.println(suit1.getMoney()); 17 | 18 | System.out.println("=========="); 19 | 20 | Suit suit2 = suitBuilder.equipB(); 21 | suit2.showItems(); 22 | System.out.println(suit2.getMoney()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/EquipStatusAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.JsonSerializationContext; 6 | import com.google.gson.JsonSerializer; 7 | 8 | import java.lang.reflect.Type; 9 | 10 | /** 11 | * Created by liuyangkly on 15/8/27. 12 | */ 13 | public class EquipStatusAdapter implements JsonSerializer { 14 | @Override 15 | public JsonElement serialize(EquipStatus equipStatus, Type type, JsonSerializationContext jsonSerializationContext) { 16 | return new JsonPrimitive(equipStatus.getValue()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/struct/adapter/objadapter/Adapter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.struct.adapter.objadapter; 2 | 3 | import cn.yccoding.demo.designpattern.struct.adapter.classadapter.Adaptee; 4 | import cn.yccoding.demo.designpattern.struct.adapter.classadapter.Target; 5 | 6 | /** 7 | * 对象适配器 8 | * 9 | * @author YC 10 | * @since 2021/1/28 11 | */ 12 | public class Adapter implements Target { 13 | private Adaptee adaptee; 14 | 15 | public Adapter(Adaptee adaptee) { 16 | this.adaptee = adaptee; 17 | } 18 | 19 | @Override 20 | public void request() { 21 | // do sth 22 | adaptee.adapteeRequest(); 23 | // do sth 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/DownloadBill.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 下载对账单 实体类 9 | * @date : 2019/10/30 10 | */ 11 | @Data 12 | public class DownloadBill extends BaseWXPay { 13 | 14 | /** 15 | * 对账单日期 16 | */ 17 | @JSONField(name = "bill_date") 18 | private String billDate; 19 | 20 | /** 21 | * 账单类型 22 | */ 23 | @JSONField(name = "bill_type") 24 | private String billType; 25 | 26 | /** 27 | * 压缩账单 28 | */ 29 | @JSONField(name = "tar_type") 30 | private String tarType; 31 | } 32 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/resources/payment/zfbinfo.properties: -------------------------------------------------------------------------------- 1 | # 支付宝网关名、partnerId和appId 2 | open_api_domain = https://openapi.alipaydev.com/gateway.do 3 | mcloud_api_domain = http://mcloudmonitor.com/gateway.do 4 | pid = 5 | appid = 6 | 7 | # RSA私钥、公钥和支付宝公钥 8 | private_key = 9 | public_key = 10 | 11 | #SHA1withRsa对应支付宝公钥 12 | #alipay_public_key = 13 | 14 | #SHA256withRsa对应支付宝公钥 15 | alipay_public_key = 16 | 17 | # 签名类型: RSA->SHA1withRsa,RSA2->SHA256withRsa 18 | sign_type = RSA2 19 | # 当面付最大查询次数和查询间隔(毫秒) 20 | max_query_retry = 5 21 | query_duration = 5000 22 | 23 | # 当面付最大撤销次数和撤销间隔(毫秒) 24 | max_cancel_retry = 3 25 | cancel_duration = 2000 26 | 27 | # 交易保障线程第一次调度延迟和调度间隔(秒) 28 | heartbeat_delay = 5 29 | heartbeat_duration = 900 30 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/property/RedisKeyProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * key 8 | * 9 | * @author YC 10 | * @since 2020/9/27 11 | */ 12 | @Data 13 | @ConfigurationProperties(prefix = "redis.key") 14 | public class RedisKeyProperties { 15 | 16 | private RedisKeyProperties.Prefix prefix; 17 | 18 | private RedisKeyProperties.Expire expire; 19 | 20 | @Data 21 | public static class Prefix { 22 | private String wxToken; 23 | } 24 | 25 | @Data 26 | public static class Expire { 27 | private Long wxToken; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/factory/AdLegendFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.factory; 2 | 3 | 4 | /** 5 | * 英雄工厂,输入英雄名,返回对应ad类型英雄 6 | * 7 | * @author YC 8 | * @since 2020/11/15 9 | */ 10 | public class AdLegendFactory { 11 | 12 | /** 13 | * 获取英雄的类 14 | * @param name 15 | * @return 16 | */ 17 | public Legend getLegend(String name){ 18 | 19 | if ("garen".equalsIgnoreCase(name)) { 20 | Garen garen = new Garen(); 21 | garen.setGarenMethod("德玛西亚"); 22 | return garen; 23 | } else if ("xinzhao".equalsIgnoreCase(name)) { 24 | return new Teemo(); 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/DownloadFundFlow.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 下载资金账单 实体类 9 | * @date : 2019/10/30 10 | */ 11 | @Data 12 | public class DownloadFundFlow extends BaseWXPay { 13 | 14 | /** 15 | * 资金账单日期 16 | */ 17 | @JSONField(name = "bill_date") 18 | private String billDate; 19 | 20 | /** 21 | * 资金账户类型 22 | */ 23 | @JSONField(name = "account_type") 24 | private String accountType; 25 | 26 | /** 27 | * 压缩账单 28 | */ 29 | @JSONField(name = "tar_type") 30 | private String tarType; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/AbstractFactoryPatternDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 抽象工厂模式--演示类 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public class AbstractFactoryPatternDemo { 10 | 11 | public static void main(String[] args) { 12 | AbstractFactory itemFactory = FactoryProducer.getFactory("item"); 13 | AbstractFactory legendFactory = FactoryProducer.getFactory("LEGEND"); 14 | 15 | Item triforce = itemFactory.getItem("triforce"); 16 | System.out.println(triforce.stat()); 17 | 18 | Legend timo = legendFactory.getLegend("teemo"); 19 | System.out.println(timo.ult()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/Legend.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 英雄 7 | * 8 | * @author YC 9 | * @since 2020/11/15 10 | */ 11 | @Data 12 | public abstract class Legend implements Cloneable{ 13 | private String name; 14 | 15 | protected String type; 16 | 17 | /** 18 | * 大招 19 | */ 20 | abstract String ult(); 21 | 22 | @Override 23 | protected Object clone(){ 24 | Object clone = null; 25 | try { 26 | clone = super.clone(); 27 | } catch (CloneNotSupportedException e) { 28 | e.printStackTrace(); 29 | } 30 | return clone; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/property/JwtCAProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * jwt证书 8 | * 9 | * @author YC 10 | * @since 2020/9/25 11 | */ 12 | @Data 13 | @ConfigurationProperties(prefix = "flow.jwt") 14 | public class JwtCAProperties { 15 | /** 16 | * 证书名称 17 | */ 18 | private String keyPairName; 19 | 20 | /** 21 | * 证书别名 22 | */ 23 | private String keyPairAlias; 24 | 25 | /** 26 | * 证书私钥 27 | */ 28 | private String keyPairSecret; 29 | 30 | /** 31 | * 证书存储密钥 32 | */ 33 | private String keyPairStoreSecret; 34 | } 35 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/service/SsoService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.service; 2 | 3 | import cn.yccoding.member.domain.entity.Member; 4 | import cn.yccoding.member.object.RegisterQo; 5 | 6 | /** 7 | * 会员登录服务类 8 | * 9 | * @author YC 10 | * @since 2020/9/3 11 | */ 12 | public interface SsoService { 13 | 14 | /** 15 | * 注册会员前,获取验证码 16 | * 17 | * @param phone 18 | * @return 19 | */ 20 | String getOtpCode(String phone); 21 | 22 | /** 23 | * 会员注册 24 | */ 25 | boolean register(RegisterQo registerQo); 26 | 27 | /** 28 | * 会员登录 29 | * @param username 30 | * @param password 31 | * @return 32 | */ 33 | Member login(String username, String password); 34 | } 35 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/feignapi/fallback/ProducerTestFeignApiFallback.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.feignapi.fallback; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import cn.yccoding.order.feignapi.ProducerTestFeignApi; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * 降级 11 | * 12 | * @author YC 13 | * @since 2020/9/24 14 | */ 15 | @Slf4j 16 | @Component 17 | public class ProducerTestFeignApiFallback implements ProducerTestFeignApi { 18 | 19 | @Override 20 | public ResponseEntity produce() { 21 | log.error("服务异常..."); 22 | return R.error().message("生产者忙碌...").buildResponseEntity(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/domain/service/MemberService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.domain.service; 2 | 3 | import cn.yccoding.member.domain.entity.Member; 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 会员表 服务类 11 | *

12 | * 13 | * @author yc 14 | * @since 2020-09-03 15 | */ 16 | public interface MemberService extends IService { 17 | 18 | /** 19 | * 根据电话获取会员信息 20 | * @param phone 21 | * @return 22 | */ 23 | List getByPhone(String phone); 24 | 25 | /** 26 | * 根据用户名查找会员 27 | * @param username 28 | * @return 29 | */ 30 | List getByUsername(String username); 31 | } 32 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/async/future/MockUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.async.future; 2 | 3 | import java.util.Random; 4 | import java.util.UUID; 5 | 6 | /** 7 | * 模拟工具类 8 | * 9 | * @author YC 10 | * @since 2021/1/9 11 | */ 12 | public class MockUtils { 13 | 14 | /** 15 | * 模拟调用延时 16 | */ 17 | public static void delay() { 18 | try { 19 | Thread.sleep(1000L); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | 25 | public static int getData() { 26 | Random random = new Random(1000); 27 | return random.nextInt(100); 28 | } 29 | 30 | public static String getInfo() { 31 | return UUID.randomUUID().toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/Champ.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 英雄类 7 | * 8 | * @author YC 9 | * @since 2020/12/6 10 | */ 11 | @Data 12 | public class Champ implements Cloneable{ 13 | 14 | private String name; 15 | 16 | @Override 17 | protected Object clone() { 18 | Object clone = null; 19 | try { 20 | clone = super.clone(); 21 | } catch (CloneNotSupportedException e) { 22 | e.printStackTrace(); 23 | } 24 | return clone; 25 | } 26 | 27 | public static void main(String[] args) { 28 | Champ champ = new Champ(); 29 | Champ clone = (Champ) champ.clone(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/property/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * jwt 配置属性 9 | * 10 | * @author YC 11 | * @since 2020/9/5 12 | */ 13 | @Data 14 | @ConfigurationProperties(prefix = "jwt") 15 | @Component 16 | public class JwtProperties { 17 | 18 | /** 19 | * 请求头 20 | */ 21 | private String header; 22 | 23 | /** 24 | * 加密密钥 25 | */ 26 | private String secret; 27 | 28 | /** 29 | * 过期时间 30 | */ 31 | private Long expire; 32 | 33 | /** 34 | * token前缀 35 | */ 36 | private String prefix; 37 | } 38 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8888 3 | spring: 4 | cloud: 5 | nacos: 6 | discovery: 7 | server-addr: localhost:8848 8 | gateway: 9 | discovery: 10 | locator: 11 | enabled: true # 开启gateway从nacos上获取服务列表 12 | lower-case-service-id: true 13 | routes: 14 | - id: service-order 15 | uri: lb://service-order 16 | predicates: # 路径断言 17 | - Path=/consumer/**,/order/** 18 | - id: service-product 19 | uri: lb://service-product 20 | predicates: 21 | - Path=/producer/** 22 | 23 | management: 24 | endpoints: 25 | web: 26 | exposure: 27 | include: '*' 28 | endpoint: 29 | health: 30 | show-details: always # 打开端点详情 -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/service/TradeService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.service; 2 | 3 | import cn.yccoding.payment.alipay.model.TradePaySummary; 4 | import cn.yccoding.payment.alipay.sdk.model.result.AlipayF2FQueryResult; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | 7 | /** 8 | * trade 9 | * 10 | * @author YC 11 | * @since 2020/9/29 12 | */ 13 | public interface TradeService { 14 | 15 | 16 | /** 17 | * 当面付2.0支付 18 | * 19 | * @param tradePaySummary 20 | * @return 21 | */ 22 | String f2fPayTradePay(@RequestBody TradePaySummary tradePaySummary); 23 | 24 | /** 25 | * 当面付2.0查询订单 26 | * @param outTradeNo 商户订单号 27 | */ 28 | AlipayF2FQueryResult f2fTradeQuery(String outTradeNo); 29 | } 30 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/ItemFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | /** 4 | * 装备工厂类,扩展自抽象工厂 5 | * 6 | * @author YC 7 | * @since 2020/11/19 8 | */ 9 | public class ItemFactory extends AbstractFactory { 10 | @Override 11 | public Legend getLegend(String legend) { 12 | return null; 13 | } 14 | 15 | @Override 16 | public Item getItem(String item) { 17 | if (item.equalsIgnoreCase("sunfire")) { 18 | return new SunFire(); 19 | } else if (item.equalsIgnoreCase("triforce")) { 20 | return new TriForce(); 21 | } else if (item.equalsIgnoreCase("zhonya")) { 22 | return new ZhonYa(); 23 | } 24 | return null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/async/AsyncTask.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.async; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.concurrent.Callable; 5 | 6 | /** 7 | * 异步任务 8 | * 9 | * @author YC 10 | * @since 2021/1/10 11 | */ 12 | public class AsyncTask implements Callable { 13 | private Object target; 14 | private String taskId; 15 | private Object[] args; 16 | private Method method; 17 | 18 | public AsyncTask(Object target, String taskId, Object[] args, Method method) { 19 | this.target = target; 20 | this.taskId = taskId; 21 | this.args = args; 22 | this.method = method; 23 | } 24 | 25 | @Override 26 | public Object call() throws Exception { 27 | return method.invoke(target, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/property/RedisKeyProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * redis属性文件配置 9 | * 10 | * @author YC 11 | * @since 2020/9/3 12 | */ 13 | @Data 14 | @Component 15 | @ConfigurationProperties(prefix = "redis.key") 16 | public class RedisKeyProperties { 17 | private RedisKeyProperties.Prefix prefix; 18 | 19 | private RedisKeyProperties.Expire expire; 20 | 21 | @Data 22 | public static class Prefix { 23 | private String otpCode; 24 | 25 | } 26 | 27 | @Data 28 | public static class Expire { 29 | private Long otpCode; 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/feignapi/AliPayFeignApi.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.feignapi; 2 | 3 | import cn.yccoding.order.feignapi.fallback.AliPayFeignApiFallBack; 4 | import cn.yccoding.order.model.TradePaySummary; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | 9 | /** 10 | * ali 11 | * 12 | * @author YC 13 | * @since 2020/9/29 14 | */ 15 | @FeignClient(name = "flow-payment",fallback = AliPayFeignApiFallBack.class) 16 | public interface AliPayFeignApi { 17 | 18 | /** 19 | * 当面付 20 | * @param summary 21 | * @return 22 | */ 23 | @PostMapping("/ali-pay/f2f") 24 | String f2fPayTradePay(@RequestBody TradePaySummary summary); 25 | } 26 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/service/impl/hb/TradeListener.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.service.impl.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/10/27. 5 | */ 6 | public interface TradeListener { 7 | 8 | // 支付成功 9 | public void onPayTradeSuccess(String outTradeNo, long beforeCall); 10 | 11 | // 支付处理中 12 | public void onPayInProgress(String outTradeNo, long beforeCall); 13 | 14 | // 支付失败 15 | public void onPayFailed(String outTradeNo, long beforeCall); 16 | 17 | // 建立连接异常 18 | public void onConnectException(String outTradeNo, long beforeCall); 19 | 20 | // 报文上送异常 21 | public void onSendException(String outTradeNo, long beforeCall); 22 | 23 | // 报文接收异常 24 | public void onReceiveException(String outTradeNo, long beforeCall); 25 | } 26 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/singleton/LazySingleton.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.singleton; 2 | 3 | /** 4 | * 单例模式--懒汉式 5 | * 6 | * @author YC 7 | * @since 2020/11/27 8 | */ 9 | public class LazySingleton { 10 | 11 | /** 12 | * 静态属性,可见性,防止指令重排 13 | */ 14 | private volatile static LazySingleton instance; 15 | 16 | /** 17 | * 构造器私有 18 | */ 19 | private LazySingleton() { 20 | } 21 | 22 | public static LazySingleton getInstance() { 23 | // DCL 24 | if (instance == null) { 25 | synchronized (LazySingleton.class) { 26 | if (instance == null) { 27 | return new LazySingleton(); 28 | } 29 | } 30 | } 31 | return instance; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/LegendFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.simplefactory; 2 | 3 | 4 | /** 5 | * 英雄工厂,输入英雄名,返回对应英雄 6 | * 7 | * @author YC 8 | * @since 2020/11/15 9 | */ 10 | public class LegendFactory { 11 | 12 | /** 13 | * 获取英雄的类 14 | * @param name 15 | * @return 16 | */ 17 | public Legend getLegend(String name){ 18 | if ("garen".equalsIgnoreCase(name)) { 19 | Garen garen = new Garen(); 20 | garen.setGarenMethod("德玛西亚"); 21 | return garen; 22 | } else if ("xinzhao".equalsIgnoreCase(name)) { 23 | return new XinZhao(); 24 | } else if ("teemo".equalsIgnoreCase(name)) { 25 | return new Teemo(); 26 | } 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | 25 | # maven ignore 26 | target/ 27 | *.jar 28 | *.war 29 | *.ear 30 | *.zip 31 | *.tar 32 | *.tar.gz 33 | 34 | # eclipse ignore 35 | .settings/ 36 | .project 37 | .classpath 38 | 39 | # idea ignore 40 | .idea/ 41 | *.ipr 42 | *.iml 43 | *.iws 44 | 45 | # logs # 46 | logs 47 | 48 | # temp ignore 49 | *.log 50 | *.cache 51 | *.diff 52 | *.patch 53 | *.tmp 54 | *.java~ 55 | *.properties~ 56 | *.xml~ 57 | 58 | # system ignore 59 | .DS_Store 60 | Thumbs.db 61 | Servers 62 | .metadata -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.exception; 2 | 3 | import cn.yccoding.common.base.ResultCodeEnum; 4 | import lombok.Data; 5 | 6 | /** 7 | * @Author YC 8 | * @create 2020/3/3 自定义异常 9 | */ 10 | @Data 11 | public class CustomException extends RuntimeException { 12 | 13 | private Integer code; 14 | 15 | public CustomException(Integer code, String message) { 16 | super(message); 17 | this.code = code; 18 | } 19 | 20 | public CustomException(ResultCodeEnum resultCodeEnum) { 21 | super(resultCodeEnum.getMessage()); 22 | this.code = resultCodeEnum.getCode(); 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "CMSException{" + "code=" + code + ", message=" + this.getMessage() + '}'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | 8 | /** 9 | * spring security配置 10 | * 11 | * @author YC 12 | * @since 2020/9/4 13 | */ 14 | @Configuration 15 | public class SecurityConfiguration { 16 | 17 | /** 18 | * hash盐密码加密 19 | * 20 | * @return 21 | */ 22 | @Bean 23 | public PasswordEncoder passwordEncoder() { 24 | return new BCryptPasswordEncoder(); 25 | } 26 | 27 | @Bean 28 | public JwtKit jwtKit() { 29 | return new JwtKit(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/PrototypePatternDemo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | /** 4 | * 原型模式--示例类 5 | * 6 | * @author YC 7 | * @since 2020/12/3 8 | */ 9 | public class PrototypePatternDemo { 10 | 11 | public static void main(String[] args) { 12 | LegendCache.loadCache(); 13 | 14 | Legend teemo1 = LegendCache.getLegend("teemo"); 15 | Legend teemo2 = LegendCache.getLegend("teemo"); 16 | System.out.println(teemo1.hashCode()); 17 | System.out.println(teemo2.hashCode()); 18 | 19 | Teemo teemo = new Teemo(); 20 | Teemo teemo3 = (Teemo) teemo.clone(); 21 | Teemo teemo4 = (Teemo) teemo.clone(); 22 | System.out.println(teemo3.hashCode()); 23 | System.out.println(teemo4.hashCode()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/feignapi/fallback/AliPayFeignApiFallBack.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.feignapi.fallback; 2 | 3 | import cn.yccoding.common.base.ResultCodeEnum; 4 | import cn.yccoding.common.exception.CustomException; 5 | import cn.yccoding.order.feignapi.AliPayFeignApi; 6 | import cn.yccoding.order.model.TradePaySummary; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | 11 | /** 12 | * ali 13 | * 14 | * @author YC 15 | * @since 2020/9/29 16 | */ 17 | @Slf4j 18 | @Component 19 | public class AliPayFeignApiFallBack implements AliPayFeignApi { 20 | 21 | @Override 22 | public String f2fPayTradePay(@RequestBody TradePaySummary summary) { 23 | log.info("当面付请求异常..."); 24 | // TODO 待完善逻辑 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/util/ExceptionUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.util; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.io.IOException; 6 | import java.io.PrintWriter; 7 | import java.io.StringWriter; 8 | 9 | /** 10 | * @Author YC 11 | * @create 2020/3/3 12 | */ 13 | @Slf4j 14 | public class ExceptionUtils { 15 | /** 16 | * 打印异常信息 17 | */ 18 | public static String getMessage(Exception e) { 19 | String swStr = null; 20 | try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) { 21 | e.printStackTrace(pw); 22 | pw.flush(); 23 | sw.flush(); 24 | swStr = sw.toString(); 25 | } catch (IOException ex) { 26 | ex.printStackTrace(); 27 | log.error(ex.getMessage()); 28 | } 29 | return swStr; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/BatchQueryComment.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 拉取订单评价数据实体类 9 | * @date : 2019/11/5 10 | */ 11 | @Data 12 | public class BatchQueryComment extends BaseWXPay { 13 | 14 | /** 15 | * 商户订单号 16 | */ 17 | @JSONField(name = "out_trade_no") 18 | private String outTradeNo; 19 | 20 | /** 21 | * 开始时间 22 | */ 23 | @JSONField(name = "begin_time") 24 | private String beginTime; 25 | 26 | /** 27 | * 结束时间 28 | */ 29 | @JSONField(name = "end_time") 30 | private String endTime; 31 | 32 | /** 33 | * 位移 34 | */ 35 | private String offset; 36 | 37 | /** 38 | * 条数 39 | */ 40 | private String limit; 41 | } 42 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/abstractfactory/LegendFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.abstractfactory; 2 | 3 | 4 | /** 5 | * 英雄工厂类,扩展自抽象工厂 6 | * 注:抽象工厂类,更建议使用接口interface,使用默认方法default修饰 7 | * @author YC 8 | * @since 2020/11/19 9 | */ 10 | public class LegendFactory extends AbstractFactory{ 11 | @Override 12 | public Legend getLegend(String legend) { 13 | if ("garen".equalsIgnoreCase(legend)) { 14 | Garen garen = new Garen(); 15 | garen.setGarenMethod("德玛西亚"); 16 | return garen; 17 | } else if ("xinzhao".equalsIgnoreCase(legend)) { 18 | return new XinZhao(); 19 | } else if ("teemo".equalsIgnoreCase(legend)) { 20 | return new Teemo(); 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | public Item getItem(String item) { 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/property/AliPayTradeProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * property 9 | * 10 | * @author YC 11 | * @since 2020/9/29 12 | */ 13 | @Component 14 | @ConfigurationProperties(prefix = "trade.ali-pay") 15 | @Data 16 | public class AliPayTradeProperties { 17 | 18 | /** 19 | * 二维码 20 | */ 21 | private AliPayTradeProperties.Qrcode qrcode; 22 | /** 23 | * 支付成功回调页面 24 | */ 25 | private String callbackUrl; 26 | 27 | @Data 28 | public static class Qrcode{ 29 | /** 30 | * qrcode存储文件路径设置 31 | */ 32 | private String storePath; 33 | /** 34 | * http访问路径设置 35 | */ 36 | private String httpBasePath; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/property/AliPayTradeProperties.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * property 9 | * 10 | * @author YC 11 | * @since 2020/9/29 12 | */ 13 | @Component 14 | @ConfigurationProperties(prefix = "trade.ali-pay") 15 | @Data 16 | public class AliPayTradeProperties { 17 | 18 | /** 19 | * 二维码 20 | */ 21 | private AliPayTradeProperties.Qrcode qrcode; 22 | /** 23 | * 支付成功回调页面 24 | */ 25 | private String callbackUrl; 26 | 27 | @Data 28 | public static class Qrcode{ 29 | /** 30 | * qrcode存储文件路径设置 31 | */ 32 | private String storePath; 33 | /** 34 | * http访问路径设置 35 | */ 36 | private String httpBasePath; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /flow-microservice-product/src/main/java/cn/yccoding/product/controller/ProducerTestController.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.product.controller; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /** 10 | * 生产者测试 11 | * 12 | * @author YC 13 | * @since 2020/9/23 14 | */ 15 | @Slf4j 16 | @RestController 17 | public class ProducerTestController { 18 | 19 | @GetMapping("/producer") 20 | public ResponseEntity produce() { 21 | log.info("生产者调用..."); 22 | try { 23 | Thread.sleep(3000); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | int i = 1/0; 28 | return R.ok().message("生产者调用成功...").data("item","from producer").buildResponseEntity(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /flow-framework-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cloud-flow 7 | cn.yccoding 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | demo包 12 | 13 | 14 | org.projectlombok 15 | lombok 16 | 17 | 18 | cn.hutool 19 | hutool-all 20 | 21 | 22 | 23 | flow-framework-demo 24 | 25 | 26 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/controller/BaseController.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.controller; 2 | 3 | import org.springframework.web.context.request.RequestContextHolder; 4 | import org.springframework.web.context.request.ServletRequestAttributes; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import javax.servlet.http.HttpSession; 9 | 10 | /** 11 | * 基础类控制器 12 | * 13 | * @author YC 14 | * @since 2020/9/4 15 | */ 16 | public class BaseController { 17 | public HttpServletRequest getRequest() { 18 | return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 19 | } 20 | 21 | public HttpServletResponse getResponse(){ 22 | return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse(); 23 | } 24 | 25 | public HttpSession getHttpSession(){ 26 | return getRequest().getSession(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/component/MyTokenEnhancer.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter.component; 2 | 3 | import cn.yccoding.authcenter.domain.Member; 4 | import org.springframework.security.oauth2.common.OAuth2AccessToken; 5 | import org.springframework.security.oauth2.provider.OAuth2Authentication; 6 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * jwt自定义增强器 13 | * 14 | * @author YC 15 | * @since 2020/9/25 16 | */ 17 | public class MyTokenEnhancer implements TokenEnhancer { 18 | @Override 19 | public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { 20 | Member member = (Member) authentication.getPrincipal(); 21 | final Map additionalInfo = new HashMap<>(); 22 | final Map retMap = new HashMap<>(); 23 | 24 | return null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/ExceptionInfoAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | import cn.yccoding.payment.alipay.sdk.utils.Utils; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonPrimitive; 6 | import com.google.gson.JsonSerializationContext; 7 | import com.google.gson.JsonSerializer; 8 | import org.apache.commons.lang.StringUtils; 9 | 10 | import java.lang.reflect.Type; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by liuyangkly on 15/8/27. 15 | */ 16 | public class ExceptionInfoAdapter implements JsonSerializer> { 17 | @Override 18 | public JsonElement serialize(List exceptionInfos, Type type, JsonSerializationContext jsonSerializationContext) { 19 | if (Utils.isListEmpty(exceptionInfos)) { 20 | return null; 21 | } 22 | 23 | return new JsonPrimitive(StringUtils.join(exceptionInfos, "|")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/ExtendParams.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * Created by liuyangkly on 15/6/26. 7 | * 扩展信息 8 | */ 9 | public class ExtendParams { 10 | // 系统商编号 11 | @SerializedName("sys_service_provider_id") 12 | private String sysServiceProviderId; 13 | 14 | @Override 15 | public String toString() { 16 | final StringBuilder sb = new StringBuilder("ExtendParams{"); 17 | sb.append("sysServiceProviderId='").append(sysServiceProviderId).append('\''); 18 | sb.append('}'); 19 | return sb.toString(); 20 | } 21 | 22 | public String getSysServiceProviderId() { 23 | return sysServiceProviderId; 24 | } 25 | 26 | public ExtendParams setSysServiceProviderId(String sysServiceProviderId) { 27 | this.sysServiceProviderId = sysServiceProviderId; 28 | return this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/base/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.base; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.io.Serializable; 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | * 基础实体类 13 | * 14 | * @author YC 15 | * @since 2020/9/3 16 | */ 17 | @Data 18 | @EqualsAndHashCode(callSuper = false) 19 | @Accessors(chain = true) 20 | public class BaseEntity implements Serializable { 21 | private static final long serialVersionUID=1L; 22 | 23 | /** 24 | * 记录主键,默认雪花算法 25 | */ 26 | @TableId(type = IdType.ASSIGN_ID) 27 | private String id; 28 | 29 | /** 30 | * 记录创建时间 31 | */ 32 | @TableField(fill = FieldFill.INSERT) 33 | private LocalDateTime createTime; 34 | 35 | /** 36 | * 记录更新时间 37 | */ 38 | @TableField(fill = FieldFill.UPDATE) 39 | private LocalDateTime updateTime; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/prototype/LegendCache.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.prototype; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | 5 | /** 6 | * 英雄缓存 7 | * 8 | * @author YC 9 | * @since 2020/12/3 10 | */ 11 | public class LegendCache { 12 | 13 | private static ConcurrentHashMap legendCache = new ConcurrentHashMap<>(); 14 | 15 | public static Legend getLegend(String name) { 16 | Legend legend = legendCache.get(name); 17 | return (Legend) legend.clone(); 18 | } 19 | 20 | public static void loadCache() { 21 | Legend garen = new Garen(); 22 | garen.setName("garen"); 23 | legendCache.put("garen",garen); 24 | 25 | Legend teemo = new Teemo(); 26 | garen.setName("teemo"); 27 | legendCache.put("teemo",teemo); 28 | 29 | Legend xinZhao = new XinZhao(); 30 | garen.setName("xinzhao"); 31 | legendCache.put("xinzhao",xinZhao); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/object/RegisterQo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.object; 2 | 3 | import lombok.Data; 4 | import org.hibernate.validator.constraints.Length; 5 | 6 | import javax.validation.constraints.NotBlank; 7 | import javax.validation.constraints.Pattern; 8 | 9 | /** 10 | * 注册 11 | * 12 | * @author YC 13 | * @since 2020/9/4 14 | */ 15 | @Data 16 | public class RegisterQo { 17 | @NotBlank(message = "用户名不能为空") 18 | @Length(min = 4,max = 20,message = "用户名长度必须在4-20字符之间") 19 | private String username; 20 | 21 | @NotBlank(message = "密码不能为空") 22 | @Length(min = 4,max = 20,message = "密码长度必须在4-20字符之间") 23 | private String password; 24 | 25 | @NotBlank(message = "手机号不能为空") 26 | @Length(min = 11,max = 11,message = "电话必须是11个字符") 27 | @Pattern(regexp = "^1[3|4|5|6|7|8|9][0-9]\\d{8}$",message = "电话号码格式不正确") 28 | private String phone; 29 | 30 | @NotBlank(message = "验证码不能为空") 31 | @Length(min = 6,max = 6,message = "验证码必须6个字符") 32 | private String otpCode; 33 | } 34 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9130 3 | tomcat: 4 | max-threads: 100 5 | spring: 6 | cloud: 7 | nacos: 8 | discovery: 9 | server-addr: 127.0.0.1:8848 10 | sentinel: 11 | transport: 12 | dashboard: 127.0.0.1:8080 13 | #开启SpringBoot Admin的监控 14 | management: 15 | endpoints: 16 | web: 17 | exposure: 18 | include: '*' 19 | # openfeign 20 | feign: 21 | httpclient: 22 | connection-timeout: 5000 23 | sentinel: 24 | enabled: true # 启用sentinel服务策略,默认关闭 25 | # 支付,拷贝自payment-service 26 | trade: 27 | ali-pay: 28 | qrcode: 29 | store-path: /Users/yc/temp/qr-code/alipay # 本地文件绝对路径路径 30 | http-base-path: /static/qrcode/alipay # http访问的url路径,对应store-path 31 | callback-url: http://chetwhy.free.idcfengye.com/ali-pay/f2f/callback # 支付宝支付的回调地址 32 | wechat-pay: 33 | qrcode: 34 | store-path: /Users/yc/temp/qr-code/wechat # 本地文件绝对路径路径 35 | callback-url: http://chetwhy.free.idcfengye.com/wechat-pay/f2f/callback # 微信支付的回调地址 -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9150 3 | tomcat: 4 | max-threads: 100 5 | spring: 6 | cloud: 7 | nacos: 8 | discovery: 9 | server-addr: 127.0.0.1:8848 10 | sentinel: 11 | transport: 12 | dashboard: 127.0.0.1:8080 13 | #开启SpringBoot Admin的监控 14 | management: 15 | endpoints: 16 | web: 17 | exposure: 18 | include: '*' 19 | 20 | 21 | ###### 自定义 22 | # 自定义redis键值 23 | redis: 24 | key: 25 | prefix: 26 | wx-token: "payment:wx-token:" 27 | expire: 28 | wx-token: 180 29 | trade: 30 | ali-pay: 31 | qrcode: 32 | store-path: /Users/yc/temp/qr-code/alipay # 本地文件绝对路径路径 33 | http-base-path: /static/qrcode/alipay # http访问的url路径,对应store-path 34 | callback-url: http://chetwhy.free.idcfengye.com/ali-pay/f2f/callback # 支付宝支付的回调地址 35 | wechat-pay: 36 | qrcode: 37 | store-path: /Users/yc/temp/qr-code/wechat # 本地文件绝对路径路径 38 | callback-url: http://chetwhy.free.idcfengye.com/wechat-pay/f2f/callback # 微信支付的回调地址 -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/config/ResourceConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.config; 2 | 3 | import cn.yccoding.order.property.AliPayTradeProperties; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /** 10 | * 资源配置 11 | * 12 | * @author YC 13 | * @since 2020/9/29 14 | */ 15 | @Configuration 16 | public class ResourceConfig implements WebMvcConfigurer { 17 | 18 | @Autowired 19 | private AliPayTradeProperties aliPayTradeProperties; 20 | 21 | @Override 22 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 23 | // 将http请求路径映射到本地路径 24 | registry.addResourceHandler(aliPayTradeProperties.getQrcode().getHttpBasePath() + "/**") 25 | .addResourceLocations("file:" + aliPayTradeProperties.getQrcode().getStorePath() + "/"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/async/future/CompareMethodMain.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.async.future; 2 | 3 | import java.util.List; 4 | import java.util.function.Supplier; 5 | 6 | /** 7 | * 测试类 8 | * 9 | * @author YC 10 | * @since 2021/1/9 11 | */ 12 | public class CompareMethodMain { 13 | 14 | private static final LocalClient localClient = new LocalClient(); 15 | 16 | public static void main(String[] args) { 17 | execute("sync", () -> localClient.findSequential()); 18 | execute("parallel", () -> localClient.findParallel()); 19 | execute("future", () -> localClient.findFuture()); 20 | execute("comFuture", () -> localClient.findCompletableFuture()); 21 | } 22 | 23 | private static void execute(String msg, Supplier> s) { 24 | long start = System.nanoTime(); 25 | System.out.println("remote interface response = " + s.get()); 26 | long duration = (System.nanoTime() - start) / 1_000_000; 27 | System.out.println(msg + " done in " + duration + " msecs"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/RefundQuery.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 查询退款请求的实体类 9 | * @date : 2019/10/29 10 | */ 11 | @Data 12 | public class RefundQuery extends BaseWXPay { 13 | 14 | // 四选一,微信订单号查询的优先级是: refund_id > out_refund_no > transaction_id > out_trade_no 15 | /** 16 | * 微信订单号 17 | */ 18 | @JSONField(name = "transaction_id") 19 | private String transactionId; 20 | 21 | /** 22 | * 商户订单号 23 | */ 24 | @JSONField(name = "out_trade_no") 25 | private String outTradeNo; 26 | 27 | /** 28 | * 商户退款单号 29 | */ 30 | @JSONField(name = "out_refund_no") 31 | private String outRefundNo; 32 | 33 | /** 34 | * 微信退款单号 35 | */ 36 | @JSONField(name = "refund_id") 37 | private String refundId; 38 | 39 | /** 40 | * 偏移量,当部分退款次数超过10次时可使用,表示返回的查询结果从这个偏移量开始取记录 41 | */ 42 | private String offset; 43 | 44 | } -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/handler/MyMetaObjectHandler.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.handler; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.ibatis.reflection.MetaObject; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * 自定义填充功能 12 | * 13 | * @author YC 14 | * @since 2020/9/4 15 | */ 16 | @Slf4j 17 | @Component 18 | public class MyMetaObjectHandler implements MetaObjectHandler { 19 | @Override 20 | public void insertFill(MetaObject metaObject) { 21 | log.info("start insert fill ...."); 22 | // 起始版本 3.3.0(推荐使用) 23 | this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); 24 | } 25 | 26 | @Override 27 | public void updateFill(MetaObject metaObject) { 28 | log.info("start update fill ...."); 29 | // 起始版本 3.3.0(推荐) 30 | this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/model/TradePaySummary.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.List; 7 | 8 | /** 9 | * model 10 | * 11 | * @author YC 12 | * @since 2020/9/29 13 | */ 14 | @Data 15 | public class TradePaySummary implements Serializable { 16 | /** 17 | * 订单标题 18 | */ 19 | private String subject; 20 | 21 | /** 22 | * 商户门店编号 23 | */ 24 | private String storeId; 25 | 26 | /** 27 | * 商户操作员编号 28 | */ 29 | private String operatorId; 30 | 31 | private List items; 32 | 33 | @Data 34 | public static class Item implements Serializable{ 35 | // 商品编号(国标) 36 | private String goodsId; 37 | 38 | private String alipayGoodsId; 39 | 40 | // 商品名称 41 | private String goodsName; 42 | 43 | // 商品数量 44 | private int quantity; 45 | 46 | // 商品价格,此处单位为元,精确到小数点后2位 47 | private String price; 48 | 49 | // 商品类别 50 | private String goodsCategory; 51 | 52 | // 商品详情 53 | private String body; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/TradeInfoAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | import cn.yccoding.payment.alipay.sdk.utils.Utils; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonPrimitive; 6 | import com.google.gson.JsonSerializationContext; 7 | import com.google.gson.JsonSerializer; 8 | import org.apache.commons.lang.StringUtils; 9 | 10 | import java.lang.reflect.Type; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by liuyangkly on 15/9/28. 15 | */ 16 | public class TradeInfoAdapter implements JsonSerializer> { 17 | @Override 18 | public JsonElement serialize(List tradeInfoList, Type type, JsonSerializationContext jsonSerializationContext) { 19 | if (Utils.isListEmpty(tradeInfoList)) { 20 | return null; 21 | } 22 | 23 | TradeInfo tradeInfo = tradeInfoList.get(0); 24 | if (tradeInfo instanceof PosTradeInfo) { 25 | return new JsonPrimitive(StringUtils.join(tradeInfoList, "")); 26 | } 27 | 28 | return jsonSerializationContext.serialize(tradeInfoList); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.controller; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import cn.yccoding.member.config.interceptor.AuthHandlerInterceptor; 5 | import io.jsonwebtoken.Claims; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | /** 13 | * 订单控制器 14 | * 15 | * @author YC 16 | * @since 2020/9/4 17 | */ 18 | @Slf4j 19 | @RestController 20 | @RequestMapping("/order") 21 | public class OrderController extends BaseController { 22 | 23 | @GetMapping 24 | public ResponseEntity getOrder() { 25 | log.info("下订单..."); 26 | // session会话信息 27 | ///Member member = (Member) getHttpSession().getAttribute("member"); 28 | Claims claims = (Claims) getRequest().getAttribute(AuthHandlerInterceptor.GLOBAL_JWT_MEMBER_INFO); 29 | return R.ok().message("测试订单调用").data("user",claims.get("sub")).buildResponseEntity(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/result/AlipayF2FPayResult.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.result; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.TradeStatus; 4 | import com.alipay.api.response.AlipayTradePayResponse; 5 | 6 | /** 7 | * Created by liuyangkly on 15/8/26. 8 | */ 9 | public class AlipayF2FPayResult implements Result { 10 | private TradeStatus tradeStatus; 11 | private AlipayTradePayResponse response; 12 | 13 | public AlipayF2FPayResult(AlipayTradePayResponse response) { 14 | this.response = response; 15 | } 16 | 17 | public void setTradeStatus(TradeStatus tradeStatus) { 18 | this.tradeStatus = tradeStatus; 19 | } 20 | 21 | public void setResponse(AlipayTradePayResponse response) { 22 | this.response = response; 23 | } 24 | 25 | public TradeStatus getTradeStatus() { 26 | return tradeStatus; 27 | } 28 | 29 | public AlipayTradePayResponse getResponse() { 30 | return response; 31 | } 32 | 33 | @Override 34 | public boolean isTradeSuccess() { 35 | return response != null && 36 | TradeStatus.SUCCESS.equals(tradeStatus); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/result/AlipayF2FQueryResult.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.result; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.TradeStatus; 4 | import com.alipay.api.response.AlipayTradeQueryResponse; 5 | 6 | /** 7 | * Created by liuyangkly on 15/8/27. 8 | */ 9 | public class AlipayF2FQueryResult implements Result { 10 | private TradeStatus tradeStatus; 11 | private AlipayTradeQueryResponse response; 12 | 13 | public AlipayF2FQueryResult(AlipayTradeQueryResponse response) { 14 | this.response = response; 15 | } 16 | 17 | public void setTradeStatus(TradeStatus tradeStatus) { 18 | this.tradeStatus = tradeStatus; 19 | } 20 | 21 | public void setResponse(AlipayTradeQueryResponse response) { 22 | this.response = response; 23 | } 24 | 25 | public TradeStatus getTradeStatus() { 26 | return tradeStatus; 27 | } 28 | 29 | public AlipayTradeQueryResponse getResponse() { 30 | return response; 31 | } 32 | 33 | @Override 34 | public boolean isTradeSuccess() { 35 | return response != null && 36 | TradeStatus.SUCCESS.equals(tradeStatus); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/result/AlipayF2FRefundResult.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.result; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.TradeStatus; 4 | import com.alipay.api.response.AlipayTradeRefundResponse; 5 | 6 | /** 7 | * Created by liuyangkly on 15/8/27. 8 | */ 9 | public class AlipayF2FRefundResult implements Result { 10 | private TradeStatus tradeStatus; 11 | private AlipayTradeRefundResponse response; 12 | 13 | public AlipayF2FRefundResult(AlipayTradeRefundResponse response) { 14 | this.response = response; 15 | } 16 | 17 | public void setTradeStatus(TradeStatus tradeStatus) { 18 | this.tradeStatus = tradeStatus; 19 | } 20 | 21 | public void setResponse(AlipayTradeRefundResponse response) { 22 | this.response = response; 23 | } 24 | 25 | public TradeStatus getTradeStatus() { 26 | return tradeStatus; 27 | } 28 | 29 | public AlipayTradeRefundResponse getResponse() { 30 | return response; 31 | } 32 | 33 | @Override 34 | public boolean isTradeSuccess() { 35 | return response != null && 36 | TradeStatus.SUCCESS.equals(tradeStatus); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/config/MyUserDetailService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.security.core.userdetails.User; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | import org.springframework.security.crypto.password.PasswordEncoder; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * 自定义用户信息类 13 | * 14 | * @author YC 15 | * @since 2020/9/25 16 | */ 17 | @Component("userDetailService") 18 | public class MyUserDetailService implements UserDetailsService { 19 | @Autowired 20 | private PasswordEncoder passwordEncoder; 21 | 22 | @Override 23 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 24 | return User.builder() 25 | // 基于内存 26 | .username(username) 27 | .password(passwordEncoder.encode("admin")) 28 | .authorities("ROLE_ADMIN") 29 | .build(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/utils/GsonFactory.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.utils; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.hb.*; 4 | import com.google.gson.Gson; 5 | import com.google.gson.GsonBuilder; 6 | import com.google.gson.reflect.TypeToken; 7 | 8 | import java.lang.reflect.Type; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by liuyangkly on 15/6/26. 13 | * 使用google gson作为json序列化反序列化工具 14 | */ 15 | public class GsonFactory { 16 | 17 | private static class GsonHolder { 18 | private static Type exceptionListType = new TypeToken>(){}.getType(); 19 | private static Type tradeInfoListType = new TypeToken>(){}.getType(); 20 | 21 | private static Gson gson = new GsonBuilder() 22 | .registerTypeAdapter(exceptionListType, new ExceptionInfoAdapter()) 23 | .registerTypeAdapter(tradeInfoListType, new TradeInfoAdapter()) 24 | .registerTypeAdapter(EquipStatus.class, new EquipStatusAdapter()) 25 | .create(); 26 | } 27 | 28 | public static Gson getGson() { 29 | return GsonHolder.gson; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/result/AlipayF2FPrecreateResult.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.result; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.TradeStatus; 4 | import com.alipay.api.response.AlipayTradePrecreateResponse; 5 | 6 | /** 7 | * Created by liuyangkly on 15/8/27. 8 | */ 9 | public class AlipayF2FPrecreateResult implements Result { 10 | private TradeStatus tradeStatus; 11 | private AlipayTradePrecreateResponse response; 12 | 13 | public AlipayF2FPrecreateResult(AlipayTradePrecreateResponse response) { 14 | this.response = response; 15 | } 16 | 17 | public void setTradeStatus(TradeStatus tradeStatus) { 18 | this.tradeStatus = tradeStatus; 19 | } 20 | 21 | public void setResponse(AlipayTradePrecreateResponse response) { 22 | this.response = response; 23 | } 24 | 25 | public TradeStatus getTradeStatus() { 26 | return tradeStatus; 27 | } 28 | 29 | public AlipayTradePrecreateResponse getResponse() { 30 | return response; 31 | } 32 | 33 | @Override 34 | public boolean isTradeSuccess() { 35 | return response != null && 36 | TradeStatus.SUCCESS.equals(tradeStatus); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/config/WXPayConfigExt.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.config; 2 | 3 | import cn.yccoding.payment.wxpay.sdk.IWXPayDomain; 4 | import cn.yccoding.payment.wxpay.sdk.WXPayConfig; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.io.ByteArrayInputStream; 8 | import java.io.InputStream; 9 | 10 | /** 11 | * ext 12 | * 13 | * @author YC 14 | * @since 2020/9/28 15 | */ 16 | @Component 17 | public class WXPayConfigExt extends WXPayConfig { 18 | 19 | /** 20 | * 证书字节流 21 | */ 22 | private byte[] certData; 23 | 24 | @Override 25 | public String getAppID() { 26 | return WXPayConfigs.getAppId(); 27 | } 28 | 29 | @Override 30 | public String getMchID() { 31 | return WXPayConfigs.getMuchId(); 32 | } 33 | 34 | @Override 35 | public String getKey() { 36 | return WXPayConfigs.getApiKey(); 37 | } 38 | 39 | @Override 40 | public InputStream getCertStream() { 41 | ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData); 42 | return certBis; 43 | } 44 | 45 | @Override 46 | public IWXPayDomain getWXPayDomain() { 47 | return WXPayDomainSimpleImpl.instance(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/model/TradePaySummary.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.model; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.GoodsDetail; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * model 12 | * 13 | * @author YC 14 | * @since 2020/9/29 15 | */ 16 | @Data 17 | public class TradePaySummary implements Serializable { 18 | /** 19 | * 订单标题 20 | */ 21 | private String subject; 22 | 23 | /** 24 | * 商户门店编号 25 | */ 26 | private String storeId; 27 | 28 | /** 29 | * 商户操作员编号 30 | */ 31 | private String operatorId; 32 | 33 | private List items; 34 | 35 | @Data 36 | public static class Item implements Serializable{ 37 | // 商品编号(国标) 38 | private String goodsId; 39 | 40 | private String alipayGoodsId; 41 | 42 | // 商品名称 43 | private String goodsName; 44 | 45 | // 商品数量 46 | private int quantity; 47 | 48 | // 商品价格,此处单位为元,精确到小数点后2位 49 | private String price; 50 | 51 | // 商品类别 52 | private String goodsCategory; 53 | 54 | // 商品详情 55 | private String body; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/domain/service/impl/MemberServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.domain.service.impl; 2 | 3 | import cn.yccoding.member.domain.entity.Member; 4 | import cn.yccoding.member.domain.mapper.MemberMapper; 5 | import cn.yccoding.member.domain.service.MemberService; 6 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 7 | import com.baomidou.mybatisplus.core.toolkit.Wrappers; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import lombok.Data; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | *

16 | * 会员表 服务实现类 17 | *

18 | * 19 | * @author yc 20 | * @since 2020-09-03 21 | */ 22 | @Service 23 | public class MemberServiceImpl extends ServiceImpl implements MemberService { 24 | 25 | @Override 26 | public List getByPhone(String phone) { 27 | return this.list(Wrappers.lambdaQuery().select(Member::getId).eq(Member::getPhone, phone)); 28 | } 29 | 30 | @Override 31 | public List getByUsername(String username) { 32 | return this.list(Wrappers.lambdaQuery().select(Member::getId,Member::getUsername,Member::getPassword).eq(Member::getUsername, username)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/InterceptorConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config; 2 | 3 | import cn.yccoding.member.config.interceptor.AuthHandlerInterceptor; 4 | import cn.yccoding.member.config.property.NoAuthUrlProperties; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * 拦截器配置 15 | * 16 | * @author YC 17 | * @since 2020/9/4 18 | */ 19 | @Configuration 20 | public class InterceptorConfiguration implements WebMvcConfigurer { 21 | 22 | @Autowired 23 | private NoAuthUrlProperties noAuthUrlProperties; 24 | 25 | @Override 26 | public void addInterceptors(InterceptorRegistry registry) { 27 | registry.addInterceptor(authInterceptorHandler()) 28 | .addPathPatterns("/**") 29 | .excludePathPatterns(new ArrayList<>(noAuthUrlProperties.getShouldSkipUrls())); 30 | } 31 | 32 | @Bean 33 | public AuthHandlerInterceptor authInterceptorHandler() { 34 | return new AuthHandlerInterceptor(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/service/AlipayTradeService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.service; 2 | 3 | 4 | import cn.yccoding.payment.alipay.sdk.model.builder.AlipayTradePayRequestBuilder; 5 | import cn.yccoding.payment.alipay.sdk.model.builder.AlipayTradePrecreateRequestBuilder; 6 | import cn.yccoding.payment.alipay.sdk.model.builder.AlipayTradeQueryRequestBuilder; 7 | import cn.yccoding.payment.alipay.sdk.model.builder.AlipayTradeRefundRequestBuilder; 8 | import cn.yccoding.payment.alipay.sdk.model.result.AlipayF2FPayResult; 9 | import cn.yccoding.payment.alipay.sdk.model.result.AlipayF2FPrecreateResult; 10 | import cn.yccoding.payment.alipay.sdk.model.result.AlipayF2FQueryResult; 11 | import cn.yccoding.payment.alipay.sdk.model.result.AlipayF2FRefundResult; 12 | 13 | /** 14 | * Created by liuyangkly on 15/7/29. 15 | */ 16 | public interface AlipayTradeService { 17 | 18 | // 当面付2.0流程支付 19 | public AlipayF2FPayResult tradePay(AlipayTradePayRequestBuilder builder); 20 | 21 | // 当面付2.0消费查询 22 | public AlipayF2FQueryResult queryTradeResult(AlipayTradeQueryRequestBuilder builder); 23 | 24 | // 当面付2.0消费退款 25 | public AlipayF2FRefundResult tradeRefund(AlipayTradeRefundRequestBuilder builder); 26 | 27 | // 当面付2.0预下单(生成二维码) 28 | public AlipayF2FPrecreateResult tradePrecreate(AlipayTradePrecreateRequestBuilder builder); 29 | } 30 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/sdk/IWXPayDomain.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.sdk; 2 | 3 | /** 4 | * 域名管理,实现主备域名自动切换 5 | */ 6 | public abstract interface IWXPayDomain { 7 | /** 8 | * 上报域名网络状况 9 | * @param domain 域名。 比如:api.mch.weixin.qq.com 10 | * @param elapsedTimeMillis 耗时 11 | * @param ex 网络请求中出现的异常。 12 | * null表示没有异常 13 | * ConnectTimeoutException,表示建立网络连接异常 14 | * UnknownHostException, 表示dns解析异常 15 | */ 16 | abstract void report(final String domain, long elapsedTimeMillis, final Exception ex); 17 | 18 | /** 19 | * 获取域名 20 | * @param config 配置 21 | * @return 域名 22 | */ 23 | abstract DomainInfo getDomain(final WXPayConfig config); 24 | 25 | static class DomainInfo{ 26 | public String domain; //域名 27 | public boolean primaryDomain; //该域名是否为主域名。例如:api.mch.weixin.qq.com为主域名 28 | public DomainInfo(String domain, boolean primaryDomain) { 29 | this.domain = domain; 30 | this.primaryDomain = primaryDomain; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "DomainInfo{" + 36 | "domain='" + domain + '\'' + 37 | ", primaryDomain=" + primaryDomain + 38 | '}'; 39 | } 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/singleton/README.md: -------------------------------------------------------------------------------- 1 | # 单例模式 2 | 3 | ## 介绍 4 | 5 | - 分类:创建型模式 6 | - 目的:保证一个类全局只有一个实例对象 7 | - 关键:构造器私有 8 | - 场景:1. 全局频繁使用的对象;2. 重量级对象,不需要多个对象,数据库连接,线程池 9 | - 优点:1. 将具体产品和创建者解耦;2. 符合单一职责原则;3. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以 10 | - 缺点:1. 没有接口,不能继承;2. 与单一职责冲突,一个类只关心内部逻辑,不关注外部如何实例化 11 | 12 | ## 源码应用 13 | 14 | Spring & JDK 15 | 16 | java.lang.Runtime org.springframework.aop.framework.ProxyFactoryBean org.springframework.beans.factory.support.DefaultSingletonBeanRegistry org.springframework.core.ReactiveAdapterRegistry 17 | 18 | ## Demo实现 19 | 20 | ### 实现方式 21 | 22 | 1. 创建一个英雄单例类,单例类构造器私有, 23 | 2. 提供获取静态实例的方法; 24 | 25 | ### 图例 26 | 27 | ![img](https://notes-yc-01.oss-cn-shenzhen.aliyuncs.com/blog/2020/11/16/a499881b181346eaaf69bff48d695c29.png) 28 | 29 | ### 实现方式 30 | 31 | > 一下设计模式都考虑了线程安全 32 | 33 | #### 饿汉模式 34 | 35 | - 特点:类加载的初始化阶段就完成了实例的初始化。 36 | - 设计:本质上就是借助于jvm 类加载机制,保证实例的唯一性(初始化过程只会执行一次)及线程安全(JVM以同步的形式来完成类加载的整个过程) 37 | - 代码:`HungrySingleton.java` 38 | 39 | #### 懒汉模式 40 | 41 | - 特点:延迟加载, 只有在真正使用的时候,才开始实例化 42 | - 设计:DCL双端校验锁优化,volatile关键字防止编译器(JIT)指令重排导致未初始化实例 43 | - 代码:`LazySingleton.java` 44 | 45 | #### 静态内部类 46 | 47 | - 特点:懒加载的一种,只有在实际使用的时候,才会触发类的初始化 48 | - 设计:本质上是利用类的加载机制来保证线程安全 49 | - 代码:`InnerClassSingleton.java` 50 | 51 | #### 枚举 52 | 53 | - 特点:天然不支持反射创建对应的实例,且有自己的反序列化机制 54 | - 设计:本质上是利用类的加载机制来保证线程安全 55 | - 代码:`EnumSingleton.java` 56 | 57 | > 反射攻击及序列化攻击课参考示例代码 58 | 59 | 60 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/config/ResourceConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.config; 2 | 3 | import cn.yccoding.payment.property.AliPayTradeProperties; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /** 10 | * 资源配置 11 | * 12 | * @author YC 13 | * @since 2020/9/29 14 | */ 15 | @Configuration 16 | public class ResourceConfig implements WebMvcConfigurer { 17 | 18 | @Autowired 19 | private AliPayTradeProperties aliPayTradeProperties; 20 | 21 | @Override 22 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 23 | String os = System.getProperty("os.name"); 24 | // 将http请求路径映射到本地路径 25 | if (os.toLowerCase().startsWith("win")) { 26 | registry.addResourceHandler(aliPayTradeProperties.getQrcode().getHttpBasePath() + "/**") 27 | .addResourceLocations("file:" + aliPayTradeProperties.getQrcode().getStorePath() + "/"); 28 | } else { 29 | registry.addResourceHandler(aliPayTradeProperties.getQrcode().getHttpBasePath() + "/**") 30 | .addResourceLocations("file:" + aliPayTradeProperties.getQrcode().getStorePath() + "/"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/simplefactory/README.md: -------------------------------------------------------------------------------- 1 | # 简单工厂模式 2 | 3 | ## 介绍 4 | 5 | - 分类:创建型模式 6 | - 目的:保证一个类全局只有一个实例对象 7 | - 关键:构造器私有 8 | - 场景:1. 全局频繁使用的对象;2. 重量级对象,不需要多个对象,数据库连接,线程池 9 | - 优点:1. 将具体产品和创建者解耦;2. 符合单一职责原则;3. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以 10 | - 缺点:1. 没有接口,不能继承;2. 与单一职责冲突,一个类只关心内部逻辑,不关注外部如何实例化 11 | 12 | ## 源码应用 13 | 14 | Spring & JDK 15 | 16 | java.lang.Runtime org.springframework.aop.framework.ProxyFactoryBean org.springframework.beans.factory.support.DefaultSingletonBeanRegistry org.springframework.core.ReactiveAdapterRegistry 17 | 18 | ## Demo实现 19 | 20 | ### 实现方式 21 | 22 | 1. 创建一个英雄单例类,单例类构造器私有, 23 | 2. 提供获取静态实例的方法; 24 | 25 | ### 图例 26 | 27 | ![img](https://notes-yc-01.oss-cn-shenzhen.aliyuncs.com/blog/2020/11/16/a499881b181346eaaf69bff48d695c29.png) 28 | 29 | ### 实现方式 30 | 31 | > 以下设计模式都考虑了线程安全 32 | 33 | #### 饿汉模式 34 | 35 | - 特点:类加载的初始化阶段就完成了实例的初始化。 36 | - 设计:本质上就是借助于jvm 类加载机制,保证实例的唯一性(初始化过程只会执行一次)及线程安全(JVM以同步的形式来完成类加载的整个过程) 37 | - 代码:`HungrySingleton.java` 38 | 39 | #### 懒汉模式 40 | 41 | - 特点:延迟加载, 只有在真正使用的时候,才开始实例化 42 | - 设计:DCL双端校验锁优化,volatile关键字防止编译器(JIT)指令重排导致未初始化实例 43 | - 代码:`LazySingleton.java` 44 | 45 | #### 静态内部类 46 | 47 | - 特点:懒加载的一种,只有在实际使用的时候,才会触发类的初始化 48 | - 设计:本质上是利用类的加载机制来保证线程安全 49 | - 代码:`InnerClassSingleton.java` 50 | 51 | #### 枚举 52 | 53 | - 特点:天然不支持反射创建对应的实例,且有自己的反序列化机制 54 | - 设计:本质上是利用类的加载机制来保证线程安全 55 | - 代码:`EnumSingleton.java` 56 | 57 | > 反射攻击及序列化攻击课参考示例代码 58 | 59 | 60 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/controller/ConsumerTestController.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.controller; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import cn.yccoding.order.feignapi.ProducerTestFeignApi; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.Map; 13 | 14 | /** 15 | * 消费者测试 16 | * 17 | * @author YC 18 | * @since 2020/9/23 19 | */ 20 | @Slf4j 21 | @RestController 22 | @RequestMapping("/consumer") 23 | public class ConsumerTestController { 24 | @Autowired 25 | ProducerTestFeignApi producerTestFeignApi; 26 | 27 | @GetMapping("/local") 28 | public ResponseEntity consume() { 29 | log.info("消费者调用..."); 30 | return R.ok().message("消费者调用成功").buildResponseEntity(); 31 | } 32 | 33 | //@GlobalTransactional 34 | @GetMapping("/feign") 35 | public ResponseEntity feign() { 36 | log.info("消费者远程调用..."); 37 | R r = producerTestFeignApi.produce().getBody(); 38 | if (!r.isSuccess()) { 39 | return R.error().message("生产者繁忙...").buildResponseEntity(); 40 | } 41 | return R.ok().message("远程调用成功").data(r.getData()).buildResponseEntity(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/BaseWXPay.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import cn.yccoding.payment.wxpay.config.WXPayConfigs; 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import lombok.Getter; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 基础类 12 | * 13 | * @author YC 14 | * @since 2020/9/27 15 | */ 16 | @Getter 17 | @Accessors(chain = true) 18 | public class BaseWXPay implements Serializable { 19 | 20 | /** 21 | * 公众账号ID 22 | */ 23 | private final String appid = WXPayConfigs.getAppId(); 24 | 25 | /** 26 | * 商户号 27 | */ 28 | @JSONField(name = "mch_id") 29 | private final String mchId = WXPayConfigs.getMuchId(); 30 | 31 | /** 32 | * 随机字符串 33 | */ 34 | @JSONField(name = "nonce_str") 35 | private String nonceStr; 36 | 37 | /** 38 | * 签名 39 | */ 40 | private String sign; 41 | 42 | 43 | /** 44 | * 签名类型 45 | */ 46 | @JSONField(name = "sign_type") 47 | private String signType; 48 | 49 | public BaseWXPay setNonceStr(String nonceStr) { 50 | this.nonceStr = nonceStr; 51 | return this; 52 | } 53 | 54 | public BaseWXPay setSign(String sign) { 55 | this.sign = sign; 56 | return this; 57 | } 58 | 59 | public BaseWXPay setSignType(String signType) { 60 | this.signType = signType; 61 | return this; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/Refund.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 退款发起请求的实体类 9 | * @date : 2019/10/29 10 | */ 11 | @Data 12 | public class Refund extends BaseWXPay { 13 | 14 | /** 15 | * 微信订单号 16 | */ 17 | @JSONField(name = "transaction_id") 18 | private String transactionId; 19 | 20 | /** 21 | * 商户订单号 22 | */ 23 | @JSONField(name = "out_trade_no") 24 | private String outTradeNo; 25 | 26 | /** 27 | * 商户退款单号 28 | */ 29 | @JSONField(name = "out_refund_no") 30 | private String outRefundNo; 31 | 32 | /** 33 | * 订单金额 34 | */ 35 | @JSONField(name = "total_fee") 36 | private String totalFee; 37 | 38 | /** 39 | * 退款金额 40 | */ 41 | @JSONField(name = "refund_fee") 42 | private String refundFee; 43 | 44 | /** 45 | * 退款货币种类 46 | */ 47 | @JSONField(name = "refund_fee_type") 48 | private String refundFeeType; 49 | 50 | /** 51 | * 退款原因 52 | */ 53 | @JSONField(name = "refund_desc") 54 | private String refundDesc; 55 | 56 | /** 57 | * 退款资金来源 58 | */ 59 | @JSONField(name = "refund_account") 60 | private String refundAccount; 61 | 62 | /** 63 | * 退款结果通知url 64 | */ 65 | @JSONField(name = "notify_url") 66 | private String notifyUrl; 67 | 68 | } -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/domain/MyUserDetails.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter.domain; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | 10 | /** 11 | * 用户信息封装 12 | * 13 | * @author YC 14 | * @since 2020/9/25 15 | */ 16 | public class MyUserDetails implements UserDetails { 17 | 18 | private Member member; 19 | 20 | public MyUserDetails(Member member) { 21 | this.member = member; 22 | } 23 | 24 | @Override 25 | public Collection getAuthorities() { 26 | // 返回当前用户的权限 27 | return Arrays.asList(new SimpleGrantedAuthority("TEST")); 28 | } 29 | 30 | @Override 31 | public String getPassword() { 32 | return null; 33 | } 34 | 35 | @Override 36 | public String getUsername() { 37 | return null; 38 | } 39 | 40 | @Override 41 | public boolean isAccountNonExpired() { 42 | return false; 43 | } 44 | 45 | @Override 46 | public boolean isAccountNonLocked() { 47 | return false; 48 | } 49 | 50 | @Override 51 | public boolean isCredentialsNonExpired() { 52 | return false; 53 | } 54 | 55 | @Override 56 | public boolean isEnabled() { 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/java/cn/yccoding/gateway/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.gateway.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.reactive.CorsWebFilter; 7 | import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; 8 | import org.springframework.web.util.pattern.PathPatternParser; 9 | 10 | /** 11 | * 全局跨域配置 12 | * 13 | * @author YC 14 | * @since 2020/9/26 15 | */ 16 | @Configuration 17 | public class CorsConfig { 18 | 19 | @Bean 20 | public CorsWebFilter corsFilter() { 21 | final CorsConfiguration corsConfiguration = new CorsConfiguration(); 22 | // 允许cookies跨域 23 | corsConfiguration.setAllowCredentials(true); 24 | // 允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin 25 | corsConfiguration.addAllowedOrigin("*"); 26 | // 允许访问的头信息,*表示全部 27 | corsConfiguration.addAllowedHeader("*"); 28 | // 允许提交请求的方法,*表示全部允许 29 | corsConfiguration.addAllowedMethod("*"); 30 | // 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 31 | corsConfiguration.setMaxAge(18000L); 32 | final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); 33 | source.registerCorsConfiguration("/**", corsConfiguration); 34 | return new CorsWebFilter(source); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/sdk/WXPayXmlUtil.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.sdk; 2 | 3 | import org.w3c.dom.Document; 4 | 5 | import javax.xml.XMLConstants; 6 | import javax.xml.parsers.DocumentBuilder; 7 | import javax.xml.parsers.DocumentBuilderFactory; 8 | import javax.xml.parsers.ParserConfigurationException; 9 | 10 | /** 11 | * 2018/7/3 12 | */ 13 | public final class WXPayXmlUtil { 14 | public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { 15 | DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 16 | documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 17 | documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); 18 | documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); 19 | documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 20 | documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 21 | documentBuilderFactory.setXIncludeAware(false); 22 | documentBuilderFactory.setExpandEntityReferences(false); 23 | 24 | return documentBuilderFactory.newDocumentBuilder(); 25 | } 26 | 27 | public static Document newDocument() throws ParserConfigurationException { 28 | return newDocumentBuilder().newDocument(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/util/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.util; 2 | 3 | import java.security.MessageDigest; 4 | 5 | /** 6 | * @author : Chet 7 | * @description : 安全,如签名类方法 8 | * @date : 2019/11/5 9 | */ 10 | public class SecurityUtils { 11 | private static final char[] HEX_DIGITS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); 12 | 13 | public static String encode(String algorithm, String str) { 14 | if (str == null) { 15 | return null; 16 | } 17 | try { 18 | MessageDigest messageDigest = MessageDigest.getInstance(algorithm); 19 | messageDigest.update(str.getBytes()); 20 | return getFormattedText(messageDigest.digest()); 21 | } catch (Exception e) { 22 | throw new RuntimeException(e); 23 | } 24 | 25 | } 26 | 27 | private static String getFormattedText(byte[] bytes) { 28 | int len = bytes.length; 29 | StringBuilder buf = new StringBuilder(len * 2); 30 | // 把密文转换成十六进制的字符串形式 31 | for (int j = 0; j < len; j++) { 32 | buf.append(HEX_DIGITS[(bytes[j] >>> 4) & 0x0f]); 33 | buf.append(HEX_DIGITS[bytes[j] & 0x0f]); 34 | } 35 | return buf.toString(); 36 | } 37 | 38 | 39 | public static String MD5(String content){ 40 | return SecurityUtils.encode("MD5", content); 41 | } 42 | 43 | public static String SHA1(String content){ 44 | return SecurityUtils.encode("SHA1", content); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.utils; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | import java.math.BigDecimal; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by liuyangkly on 15/6/27. 12 | * 杂物工具类 13 | */ 14 | public class Utils { 15 | 16 | private Utils() { 17 | // No instances. 18 | } 19 | 20 | public static String toAmount(long amount) { 21 | return new BigDecimal(amount).divide(new BigDecimal(100)).toString(); 22 | } 23 | 24 | public static String toDate(Date date) { 25 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); 26 | } 27 | 28 | public static boolean isEmpty(Object object) { 29 | if (object instanceof String) { 30 | return StringUtils.isEmpty((String) object); 31 | } 32 | return object == null; 33 | } 34 | 35 | public static boolean isNotEmpty(Object object) { 36 | return !isEmpty(object); 37 | } 38 | 39 | public static boolean isListNotEmpty(List list) { 40 | return list != null && list.size() > 0; 41 | } 42 | 43 | public static boolean isListEmpty(List list) { 44 | return !isListNotEmpty(list); 45 | } 46 | 47 | public static void sleep(long time) { 48 | try { 49 | Thread.sleep(time); 50 | } catch (InterruptedException e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/config/MyBatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; 5 | import com.baomidou.mybatisplus.core.MybatisConfiguration; 6 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 7 | import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; 8 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 9 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 10 | import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; 11 | import org.mybatis.spring.annotation.MapperScan; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.transaction.annotation.EnableTransactionManagement; 15 | 16 | /** 17 | * @author YC 18 | * @since 2020/9/3 19 | */ 20 | @EnableTransactionManagement 21 | @Configuration 22 | @MapperScan("cn.yccoding.*.domain.mapper") 23 | public class MyBatisPlusConfig { 24 | /** 25 | * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题 26 | */ 27 | @Bean 28 | public MybatisPlusInterceptor paginationInterceptor() { 29 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 30 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 31 | return interceptor; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /flow-framework-mbg/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cloud-flow 7 | cn.yccoding 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | flow-framework-mbg 13 | mybatis-plus模版生成模块 14 | 15 | 16 | 17 | 18 | cn.yccoding 19 | flow-framework-common 20 | 21 | 22 | 23 | mysql 24 | mysql-connector-java 25 | 26 | 27 | 28 | com.baomidou 29 | mybatis-plus-boot-starter 30 | 31 | 32 | com.baomidou 33 | mybatis-plus-generator 34 | 35 | 36 | 37 | org.apache.velocity 38 | velocity-engine-core 39 | 40 | 41 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/service/impl/AbsAlipayService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.service.impl; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.builder.RequestBuilder; 4 | import com.alipay.api.AlipayApiException; 5 | import com.alipay.api.AlipayClient; 6 | import com.alipay.api.AlipayRequest; 7 | import com.alipay.api.AlipayResponse; 8 | import org.apache.commons.logging.Log; 9 | import org.apache.commons.logging.LogFactory; 10 | 11 | /** 12 | * Created by liuyangkly on 15/10/22. 13 | */ 14 | abstract class AbsAlipayService { 15 | protected Log log = LogFactory.getLog(getClass()); 16 | 17 | // 验证bizContent对象 18 | protected void validateBuilder(RequestBuilder builder) { 19 | if (builder == null) { 20 | throw new NullPointerException("builder should not be NULL!"); 21 | } 22 | 23 | if (!builder.validate()) { 24 | throw new IllegalStateException("builder validate failed! " + builder.toString()); 25 | } 26 | } 27 | 28 | // 调用AlipayClient的execute方法,进行远程调用 29 | @SuppressWarnings({ "rawtypes", "unchecked" }) 30 | protected AlipayResponse getResponse(AlipayClient client, AlipayRequest request) { 31 | try { 32 | AlipayResponse response = client.execute(request); 33 | if (response != null) { 34 | log.info(response.getBody()); 35 | } 36 | return response; 37 | 38 | } catch (AlipayApiException e) { 39 | e.printStackTrace(); 40 | return null; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/SysTradeInfo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * Created by liuyangkly on 15/8/27. 7 | */ 8 | public class SysTradeInfo implements TradeInfo { 9 | @SerializedName("OTN") 10 | private String outTradeNo; 11 | 12 | @SerializedName("TC") 13 | private double timeConsume; 14 | 15 | @SerializedName("STAT") 16 | private HbStatus status; 17 | 18 | private SysTradeInfo() { 19 | // no public constructor. 20 | } 21 | 22 | public static SysTradeInfo newInstance(String outTradeNo, double timeConsume, HbStatus status) { 23 | SysTradeInfo info = new SysTradeInfo(); 24 | info.setOutTradeNo(outTradeNo); 25 | if (timeConsume > 99 || timeConsume < 0) { 26 | timeConsume = 99; 27 | } 28 | info.setTimeConsume(timeConsume); 29 | info.setStatus(status); 30 | return info; 31 | } 32 | 33 | public String getOutTradeNo() { 34 | return outTradeNo; 35 | } 36 | 37 | public void setOutTradeNo(String outTradeNo) { 38 | this.outTradeNo = outTradeNo; 39 | } 40 | 41 | @Override 42 | public HbStatus getStatus() { 43 | return status; 44 | } 45 | 46 | public void setStatus(HbStatus status) { 47 | this.status = status; 48 | } 49 | 50 | @Override 51 | public double getTimeConsume() { 52 | return timeConsume; 53 | } 54 | 55 | public void setTimeConsume(double timeConsume) { 56 | this.timeConsume = timeConsume; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/model/Report.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.model; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author : Chet 8 | * @description : 交易保障 实体类 9 | * @date : 2019/10/30 10 | */ 11 | @Data 12 | public class Report extends BaseWXPay { 13 | 14 | /** 15 | * 设备号 16 | */ 17 | @JSONField(name = "device_info") 18 | private String deviceInfo; 19 | 20 | /** 21 | * 接口URL 22 | */ 23 | @JSONField(name = "interface_url") 24 | private String interfaceUrl; 25 | 26 | /** 27 | * 接口耗时 28 | */ 29 | @JSONField(name = "execute_time") 30 | private String executeTime; 31 | 32 | /** 33 | * 返回状态码 34 | */ 35 | @JSONField(name = "return_code") 36 | private String returnCode; 37 | 38 | /** 39 | * 返回信息 40 | */ 41 | @JSONField(name = "return_msg") 42 | private String returnMsg; 43 | 44 | /** 45 | * 业务结果 46 | */ 47 | @JSONField(name = "result_code") 48 | private String resultCode; 49 | 50 | /** 51 | * 错误代码 52 | */ 53 | @JSONField(name = "err_code") 54 | private String errCode; 55 | 56 | /** 57 | * 错误代码描述 58 | */ 59 | @JSONField(name = "err_code_des") 60 | private String errCodeDes; 61 | 62 | /** 63 | * 商户订单号 64 | */ 65 | @JSONField(name = "out_trade_no") 66 | private String outTradeNo; 67 | 68 | /** 69 | * 访问接口IP 70 | */ 71 | @JSONField(name = "user_ip") 72 | private String userIp; 73 | 74 | /** 75 | * 商户上报时间 76 | */ 77 | private String time; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/hb/PosTradeInfo.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.hb; 2 | 3 | /** 4 | * Created by liuyangkly on 15/9/28. 5 | */ 6 | public class PosTradeInfo implements TradeInfo { 7 | private HbStatus status; 8 | private String time; 9 | private int timeConsume; 10 | 11 | private PosTradeInfo() { 12 | // no public constructor. 13 | } 14 | 15 | public static PosTradeInfo newInstance(HbStatus status, String time, int timeConsume) { 16 | PosTradeInfo info = new PosTradeInfo(); 17 | if (timeConsume > 99 || timeConsume < 0) { 18 | timeConsume = 99; 19 | } 20 | info.setTimeConsume(timeConsume); 21 | info.setStatus(status); 22 | info.setTime(time); 23 | return info; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return new StringBuilder(status.name()) 29 | .append(time) 30 | .append(String.format("%02d", timeConsume)) 31 | .toString(); 32 | } 33 | 34 | @Override 35 | public HbStatus getStatus() { 36 | return status; 37 | } 38 | 39 | public void setStatus(HbStatus status) { 40 | this.status = status; 41 | } 42 | 43 | public String getTime() { 44 | return time; 45 | } 46 | 47 | public void setTime(String time) { 48 | this.time = time; 49 | } 50 | 51 | @Override 52 | public double getTimeConsume() { 53 | return (double) timeConsume; 54 | } 55 | 56 | public void setTimeConsume(int timeConsume) { 57 | this.timeConsume = timeConsume; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/src/main/java/cn/yccoding/authcenter/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.authcenter.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.authentication.AuthenticationManager; 7 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 11 | import org.springframework.security.crypto.password.PasswordEncoder; 12 | 13 | /** 14 | * 安全配置 15 | * 16 | * @author YC 17 | * @since 2020/9/25 18 | */ 19 | @Configuration 20 | @EnableWebSecurity 21 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 22 | 23 | @Autowired 24 | private MyUserDetailService userDetailService; 25 | /** 26 | * 构建用户认证组 27 | * @param auth 28 | * @throws Exception 29 | */ 30 | @Override 31 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 32 | auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder()); 33 | } 34 | 35 | @Override 36 | @Bean 37 | public AuthenticationManager authenticationManagerBean() throws Exception { 38 | return super.authenticationManagerBean(); 39 | } 40 | 41 | @Bean 42 | public PasswordEncoder passwordEncoder() { 43 | return new BCryptPasswordEncoder(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cloud-flow 2 | 3 | 云流——微服务聚合平台 4 | 5 | ## 核心依赖 6 | 7 | SpringBoot 2.1.7.RELEASE 8 | 9 | ## 模块简介 10 | 11 | ``` 12 | cloud-flow 13 | |-- flow-framework-parent 父项目,管理版本依赖 14 | |-- flow-framework-common 公共模块,为各个子模块调用 15 | |-- flow-framework-mbg mybatis-plus自动生成工具 16 | |-- flow-microservice-authcenter 授权中心 17 | |-- flow-microservice-gatewayr 网关 18 | |-- flow-microservice-member 会员中心 19 | |-- flow-microservice-order 订单服务 20 | |-- flow-microservice-payment 支付服务 21 | |-- flow-microservice-product 产品服务 22 | ``` 23 | 24 | ## 启动说明 25 | 26 | ### 注册&配置中心 27 | 28 | 项目使用的微服务是基于alibaba的springcloud,因此需要做以下准备: 29 | 30 | - 下载[nacos](https://github.com/alibaba/nacos/releases),他是服务的注册中心和配置中心。详细使用可参考[官方文档](https://nacos.io/zh-cn/docs/what-is-nacos.html) 31 | 32 | ![](https://notes-yc-01.oss-cn-shenzhen.aliyuncs.com/blog/2020/09/30/992c5d10be444f4a967b4e57f419eb44.png) 33 | 34 | - 解压到本地,进入bin目录,打开终端 35 | 36 | - 输入命令,启动nacos,以单机为例: 37 | 38 | ```shell script 39 | sh startup.sh -m standalone 40 | ``` 41 | 42 | - 访问nacos界面,默认端口8848 http://localhost:8848/nacos/index.html 43 | 44 | ![](https://notes-yc-01.oss-cn-shenzhen.aliyuncs.com/blog/2020/09/30/e7adadbbba7d4b2ab7dd34406c45a5b2.png) 45 | 46 | ### 服务启动 47 | 48 | 以下启动流程是一个常规的微服务启动流程,若是开发或测试功能,根据需要启动即可 49 | 50 | 1. GateWayApplication 51 | 52 | 网关服务,支持路由,断言,过滤等功能 53 | 54 | 2. AuthCenterApplication 55 | 56 | 授权中心,支持token的颁发 57 | 58 | > 为避免只启动单独几个应用,默认注释认证和授权配置 59 | 60 | 3. ProductApplication 61 | 62 | 产品服务,模拟生产者 63 | 64 | 4. OderApplication 65 | 66 | 订单服务,默认消费者 67 | 68 | 5. PaymentApplication 69 | 70 | 支付服务,支持支付宝和微信支付 71 | 72 | 6. MemberApplication 73 | 74 | 会员中心,简要集成session和jwt的使用 75 | 76 | ## 代码格式化说明 77 | 本项目代码使用了阿里巴巴的代码规范,Eeclipse/Idea代码格式化设置可参考链接: [java代码格式化模板(阿里代码规范)](http://ddrv.cn/a/235259) 78 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/client/RedisOpsClient.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.client; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.data.redis.core.RedisTemplate; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * redis 10 | * 11 | * @author YC 12 | * @since 2020/9/27 13 | */ 14 | public class RedisOpsClient { 15 | 16 | @Autowired 17 | private RedisTemplate redisTemplate; 18 | 19 | public void set(String key,Object value){ 20 | redisTemplate.opsForValue().set(key,value); 21 | } 22 | 23 | public void set(String key, Object value, long timeout, TimeUnit unit){ 24 | redisTemplate.opsForValue().set(key,value,timeout,unit); 25 | } 26 | 27 | public boolean setIfAbsent(String key, Object value, long timeout, TimeUnit unit){ 28 | return redisTemplate.opsForValue().setIfAbsent(key,value,timeout,unit); 29 | } 30 | 31 | public T get(String key,Class T){ 32 | return (T)redisTemplate 33 | .opsForValue().get(key); 34 | } 35 | 36 | public String get(String key){ 37 | return (String) redisTemplate 38 | .opsForValue().get(key); 39 | } 40 | 41 | public Long decr(String key){ 42 | return redisTemplate 43 | .opsForValue().decrement(key); 44 | } 45 | 46 | public Long decr(String key,long delta){ 47 | return redisTemplate 48 | .opsForValue().decrement(key,delta); 49 | } 50 | 51 | public Long incr(String key){ 52 | return redisTemplate 53 | .opsForValue().increment(key); 54 | } 55 | 56 | public Long incr(String key,long delta){ 57 | return redisTemplate 58 | .opsForValue().increment(key,delta); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /flow-framework-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cloud-flow 7 | cn.yccoding 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | flow-framework-common 13 | 公共模块 14 | jar 15 | 16 | 17 | 18 | 19 | org.projectlombok 20 | lombok 21 | 22 | 23 | cn.hutool 24 | hutool-all 25 | 26 | 27 | 28 | org.springframework 29 | spring-web 30 | 31 | 32 | 33 | mysql 34 | mysql-connector-java 35 | true 36 | 37 | 38 | 39 | com.alibaba 40 | druid-spring-boot-starter 41 | true 42 | 43 | 44 | 45 | com.baomidou 46 | mybatis-plus-boot-starter 47 | true 48 | 49 | 50 | -------------------------------------------------------------------------------- /flow-microservice-authcenter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cloud-flow 7 | cn.yccoding 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | flow-microservice-authcenter 13 | 认证授权中心 14 | 15 | 16 | 17 | cn.yccoding 18 | flow-framework-common 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | 27 | com.alibaba.cloud 28 | spring-cloud-alibaba-nacos-discovery 29 | 30 | 31 | 32 | com.alibaba.cloud 33 | spring-cloud-alibaba-nacos-config 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-starter-oauth2 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/service/impl/hb/HbQueue.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.service.impl.hb; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.hb.SysTradeInfo; 4 | import org.apache.commons.logging.Log; 5 | import org.apache.commons.logging.LogFactory; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.concurrent.ArrayBlockingQueue; 10 | import java.util.concurrent.BlockingQueue; 11 | 12 | /** 13 | * Created by liuyangkly on 15/10/23. 14 | private List> concurrentQueueList = Collections.synchronizedList(queueList); 15 | */ 16 | public class HbQueue { 17 | private static Log log = LogFactory.getLog(HbQueue.class); 18 | 19 | public static final int QUEUE_SIZE = 300; // 最多同时保存300条交易记录 20 | private static final BlockingQueue queue = new ArrayBlockingQueue(QUEUE_SIZE); 21 | 22 | public synchronized static void offer(SysTradeInfo info) { 23 | // blockingQueue不需要考虑队列满的情况,生产者会被阻塞直到队列被消耗 24 | if (info != null) { 25 | try { 26 | // 使用阻塞put 27 | queue.put(info); 28 | } catch (InterruptedException e) { 29 | log.warn("interrupted for tradeInfo:" + info); 30 | e.printStackTrace(); 31 | } 32 | } 33 | } 34 | 35 | public synchronized static List poll() { 36 | if (queue.isEmpty()) { 37 | // 如果队列为空,则直接返回 38 | return null; 39 | } 40 | 41 | int size = 30; 42 | List tradeInfoList = new ArrayList(size); 43 | for (int i = 0; i < size; i++) { 44 | // 使用非阻塞poll 45 | SysTradeInfo info = queue.poll(); 46 | if (info == null) { 47 | break; 48 | } 49 | tradeInfoList.add(info); 50 | } 51 | return tradeInfoList; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9110 3 | # tomcat的最大并发值修 4 | tomcat: 5 | max-threads: 100 6 | 7 | spring: 8 | application: 9 | name: flow-member 10 | # redis 配置 11 | redis: 12 | #redis数据库,默认是0 13 | database: 0 14 | #redis服务器地址 15 | host: localhost 16 | #redis服务端口,默认6379 17 | port: 6379 18 | #redis密码,默认为空 19 | password: 20 | #超时 21 | timeout: 5000ms 22 | # mysql数据源配置 23 | datasource: 24 | driver-class-name: com.mysql.cj.jdbc.Driver 25 | hikari: 26 | connection-test-query: SELECT 1 FROM DUAL 27 | connection-timeout: 60000 28 | idle-timeout: 500000 29 | max-lifetime: 540000 30 | maximum-pool-size: 12 31 | minimum-idle: 10 32 | pool-name: GuliHikariPool 33 | type: com.zaxxer.hikari.HikariDataSource 34 | url: jdbc:mysql://localhost:3306/flow_single?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai 35 | username: root 36 | password: 1234 37 | 38 | # spring session 会员存储 39 | # session: 40 | # store-type: redis 41 | 42 | # mybatis日志 43 | mybatis-plus: 44 | global-config: 45 | db-config: 46 | logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2) 47 | logic-delete-value: 1 # 逻辑已删除值(默认为 1) 48 | logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) 49 | configuration: 50 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 51 | mapper-locations: classpath:cn/yccoding/member/domain/mapper/xml/*.xml 52 | 53 | 54 | ####### 自定义属性健 55 | # 自定义redis键值 56 | redis: 57 | key: 58 | prefix: 59 | otpCode: "member:otpCode:" #动态校验码前缀 60 | expire: 61 | otpCode: 60 #动态校验码过期时间 62 | #登录拦截验证 63 | member: 64 | auth: 65 | # 免拦截 66 | shouldSkipUrls: 67 | - /sso/** 68 | - /home/** 69 | #jwt配置 70 | jwt: 71 | header: Authorization #JWT存储的请求头 72 | secret: mall-member-secret #JWT加解密使用的密钥 73 | expire: 604800 #JWT的超期限时间(60*60*24) 74 | prefix: Bearer #JWT负载中拿到开头 75 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/RedisConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.data.redis.connection.RedisConnectionFactory; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 11 | import org.springframework.data.redis.serializer.StringRedisSerializer; 12 | 13 | /** 14 | * redis配置类 15 | * 16 | * @author YC 17 | * @since 2020/9/3 18 | */ 19 | @Configuration 20 | public class RedisConfiguration { 21 | 22 | @Bean 23 | public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { 24 | RedisTemplate redisTemplate = new RedisTemplate(); 25 | redisTemplate.setConnectionFactory(redisConnectionFactory); 26 | 27 | // json对象序列化 28 | Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); 29 | ObjectMapper om = new ObjectMapper(); 30 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 31 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 32 | jsonRedisSerializer.setObjectMapper(om); 33 | 34 | // string序列化 35 | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 36 | 37 | redisTemplate.setKeySerializer(stringRedisSerializer); 38 | redisTemplate.setValueSerializer(jsonRedisSerializer); 39 | redisTemplate.setHashKeySerializer(stringRedisSerializer); 40 | redisTemplate.setHashValueSerializer(jsonRedisSerializer); 41 | 42 | redisTemplate.afterPropertiesSet(); 43 | return redisTemplate; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/base/ResultCodeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.base; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @Author YC 8 | * @create 2020/3/3 9 | * 结果信息枚举 10 | */ 11 | @Getter 12 | @AllArgsConstructor 13 | public enum ResultCodeEnum { 14 | SUCCESS(true, 20000, "成功"), 15 | 16 | UNKNOWN_ERROR(false, 30001, "未知错误"), 17 | 18 | PARAM_ERROR(false, 30002, "参数错误"), 19 | 20 | NULL_POINTER(false, 30003, "空指针异常"), 21 | SQL_EXCEPTION(false,30004, "sql执行异常" ), 22 | DUPLICATE_KEY(false,30005, "关键字重复" ), 23 | NOTFOUND_USER(false, 30006, "用户名不存在"), 24 | UNMATCH_UNAME_PWD(false, 30006, "用户名或密码错误"), 25 | 26 | JWT_EXPIRED(false, 31001, "JWT验证失败:token已经过期"), 27 | JWT_UNSUPPORTED(false, 31001, "JWT验证失败:token格式不支持"), 28 | JWT_MALFORMED(false, 31001, "JWT验证失败:token格式错误"), 29 | JWT_SIGNATURE(false, 31001, "JWT验证失败:token签名错误"), 30 | JWT_ILLEGAL_ARGUMENT(false, 31001, "JWT验证失败:token非法参数"), 31 | 32 | /** 33 | * member module 34 | */ 35 | EXISTED_USER(false, 41000, "用户已存在"), 36 | INCORRECT_OPTCODE(false, 41001, "验证码未过期"), 37 | UNMATCH_OPTCODE(false, 41002, "验证码不匹配"), 38 | UNAUTHORIZED(false, 41003, "未登录或token已经过期"), 39 | AUTHORIZATION_HEADER_IS_EMPTY(false, 41004, "请求头无授权信息"), 40 | AUTHORIZATION_INVALID(false,41005, "无效的token信息"), 41 | TOKEN_EXPIRED(false, 41006, "token已过期"), 42 | ACCESS_FORBIDEN(false, 41007, "没有访问权限"), 43 | 44 | /** 45 | * wechat pay 46 | */ 47 | WXPAY_INSTANCE_CREATE_FAIL(false, 51001, "微信支付实例创建失败"), 48 | WXPAY_REQUEST_FAILED(false, 51002, "微信支付接口请求失败"), 49 | WXPAY_FETCH_TOKEN_FAILED(false, 51003, "微信公众号获取access token失败"), 50 | ALIPAY_CALLBACK_CHECK_FAILED(false, 52001, "支付宝支付回调结果验签失败"),; 51 | 52 | /** 53 | * 响应是否成功 54 | */ 55 | private final boolean success; 56 | /** 57 | * 响应状态码 58 | */ 59 | private final int code; 60 | /** 61 | * 响应信息 62 | */ 63 | private final String message; 64 | } 65 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/config/WXPaymentConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.config; 2 | 3 | import cn.yccoding.common.base.ResultCodeEnum; 4 | import cn.yccoding.common.exception.CustomException; 5 | import cn.yccoding.payment.wxpay.config.WXPayConfigs; 6 | import cn.yccoding.payment.wxpay.config.WXPayConfigExt; 7 | import cn.yccoding.payment.wxpay.sdk.WXPay; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | /** 13 | * config 14 | * 15 | * @author YC 16 | * @since 2020/9/28 17 | */ 18 | @Slf4j 19 | @Configuration 20 | public class WXPaymentConfig { 21 | public static String APP_ID; 22 | public static String APP_SECRET; 23 | public static String MUCH_ID; 24 | public static String API_KEY; 25 | public static String REGISTER_DOMAIN; 26 | public static String JSAPI_PAYMENT_AUTH_DIR; 27 | public static String JS_DOMAIN; 28 | public static String WEB_AUTH_DOMAIN; 29 | public static String APICLIENT_CERT; 30 | public static String NOTIFY_URL; 31 | public static String NOTIFY_URL_REFUND; 32 | 33 | static { 34 | WXPayConfigs.init("payment/wxinfo.properties"); 35 | APP_ID = WXPayConfigs.getAppId(); 36 | APP_SECRET = WXPayConfigs.getAppSecret(); 37 | MUCH_ID = WXPayConfigs.getMuchId(); 38 | API_KEY = WXPayConfigs.getApiKey(); 39 | NOTIFY_URL = WXPayConfigs.getNotifyUrl(); 40 | NOTIFY_URL_REFUND = WXPayConfigs.getNotifyUrlRefund(); 41 | } 42 | 43 | /** 44 | * 注入wxpay实例,同时获取微信支付的信息参数 45 | * @return 46 | */ 47 | @Bean 48 | public WXPay wxPay() { 49 | WXPay wxPay = null; 50 | try { 51 | wxPay = new WXPay(new WXPayConfigExt()); 52 | } catch (Exception e) { 53 | log.error("创建默认wxpay实列失败:[{}]", e.getMessage()); 54 | throw new CustomException(ResultCodeEnum.WXPAY_INSTANCE_CREATE_FAIL); 55 | } 56 | return wxPay; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/singleton/InnerClassSingleton.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.singleton; 2 | 3 | import java.io.ObjectStreamException; 4 | import java.io.Serializable; 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.InvocationTargetException; 7 | 8 | /** 9 | * 单例模式--静态内部类 10 | * 11 | * @author YC 12 | * @since 2020/11/27 13 | */ 14 | public class InnerClassSingleton implements Serializable { 15 | static final long serialVersionUID = 1L; 16 | 17 | private InnerClassSingleton() { 18 | // 防止反射破坏 19 | if (InnerClassHolder.instance != null) { 20 | throw new RuntimeException("单例模式不允许多个实例"); 21 | } 22 | } 23 | 24 | public static InnerClassSingleton getInstance() { 25 | return InnerClassHolder.instance; 26 | } 27 | 28 | /** 29 | * 模拟反射攻击 30 | * 31 | * @param args 32 | */ 33 | public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { 34 | Constructor declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor(); 35 | declaredConstructor.setAccessible(true); 36 | InnerClassSingleton innerClassSingleton = declaredConstructor.newInstance(); 37 | InnerClassSingleton instance = InnerClassSingleton.getInstance(); 38 | System.out.println(innerClassSingleton == instance); 39 | } 40 | 41 | /** 42 | * 提供readResolve()方法,防反序列化 43 | * 当JVM反序列化地恢复一个新对象时,系统会自动调用这个readResolve()方法返回指定好的对象,从而保证系统通过反序列化机制不会产生多个java对象 44 | * 45 | * @return 46 | * @throws ObjectStreamException 47 | */ 48 | Object readResolve() throws ObjectStreamException { 49 | return InnerClassHolder.instance; 50 | } 51 | 52 | /** 53 | * 实例的创建,只有世纪调用外部类时,出发静态内部类的初始化,属于懒加载 54 | */ 55 | private static class InnerClassHolder { 56 | private static final InnerClassSingleton instance = new InnerClassSingleton(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/service/impl/hb/HbListener.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.service.impl.hb; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.hb.HbStatus; 4 | import cn.yccoding.payment.alipay.sdk.model.hb.SysTradeInfo; 5 | import org.apache.commons.logging.Log; 6 | import org.apache.commons.logging.LogFactory; 7 | 8 | /** 9 | * Created by liuyangkly on 15/10/28. 10 | */ 11 | public class HbListener implements TradeListener { 12 | private static Log log = LogFactory.getLog(HbListener.class); 13 | 14 | private void offerTradeInfo(String outTradeNo, long beforeCall, HbStatus status) { 15 | // 获取当前毫秒数 16 | long afterCall = System.currentTimeMillis(); 17 | 18 | // 通过交易请求发生时毫秒数计算得到交易耗时 19 | double timeConsume = ((double) (afterCall - beforeCall)) / 1000.0; 20 | 21 | log.debug(outTradeNo + " offer " + status + ": " + timeConsume); 22 | 23 | // 创建系统商trade_info结构,添加进队列 24 | HbQueue.offer(SysTradeInfo.newInstance(outTradeNo, timeConsume, status)); 25 | } 26 | 27 | @Override 28 | public void onPayTradeSuccess(String outTradeNo, long beforeCall) { 29 | offerTradeInfo(outTradeNo, beforeCall, HbStatus.S); 30 | } 31 | 32 | @Override 33 | public void onPayInProgress(String outTradeNo, long beforeCall) { 34 | offerTradeInfo(outTradeNo, beforeCall, HbStatus.I); 35 | } 36 | 37 | @Override 38 | public void onPayFailed(String outTradeNo, long beforeCall) { 39 | offerTradeInfo(outTradeNo, beforeCall, HbStatus.F); 40 | } 41 | 42 | @Override 43 | public void onConnectException(String outTradeNo, long beforeCall) { 44 | offerTradeInfo(outTradeNo, beforeCall, HbStatus.X); 45 | } 46 | 47 | @Override 48 | public void onSendException(String outTradeNo, long beforeCall) { 49 | offerTradeInfo(outTradeNo, beforeCall, HbStatus.Y); 50 | } 51 | 52 | @Override 53 | public void onReceiveException(String outTradeNo, long beforeCall) { 54 | offerTradeInfo(outTradeNo, beforeCall, HbStatus.Z); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /flow-microservice-product/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cloud-flow 7 | cn.yccoding 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | flow-microservice-product 13 | 产品微服务 14 | 15 | 16 | 17 | cn.yccoding 18 | flow-framework-common 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | 27 | com.alibaba.cloud 28 | spring-cloud-starter-alibaba-nacos-config 29 | 30 | 31 | 32 | com.alibaba.cloud 33 | spring-cloud-starter-alibaba-nacos-discovery 34 | 35 | 36 | 37 | com.alibaba.cloud 38 | spring-cloud-starter-alibaba-sentinel 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-actuator 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/builder/RequestBuilder.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.builder; 2 | 3 | import cn.yccoding.payment.alipay.sdk.utils.GsonFactory; 4 | 5 | /** 6 | * Created by liuyangkly on 15/7/31. 7 | */ 8 | public abstract class RequestBuilder { 9 | private String appAuthToken; 10 | private String notifyUrl; 11 | 12 | // 验证请求对象 13 | public abstract boolean validate(); 14 | 15 | // 获取bizContent对象,用于下一步转换为json字符串 16 | public abstract Object getBizContent(); 17 | 18 | // 将bizContent对象转换为json字符串 19 | public String toJsonString() { 20 | // 使用gson将对象转换为json字符串 21 | /** 22 | * See https://sites.google.com/site/gson/gson-user-guide#TOC-Using-Gson 23 | * Object Examples 24 | 25 | class BagOfPrimitives { 26 | private int value1 = 1; 27 | private String value2 = "abc"; 28 | private transient int value3 = 3; 29 | BagOfPrimitives() { 30 | // no-args constructor 31 | } 32 | } 33 | 34 | (Serialization) 35 | BagOfPrimitives obj = new BagOfPrimitives(); 36 | Gson gson = new Gson(); 37 | String json = gson.toJson(obj); 38 | ==> json is {"value1":1,"value2":"abc"} 39 | */ 40 | return GsonFactory.getGson().toJson(this.getBizContent()); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | final StringBuilder sb = new StringBuilder("RequestBuilder{"); 46 | sb.append("appAuthToken='").append(appAuthToken).append('\''); 47 | sb.append(", notifyUrl='").append(notifyUrl).append('\''); 48 | sb.append('}'); 49 | return sb.toString(); 50 | } 51 | 52 | public String getAppAuthToken() { 53 | return appAuthToken; 54 | } 55 | 56 | public RequestBuilder setAppAuthToken(String appAuthToken) { 57 | this.appAuthToken = appAuthToken; 58 | return this; 59 | } 60 | 61 | public String getNotifyUrl() { 62 | return notifyUrl; 63 | } 64 | 65 | public RequestBuilder setNotifyUrl(String notifyUrl) { 66 | this.notifyUrl = notifyUrl; 67 | return this; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/sdk/WXPayConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.sdk; 2 | 3 | import java.io.InputStream; 4 | 5 | public abstract class WXPayConfig { 6 | 7 | 8 | 9 | /** 10 | * 获取 App ID 11 | * 12 | * @return App ID 13 | */ 14 | public abstract String getAppID(); 15 | 16 | 17 | /** 18 | * 获取 Mch ID 19 | * 20 | * @return Mch ID 21 | */ 22 | public abstract String getMchID(); 23 | 24 | 25 | /** 26 | * 获取 API 密钥 27 | * 28 | * @return API密钥 29 | */ 30 | public abstract String getKey(); 31 | 32 | 33 | /** 34 | * 获取商户证书内容 35 | * 36 | * @return 商户证书内容 37 | */ 38 | public abstract InputStream getCertStream(); 39 | 40 | /** 41 | * HTTP(S) 连接超时时间,单位毫秒 42 | * 43 | * @return 44 | */ 45 | public int getHttpConnectTimeoutMs() { 46 | return 6*1000; 47 | } 48 | 49 | /** 50 | * HTTP(S) 读数据超时时间,单位毫秒 51 | * 52 | * @return 53 | */ 54 | public int getHttpReadTimeoutMs() { 55 | return 8*1000; 56 | } 57 | 58 | /** 59 | * 获取WXPayDomain, 用于多域名容灾自动切换 60 | * @return 61 | */ 62 | public abstract IWXPayDomain getWXPayDomain(); 63 | 64 | /** 65 | * 是否自动上报。 66 | * 若要关闭自动上报,子类中实现该函数返回 false 即可。 67 | * 68 | * @return 69 | */ 70 | public boolean shouldAutoReport() { 71 | return true; 72 | } 73 | 74 | /** 75 | * 进行健康上报的线程的数量 76 | * 77 | * @return 78 | */ 79 | public int getReportWorkerNum() { 80 | return 6; 81 | } 82 | 83 | 84 | /** 85 | * 健康上报缓存消息的最大数量。会有线程去独立上报 86 | * 粗略计算:加入一条消息200B,10000消息占用空间 2000 KB,约为2MB,可以接受 87 | * 88 | * @return 89 | */ 90 | public int getReportQueueMaxSize() { 91 | return 10000; 92 | } 93 | 94 | /** 95 | * 批量上报,一次最多上报多个数据 96 | * 97 | * @return 98 | */ 99 | public int getReportBatchSize() { 100 | return 10; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /flow-microservice-gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | cloud-flow 7 | cn.yccoding 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | flow-microservice-gateway 13 | 网关服务 14 | 15 | 16 | 17 | cn.yccoding 18 | flow-framework-common 19 | 20 | 26 | 27 | 28 | 29 | com.alibaba.cloud 30 | spring-cloud-alibaba-nacos-discovery 31 | 32 | 33 | 34 | com.alibaba.cloud 35 | spring-cloud-starter-alibaba-nacos-config 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-actuator 41 | 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-gateway 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/builder/AlipayTradeCancelRequestBuilder.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.builder; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import org.apache.commons.lang.StringUtils; 5 | 6 | /** 7 | * Created by liuyangkly on 16/3/3. 8 | */ 9 | public class AlipayTradeCancelRequestBuilder extends RequestBuilder { 10 | 11 | private BizContent bizContent = new BizContent(); 12 | 13 | @Override 14 | public BizContent getBizContent() { 15 | return bizContent; 16 | } 17 | 18 | @Override 19 | public boolean validate() { 20 | if (StringUtils.isEmpty(bizContent.outTradeNo)) { 21 | throw new NullPointerException("out_trade_no should not be NULL!"); 22 | } 23 | return true; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | final StringBuilder sb = new StringBuilder("AlipayTradeCancelRequestBuilder{"); 29 | sb.append("bizContent=").append(bizContent); 30 | sb.append(", super=").append(super.toString()); 31 | sb.append('}'); 32 | return sb.toString(); 33 | } 34 | 35 | @Override 36 | public AlipayTradeCancelRequestBuilder setAppAuthToken(String appAuthToken) { 37 | return (AlipayTradeCancelRequestBuilder) super.setAppAuthToken(appAuthToken); 38 | } 39 | 40 | @Override 41 | public AlipayTradeCancelRequestBuilder setNotifyUrl(String notifyUrl) { 42 | return (AlipayTradeCancelRequestBuilder) super.setNotifyUrl(notifyUrl); 43 | } 44 | 45 | public String getOutTradeNo() { 46 | return bizContent.outTradeNo; 47 | } 48 | 49 | public AlipayTradeCancelRequestBuilder setOutTradeNo(String outTradeNo) { 50 | bizContent.outTradeNo = outTradeNo; 51 | return this; 52 | } 53 | 54 | public static class BizContent { 55 | // 商户订单号,通过此商户订单号撤销当面付的交易状态 56 | @SerializedName("out_trade_no") 57 | private String outTradeNo; 58 | 59 | @Override 60 | public String toString() { 61 | final StringBuilder sb = new StringBuilder("BizContent{"); 62 | sb.append("outTradeNo='").append(outTradeNo).append('\''); 63 | sb.append('}'); 64 | return sb.toString(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/domain/entity/Member.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.domain.entity; 2 | 3 | import cn.yccoding.common.base.BaseEntity; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import com.baomidou.mybatisplus.annotation.IdType; 6 | import java.util.Date; 7 | import com.baomidou.mybatisplus.annotation.TableId; 8 | import lombok.Data; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.experimental.Accessors; 11 | 12 | /** 13 | *

14 | * 会员表 15 | *

16 | * 17 | * @author yc 18 | * @since 2020-09-03 19 | */ 20 | @Data 21 | @EqualsAndHashCode(callSuper = true) 22 | @Accessors(chain = true) 23 | @TableName("ums_member") 24 | public class Member extends BaseEntity { 25 | 26 | private static final long serialVersionUID=1L; 27 | 28 | private Long memberLevelId; 29 | 30 | /** 31 | * 用户名 32 | */ 33 | private String username; 34 | 35 | /** 36 | * 密码 37 | */ 38 | private String password; 39 | 40 | /** 41 | * 昵称 42 | */ 43 | private String nickname; 44 | 45 | /** 46 | * 手机号码 47 | */ 48 | private String phone; 49 | 50 | /** 51 | * 帐号启用状态:0->禁用;1->启用 52 | */ 53 | private Integer status; 54 | 55 | /** 56 | * 头像 57 | */ 58 | private String icon; 59 | 60 | /** 61 | * 性别:0->未知;1->男;2->女 62 | */ 63 | private Integer gender; 64 | 65 | /** 66 | * 生日 67 | */ 68 | private Date birthday; 69 | 70 | /** 71 | * 所做城市 72 | */ 73 | private String city; 74 | 75 | /** 76 | * 职业 77 | */ 78 | private String job; 79 | 80 | /** 81 | * 个性签名 82 | */ 83 | private String personalizedSignature; 84 | 85 | /** 86 | * 用户来源 87 | */ 88 | private Integer sourceType; 89 | 90 | /** 91 | * 积分 92 | */ 93 | private Integer integration; 94 | 95 | /** 96 | * 成长值 97 | */ 98 | private Integer growth; 99 | 100 | /** 101 | * 剩余抽奖次数 102 | */ 103 | private Integer luckeyCount; 104 | 105 | /** 106 | * 历史积分数量 107 | */ 108 | private Integer historyIntegration; 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.config; 2 | 3 | import cn.yccoding.payment.client.RedisOpsClient; 4 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 5 | import com.fasterxml.jackson.annotation.PropertyAccessor; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.Primary; 11 | import org.springframework.data.redis.connection.RedisConnectionFactory; 12 | import org.springframework.data.redis.core.RedisTemplate; 13 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 14 | import org.springframework.data.redis.serializer.StringRedisSerializer; 15 | 16 | /** 17 | * 配置 18 | * 19 | * @author YC 20 | * @since 2020/9/27 21 | */ 22 | @Configuration 23 | public class RedisConfig { 24 | @Autowired 25 | private RedisConnectionFactory connectionFactory; 26 | 27 | @Bean 28 | @Primary 29 | public RedisTemplate redisTemplate(){ 30 | RedisTemplate template = new RedisTemplate(); 31 | template.setConnectionFactory(connectionFactory); 32 | // 序列化后会产生java类型说明,如果不需要用“Jackson2JsonRedisSerializer”和“ObjectMapper ”配合效果更好 33 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 34 | ObjectMapper om = new ObjectMapper(); 35 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 36 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 37 | jackson2JsonRedisSerializer.setObjectMapper(om); 38 | 39 | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 40 | template.setKeySerializer(stringRedisSerializer); 41 | template.setValueSerializer(jackson2JsonRedisSerializer); 42 | 43 | template.setHashKeySerializer(jackson2JsonRedisSerializer); 44 | template.setHashValueSerializer(jackson2JsonRedisSerializer); 45 | 46 | template.afterPropertiesSet(); 47 | return template; 48 | } 49 | 50 | @Bean 51 | public RedisOpsClient redisOpsClient() { 52 | return new RedisOpsClient(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/DemoHbRunner.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk; 2 | 3 | import cn.yccoding.payment.alipay.sdk.model.builder.AlipayHeartbeatSynRequestBuilder; 4 | import cn.yccoding.payment.alipay.sdk.model.hb.*; 5 | import cn.yccoding.payment.alipay.sdk.service.AlipayMonitorService; 6 | import cn.yccoding.payment.alipay.sdk.service.impl.hb.AbsHbRunner; 7 | import cn.yccoding.payment.alipay.sdk.service.impl.hb.HbQueue; 8 | import cn.yccoding.payment.alipay.sdk.utils.Utils; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Date; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by liuyangkly on 15/10/23. 16 | 执行调度,主要任务由两个线程完成,交易线程(调用当面付2.0接口)和交易保障线程(轮询),具体需要做的事情 17 | 1.当面付程序每执行完一笔交易后将交易结果保存在临时队列 18 | 2.轮询线程读取临时队列,获取基础采集信息和最多30条trade_info信息,调用支付宝monitor.heartbeat.syn接口 19 | 示例代码仅封装了如何调用该接口api,采集数据,比如采集网络信息、交易耗时、异常信息等,需要系统商开发者自行完成。 20 | */ 21 | public class DemoHbRunner extends AbsHbRunner { 22 | 23 | public DemoHbRunner(AlipayMonitorService monitorService) { 24 | super(monitorService); 25 | } 26 | 27 | @Override 28 | public String getAppAuthToken() { 29 | // 对于系统商,如果是为了商户开发监控保障接口,则需要传此值,否则如果为系统商自己做交易保障接口开发,则可不传。 30 | return null; 31 | } 32 | 33 | @Override 34 | public AlipayHeartbeatSynRequestBuilder getBuilder() { 35 | // 系统商使用的交易信息格式,json字符串类型,从交易队列中获取 36 | List sysTradeInfoList = HbQueue.poll(); 37 | 38 | // 异常信息的采集,系统商自行完成 39 | List exceptionInfoList = new ArrayList(); 40 | // exceptionInfoList.add(ExceptionInfo.HE_SCANER); 41 | // exceptionInfoList.add(ExceptionInfo.HE_PRINTER); 42 | // exceptionInfoList.add(ExceptionInfo.HE_OTHER); 43 | 44 | AlipayHeartbeatSynRequestBuilder builder = new AlipayHeartbeatSynRequestBuilder() 45 | .setProduct(Product.FP).setType(Type.CR).setEquipmentId("cr1000001") 46 | .setEquipmentStatus(EquipStatus.NORMAL).setTime(Utils.toDate(new Date())) 47 | .setStoreId("store10001").setMac("0a:00:27:00:00:00").setNetworkType("LAN") 48 | .setProviderId("2088911212323549") // 设置系统商pid 49 | .setSysTradeInfoList(sysTradeInfoList) // 系统商同步trade_info信息 50 | .setExceptionInfoList(exceptionInfoList) // 填写异常信息,如果有的话 51 | ; 52 | return builder; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /flow-framework-common/src/main/java/cn/yccoding/common/util/XmlConvertUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.common.util; 2 | 3 | //import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler; 4 | 5 | import javax.xml.bind.JAXBContext; 6 | import javax.xml.bind.JAXBException; 7 | import javax.xml.bind.Marshaller; 8 | import javax.xml.bind.Unmarshaller; 9 | import java.io.StringReader; 10 | import java.io.StringWriter; 11 | 12 | /** 13 | * @Author YC 14 | * @create 2020/2/3 xml工具类 15 | */ 16 | public class XmlConvertUtils { 17 | 18 | /** 19 | * transfer xml to bean 20 | * 21 | * @param xml 22 | * 待转化的xml字符串 23 | * @param c 24 | * 转化后的类 25 | * @param 26 | * 转化后类类型 27 | * @return 转化后的类对象 28 | */ 29 | @SuppressWarnings("unchecked") 30 | public static T xmlToBean(String xml, Class c) { 31 | T t = null; 32 | try { 33 | JAXBContext context = JAXBContext.newInstance(c); 34 | Unmarshaller unmarshaller = context.createUnmarshaller(); 35 | t = (T)unmarshaller.unmarshal(new StringReader(xml)); 36 | } catch (JAXBException e) { 37 | e.printStackTrace(); 38 | } 39 | return t; 40 | } 41 | 42 | /** 43 | * transfer bean to xml 44 | * 45 | * @param obj 46 | * 待转化类对象 47 | * @param clazz 48 | * 待转化类 49 | * @return 转化后的xml字符串 50 | * @throws JAXBException 51 | */ 52 | public static String beanToXml(Object obj, java.lang.Class clazz) throws JAXBException { 53 | String result = null; 54 | try { 55 | JAXBContext context = JAXBContext.newInstance(clazz); 56 | Marshaller marshaller = context.createMarshaller(); 57 | marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 58 | marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8"); 59 | // 不转义,根据需要添加 60 | /*marshaller.setProperty(CharacterEscapeHandler.class.getName(), 61 | (CharacterEscapeHandler)(chars, start, length, isAttVal, writer) -> writer.write(chars, start, length));*/ 62 | StringWriter writer = new StringWriter(); 63 | marshaller.marshal(obj, writer); 64 | result = writer.toString(); 65 | } catch (JAXBException e) { 66 | e.printStackTrace(); 67 | System.out.println("JAXBException happened."); 68 | } 69 | return result; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /flow-microservice-gateway/src/main/java/cn/yccoding/gateway/filter/AuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.gateway.filter; 2 | 3 | import cn.yccoding.common.base.ResultCodeEnum; 4 | import cn.yccoding.common.exception.CustomException; 5 | import cn.yccoding.gateway.common.TokenInfo; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.InitializingBean; 8 | import org.springframework.cloud.gateway.filter.GatewayFilterChain; 9 | import org.springframework.cloud.gateway.filter.GlobalFilter; 10 | import org.springframework.core.Ordered; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.web.server.ServerWebExchange; 13 | import reactor.core.publisher.Mono; 14 | 15 | import java.util.Arrays; 16 | import java.util.LinkedHashSet; 17 | import java.util.Set; 18 | 19 | /** 20 | * 鉴权过滤器 21 | * 22 | * @author YC 23 | * @since 2020/9/25 24 | */ 25 | //@Component 26 | @Slf4j 27 | public class AuthenticationFilter implements GlobalFilter, Ordered, InitializingBean { 28 | /** 29 | * 请求各个微服务 不需要用户认证的URL 30 | */ 31 | private static Set shouldSkipUrl = new LinkedHashSet<>(); 32 | 33 | @Override 34 | public void afterPropertiesSet() throws Exception { 35 | // TODO 从数据库读取 36 | shouldSkipUrl.add("/producer"); 37 | // 去认证的请求,本来就不需要拦截 38 | shouldSkipUrl.add("/oauth/token"); 39 | } 40 | 41 | @Override 42 | public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { 43 | String reqPath = exchange.getRequest().getURI().getPath(); 44 | TokenInfo tokenInfo = (TokenInfo) exchange.getAttribute("tokenInfo"); 45 | 46 | // 无需拦截的路径 47 | boolean approveFlag = shouldSkipUrl.stream().anyMatch(reqPath::contains); 48 | if (approveFlag) { 49 | return chain.filter(exchange); 50 | } 51 | 52 | // token过期 53 | if (!tokenInfo.isActive()) { 54 | log.warn("token已过期"); 55 | throw new CustomException(ResultCodeEnum.TOKEN_EXPIRED); 56 | } 57 | 58 | // 鉴权 59 | String[] authorities = tokenInfo.getAuthorities(); 60 | boolean permissionFlag = Arrays.stream(authorities).anyMatch(reqPath::contains); 61 | if (!permissionFlag) { 62 | log.warn("权限不足"); 63 | throw new CustomException(ResultCodeEnum.ACCESS_FORBIDEN); 64 | } 65 | return chain.filter(exchange); 66 | } 67 | 68 | @Override 69 | public int getOrder() { 70 | return 1; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /flow-microservice-order/src/main/java/cn/yccoding/order/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.order.controller; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import cn.yccoding.order.feignapi.AliPayFeignApi; 5 | import cn.yccoding.order.model.TradePaySummary; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.util.StringUtils; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.lang.reflect.Array; 15 | import java.time.LocalDate; 16 | import java.time.LocalDateTime; 17 | import java.util.Arrays; 18 | import java.util.Enumeration; 19 | import java.util.HashMap; 20 | 21 | /** 22 | * 订单 23 | * 24 | * @author YC 25 | * @since 2020/9/26 26 | */ 27 | @Slf4j 28 | @RestController 29 | @RequestMapping("/order") 30 | public class OrderController { 31 | 32 | @Autowired 33 | private AliPayFeignApi aliPayFeignApi; 34 | 35 | /** 36 | * 测试方法 37 | * @param id 38 | * @return 39 | */ 40 | @GetMapping("/{id}") 41 | public ResponseEntity getOrderById(@PathVariable String id) { 42 | log.info("获取订单id=->{}", id); 43 | HashMap map = new HashMap<>(); 44 | map.put("id", id); 45 | map.put("price", "100"); 46 | map.put("date", LocalDateTime.now().toString()); 47 | return R.ok().message("订单详情").data("item",map).buildResponseEntity(); 48 | } 49 | 50 | /** 51 | * 支付宝支付 52 | * @return 53 | */ 54 | @PostMapping("/ali-pay") 55 | public ResponseEntity doOrder() { 56 | log.info("测试支付宝支付..."); 57 | TradePaySummary summary = new TradePaySummary(); 58 | summary.setSubject("测试支付宝当面付"); 59 | summary.setOperatorId("yc"); 60 | summary.setStoreId("yc"); 61 | TradePaySummary.Item item = new TradePaySummary.Item(); 62 | item.setGoodsId("1001"); 63 | item.setGoodsName("测试商品"); 64 | item.setPrice("1"); 65 | item.setQuantity(1); 66 | summary.setItems(Arrays.asList(item)); 67 | String qrcode = aliPayFeignApi.f2fPayTradePay(summary); 68 | if (StringUtils.isEmpty(qrcode)) { 69 | return R.error().message("网络繁忙").buildResponseEntity(); 70 | } 71 | // TODO 保存订单,更新状态 72 | return R.ok().message("测试成功").data("qrcode",qrcode).buildResponseEntity(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/controller/SsoController.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.controller; 2 | 3 | import cn.yccoding.common.vo.R; 4 | import cn.yccoding.member.config.JwtKit; 5 | import cn.yccoding.member.config.property.JwtProperties; 6 | import cn.yccoding.member.domain.entity.Member; 7 | import cn.yccoding.member.object.RegisterQo; 8 | import cn.yccoding.member.service.SsoService; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.http.ResponseEntity; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import javax.validation.Valid; 15 | import java.util.HashMap; 16 | 17 | /** 18 | * 会员登录控制器 19 | * 20 | * @author YC 21 | * @since 2020/9/3 22 | */ 23 | @Slf4j 24 | @RestController 25 | @RequestMapping("/sso") 26 | public class SsoController extends BaseController { 27 | @Autowired 28 | private SsoService ssoService; 29 | 30 | @Autowired 31 | private JwtKit jwtKit; 32 | 33 | @Autowired 34 | private JwtProperties jwtProperties; 35 | 36 | /** 37 | * 获取手机验证码 38 | * @param phone 39 | * @return 40 | */ 41 | @GetMapping("/optCode") 42 | public ResponseEntity getOptCode(@RequestParam String phone) { 43 | String optCode = ssoService.getOtpCode(phone); 44 | return R.ok().data("optCode", optCode).buildResponseEntity(); 45 | } 46 | 47 | /** 48 | * 获取注册信息 49 | * @param registerQo 50 | * @return 51 | */ 52 | @PostMapping("/register") 53 | public ResponseEntity register(@Valid @RequestBody RegisterQo registerQo) { 54 | ssoService.register(registerQo); 55 | return R.ok().message("注册成功").buildResponseEntity(); 56 | } 57 | 58 | //@GetMapping("/login") 59 | public ResponseEntity sessionLogin(String username, String password) { 60 | Member member = ssoService.login(username, password); 61 | // 登录记录session 62 | getHttpSession().setAttribute("member", member); 63 | // TODO 返回member的vo类 64 | return R.ok().message("登录成功").data("username", member.getUsername()).buildResponseEntity(); 65 | } 66 | 67 | @GetMapping("/login") 68 | public ResponseEntity jwtLogin(String username, String password) { 69 | Member member = ssoService.login(username, password); 70 | // 返回jwt 71 | HashMap map = new HashMap<>(2); 72 | map.put("token", jwtKit.generate(member)); 73 | map.put("header", jwtProperties.getPrefix()); 74 | return R.ok().message("登录成功").data("jwt", map).buildResponseEntity(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/JwtKit.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config; 2 | 3 | import cn.yccoding.common.base.ResultCodeEnum; 4 | import cn.yccoding.common.exception.CustomException; 5 | import cn.yccoding.member.config.property.JwtProperties; 6 | import cn.yccoding.member.domain.entity.Member; 7 | import io.jsonwebtoken.*; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | 10 | import java.time.LocalDateTime; 11 | import java.util.Date; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | /** 16 | * jwt工具类 17 | * 18 | * @author YC 19 | * @since 2020/9/5 20 | */ 21 | public class JwtKit { 22 | 23 | @Autowired 24 | private JwtProperties jwtProperties; 25 | 26 | 27 | /** 28 | * 生成jwt token 29 | * 30 | * iss (issuer):签发人 31 | * exp (expiration time):过期时间 32 | * sub (subject):主题 33 | * aud (audience):受众 34 | * nbf (Not Before):生效时间 35 | * iat (Issued At):签发时间 36 | * jti (JWT ID):编号 37 | * @return 38 | */ 39 | public String generate(Member member) { 40 | Map claims = new HashMap<>(4); 41 | // payload消息题 42 | claims.put("sub", member.getUsername()); 43 | claims.put("iat", LocalDateTime.now()); 44 | claims.put("id", member.getId()); 45 | claims.put("memberLevelId", member.getMemberLevelId()); 46 | return Jwts.builder() 47 | .setClaims(claims) 48 | .setExpiration(new Date(System.currentTimeMillis() + jwtProperties.getExpire() * 1000)) 49 | .signWith(SignatureAlgorithm.HS256, jwtProperties.getSecret()) 50 | .compact(); 51 | } 52 | 53 | /** 54 | * 解析jwt token 55 | * 56 | * @return 57 | */ 58 | public Claims parse(String token) { 59 | Claims claims = null; 60 | try { 61 | claims = Jwts.parser() 62 | .setSigningKey(jwtProperties.getSecret()) 63 | .parseClaimsJws(token) 64 | .getBody(); 65 | } catch (ExpiredJwtException e) { 66 | throw new CustomException(ResultCodeEnum.JWT_EXPIRED); 67 | } catch (UnsupportedJwtException e) { 68 | throw new CustomException(ResultCodeEnum.JWT_UNSUPPORTED); 69 | } catch (MalformedJwtException e) { 70 | throw new CustomException(ResultCodeEnum.JWT_MALFORMED); 71 | } catch (SignatureException e) { 72 | throw new CustomException(ResultCodeEnum.JWT_SIGNATURE); 73 | } catch (IllegalArgumentException e) { 74 | throw new CustomException(ResultCodeEnum.JWT_ILLEGAL_ARGUMENT); 75 | } 76 | return claims; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/service/WXPayTradeService.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.service; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 支付服务 7 | * 8 | * @author YC 9 | * @since 2020/9/27 10 | */ 11 | public interface WXPayTradeService { 12 | 13 | /** 14 | * 统一下单接口,输入指定参数,只关心必要参数 15 | * 16 | * @param openid 用户在公众号的唯一识别号 17 | * @param tradeType 交易类型 18 | * @param price 价格 19 | * @param productDesc 商品描述 20 | * @param terminalIP 终端ip 21 | * @param requestUrl 请求来源的url 22 | * @return 返回js校验参数的的map 23 | */ 24 | Map unifiedorder(String openid, String tradeType, String price, String productDesc, 25 | String terminalIP, String requestUrl); 26 | 27 | /** 28 | * 订单查询 29 | * 30 | * @param outTradeNo 31 | * @return 32 | */ 33 | Map orderQuery(String outTradeNo); 34 | 35 | /** 36 | * 关闭订单 37 | * 38 | * @param outTradeNo 39 | * @return 40 | */ 41 | Map closeOrder(String outTradeNo); 42 | 43 | /** 44 | * 申请退款 45 | * 46 | * @param outTradeNo 47 | * @param outRefundNo 48 | * @param totalFee 49 | * @param refundFee 50 | * @return 51 | */ 52 | Map refund(String outTradeNo, String outRefundNo, String totalFee, String refundFee); 53 | 54 | /** 55 | * 退款查询 56 | * 57 | * @param outTradeNo 58 | * @return 59 | */ 60 | Map refundQuery(String outTradeNo); 61 | 62 | /** 63 | * 下载交易账单 64 | * 65 | * @param billDate 66 | * @param billType 67 | * @return 68 | */ 69 | Map downloadBill(String billDate, String billType); 70 | 71 | /** 72 | * 下载资金账单 73 | * @param billDate 74 | * @param accountType 75 | * @return 76 | */ 77 | Map downloadFundFlow(String billDate, String accountType); 78 | 79 | /** 80 | * 交易保障 81 | * 82 | * @param interfaceUrl 83 | * @param executeTime 84 | * @param returnCode 85 | * @param returnMsg 86 | * @param resultCode 87 | * @param userIp 88 | * @return 89 | */ 90 | Map report(String interfaceUrl, String executeTime, String returnCode, 91 | String returnMsg, String resultCode, String userIp); 92 | 93 | /** 94 | * 拉取订单评价数据 95 | * 96 | * @param beginTime 97 | * @param endTime 98 | * @param offset 99 | * @return 100 | */ 101 | Map batchQueryComment(String beginTime, String endTime, String offset); 102 | } 103 | -------------------------------------------------------------------------------- /flow-microservice-member/src/main/java/cn/yccoding/member/config/interceptor/AuthHandlerInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.member.config.interceptor; 2 | 3 | import cn.yccoding.common.base.ResultCodeEnum; 4 | import cn.yccoding.common.vo.R; 5 | import cn.yccoding.member.config.JwtKit; 6 | import cn.yccoding.member.config.property.JwtProperties; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import io.jsonwebtoken.Claims; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.util.ObjectUtils; 12 | import org.springframework.util.StringUtils; 13 | import org.springframework.web.servlet.HandlerInterceptor; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | 18 | /** 19 | * 认证处理拦截器 20 | * 21 | * @author YC 22 | * @since 2020/9/4 23 | */ 24 | @Slf4j 25 | public class AuthHandlerInterceptor implements HandlerInterceptor { 26 | @Autowired 27 | private JwtProperties jwtProperties; 28 | 29 | @Autowired 30 | private JwtKit jwtKit; 31 | 32 | public final static String GLOBAL_JWT_MEMBER_INFO="jwt:member:info"; 33 | 34 | @Override 35 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 36 | log.info("进入前置拦截器..."); 37 | String authorization = request.getHeader(jwtProperties.getHeader()); 38 | // 1.校验token 39 | if (StringUtils.isEmpty(authorization)||!authorization.startsWith(jwtProperties.getPrefix())) { 40 | printUnauthorized(response); 41 | return false; 42 | } 43 | // 2. 去除Bearer前缀 44 | String token = authorization.substring(jwtProperties.getPrefix().length()); 45 | // 3. 解析 46 | Claims claims = jwtKit.parse(token); 47 | if (claims == null) { 48 | printUnauthorized(response); 49 | return false; 50 | } 51 | request.setAttribute(GLOBAL_JWT_MEMBER_INFO,claims); 52 | 53 | // session校验 54 | /*if (ObjectUtils.isEmpty(request.getSession().getAttribute("member"))) { 55 | printUnauthorized(response); 56 | return false; 57 | }*/ 58 | return true; 59 | } 60 | 61 | /** 62 | * 该部分没有进入到mvc,无法使用自定义异常,需要从response返回 63 | * 64 | * @param response 65 | * @throws Exception 66 | */ 67 | protected void printUnauthorized(HttpServletResponse response) throws Exception { 68 | response.setHeader("Content-Type", "application/json"); 69 | response.setCharacterEncoding("UTF-8"); 70 | response.setStatus(401); 71 | String result = new ObjectMapper().writeValueAsString(R.setResult(ResultCodeEnum.UNAUTHORIZED)); 72 | response.getWriter().print(result); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /flow-framework-demo/src/main/java/cn/yccoding/demo/designpattern/create/builder/builder2/Champ.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.demo.designpattern.create.builder.builder2; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | /** 9 | * 英雄 10 | * 11 | * @author YC 12 | * @since 2020/12/2 13 | */ 14 | @Data 15 | public class Champ { 16 | 17 | /** 18 | * 昵称 19 | */ 20 | private String nickname; 21 | 22 | /** 23 | * 召唤师技能 24 | */ 25 | private List sums; 26 | 27 | /** 28 | * 被动技能 29 | */ 30 | private String passive; 31 | 32 | /** 33 | * 角色 34 | */ 35 | private int roleId = 0; 36 | 37 | private Champ(String nickname, List sums, String passive, int roleId) { 38 | this.nickname = nickname; 39 | this.sums = sums; 40 | this.passive = passive; 41 | this.roleId = roleId; 42 | } 43 | 44 | /** 45 | * 私有构造器,只能通过建造者创建 46 | */ 47 | private Champ() { 48 | } 49 | 50 | public static ChampBuilder builder() { 51 | return new ChampBuilder(); 52 | } 53 | 54 | /** 55 | * 建造者 56 | */ 57 | public static class ChampBuilder { 58 | 59 | private String nickname; 60 | private List sums; 61 | private String passive; 62 | private int roleId = 0; 63 | 64 | public ChampBuilder nickname(String nickname) { 65 | this.nickname = nickname; 66 | return this; 67 | } 68 | 69 | public ChampBuilder setSums(String... sums) { 70 | this.sums = Arrays.asList(sums); 71 | return this; 72 | } 73 | 74 | public ChampBuilder setPassive(String passive) { 75 | this.passive = passive; 76 | return this; 77 | } 78 | 79 | public ChampBuilder setRoleId(int roleId) { 80 | this.roleId = roleId; 81 | return this; 82 | } 83 | 84 | /** 85 | * 创建 86 | */ 87 | public Champ build() { 88 | // TODO 校验参数... 89 | if (nickname == null || "".equalsIgnoreCase(nickname)) { 90 | throw new RuntimeException("名称不可以为空"); 91 | } 92 | // 构造实例 93 | Champ champ = new Champ(); 94 | champ.setNickname(nickname); 95 | if (sums != null && sums.isEmpty()) { 96 | champ.setSums(sums); 97 | } 98 | if (passive != null && "".equalsIgnoreCase(passive)) { 99 | champ.setPassive(passive); 100 | } 101 | if (roleId > 0) { 102 | champ.setRoleId(roleId); 103 | } 104 | return champ; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/model/builder/AlipayTradeQueryRequestBuilder.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.model.builder; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import org.apache.commons.lang.StringUtils; 5 | 6 | /** 7 | * Created by liuyangkly on 16/3/3. 8 | */ 9 | public class AlipayTradeQueryRequestBuilder extends RequestBuilder { 10 | 11 | private BizContent bizContent = new BizContent(); 12 | 13 | @Override 14 | public BizContent getBizContent() { 15 | return bizContent; 16 | } 17 | 18 | @Override 19 | public boolean validate() { 20 | if (StringUtils.isEmpty(bizContent.tradeNo) && 21 | StringUtils.isEmpty(bizContent.outTradeNo)) { 22 | throw new IllegalStateException("tradeNo and outTradeNo can not both be NULL!"); 23 | } 24 | return true; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | final StringBuilder sb = new StringBuilder("AlipayTradeQueryRequestBuilder{"); 30 | sb.append("bizContent=").append(bizContent); 31 | sb.append(", super=").append(super.toString()); 32 | sb.append('}'); 33 | return sb.toString(); 34 | } 35 | 36 | @Override 37 | public AlipayTradeQueryRequestBuilder setAppAuthToken(String appAuthToken) { 38 | return (AlipayTradeQueryRequestBuilder) super.setAppAuthToken(appAuthToken); 39 | } 40 | 41 | @Override 42 | public AlipayTradeQueryRequestBuilder setNotifyUrl(String notifyUrl) { 43 | return (AlipayTradeQueryRequestBuilder) super.setNotifyUrl(notifyUrl); 44 | } 45 | 46 | public String getTradeNo() { 47 | return bizContent.tradeNo; 48 | } 49 | 50 | public AlipayTradeQueryRequestBuilder setTradeNo(String tradeNo) { 51 | bizContent.tradeNo = tradeNo; 52 | return this; 53 | } 54 | 55 | public String getOutTradeNo() { 56 | return bizContent.outTradeNo; 57 | } 58 | 59 | public AlipayTradeQueryRequestBuilder setOutTradeNo(String outTradeNo) { 60 | bizContent.outTradeNo = outTradeNo; 61 | return this; 62 | } 63 | 64 | public static class BizContent { 65 | // 支付宝交易号,和商户订单号不能同时为空, 如果同时存在则通过tradeNo查询支付宝交易 66 | @SerializedName("trade_no") 67 | private String tradeNo; 68 | 69 | // 商户订单号,通过此商户订单号查询当面付的交易状态 70 | @SerializedName("out_trade_no") 71 | private String outTradeNo; 72 | 73 | @Override 74 | public String toString() { 75 | final StringBuilder sb = new StringBuilder("BizContent{"); 76 | sb.append("tradeNo='").append(tradeNo).append('\''); 77 | sb.append(", outTradeNo='").append(outTradeNo).append('\''); 78 | sb.append('}'); 79 | return sb.toString(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/alipay/sdk/utils/ZxingUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.alipay.sdk.utils; 2 | 3 | import com.google.zxing.BarcodeFormat; 4 | import com.google.zxing.EncodeHintType; 5 | import com.google.zxing.MultiFormatWriter; 6 | import com.google.zxing.common.BitMatrix; 7 | import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 8 | import org.apache.commons.logging.Log; 9 | import org.apache.commons.logging.LogFactory; 10 | 11 | import javax.imageio.ImageIO; 12 | import java.awt.image.BufferedImage; 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.util.Hashtable; 16 | import java.util.Map; 17 | 18 | /** 19 | * Created by liuyangkly on 15/6/27. 20 | * 使用了google zxing作为二维码生成工具 21 | */ 22 | public class ZxingUtils { 23 | private static Log log = LogFactory.getLog(ZxingUtils.class); 24 | 25 | private static final int BLACK = 0xFF000000; 26 | private static final int WHITE = 0xFFFFFFFF; 27 | 28 | private static BufferedImage toBufferedImage(BitMatrix matrix) { 29 | int width = matrix.getWidth(); 30 | int height = matrix.getHeight(); 31 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 32 | for (int x = 0; x < width; x++) { 33 | for (int y = 0; y < height; y++) { 34 | image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); 35 | } 36 | } 37 | return image; 38 | } 39 | 40 | private static void writeToFile(BitMatrix matrix, String format, File file) throws IOException { 41 | BufferedImage image = toBufferedImage(matrix); 42 | if (!ImageIO.write(image, format, file)) { 43 | throw new IOException("Could not write an image of format " + format + " to " + file); 44 | } 45 | } 46 | 47 | /** 将内容contents生成长宽均为width的图片,图片路径由imgPath指定 48 | */ 49 | public static File getQRCodeImge(String contents, int width, String imgPath) { 50 | return getQRCodeImge(contents, width, width, imgPath); 51 | } 52 | 53 | /** 将内容contents生成长为width,宽为width的图片,图片路径由imgPath指定 54 | */ 55 | public static File getQRCodeImge(String contents, int width, int height, String imgPath) { 56 | try { 57 | Map hints = new Hashtable(); 58 | hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); 59 | hints.put(EncodeHintType.CHARACTER_SET, "UTF8"); 60 | 61 | BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); 62 | 63 | File imageFile = new File(imgPath); 64 | writeToFile(bitMatrix, "png", imageFile); 65 | 66 | return imageFile; 67 | 68 | } catch (Exception e) { 69 | log.error("create QR code error!", e); 70 | return null; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /flow-microservice-payment/src/main/java/cn/yccoding/payment/wxpay/util/SignatureUtils.java: -------------------------------------------------------------------------------- 1 | package cn.yccoding.payment.wxpay.util; 2 | 3 | import cn.yccoding.common.util.SecurityUtils; 4 | import cn.yccoding.payment.wxpay.sdk.WXPayConstants; 5 | import cn.yccoding.payment.wxpay.sdk.WXPayUtil; 6 | 7 | import java.security.MessageDigest; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Set; 11 | import java.util.TreeMap; 12 | 13 | /** 14 | * 微信内H5调起支付 15 | * 16 | * @author YC 17 | * @since 2020/9/27 18 | */ 19 | public class SignatureUtils { 20 | 21 | /** 22 | * 网页端接口请求参数列表(参数需要重新进行签名计算,参与签名的参数为:appId、timeStamp、nonceStr、package、signType,参数区分大小写。) 23 | * @param appId 24 | * @param nonceStr 25 | * @param url 26 | * @param prepayId 27 | * @param key 28 | * @param jsapiTicket 29 | * @return 30 | * @throws Exception 31 | */ 32 | public static Map permissionValidate(String appId, String nonceStr, String url, String prepayId, 33 | String key, String jsapiTicket) throws Exception { 34 | Map data = new HashMap<>(); 35 | 36 | // 传入js中getBrandWCPayRequest的参数 37 | TreeMap param = new TreeMap<>(); 38 | param.put("appId", appId); 39 | String timestamp = String.valueOf(WXPayUtil.getCurrentTimestamp()); 40 | param.put("timestamp", timestamp); 41 | param.put("nonceStr", nonceStr); 42 | param.put("signature", createSignature(timestamp, nonceStr, url, jsapiTicket)); 43 | data.put("configMap", param); 44 | 45 | // 重新进行签名计算 46 | Map payMap = new HashMap<>(); 47 | payMap.put("appId", appId); 48 | payMap.put("timeStamp", timestamp); 49 | payMap.put("nonceStr", nonceStr); 50 | payMap.put("package", "prepay_id=" + prepayId); 51 | payMap.put("signType", WXPayConstants.MD5); 52 | payMap.put("paySign", WXPayUtil.generateSignature(payMap, key)); 53 | data.put("payMap", payMap); 54 | 55 | return data; 56 | } 57 | 58 | public static String createSignature(String timestamp, String nonceStr, String url, String jsapiTicket) { 59 | // 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序) 60 | Map map = new TreeMap<>(); 61 | map.put("jsapi_ticket", jsapiTicket); 62 | map.put("timestamp", timestamp); 63 | map.put("noncestr", nonceStr); 64 | map.put("url", url); 65 | // 使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1 66 | StringBuilder sb = new StringBuilder(); 67 | Set set = map.keySet(); 68 | for (String key : set) { 69 | sb.append(key + "=" + map.get(key)).append("&"); 70 | } 71 | // 去掉最后一个&符号 72 | String temp = sb.substring(0, sb.length() - 1); 73 | // 使用sha1加密 74 | return SecurityUtils.SHA1(temp); 75 | } 76 | } 77 | --------------------------------------------------------------------------------