This commit is contained in:
六如
2024-11-04 21:46:18 +08:00
parent f72fd07ea4
commit 5956af3564
201 changed files with 84 additions and 8702 deletions

199
README.md
View File

@@ -1,144 +1,113 @@
# SOP(Simple Open Platform)
一个开放平台解决方案项目基于Spring Cloud实现目标让用户快速搭建自己的开放平台。
一个开放平台解决方案项目基于dubbo实现目标让用户快速搭建自己的开放平台。
通过简单的配置后,你的项目就具备了和支付宝开放平台的一样的接口提供能力。
SOP封装了开放平台大部分功能包括签名验证、统一异常处理、统一返回内容 、业务参数验证JSR-303、秘钥管理等未来还会实现更多功能。
## 项目特点
- 接入方式简单,与老项目不冲突,老项目注册到注册中心,然后在方法上加上注解即可。
- 架构松耦合业务代码实现在各自微服务上SOP不参与业务实现这也是Spring Cloud微服务体系带来的好处
- 扩展简单,开放平台对应的功能各自独立,可以自定义实现自己的需求,如:更改参数,更改签名规则等
## 项目特点
+ 接入方式简单,与老项目不冲突,老项目注册到注册中心,然后在方法上加上注解即可。
+ 架构松耦合业务代码实现在各自微服务上SOP不参与业务实现这也是dubbo微服务体系带来的好处
+ 扩展简单,开放平台对应的功能各自独立,可以自定义实现自己的需求,如:更改参数,更改签名规则等。
## 谁可以使用这个项目
- 有现成的项目,想改造成开放平台供他人调用
- 有现成的项目,想暴露其中几个接口并通过开放平台供他人调用
- 想搭一个开放平台新项目,并结合微服务的方式去维护
- 对开放平台感兴趣的朋友
+ 有现成的项目,想改造成开放平台供他人调用
+ 有现成的项目,想暴露其中几个接口并通过开放平台供他人调用
+ 想搭一个开放平台新项目,并结合微服务的方式去维护
+ 对开放平台感兴趣的朋友
以上情况都可以考虑使用SOP
## 例子
开放接口定义
```java
// 加一个注解即可
@Open("story.get")
@RequestMapping("/get")
public StoryResult get() {
StoryResult result = new StoryResult();
result.setId(1L);
result.setName("海底小纵队");
return result;
/**
* 支付接口
*
* @author 六如
*/
@Api("支付接口")
public interface OpenPayment {
@ApiOperation(
value = "alipay.trade.wap.pay(手机网站支付接口2.0)",
notes = "该接口是页面跳转接口,用于生成用户访问支付宝的跳转链接。" +
"请在服务端执行支付宝SDK中pageExecute方法读取响应中的body()结果。" +
"该结果用于跳转到支付宝页面,返回到用户浏览器渲染或重定向跳转到支付宝页面。" +
"具体使用方法请参考 <a href=\"https://torna.cn\" target=\"_blank\">接入指南</a>"
)
@Open(value = "alipay.trade.wap.pay", version = "2.0")
AlipayTradeWapPayResponse tradeWapPay(AlipayTradeWapPayRequest request);
}
```
接口实现
```java
/**
* 开放接口实现
*
* @author 六如
*/
@DubboService(validation = "true")
public class OpenPaymentImpl implements OpenPayment {
@Override
public AlipayTradeWapPayResponse tradeWapPay(AlipayTradeWapPayRequest request) {
AlipayTradeWapPayResponse alipayTradeWapPayResponse = new AlipayTradeWapPayResponse();
alipayTradeWapPayResponse.setPageRedirectionData(UUID.randomUUID().toString());
return alipayTradeWapPayResponse;
}
}
```
调用:
```java
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
params.put("method", "story.get");
params.put("format", "json");
params.put("charset", "utf-8");
params.put("sign_type", "RSA2");
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("version", "1.0");
@Test
public void testGet() throws Exception {
// 业务参数
Map<String, String> bizContent = new HashMap<>();
bizContent.put("id", "1");
bizContent.put("name", "葫芦娃");
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
params.put("method", "alipay.trade.wap.pay");
params.put("format", "json");
params.put("charset", "utf-8");
params.put("sign_type", "RSA2");
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("version", "2.0");
params.put("biz_content", JSON.toJSONString(bizContent));
// 业务参数
Map<String, Object> bizContent = new HashMap<>();
bizContent.put("out_trade_no", "70501111111S001111119");
bizContent.put("total_amount", "9.00");
bizContent.put("subject", "衣服");
bizContent.put("product_code", "QUICK_WAP_WAY");
System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey);
String content = AlipaySignature.getSignContent(params);
System.out.println("待签名内容:" + content);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
System.out.println("签名(sign)" + sign);
params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
params.put("sign", sign);
System.out.println("URL参数:" + buildUrlQuery(params));
System.out.println("----------- 请求信息 -----------");
System.out.println("请求参数:" + buildParamQuery(params));
System.out.println("商户秘钥:" + privateKey);
System.out.println("待签名内容:" + content);
System.out.println("签名(sign)" + sign);
System.out.println("URL参数" + buildUrlQuery(params));
System.out.println("----------- 返回结果 -----------");
String responseData = get(url, params);// 发送请求
System.out.println(responseData);
System.out.println("----------- 返回结果 -----------");
String responseData = postJson(url, params);// 发送请求
System.out.println(responseData);
}
```
## 架构
## 整体架构
![整体架构](./asset/arc.jpg)
![架构图](https://images.gitee.com/uploads/images/2019/1227/145216_c9b45109_332975.png "sop3.png")
> 如上图所示,整个系统运行后,开发者只需关注微服务中的业务代码,接口变更后重新部署微服务应用即可
## 已完成列表
- 签名验证
- 统一异常处理
- 统一返回内容
- session管理
- 秘钥管理
- 微服务端自动验证JSR-303
- Admin管理平台统一管理微服务配置管理路由管理微服务上下线
- 门户网站,提供用户注册账号
- 接入方管理+秘钥管理
- 接口权限分配
- 文件上传/下载
- 提供基础SDKJava,C++,C#,Python,Go,Rust,Nodejs
- 接口限流
- 文档整合
- 应用授权
- 监控日志
- 注册中心支持nacos/eureka
- 网关动态修改参数
- 预发布/灰度环境切换
## 界面预览
![服务列表](https://images.gitee.com/uploads/images/2020/1016/134354_c1915902_332975.png "service.png")
![路由管理](https://images.gitee.com/uploads/images/2020/1016/134039_bed1608d_332975.png "route.png")
![限流管理](https://images.gitee.com/uploads/images/2020/1016/134102_f2dcfb25_332975.png "limit.png")
![秘钥信息](https://images.gitee.com/uploads/images/2019/0711/174921_bd817533_332975.png "秘钥信息")
- 门户网站
![首页2](https://images.gitee.com/uploads/images/2021/0318/195935_1d610da8_332975.png "portal-vue.png")
![文档页](https://images.gitee.com/uploads/images/2020/1107/104342_d44849a9_332975.png "portal1.png")
## 工程说明
> 运行环境JDK8Maven3[Nacos](https://nacos.io/zh-cn/docs/what-is-nacos.html)Mysql
- doc开发文档
- sop-common公共模块封装常用功能包含签名校验、错误处理、限流等功能
- sop-gateway网关统一访问入口`Spring Cloud Zuul``Spring Cloud Gateway`实现
- sop-example微服务示例含springboot,springmvc示例
- sop-website开放平台对应网站提供文档API、沙箱测试等内容
- sop-auth应用授权服务示例
- sop-admin后台管理
- sop-sdk基础sdk含Java、C#版本
- sop-test接口调用测试用例
## 分支说明
- master发版分支
- develop日常开发分支
- eureka使用eureka注册中心
- pr接受PR的分支提交PR请提交到此分支
[更新说明](./changelog.md)
## 相关文档
[开发文档](http://durcframework.gitee.io/sop)