911 Commits

Author SHA1 Message Date
六如
6e356abf1e 优化签名验证算法 2025-11-12 09:22:18 +08:00
六如
7599c51f80 UPDATE 2025-11-06 11:30:00 +08:00
六如
c2f3afdffa 添加SDK示例,返回List 2025-11-05 09:30:34 +08:00
六如
922b00c027 添加SDK示例,返回List 2025-11-05 09:30:01 +08:00
六如
e68ff2dcfd UPDATE 2025-11-03 10:29:41 +08:00
六如
b9c58b328b 回调管理 2025-11-03 09:27:06 +08:00
六如
5001809fef 回调管理 2025-11-03 07:56:35 +08:00
六如
9d8a04b702 UPDATE 2025-10-20 16:54:34 +08:00
六如
6310d895cb UPDATE 2025-10-20 16:53:29 +08:00
六如
e0f64e43c5 UPDATE 2025-09-17 13:08:24 +08:00
六如
5a042175be 修复推送文档报找不到@Open注解问题 2025-09-12 19:37:13 +08:00
六如
51dd0faced 修复推送文档报找不到@Open注解问题 2025-09-12 19:35:45 +08:00
六如
77c92c646e smart-doc升级到3.1.1 2025-08-29 10:45:55 +08:00
六如
f5d0c9d4b4 smart-doc升级到3.1.1 2025-08-29 10:36:39 +08:00
Lin
6d1430c8ad !22 build: upgrade smart-doc to 3.1.1
* build: upgrade smart-doc to 3.1.1
2025-08-29 02:30:48 +00:00
六如
5fa5e76f61 admin后台可关联商户;fastmybatis升级到3.1.7 2025-08-18 14:05:17 +08:00
六如
fd4ff7c98d admin后台可关联商户;fastmybatis升级到3.1.7 2025-08-18 13:38:44 +08:00
六如
0588006cd1 admin后台可关联商户;fastmybatis升级到3.1.6 2025-08-18 10:02:45 +08:00
六如
933612bad3 admin后台可关联商户 2025-08-18 08:09:26 +08:00
六如
c8ae961b0e Merge remote-tracking branch 'origin/master'
# Conflicts:
#	changelog.md
2025-08-17 21:56:50 +08:00
六如
8cbf74d53a admin后台可关联商户 2025-08-17 21:56:23 +08:00
六如
1d18e1b7d3 修复当objClass被代理后,获取不到interface BUG 2025-07-22 19:58:18 +08:00
六如
71e22bc4ae 新增帮助文档管理 2025-06-18 16:45:29 +08:00
六如
f908af2323 新增帮助文档管理 2025-06-18 16:34:27 +08:00
六如
4d70c5167d 新增帮助文档管理 2025-06-15 15:27:43 +08:00
六如
c18ee0dff9 java-sdk添加文件下载示例 2025-06-11 21:57:51 +08:00
六如
c357202e53 java-sdk添加文件下载示例 2025-06-11 21:53:53 +08:00
六如
49283557c2 OpenContext添加charset字段 2025-06-01 20:28:11 +08:00
六如
fe0c08ad75 修复网关registerAddress配置 2025-05-18 13:53:12 +08:00
六如
3643466507 修复admin后台发布文档不生效问题;业务服务启动不用依赖网关 2025-05-12 08:56:30 +08:00
六如
a162db3354 修复admin后台发布文档不生效问题;业务服务启动不用依赖网关 2025-05-11 17:40:00 +08:00
六如
d3d0eb4b1b 优化dubbo filter 2025-03-13 01:21:07 +08:00
六如
f8350fe357 优化dubbo filter 2025-03-13 00:09:14 +08:00
六如
be2af14104 优化dubbo filter 2025-03-13 00:02:39 +08:00
六如
c7c7e4cf98 优化dubbo filter 2025-03-12 23:13:22 +08:00
六如
cd6c85a9c4 优化dubbo filter 2025-03-12 22:39:03 +08:00
六如
acabd2ed70 优化dubbo filter 2025-03-12 20:01:29 +08:00
六如
20851cfbda 优化dubbo filter 2025-03-12 11:15:19 +08:00
六如
1abc277f40 优化dubbo filter 2025-03-12 11:14:36 +08:00
六如
d82dd73099 优化dubbo filter 2025-03-12 09:55:12 +08:00
六如
30c7245cbb 优化dubbo filter 2025-03-12 01:14:07 +08:00
六如
c5f4e06df1 优化dubbo filter 2025-03-12 01:13:48 +08:00
六如
5acf4f85b0 优先使用本地缓存 2025-03-09 23:51:14 +08:00
六如
9106daf96c RouteContext新增isv对象 2025-03-06 09:46:47 +08:00
六如
8c5b0e2349 RouteContext新增isv对象 2025-03-06 09:46:26 +08:00
六如
7ffb3b8d9c 变更拦截器方法参数 2025-03-05 22:32:55 +08:00
六如
2724e34dc9 新增ListSerializer 2025-03-05 09:34:38 +08:00
六如
3a19208442 拦截器新增init方法 2025-03-04 22:30:39 +08:00
六如
1f2ab33ba3 拦截器新增init方法 2025-03-04 22:27:21 +08:00
六如
01b538366d UPDATE 2025-03-03 23:21:39 +08:00
六如
df51be3472 UPDATE 2025-03-03 22:42:42 +08:00
六如
ff382b86b7 校验token 2025-02-27 20:27:48 +08:00
六如
e5e1e00b9c 校验token 2025-02-27 20:27:14 +08:00
六如
46110d9f4f 校验token 2025-02-27 20:17:37 +08:00
六如
e4a7791fd2 校验token 2025-02-27 20:14:38 +08:00
六如
8dd6b66951 校验token 2025-02-27 20:13:41 +08:00
六如
a748399e41 校验token 2025-02-27 20:11:41 +08:00
六如
b0a68908bd 校验token 2025-02-27 20:08:27 +08:00
六如
c2664c4e37 fastmybatis升级到3.0.17 2025-02-26 23:15:17 +08:00
六如
96a37e65be 添加Java17示例 2025-02-26 09:40:43 +08:00
六如
b0dadbaa1f 添加Java17示例 2025-02-26 09:38:11 +08:00
六如
3213a634c5 UPDATE 2025-02-21 11:53:58 +08:00
六如
07c21c426a 优化收到接口注册 2025-02-20 11:03:08 +08:00
六如
914adf6918 优化收到接口注册 2025-02-20 10:58:32 +08:00
六如
09eef2f049 修复加载i18n问题 2025-02-20 10:55:13 +08:00
六如
bb132abe28 修复加载i18n问题 2025-02-20 10:45:41 +08:00
六如
e3e6ae4d7f 修复加载i18n问题 2025-02-19 21:16:10 +08:00
六如
26da6bf754 修复加载i18n问题 2025-02-19 21:06:51 +08:00
六如
6c70e9a5d2 修复加载i18n问题 2025-02-19 16:12:34 +08:00
六如
7786d72ea3 修复加载i18n问题 2025-02-19 16:11:27 +08:00
六如
8515f26b24 升级fastmybatis到3.0.16 2025-02-19 15:40:56 +08:00
六如
33b362befb 优化Restful接口校验 2025-02-09 17:45:42 +08:00
六如
dc6ca2854e 优化Restful接口校验 2025-02-09 17:42:44 +08:00
六如
71b064d607 优化Restful接口校验 2025-02-09 17:14:54 +08:00
六如
be50186da6 菜单排序 2025-02-07 09:00:21 +08:00
六如
ab4fb5a914 菜单排序 2025-02-06 12:21:32 +08:00
六如
1fa806fcd5 新增restful模式 2025-02-04 12:16:58 +08:00
六如
f9a663d560 新增restful模式 2025-02-04 12:12:41 +08:00
六如
a2a438562b 新增restful模式 2025-02-04 11:58:25 +08:00
六如
1cecae512c License 2025-02-03 13:22:54 +08:00
六如
a5dbf71513 新增OpenGroup注解 2025-02-03 11:31:29 +08:00
六如
aa8f044c70 完善SDK 2025-02-02 21:28:05 +08:00
六如
e09c0106a0 完善SDK 2025-02-02 21:14:07 +08:00
六如
10b060255c 新增restful模式 2025-02-02 16:37:12 +08:00
六如
ddc709ede4 新增restful模式 2025-02-02 15:51:47 +08:00
六如
1f04edeaff 调整依赖 2025-02-01 11:14:58 +08:00
六如
473ee11323 调整依赖 2025-01-30 14:58:50 +08:00
六如
aaf978bd0d 添加依赖 2025-01-30 12:32:10 +08:00
六如
72f5420d4f 添加代码生成器 2025-01-17 09:25:57 +08:00
六如
7bc96d690b 5.1 2025-01-08 09:46:07 +08:00
六如
5868708065 5.1 2025-01-08 09:17:41 +08:00
六如
92b2d6443b 5.1 2025-01-06 17:40:50 +08:00
六如
b4e6e3f94d 5.1 2025-01-03 13:36:06 +08:00
六如
5bd0670389 5.1 2025-01-03 13:35:32 +08:00
六如
e4e5cb0496 5.1 2025-01-02 13:55:59 +08:00
六如
c18c05e019 5.1 2024-12-31 10:03:57 +08:00
六如
3e900cf0fe 5.1 2024-12-30 20:49:17 +08:00
六如
40865ab049 5.0 2024-12-30 09:04:23 +08:00
六如
9e4c9e02ff 5.0 2024-12-26 15:30:33 +08:00
六如
bf6af442e0 5.0 2024-12-26 09:42:16 +08:00
六如
b9d5875847 5.0 2024-12-26 09:38:05 +08:00
六如
150379c5f9 5.0 2024-12-26 09:37:50 +08:00
六如
054560ae64 5.0 2024-12-25 10:28:24 +08:00
六如
091482f9cc 5.0 2024-12-25 10:09:50 +08:00
六如
5e25555404 5.0 2024-12-25 09:48:49 +08:00
六如
ff5dc5204d 5.0 2024-12-25 09:48:12 +08:00
六如
5d9fbc4ef9 5.0 2024-12-23 15:32:34 +08:00
六如
e009576889 5.0 2024-12-23 15:24:43 +08:00
六如
d435015ba9 5.0 2024-12-23 12:28:09 +08:00
六如
12479cffd2 5.0 2024-12-23 11:45:47 +08:00
六如
3f7bb181fa 5.0 2024-12-23 09:58:29 +08:00
六如
7d9a37edf4 5.0 2024-12-23 09:39:58 +08:00
六如
c77312b178 5.0 2024-12-23 09:18:44 +08:00
六如
4ab34db4fe 5.0 2024-12-23 00:23:25 +08:00
六如
552875289e Merge branch '5.0'
# Conflicts:
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/entity/ConfigServiceRoute.java
#	sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigServiceRoute.java
2024-12-23 00:18:44 +08:00
六如
47f061fd43 5.0 2024-12-22 23:09:56 +08:00
六如
403e8111f4 5.0 2024-12-22 23:09:46 +08:00
六如
02fb5a9e85 5.0 2024-12-22 08:42:31 +08:00
六如
bb2a9eb314 5.0 2024-12-21 20:16:00 +08:00
六如
f7f04c28eb 5.0 2024-12-19 18:05:59 +08:00
六如
3e06fcd799 5.0 2024-12-12 22:05:25 +08:00
六如
28808ab1e3 5.0 2024-12-05 23:48:32 +08:00
六如
960b83c916 5.0 2024-12-04 15:29:37 +08:00
tanghc
91e3420b6f !21 ConfigServiceRoute修改为自定义主键配置
Merge pull request !21 from 程子/N/A
2024-12-04 03:19:17 +00:00
tanghc
6ad3b309fb !20 ConfigServiceRoute修改为自定义主键
Merge pull request !20 from 程子/N/A
2024-12-04 03:19:05 +00:00
六如
bd72c334cb 5.0 2024-12-04 10:07:49 +08:00
六如
c407261bd7 5.0 2024-12-03 22:58:44 +08:00
六如
77b52508bb 5.0 2024-12-03 10:29:57 +08:00
六如
d70800d0e1 5.0 2024-12-03 10:16:45 +08:00
六如
1ce9ebbff9 5.0 2024-12-03 10:13:55 +08:00
六如
942826f4b0 5.0 2024-12-02 23:03:25 +08:00
六如
c0cfdbafd9 5.0 2024-12-01 13:10:32 +08:00
六如
09330a7431 5.0 2024-11-29 23:47:58 +08:00
程子
a9598f6e0a ConfigServiceRoute主键配置为修改为自定义主键
ConfigServiceRoute主键为自定义主键, 解决目前配置为自增主键导致批量新增时主键冲突异常

Signed-off-by: 程子 <395030787@qq.com>
2024-11-28 08:54:43 +00:00
程子
29f8a95833 update sop-gateway/src/main/java/com/gitee/sop/gateway/entity/ConfigServiceRoute.java.
ConfigServiceRoute主键为自定义主键, 解决批量目前配置为自增主键导致批量新增时主键冲突异常

Signed-off-by: 程子 <395030787@qq.com>
2024-11-28 08:51:48 +00:00
六如
85b33e7c3d 5.0 2024-11-27 10:08:24 +08:00
六如
5e2c3fab46 5.0 2024-11-25 00:18:47 +08:00
六如
ba384660f1 5.0 2024-11-20 10:37:42 +08:00
六如
16a2ca7723 5.0 2024-11-19 22:27:51 +08:00
六如
eefddbe5c0 5.0 2024-11-18 15:35:42 +08:00
六如
3db05e8bdd 5.0 2024-11-16 17:19:19 +08:00
六如
00f639ba19 5.0 2024-11-13 10:43:21 +08:00
六如
5f04df2ce3 5.0 2024-11-13 10:40:08 +08:00
六如
64637e6dfe 5.0 2024-11-13 10:36:58 +08:00
六如
7c5c47153e 5.0 2024-11-10 23:47:29 +08:00
六如
1ee4b2384c 5.0 2024-11-10 23:17:17 +08:00
六如
0498d0f7b5 5.0 2024-11-08 10:29:14 +08:00
六如
9e05259d92 5.0 2024-11-07 22:55:06 +08:00
六如
5956af3564 5.0 2024-11-04 21:46:18 +08:00
六如
f72fd07ea4 5.0 2024-11-04 16:23:16 +08:00
六如
9b2dc49a03 5.0 2024-11-04 14:41:13 +08:00
六如
21b427f116 5.0 2024-11-04 14:40:45 +08:00
六如
a88bb80717 5.0 2024-11-04 14:38:40 +08:00
六如
53a40a1cb4 5.0 2024-11-04 14:37:54 +08:00
六如
d9a257ff23 5.0 2024-11-04 11:12:30 +08:00
六如
7334fad2ab 5.0 2024-11-04 11:12:04 +08:00
六如
a598bf3404 5.0 2024-11-04 00:13:28 +08:00
六如
f76eab3c30 5.0 2024-11-04 00:01:02 +08:00
六如
0e29510d0e 5.0 2024-10-31 09:36:48 +08:00
六如
08f708d8a4 5.0 2024-10-28 09:13:08 +08:00
六如
d3b80f63b8 5.0 2024-10-27 21:34:10 +08:00
六如
a690c4a72d 5.0 2024-10-27 21:31:34 +08:00
六如
40835d2f69 5.0 2024-10-27 21:08:00 +08:00
六如
13b06f0592 5.0 2024-10-25 20:43:06 +08:00
六如
dabf8032ca 5.0 2024-10-25 20:28:42 +08:00
六如
8b34c0a80d 5.0 2024-10-23 22:26:08 +08:00
六如
b01f16d6df 5.0 2024-10-23 15:02:49 +08:00
六如
054c86a450 5.0 2024-10-23 10:39:08 +08:00
六如
d06a13df4a 5.0 2024-10-22 14:26:23 +08:00
六如
d32c9616c6 5.0 2024-10-22 14:15:45 +08:00
六如
483e3969be 5.0 2024-10-22 14:13:12 +08:00
六如
89304e8004 5.0 2024-10-21 14:15:03 +08:00
六如
c84a05b522 5.0 2024-10-20 23:28:17 +08:00
六如
0cbadbeda8 5.0 2024-10-19 20:27:16 +08:00
六如
17bc2d5ca8 5.0 2024-10-17 09:41:34 +08:00
六如
35b3e6489d 5.0 2024-10-11 09:59:52 +08:00
六如
cff2ee120b 5.0 2024-10-10 22:00:30 +08:00
六如
dd11ab46be 5.0 2024-10-10 21:52:37 +08:00
六如
e23911b075 5.0 2024-10-10 11:35:34 +08:00
六如
d9fb25dc0a 5.0 2024-10-05 21:13:29 +08:00
六如
c08fec74c9 5.0 2024-10-04 21:48:38 +08:00
六如
00da3cc0a9 5.0 2024-09-19 20:51:14 +08:00
六如
89ce369c8f 5.0 2024-09-17 23:07:32 +08:00
六如
50e576b9fc 5.0 2024-09-16 21:55:10 +08:00
六如
a14ac9e3c9 5.0 2024-09-14 10:33:43 +08:00
六如
95072a02f6 5.0 2024-09-12 21:52:54 +08:00
六如
cccafde158 5.0 2024-09-11 00:03:51 +08:00
六如
d4823ae473 5.0 2024-09-10 21:01:57 +08:00
六如
5e8a5d7133 5.0 2024-09-10 00:20:43 +08:00
六如
9a213743d7 5.0 2024-09-06 23:17:43 +08:00
六如
5dd9c597a9 Merge branch 'master' into 5.0
# Conflicts:
#	doc/docs/files/10011_项目接入到SOP.md
#	pom.xml
#	sop-common/sop-bridge-nacos/pom.xml
#	sop-common/sop-service-common/pom.xml
2024-09-04 09:58:05 +08:00
六如
7f6b3a4309 5.0 2024-09-04 09:55:29 +08:00
tanghc
0831ddd073 !19 升级相关组件版本
Merge pull request !19 from 整洁架构/master
2024-09-04 01:53:50 +00:00
整洁架构
6053a3f0ec 升级springboot版本至2.6.16
升级springcloud alibaba版本至2021.0.5.0
升级springcloud版本至2021.0.5
移除ribbon,使用spring cloud loadbalancer
2024-06-12 23:17:25 +08:00
tanghc
19022bdbe1 Merge branch 'pr' 2022-03-14 16:25:27 +08:00
tanghc
c7386f5f66 !13 解决 eureka 配置 security 时请求 401 无权限问题
Merge pull request !13 from 程子/pr
2022-03-14 08:07:02 +00:00
chengzi
7b930fa4b8 解决eureka开启basic时请求无权限问题 2022-03-14 11:58:44 +08:00
tanghc
a4ad90c90e 描述支持html 2022-01-12 16:39:46 +08:00
tanghc
f974d75f45 UPDATE 2021-08-04 15:30:44 +08:00
tanghc
ba61d9dd58 UPDATE 2021-08-04 15:30:17 +08:00
tanghc
5a2c15a835 UPDATE 2021-07-23 11:56:06 +08:00
tanghc
fde8e73bdc UPDATE 2021-07-22 11:09:43 +08:00
tanghc
b1e346d48d Merge branch 'develop' 2021-07-07 10:58:22 +08:00
tanghc
98b78339ab 扩展存放业务参数 2021-07-07 10:57:48 +08:00
tanghc
08d7745f4e Merge branch 'develop' 2021-07-07 10:52:38 +08:00
tanghc
f0c01dfd16 扩展存放业务参数 2021-07-07 10:52:20 +08:00
tanghc
66f5493e52 UPDATE 2021-06-29 06:59:59 +08:00
tanghc
efe46ff3e1 4.4.2 2021-06-16 17:44:39 +08:00
tanghc
a16a7aa2d3 4.4.2 2021-06-04 09:02:49 +08:00
tanghc
f8b8e5fca1 4.4.1 2021-06-03 15:50:33 +08:00
tanghc
06f400fb81 4.4.1 2021-05-17 09:59:02 +08:00
tanghc
0e20e75752 4.4.0 2021-05-12 18:02:36 +08:00
tanghc
1ef78cf582 4.4.0 2021-04-27 17:08:30 +08:00
tanghc
9ca2488f73 4.4.0 2021-04-17 10:26:45 +08:00
tanghc
e1cc2c982d !12 sdk-nodejs升级
Merge pull request !12 from Changeden/feature-sdk-nodejs-axios
2021-04-14 15:21:50 +08:00
tanghc
0b609305b1 优化参数校验 2021-04-14 15:18:42 +08:00
Changeden
4eae92b033 优化格式 2021-04-14 14:41:35 +08:00
Changeden
3ceb8cdc93 移除临时文件 2021-04-14 14:13:20 +08:00
Changeden
fc82fab1cf 使用es6+axios 2021-04-14 14:10:46 +08:00
Changeden
c573a5118d 完善sdk-nodejs-axios分支 2021-04-14 10:41:53 +08:00
Changeden
2d6370ba1b 完善sdk-nodejs-axios分支 2021-04-14 10:33:57 +08:00
Changeden
f09e00ddd7 完善sdk-nodejs-axios分支 2021-04-14 10:21:52 +08:00
Changeden
ccca3c26ee 完善sdk-nodejs-axios分支 2021-04-14 10:21:38 +08:00
Changeden
764d492449 新增nodejs-axios版本分支 2021-04-14 00:30:43 +08:00
tanghc
4fe912ab58 fix #I3IMEH 2021-04-13 20:39:17 +08:00
tanghc
2d8948fd5a UPDATE 2021-04-13 17:56:14 +08:00
tanghc
2150d499bb Merge remote-tracking branch 'origin/develop' into develop 2021-04-13 17:46:31 +08:00
tanghc
4055210942 UPDATE 2021-04-13 17:46:23 +08:00
tanghc
7819f21fbf !11 升级sdk-nodejs
Merge pull request !11 from Changeden/develop
2021-04-12 21:00:02 +08:00
Changeden
aaef05525e 优化sdk-nodejs以下功能:
1、新增同步请求方式(executeSync、executeTokenSync);
2、优化请求异常中断问题,返回502错误码;
3、优化签名方法;
2021-04-12 15:45:49 +08:00
Changeden
e1b860c75a 优化sdk-nodejs以下功能:
1、新增同步请求方式(executeSync、executeTokenSync);
2、优化请求异常中断问题,返回502错误码;
3、优化签名方法;
2021-04-12 15:42:52 +08:00
Changeden
472942e93e 优化sdk-nodejs以下功能:
1、新增同步请求方式(executeSync、executeTokenSync);
2、优化请求异常中断问题,返回502错误码;
3、优化签名方法;
2021-04-12 15:23:19 +08:00
tanghc
a1fdf71f3e 4.4.0 2021-04-09 20:59:30 +08:00
tanghc
bf977b2218 4.4.0 2021-04-09 20:50:05 +08:00
tanghc
c8fb583c7a 4.4.0 2021-04-09 20:17:17 +08:00
tanghc
412a061668 4.4.0 2021-04-09 20:14:41 +08:00
tanghc
9c3bafdd92 4.4.0 2021-04-08 17:40:24 +08:00
tanghc
3804bf33a7 4.4.0 2021-04-08 17:17:44 +08:00
tanghc
31202908a4 4.3.4 2021-04-01 18:11:07 +08:00
tanghc
ef0c09cb02 4.3.3 2021-03-30 09:48:32 +08:00
tanghc
7ec542abce 4.3.3 2021-03-30 09:46:39 +08:00
tanghc
8543754888 4.3.2 2021-03-27 14:47:22 +08:00
tanghc
f753faed66 4.3.2 2021-03-25 17:16:34 +08:00
tanghc
842f3a2ae5 4.3.2 2021-03-25 14:33:43 +08:00
tanghc
8aeb6c16bf 4.3.2 2021-03-25 14:28:21 +08:00
tanghc
9058022933 4.3.1 2021-03-20 13:58:16 +08:00
tanghc
66f88ddf30 4.3.1 2021-03-20 11:45:11 +08:00
tanghc
307d63e21e 4.3.1 2021-03-20 11:40:03 +08:00
tanghc
1b938b6ac2 4.3.1 2021-03-18 20:00:37 +08:00
tanghc
0430bb9bf6 4.3.1 2021-03-18 17:58:34 +08:00
tanghc
df8368cafc 4.3.1 2021-03-18 17:54:09 +08:00
tanghc
c38939ae4b 4.3.1 2021-03-18 17:22:01 +08:00
tanghc
66e5276360 4.3.1 2021-03-18 17:13:37 +08:00
tanghc
9188916926 4.3.1 2021-03-18 17:11:56 +08:00
tanghc
8cdb1fd031 4.3.1 2021-03-18 14:21:52 +08:00
tanghc
bf022b2da2 4.3.1 2021-03-18 10:43:10 +08:00
tanghc
7dccb19161 4.3.1 2021-03-17 15:52:53 +08:00
tanghc
de22c333d0 fix:serviceId大小写问题 2021-03-17 15:51:16 +08:00
tanghc
db9a2f4e23 4.3.0 2021-03-17 14:50:36 +08:00
tanghc
1b19b65d81 4.3.0 2021-03-17 14:26:17 +08:00
tanghc
c05f08cc36 4.3.0 2021-03-10 18:01:31 +08:00
tanghc
1f1509f6db 4.3.0 2021-03-10 10:33:33 +08:00
tanghc
581b4c869b 4.3.0 2021-03-05 16:59:23 +08:00
tanghc
3fb6ac30e6 4.3.0 2021-03-05 16:33:10 +08:00
tanghc
3379ae1020 4.3.0 2021-03-04 10:13:14 +08:00
tanghc
f3ade3e7db 4.3.0 2021-03-04 10:12:12 +08:00
tanghc
f32eccd492 4.3.0 2021-03-04 10:03:56 +08:00
tanghc
a01a6e88d3 4.3.0 2021-03-04 10:02:59 +08:00
tanghc
008c0f830f 4.3.0 2021-03-03 09:51:57 +08:00
tanghc
73fbd7a072 4.3.0 2021-03-03 09:33:05 +08:00
tanghc
888825ba50 4.3.0 2021-03-02 19:03:48 +08:00
tanghc
d0fe92a96c 4.3.0 2021-03-02 17:59:14 +08:00
tanghc
995d5ba623 4.3.0 2021-03-02 17:41:41 +08:00
tanghc
181b881bc5 优化性能 2021-03-02 14:34:08 +08:00
tanghc
91f8c82f0e 优化性能 2021-03-02 14:28:22 +08:00
tanghc
5d00092cc5 4.2.7 2021-03-01 11:12:33 +08:00
tanghc
2c765af036 4.2.7 2021-03-01 09:02:19 +08:00
tanghc
d223659376 4.2.7 2021-02-25 18:11:01 +08:00
tanghc
419f041786 4.2.7 2021-02-25 15:08:08 +08:00
tanghc
7bae549b30 4.2.7 2021-02-25 15:00:03 +08:00
tanghc
4b135a62dd 4.2.7 2021-02-25 13:53:44 +08:00
tanghc
a9a3dcdd0a 4.2.7 2021-02-25 13:43:09 +08:00
tanghc
a577df49c1 4.2.7 2021-02-25 11:32:55 +08:00
tanghc
306742b72f 4.2.7 2021-02-23 15:13:45 +08:00
tanghc
43bd300f4a 4.2.7 2021-02-23 11:55:00 +08:00
tanghc
c475a1b8cd 4.2.6 2021-02-22 11:31:38 +08:00
tanghc
5af379160c 4.2.6 2021-02-22 10:41:26 +08:00
tanghc
0f5f659b48 4.2.5 2021-02-03 11:45:19 +08:00
tanghc
2f707cc99d 4.2.5 2021-02-03 11:41:38 +08:00
tanghc
8efd1fc7b4 4.2.5 2021-02-02 14:08:56 +08:00
tanghc
e09f332fe6 4.2.5 2021-02-02 14:03:01 +08:00
tanghc
d642a4f9c6 修复restful负载均衡问题 2021-02-02 14:00:50 +08:00
tanghc
8d071e2ac3 4.2.4 2021-02-01 16:10:46 +08:00
tanghc
a3d97a4f8c 4.2.4 2021-01-27 11:18:57 +08:00
tanghc
b053c7b4e5 4.2.4 2021-01-26 14:58:08 +08:00
tanghc
883a6afd0b 4.2.4 2021-01-04 14:42:41 +08:00
tanghc
14e0383617 4.2.4 2020-12-24 11:03:42 +08:00
tanghc
32425e7903 4.2.4 2020-12-24 11:03:19 +08:00
tanghc
db384fe8a0 4.2.4 2020-12-17 14:59:11 +08:00
tanghc
9fa4ccce2b 4.2.4 2020-12-15 16:37:20 +08:00
tanghc
4451918acb 4.2.4 2020-12-15 15:13:45 +08:00
tanghc
f12b6e7b01 4.2.4 2020-12-13 14:24:14 +08:00
tanghc
1ff4303d2f 4.2.4 2020-12-13 14:19:23 +08:00
tanghc
dee635ba6c 4.2.3 2020-12-13 14:17:15 +08:00
tanghc
44e321720a 4.2.3 2020-12-09 18:11:31 +08:00
tanghc
ced55fb3b2 4.2.2 2020-12-09 16:44:49 +08:00
tanghc
950e8a53c3 4.2.2 2020-12-04 09:41:17 +08:00
tanghc
e40d885078 4.2.2 2020-12-04 09:38:21 +08:00
tanghc
3fce909a35 4.2.2 2020-12-04 09:09:08 +08:00
tanghc
eecbce1e4d 4.2.2 2020-12-03 09:20:00 +08:00
tanghc
019fa9db09 4.2.2 2020-12-02 16:36:49 +08:00
tanghc
e92f7c480d 4.2.2 2020-12-02 16:35:52 +08:00
tanghc
f59223b36e 4.2.2 2020-12-02 16:24:22 +08:00
tanghc
37f61700c1 4.2.2 2020-12-02 16:07:00 +08:00
tanghc
354d9c70b0 Merge branch 'develop' 2020-12-02 14:45:00 +08:00
tanghc
3d68ea80cd 4.2.1 2020-12-02 14:44:46 +08:00
tanghc
ae717f094f Merge branch 'develop' 2020-12-01 13:58:37 +08:00
tanghc
c0e165f59b 4.2.1 2020-12-01 13:58:17 +08:00
tanghc
376c5179b2 Merge branch 'develop' 2020-11-25 14:37:36 +08:00
tanghc
01937163b3 4.2.1 2020-11-25 14:37:28 +08:00
tanghc
4e6de894f0 4.2.1 2020-11-25 14:36:53 +08:00
tanghc
a79272df2d 4.2.1 2020-11-25 14:35:23 +08:00
tanghc
47b7037a12 Merge branch 'develop' 2020-11-25 13:48:09 +08:00
tanghc
32c3925986 4.2.1 2020-11-25 13:47:50 +08:00
tanghc
bdd02abda2 Merge branch 'develop' 2020-11-23 20:23:14 +08:00
tanghc
6bc596efe1 4.2.1 2020-11-23 20:21:59 +08:00
tanghc
d3bb2a6c29 Merge branch 'develop' 2020-11-20 10:28:47 +08:00
tanghc
35161c300a 4.2.0 2020-11-20 10:28:34 +08:00
tanghc
503631fcbe 4.2.0 2020-11-18 13:35:57 +08:00
tanghc
413327df63 4.2.0 2020-11-18 09:45:17 +08:00
tanghc
63d9033858 4.2.0 2020-11-18 09:42:01 +08:00
tanghc
4b1fa84f36 !9 文档业务参数中的“是否必填”值不正确
Merge pull request !9 from Jerry/master
2020-11-18 09:25:08 +08:00
Jerry
eeda6b36f2 fix: 字段 required 属性未获取到值 2020-11-17 19:19:46 +08:00
tanghc
3247f4528a 4.2.0 2020-11-13 14:37:15 +08:00
tanghc
b3aa515d01 4.2.0 2020-11-13 14:29:35 +08:00
tanghc
35564e66d8 4.2.0 2020-11-13 14:26:54 +08:00
tanghc
e1b287240e 4.2.0 2020-11-13 10:56:08 +08:00
tanghc
1203aaf246 4.2.0 2020-11-12 17:14:14 +08:00
tanghc
3ab4e70be9 4.2.0 2020-11-12 14:20:04 +08:00
tanghc
a9a17731b2 4.2.0 2020-11-12 11:35:48 +08:00
tanghc
d5d987c3d2 4.2.0 2020-11-11 14:19:15 +08:00
tanghc
13e30c87b6 4.2.0 2020-11-10 19:53:24 +08:00
tanghc
2243a93f5b 4.2.0 2020-11-10 19:53:07 +08:00
tanghc
7f6eee4c07 4.2.0 2020-11-10 18:18:04 +08:00
tanghc
bf42779369 4.2.0 2020-11-10 11:16:31 +08:00
tanghc
3a8be78532 4.2.0 2020-11-10 11:15:50 +08:00
tanghc
d76a2d7b68 4.2.0 2020-11-10 11:07:43 +08:00
tanghc
973c8a142d 4.2.0 2020-11-09 19:22:52 +08:00
tanghc
326eba4d5a 4.2.0 2020-11-09 17:18:53 +08:00
tanghc
309707f4a3 4.2.0 2020-11-09 17:15:29 +08:00
tanghc
84856e6865 4.2.0 2020-11-09 16:03:18 +08:00
tanghc
ae3ffd4f39 4.2.0 2020-11-09 09:04:40 +08:00
tanghc
832c6cb5fd 4.2.0 2020-11-08 08:15:11 +08:00
tanghc
eb7f9d69c0 4.2.0 2020-11-07 14:34:47 +08:00
tanghc
a79eeb0208 4.2.0 2020-11-07 14:17:28 +08:00
tanghc
1f9b82776d 4.2.0 2020-11-07 13:47:43 +08:00
tanghc
27ec6c5915 4.2.0 2020-11-07 13:36:25 +08:00
tanghc
2b08d4d9f2 4.2.0 2020-11-07 11:00:59 +08:00
tanghc
307065dded 4.2.0 2020-11-07 10:56:26 +08:00
tanghc
6ab696dfaf - 新增ISV用户平台
- 新增门户网站(portal)
- 新增`C++`,`Rust`语言SDK
2020-11-07 10:55:12 +08:00
tanghc
1370883af9 4.1.0 2020-11-04 09:37:48 +08:00
tanghc
c49b6eecaa 调整启动的扫描路径,去除重复注册。 2020-11-02 20:53:03 +08:00
林志强
8c8b1c7442 1、升级SpringBoot,alibaba,springCloud版本。
2、移除部分在SpringBoot已经定义的依赖,避免版本冲突。
3、升级guava版本。
2020-11-02 15:59:23 +08:00
tanghc
ad16abe9f4 重构路由监控 2020-11-02 11:34:57 +08:00
tanghc
ca6021a67c 重构路由监控 2020-11-01 07:57:49 +08:00
tanghc
287dba9c89 重构路由监控 2020-10-31 18:03:09 +08:00
tanghc
80003c44d3 重构路由监控 2020-10-31 18:02:02 +08:00
tanghc
4ce2fc826d 4.0.3 2020-10-30 10:27:37 +08:00
tanghc
dc584c36d6 4.0.3 2020-10-29 16:27:37 +08:00
tanghc
6f4c635855 4.0.3 2020-10-29 15:58:34 +08:00
tanghc
8e833c295f 4.0.3 2020-10-29 15:01:29 +08:00
tanghc
3cef44dc96 4.0.3 2020-10-29 14:06:20 +08:00
tanghc
5e906bc4ba 4.0.3 2020-10-29 11:31:57 +08:00
tanghc
446b98ea7a 4.0.3 2020-10-29 11:24:01 +08:00
tanghc
06dbb21796 4.0.3 2020-10-28 17:20:44 +08:00
tanghc
80cc48b3b1 4.0.3 2020-10-28 16:40:16 +08:00
tanghc
4c552199fb 4.0.3 2020-10-27 15:48:47 +08:00
tanghc
70b8525ccc 4.0.3 2020-10-27 15:38:39 +08:00
tanghc
9dfaca5c6f !4 优化:补充gitignore文件
Merge pull request !4 from hzf/master
2020-10-23 17:12:16 +08:00
Harry
3b1b1845f8 优化:增加连接池配置 2020-10-23 16:37:04 +08:00
Harry
fc8f305e3d 优化:补充gitignore文件 2020-10-23 16:22:41 +08:00
tanghc
a360fe713a !3 新的微服务启动后路由信息入库失败问题优化
Merge pull request !3 from hzf/master
2020-10-22 14:33:13 +08:00
Harry
a94b8e2770 优化路由加载时数据库连接池自动断开导致路由信息入库失败 2020-10-22 11:59:57 +08:00
tanghc
dc8d28a256 支持docker 2020-10-20 19:51:09 +08:00
tanghc
418c9ffc7a 支持docker 2020-10-20 19:36:58 +08:00
tanghc
02d3955d00 支持docker 2020-10-20 17:29:17 +08:00
tanghc
3b2a7f92d7 支持docker 2020-10-20 17:10:28 +08:00
tanghc
71d420c22e 支持docker 2020-10-20 17:02:01 +08:00
tanghc
ace5e1d5f6 支持docker 2020-10-20 13:57:48 +08:00
tanghc
3c55c17818 支持docker 2020-10-20 13:56:55 +08:00
tanghc
62bbb9a130 支持docker 2020-10-20 13:47:47 +08:00
tanghc
92d2ba6a20 支持docker 2020-10-20 11:40:36 +08:00
tanghc
9f83da1cda 支持docker 2020-10-20 11:07:14 +08:00
tanghc
58d42dc382 支持docker 2020-10-20 10:58:02 +08:00
tanghc
645a14e4f2 支持docker 2020-10-20 10:28:10 +08:00
tanghc
dc24e511a1 支持docker 2020-10-20 10:17:36 +08:00
tanghc
34fed4b924 支持docker 2020-10-20 10:10:44 +08:00
tanghc
c38c31031a 支持docker 2020-10-19 19:28:42 +08:00
tanghc
b4a805ccef 支持docker 2020-10-19 16:30:29 +08:00
tanghc
c4194817d5 支持docker 2020-10-19 16:23:45 +08:00
tanghc
e661f45bd1 支持docker 2020-10-19 15:52:10 +08:00
tanghc
5e081b5cfd 支持docker 2020-10-19 11:58:10 +08:00
tanghc
3ea29e8bf0 4.0.3 2020-10-19 10:07:03 +08:00
tanghc
c2489e4d7e 4.0.3 2020-10-16 13:44:47 +08:00
tanghc
af69ccb730 4.0.3 2020-10-16 13:42:09 +08:00
tanghc
9ea5626074 4.0.3 2020-10-15 20:16:24 +08:00
tanghc
65342b54ee 4.0.3 2020-10-15 15:24:57 +08:00
tanghc
98f2900e13 4.0.3 2020-10-15 09:38:47 +08:00
tanghc
676771f5d0 4.0.3 2020-10-15 09:28:20 +08:00
tanghc
0c4dd04bc7 4.0.3 2020-10-14 21:02:41 +08:00
tanghc
1850d6d567 4.0.3 2020-10-14 16:29:52 +08:00
tanghc
d0d4ab09f2 4.0.3 2020-10-13 16:30:30 +08:00
tanghc
ad742128b7 4.0.3 2020-10-09 08:20:43 +08:00
tanghc
87a2a3a629 4.0.3 2020-09-25 14:03:51 +08:00
tanghc
994960da31 4.0.3 2020-09-25 13:49:36 +08:00
tanghc
faa9310759 4.0.3 2020-09-25 13:35:37 +08:00
tanghc
3ca80dd6a6 4.0.3 2020-09-24 15:01:57 +08:00
tanghc
2eca422224 4.0.3 2020-09-23 15:57:18 +08:00
tanghc
c9b6f73a46 4.0.3 2020-09-23 15:34:42 +08:00
tanghc
636bbf20df 4.0.3 2020-09-22 15:39:20 +08:00
tanghc
4ed9da7707 4.0.3 2020-09-22 15:34:35 +08:00
tanghc
f66d8bed59 4.0.3 2020-09-15 10:59:10 +08:00
tanghc
95f2ecf7dc 4.0.3 2020-09-14 13:27:13 +08:00
tanghc
c6e5a20a81 4.0.3 2020-09-11 15:45:13 +08:00
tanghc
01bb3eae06 4.0.3 2020-09-09 18:15:27 +08:00
tanghc
c318534922 4.0.3 2020-09-09 18:14:03 +08:00
tanghc
9c507c8bd3 4.0.3 2020-09-09 12:00:57 +08:00
tanghc
725e08d8e7 4.0.3 2020-09-09 10:55:16 +08:00
tanghc
066e6a7d57 4.0.3 2020-09-09 10:50:09 +08:00
tanghc
2270c50886 4.0.3 2020-09-02 09:50:33 +08:00
tanghc
3f9365f5d5 4.0.3 2020-08-28 11:34:36 +08:00
tanghc
8410b90001 4.0.3 2020-08-25 17:04:51 +08:00
tanghc
6e54384571 4.0.3 2020-08-24 12:13:29 +08:00
tanghc
f223a56fd5 4.0.3 2020-08-24 12:09:51 +08:00
tanghc
8e8f24f5e8 4.0.3 2020-08-24 11:51:14 +08:00
tanghc
ebae72d883 4.0.3 2020-08-24 11:20:24 +08:00
tanghc
4fad0d67ef 4.0.3 2020-08-20 16:09:35 +08:00
tanghc
34519ee280 4.0.3 2020-08-20 14:28:51 +08:00
tanghc
bdf3334732 4.0.3 2020-08-20 14:23:36 +08:00
tanghc
7468ce3524 4.0.3 2020-08-20 12:24:08 +08:00
tanghc
45ceebc34b 4.0.3 2020-08-20 11:38:38 +08:00
tanghc
25fa143dda 4.0.3 2020-08-20 11:32:33 +08:00
tanghc
f6f412d102 4.0.3 2020-08-20 11:19:25 +08:00
tanghc
77ecbb668c 4.0.3 2020-08-20 09:53:42 +08:00
tanghc
e86296ad5b 4.0.3 2020-08-20 09:25:17 +08:00
tanghc
4d260c72ab 4.0.3 2020-08-19 16:20:23 +08:00
tanghc
27d5b0135c 4.0.3 2020-08-19 09:56:20 +08:00
tanghc
a22bfb84db 4.0.3 2020-08-18 15:44:42 +08:00
tanghc
9e905666c8 4.0.3 2020-08-18 15:20:18 +08:00
tanghc
5aa11c734e 4.0.3 2020-08-18 15:07:01 +08:00
tanghc
43e5707c01 4.0.3 2020-08-18 14:04:29 +08:00
tanghc
1ac069fae8 4.0.3 2020-08-17 17:34:26 +08:00
tanghc
7dab8da699 4.0.3 2020-08-17 16:51:33 +08:00
tanghc
160e57df0e 4.0.2 2020-08-10 17:18:20 +08:00
tanghc
42979771ee 4.0.2 2020-08-10 11:34:21 +08:00
tanghc
315177677c 4.0.2 2020-08-10 11:16:48 +08:00
tanghc
f1d8cc8318 4.0.2 2020-08-10 11:12:02 +08:00
tanghc
49cd8f7fda 4.0.2 2020-08-05 11:34:50 +08:00
tanghc
8239a536b9 4.0.2 2020-08-05 11:32:17 +08:00
tanghc
c8598b5a0e 4.0.2 2020-08-05 11:08:18 +08:00
tanghc
67a3119e5d 4.0.2 2020-08-05 11:03:04 +08:00
tanghc
8a87e945de 4.0.2 2020-08-04 18:02:46 +08:00
tanghc
5b58f110a2 4.0.2 2020-08-04 14:20:11 +08:00
tanghc
a20c3fa14c 4.0.2 2020-08-04 14:10:41 +08:00
tanghc
199cb67fa3 支持swagger排序 2020-08-04 13:55:44 +08:00
tanghc
57c8f34c3b v4.0.1 2020-08-04 10:55:02 +08:00
tanghc
4456d15182 v4.0.1 2020-07-30 13:34:14 +08:00
tanghc
e163dbc2a8 v4.0.1 2020-07-30 12:29:38 +08:00
tanghc
c62f13e897 修复请求体超过256KB无法请求问题 2020-07-30 12:27:03 +08:00
tanghc
4d6693aca2 修复请求体超过256KB无法请求问题 2020-07-30 11:58:32 +08:00
tanghc
f86e569c03 4.0.0 2020-07-29 17:31:25 +08:00
tanghc
ab56f20939 4.0.0 2020-07-29 12:04:51 +08:00
tanghc
71bcf2da1b 4.0.0 2020-07-29 11:37:20 +08:00
tanghc
8e0677a86e 4.0.0 2020-07-29 11:36:23 +08:00
tanghc
294b58a7f6 4.0.0 2020-07-29 11:29:08 +08:00
tanghc
4c1197e181 4.0.0 2020-07-29 11:18:45 +08:00
tanghc
33e50a1fae 4.0 2020-07-29 10:33:45 +08:00
tanghc
0fea955db9 4.0 2020-07-28 18:21:01 +08:00
tanghc
ee30f18d53 3.2.1 2020-07-27 14:45:53 +08:00
tanghc
a68ac1a10c 3.2.1 2020-07-09 15:36:43 +08:00
tanghc
6df91ddfda 3.2.1 2020-07-06 13:57:38 +08:00
tanghc
57d0ccbede 3.2.1 2020-07-03 17:32:50 +08:00
tanghc
c120788857 3.2.1 2020-06-28 09:06:57 +08:00
tanghc
d4225aff9d 3.2.1 2020-06-24 18:44:29 +08:00
tanghc
cc8bb34bb0 3.2.1 2020-06-24 11:05:23 +08:00
tanghc
06229d6b90 RouteInterceptorContext可获转发的目标微服务信息 2020-06-24 11:01:02 +08:00
tanghc
a90d0214a8 3.2.0 2020-06-20 11:25:44 +08:00
tanghc
f2e6ea6201 3.2.0 2020-06-18 09:08:41 +08:00
tanghc
e8b251ddb8 Merge remote-tracking branch 'origin/master' 2020-06-18 09:02:48 +08:00
tanghc
acb259fe6f 3.2.0 2020-06-18 09:02:20 +08:00
tanghc
a1f2954544 !2 Bugfix:接口文档解析NPE
Merge pull request !2 from bigbenfather/master
2020-06-17 17:31:44 +08:00
tanghc
2d10d58935 3.2.0 2020-06-17 15:43:29 +08:00
tanghc
3118f07bbc 3.2.0 2020-06-17 10:36:54 +08:00
tanghc
6406f023db 3.2.0 2020-06-17 10:36:22 +08:00
梁来宾
7f83dbe5b0 bugfix-NPE异常
例如:当 ref = ApiResult«Void» 时, definitions的结构如下

         	"definitions": {
        		"ApiResult«Void»": {
        			"type": "object",
        			"title": "ApiResult«Void»"
        		}
        	}
2020-06-17 10:00:16 +08:00
tanghc
f66e2f8891 3.2.0 2020-06-17 09:35:15 +08:00
tanghc
04a1a05127 3.2.0 2020-06-16 18:02:41 +08:00
tanghc
2588014b6e 3.2.0 2020-06-16 11:19:16 +08:00
tanghc
70a23d1d44 3.2.0 2020-06-16 09:46:31 +08:00
tanghc
d943377c00 3.2.0 2020-06-15 14:34:47 +08:00
tanghc
007c52b174 3.2.0 2020-06-12 10:00:56 +08:00
tanghc
131e7b9403 3.2.0 2020-06-12 09:58:22 +08:00
tanghc
739545526e 3.2.0 2020-06-12 09:54:14 +08:00
tanghc
0fb884c451 3.2.0 2020-06-12 08:38:28 +08:00
tanghc
5f0a1d1a43 优化交互 2020-06-11 20:05:25 +08:00
tanghc
45eae0c99f 3.2.0 2020-06-11 19:01:45 +08:00
tanghc
08d2371b2b 3.1.5 2020-06-10 10:48:52 +08:00
tanghc
46f8558c5a 修复文件上传大小不一致问题 2020-06-10 10:47:56 +08:00
tanghc
fe496a1dc3 doc 2020-06-08 14:20:41 +08:00
tanghc
7a0fa4c039 修复i18n配置 2020-06-01 16:55:31 +08:00
tanghc
b2f6159f0c 修复zuul推送问题 2020-05-26 14:15:14 +08:00
tanghc
5f9bab5807 3.1.4 2020-05-26 10:05:19 +08:00
tanghc
44f5506375 优化跨域 2020-05-26 10:04:27 +08:00
tanghc
760adf0f6d 3.1.3 2020-05-26 10:02:22 +08:00
tanghc
fc7ddef575 3.1.3 2020-05-18 17:29:26 +08:00
tanghc
33ae5013e9 3.1.3 2020-05-18 15:34:47 +08:00
tanghc
43070efae9 3.1.3 2020-05-18 15:32:48 +08:00
tanghc
e0249e5e6e 修复监控异常乱码问题. thx for 清风 2020-05-18 15:31:32 +08:00
tanghc
801b5f1fd4 完善springmvc demo 2020-05-09 16:53:41 +08:00
tanghc
e8e34f0137 3.1.2 2020-04-15 16:00:06 +08:00
tanghc
33b9c870bb 修复图片上传保存后图片破损问题 2020-04-15 15:58:47 +08:00
tanghc
7b8899abec 3.1.1 2020-04-07 10:32:12 +08:00
tanghc
53a995a5c5 3.1.1 2020-04-05 10:41:58 +08:00
tanghc
8e20db4514 修复继承WebMvcConfigurationSupport导致的jackson序列化时间问题
修复微服务接口返回void网关不会返回code和msg问题
2020-04-05 10:41:05 +08:00
tanghc
49c9572a3b 文档显示优化 2020-03-31 15:13:04 +08:00
tanghc
eaecc720b3 更新fastmybatis 2020-03-30 08:56:50 +08:00
tanghc
026b8706e9 3.1.0 2020-03-24 12:22:07 +08:00
tanghc
bd086e386a 3.1.0 2020-03-24 12:19:43 +08:00
tanghc
d0b8ff94d9 3.1.0 2020-03-24 10:13:34 +08:00
tanghc
8e71da73ba 3.1.0 2020-03-19 16:23:04 +08:00
tanghc
d08ba46063 3.1.0 2020-03-02 08:48:59 +08:00
tanghc
62261dc107 3.1.0 2020-02-27 13:57:03 +08:00
tanghc
ad302514d4 3.1.0 2020-02-21 10:55:08 +08:00
tanghc
beff70de45 3.1.0 2020-02-20 09:03:56 +08:00
tanghc
56ec7cfc84 3.1.0 2020-02-19 18:03:06 +08:00
tanghc
145f683ad7 3.1.0 2020-02-19 13:56:46 +08:00
tanghc
68e9f173f2 新增路由监控功能、优化负载均衡策略、新增拦截器接口 2020-02-19 13:54:52 +08:00
tanghc
b76684c3c6 修改zuul默认配置 2020-02-19 12:57:28 +08:00
tanghc
6a93e325f4 修改测试用例 2020-02-19 12:56:05 +08:00
tanghc
8de9db5ff1 路由拦截器文档 2020-02-18 19:51:26 +08:00
tanghc
405c161c68 新增路由监控功能 2020-02-18 19:50:57 +08:00
tanghc
6acee19124 3.0.1 2020-02-07 17:33:07 +08:00
tanghc
21374c1665 3.0.1-优化限流配置页 2020-02-07 17:10:43 +08:00
tanghc
aeae182628 更新性能测试文档 2020-02-05 10:57:52 +08:00
tanghc
e7daa46005 更新性能测试文档 2020-02-05 10:56:58 +08:00
tanghc
1c4ff766df 更新群号 2020-02-03 10:37:47 +08:00
tanghc
69cb993f6e 更新群号 2020-02-03 10:32:27 +08:00
tanghc
089964af91 更新群号 2020-02-03 10:20:47 +08:00
tanghc
59d07d94f8 !1 admin增加nacos的namespace
Merge pull request !1 from bigbenfather/master
2020-02-03 09:40:27 +08:00
tanghc
d3d53745f9 3.0.0 2020-01-21 15:02:31 +08:00
tanghc
5c0a635a64 3.0.0 2020-01-21 14:10:54 +08:00
tanghc
d7a089b1ca 3.0.0 2020-01-21 14:09:38 +08:00
tanghc
c3065adef1 3.0.0 2020-01-21 14:03:27 +08:00
tanghc
4ba59e0ebe 3.0.0 2020-01-21 13:51:42 +08:00
tanghc
9b8f7be8dd 3.0.0 2020-01-21 11:07:59 +08:00
tanghc
7d2d182263 3.0.0 2020-01-21 10:15:47 +08:00
tanghc
03b6ce2c70 3.0.0 2020-01-21 09:51:49 +08:00
tanghc
8fe0951c02 2.5.12 2020-01-21 09:42:22 +08:00
tanghc
7887d1ac62 修复限流BUG 2020-01-21 09:40:32 +08:00
tanghc
65038a9438 3.0.0 2020-01-21 09:39:07 +08:00
tanghc
250a9b61c5 3.0.0 2020-01-21 09:29:43 +08:00
tanghc
f92318dc7a 3.0.0 2020-01-21 08:50:57 +08:00
tanghc
2a7835e290 3.0.0 2020-01-20 16:11:51 +08:00
tanghc
99cb38eaa4 3.0.0 2020-01-20 16:10:24 +08:00
tanghc
563d5adcc0 3.0.0 2020-01-20 15:16:26 +08:00
tanghc
e8e6fc4ce4 3.0.0 2020-01-19 16:24:45 +08:00
tanghc
fab1a88d78 3.0.0 2020-01-19 10:44:21 +08:00
tanghc
09a25f9629 3.0.0 2020-01-19 09:40:24 +08:00
tanghc
150fae4ae0 3.0.0 2020-01-17 14:56:22 +08:00
tanghc
8991694971 3.0.0 2020-01-17 14:51:38 +08:00
tanghc
40b4709b38 3.0.0 2020-01-17 14:00:37 +08:00
tanghc
820909036b 3.0.0 2020-01-17 11:24:57 +08:00
tanghc
935bb2a454 3.0.0 2020-01-16 18:20:58 +08:00
tanghc
d76c5a5963 3.0.0 2020-01-16 17:26:01 +08:00
tanghc
7b7ccf0e08 3.0.0 2020-01-16 15:52:18 +08:00
tanghc
554520d4b8 3.0.0 2020-01-16 15:10:04 +08:00
tanghc
3a6ea57226 3.0.0 2020-01-16 11:52:40 +08:00
tanghc
f6ec1a6654 3.0.0 2020-01-16 11:05:09 +08:00
tanghc
58add8be82 3.0.0 2020-01-16 10:38:59 +08:00
tanghc
626fd3a8e4 2.5.11 2020-01-16 10:21:40 +08:00
tanghc
8537ea8a70 Merge branch 'develop' 2020-01-16 09:49:28 +08:00
tanghc
3bd540d98f 2.5.11 2020-01-16 09:47:30 +08:00
tanghc
6b505dfd8d 优化灰度预发布 2020-01-16 09:46:27 +08:00
tanghc
c1849bcaf3 优化灰度预发布 2020-01-16 09:44:18 +08:00
tanghc
bba600a4f5 3.0.0 2020-01-15 18:12:43 +08:00
tanghc
23bbf26db7 重构预发布/灰度发布环境选择 2020-01-15 18:08:35 +08:00
tanghc
9bb6bcb9cb 3.0.0 2020-01-15 18:05:18 +08:00
tanghc
7ce714dc05 3.0.0 2020-01-15 18:04:56 +08:00
tanghc
69131929c7 3.0.0 2020-01-14 11:22:22 +08:00
tanghc
0d3489f17e 3.0.0 2020-01-14 09:29:03 +08:00
tanghc
e1cd5c2298 3.0.0 2020-01-13 18:12:31 +08:00
tanghc
7d682587f2 3.0.0 2020-01-13 17:58:40 +08:00
tanghc
0e686ef888 3.0.0 2020-01-13 16:29:38 +08:00
tanghc
d704d6770f UPDATE 2020-01-13 16:14:09 +08:00
tanghc
8b72108a58 UPDATE 2020-01-13 16:12:40 +08:00
tanghc
5a773745f9 3.0.0 2020-01-13 15:55:44 +08:00
tanghc
c12eac02e6 2.6.0 2020-01-12 09:11:57 +08:00
tanghc
7d759024b7 2.6.0 2020-01-11 10:53:27 +08:00
tanghc
0935a185fa 2.6.0 2020-01-10 21:32:18 +08:00
tanghc
1a787c182a 2.6.0 2020-01-10 21:31:41 +08:00
tanghc
06c800cbdd 2.6.0 2020-01-10 20:55:34 +08:00
tanghc
b107886ed9 2.6.0 2020-01-10 20:46:12 +08:00
tanghc
744e28b343 Merge remote-tracking branch 'origin/2in1' into 2in1
# Conflicts:
#	doc/docs/files/10096_使用SpringCloudGateway.md
2020-01-10 20:41:44 +08:00
tanghc
59289cb170 2.6.0 2020-01-10 20:41:17 +08:00
tanghc
e995a2a64f 网关二合一 2020-01-10 20:38:38 +08:00
tanghc
8530867653 网关二合一 2020-01-10 20:20:56 +08:00
tanghc
3d0a940b2c 网关二合一 2020-01-10 18:20:29 +08:00
tanghc
994b486163 代码转移 2020-01-10 14:02:21 +08:00
tanghc
57f272df94 2.5.10 2020-01-08 09:57:56 +08:00
tanghc
f3575a6add 2.5.10 2020-01-07 15:07:26 +08:00
tanghc
0c7b1ae408 2.5.10 2020-01-07 10:57:50 +08:00
tanghc
f068e6f941 2.5.10 2020-01-07 10:45:24 +08:00
tanghc
ee710f8bf3 2.5.10 2020-01-06 09:52:32 +08:00
tanghc
01b1e7b72d 2.5.10 2020-01-03 17:41:47 +08:00
tanghc
0958cf003c 2.5.9 2020-01-03 09:37:41 +08:00
tanghc
5fdddfd47c 2.5.9 2020-01-02 10:34:30 +08:00
tanghc
a12f08a485 优化结果返回 2020-01-02 10:31:37 +08:00
tanghc
0774e52cc9 获取context-path优化 2020-01-02 10:11:27 +08:00
tanghc
0db69a88bf 去掉redis依赖 2019-12-31 17:21:10 +08:00
tanghc
77e0db05be 兼容注册中心配置 2019-12-30 17:04:45 +08:00
tanghc
d505ad94ab Merge remote-tracking branch 'origin/master' 2019-12-27 14:53:29 +08:00
tanghc
43847a5a79 UPDATE 2019-12-27 14:53:07 +08:00
tanghc
562b925ce5 add LICENSE. 2019-12-27 14:51:15 +08:00
tanghc
3d906b5f7f 更新test 2019-12-27 11:41:41 +08:00
tanghc
3f8e2226a8 2.5.8 2019-12-25 16:55:58 +08:00
tanghc
ca833a26e9 2.5.8 2019-12-25 14:33:18 +08:00
tanghc
38d11f3486 优化交互 2019-12-25 14:29:52 +08:00
tanghc
f037fe23d8 2.5.8 2019-12-25 13:39:20 +08:00
tanghc
eb6af6a97d 优化交互 2019-12-25 13:37:18 +08:00
tanghc
3b60ee27b0 2.5.8 2019-12-25 13:22:25 +08:00
tanghc
26cba8ff1e 2.5.8 2019-12-25 11:28:49 +08:00
tanghc
774d092465 2.5.8 2019-12-23 11:13:51 +08:00
tanghc
dfcd4d42d7 2.5.8 2019-12-19 15:36:48 +08:00
tanghc
93b48088e3 2.5.8 2019-12-19 15:29:45 +08:00
tanghc
05395ea0b9 优化参数绑定 2019-12-19 15:28:41 +08:00
tanghc
49615e6476 2.5.7 2019-12-19 12:02:57 +08:00
tanghc
eaf501b3d0 2.5.7 2019-12-19 12:02:02 +08:00
tanghc
5d02c8f608 优化交互 2019-12-19 11:41:05 +08:00
tanghc
fdd5d3b00d 2.5.7 2019-12-19 11:30:50 +08:00
tanghc
f2d3ee1af9 2.5.7 2019-12-13 13:29:27 +08:00
tanghc
1532f3addc 2.5.7 2019-12-13 11:36:48 +08:00
tanghc
b03e908173 2.5.7 2019-12-11 10:51:50 +08:00
tanghc
7fabddcd11 更新示例 2019-12-11 10:32:10 +08:00
tanghc
42ac4fff77 更新文档 2019-12-10 20:02:22 +08:00
梁来宾
5576653ae5 Merge branch 'master' of https://gitee.com/durcframework/SOP 2019-12-10 13:49:57 +08:00
tanghc
8f9acdffac 修复不传参数问题 2019-12-10 10:56:12 +08:00
梁来宾
08ca6a2a59 增加nacos的namespace配置 2019-12-09 13:44:16 +08:00
tanghc
888d1e0c4e 2.5.7 2019-12-04 08:27:05 +08:00
tanghc
a50f73563a 2.5.7 2019-12-03 12:03:12 +08:00
tanghc
bb3f45b197 restful调用优化 2019-12-03 11:57:40 +08:00
tanghc
0f0c1ec710 restful调用优化 2019-12-03 11:57:18 +08:00
tanghc
bddb668452 2.5.6 2019-11-29 14:56:35 +08:00
tanghc
e1f9663487 2.5.6 2019-11-29 14:54:52 +08:00
tanghc
1b3740a99a 2.5.6 2019-11-27 11:48:52 +08:00
tanghc
6818ed062d 2.5.6 2019-11-26 17:26:50 +08:00
tanghc
ef2cb5ccdd 2.5.6 2019-11-26 16:51:27 +08:00
tanghc
d6eef1218e 修复文档显示BUG 2019-11-26 16:51:01 +08:00
tanghc
2e88574284 2.5.5 2019-11-26 14:59:04 +08:00
tanghc
baace8f53e 2.5.5 2019-11-26 14:47:45 +08:00
tanghc
7a3960117a 2.5.5 2019-11-25 19:55:35 +08:00
tanghc
75d5d9b101 优化Springmvc文档显示 2019-11-25 19:54:19 +08:00
tanghc
94d9b0da90 优化文档显示 2019-11-25 19:53:32 +08:00
tanghc
3cf806cc90 2.5.4 2019-11-25 16:11:39 +08:00
tanghc
2e853bb77c 2.5.4 2019-11-25 15:52:23 +08:00
tanghc
1077f57ff6 2.5.4 2019-11-22 16:32:22 +08:00
tanghc
82b1ff61c8 2.5.4 2019-11-22 15:51:35 +08:00
tanghc
cea8fbba7b 可排除其它服务 2019-11-22 15:49:48 +08:00
tanghc
8d63d865f6 修复NPE问题 2019-11-21 14:10:46 +08:00
tanghc
95c577f2a5 修改网关serviceId 2019-11-20 20:10:51 +08:00
tanghc
6f9fff2b89 修改文档 2019-11-20 10:01:09 +08:00
tanghc
42abb033ab 2.5.3 2019-11-14 19:25:24 +08:00
tanghc
d193035d69 2.5.3 2019-11-14 19:22:48 +08:00
tanghc
efe08c6389 2.5.3 2019-11-14 17:21:28 +08:00
tanghc
0bdac8506b 2.5.3 2019-11-14 14:05:26 +08:00
tanghc
6a0bcf9061 2.5.3 2019-11-13 17:25:06 +08:00
tanghc
f8ff5e7e8e 2.5.3 2019-11-13 16:30:54 +08:00
tanghc
64cb58a9ca 2.5.3 2019-11-06 20:26:58 +08:00
tanghc
f62475d3fc JSR-303优化 2019-11-06 20:26:39 +08:00
tanghc
015b084855 JSR-303优化 2019-11-06 16:41:29 +08:00
tanghc
48395c396c 2.5.2 2019-11-06 09:32:19 +08:00
tanghc
511370e9b3 2.5.2 2019-11-05 16:37:16 +08:00
tanghc
4e8bdc4de4 2.5.2 2019-11-05 16:33:35 +08:00
tanghc
5d2318f72d JSR-303支持嵌套校验 2019-11-05 16:28:58 +08:00
tanghc
55c5d0cad9 2.5.1 2019-11-05 12:00:46 +08:00
tanghc
f787bdfab7 JSR-303支持嵌套校验 2019-11-05 11:50:59 +08:00
tanghc
eef82419c8 2.5.0 2019-10-29 16:14:39 +08:00
tanghc
2b850929d9 2.5.0 2019-10-28 14:28:54 +08:00
tanghc
2f8438ff09 2.5.0 2019-10-26 16:00:59 +08:00
tanghc
ba6bf5f8e7 2.5.0 2019-10-26 15:57:12 +08:00
tanghc
a08313ea81 网关可校验token 2019-10-26 15:54:48 +08:00
tanghc
530a92a3ea 2.4.1 2019-10-15 12:56:44 +08:00
tanghc
538452dbe6 2.4.1 2019-10-15 12:51:51 +08:00
tanghc
8159c999af 2.4.1 2019-10-15 12:49:08 +08:00
tanghc
ec0cbfb87e 2.4.1 2019-10-15 12:42:38 +08:00
tanghc
58cd959e01 restful调用优化 2019-10-15 12:41:02 +08:00
tanghc
6b3b38e058 2.4.0 2019-10-15 08:52:29 +08:00
tanghc
90b420e7d8 2.4.0 2019-10-14 16:28:14 +08:00
tanghc
89be4288a7 支持限流持续时间 2019-10-14 16:27:00 +08:00
tanghc
f5b5a1286f 2.3.2 2019-10-10 12:09:14 +08:00
tanghc
3925568bea 2.3.2 2019-10-10 12:04:28 +08:00
tanghc
fe0d348b41 spring cloud gateway支持restful调用 2019-10-10 12:01:13 +08:00
tanghc
2f4c46dc16 2.3.1 2019-10-10 09:14:48 +08:00
tanghc
78c93578d9 2.3.1 2019-10-09 18:31:59 +08:00
tanghc
0cc8c0b991 restful支持@PathVariable 2019-10-09 18:27:43 +08:00
tanghc
caaff21876 2.3.0 2019-10-08 16:35:04 +08:00
tanghc
18841b199e 2.3.0 2019-10-08 16:24:09 +08:00
tanghc
3871132b55 2.3.0 2019-10-08 16:05:32 +08:00
tanghc
41386f6996 支持传统web开发 2019-10-08 15:44:47 +08:00
tanghc
ae40a868d2 支持传统web开发 2019-10-08 15:44:28 +08:00
tanghc
d85a09ef11 2.2.0 2019-09-30 15:42:53 +08:00
tanghc
b4b48fc482 2.2.0 2019-09-30 14:33:28 +08:00
tanghc
60bde25c23 2.2.0 2019-09-30 10:28:37 +08:00
tanghc
a101b5e5a8 Merge branch 'eureka' into fit-eureka 2019-09-30 10:24:04 +08:00
tanghc
1c78bdcc02 2.2.0 2019-09-30 10:23:51 +08:00
tanghc
f939fef1fa 适配eureka 2019-09-30 10:22:35 +08:00
tanghc
8f6a76f4e4 Merge branch 'eureka' into fit-eureka 2019-09-30 10:09:11 +08:00
tanghc
7c4a92a88c 适配eureka 2019-09-30 10:08:57 +08:00
tanghc
c014765c8d Merge branch 'eureka' into fit-eureka 2019-09-29 19:12:14 +08:00
tanghc
a65d9dd501 适配eureka 2019-09-29 19:11:53 +08:00
tanghc
2e6dca1467 适配eureka 2019-09-29 19:10:22 +08:00
tanghc
68e80ba984 Merge branch 'eureka' into fit-eureka 2019-09-29 19:02:52 +08:00
tanghc
c0fb37255a 适配eureka 2019-09-29 19:02:35 +08:00
tanghc
d6756b7f88 Merge branch 'eureka' into fit-eureka 2019-09-29 11:30:47 +08:00
tanghc
3e506b27ef 适配eureka 2019-09-29 11:23:53 +08:00
tanghc
b94b48eb60 Merge branch 'eureka' into fit-eureka 2019-09-29 11:07:57 +08:00
tanghc
ebae593ab6 适配eureka 2019-09-29 10:59:53 +08:00
tanghc
77017cdd01 适配eureka 2019-09-29 09:42:19 +08:00
tanghc
c5d36a8200 适配eureka 2019-09-27 20:15:51 +08:00
tanghc
35253be77d 适配eureka 2019-09-27 20:06:52 +08:00
tanghc
be0adc0a8e 适配eureka 2019-09-26 20:01:35 +08:00
tanghc
51ca5ba319 2.1.3 2019-09-25 17:13:07 +08:00
tanghc
bfe09e26a6 2.1.3 2019-09-24 19:46:42 +08:00
tanghc
64c049912b 2.1.3 2019-09-24 19:35:46 +08:00
tanghc
fb7b659950 优化文件上传校验 2019-09-24 19:34:32 +08:00
tanghc
14cf242722 2.1.2 2019-09-19 15:26:15 +08:00
tanghc
298a684bd6 2.1.2 2019-09-19 09:53:23 +08:00
tanghc
6ab5b50a80 2.1.2 2019-09-18 10:49:28 +08:00
tanghc
3dc11f0e20 2.1.2 2019-09-18 10:34:54 +08:00
tanghc
0f04d86432 2.1.2 2019-09-18 10:30:33 +08:00
tanghc
74966e1f91 2.1.2 2019-09-16 17:19:50 +08:00
tanghc
fc1743242f 2.1.2 2019-09-16 17:18:16 +08:00
tanghc
1500237b6e 2.1.2 2019-09-16 17:14:56 +08:00
tanghc
7d2b7219be 2.1.2 2019-09-16 17:14:42 +08:00
tanghc
1cc0393043 2.1.2 2019-09-16 17:08:42 +08:00
tanghc
20c0ba9724 2.1.2 2019-09-16 16:44:56 +08:00
tanghc
3522269626 可自定义路由拉取url 2019-09-16 16:35:03 +08:00
tanghc
fcf4b6362d 可自定义路由拉取url 2019-09-16 15:57:41 +08:00
tanghc
ab7b0bd4c0 可自定义路由拉取url 2019-09-16 12:05:05 +08:00
tanghc
5c77e0030c 2.1.1 2019-09-12 15:48:50 +08:00
tanghc
2698827ba0 2.1.1 2019-09-12 15:33:51 +08:00
tanghc
99fd427eaa 修复springmvc路由获取问题 2019-09-12 15:32:56 +08:00
tanghc
9d6d24bd5b 优化打印日志 2019-09-12 10:42:08 +08:00
tanghc
c2b8c0a617 优化打印日志 2019-09-12 10:40:34 +08:00
tanghc
e3ff576268 2.1.0 2019-09-11 10:41:14 +08:00
tanghc
cb03f5a554 2.1.0 2019-09-11 09:40:35 +08:00
tanghc
d32d3931a1 2.1.0 2019-09-10 15:51:29 +08:00
tanghc
b859e8b88f 2.1.0 2019-09-10 09:12:48 +08:00
tanghc
3021345dd6 2.1.0 2019-09-10 09:11:27 +08:00
tanghc
e62c6ee9a3 2.1.0 2019-09-09 18:42:47 +08:00
tanghc
d4db7242c3 2.1.0 2019-09-09 12:31:32 +08:00
tanghc
d0eefd5ef0 2.1.0 2019-09-09 09:24:05 +08:00
tanghc
ab8f87d043 2.1.0 2019-09-06 19:49:12 +08:00
tanghc
603e2b7dc6 升级fastjson到1.2.60 2019-09-06 19:47:17 +08:00
tanghc
2626b05897 支持分布式限流 2019-09-06 19:46:36 +08:00
tanghc
de50c4dd5a 支持分布式限流 2019-09-06 19:46:14 +08:00
tanghc
f6bdc25ea2 升级fastjson到1.2.60 2019-09-06 11:24:50 +08:00
tanghc
4827ff3a99 2.0.0 2019-09-05 10:27:01 +08:00
tanghc
afe3ae59e4 2.0.0 2019-09-05 10:12:59 +08:00
tanghc
c5d2b88922 2.0.0 2019-09-05 10:11:12 +08:00
tanghc
5c1c174c8b 2.0.0 2019-09-04 10:43:40 +08:00
tanghc
097cc04514 2.0.0 2019-09-04 10:21:52 +08:00
tanghc
6f880a3a51 Merge remote-tracking branch 'origin/only-nacos'
# Conflicts:
#	doc/docs/_sidebar.md
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/HttpTool.java
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/RouteDefinition.java
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ServiceInfo.java
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/bean/ServiceInstance.java
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/RegistryService.java
#	sop-admin/sop-admin-server/src/main/java/com/gitee/sop/adminserver/service/impl/RegistryServiceNacosImpl.java
#	sop-admin/sop-admin-server/src/main/resources/public/static/css/app.c6dfb7ee.css
#	sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-2c1f2e8f.0314067f.css
#	sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-4de1c2b6.a37cd815.css
#	sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-510c5a69.5e48e29a.css
#	sop-admin/sop-admin-server/src/main/resources/public/static/css/chunk-c3ce42fe.6b789903.css
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d2085ef.2e46d1f4.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-2d221c34.0db10350.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-4de1c2b6.0188bd8f.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-510c5a69.c3dd05bb.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-6f78c9fe.bec8af48.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-9f479afe.6b795525.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-elementUI.298ac98c.js
#	sop-admin/sop-admin-server/src/main/resources/public/static/js/chunk-libs.75deb05f.js
#	sop-auth/.gitignore
#	sop-auth/pom.xml
#	sop-auth/readme.md
#	sop-auth/src/main/java/com/gitee/sop/sopauth/SopAuthApplication.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/AccessToken.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/AppIdManager.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/FetchTokenParam.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/FetchTokenResult.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/OAuth2Config.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/OAuth2Manager.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/OAuth2Service.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/OpenUser.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/RefreshToken.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/TokenPair.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/exception/LoginErrorException.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/impl/AppIdManagerImpl.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/impl/OAuth2ManagerCache.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/impl/OAuth2ManagerRedis.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/auth/impl/OAuth2ServiceImpl.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/config/OpenServiceConfig.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/controller/CallbackController.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/controller/OAuth2Controller.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/entity/IsvInfo.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/entity/UserInfo.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/mapper/IsvInfoMapper.java
#	sop-auth/src/main/java/com/gitee/sop/sopauth/mapper/UserInfoMapper.java
#	sop-auth/src/main/resources/application.properties
#	sop-auth/src/main/resources/templates/oauth2login.html
#	sop-auth/src/test/java/com/gitee/sop/sopauth/RefreshTokenTest.java
#	sop-auth/src/test/java/com/gitee/sop/sopauth/SopAuthApplicationTests.java
#	sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/GatewayFilterDefinition.java
#	sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/RouteDefinition.java
#	sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreEnvGrayFilter.java
#	sop-example/sop-easyopen/src/main/resources/application.properties
#	sop-example/sop-story/sop-story-web/src/main/java/com/gitee/sop/storyweb/controller/result/FileUploadResult.java
#	sop-website/.gitignore
#	sop-website/src/main/java/com/gitee/sop/websiteserver/WebsiteServerApplication.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocInfo.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocItem.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocModule.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocParameter.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/DocParserContext.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/EurekaApplication.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/EurekaApplications.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/EurekaApps.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/EurekaInstance.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/bean/EurekaUri.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/config/CorsConfig.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/config/WebsiteConfig.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/controller/DocController.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/controller/SandboxController.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/manager/DocManager.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/manager/DocParser.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/manager/EasyopenDocParser.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/manager/SwaggerDocParser.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/sign/AlipayApiException.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/sign/AlipayConstants.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/sign/AlipaySignature.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/sign/StreamUtil.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/sign/StringUtils.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/util/UploadUtil.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/vo/DocBaseInfoVO.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/vo/DocInfoVO.java
#	sop-website/src/main/java/com/gitee/sop/websiteserver/vo/ServiceInfoVO.java
#	sop-website/src/main/resources/api.json
#	sop-website/src/main/resources/public/assets/css/global.css
#	sop-website/src/main/resources/public/assets/image/auth.png
#	sop-website/src/main/resources/public/assets/js/format.js
#	sop-website/src/main/resources/public/assets/js/inputcache.js
#	sop-website/src/main/resources/public/assets/lib/jquery/3.2.1/jquery.min.js
#	sop-website/src/main/resources/public/assets/lib/layui/css/layui.css
#	sop-website/src/main/resources/public/assets/lib/layui/css/layui.mobile.css
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/code.css
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/laydate/default/laydate.css
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/layer/default/icon-ext.png
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/layer/default/icon.png
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/layer/default/layer.css
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/layer/default/loading-0.gif
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/layer/default/loading-1.gif
#	sop-website/src/main/resources/public/assets/lib/layui/css/modules/layer/default/loading-2.gif
#	sop-website/src/main/resources/public/assets/lib/layui/font/iconfont.eot
#	sop-website/src/main/resources/public/assets/lib/layui/font/iconfont.svg
#	sop-website/src/main/resources/public/assets/lib/layui/font/iconfont.ttf
#	sop-website/src/main/resources/public/assets/lib/layui/font/iconfont.woff
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/0.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/1.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/10.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/11.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/12.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/13.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/14.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/15.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/16.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/17.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/18.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/19.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/2.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/20.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/21.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/22.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/23.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/24.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/25.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/26.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/27.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/28.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/29.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/3.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/30.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/31.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/32.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/33.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/34.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/35.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/36.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/37.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/38.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/39.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/4.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/40.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/41.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/42.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/43.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/44.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/45.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/46.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/47.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/48.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/49.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/5.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/50.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/51.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/52.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/53.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/54.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/55.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/56.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/57.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/58.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/59.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/6.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/60.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/61.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/62.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/63.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/64.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/65.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/66.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/67.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/68.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/69.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/7.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/70.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/71.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/8.gif
#	sop-website/src/main/resources/public/assets/lib/layui/images/face/9.gif
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/carousel.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/code.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/colorpicker.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/element.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/flow.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/form.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/jquery.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/laydate.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/layedit.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/layer.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/laypage.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/laytpl.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/mobile.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/rate.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/slider.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/table.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/tree.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/upload.js
#	sop-website/src/main/resources/public/assets/lib/layui/lay/modules/util.js
#	sop-website/src/main/resources/public/assets/lib/layui/layui.all.js
#	sop-website/src/main/resources/public/assets/lib/layui/layui.js
#	sop-website/src/main/resources/public/assets/lib/layuiext/Form.js
#	sop-website/src/main/resources/public/assets/lib/layuiext/module/treetable-lay/treetable.css
#	sop-website/src/main/resources/public/assets/lib/layuiext/module/treetable-lay/treetable.js
#	sop-website/src/main/resources/public/config/config.js
#	sop-website/src/main/resources/public/index.html
#	sop-website/src/main/resources/public/pages/doc/auth.html
#	sop-website/src/main/resources/public/pages/doc/code.html
#	sop-website/src/main/resources/public/pages/doc/doc.html
#	sop-website/src/main/resources/public/pages/doc/doc.js
#	sop-website/src/main/resources/public/pages/doc/docEvent.js
#	sop-website/src/main/resources/public/pages/doc/sign.html
#	sop-website/src/main/resources/public/pages/sandbox/sandbox.html
#	sop-website/src/main/resources/public/pages/sandbox/sandbox.js
#	sop-website/src/test/java/com/gitee/sop/websiteserver/WebsiteServerApplicationTests.java
2019-09-04 10:09:13 +08:00
tanghc
36ee797ea6 2.0.0 2019-09-04 09:43:42 +08:00
tanghc
4cbb92cf27 2.0 2019-09-04 08:56:44 +08:00
tanghc
bdb4446758 2.0 2019-09-03 21:39:24 +08:00
tanghc
a4f7527716 2.0 2019-09-03 16:04:17 +08:00
tanghc
c68f071847 2.0 2019-09-03 16:03:50 +08:00
tanghc
5b53d97b26 2.0 2019-09-03 14:35:17 +08:00
tanghc
1b30e5ae97 2.0 2019-09-03 12:00:14 +08:00
tanghc
efaf35ea7c 2.0 2019-09-02 20:16:19 +08:00
tanghc
5b2b9e4c57 2.0 2019-09-02 20:14:09 +08:00
tanghc
e47cd0e002 2.0 2019-09-02 19:37:22 +08:00
tanghc
0cafb5829b 2.0 2019-09-02 16:48:14 +08:00
tanghc
9fa4407091 2.0 2019-09-02 15:57:37 +08:00
tanghc
77aea2256d 2.0 2019-09-02 15:57:04 +08:00
tanghc
c19686d003 2.0 2019-09-02 14:35:13 +08:00
tanghc
ab884b3618 2.0 2019-09-02 13:52:18 +08:00
tanghc
77f6b5e4a5 2.0 2019-09-02 10:38:03 +08:00
tanghc
63775525cb 2.0 2019-09-02 10:14:53 +08:00
tanghc
ab21e1f9eb 2.0 2019-08-30 20:00:49 +08:00
tanghc
d4ec362a07 2.0 2019-08-30 20:00:18 +08:00
tanghc
a994392e5f 2.0 2019-08-30 19:52:34 +08:00
tanghc
b32b2300b0 2.0 2019-08-30 19:08:25 +08:00
tanghc
e101358673 2.0 2019-08-30 18:34:16 +08:00
tanghc
9429d32f42 2.0 2019-08-30 17:39:15 +08:00
tanghc
1ab8e22885 2.0 2019-08-30 08:51:43 +08:00
tanghc
c240a6337a 2.0 2019-08-29 17:16:35 +08:00
tanghc
cf28d4eab4 2.0 2019-08-29 17:03:27 +08:00
tanghc
ec32e8b39f 2.0 2019-08-29 14:42:39 +08:00
tanghc
84b31313bf 2.0 2019-08-29 13:02:32 +08:00
tanghc
d19e4a79e9 2.0 2019-08-29 12:07:49 +08:00
tanghc
0ecc8cfb89 2.0 2019-08-29 11:27:56 +08:00
tanghc
7e3c40ed92 2.0 2019-08-29 11:04:59 +08:00
tanghc
3b1917428a 2.0 2019-08-28 17:16:30 +08:00
tanghc
84b3bcbb04 2.0 2019-08-28 16:03:28 +08:00
tanghc
f123472912 2.0 2019-08-28 15:06:02 +08:00
tanghc
691d642f26 2.0 2019-08-27 17:33:07 +08:00
tanghc
6c9f5528f2 2.0 2019-08-27 17:29:02 +08:00
tanghc
ba7f9a4e4d 2.0 2019-08-27 17:03:57 +08:00
tanghc
c217028521 2.0 2019-08-27 14:34:32 +08:00
tanghc
2969f1738a 2.0 2019-08-27 14:33:42 +08:00
tanghc
cf3f3a7b0d 2.0 2019-08-27 14:15:32 +08:00
tanghc
045e8cdaba 2.0 2019-08-27 13:32:54 +08:00
tanghc
aaa5a86977 2.0 2019-08-26 17:36:23 +08:00
tanghc
e839692da4 2.0 2019-08-26 17:34:45 +08:00
tanghc
6408f0e7d2 2.0 2019-08-26 17:22:42 +08:00
tanghc
0966784976 2.0 2019-08-26 14:58:20 +08:00
tanghc
51c4c7a82d 2.0 2019-08-26 14:13:46 +08:00
tanghc
45f3eb8f89 2.0 2019-08-26 12:45:37 +08:00
tanghc
3446a32bdf 2.0 2019-08-26 10:50:10 +08:00
tanghc
7d5d6ed3e3 2.0 2019-08-23 16:18:45 +08:00
tanghc
90fdbbccf2 2.0 2019-08-23 15:29:11 +08:00
tanghc
bbd4e55c6a 2.0 2019-08-23 13:52:05 +08:00
tanghc
555ba667bf 2.0 2019-08-23 10:21:59 +08:00
tanghc
a02ec8618c 2.0 2019-08-23 09:15:18 +08:00
tanghc
39c2f1a1c2 2.0 2019-08-23 09:12:56 +08:00
tanghc
be4868ba01 2.0 2019-08-22 20:15:19 +08:00
tanghc
693f069c48 2.0 2019-08-22 20:11:08 +08:00
tanghc
bffc5b7e00 2.0 2019-08-22 19:25:53 +08:00
tanghc
9caf70e267 2.0 2019-08-22 19:10:07 +08:00
tanghc
1cae82176d 2.0 2019-08-22 17:15:12 +08:00
tanghc
299195e9a1 2.0 2019-08-22 17:08:25 +08:00
tanghc
bb19a34444 2.0 2019-08-22 14:05:31 +08:00
tanghc
b6c60f48a2 2.0 2019-08-22 14:03:25 +08:00
tanghc
63ebdce4a8 2.0 2019-08-22 11:37:07 +08:00
tanghc
75800d0ca2 2.0 2019-08-22 11:32:19 +08:00
tanghc
c5c43b3be4 2.0 2019-08-22 11:31:08 +08:00
tanghc
26f7d2843e 2.0 2019-08-22 11:25:22 +08:00
tanghc
9194482522 2.0 2019-08-21 20:52:48 +08:00
tanghc
0496b70ec5 2.0 2019-08-21 20:16:46 +08:00
tanghc
02c53920a4 2.0 2019-08-21 18:03:33 +08:00
tanghc
ef51fe7667 全面使用nacos,舍弃zookeeper 2019-08-21 18:01:08 +08:00
tanghc
e1bfbbb645 支持easyopen 2019-08-21 17:59:33 +08:00
tanghc
6d240ef243 支持easyopen 2019-08-21 17:58:53 +08:00
tanghc
6e2a0e6c13 全面使用nacos,舍弃zookeeper 2019-08-21 16:04:32 +08:00
tanghc
90d6823693 全面使用nacos,舍弃zookeeper 2019-08-21 14:41:43 +08:00
tanghc
d2fab766c4 全面使用nacos,舍弃zookeeper 2019-08-21 13:55:18 +08:00
tanghc
c7451c84f9 全面使用nacos,舍弃zookeeper 2019-08-21 12:35:07 +08:00
tanghc
bf4b920e17 全面使用nacos,舍弃zookeeper 2019-08-21 11:58:23 +08:00
tanghc
219f944162 全面使用nacos,舍弃zookeeper 2019-08-20 19:17:23 +08:00
tanghc
55e5a7e795 Merge branch 'master' into registry-nacos 2019-08-19 13:41:00 +08:00
tanghc
6fc6d9cea3 Merge branch 'master' into registry-nacos 2019-08-16 14:51:26 +08:00
tanghc
121c4da23b Merge branch 'master' into registry-nacos 2019-08-15 18:02:19 +08:00
tanghc
1717a8ab4f Merge branch 'master' into registry-nacos 2019-08-15 14:52:57 +08:00
tanghc
12a3cec8a3 Merge branch 'master' into registry-nacos 2019-08-14 17:42:29 +08:00
tanghc
16e56a93e3 Merge branch 'master' into registry-nacos 2019-08-14 16:13:00 +08:00
tanghc
d13fe50773 Merge branch 'master' into registry-nacos 2019-08-14 15:37:39 +08:00
tanghc
8e54d86606 Merge branch 'master' into registry-nacos 2019-08-14 14:19:58 +08:00
tanghc
a16e9df6a5 Merge branch 'master' into registry-nacos 2019-08-14 14:16:30 +08:00
tanghc
2f20184edd Merge branch 'master' into registry-nacos 2019-08-14 09:49:59 +08:00
tanghc
ae69b02a0f Merge branch 'master' into registry-nacos 2019-08-14 09:09:16 +08:00
tanghc
18fac20ffd Merge branch 'master' into registry-nacos 2019-08-13 15:34:19 +08:00
tanghc
9b8a176491 Merge branch 'master' into registry-nacos 2019-08-12 19:36:03 +08:00
tanghc
62f49eb404 Merge branch 'develop' into registry-nacos 2019-08-09 17:32:20 +08:00
tanghc
3a2d591005 admin服务列表在线靠前 2019-08-09 17:08:47 +08:00
tanghc
d166e425c0 Merge branch 'develop' into registry-nacos 2019-08-09 16:30:06 +08:00
tanghc
0be8a83d07 Merge branch 'master' into registry-nacos 2019-08-07 17:12:57 +08:00
tanghc
6cca0a7e5e Merge branch 'master' into registry-nacos 2019-08-07 16:26:13 +08:00
tanghc
4bfc70065d Merge branch 'master' into registry-nacos 2019-08-07 16:21:50 +08:00
tanghc
68e0cc96c5 Merge branch 'master' into registry-nacos 2019-08-07 15:44:01 +08:00
tanghc
c5ce01208f Merge branch 'master' into registry-nacos 2019-08-07 15:18:20 +08:00
tanghc
734265601c Merge branch 'master' into registry-nacos 2019-08-07 10:00:00 +08:00
tanghc
f244575976 Merge branch 'master' into registry-nacos 2019-07-29 20:08:43 +08:00
tanghc
c263180812 Merge branch 'master' into registry-nacos 2019-07-29 15:25:22 +08:00
tanghc
d21bbfaa21 Merge branch 'master' into registry-nacos 2019-07-29 11:53:31 +08:00
tanghc
753fbc651a Merge branch 'master' into registry-nacos 2019-07-29 11:29:51 +08:00
tanghc
01c4fda639 Merge branch 'master' into registry-nacos 2019-07-28 10:56:19 +08:00
tanghc
2d5a65e525 Merge branch 'master' into registry-nacos 2019-07-26 17:36:38 +08:00
tanghc
47f621837a Merge branch 'master' into registry-nacos 2019-07-26 12:23:33 +08:00
tanghc
e5a49846ce Merge branch 'master' into registry-nacos 2019-07-25 21:01:56 +08:00
tanghc
49fb6bf15f Merge branch 'master' into registry-nacos 2019-07-25 20:34:58 +08:00
tanghc
6fc25b5434 Merge branch 'master' into registry-nacos 2019-07-25 14:06:57 +08:00
tanghc
05db438b9f Merge branch 'master' into registry-nacos 2019-07-24 18:55:17 +08:00
tanghc
7a7a3b7c8c Merge branch 'master' into registry-nacos 2019-07-24 18:46:36 +08:00
tanghc
3e49780fa2 Merge branch 'master' into registry-nacos 2019-07-24 17:05:33 +08:00
tanghc
8d9debbc2d Merge branch 'master' into registry-nacos 2019-07-21 20:30:57 +08:00
tanghc
fb4108e980 Merge branch 'master' into registry-nacos 2019-07-19 20:16:39 +08:00
tanghc
0f1c7e4d2a Merge branch 'master' into registry-nacos 2019-07-19 10:22:31 +08:00
tanghc
ef28db6a1d Merge branch 'master' into registry-nacos
# Conflicts:
#	sop-gateway/src/main/resources/application-dev.properties
2019-07-19 10:14:32 +08:00
tanghc
7c90239ef3 Merge branch 'master' into registry-nacos 2019-07-18 17:44:12 +08:00
tanghc
167d0a77f7 配置文件优化 2019-07-18 15:28:48 +08:00
tanghc
fce0b4d242 Merge branch 'develop' into registry-nacos 2019-07-18 14:34:38 +08:00
tanghc
7a97b0ff9d Merge branch 'master' into registry-nacos 2019-07-16 08:46:09 +08:00
tanghc
306523511c Merge branch 'master' into registry-nacos 2019-07-13 15:29:33 +08:00
tanghc
d25e1de3d9 Merge branch 'master' into registry-nacos 2019-07-12 18:12:56 +08:00
tanghc
459f04a459 Merge branch 'master' into registry-nacos 2019-07-12 18:08:17 +08:00
tanghc
55cf0d5329 Merge branch 'master' into registry-nacos 2019-07-11 17:53:47 +08:00
tanghc
83627f1b2f Merge branch 'master' into registry-nacos 2019-07-11 16:47:49 +08:00
tanghc
9803c5133e Merge branch 'master' into registry-nacos 2019-07-10 17:54:48 +08:00
tanghc
bf5b1f37aa Merge branch 'master' into registry-nacos 2019-07-10 17:38:34 +08:00
tanghc
ee9d8ba240 Merge branch 'master' into registry-nacos 2019-07-10 11:57:16 +08:00
tanghc
d9bd18f72e Merge branch 'master' into registry-nacos 2019-07-09 17:34:36 +08:00
tanghc
0910f0500f Merge branch 'develop' into registry-nacos 2019-07-08 09:35:13 +08:00
tanghc
e97facbc5b Merge branch 'develop' into registry-nacos 2019-07-05 09:29:23 +08:00
tanghc
2dd0f19328 Merge branch 'develop' into registry-nacos 2019-07-05 09:26:45 +08:00
tanghc
0341491dd5 Merge branch 'develop' into registry-nacos 2019-07-04 17:39:15 +08:00
tanghc
adb9d9fcf1 Merge branch 'develop' into registry-nacos 2019-07-02 14:56:35 +08:00
tanghc
dad2fa7de3 nacos 2019-07-02 14:06:38 +08:00
tanghc
6360604879 Merge branch 'develop' into registry-nacos
# Conflicts:
#	sop-gateway/src/main/resources/application-dev.yml
2019-07-02 12:06:50 +08:00
tanghc
0f46896306 update 2019-07-01 20:55:25 +08:00
tanghc
baa6289aa3 update 2019-07-01 17:53:12 +08:00
2587 changed files with 126623 additions and 56554 deletions

17
.gitignore vendored Normal file → Executable file
View File

@@ -1,4 +1,5 @@
/target/
target/
logs/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
@@ -8,7 +9,6 @@
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
@@ -17,10 +17,9 @@
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/
nbproject/private/
nbbuild/
dist/
nbdist/
.nb-gradle/
/local-config/

14
Dockerfile Executable file
View File

@@ -0,0 +1,14 @@
FROM java:8
VOLUME /tmp
VOLUME /sop
# 将所有应用放到一个镜像当中
ADD sop-gateway/target/*.jar sop/sop-gateway/sop-gateway.jar
ADD sop-admin/sop-admin-backend/backend-boot/target/*.jar sop/sop-admin/sop-admin.jar
ADD sop-example/example-story/target/*.jar sop/sop-story/sop-story.jar
# 拷贝启动脚本
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

215
README.md Normal file → Executable file
View File

@@ -1,91 +1,190 @@
# SOP(Simple Open Platform)
> 2.0版本正在开发中...
**当前版本为5.0**
一个开放平台解决方案项目基于Spring Cloud实现目标是能够让用户快速得搭建起自己的开放平台。
👉🏻 [开发文档](https://xcnm3jsc8anf.feishu.cn/wiki/IJygwHV5Wij9i9kZ2yEcTblbnPg)
---
一个开放平台解决方案项目基于dubbo实现目标让用户快速搭建自己的开放平台。
SOP提供了两种接口调用方式分别是[支付宝开放平台](https://docs.open.alipay.com/api)的调用方式和[淘宝开放平台](http://open.taobao.com/api.htm?docId=285&docType=2)的调用方式。
通过简单的配置后,你的项目就具备了和支付宝开放平台的一样的接口提供能力。
SOP封装了开放平台大部分功能包括签名验证、统一异常处理、统一返回内容 、业务参数验证JSR-303、秘钥管理等,未来还会实现更多功能
SOP封装了开放平台大部分功能包括签名验证、统一异常处理、统一返回内容 、业务参数验证JSR-303、秘钥管理、接口回调等。
## 项目特点
- 接入方式简单,与老项目不冲突,老项目注册到注册中心,然后在方法上加上注解即可
- 架构松耦合业务代码实现在各自微服务上SOP不参与业务实现这也是Spring Cloud微服务体系带来的好处
- 扩展简单,开放平台对应的功能各自独立,可以自定义实现自己的需求,如:更改参数,更改签名规则等。
+ 接入方式简单,与老项目不冲突,老项目注册到注册中心,然后在方法上加上注解即可。
+ 架构松耦合业务代码实现在各自微服务上SOP不参与业务实现这也是dubbo微服务体系带来的好处
+ 扩展简单,开放平台对应的功能各自独立,可以自定义实现自己的需求,如:更改参数,更改签名规则等
## 谁可以使用这个项目
- 有现成的项目,想改造成开放平台供他人调用
- 有现成的项目,想暴露其中几个接口并通过开放平台供他人调用
- 想搭一个开放平台新项目,并结合微服务的方式去维护
- 对开放平台感兴趣的朋友
+ 有现成的项目,想改造成开放平台供他人调用
+ 有现成的项目,想暴露其中几个接口并通过开放平台供他人调用
+ 想搭一个开放平台新项目,并结合微服务的方式去维护
+ 对开放平台感兴趣的朋友
以上情况都可以考虑使用SOP
## 架构图
## 例子
开放接口定义
![架构图](https://images.gitee.com/uploads/images/2019/0610/183127_408bc054_332975.png "sop.png")
## 已完成列表
```java
/**
* 支付接口
*
* @author 六如
*/
public interface OpenPayment {
- 签名验证
- 统一异常处理
- 统一返回内容
- session管理
- 秘钥管理
- 微服务端自动验证JSR-303
- 支持Spring Cloud Gateway
- Admin管理平台统一管理微服务配置管理路由管理微服务上下线
- 接入方管理+秘钥管理
- 接口权限分配
- 文件上传
- SDK
- 接口限流
- 文档整合
- 应用授权
- 监控日志
- 支持nacos
- 网关动态修改参数
/**
* 手机网站支付接口
*
* @apiNote 该接口是页面跳转接口,用于生成用户访问跳转链接。
* 请在服务端执行SDK中pageExecute方法读取响应中的body()结果。
* 该结果用于跳转到页面,返回到用户浏览器渲染或重定向跳转到页面。
* 具体使用方法请参考 <a href="https://torna.cn" target="_blank">接入指南</a>
*/
@Open("pay.trade.wap.pay")
PayTradeWapPayResponse tradeWapPay(PayTradeWapPayRequest request);
## 界面预览
}
```
![服务列表](https://images.gitee.com/uploads/images/2019/0711/174825_2856281f_332975.png "admin_servicelist.png")
![路由管理](https://images.gitee.com/uploads/images/2019/0711/174843_1648591c_332975.png "admin_route.png")
![限流管理](https://images.gitee.com/uploads/images/2019/0711/174900_9315cc8e_332975.png "admin_limit.png")
接口实现
![秘钥信息](https://images.gitee.com/uploads/images/2019/0711/174921_bd817533_332975.png "admin_key.png")
```java
/**
* 开放接口实现
*
* @author 六如
*/
@DubboService(validation = "true")
public class OpenPaymentImpl implements OpenPayment {
![API文档](https://images.gitee.com/uploads/images/2019/0711/174939_97886883_332975.png "website_doc.png")
@Override
public PayTradeWapPayResponse tradeWapPay(PayTradeWapPayRequest request) {
PayTradeWapPayResponse payTradeWapPayResponse = new PayTradeWapPayResponse();
payTradeWapPayResponse.setPageRedirectionData(UUID.randomUUID().toString());
return payTradeWapPayResponse;
}
}
![沙箱环境](https://images.gitee.com/uploads/images/2019/0711/175226_3f69346a_332975.png "website_sandbox.png")
```
## 工程说明
调用:
> 运行环境JDK8Maven3Zookeeper
```java
@Test
public void testGet() throws Exception {
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
params.put("method", "pay.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", "1.0");
// 业务参数
Map<String, Object> bizContent = new HashMap<>();
bizContent.put("outTradeNo", "70501111111S001111119");
bizContent.put("totalAmount", "9.00");
bizContent.put("subject", "衣服");
bizContent.put("productCode", "QUICK_WAP_WAY");
params.put("biz_content", JSON.toJSONString(bizContent));
String content = AlipaySignature.getSignContent(params);
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
params.put("sign", sign);
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 = postJson(url, params);// 发送请求
System.out.println(responseData);
}
```
- doc开发文档
- sop-admin后台管理
- sop-registry注册中心eureka实现
- sop-gateway网关统一访问入口Spring Cloud Zuul实现可切换成Spring Cloud Gateway
- sop-common公共模块封装常用功能包含签名校验、错误处理、限流等功能
- sop-example微服务示例含springboot,springmvc示例
- sop-sdk基础sdk含Java、C#版本
- sop-test接口调用测试用例
- sop-website开放平台对应网站提供文档API、沙箱测试等内容
SDK调用
```java
@Test
public void test() {
PayTradeWapPayRequest request = new PayTradeWapPayRequest();
PayTradeWapPayModel model = new PayTradeWapPayModel();
model.setOutTradeNo("70501111111S001111119");
model.setTotalAmount(new BigDecimal("1000"));
model.setSubject("衣服");
model.setProductCode("QUICK_WAP_WAY");
request.setBizModel(model);
Result<PayTradeWapPayResponse> result = client.execute(request);
if (result.isSuccess()) {
PayTradeWapPayResponse response = result.getData();
System.out.println(response);
} else {
System.out.println(result);
}
}
```
## 功能实现
- [x] 签名验签
- [x] 秘钥管理
- [x] 国际化
- [x] 异常处理
- [x] 文件上传/下载
- [x] 文档管理
- [x] 回调处理
- [x] 自定义拦截器
- [x] SDK
- [x] C++ SDK
- [x] C# SDK
- [x] Go SDK
- [x] Java SDK
- [x] Nodejs SDK
- [x] Python SDK
- [x] Rust SDK
## 整体架构
![整体架构](./asset/arc.jpg)
## 分支说明
- develop日常开发分支
- registry-nacosnacos作为注册中心
- SpringCloudGatewaySpringCloudGateway作为网关
- master发布分支
- develop开发分支从master衍生
- pr接收PR合并分支从master衍生
## 相关文档
## 页面预览
[开发文档](http://durcframework.gitee.io/sop)
- 文档页面
<img src="./asset/sop_doc.png" />
- 后台管理-文档管理
<img src="./asset/sop_admin_doc.jpg" />
- 后台管理-秘钥管理
<img src="./asset/sop_admin_secret.jpg" />
- 后台管理-用户管理
<img src="./asset/sop_admin_user.jpg" />
## 沟通交流
Q群328419269
<img src="./asset/sop_qqgroup.jpg" width="50%" height="50%" />

BIN
asset/arc.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
asset/sop_admin_doc.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
asset/sop_admin_secret.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
asset/sop_admin_user.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
asset/sop_doc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
asset/sop_qqgroup.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

51
build-admin.sh Executable file
View File

@@ -0,0 +1,51 @@
# 构建admin, 结果输出在dist/sop-admin目录
# 获取当前路径并赋值给变量 current_path
current_path=$(pwd)
# 打印变量的值,以验证赋值是否成功
echo "当前路径是: $current_path"
# 构建目录
dist_dir="dist"
# 服务端文件夹名称
# 执行文件名称
app_name="sop-admin"
version="5.0"
build_folder="${app_name}-${version}"
# 输出目录
target_dir="$dist_dir/${build_folder}"
server_source=sop-admin/sop-admin-backend/admin-boot
# admin前端路径
front_source=sop-admin/sop-admin-frontend
# ------ 构建前端 ------
echo "开始构建sop-admin前端..."
cd $front_source
sh build.sh
cd $current_path
# ------ 构建后端 ------
echo "开始构建sop-admin服务端..."
mvn clean package -pl $server_source -am -DskipTests
# ------ 复制文件 ------
if [ ! -d "$target_dir" ]; then
mkdir -p $target_dir
fi
rm -rf ${target_dir}/*
# 复制前端资源
echo "复制前端文件到$target_dir"
cp -r ${front_source}/dist ./$target_dir
# 复制服务端资源
cp -r ${server_source}/target/*.jar $target_dir
cp -r script/* $target_dir
cp -r ${server_source}/src/main/resources/application-test.properties $target_dir/application.properties
echo "服务端构建完毕,构建结果在${target_dir}文件夹下"

39
build-gateway.sh Normal file
View File

@@ -0,0 +1,39 @@
# 构建网关
# 获取当前路径并赋值给变量 current_path
current_path=$(pwd)
# 打印变量的值,以验证赋值是否成功
echo "当前路径是: $current_path"
# 构建目录
dist_dir="dist"
# 服务端文件夹名称
# 执行文件名称
app_name="sop-gateway"
version="5.0"
build_folder="${app_name}-${version}"
# 输出目录
target_dir="$dist_dir/${build_folder}"
server_source=sop-gateway
# ------ 构建后端 ------
echo "开始构建sop-gateway..."
mvn clean package -pl $server_source -am -DskipTests
# ------ 复制文件 ------
if [ ! -d "$target_dir" ]; then
mkdir -p $target_dir
fi
rm -rf ${target_dir}/*
# 复制服务端资源
cp -r ${server_source}/target/*.jar $target_dir
cp -r script/* $target_dir
cp -r ${server_source}/src/main/resources/application-test.properties $target_dir/application.properties
echo "服务端构建完毕,构建结果在${target_dir}文件夹下"

51
build-website.sh Executable file
View File

@@ -0,0 +1,51 @@
# 构建admin, 结果输出在dist/sop-admin目录
# 获取当前路径并赋值给变量 current_path
current_path=$(pwd)
# 打印变量的值,以验证赋值是否成功
echo "当前路径是: $current_path"
# 构建目录
dist_dir="dist"
# 服务端文件夹名称
# 执行文件名称
app_name="sop-website"
version="5.0"
build_folder="${app_name}-${version}"
# 输出目录
target_dir="$dist_dir/${build_folder}"
server_source=sop-website/sop-website-backend/website-boot
# admin前端路径
front_source=sop-website/sop-website-frontend
# ------ 构建前端 ------
echo "开始构建sop-website前端..."
cd $front_source
sh build.sh
cd $current_path
# ------ 构建后端 ------
echo "开始构建sop-website服务端..."
mvn clean package -pl $server_source -am -DskipTests
# ------ 复制文件 ------
if [ ! -d "$target_dir" ]; then
mkdir -p $target_dir
fi
rm -rf ${target_dir}/*
# 复制前端资源
echo "复制前端文件到$target_dir"
cp -r ${front_source}/dist ./$target_dir
# 复制服务端资源
cp -r ${server_source}/target/*.jar $target_dir
cp -r script/* $target_dir
cp -r ${server_source}/src/main/resources/application-test.properties $target_dir/application.properties
echo "服务端构建完毕,构建结果在${target_dir}文件夹下"

175
changelog.md Normal file → Executable file
View File

@@ -1,152 +1,37 @@
# changelog
## 1.15.2
## 日常更新
- 优化SpringCloudGateway上传文件功能
- 优化SpringCloudGateway动态修改参数功能
- 2025-11-12优化签名验证算法
- 2025-11-05添加SDK示例返回List。详见com.gitee.sop.sdk.SdkTest.testList
- 2025-11-01添加回调处理。有升级SQL[sop-20251101.sql](./upgrade/sop-20251101.sql)
- 2025-09-12修复推送文档报找不到@Open注解问题
- 2025-08-29smart-doc升级到3.1.1
- 2025-08-17admin后台可关联商户;fastmybatis升级到3.1.7。有升级SQL[sop-20250817.sql](./upgrade/sop-20250817.sql)
- 2025-07-22: 修复当objClass被代理后获取不到interface BUG
- 2025-06-15新增帮助文档管理。有升级SQL[sop-20250615.sql](./upgrade/sop-20250615.sql)
- 2025-06-11java-sdk添加文件下载示例
- 2025-06-01OpenContext添加charset字段
- 2025-05-18修复网关registerAddress配置
- 2025-05-11
- 修复admin后台发布文档不生效问题
- 优化:业务服务启动不用依赖网关
- 2025-03-12优化dubbo filter
- 2025-03-09优先使用本地缓存
- 2025-03-06RouteContext新增isv对象
- 2025-03-05变更拦截器方法参数
- 2025-03-04拦截器新增init方法用来做一些初始化工作
- 2025-02-27新增token校验,com.gitee.sop.gateway.interceptor.internal.TokenValidateInterceptor.checkToken
- 2025-02-20修复Linux环境下启动报错加载i18n问题优化新增接口注册保存逻辑
- 2025-02-19升级fastmybatis到3.0.16
- 2025-02-09优化Restful接口校验
- 2025-02-07优化菜单排序
- 2025-02-04新增Restful模式
## 1.15.1
## 5.1
- 修复未配置正确MessageConverter导致的异常
接入smart-doc
## 1.15.0
## 5.0
- 优化预发布、灰度
- 网关动态修改请求参数
- 支持swagger-bootstrap插件
- 优化admin服务列表显示
- 优化文档刷新逻辑
- 新增测试all in one
- 修复中文乱码问题
## 1.14.0
- 支持预发布、灰度发布环境
## 1.13.7
- 修复修复context-path识别问题
## 1.13.6
- 修复@RequestBody不能绑定问题
## 1.13.5
- 修复postJson下version获取不到问题
## 1.13.4
- 修复admin服务列表最后更新时间不显示问题
- 优化上传路由配置逻辑
- 微服务可获得access_token, notify_url参数
## 1.13.3
- 优化参数绑定
## 1.13.2
- 修复json方式请求获取不到参数问题
- 微服务端新增获取开放平台请求参数
## 1.13.1
- 支持json方式请求application/json
- 支持传统web服务开发见文档`传统web开发`
## 1.13.0
- 新增IP黑名单
## 1.12.4
- 优化属性文件配置
- 新增sleuth接入文档
- admin的isv列表新增备注字段
## 1.12.3
- 修复删除zk节点导致的BUG
## 1.12.2
- 沙盒支持文件上传
## 1.12.1
- 修复重启网关路由状态重置BUG
- 优化SpringCloudGateway
## 1.12.0
- admin后台新增角色管理
- 支持nacos作为注册中心
## 1.11.0
- 秘钥管理改造
- 服务端返回sign
- 新增SDK返回sign处理
- 新增沙箱环境
## 1.10.0
- 新增监控日志
## 1.9.0
- 改造限流
- 增强参数绑定
## 1.8.0
- 支持文件上传
## 1.7.2
- 修复微服务参数绑定BUG
- Admin新增vue界面
## 1.7.1
- 支持接口名版本号放在url后面
## 1.7.0
- 可自定义数据节点名称
## 1.6.0
- 新增应用授权
## 1.5.0
- admin新增signType字段
- 修复easyopen接入无法访问BUG
## 1.4.0
- 新增文档分组显示
- 支持easyopen文档注解
- BUG修复
## 1.3.0
- 新增接口限流功能 [doc](http://durcframework.gitee.io/sop/#/files/10092_%E6%8E%A5%E5%8F%A3%E9%99%90%E6%B5%81?t=1555378655699)
- 新增文档整合功能 [doc](http://durcframework.gitee.io/sop/#/files/10041_%E7%BC%96%E5%86%99%E6%96%87%E6%A1%A3?t=1555378655698)
- 新增springmvc项目接入demo
## 1.2.0
- SOP Admin新增用户登录
- 新增基础SDK(Java,C#) [doc](http://durcframework.gitee.io/sop/#/files/10095_SDK%E5%BC%80%E5%8F%91?t=1554693919597)
## 1.1.0
- 新增ISV管理 [doc](http://durcframework.gitee.io/sop/#/files/10085_ISV%E7%AE%A1%E7%90%86?t=1554123435621)
- 新增接口授权 [doc](http://durcframework.gitee.io/sop/#/files/10090_%E8%B7%AF%E7%94%B1%E6%8E%88%E6%9D%83?t=1554123435621)
## 1.0.0
- 第一次发布
全面重构,欢迎体验:[文档](https://xcnm3jsc8anf.feishu.cn/wiki/IJygwHV5Wij9i9kZ2yEcTblbnPg)

176
checkstyle.xml Executable file
View File

@@ -0,0 +1,176 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<!-- 文件长度不超过1500行 -->
<module name="FileLength">
<property name="max" value="2500"/>
</module>
<!-- 长度检查 -->
<!-- 每行不超过200个字符 -->
<module name="LineLength">
<property name="max" value="400"/>
</module>
<module name="SuppressWarningsFilter" />
<!-- 每个java文件一个语法树 -->
<module name="TreeWalker">
<module name="SuppressWarningsHolder" />
<!-- import检查-->
<!-- 检查是否从非法的包中导入了类 -->
<module name="IllegalImport"/>
<!-- 检查是否导入了多余的包 -->
<module name="RedundantImport"/>
<!-- 没用的import检查比如1.没有被用到2.重复的3.import java.lang的4.import 与该类在同一个package的 -->
<module name="UnusedImports"/>
<!-- 注释检查 -->
<!-- 检查构造函数的javadoc -->
<module name="JavadocType">
<property name="allowUnknownTags" value="true"/>
<message key="javadoc.missing" value="类注释缺少Javadoc注释。"/>
</module>
<!-- 命名检查 -->
<!-- 局部的final变量包括catch中的参数的检查 -->
<module name="LocalFinalVariableName"/>
<!-- 局部的非final型的变量包括catch中的参数的检查 -->
<module name="LocalVariableName"/>
<!-- 包名的检查(只允许小写字母),默认^[a-z]+(\.[a-zA-Z_][a-zA-Z_0-9_]*)*$ -->
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern" value="包名 ''{0}'' 要符合 ''{1}''格式."/>
</module>
<!-- 仅仅是static型的变量不包括static final型的检查 -->
<module name="StaticVariableName"/>
<!-- Class或Interface名检查默认^[A-Z][a-zA-Z0-9]*$-->
<module name="TypeName">
<property name="severity" value="warning"/>
<message key="name.invalidPattern" value="名称 ''{0}'' 要符合 ''{1}''格式."/>
</module>
<!-- 非static型变量的检查
<module name="MemberName"/>
-->
<!-- 方法名的检查 -->
<module name="MethodName"/>
<!-- 方法的参数名
<module name="ParameterName "/>
-->
<!-- 常量名的检查(只允许大写),默认^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$ -->
<module name="ConstantName"/>
<!-- 定义检查 -->
<!-- 检查数组类型定义的样式 -->
<module name="ArrayTypeStyle"/>
<!-- 检查long型定义是否有大写的“L” -->
<module name="UpperEll"/>
<!-- 方法不超过100行 -->
<module name="MethodLength">
<property name="tokens" value="METHOD_DEF"/>
<property name="max" value="300"/>
</module>
<!-- 方法的参数个数不超过8个。 并且不对构造方法进行检查-->
<module name="ParameterNumber">
<property name="max" value="8"/>
<property name="ignoreOverriddenMethods" value="true"/>
<property name="tokens" value="METHOD_DEF"/>
</module>
<!-- 空格检查-->
<!-- 方法名后跟左圆括号"(" -->
<module name="MethodParamPad"/>
<!-- 在类型转换时,不允许左圆括号右边有空格,也不允许与右圆括号左边有空格 -->
<module name="TypecastParenPad"/>
<!-- 检查在某个特定关键字之后应保留空格 -->
<module name="NoWhitespaceAfter"/>
<!-- 检查在某个特定关键字之前应保留空格 -->
<module name="NoWhitespaceBefore"/>
<!-- 圆括号空白 -->
<module name="ParenPad"/>
<!-- 检查分隔符是否在空白之后 -->
<module name="WhitespaceAfter"/>
<!-- 检查分隔符周围是否有空白 -->
<module name="WhitespaceAround"/>
<!-- 修饰符检查 -->
<!-- 检查修饰符的顺序是否遵照java语言规范默认public、protected、private、abstract、static、final、transient、volatile、synchronized、native、strictfp -->
<module name="ModifierOrder"/>
<!-- 检查接口和annotation中是否有多余修饰符如接口方法不必使用public -->
<module name="RedundantModifier"/>
<!-- 代码块检查 -->
<!-- 检查是否有嵌套代码块 -->
<module name="AvoidNestedBlocks"/>
<!-- 检查是否有空代码块 -->
<module name="EmptyBlock"/>
<!-- 检查左大括号位置 -->
<module name="LeftCurly"/>
<!-- 检查代码块是否缺失{} -->
<module name="NeedBraces"/>
<!-- 检查右大括号位置 -->
<module name="RightCurly"/>
<!-- 代码检查 -->
<!-- 检查空的代码段 -->
<module name="EmptyStatement"/>
<!-- 检查在重写了equals方法后是否重写了hashCode方法 -->
<module name="EqualsHashCode"/>
<!-- 检查局部变量或参数是否隐藏了类中的变量 -->
<module name="HiddenField">
<property name="tokens" value="VARIABLE_DEF"/>
</module>
<!-- 检查子表达式中是否有赋值操作 -->
<module name="InnerAssignment"/>
<!-- 检查switch语句是否有default -->
<module name="MissingSwitchDefault"/>
<!-- 检查是否有过度复杂的布尔表达式 -->
<module name="SimplifyBooleanExpression"/>
<!-- 检查是否有过于复杂的布尔返回代码段 -->
<module name="SimplifyBooleanReturn"/>
<!-- 类设计检查 -->
<!-- 检查类是否为扩展设计l -->
<!-- 检查只有private构造函数的类是否声明为final
<module name="FinalClass"/>
-->
<!-- 检查接口是否仅定义类型 -->
<module name="InterfaceIsType"/>
<!-- 检查类成员的可见度 检查类成员的可见性。只有static final 成员是public的
除非在本检查的protectedAllowed和packagedAllowed属性中进行了设置-->
<module name="VisibilityModifier">
<property name="packageAllowed" value="true"/>
<property name="protectedAllowed" value="true"/>
</module>
<!-- 语法 -->
<!-- String的比较不能用!= 和 == -->
<module name="StringLiteralEquality"/>
<!-- 限制for循环最多嵌套2层 -->
<module name="NestedForDepth">
<property name="max" value="2"/>
</module>
<!-- if最多嵌套3层 -->
<module name="NestedIfDepth">
<property name="max" value="10"/>
</module>
<!-- 检查未被注释的main方法,排除以Appllication结尾命名的类 -->
<module name="UncommentedMain">
<property name="excludedClasses" value=".*[Application,Test]$"/>
</module>
<!-- 禁止使用System.out.println -->
<module name="Regexp">
<property name="format" value="System\.out\.println"/>
<property name="illegalPattern" value="true"/>
</module>
<!--try catch 异常处理数量 3-->
<module name="NestedTryDepth ">
<property name="max" value="3"/>
</module>
<!-- clone方法必须调用了super.clone() -->
<module name="SuperClone"/>
<!-- finalize 必须调用了super.finalize() -->
<module name="SuperFinalize"/>
</module>
</module>

View File

@@ -1,11 +0,0 @@
# 开发文档
文档放在docs/files下写完文档记得执行下`SidebarTest.main()`方法
配合gitee pages服务使用gitee pages服务指定docs目录。
## 本地查看开发文档
- 前提先安装好npm[npm安装教程](https://blog.csdn.net/zhangwenwu2/article/details/52778521)。建议使用淘宝镜像。
- 安装docsify执行npm命令`npm i docsify-cli -g --registry=https://registry.npm.taobao.org`
- cd到当前目录运行命令`docsify serve docs`,然后访问:`http://localhost:3000`即可查看。

View File

@@ -1,5 +0,0 @@
# SOP开发文档
Git地址[SOP](https://gitee.com/durcframework/SOP)
Q群328419269

View File

@@ -1 +0,0 @@
include: [_navbar,_sidebar]

View File

@@ -1,12 +0,0 @@
![logo](_media/icon.svg)
# docsify <small>4.6.10</small>
> A magical documentation site generator.
* Simple and lightweight (~19kB gzipped)
* No statically built html files
* Multiple themes
[GitHub](https://github.com/QingWei-Li/docsify/)
[Get Started](#docsify)

View File

@@ -1,3 +0,0 @@
- 关于
- [帮助](/zh-cn/)
- [API](/)

View File

@@ -1,34 +0,0 @@
* [首页](/?t=1565916799573)
* 开发文档
* [快速体验](files/10010_快速体验.md?t=1565916799577)
* [项目接入到SOP](files/10011_项目接入到SOP.md?t=1565916799596)
* [新增接口](files/10020_新增接口.md?t=1565916799596)
* [业务参数校验](files/10030_业务参数校验.md?t=1565916799596)
* [错误处理](files/10040_错误处理.md?t=1565916799596)
* [编写文档](files/10041_编写文档.md?t=1565916799596)
* [接口交互详解](files/10050_接口交互详解.md?t=1565916799597)
* [easyopen支持](files/10070_easyopen支持.md?t=1565916799597)
* [使用签名校验工具](files/10080_使用签名校验工具.md?t=1565916799597)
* [ISV管理](files/10085_ISV管理.md?t=1565916799597)
* [自定义路由](files/10086_自定义路由.md?t=1565916799597)
* [自定义返回结果](files/10087_自定义返回结果.md?t=1565916799597)
* [自定义过滤器](files/10088_自定义过滤器.md?t=1565916799597)
* [路由授权](files/10090_路由授权.md?t=1565916799598)
* [接口限流](files/10092_接口限流.md?t=1565916799598)
* [监控日志](files/10093_监控日志.md?t=1565916799598)
* [SDK开发](files/10095_SDK开发.md?t=1565916799598)
* [使用SpringCloudGateway](files/10096_使用SpringCloudGateway.md?t=1565916799598)
* [应用授权](files/10097_应用授权.md?t=1565916799598)
* [传统web开发](files/10100_传统web开发.md?t=1565916799598)
* [文件上传](files/10104_文件上传.md?t=1565916799598)
* [nacos注册中心](files/10106_nacos注册中心.md?t=1565916799599)
* [扩展其它注册中心](files/10107_扩展其它注册中心.md?t=1565916799599)
* [配置Sleuth链路追踪](files/10109_配置Sleuth链路追踪.md?t=1565916799599)
* [预发布灰度发布](files/10110_预发布灰度发布.md?t=1565916799599)
* [动态修改请求参数](files/10111_动态修改请求参数.md?t=1565916799599)
* 原理分析
* [原理分析之@ApiMapping](files/90010_原理分析之@ApiMapping.md?t=1565916799599)
* [原理分析之路由存储](files/90011_原理分析之路由存储.md?t=1565916799599)
* [原理分析之如何路由](files/90012_原理分析之如何路由.md?t=1565916799599)
* [原理分析之文档归纳](files/90013_原理分析之文档归纳.md?t=1565916799600)
* [常见问题](files/90100_常见问题.md?t=1565916799600)

View File

@@ -1,28 +0,0 @@
# 快速体验
> 运行环境JDK8Maven3ZookeeperMysql
- 安装并启动zookeeper[安装教程](http://zookeeper.apache.org/doc/r3.4.13/zookeeperStarted.html)
- 执行Mysql脚本`sop.sql`
- IDE安装lombok插件然后打开项目(IDEA下可以打开根pom.xml然后open as project)
- 启动注册中心sop-registry运行SopRegistryApplication.java
- 启动网关打开sop-gateway下的`application-dev.properties`
1. 修改数据库`username/password`
2. 指定zookeeper地址如果zookeeper安装在本机则不用改
3. 运行`SopGatewayApplication.java`
- 启动微服务打开sop-story-web下的`application-dev.properties`文件
1. 指定zookeeper地址如果zookeeper安装在本机则不用改
2. 运行`SopStoryApplication.java`
- 找到sop-test打开`AllInOneTest.java`进行接口调用测试
确保注册中心先启动
## 使用admin
- 找到`sop-admin/sop-admin-server`工程打开sop-admin-server下的`application-dev.properties`,修改相关配置
- 运行`SopAdminServerApplication.java`
- 访问:`http://localhost:8082`
登录账号admin/123456

View File

@@ -1,58 +0,0 @@
# 项目接入到SOP
以springboot项目为例springmvc目前暂不支持以后可以支持。
- pom.xml添加SpringCloud支持
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
- pom.xml依赖sop-service-common和eureka
```xml
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>最新版本</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
```
- application.properties配置文件添加
```properties
server.port=2222
# 服务名称
spring.application.name=story-service
# eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
# zookeeper配置
spring.cloud.zookeeper.connect-string=localhost:2181
```
- 在springboot启动类上添加`@EnableDiscoveryClient`
- 新增一个配置类,继承`AlipayServiceConfiguration.java`,内容为空
```java
@Configuration
public class OpenServiceConfig extends AlipayServiceConfiguration {
}
```
到此准备工作就完成了,接下来可前往`新增接口`查看如何新增接口。

View File

@@ -1,212 +0,0 @@
# 新增接口
以story服务为例新增一个获取故事内容接口
- 在controller下新建一个类StoryDemoController.java
- 加上`@RestController`注解
```java
@RestController
public class StoryDemoController {
}
```
- 新增一个接口
```java
@ApiMapping(value = "story.demo.get")
public Story getStory() {
Story story = new Story();
story.setId(1);
story.setName("白雪公主");
return story;
}
```
这里的`@ApiMapping`注解作用同`@RequestMapping`注解,可以理解为是它的扩展
value就是接口名对应客户端的`method`参数
如果要加上版本号,指定`version`参数:`@ApiMapping(value = "story.demo.get", version = "2.0")`
- 重启story服务这样接口就可以使用了。
## 绑定业务参数
网关校验通过后,请求参数会传递到微服务上来,完整的参数如下所示:
```
请求参数charset=utf-8&biz_content={"goods_remark":"iphone6"}&method=goods.add&format=json&app_id=2019032617262200001&sign_type=RSA2&version=1.0&timestamp=2019-04-29 19:18:38
```
其中biz_content部分是我们想要的在方法上申明一个对象对应biz_content中的内容即可完成参数绑定并且对参数进行JSR-303校验。
```java
@ApiMapping(value = "goods.add")
public Object addGoods(GoodsParam param) {
return param;
}
@Data
public class GoodsParam {
@NotEmpty(message = "不能为空") // 支持JSR-303校验
private String goods_remark;
}
```
一般情况下,只需要获取业务参数即可,如果想要获取更多的参数,可在后面跟一个`HttpServletRequest`对象。
```java
@ApiMapping(value = "goods.add")
public Object addGoods(GoodsParam param, HttpServletRequest request) {
System.out.println(request.getParameter("method"));
return param;
}
```
- 方式2
```java
@ApiMapping(value = "story.get", version = "2.2")
public Story getStory22(OpenContext<Story> openContext) {
// 业务参数
Story bizObject = openContext.getBizObject();
// 获取appid更多方法查看OpenContext类
String appId = openContext.getAppId();
System.out.println(appId);
return bizObject;
}
```
另一种方式OpenContext泛型参数填bizObject类调用openContext.getBizObject()可直接获得对象
此方式等价于:
```java
@ApiMapping(value = "story.get", version = "2.2")
public Story getStory22(Story bizObject) {
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
String appId = openContext.getAppId();
System.out.println(appId);
return bizObject;
}
```
## 接口命名
接口命名没有做强制要求,但我们还是推荐按照下面的方式进行命名:
接口名的命名规则为:`服务模块.业务模块.功能模块.行为`,如:
- mini.user.userinfo.get 小程序服务.用户模块.用户信息.获取
- member.register.total.get 会员服务.注册模块.注册总数.获取
如果觉得命名规则有点长可以精简为:`服务模块.功能模块.行为`,如`member.usercount.get`,前提是确保前缀要有所区分,不和其它服务冲突。
## 测试接口
- 在sop-test工程下新建一个测试用例`StoryDemoTest`继承TestBase
```java
public class StoryDemoTest extends TestBase {
String url = "http://localhost:8081/api"; // zuul
String appId = "2019032617262200001";
// 私钥
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
@Test
public void testDemo() throws Exception {
// 公共请求参数
Map<String, String> params = new HashMap<String, String>();
params.put("app_id", appId);
// 这里对应@ApiMapping.value属性
params.put("method", "story.demo.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()));
// 这里对应@ApiMapping.version属性
params.put("version", "1.0");
// 业务参数
Map<String, String> bizContent = new HashMap<>();
params.put("biz_content", JSON.toJSONString(bizContent));
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("sign", sign);
System.out.println("----------- 返回结果 -----------");
String responseData = post(url, params);// 发送请求
System.out.println(responseData);
}
}
```
- 请求成功后,控制台会打印:
```
----------- 请求信息 -----------
请求参数charset=utf-8&biz_content={}&method=story.demo.get&format=json&app_id=alipay_test&sign_type=RSA2&version=1.0&timestamp=2019-03-23 15:41:22
商户秘钥MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=
待签名内容app_id=alipay_test&biz_content={}&charset=utf-8&format=json&method=story.demo.get&sign_type=RSA2&timestamp=2019-03-23 15:41:22&version=1.0
签名(sign)YMbxTPdovi6htcn1K3USTS6/Tbg6MOAMigG6x/kG0kQFCYH8ljvxXzcY86UT056nUG3OXxnj0xkw07eV6E03HMlu7bn3/jrT3PCcV3YguhA92aWz720x2xJWdfXY13OUPS9VOCC9zIVxu6EBD+PoZ7ojYChYvOfCR5I8bR/oOc0ZLjK63PWTBdf0eFS4sybXzRf81uNLMROsMhmBDDy0Fhml3ml77qzWBIpsmq5ECZ+89rMPbkNhAUcnFAe7ik7xZIL6WcUhAOhKVa8ZQK1GMjoGnAbGRed1FbuOHZGubgffg4/vMqrY10Bcy6h9jt/zK5w9L3HVgK3aPgQlfP16Gg==
----------- 返回结果 -----------
{"story_demo_get_response":{"msg":"Success","code":"10000","name":"白雪公主","id":1},"sign":"YMbxTPdovi6htcn1K3USTS6/Tbg6MOAMigG6x/kG0kQFCYH8ljvxXzcY86UT056nUG3OXxnj0xkw07eV6E03HMlu7bn3/jrT3PCcV3YguhA92aWz720x2xJWdfXY13OUPS9VOCC9zIVxu6EBD+PoZ7ojYChYvOfCR5I8bR/oOc0ZLjK63PWTBdf0eFS4sybXzRf81uNLMROsMhmBDDy0Fhml3ml77qzWBIpsmq5ECZ+89rMPbkNhAUcnFAe7ik7xZIL6WcUhAOhKVa8ZQK1GMjoGnAbGRed1FbuOHZGubgffg4/vMqrY10Bcy6h9jt/zK5w9L3HVgK3aPgQlfP16Gg=="}
```
## 开放现有接口
如果想把现有项目中的接口开放出去,提供给客户调用,具体操作如下:
- 将现有项目接入到SOP前往`项目接入到SOP`文档页查看
- 在现有接口方法上加上一个注解`@ApiAbility`,如下面这个接口
```java
// 具备开放平台能力
@ApiAbility
@RequestMapping("getStory2")
public Story getStory2_0() {
Story story = new Story();
story.setId(1);
story.setName("海底小纵队(默认版本号)");
return story;
}
```
- 启动程序
这种情况下,老接口依然能正常访问,同时开放平台也能访问进来。
**注意** 此时的开放接口对应的接口名为:类@RequestMapping.value + "." + 方法@RequestMapping.value
举个列子:
```java
@RequestMapping("goods")
public class MyController {
@ApiAbility
@RequestMapping("listGoods")
public Object fun() {
}
}
```
fun接口对应的路径为`/goods/listGoods`
那么对应开放平台的接口名会转换成:`goods.listGoods`客户端的method参数要填`goods.listGoods`
当然也可以直接把@RequestMapping替换成`@ApiMapping`并指定接口名,这样的话不能兼容以前的访问形式。

View File

@@ -1,72 +0,0 @@
# 业务参数校验
业务参数校验采用JSR-303方式关于JSR-303介绍可以参考这篇博文[JSR 303 - Bean Validation 介绍及最佳实践](https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/)
在参数中使用注解即可框架会自动进行验证。如下面一个添加商品接口它的参数是GoodsParam
```java
@ApiMapping(value = "goods.add")
public void addGoods(GoodsParam param) {
...
}
```
在GoodsParam中添加JSR-303注解:
```java
@Data
public class GoodsParam {
@NotEmpty(message = "商品名称不能为空")
private String goods_name;
}
```
如果不传商品名称则返回
```
{"goods_add_response":{"msg":"Success","code":"10000","sub_msg":"商品名称不能为空","sub_code":"isv.invalid-parameter"},"sign":"Eh3Z5CxDCHsb4MyYFVxsPSmBpwVi1LISJdOkrzglxXoqG7RVyEOt4ef1kNpznUvMI3FDQU1suR7Rsmx6NjGdEVS6NSH2Kt0d8TFBRpLhWz8hApnxOtgzqMqbYeMuJie7X5gF6m8hTnvuuxF21IrkixMe+lyBcXw7dk0C3w1SwdEZkHQ+xC+M4bLqAZt5/3kl79/FWSMFJWHiZmg5YeEi8e8XhYCNcz+xlJRJL0x2Y87fFxqSY0UYWNxbQHgdVI8xRfn1n31nzkcLxiAtTh4LPtNRrG7w7absK/C1Oi/vczuBlFeq2EWUsYVWOVpKiJifUwvYVUUsztSLElzplzOjbg=="}
```
## 参数校验国际化
国际化的配置方式如下:
```java
@NotEmpty(message = "{goods.remark.notNull}")
private String goods_remark;
```
国际化资源文件`bizerror_en.properties`中添加:
```
goods.remark.notNull=The goods_remark can not be null
```
bizerror_zh_CN.properties中添加
```
# 商品备注不能为空
goods.remark.notNull=\u5546\u54c1\u5907\u6ce8\u4e0d\u80fd\u4e3a\u7a7a
```
## 参数校验国际化传参
下面校验商品评论的长度要求大于等于3且小于等于20。数字3和20要填充到国际化资源中去。
```
// 传参的格式:{xxx}=value1,value2...
@Length(min = 3, max = 20, message = "{goods.comment.length}=3,20")
private String goods_comment;
```
bizerror_en.properties:
```
goods.comment.length=The goods_comment length must >= {0} and <= {1}
```
bizerror_zh_CN.properties中添加
```
# 商品评论长度必须在{0}和{1}之间
goods.comment.length=\u5546\u54c1\u8bc4\u8bba\u957f\u5ea6\u5fc5\u987b\u5728{0}\u548c{1}\u4e4b\u95f4
```
这样value1value2会分别填充到{0},{1}中

View File

@@ -1,91 +0,0 @@
# 错误处理
SOP对错误处理已经封装好了简单做法是`throw ServiceException`在最顶层的Controller会做统一处理。例如
```java
if(StringUtils.isEmpty(param.getGoods_name())) {
throw new ServiceException("goods_name不能为null");
}
```
为了保证编码风格的一致性推荐统一使用ServiceException
## i18n国际化
SOP支持国际化消息。通过Request对象中的getLocale()来决定具体返回那种语言客户端通过设置Accept-Language头部来决定返回哪种语言中文是zh英文是en。
SOP通过模块化来管理国际化消息这样做的好处结构清晰维护方便。下面就来讲解如何设置国际化消息。
以story服务为例假设我们要对商品模块进行设置步骤如下
-`resource/i18n/isp`目录下新建goods_error_zh_CN.properties属性文件
属性文件的文件名有规律, **i18n/isp/goods_error** 表示模块路径, **_zh_CN.properties** 表示中文错误消息。如果要使用英文错误,则新建一个`goods_error_en.properties`即可。
- 在goods_error_zh_CN.properties中配置错误信息
```
# 商品名字不能为空
isp.goods_error_100=\u5546\u54C1\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A
```
isp.goods_error_为固定前缀100为错误码这两个值后续会用到。
接下来是把属性文件加载到国际化容器当中。
- 添加国际化配置在OpenServiceConfig中的static块中添加代码如下
```java
@Configuration
public class OpenServiceConfig extends AlipayServiceConfiguration {
static {
ServiceConfig.getInstance().getI18nModules().add("i18n/isp/goods_error");
}
}
```
- 新建一个枚举用来定义错误
```java
// 按模块来定义异常消息,团队开发可以分开进行
public enum GoodsErrorEnum {
/** 参数错误 */
NO_GOODS_NAME("100"),
;
private ServiceErrorMeta errorMeta;
StoryErrorEnum(String subCode) {
this.errorMeta = new ServiceErrorMeta("isp.goods_error_", subCode);
}
public ServiceErrorMeta getErrorMeta() {
return errorMeta;
}
}
```
接下来就可以使用了
```java
if (StringUtils.isEmpty(param.getGoods_name())) {
throw GoodsErrorEnum.NO_GOODS_NAME.getErrorMeta().getException();
}
```
### 国际化消息传参
即代码中变量传入到properties文件中去做法是采用{0},{1}占位符。0代表第一个参数1表示第二个参数。
```
# 商品名称太短,不能小于{0}个字
isp.goods_error_101=\u5546\u54C1\u540D\u79F0\u592A\u77ED\uFF0C\u4E0D\u80FD\u5C0F\u4E8E{0}\u4E2A\u5B57
```
```java
if (param.getGoods_name().length() <= 3) {
throw GoodsErrorEnum.LESS_GOODS_NAME_LEN.getErrorMeta().getException(3);
}
```
直接放进getException(Object... params)方法参数中,因为是可变参数,可随意放。

View File

@@ -1,119 +0,0 @@
# 编写文档
作为开放平台必须要提供API文档。
SOP采用微服务架构实现因此文档应该由各个微服务各自实现。难点就是如何统一归纳各个微服务端提供的文档信息并且统一展示。
写完接口后使用swagger注解来定义自己的文档信息。步骤如下
- maven添加swagger
```xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
```
- 在config中添加swagger配置
```java
@Configuration
public class OpenServiceConfig extends AlipayServiceConfiguration {
// 开启文档
@Configuration
@EnableSwagger2
public static class Swagger2 extends SwaggerSupport {
@Override
protected String getDocTitle() {
// 不能重复。比如订单服务返回:`订单API`;库存服务返回:`库存API`
return "图书API";
}
}
}
```
其中`getDocTitle()`返回文档模块名,不能和其它微服务重复。比如订单服务返回:`订单API`;库存服务返回:`库存API`
- 编写swagger注解
分别在请求参数和返回结果类中编写`@ApiModelProperty`
```java
// 请求参数
@Data
public class BookParam {
@ApiModelProperty(value = "图书id", example = "1")
private int id;
@ApiModelProperty(value = "图书ISBN", example = "xxxx")
private String isbn;
}
// 返回结果
@Data
public class BookVO {
@ApiModelProperty(value = "图书id", example = "1")
private int id;
@ApiModelProperty(value = "图书名称", example = "白雪公主")
private String name;
@ApiModelProperty(value = "isbn", example = "xxxxxx")
private String isbn;
}
```
- 在接口方法上编写`@ApiOperation`注解
```java
@ApiOperation(value="查询书本信息", notes = "可以根据ISBN查询书本信息")
@ApiMapping(value = "book.search")
public BookVO searchBook(BookParam param) {
BookVO bookVO = new BookVO();
bookVO.setId(1);
bookVO.setName("白雪公主ISBN:" + param.getIsbn());
bookVO.setIsbn("ABCSSSSDDD");
return bookVO;
}
```
其中`value`属性填接口名称,简明扼要。`notes`填写接口的详细信息,介绍,用途,注意事项等。
## 查看文档
- 启动website-server(运行WebsiteServerApplication.java)
- 找到sop-website/website-front/pages/doc/doc.htmlIDEA下右键--Debug
如果没有IDEA可以下个webstorm同样有本地静态服务器功能。
效果图如下
![预览](images/10041_1.png "10041_1.png")
## 注解对应关系
swagger注解和文档界面显示关系如下图所示
![预览](images/10041_2.png "10041_2.png")
![预览](images/10041_3.png "10041_3.png")

View File

@@ -1,61 +0,0 @@
# 接口交互详解
开放平台所提供的接口有几十个到几百个不等,同样支持的服务也是多个的。就拿[支付宝开放平台](https://docs.open.alipay.com/api)来说
它所提供的服务有支付服务、会员服务、店铺服务、芝麻信用服务等。相信这些服务接口肯定不是写在同一个项目中但是它的接口地址只有一个https://openapi.alipay.com/gateway.do
从地址信息中可以看到,这是一个网关服务。也就是说,网关是所有请求的入口,然后通过请求分发的方式,把请求路由到具体某个服务中去。
虽然支付宝开放平台的实现方式我们不得而知,但是这种思路是可行的。
SOP也是采用这种方式实现大致步骤如下
- 每个服务注册到注册中心在启动的时候把自己的路由信息上传到zookeeper并且保证每一个接口都能对应到哪个服务。
- 网关启动时同样注册到注册中心获取zookeeper上的接口信息保存到本地并监听zookeeper上的接口信息一旦接口信息有修改网关这边能及时进行更新。
- 网关收到客户端请求后,先进行签名校验,通过之后根据接口信息找到对应的服务,然后进行路由
- 网关对返回结果进行处理(或不处理),返回给客户端。
如何通过接口参数找到对应的服务呢?
在网关定义一个`Map<String, RouteInfo> routeMap = ...`key为接口名+版本号。
网关启动时从zookeeper中获取路由信息并保存到routeMap中
```java
routeMap = buildFromZookeeper();
```
接口请求进来后,根据`方法名+版本号`获取路由信息,然后进行路由转发。
```java
String method = request.getParameter("method");
String version = request.getParameter("version");
RouteInfo routeInfo = routeMap.get(method + version);
doRoute(routeInfo);
```
因为有多个服务把路由信息注册到zookeeper我们要确保接口名唯一`method`全局唯一。
我们推荐接口名的命名规则应该是:`服务模块.业务模块.功能模块.行为`,如:
mini.user.userinfo.get 小程序服务.用户模块.用户信息.获取
member.register.total.get 会员服务.注册模块.注册总数.获取
如果觉得命名规则有点长可以精简为:`服务模块.功能模块.行为`,如`member.usercount.get`,前提是确保前缀要有所区分,不和其它服务冲突。
得益于Spring Cloud的注册中心和和网关功能我们能很方便的进行接口路由并且还能实现LoadBalance不需要自己再去实现。
整个SOP的架构如下图所示
![SOP架构图](https://images.gitee.com/uploads/images/2019/0309/093312_8afb4789_332975.png "sop.png")
- 完整请求路线
```
客户端生成签名串 → 客户端发送请求 →【网关签名校验 → 权限校验 → 限流处理 → 路由转发】→ {微服务端业务参数校验 → 处理业务逻辑 → 微服务端返回结果}
客户端业务处理 ← 客户端验证服务端签名 ← 客户端收到结果 ← -------------【网关返回最终结果 ← 生成服务端签名 ← 网关处理结果】← 结果返回到网关
【】:表示网关处理
{}:表示微服务端处理
```

View File

@@ -1,62 +0,0 @@
# easyopen支持
SOP对easyopen项目提供了很好的支持如果您的服务端使用了easyopen框架相关配置步骤如下
## 服务端配置
首先是服务端相关配置
- pom添加依赖
```xml
<!-- sop接入依赖 -->
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>easyopen</artifactId>
<version>1.16.1</version>
</dependency>
<!-- sop接入依赖 end -->
```
easyopen版本必须升级到1.16.1
- 启动类上面添加注解@EnableDiscoveryClient,将自己注册到注册中心
- 新增一个配置类继承EasyopenServiceConfiguration内容为空
```java
@Configuration
public class SopConfig extends EasyopenServiceConfiguration {
}
```
服务端配置完毕,重启服务。
## 网关端配置
接下来是网关的配置
- 打开ZuulConfig.java注释掉原本的@Configuration新增如下Configuration
```java
@Configuration
public class ZuulConfig extends EasyopenZuulConfiguration {
static {
new ManagerInitializer();
}
}
```
配置完毕,重启网关服务,可运行测试用例`EasyopenClientPostTest.java`验证
**注:** 配置完成后easyopen签名校验将会关闭改用网关端来校验网关对easyopen返回的结果不进行处理直接返回服务端的结果。
完整配置可查看sop-example/sop-easyopen项目

View File

@@ -1,48 +0,0 @@
# 使用签名校验工具
## 生成公私钥
SOP默认签名算法仿照的是支付宝开放平台因此我们可以使用支付宝开放平台提供的密钥生成工具[下载地址](https://docs.open.alipay.com/291/105971/)
工具下载完后,运行工具
- 秘钥格式选择PKCS8(JAVA适用)
- 秘钥长度2048
然后点击`生成秘钥`,下面文本框会生成,公私钥,如下图所示:
![示例图](https://gw.alipayobjects.com/zos/skylark/6dbc42cc-6b9b-4691-83f1-e7b875e1a602/2018/png/e6b725d0-8257-4a71-b7a0-f5479c9d43d0.png)
公钥给到开放平台打开sop-gateway项目中的`ZuulConfig.java`,复制公钥
```java
appSecretStore.put(应用ID, 公钥内容);
```
- 应用ID(app_id):建议个格式为`yyyyMMddHHmmss+自增ID`如2019032617262200001
- 公钥内容:刚刚生成的公钥字符串
接着私钥放入客户端进行调用。参见AlipayClientPostTest类
## 签名校验
验证工具切换到`签名`tab页
例如执行com.gitee.sop.AlipayClientPostTest.testPost()方法,控制台会打印如下信息:
```
----------- 请求信息 -----------
请求参数charset=utf-8&biz_content={"name":"葫芦娃","id":"1"}&method=alipay.story.get&format=json&app_id=2019032617262200001&sign_type=RSA2&version=1.0&timestamp=2019-03-26 17:37:41
商户秘钥MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=
待签名内容app_id=2019032617262200001&biz_content={"name":"葫芦娃","id":"1"}&charset=utf-8&format=json&method=alipay.story.get&sign_type=RSA2&timestamp=2019-03-26 17:37:41&version=1.0
签名(sign)JCZMSFkXSjw/4TokyM9/9shyrMl7KxQGIZDHIm7+Bvl49Z816/iF/xXLYjUiPXWAXYfp+HlEs3VVQp1Kjh4tIKuKX/i1+exNVs+ICcqVGBewPSZwiWHGpZTfEUiYOoPyUL/eoRIj7Mvlaow0sI9uP7NXNo0kxEFjUOMCzZA7eKm/pu2FHRXt4OhgXq2Go30K5a9oCbbMc/2xcQCc2+zwvOgV3o0A6eMyeAXDJW+eQ2KLhtlqPQvbRV+xyfSut7TkwYSEuNXVVQAfN2lwAS3ru9CQIs8Uz7lK1ITkLu80yLapZVL7tS1PdxK0e3QYToCWD43Wtuoow4ZdDwwzir90HQ==
----------- 返回结果 -----------
{"alipay_story_get_response":{"msg":"Success","code":"10000","name":"海底小纵队(alipay.story.get)","id":1},"sign":"JCZMSFkXSjw/4TokyM9/9shyrMl7KxQGIZDHIm7+Bvl49Z816/iF/xXLYjUiPXWAXYfp+HlEs3VVQp1Kjh4tIKuKX/i1+exNVs+ICcqVGBewPSZwiWHGpZTfEUiYOoPyUL/eoRIj7Mvlaow0sI9uP7NXNo0kxEFjUOMCzZA7eKm/pu2FHRXt4OhgXq2Go30K5a9oCbbMc/2xcQCc2+zwvOgV3o0A6eMyeAXDJW+eQ2KLhtlqPQvbRV+xyfSut7TkwYSEuNXVVQAfN2lwAS3ru9CQIs8Uz7lK1ITkLu80yLapZVL7tS1PdxK0e3QYToCWD43Wtuoow4ZdDwwzir90HQ=="}
```
字符集选UTF-8签名方式RSA2
把控制台中的`请求参数``商户秘钥`填入文本框中,然后点击`开始签名`下方会出现待签名内容和sign。
通过比对判断签名过程是否正确。

View File

@@ -1,24 +0,0 @@
# ISV管理
ISV独立软体开发商independent software vendor即接入方或者说接口调用者在SOP中称为ISV。
---
在1.1.0版本中新增了ISV管理功能在sop-admin中ISV管理模块下。功能如下
- 基本信息的增查改
- 设置对应角色
界面如下图所示:
![admin预览](images/10085_1.png "10085_1.png")
## 秘钥管理
点击操作列的`秘钥管理`可对ISV的秘钥进行设置。
- 如果采用淘宝开放平台签名方式,签名方式选择`MD5`,如果采用支付宝开放平台签名方式,选择`RSA`
- 如果对接的开发者使用非Java语言秘钥格式选择`PKCS1`
- 带 ★ 的分配给开发者
![admin预览](images/10085_2.png "10085_2.png")

View File

@@ -1,23 +0,0 @@
# 自定义路由
假设有一个非java开发的接口比如php开发的接口然后需要接入到SOP使用接口名版本号进行路由跳转。
操作方式如下:
- 登录sop-admin服务管理--路由管理
- 新建一个自定义服务:`php-service`
![新建一个自定义服务](images/10086_1.png "10086_1.png")
- 选中php-service新建一个路由输入接口名、版本号、uri
![新建一个路由](images/10086_2.png "10086_2.png")
- 请求网关
`http://localhost:8081/api?method=php.goods.list&version=1.0`会跳转到`http://www.xxx.com/api/listGoods.php`
注意:
- php接口返回数据必须是json格式返回其它内容可能会调用失败
- 只有自定义服务、路由可以删除

View File

@@ -1,125 +0,0 @@
# 自定义返回结果
网关默认对业务结果进行合并,然后返回统一的格式。
针对`alipay.story.find`接口,微服务端返回结果如下:
```json
{
"name": "白雪公主",
"id": 1,
"gmtCreate": 1554193987378
}
```
网关合并后,最终结果如下
```json
{
"alipay_story_find_response": {
"msg": "Success",
"code": "10000",
"name": "白雪公主",
"id": 1,
"gmtCreate": 1554193987378
},
"sign": "xxxxx"
}
```
其中`alipay_story_find_response`是它的数据节点。规则是:
> 将接口名中的点`.`转换成下划线`_`,后面加上`_response`
代码实现如下:
```java
String method = "alipay.story.find";
return method.replace('.', '_') + "_response";
```
详见`DefaultDataNameBuilder.java`
如果要更改数据节点,比如`result`,可使用`CustomDataNameBuilder.java`
```java
@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {
static {
...
ApiConfig.getInstance().setDataNameBuilder(new CustomDataNameBuilder());
...
}
}
```
设置后,网关统一的返回结果如下:
```json
{
"result": {
...
},
"sign": "xxxxx"
}
```
此外,构造方法可指定自定义字段名称:`new CustomDataNameBuilder("data");`
设置后,数据节点将变成`data`
```json
{
"data": {
...
},
"sign": "xxxxx"
}
```
**注**网关设置了CustomDataNameBuilder后SDK也要做相应的更改`SdkConfig.dataNameBuilder = new CustomDataNameBuilder();`
## 自定义结果处理
如果想要对微服务结果做更深一步处理,步骤如下:
1. 新增一个类,继承`ZuulResultExecutor.java`,并重写`public String merge(T exchange, JSONObject responseData)`方法
方法merge参数说明如下
exchangeRequestContext对象
responseData微服务端返回的结果
方法返回最终结果
2. 配置自定义类
```java
public class SopGatewayApplication {
public static void main(String[] args) {
ApiConfig.getInstance().setZuulResultExecutor(new MyzuulResultExecutor());
SpringApplication.run(SopGatewayApplication.class, args);
}
}
```
## 不合并结果
如果不希望对结果进行合并,可设置`ApiConfig.getInstance().setMergeResult(false);`
```java
public class SopGatewayApplication {
public static void main(String[] args) {
ApiConfig.getInstance().setMergeResult(false);
SpringApplication.run(SopGatewayApplication.class, args);
}
}
```
这样,网关最终返回结果即为微服务端的返回结果。

View File

@@ -1,105 +0,0 @@
# 自定义过滤器
## zuul过滤器
zuul过滤器列表如下
| 类型 | 顺序 | 过滤器 | 功能 |
| ----- | ---- | ----------------------- | ---------------------------- |
| pre | -1000 | PreValidateFilter (SOP自带) | 校验签名 |
| pre | -999 | PreRoutePermissionFilter (SOP自带) | 路由权限校验,有些接口需要配置权限才能访问 |
| pre | -998 | PreLimitFilter (SOP自带) | 限流拦截器 |
| pre | -3 | ServletDetectionFilter | 标记处理 Servlet 的类型 |
| pre | -2 | Servlet30WrapperFilter | 包装 HttpServletRequest 请求 |
| pre | -1 | FormBodyWrapperFilter | 包装请求体 Servlet30WrapperFilter |
| pre | 1 | DebugFilter | 标记调试标志 |
| pre | 5 | PreDecorationFilter | 决定路由转发过滤器 |
| route | 10 | RibbonRoutingFilter | serviceId 请求转发 |
| route | 100 | SimpleHostRoutingFilter | url 请求转发 |
| route | 500 | SendForwardFilter | forward 请求转发 |
| post | 0 | SendErrorFilter | 处理有错误的请求响应 |
| post | 1000 | SendResponseFilter | 处理正常的请求响应 |
顺序值小的优先执行,`-3`之前是sop自带的过滤器`-3`开始是zuul自带的过滤器。
创建自定义过滤器可以从`-500`开始(-1000 ~ -501留给SOP。下面是一个自定义过虑器的例子
```java
public class PreXXXFilter extends BaseZuulFilter {
@Override
protected FilterType getFilterType() {
return FilterType.PRE;
}
@Override
protected int getFilterOrder() {
return -500;
}
@Override
protected Object doRun(RequestContext requestContext) throws ZuulException {
HttpServletRequest request = requestContext.getRequest();
ApiParam apiParam = ZuulContext.getApiParam();
String appKey = apiParam.fetchAppKey();
// ...业务处理
// 固定返回null
return null;
}
}
```
过滤器编写完毕后在Config中使用
```java
@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {
...
@Bean
PreXXXFilter preXXXFilter() {
return new PreXXXFilter();
}
...
}
```
## spring cloud gateway
跟zuul同理
```java
public class XXXFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ApiParam apiParam = (ApiParam)exchange.getAttribute(SopConstants.CACHE_API_PARAM);
String appKey = apiParam.fetchAppKey();
// ...业务处理
...
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -500;
}
}
```
使用过滤器:
```java
@Configuration
public class GatewayConfig extends AlipayGatewayConfiguration {
...
@Bean
XXXFilter xxxFilter() {
return new XXXFilter();
}
...
}
```

View File

@@ -1,25 +0,0 @@
# 路由授权
1.1.0版本新增了路由授权功能采用RBAC权限管理方式实现。
- 每个ISVappKey对应一个或多个角色
- 每个角色分配多个路由权限
接口跟角色相关联ISV拥有哪些角色就具有角色对应的接口访问权限。
假设把路由a,b,c分配给了`VIP角色`那么具有VIP角色的ISV可以访问a,b,c三个路由。
默认情况下接口访问时公开的ISV都能访问。如果要设置某个接口访问权限`@ApiMapping`注解中指定permission=true。
如:`@ApiMapping(value = "permission.story.get", permission = true)`。这样该接口是需要经过授权给ISV才能访问的。
重启服务后登录admin服务管理-路由列表界面中,操作操作列会出现一个授权按钮,点击出现授权窗口,勾选对应的角色即可完成授权。
- 点击`授权`按钮,进行角色授权
![admin预览](images/10090_1.png "10090_1.png")
- 勾选对应角色,点击保存
![admin预览](images/10090_2.png "10090_2.png")
这里演示的是具有普通权限的ISV能够访问`permission.story.get`接口,运行`PermissionDemoPostTest`测试用例进行验证

View File

@@ -1,44 +0,0 @@
# 接口限流
SOP提供了简单的接口限流策略
- 漏桶策略:每秒处理固定数量的请求,超出请求返回错误信息。
- 令牌桶策略:每秒放置固定数量的令牌数,每个请求进来后先去拿令牌,拿到了令牌才能继续,拿不到则等候令牌重新生成了再拿。
如果一个接口设置了漏桶策略假设接口每秒可处理5个请求一秒内同时有6个请求进来前5个接口是能够访问的第六个请求将返回错误信息。
如果设置了令牌桶策略桶的容量是5那么每秒中生成5个令牌同一时间有6个请求进来那么前5个能成功拿到令牌继续第六个则等待令牌重新生成了再拿。
默认情况下接口的限流功能是关闭的可在sop admin中配置并开启。功能在`路由管理-->限流管理`下。
## 新版限流1.9.0
1.9.0将之前的限流进行了改造,新的限流支持更多的限流方式。之前只能针对某个接口限流,新版限流可以在`路由ID接口、appKey、ip`上进行限流。
- 可针对接口进行限流,所有访问该接口的请求都被限流
- 可针对appKey进行限流某个appKey请求过来后对他限流
- 可针对IP进行限流某个IP请求过来后对他限流
此外还可以进行组合
- 可针对接口+appKey进行限流这个appKey调用某个接口比较频繁可以将它限制住
- 可针对接口+IP进行限流某个ip在频繁调用接口可以将它限制住
由于存在组合情况,一个接口可能会配置多个限流规则。在这种情况下会优先取排序值小的那一条,如果排序值一样,则默认取第一条。
假设有下面几个限流规则:
- 接口:`goods.get` 排序值1 每秒可处理请求数10
- 接口:`goods.get` appKeyxxxx 排序值0 每秒可处理请求数5
- 接口:`goods.get` ip172.1.2.2 排序值2 每秒可处理请求数6
客户端调用接口:`http://open.domain.com/api?method=goods.get&app_key=xxxx`客户端IP为`172.1.2.2`
这种情况下上面三条限流规则都命中了,由于排序值小优先执行,因此第二条规则命中.
具体设置方式可在sop admin中配置功能在`服务管理-->限流管理`下。执行`sop-test/src/test/java/com/gitee/sop/LimitDemoPostTest.java`测试用例验证限流情况
![限流配置](images/10092_1.png "10092_1.png")
![限流配置](images/10092_2.png "10092_2.png")

View File

@@ -1,44 +0,0 @@
# 监控日志
1.10.0开始sop-admin提供了简单的监控日志查询方便在线排查问题。
- 错误日志统一在网关负责收集
- 只收集未知类型的错误日志开发人员主动throw的异常不收集
- sop-admin通过网关提供的restful接口获取日志内容然后在后台展示
- 收集的日志存放在内存中,重启网关日志会消失
- 只会收集20条不同的日志内容相同内容会count+1。可设置`ApiConfig.storeErrorCapacity`属性扩大容量默认容量20
第一次使用需要添加网关服务器实例,前往:`服务管理--监控日志--添加监控服务器`
## 永久保存日志
默认收集的日志存放在内存中,重启网关日志会消失(见:`DefaultServiceErrorManager.java`)。如果要永久保存日志内容,需要自己实现`ServiceErrorManager`接口
```java
public class MyServiceErrorManager implements ServiceErrorManager {
...
}
```
然后在ApiConfig中配置
```java
@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {
static {
...
ApiConfig.getInstance().setServiceErrorManager(new MyServiceErrorManager());
// 日志收集容量默认20。只会收集20条不同内容的日志
ApiConfig.getInstance().setStoreErrorCapacity(20);
...
}
}
```
- 后台预览
![监控日志](images/10093_1.png "10093_1.png")
![监控日志](images/10093_2.png "10093_2.png")

View File

@@ -1,335 +0,0 @@
# 开发SDK
开放平台把接口开发完毕后一般需要开发对应的SDK提供给ISV。SOP提供了一个基础的SDK开发包
开发者可以在此基础上做开发就拿sdk-java来说具体步骤如下
## sdk-java
SDK依赖了三个jar包
- okhttp.jar 用于网络请求
- fastjson.jar 用于json处理
- commons-logging.jar 日志处理
### 接口封装步骤
比如获取故事信息接口
- 接口名alipay.story.find
- 版本号1.0
- 参数name 故事名称
- 返回信息
```json
{
"alipay_story_find_response": {
"msg": "Success",
"code": "10000",
"name": "白雪公主",
"id": 1,
"gmtCreate": 1554193987378
},
"sign": "xxxxx"
}
```
针对这个接口,封装步骤如下:
1.在`model`包下新建一个类,定义业务参数
```java
@Data
public class GetStoryModel {
@JSONField(name = "name")
private String name;
}
```
2.在`response`包下新建一个返回类GetStoryResponse继承`BaseResponse`
里面填写返回的字段
```
@Data
public class GetStoryResponse extends BaseResponse {
private Long id;
private String name;
private Date gmtCreate;
}
```
3.在`request`包下新建一个请求类,继承`BaseRequest`
BaseRequest中有个泛型参数`GetStoryResponse`类,表示这个请求对应的返回类。
重写`method()`方法,填接口名。
如果要指定版本号,可重写`version()`方法,或者后续使用`request.setVersion(version)`进行设置
```java
public class GetStoryRequest extends BaseRequest<GetStoryResponse> {
@Override
protected String method() {
return "alipay.story.find";
}
}
```
可重写`getRequestMethod()`方法指定HTTP请求method默认是POST。
```java
@Override
protected RequestMethod getRequestMethod() {
return RequestMethod.GET;
}
```
**建议读请求用GET写请求用POST**
### 使用方式
```java
String url = "http://localhost:8081/api"; // zuul
String appId = "2019032617262200001";
String privateKey = "你的私钥";
// 声明一个就行
OpenClient client = new OpenClient(url, appId, privateKey);
// 标准用法
@Test
public void testGet() {
// 创建请求对象
GetStoryRequest request = new GetStoryRequest();
// 请求参数
GetStoryModel model = new GetStoryModel();
model.setName("白雪公主");
request.setBizModel(model);
// 发送请求
GetStoryResponse response = client.execute(request);
if (response.isSuccess()) {
// 返回结果
System.out.println(String.format("成功response:%s\n响应原始内容:%s",
JSON.toJSONString(response), response.getBody()));
} else {
System.out.println("错误subCode:" + response.getSubCode() + ", subMsg:" + response.getSubMsg());
}
}
```
### 使用方式2(懒人版)
如果不想添加Request,Response,Model。可以用这种方式返回body部分是字符串后续自己处理
body对应的是alipay_story_find_response部分
```java
@Test
public void testLazy() {
// 创建请求对象
CommonRequest request = new CommonRequest("alipay.story.find");
// 请求参数
Map<String, Object> bizModel = new HashMap<>();
bizModel.put("name", "白雪公主");
request.setBizModel(bizModel);
// 发送请求
CommonResponse response = client.execute(request);
if (response.isSuccess()) {
// 返回结果body对应的是alipay_story_find_response部分
String body = response.getBody();
JSONObject jsonObject = JSON.parseObject(body);
System.out.println(jsonObject);
} else {
System.out.println(response);
}
}
```
## sdk-.net
### 接口封装步骤
比如获取故事信息接口
- 接口名alipay.story.find
- 版本号1.0
- 参数name 故事名称
- 返回信息
```
{
"alipay_story_find_response": {
"msg": "Success",
"code": "10000",
"name": "白雪公主",
"id": 1,
"gmtCreate": 1554193987378
},
"sign": "xxxxx"
}
```
针对这个接口,封装步骤如下:
1.在`Model`包下新建一个类,定义业务参数
```
namespace SDKCSharp.Model
{
public class GetStoryModel
{
/// <summary>
/// 故事名称
/// </summary>
/// <value>The name.</value>
[JsonProperty("name")]
public string Name { get; set; }
}
}
```
`[JsonProperty("name")]`是Newtonsoft.Json组件中的类用于Json序列化括号中的是参数名称。
类似于Java中的注解`@JSONField(name = "xx")`
2.在`Response`包下新建一个返回类GetStoryResponse继承`BaseResponse`
里面填写返回的字段
```
namespace SDKCSharp.Response
{
public class GetStoryResponse: BaseResponse
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("gmt_create")]
public string GmtCreate { get; set; }
}
}
```
3.在`Request`文件夹下新建一个请求类,继承`BaseRequest`
BaseRequest中有个泛型参数`GetStoryResponse`类,表示这个请求对应的返回类。
重写`GetMethod()`方法,填接口名。
如果要指定版本号,可重写`GetVersion()`方法,或者后续使用`request.Version = version`进行设置
```
namespace SDKCSharp.Request
{
public class GetStoryRequest : BaseRequest<GetStoryResponse>
{
public override string GetMethod()
{
return "alipay.story.find";
}
}
}
```
### 使用方式
```
class MainClass
{
static string url = "http://localhost:8081/api"; // zuul
static string appId = "2019032617262200001";
// 支付宝私钥
static string privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
// 声明一个就行
static OpenClient client = new OpenClient(url, appId, privateKey);
public static void Main(string[] args)
{
TestGet();
}
// 标准用法
private static void TestGet()
{
// 创建请求对象
GetStoryRequest request = new GetStoryRequest();
// 请求参数
GetStoryModel model = new GetStoryModel();
model.Name = "白雪公主";
request.BizModel = model;
// 发送请求
GetStoryResponse response = client.Execute(request);
if (response.IsSuccess())
{
// 返回结果
Console.WriteLine("故事名称:{0}", response.Name);
}
else
{
Console.WriteLine("错误, code:{0}, msg:{1}, subCode:{2}, subMsg:{3}",
response.Code, response.Msg, response.SubCode, response.SubMsg);
}
}
}
```
### 使用方式2(懒人版)
如果不想添加Request,Response,Model。可以用这种方式返回data部分是Dictionary<string, object>,后续自己处理
```
// 懒人版如果不想添加Request,Response,Model。可以用这种方式返回Dictionary<string, object>,后续自己处理
private static void TestCommon()
{
// 创建请求对象
CommonRequest request = new CommonRequest("alipay.story.find");
// 请求参数
Dictionary<string, string> bizModel = new Dictionary<string, string>
{
["name"] = "白雪公主"
};
request.BizModel = bizModel;
// 发送请求
CommonResponse response = client.Execute(request);
if (response.IsSuccess())
{
// 返回结果
string body = response.Body;
Dictionary<string, object> dict = JsonUtil.ParseToDictionary(body);
Console.WriteLine("Dictionary内容:");
foreach (var item in dict)
{
Console.WriteLine("{0}:{1}", item.Key, item.Value);
}
}
else
{
Console.WriteLine("错误, code:{0}, msg:{1}, subCode:{2}, subMsg:{3}",
response.Code, response.Msg, response.SubCode, response.SubMsg);
}
}
```

View File

@@ -1,75 +0,0 @@
# 使用SpringCloudGateway
SOP默认网关是使用Spring Cloud Zuul您也可以切换成Spring Cloud Gateway完整代码见`SpringCloudGateway`分支。
**注:**SOP对Spring Cloud Gateway的支持目前处于beta阶段推荐使用zuul。
步骤如下:
- 打开sop-gateway/pom.xml注释spring cloud zuul依赖打开Spring Cloud Gateway依赖
```xml
<!-- ↓↓↓ 使用spring cloud zuul ↓↓↓
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
-->
<!-- ↑↑↑ 使用spring cloud zuul ↑↑↑ -->
<!-- ↓↓↓ 使用spring cloud gateway处于beta阶段推荐使用zuul ↓↓↓ -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- ↑↑↑ 使用spring cloud gateway ↑↑↑ -->
```
- 打开启动类`SopGatewayApplication.java`, 注释zuul相关注解
```java
package com.gitee.sop.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
// 开启网关功能
//@EnableZuulProxy
@SpringBootApplication
public class SopGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(SopGatewayApplication.class, args);
}
}
```
- 禁用ZuulConfig类注释掉@Configuration注解即可
```java
//@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {...}
```
- 启用GatewayConfig类打开@Configuration注释
```java
@Configuration
public class GatewayConfig extends AlipayGatewayConfiguration {...}
```
修改完毕重启sop-gateway
运行SpringCloudGatewayClientPostTest测试用例。

View File

@@ -1,117 +0,0 @@
# 应用授权
## 概述
- 1、用户对开发者进行应用授权后开发者可以帮助用户完成相应的业务逻辑。
- 2、授权采用标准的OAuth 2.0流程。
## 授权流程
![授权流程](images/10097_1.png "10097_1.png")
## 快速接入
- 第一步应用授权URL拼装
拼接规则:
http://openauth.yourdomain.com/oauth2/appToAppAuth?app_id=2019032617262200001&redirect_uri=http%3a%2f%2flocalhost%3a8087%2foauth2callback
参数说明:
| 参数 | 参数名称 | 类型 | 必填 | 描述 | 范例 |
|--------------|-------------|--------|----|---------------|--------------------------|
| app_id | 开发者应用的AppId | String | 是 | 开发者应用的AppId | 2015101400446982 |
| redirect_uri | 回调页面 | String | 是 | 参数需要UrlEncode | http%3A%2F%2Fexample.com |
- 第二步获取code
授权成功后会跳转至开发者定义的回调页面即redirect_uri参数对应的url在回调页面请求中会带上当次授权的授权码code和开发者的app_id示例如下
http://www.xxx.com/oauth2callback?app_id=2015101400446982&code=ca34ea491e7146cc87d25fca24c4cD11
- 第三步使用code换取app_auth_token
接口名称open.auth.token.app
开发者通过code可以换取app_auth_token、授权用户的userId。
**注意**应用授权的code唯一code使用一次后失效有效期24小时 app_auth_token永久有效。
**请求参数说明**
| 参数 | 参数名称 | 类型 | 必填 | 描述 | 范例 |
|---------------|------|--------|----|---------------------------------------------------------------------------------|------------------------------------------|
| grant_type | 授权类型 | String | 是 | 如果使用code换取token则为authorization_code如果使用refresh_token换取新的token则为refresh_token | authorization_code |
| code | 授权码 | String | 否 | 与refresh_token二选一用户对应用授权后得到即第一步中开发者获取到的code值 | bf67d8d5ed754af297f72cc482287X62 |
| refresh_token | 刷新令牌 | String | 否 | 与code二选一可为空刷新令牌时使用 | 201510BB0c409dd5758b4d939d4008a525463X62 |
**接口请求SDK示例**
```java
@GetMapping("oauth2callback")
@ResponseBody
public String callback(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
String app_id = servletRequest.getParameter("app_id");
String code = servletRequest.getParameter("code");
OpenAuthTokenAppRequest request = new OpenAuthTokenAppRequest();
OpenAuthTokenAppModel model = new OpenAuthTokenAppModel();
model.setCode(code);
model.setGrant_type("authorization_code");
request.setBizModel(model);
// 根据code获取token
OpenAuthTokenAppResponse response = openClient.execute(request);
if (response.isSuccess()) {
// 成功拿到token开发者在这里保存token信息
// 后续使用token进行接口访问
log.info("授权成功body:{}", response.getBody());
}
return response.getBody();
}
```
**同步响应参数说明**
| 参数 | 参数名称 | 类型 | 必填 | 描述 | 范例 |
|-------------------|---------|--------|----|----------------------------------------------------------|----------------------------------|
| app_auth_token | 用户授权令牌 | String | 是 | 通过该令牌来帮助用户发起请求,完成业务 | 856faf8d77d3b985c1073557ce6ea724 |
| user_id | 授权用户的ID | String | 是 | 授权者id | 1 |
| expires_in | 令牌有效期 | Long | 是 | 负值表示永久有效 | -1 |
| re_expires_in | 刷新令牌有效期 | Long | 是 | 负值表示永久有效 | -3 |
| app_refresh_token | 刷新令牌时使用 | String | 是 | 刷新令牌后我们会保证老的app_auth_token从刷新开始10分钟内可继续使用请及时替换为最新token | 88e68196d2359667f0dc8136e6c86803 |
**同步响应结果示例**
```json
{
"open_auth_token_app_response": {
"code": "10000",
"msg": "Success",
"app_auth_token": "88e68196d2359667f0dc8136e6c86803",
"app_refresh_token": "856faf8d77d3b985c1073557ce6ea724",
"expires_in": -1,
"re_expires_in": -3,
"user_id": "1"
},
"sign": "xxx"
}
```
**刷新token**
```java
OpenAuthTokenAppRequest request = new OpenAuthTokenAppRequest();
OpenAuthTokenAppModel model = new OpenAuthTokenAppModel();
model.setGrant_type("refresh_token");
model.setRefresh_token("856faf8d77d3b985c1073557ce6ea724");
request.setBizModel(model);
OpenAuthTokenAppResponse response = openClient.execute(request);
if (response.isSuccess()) {
// 成功拿到token开发者在这里保存token信息
// 后续使用token进行接口访问
log.info("换取token成功body:{}", response.getBody());
}
```

View File

@@ -1,182 +0,0 @@
# 传统web开发
SOP既可以作为网关服务开发又可以作为传统的webapp服务开发传统web开发意思是像普通的web开发那样提供restful接口没有签名校验功能。
本篇介绍如何使用SOP进行传统web服务开发即对接前端应用H5、小程序、App
- 网关ZuulConfig继承WebappZuulConfiguration类
```java
@Configuration
public class ZuulConfig extends WebappZuulConfiguration {
static {
new ManagerInitializer();
}
}
```
设置完毕,网关不在进行签名验证,网关统一的返回结果如下:
```json
{
"result": {
...
}
}
```
- 微服务OpenServiceConfig继承WebappServiceConfiguration类
```java
public class OpenServiceConfig extends WebappServiceConfiguration {
...
}
```
其它内容不变
- 前端app请求网关
请求格式为:`http://ip:port/rest/your_path`,其中`http://ip:port/rest/`为固定部分,后面跟微服务请求路径。
注意:为了确保各个微服务路径不冲突,必须保证类上方定义的`@RequestMapping`内容唯一,不与其它微服务重复。
下面是一个微服务的接口例子
```java
@RestController
@RequestMapping("food")
public class TraditionalWebappController {
@ApiMapping(value = "getFoodById", method = RequestMethod.GET)
public Food getFoodById(Integer id) {
Food food = new Food();
food.setId(id);
food.setName("香蕉");
food.setPrice(new BigDecimal(20.00));
return food;
}
// 加版本号
@ApiMapping(value = "getFoodById", method = RequestMethod.GET, version = "1.1")
public Food getFoodById2(Integer id) {
Food food = new Food();
food.setId(id);
food.setName("香蕉2");
food.setPrice(new BigDecimal(22.00));
return food;
}
}
```
这是一个`食品服务`例子假设网关ip为10.0.1.11端口8081食品服务ip为10.0.1.22端口2222
1. 网关访问:`http://10.0.1.11:8081/rest/food/getFoodById?id=2`。加版本号:`http://localhost:8081/rest/food/getFoodById?id=2&version=1.1`
2. 本地访问:`http://10.0.1.22:2222/food/getFoodById/?id=2`
更多例子,可查看源码类:`TraditionalWebappController.java`
由此可见,对于前端调用者来说,它把网关看做一个大服务,只访问网关提供的请求,不需要关心网关后面的路由转发。网关后面各个微服务独自管理,
微服务之间的调用可以使用dubbo或feign有了版本号的管理可以做到服务的平滑升级对用户来说都是无感知的。结合SOP-Admin提供的上下线功能
可实现预发布环境功能。
- 封装请求工具【可选】
封装请求方便调用针对vue的封装如下
```js
import axios from 'axios'
// 创建axios实例
const client = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
timeout: 5000, // 请求超时时间
headers: { 'Content-Type': 'application/json' }
})
const RequestUtil = {
/**
* 请求接口
* @param url 请求路径如http://localhost:8081/rest/food/getFoodById
* @param data 请求数据json格式
* @param callback 成功回调
* @param errorCallback 失败回调
*/
post: function(url, data, callback, errorCallback) {
client.post(url, data)
.then(function(response) {
const resp = response.result
const code = resp.code
// 成功,网关正常且业务正常
if (code === '10000' && !resp.sub_code) {
callback(resp)
} else {
// 报错
Message({
message: resp.msg,
type: 'error',
duration: 5 * 1000
})
}
})
.catch(function(error) {
console.log('err' + error) // for debug
errorCallback && errorCallback(error)
})
}
}
export default RequestUtil
```
jQuery版本如下
```js
var RequestUtil = {
/**
* 请求接口
* @param url 请求路径如http://localhost:8081/rest/food/getFoodById
* @param data 请求数据json格式
* @param callback 成功回调
* @param errorCallback 失败回调
*/
post: function(url, data, callback, errorCallback) {
$.ajax({
url: 'http://localhost:8081/api' // 网关url
, type: 'post'
, headers: { 'Content-Type': 'application/json' }
, data: data
,success:function(response) {
var resp = response.result
var code = resp.code
// 成功,网关正常且业务正常
if (code === '10000' && !resp.sub_code) {
callback(resp)
} else {
// 报错
alert(resp.msg);
}
}
, error: function(error) {
errorCallback && errorCallback(error)
}
});
}
}
```
jQuery调用示例
```js
$(function () {
var data = {
id: 1
,name: '葫芦娃'
}
RequestUtil.post('http://localhost:8081/rest/food/getFoodById', data, function (result) {
console.log(result)
});
})
```

View File

@@ -1,109 +0,0 @@
# 文件上传
请求接口时带上文件
## 客户端调用
```java
DemoFileUploadRequest request = new DemoFileUploadRequest();
DemoFileUploadModel model = new DemoFileUploadModel();
model.setRemark("上传文件参数");
request.setBizModel(model);
List<UploadFile> files = new ArrayList<>();
String root = System.getProperty("user.dir");
System.out.println(root);
// 这里演示将resources下的两个文件上传到服务器
files.add(new UploadFile("file1", new File(root + "/src/main/resources/file1.txt")));
files.add(new UploadFile("file2", new File(root + "/src/main/resources/file2.txt")));
request.setFiles(files);
DemoFileUploadResponse response = client.execute(request);
System.out.println("--------------------");
if (response.isSuccess()) {
List<DemoFileUploadResponse.FileMeta> responseFiles = response.getFiles();
System.out.println("您上传的文件信息:");
responseFiles.stream().forEach(file->{
System.out.println(file);
});
} else {
System.out.println("errorCode:" + response.getCode() + ",errorMsg:" + response.getMsg());
}
System.out.println("--------------------");
```
客户端使用`UploadFile`添加上传文件
```java
/**
* @param name 表单名称,不能重复
* @param file 文件
* @throws IOException
*/
public UploadFile(String name, File file) throws IOException {
this(name, file.getName(), FileUtil.toBytes(file));
}
```
其中`name`表示字段名称,相当于`<input type="file" name="file1"/>`中的name
源码详见sop-sdk
## 服务端接收文件
- 方式1
```java
/**
* 方式1将文件写在参数中可直接获取。好处是可以校验是否上传
* @param param
* @return
*/
@ApiMapping(value = "demo.file.upload")
public FileUploadVO file1(FileUploadParam param) {
System.out.println(param.getRemark());
// 获取上传的文件
MultipartFile file1 = param.getFile1();
MultipartFile file2 = param.getFile2();
...
return vo;
}
@Data
public class FileUploadParam {
private String remark;
// 上传文件字段名称对应表单中的name属性值
@NotNull(message = "文件1不能为空")
private MultipartFile file1;
@NotNull(message = "文件2不能为空")
private MultipartFile file2;
}
```
方式1的好处是可以使用`JSR-303`校验文件是否上传
- 方式2
```java
/**
* 方式2从request中获取上传文件
*
* @param param
* @return
*/
@ApiMapping(value = "demo.file.upload2")
public FileUploadVO file2(FileUploadParam2 param, HttpServletRequest request) {
System.out.println(param.getRemark());
FileUploadVO vo = new FileUploadVO();
// 获取上传的文件
Collection<MultipartFile> uploadFiles = UploadUtil.getUploadFiles(request);
...
return vo;
}
```
微服务端源码参考`FileUploadDemoController.java`

View File

@@ -1,90 +0,0 @@
# nacos注册中心
使用nacos作为注册中心源码在`registry-nacos`分支
这里演示如何将默认的eureka注册中心替换成nacos步骤如下
- 准备工作
1.安装nacos前往[最新稳定版本](https://github.com/alibaba/nacos/releases)下载最新版nacos
2.启动nacos服务器cd nacos/bin
Linux/Unix/Mac启动命令(standalone代表着单机模式运行非集群模式):
`sh startup.sh -m standalone`
Windows启动命令
`cmd startup.cmd`
或者双击startup.cmd运行文件。
更多访问https://nacos.io/zh-cn/docs/quick-start.html
- 微服务端修改
1.修改微服务应用pom打开`sop-example/sop-story/sop-story-web/pom.xml`注释eureka服务发现依赖添加nacos服务发现依赖
```xml
<!-- 注册中心【只能用一个,不用的注释掉】 -->
<!-- 使用eureka注册中心
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
-->
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<!-- 注册中心end -->
```
2.yml文件新增nacos配置并注释掉eureka相关配置
```yaml
spring:
cloud:
# nacos注册中心和eureka只能用一个
nacos:
discovery:
server-addr: 127.0.0.1:8848
```
- 网关修改
找到`sop-gateway`工程,步骤同上
- SOP-admin修改
修改yml文件设置nacos服务器地址`registry.name`填nacos
```yaml
# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册
registry:
eureka-server-addr: http://localhost:1111/eureka/
# nacos服务器地址
nacos-server-addr: 127.0.0.1:8848
# 使用eurekaeureka使用nacos填nacos
name: nacos
```
- website-server修改
步骤同`SOP-admin修改`
如果要改成consul注册中心可参照以上步骤。
- 参考资料
1.[nacos介绍及安装](https://nacos.io/zh-cn/docs/quick-start.html)
2.[nacos spring cloud注册发现](https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html)

View File

@@ -1,112 +0,0 @@
# 扩展其它注册中心
**注: nacos注册中心已经实现本篇以nacos为例介绍如何扩展如果要改成consul可按照此方式进行修改**
SOP默认使用eureka注册中心如果要换成nacos注册中心步骤如下
- 实现`com.gitee.sop.registryapi.service.RegistryService`接口
1.找到`SOP/sop-common/sop-registry-api`工程在service.impl包下新建一个类实现RegistryService接口
```java
public class RegistryServiceNacos implements RegistryService {
@Override
public List<ServiceInfo> listAllService(int pageNo, int pageSize) throws Exception {
// TODO: 返回服务实例
}
@Override
public void onlineInstance(ServiceInstance serviceInstance) throws Exception {
// TODO: 实例上线
}
@Override
public void offlineInstance(ServiceInstance serviceInstance) throws Exception {
// TODO: 实例下线
}
}
```
2.在`com.gitee.sop.registryapi.config.BaseRegistryConfig`中新增
```java
/**
* 当配置了registry.name=nacos生效
*
* @return
*/
@Bean
@ConditionalOnProperty(prefix = "registry", name = "name", havingValue = "nacos")
RegistryService registryServiceNacos() {
return new RegistryServiceNacos();
}
```
其中`@ConditionalOnProperty(prefix = "registry", name = "name", havingValue = "nacos")`
表示`application.properties`配置了`registry.name=nacos`参数才能生效registry.name=nacos下文会讲到。
- 微服务端修改
1.修改微服务应用pom.xml注释eureka服务发现依赖添加nacos服务发现依赖
```xml
<!-- 注册中心【只能用一个,不用的注释掉】 -->
<!-- 使用eureka注册中心
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
-->
<!-- 使用nacos注册中心
版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 对应的是 Spring Boot 1.x 版本。
https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
<!-- 注册中心end -->
```
2.yml文件新增nacos配置并注释掉eureka相关配置
```yaml
spring:
cloud:
# nacos注册中心和eureka只能用一个
nacos:
discovery:
server-addr: 127.0.0.1:8848
```
- 网关修改
找到`sop-gateway`工程,步骤同上
- SOP-admin修改
修改yml文件新增nacos服务器地址`registry.name`填nacos
```yaml
# 注册中心地址,根据实际情况改,这里只是参数,并不会去注册
registry:
# 使用eurekaeureka使用nacos填nacos
name: nacos
eureka-server-addr: http://localhost:1111/eureka/
nacos-server-addr: 127.0.0.1:8848
```
- website-server修改
步骤同`SOP-admin修改`
- 参考资料
1.[nacos介绍及安装](https://nacos.io/zh-cn/docs/quick-start.html)
2.[nacos spring cloud注册发现](https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html)

View File

@@ -1,104 +0,0 @@
# 配置Sleuth链路追踪
配置了Sleuth可以很方便查看微服务的调用路线图可快速定位问题。
SOP基于SpringCloud因此只要整合[Spring Cloud Sleuth](https://spring.io/projects/spring-cloud-sleuth)即可。
除此之外还需要支持dubbo的链路的跟踪Sleuth在2.0已经对dubbo做了支持详见[brave-instrumentation-dubbo-rpc](https://github.com/openzipkin/brave/tree/master/instrumentation/dubbo-rpc)
接入Spring Cloud Sleuth步骤如下
- 下载zipkin服务器
以mac环境为例执行下面命令下载jar并启动zipkin服务
```
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
```
默认端口是9411更多安装方式详见[quickstart](https://zipkin.io/pages/quickstart.html)
- sop-gateway/pom.xml添加依赖
```xml
<!--开启zipkin服务链路跟踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
```
配置文件新增
```properties
# zipkin服务跟踪
spring.zipkin.base-url=http://127.0.0.1:9411/
# 设置sleuth收集信息的比率默认0.1最大是1数字越大越耗性能
spring.sleuth.sampler.probability=1
```
重启sop-gateway
- 打开sop-story-web/pom.xml
添加依赖:
```xml
<!--开启zipkin服务链路跟踪-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- zipkin支持dubbo -->
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave-instrumentation-dubbo-rpc</artifactId>
<version>5.6.6</version>
</dependency>
```
配置文件新增:
```properties
# zipkin服务跟踪
spring.zipkin.base-url=http://127.0.0.1:9411/
# 设置sleuth收集信息的比率默认0.1最大是1数字越大越耗性能
spring.sleuth.sampler.probability=1
# dubbo使用zipkin过滤器
dubbo.provider.filter=tracing
dubbo.consumer.filter=tracing
```
重启服务
- 打开sop-book/sop-book-web/pom.xml
步骤同上
- 运行DubboDemoTest.java单元测试
运行完毕看控制台,找到日志信息
```text
2019-07-18 16:22:04.438 INFO [story-service,59dae98250b276bd,60828035658f175f,true] 90553 --- [:12345-thread-2] c.g.s.s.service.DefaultDemoService : dubbo provider, param: DemoParam(id=222)
```
日志内容多了`[story-service,59dae98250b276bd,60828035658f175f,true]`部分这些是zipkin加进去的说明如下
```text
story-service服务名称
59dae98250b276bdtraceId
60828035658f175fspanId
true是否上传到zipkin服务器
```
查看各个服务的控制台可以发现traceId是一致的。
- 浏览器打开http://127.0.0.1:9411/
将traceId复制黏贴到右上角文本框进行查询可看到服务调用链。
![预览](images/10109_1.png "10109_1.png")

View File

@@ -1,46 +0,0 @@
# 预发布灰度发布
从1.14.0开始支持预发布、灰度发布,可登陆`SOP-Admin`,然后选择`服务列表`进行操作。
## 使用预发布
假设网关工程在阿里云负载均衡有两台服务器,域名分别为:
|域名|说明|
|:---- |:---- |
|open1.domain.com |网关服务器1 |
|openpre.domain.com | 网关服务器2作为预发布请求入口|
线上网关入口为`http://open.domain.com/api`,请求网关`http://open.domain.com/api`会负载均衡到这两台服务器
SOP开启预发布步骤如下
修改网关工程配置文件,指定预发布域名
```properties
# 预发布网关域名
pre.domain=openpre.domain.com
```
重启网关
微服务启动参数添加:`--eureka.instance.metadata-map.env=pre`
建议线上配两套启动脚本,其中预发布启动脚本添加启动参数`--eureka.instance.metadata-map.env=pre`
登录SOP-Admin在服务列表中点击预发布然后预发布请求地址变成`http://openpre.domain.com/api`
`openpre.domain.com`请求进来的用户都会进预发布服务器,其它情况都走非预发布服务器。
## 使用灰度发布
灰度发布可允许指定的用户访问灰度服务器,其它用户还是走正常流程。
微服务启动参数添加:`--eureka.instance.metadata-map.env=gray`
登录SOP-Admin前往服务列表。
- 先设置灰度参数,指定灰度用户和灰度接口
- 服务器实例开启灰度
参考类:
- PreVersionDecisionFilter.java
- EnvironmentServerChooser.java

View File

@@ -1,33 +0,0 @@
# 动态修改请求参数
自1.14.0开始zuul网关支持动态修改请求参数。即在网关修改客户端传递过来的参数然后发送到微服务端。
```
客户端参数{"name": "jim"} --> zuul中修改为{"name": "Lucy"} --> 微服务端将收到{"name": "Lucy"}
```
使用场景:客户端请求参数经过加密,在网关解密后,再次发送明文参数给微服务端
- 如何使用
在网关springboot启动函数中添加如下代码
```java
public static void main(String[] args) {
ApiConfig.getInstance().setParameterFormatter(requestParams -> {
// 获取biz_content
JSONObject jsonObject = requestParams.getJSONObject(ParamNames.BIZ_CONTENT_NAME);
// 修改biz_content中的值
jsonObject.put("name", "name修改了111");
jsonObject.put("remark", "remark修改了222");
// 重新设置biz_content
requestParams.put(ParamNames.BIZ_CONTENT_NAME, jsonObject);
});
SpringApplication.run(SopGatewayApplication.class, args);
}
```
其中requestParams是客户端传递过来的参数直接修改其中的值即可。
更多参考com.gitee.sop.gatewaycommon.zuul.filter.PreParameterFormatterFilter.java

View File

@@ -1,21 +0,0 @@
# 原理分析之@ApiMapping注解
@ApiMapping注解的使用方式参考了Spring自带的@PostMapping注解
查看org.springframework.web.bind.annotation.PostMapping的类注释有这么一句话
> Specifically, @PostMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST).
翻译过来就是说,@PostMapping是一个组合模式的注解,可以看成是@RequestMapping(method = RequestMethod.POST)快捷方式。
如果我们自己定义个Mapping仿照@PostMapping的方式,然后作用在方法上面会不会成功呢?实践证明是可以的。
@ApiMapping注解正是仿照了@PostMapping注解,然后再添加了几个自己的属性,比如版本号字段。
那么如何才能通过path + 版本号来确定一个接口呢?
springmvc提供了RequestCondition接口来实现这个功能具体的操作可参考这篇文章[让SpringMVC支持可版本管理的Restful接口](http://www.cnblogs.com/jcli/p/springmvc_restful_version.html)
SOP对应的是`com.gitee.sop.servercommon.mapping.ApiMappingRequestCondition`这个类在com.gitee.sop.servercommon.mapping下。可以从`ApiMappingHandlerMapping`类开始解读。

View File

@@ -1,25 +0,0 @@
# 原理分析之路由存储
SOP将路由信息存到了zookeeper当中服务在启动时将自己的路由信息上传到zookeeper中。
网关监听存放路由的节点,动态更新到本地。
zookeeper存储路由的结构如下
```xml
/com.gitee.sop.route 根节点
/serviceId 服务节点,名字为服务名
/route1 路由节点名字为name+version存放路由信息
/route2
/...
```
服务启动时,创建`/serviceId`节点,然后遍历创建`/routeN`节点
同时,网关监听`服务节点``路由节点`,当有新服务加入时,网关会获取到新加入的路由节点信息,
同时路由节点下面的子节点也会被监听到。后续子节点的增删改都会被网关监听到,然后更新到本地。
服务上传路由相关代码在`com.gitee.sop.servercommon.manager.ServiceZookeeperApiMetaManager`类中
网关监听相关代码在`com.gitee.sop.gatewaycommon.manager.BaseRouteManager`

View File

@@ -1,77 +0,0 @@
# 原理分析之如何路由
## zuul如何路由
SOP网关默认使用zuul当然也默认使用了zuul提供的路由功能。zuul默认使用过滤器来实现路由转发
我们看下zuul中自带的过滤器
| 类型 | 顺序 | 过滤器 | 功能 |
| ----- | ---- | ----------------------- | ---------------------------- |
| pre | -3 | ServletDetectionFilter | 标记处理 Servlet 的类型 |
| pre | -2 | Servlet30WrapperFilter | 包装 HttpServletRequest 请求 |
| pre | -1 | FormBodyWrapperFilter | 包装请求体 |
| pre | 1 | DebugFilter | 标记调试标志 |
| pre | 5 | PreDecorationFilter | 决定路由转发过滤器 |
| route | 10 | RibbonRoutingFilter | serviceId 请求转发 |
| route | 100 | SimpleHostRoutingFilter | url 请求转发 |
| route | 500 | SendForwardFilter | forward 请求转发 |
| post | 0 | SendErrorFilter | 处理有错误的请求响应 |
| post | 1000 | SendResponseFilter | 处理正常的请求响应 |
上图就是zuul提供的默认过滤器可在org.springframework.cloud.netflix.zuul.filters下查看。
zuul的过滤器顺序值小的优先执行其中的`PreDecorationFilter`是我们重点关注的类,由它来决定路由转发去向。
打开PreDecorationFilter类看到类注释有一句话`that determines where and how to route based on the supplied`
翻译过来就是说,决定从哪里获取路由,然后怎样去路由。
PreDecorationFilter类的核心方法是run()方法。找到run方法中这一句代码
`Route route = this.routeLocator.getMatchingRoute(requestURI);`
这句代码很重要表示路由从哪里获取如果我们能够重写getMatchingRoute方法那就可以返回自己定义的路由了。
接下来找到RouteLocator类的定义发现是通过构造方法传进来的那么我们就去找使用构造方法的类。IDEA下右键构造方法--Find Usage
在org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration类中找到了定义
```java
// pre filters
@Bean
@ConditionalOnMissingBean(PreDecorationFilter.class)
public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator, ProxyRequestHelper proxyRequestHelper) {
return new PreDecorationFilter(routeLocator, this.server.getServlet().getContextPath(), this.zuulProperties,
proxyRequestHelper);
}
```
方法默认注入了RouteLocator类默认注入的实现是CompositeRouteLocator类通过打断点可以查看
同时方法上用了`@ConditionalOnMissingBean`注解,表示如果其它地方没有声明,则默认使用这个。
因此我们可以自己声明一个PreDecorationFilter然后注入自定义的RouteLocator就行了。
SOP自定义的RouteLocator为`com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator`,可自行前往查看。
然后再我们的Config中定义
```java
/**
* 选取路由
* @param zuulRouteRepository
* @param proxyRequestHelper
* @return
*/
@Bean
public PreDecorationFilter preDecorationFilter(ZuulRouteRepository zuulRouteRepository, ProxyRequestHelper proxyRequestHelper) {
// 自定义路由
RouteLocator routeLocator = new SopRouteLocator(zuulRouteRepository);
return new PreDecorationFilter(routeLocator,
this.server.getServlet().getContextPath(),
this.zuulProperties,
proxyRequestHelper);
}
```
到此我们只需要实现RouteLocator接口就能使用zuul默认的路由功能非常方便。

View File

@@ -1,26 +0,0 @@
# 原理分析之文档归纳
作为开放平台必须要提供API文档。
SOP采用微服务架构实现因此文档应该由各个微服务各自实现。难点是如何归纳各个微服务端提供的文档信息并统一展示。
SOP的解决思路如下
- 各微服务使用swagger定义自己的接口信息
- sop-website项目在启动时向注册中心获取所有服务实例分别调用各个服务提供的swagger文档信息保存到本地
- sop-website前端页面负责展示swagger提供的文档信息
由于注册中心的存在可以很方便的获取每个微服务提供的接口因此可以获取到swagger提供的文档信息。
如此一来的好处是各微服务不用关心文档该怎么展示只需要写好swagger注解即可文档信息展示统一交给另外一个工程来维护各司其职。
SOP设计初衷亦是如此微服务只管写业务代码其它的都交给SOP来处理。
文档归纳原理图:
![文档归纳原理图](images/90013_1.png "10090_1.png")
- sop-website服务启动时向各微服务获取接口信息保存到本地
- 用户访问website页面website提供对应的接口文档并展示

View File

@@ -1,105 +0,0 @@
# 常见问题
## 微服务端如何获取appId等参数
```java
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
String appId = openContext.getAppId();
```
## 在其它地方获取业务参数
```java
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
Story bizObject = (Story)openContext.getBizObject();
OpenContext openContext = ServiceContext.getCurrentContext().getOpenContext();
Story bizObject = openContext.getBizObject(Story.class);
```
## Socket error occurred: `localhost/0:0:0:0:0:0:0:1:2181`: Connection refused
检查本地zookeeper有没启动如果zookeeper在其他机器上修改application-dev.yml
```yaml
cloud:
zookeeper:
connect-string: ip:2181
```
## 如何关闭签名验证
- 针对某一个接口关闭签名验证
`@ApiMapping(value = "alipay.story.get", ignoreValidate = true)`
- 针对所有接口关闭签名验证
```java
@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {
static {
...
ApiConfig.getInstance().setIgnoreValidate(true);
...
}
}
```
## 注册到eureka显示hostname非ip
```yaml
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
```
```xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
```
参考https://www.jianshu.com/p/5ad8317961b7
## 直接访问服务的swagger-ui.html 提示access forbidden
找到微服务的`OpenServiceConfig.java`重写内部类Swagger2中的swaggerAccessProtected()方法返回false。线上请设置成true
```java
// 开启文档
@Configuration
@EnableSwagger2
public static class Swagger2 extends SwaggerSupport {
@Override
protected String getDocTitle() {
return "故事API";
}
@Override
protected boolean swaggerAccessProtected() {
return false;
}
}
```
## 调试网关出现服务不可用
打断点调试网关出现Read Timeout
参考https://blog.csdn.net/qq_36872046/article/details/81058045
yml添加
```yaml
ribbon:
# https://blog.csdn.net/qq_36872046/article/details/81058045
# 路由转发超时时间毫秒默认值1000详见RibbonClientConfiguration.DEFAULT_READ_TIMEOUT。
# 如果微服务端 处理时间过长会导致ribbon read超时解决办法将这个值调大一点
ReadTimeout: 60000
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -1,68 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SOP开发文档</title>
<link rel="icon" href="_media/favicon.ico">
<meta name="google-site-verification" content="6t0LoIeFksrjF4c9sqUEsVXiQNxLp2hgoqo0KryT-sE" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="keywords" content="doc,docs,documentation,gitbook,creator,generator,github,jekyll,github-pages">
<meta name="description" content="A magical documentation generator.">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css" title="vue" >
<style>
nav.app-nav li ul {
min-width: 100px;
}
/* 显示区域宽度 */
.markdown-section{
max-width: 90%;
}
.sidebar li {
margin: 0px 0;
}
</style>
</head>
<body>
<div id="app">加载中 ...</div>
<script>
window.$docsify = {
alias: {
'/.*/_sidebar.md': '/_sidebar.md?t=' + new Date().getTime()
},
auto2top: true,
coverpage: false,
executeScript: true,
loadSidebar: true,
loadNavbar: false,
mergeNavbar: true,
maxLevel: 3,
subMaxLevel: 2,
ga: 'UA-106147152-1',
name: '',
search: {
noData: {
'/zh-cn/': '没有结果!',
'/': '没有结果!'
},
paths: 'auto',
placeholder: {
'/zh-cn/': '搜索',
'/': '搜索'
}
},
formatUpdated: '{MM}/{DD} {HH}:{mm}'
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-java.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-json.min.js"></script>
</body>
</html>

View File

@@ -1,49 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>doc</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<!-- Generic properties -->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包时跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1 +0,0 @@
docsify serve docs

View File

@@ -1,55 +0,0 @@
const liveServer = require('live-server')
const isSSR = !!process.env.SSR
const middleware = []
if (isSSR) {
const Renderer = require('./packages/docsify-server-renderer/build.js')
const renderer = new Renderer({
template: `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>docsify</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="/themes/vue.css" title="vue">
</head>
<body>
<!--inject-app-->
<!--inject-config-->
<script src="/lib/docsify.js"></script>
</body>
</html>`,
config: {
name: 'docsify',
repo: 'docsifyjs/docsify',
basePath: 'https://docsify.js.org/',
loadNavbar: true,
loadSidebar: true,
subMaxLevel: 3,
auto2top: true,
alias: {
'/de-de/changelog': '/changelog',
'/zh-cn/changelog': '/changelog',
'/changelog':
'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG'
}
},
path: './'
})
middleware.push(function(req, res, next) {
if (/\.(css|js)$/.test(req.url)) {
return next()
}
renderer.renderToString(req.url).then(html => res.end(html))
})
}
const params = {
port: 3000,
watch: ['lib', 'docs', 'themes'],
middleware
}
liveServer.start(params)

View File

@@ -1,96 +0,0 @@
package com.gitee.sop.doc;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 生成_sidebar.md文件直接运行即可
*
* @author tanghc
*/
public class SidebarTest {
static String format = " * [%s](files/%s?t=%s)\r\n";
static Map<String, Menu> levelMap = new HashMap<>(8);
static {
int i = 0;
levelMap.put("1", new Menu("* 开发文档\n", i++));
levelMap.put("9", new Menu("* 原理分析\n", i++));
}
public static void main(String[] args) throws Exception {
String path = SidebarTest.class.getClassLoader().getResource("").getPath();
String root = path.substring(0, path.indexOf("doc")) + "doc";
String fileDir = root + "/docs/files";
File dir = new File(fileDir);
File[] files = dir.listFiles();
Stream<File> filesStream = Stream.of(files);
Map<String, List<FileExt>> menuMap = filesStream
.sorted(Comparator.comparing(File::getName))
.map(file -> {
if (file.isDirectory()) {
return null;
}
FileExt fileExt = new FileExt();
fileExt.menu = file.getName().substring(0, 1);
fileExt.file = file;
return fileExt;
})
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(FileExt::getMenu));
StringBuilder output = new StringBuilder();
output.append("* [首页](/?t=" + System.currentTimeMillis() + ")\n");
for (Map.Entry<String, List<FileExt>> entry : menuMap.entrySet()) {
Menu menu = levelMap.get(entry.getKey());
output.append(menu.parentName);
for (FileExt fileExt : entry.getValue()) {
String filename = fileExt.file.getName();
String title = filename.substring(filename.indexOf("_") + 1, filename.length() - 3);
String line = String.format(format, title, filename, System.currentTimeMillis());
output.append(line);
}
}
System.out.println(output);
String sidebarFilepath = root + "/docs/_sidebar.md";
FileOutputStream out = new FileOutputStream(new File(sidebarFilepath));
out.write(output.toString().getBytes());
out.close();
}
static class Menu {
String parentName;
int order;
public Menu(String parentName, int order) {
this.parentName = parentName;
this.order = order;
}
}
static class FileExt {
File file;
String menu;
public File getFile() {
return file;
}
public String getMenu() {
return menu;
}
}
}

12
docker-build.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
# 打包
mvn clean package
# 创建镜像
docker build -t gitee.com/sop .
# 获取镜像id
image_id=`docker images gitee.com/sop --format "{{.ID}}" | awk '{print $1}'`
# 运行镜像
docker run --name sop -p 8081:8081 -p 8082:8082 -p 8083:8083 -p 8087:8087 -p 2222:2222 -d $image_id

11
docker-entrypoint.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
JAVA_OPTS="-Xms128m -Xmx128m"
# mysql, nacos配置
args="--mysql.host=10.1.30.110:3306 --mysql.username=root --mysql.password=root --dubbo.registry.address=10.1.30.110:8848"
java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /sop/sop-gateway/sop-gateway.jar $args --logging.file.path=/sop/sop-gateway/log &
java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /sop/sop-admin/sop-admin.jar $args --logging.file.path=/sop/sop-admin/log &
# 最后一条没有&
java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /sop/sop-story/sop-story.jar $args --logging.file.path=/sop/sop-story/log

BIN
gen.db Normal file

Binary file not shown.

233
pom.xml Normal file → Executable file
View File

@@ -2,23 +2,238 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.15</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<description>一个开放平台解决方案项目基于Spring Cloud实现目标是能够让用户快速得搭建起自己的开放平台</description>
<description>一个开放平台解决方案项目基于Dubbo实现目标是能够让用户快速得搭建起自己的开放平台</description>
<modules>
<module>doc</module>
<module>sop-common</module>
<module>sop-example</module>
<module>sop-admin</module>
<module>sop-registry</module>
<module>sop-gateway</module>
<module>sop-website</module>
<module>sop-test</module>
<module>sop-sdk</module>
<module>sop-website</module>
<module>sop-gateway</module>
<module>sop-registry</module>
<module>sop-support</module>
<module>sop-notify</module>
</modules>
</project>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- springboot 版本-->
<spring-boot.version>2.6.15</spring-boot.version>
<!-- spring cloud 版本 -->
<spring-cloud.version>2021.0.5</spring-cloud.version>
<!-- spring cloud alibaba 版本 -->
<!-- 具体版本对应关系见https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E -->
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
<!-- dubbo版本 -->
<dubbo.version>3.2.16</dubbo.version>
<junit.version>4.11</junit.version>
<commons-io.version>2.5</commons-io.version>
<commons-fileupload.version>1.3.3</commons-fileupload.version>
<commons-collection.version>3.2.2</commons-collection.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<commons-codec.version>1.11</commons-codec.version>
<commons-logging.version>1.2</commons-logging.version>
<validation-api.version>2.0.1.Final</validation-api.version>
<hibernate-validator.version>6.0.13.Final</hibernate-validator.version>
<fastmybatis.version>3.1.7</fastmybatis.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 加了这个就不需要加版本号了 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.gitee.durcframework</groupId>
<artifactId>fastmybatis-spring-boot-starter</artifactId>
<version>${fastmybatis.version}</version>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>http-helper</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.52</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.7</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${validation-api.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
<!-- commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collection.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<build>
<plugins>
<!-- 打包时跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

21
script/startup.sh Normal file
View File

@@ -0,0 +1,21 @@
#!/bin/sh
# 执行文件名称
app_name=${1}
if [ -z "${1}" ];then
echo "未指定应用程序参数,格式:sh startup.sh xxx.jar"
exit 0
fi
echo "启动程序:${app_name}"
# 先关闭服务
pid=$(ps -ef | grep $app_name | grep -v grep | grep -v .sh | awk '{print $2}')
if [ -n "$pid" ]; then
echo "stop $app_name, pid:$pid"
kill -9 "$pid"
fi
nohup java -server -jar -Dspring.profiles.active=test -Duser.timezone=Asia/Shanghai -Xms512m -Xmx512m $app_name >/dev/null 2>&1 &

View File

@@ -1,13 +0,0 @@
DROP TABLE IF EXISTS `config_common`;
CREATE TABLE `config_common` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`config_group` varchar(64) NOT NULL DEFAULT '' COMMENT '配置分组',
`config_key` varchar(64) NOT NULL DEFAULT '' COMMENT '配置key',
`content` varchar(128) NOT NULL DEFAULT '' COMMENT '内容',
`remark` varchar(128) DEFAULT NULL COMMENT '备注',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_groupkey` (`config_group`,`config_key`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='通用配置表';

View File

@@ -1,20 +0,0 @@
DROP TABLE IF EXISTS `isv_keys`;
CREATE TABLE `isv_keys` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`app_key` varchar(128) NOT NULL DEFAULT '应用id交给开发者',
`sign_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1:RSA2,2:MD5',
`secret` varchar(200) NOT NULL DEFAULT '' COMMENT 'sign_type=2时使用',
`key_format` tinyint(4) NOT NULL DEFAULT '1' COMMENT '秘钥格式1PKCS8(JAVA适用)2PKCS1(非JAVA适用)',
`public_key_isv` text NOT NULL COMMENT '开发者生成的公钥',
`private_key_isv` text NOT NULL COMMENT '开发者生成的私钥(交给开发者)',
`public_key_platform` text NOT NULL COMMENT '平台生成的公钥(交给开发者)',
`private_key_platform` text NOT NULL COMMENT '平台生成的私钥',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_appkey` (`app_key`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ISV秘钥';
INSERT INTO `sop`.`isv_keys` (`app_key`,`sign_type`, `secret`,`key_format`, `public_key_isv`, `private_key_isv`, `public_key_platform`, `private_key_platform`)
select app_key, sign_type, secret, 1, pub_key,pri_key,'','' from isv_info;

View File

@@ -1,2 +0,0 @@
ALTER TABLE `sop`.`isv_info` ADD COLUMN `remark` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注' AFTER `sign_type`;

View File

@@ -1,11 +0,0 @@
use sop;
CREATE TABLE `config_ip_blacklist` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(64) NOT NULL DEFAULT '' COMMENT 'ip',
`remark` varchar(128) DEFAULT NULL COMMENT '备注',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_ip` (`ip`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='IP黑名单';

View File

@@ -1,25 +0,0 @@
use sop;
CREATE TABLE `config_gray` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`service_id` varchar(64) NOT NULL DEFAULT '',
`user_key_content` text COMMENT '用户key多个用引文逗号隔开',
`name_version_content` text COMMENT '需要灰度的接口goods.get1.0=1.2,多个用英文逗号隔开',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_serviceid` (`service_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='服务灰度配置';
CREATE TABLE `config_gray_instance` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`instance_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'instance_id',
`service_id` varchar(64) NOT NULL DEFAULT '' COMMENT 'service_id',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0禁用1启用',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_instanceid` (`instance_id`) USING BTREE,
KEY `idx_serviceid` (`service_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='开启灰度服务器实例';

View File

@@ -1,3 +0,0 @@
ALTER TABLE `sop`.`isv_info` ADD COLUMN `sign_type` TINYINT NOT NULL DEFAULT 1 COMMENT '签名类型1:RSA2,2:MD5' AFTER `status`;
update isv_info set sign_type=2 where secret <> '';

View File

@@ -1,16 +0,0 @@
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL DEFAULT '' COMMENT '用户名',
`password` varchar(128) NOT NULL DEFAULT '' COMMENT '密码',
`nickname` varchar(64) NOT NULL DEFAULT '' COMMENT '昵称',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_unamepwd` (`username`,`password`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';
INSERT INTO `user_info` ( `username`, `password`, `nickname`, `gmt_create`, `gmt_modified`) VALUES
('zhangsan','123456','张三','2019-04-27 08:32:57','2019-04-27 08:32:57');

View File

@@ -1,32 +0,0 @@
DROP TABLE IF EXISTS `config_limit`;
CREATE TABLE `config_limit` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`route_id` varchar(128) DEFAULT NULL COMMENT '路由id',
`app_key` varchar(128) DEFAULT NULL,
`limit_ip` varchar(300) DEFAULT NULL COMMENT '限流ip多个用英文逗号隔开',
`service_id` varchar(64) NOT NULL DEFAULT '' COMMENT '服务id',
`limit_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '限流策略1漏桶策略2令牌桶策略',
`exec_count_per_second` int(11) DEFAULT NULL COMMENT '每秒可处理请求数',
`limit_code` varchar(64) DEFAULT NULL COMMENT '返回的错误码',
`limit_msg` varchar(100) DEFAULT NULL COMMENT '返回的错误信息',
`token_bucket_count` int(11) DEFAULT NULL COMMENT '令牌桶容量',
`limit_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '限流开启状态1:开启0关闭',
`order_index` int(11) NOT NULL DEFAULT '0' COMMENT '顺序,值小的优先执行',
`remark` varchar(128) DEFAULT NULL COMMENT '备注',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='限流配置';
INSERT INTO `config_limit` (`id`, `route_id`, `app_key`, `limit_ip`, `service_id`, `limit_type`, `exec_count_per_second`, `limit_code`, `limit_msg`, `token_bucket_count`, `limit_status`, `order_index`, `remark`, `gmt_create`, `gmt_modified`) VALUES
(1,'alipay.story.get1.0','','192.168.1.1,172.2.2.3','story-service',2,5,'','',6,1,3,NULL,'2019-05-17 19:21:35','2019-05-21 09:12:15'),
(2,'alipay.story.get1.0','2019032617262200001','','story-service',1,5,'service-budy','服务器忙',5,1,0,NULL,'2019-05-17 19:39:30','2019-05-21 15:36:52'),
(3,'alipay.story.find1.0','20190331562013861008375808','','story-service',1,3,'service-busy','服务器忙',5,1,1,NULL,'2019-05-17 20:20:32','2019-05-20 17:40:17'),
(4,'alipay.story.get1.2','','','story-service',2,5,'','',3,1,1,NULL,'2019-05-20 16:27:21','2019-05-21 15:53:10'),
(5,'','20190401562373796095328256','','story-service',1,5,'service-busy','服务器忙',5,1,0,'这个appKey调用很频繁重点照顾','2019-05-21 15:48:08','2019-05-21 18:45:32'),
(6,'','','10.1.30.54','story-service',1,5,'service-busy','服务器忙',5,1,0,'这个ip在攻击我们','2019-05-21 15:55:33','2019-05-21 18:17:29'),
(7,'story.get1.1','','10.1.30.54','story-service',1,5,'service-busy','服务器忙',5,1,0,NULL,'2019-05-21 16:30:48','2019-05-21 16:30:48'),
(8,'','20190513577548661718777857','10.1.30.54','story-service',1,5,'service-busy','服务器忙',5,1,0,NULL,'2019-05-21 17:10:45','2019-05-21 17:10:52');

14
sop-admin/pom.xml Normal file → Executable file
View File

@@ -2,14 +2,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.sop</groupId>
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
</parent>
<artifactId>sop-admin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>sop-admin-front</module>
<module>sop-admin-server</module>
<module>sop-admin-backend</module>
<module>sop-code-gen</module>
</modules>
</project>
</project>

7
sop-admin/readme.md Normal file → Executable file
View File

@@ -1,5 +1,6 @@
# 后台admin
- sop-admin-front: admin前端layui实现(停止维护改用sop-admin-vue)
- sop-admin-server: admin服务端
- sop-admin-vue: admin前端vue实现
- sop-admin-backend: admin服务端
- sop-admin-frontend: admin前端实现
- sop-code-gen: 代码生成器

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-admin-backend</artifactId>
<version>5.0.0-SNAPSHOT</version>
</parent>
<artifactId>admin-boot</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>admin-web</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- nacos注册中心 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
</dependency>
<!-- zookeeper注册中心 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-zookeeper-curator5-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- provided -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<build>
<finalName>sop-admin-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 打包时跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,15 @@
package com.gitee.sop.admin;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo
public class SopAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SopAdminApplication.class, args);
}
}

View File

@@ -0,0 +1,17 @@
package com.gitee.sop.admin.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author 六如
*/
@Configuration
@ConfigurationProperties(prefix = "admin")
@Data
public class AdminConfig {
private int jwtTimeoutDays;
}

View File

@@ -0,0 +1,106 @@
package com.gitee.sop.admin.config;
import com.gitee.sop.admin.common.context.SpringContext;
import com.gitee.sop.admin.common.util.SystemUtil;
import com.gitee.sop.admin.interceptor.LoginInterceptor;
import com.gitee.sop.admin.service.sys.UserCacheService;
import com.gitee.sop.admin.service.sys.impl.LocalUserCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 六如
*/
@Configuration
@Slf4j
public class SopAdminConfiguration implements ApplicationContextAware, WebMvcConfigurer {
@Value("${front-location:}")
private String frontLocation;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContext.setApplicationContext(applicationContext);
}
@Bean
@ConditionalOnProperty(value = "user.cache.type", havingValue = "local", matchIfMissing = true)
public UserCacheService userCacheService() {
return new LocalUserCacheService();
}
/**
* 配置拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
String[] excludes = {
"/", "/error",
// 排除前端资源
"/*.html", "/*.ico", "/*.png", "/*.json", "/static/**", "/assets/**"
};
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns(excludes);
}
/**
* 跨域设置
*/
@Bean
public CorsFilter corsFilter(
@Value("${torna.cors.allowed-origin-pattern:*}") String allowedOriginPattern,
@Value("${torna.cors.allowed-header:*}") String allowedHeader
) {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// SpringBoot升级2.4.0之后,跨域配置中的.allowedOrigins不再可用,改成addAllowedOriginPattern
corsConfiguration.addAllowedOriginPattern(allowedOriginPattern);
corsConfiguration.addAllowedHeader(allowedHeader);
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
corsConfiguration.addExposedHeader("Content-Disposition");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
/**
* 配置静态资源
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String homeDir = SystemUtil.getBinPath();
String frontRoot;
if (StringUtils.hasText(frontLocation)) {
frontRoot = StringUtils.trimTrailingCharacter(frontLocation, '/');
} else {
frontRoot = homeDir + "/dist";
}
log.info("前端资源目录:{}", frontRoot);
String location = "file:" + frontRoot;
registry.addResourceHandler("/index.html").addResourceLocations(location + "/index.html");
registry.addResourceHandler("/favicon.ico").addResourceLocations(location + "/favicon.ico");
registry.addResourceHandler("/logo.png").addResourceLocations(location + "/logo.png");
registry.addResourceHandler("/platform-config.json").addResourceLocations(location + "/platform-config.json");
registry.addResourceHandler("/static/**").addResourceLocations(location + "/static/");
registry.addResourceHandler("/assets/**").addResourceLocations(location + "/assets/");
}
}

View File

@@ -0,0 +1,45 @@
package com.gitee.sop.admin.interceptor;
import com.gitee.sop.admin.common.annotation.NoToken;
import com.gitee.sop.admin.common.enums.StatusEnum;
import com.gitee.sop.admin.common.user.User;
import com.gitee.sop.admin.common.context.UserContext;
import com.gitee.sop.admin.common.exception.LoginFailureException;
import com.gitee.sop.admin.common.util.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author tanghc
*/
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
NoToken noLogin = handlerMethod.getMethodAnnotation(NoToken.class);
if (noLogin != null) {
return true;
}
noLogin = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), NoToken.class);
if (noLogin != null) {
return true;
}
User user = UserContext.getUser(request);
if (user == null || StatusEnum.of(user.getStatus()) == StatusEnum.DISABLED) {
log.error("登录失败, 客户端ip:{}, uri:{}", RequestUtil.getIP(request), request.getRequestURI());
throw new LoginFailureException("登录失败");
}
return true;
}
}

View File

@@ -0,0 +1,9 @@
dubbo.registry.address=zookeeper://localhost:2181
mybatis.print-sql=true
# mysql config
mysql.host=127.0.0.1:3306
mysql.db=sop
mysql.username=root
mysql.password=root

View File

@@ -0,0 +1,9 @@
dubbo.registry.address=nacos://localhost:8848
mybatis.print-sql=true
# mysql config
mysql.host=127.0.0.1:3306
mysql.db=sop
mysql.username=root
mysql.password=root

View File

@@ -0,0 +1,52 @@
server.port=8082
spring.profiles.active=dev
spring.application.name=sop-admin
index.path=/
####### admin config #######
# user cache
user.cache.type=local
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.application.qos-enable=false
dubbo.consumer.check=false
# ### register config see:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/
# ------
# nacos://localhost:8848 Cluster config:nacos://localhost:8848?backup=localshot:8846,localshot:8847
# zookeeper://localhost:2181 Cluster config:zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181
# redis://localhost:6379 Cluster config:redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379
# ------
dubbo.registry.address=zookeeper://localhost:2181
####### mysql config #######
mysql.host=127.0.0.1:3306
mysql.db=sop
mysql.username=
mysql.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://${mysql.host}/${mysql.db}?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
spring.datasource.username=${mysql.username}
spring.datasource.password=${mysql.password}
####### mybatis config #######
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillInsert=add_time
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillUpdate=update_time
mybatis.fill.com.gitee.sop.admin.common.fill.AddByFill=
mybatis.fill.com.gitee.sop.admin.common.fill.UpdateByFill=
# mybatis config file
mybatis.config-location=classpath:mybatis/mybatisConfig.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# log level
logging.level.com.gitee.sop=info
# log path
logging.file.name=logs/sop-admin.log
# print SQL
logging.level.com.gitee.sop.admin.dao=error
logging.level.com.gitee.fastmybatis=info
mybatis.print-sql=false

View File

@@ -0,0 +1,13 @@
package com.gitee.sop.admin;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class BaseTest {
@Test
void contextLoads() {
}
}

View File

@@ -0,0 +1,44 @@
package com.gitee.sop.admin.service;
import com.alibaba.fastjson2.JSON;
import com.gitee.sop.admin.BaseTest;
import com.gitee.sop.admin.service.sys.login.LoginService;
import com.gitee.sop.admin.service.sys.login.dto.LoginDTO;
import com.gitee.sop.admin.service.sys.login.dto.LoginUser;
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.util.Assert;
/**
* @author 六如
*/
public class LoginServiceTest extends BaseTest {
@Autowired
LoginService loginService;
@Test
public void login() {
LoginDTO loginDTO = new LoginDTO();
loginDTO.setUsername("admin");
loginDTO.setPassword("123456");
loginDTO.setRegType(RegTypeEnum.BACKEND);
LoginUser loginUser = loginService.login(loginDTO);
Assert.notNull(loginUser, "not null");
System.out.println(JSON.toJSONString(loginUser));
}
@Test
public void resetAdminPwd() {
// 初始密码
String defPassword = "123456";
defPassword = DigestUtils.sha256Hex(defPassword);
String encodedPassword = BCrypt.hashpw(defPassword, BCrypt.gensalt());
}
}

View File

@@ -0,0 +1,36 @@
package com.gitee.sop.admin.service;
import com.gitee.sop.admin.BaseTest;
import com.gitee.sop.admin.dao.entity.SysUser;
import com.gitee.sop.admin.service.sys.SysUserService;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;
/**
* @author 六如
*/
public class PasswordTest extends BaseTest {
@Autowired
SysUserService sysAdminUserService;
/**
* 重置admin密码
*/
@Test
public void resetAdminPwd() {
String username = "admin";
String defPassword = "123456";
defPassword = DigestUtils.sha256Hex(defPassword);
String encodedPassword = BCrypt.hashpw(defPassword, BCrypt.gensalt());
System.out.println("数据库保存:" + encodedPassword);
sysAdminUserService.query()
.eq(SysUser::getUsername, username)
.set(SysUser::getPassword, encodedPassword)
.update();
}
}

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-admin-backend</artifactId>
<version>5.0.0-SNAPSHOT</version>
</parent>
<artifactId>admin-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-support</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.gitee.durcframework</groupId>
<artifactId>fastmybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- json处理 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>http-helper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Some files were not shown because too many files have changed in this diff Show More