mirror of
https://gitee.com/ChinaLym/shoulder-platform.git
synced 2025-12-30 02:52:27 +00:00
feat:初步适配shoulder 0.6
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
/**/*.log.*
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
3488
doc/shoulder-platform.sql
Normal file
3488
doc/shoulder-platform.sql
Normal file
File diff suppressed because it is too large
Load Diff
1
pom.xml
1
pom.xml
@@ -21,6 +21,7 @@
|
||||
<module>shoulder-pay-center</module>
|
||||
<module>shoulder-storage-center</module>
|
||||
<module>shoulder-backstage</module>
|
||||
<module>shoulder-universal</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,39 @@ USER-CENTER
|
||||
- 日志审计
|
||||
|
||||
|
||||
## 领域模型
|
||||
(个体/组织-组织信息)自然人0..1 - n **用户**1 - n业务载体(如资产:卡、画像、外部站点信息、业务权限等)
|
||||
|
||||
用户 1 - n 角色 1 - n 各种角色信息
|
||||
|
||||
用户 1 - 1..n 操作员 1..n - 1 通行证 1 - 1..n 通行证别名(供外部或扩展认证机制)
|
||||
|
||||
操作员 - 操作权限
|
||||
|
||||
通行证 1 - 1 同行密码
|
||||
|
||||
|
||||
|
||||
## 权限相关:
|
||||
|
||||
依赖 RBAC 模型,业务规则由编码实现。
|
||||
|
||||
|
||||
#### Why NOT ABAC
|
||||
ABAC 与 RBAC 相比,可以动态管理操作所需属性、环境因素,业务场景举例
|
||||
|
||||
`最近 15 天未出境` 且 `戴口罩` 的 `保安` 可以通过 `指纹`+`工牌` 在 `工作时间` `进入` `所属工作区` 的 `监控室`
|
||||
|
||||
- `保安` 是 角色
|
||||
- `指纹`、`工牌` 是 认证令牌
|
||||
- `视力好` 是 属性,可以动态调整,如 `user.lastExitTime - now() > 15 && user.withMask`
|
||||
- `工作时间` `所属工作区` 是环境因素,且可调整,如 `isWorkTime(now()) == true && resource.address == user.workplace`
|
||||
- `进入` 是 动作
|
||||
- `监控室` 是 资源
|
||||
|
||||
通过ABAC实现动态的权限配置过于复杂。需要制定自己的解析语言,且每次判断都要解析规则,对程序的性能也造成严重的影响,即使大规模使用缓存,命中的概率也是非常的小,毕竟太多很多因素都是动态的,需要每次都对规则进行解析并计算。
|
||||
|
||||
|
||||
权限相关:
|
||||
- [RBAC](https://zhuanlan.zhihu.com/p/98559681)
|
||||
- [ACL, DAC, MAC, RBAC, ABAC模型的不同应用场景](https://zhuanlan.zhihu.com/p/70548562)
|
||||
- [服务认证与鉴权](https://zhuanlan.zhihu.com/p/101595143)(适合权限数量较少,如OpenAPI)
|
||||
|
||||
@@ -16,5 +16,11 @@
|
||||
<artifactId>shoulder-auth-center</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
|
||||
<properties>
|
||||
<shoulder.version>0.6-SNAPSHOT</shoulder.version><!-- shoulder-version -->
|
||||
<shoulder.version>0.6</shoulder.version><!-- shoulder-version -->
|
||||
<spring-boot.version>2.3.6.RELEASE</spring-boot.version>
|
||||
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
|
||||
<spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
|
||||
|
||||
@@ -8,3 +8,141 @@ API 服务网关:超时、缓存、熔断、重试、查询聚合、数据校
|
||||
【贴近业务】
|
||||
|
||||
实际应用中,也可以根据自己的设计,将代理网关的能力赋予 API gateway 中。
|
||||
|
||||
- 安全
|
||||
- 租户识别
|
||||
- 调用者识别
|
||||
- 外部调用网关时请求验签、解密
|
||||
- 内部返回给外部、内部调用外部时加签、加密 (字段排序)
|
||||
- 参数校验
|
||||
- 字段控制
|
||||
- 排序
|
||||
- 黑白名单
|
||||
- 额外字段填充/抹除
|
||||
|
||||
- Oauth 验权
|
||||
- 认证
|
||||
- 字段脱敏
|
||||
- 调用源信息解析
|
||||
- 源ip
|
||||
- 源地址
|
||||
- OAuthClient
|
||||
- WEB 攻击抵御
|
||||
- redirect
|
||||
- xss
|
||||
- ssrf
|
||||
- 文件上传
|
||||
- referer
|
||||
- 默认 error 页面
|
||||
- 日志
|
||||
- 日志字段配置(解析方式/位置)、提取、记录
|
||||
- 摘要日志
|
||||
- 审计日志
|
||||
|
||||
- 协议转换
|
||||
- 通信协议转换
|
||||
- HTTP - GRPC
|
||||
- HTTP - DUBBO
|
||||
- ...
|
||||
- 格式转换
|
||||
- 标准错误码与 HTTP 响应码映射
|
||||
- 错误码转换
|
||||
- 错误消息处理
|
||||
- 特殊格式
|
||||
- 数据转换
|
||||
- 上下文
|
||||
- Trace 追踪
|
||||
|
||||
- 流量控制
|
||||
- 流量切换
|
||||
- 流量分组(基于ip/cookie)
|
||||
- 机房转发
|
||||
- 流量复制
|
||||
- 链路分组
|
||||
- 基于应用版本,减少新老版本互通
|
||||
- 基于逻辑区域
|
||||
- 灰度引流
|
||||
- 单元分隔(全局存储G/可副本读C/逻辑分区R)
|
||||
- 流量限制
|
||||
- 滑动窗口
|
||||
- 直接用 redis incr (key为当前的秒时间),计算一秒内的请求次数,当value大于 xxx 时,其余的请求丢弃。
|
||||
- 简单、但粒度较粗,可能在极端情况出现双倍流量、容易出现流量尖刺,使得整体响应时间变长体验较差
|
||||
- 漏桶
|
||||
- 遇到压力时流量仍然可控,但即使没有负载,也需要等待漏出,不能容忍突发峰值
|
||||
- 令牌桶【默认】
|
||||
- 比漏桶多了允许一定的突发流量,使用较广泛,最大峰值=桶大小,最大高压值=令牌产出速率
|
||||
|
||||
- 流量回放
|
||||
- 流量记录
|
||||
- 流量重播
|
||||
- 负载均衡
|
||||
- 超时熔断
|
||||
- 数据缓存
|
||||
- 服务降级
|
||||
|
||||
- API 管理
|
||||
- 上线
|
||||
- 下线
|
||||
- 分组
|
||||
- 自定域名
|
||||
- 发布
|
||||
- 灰度
|
||||
- 流程审批
|
||||
- 导入导出
|
||||
- 订阅
|
||||
- 版本管理
|
||||
- OpenAPI
|
||||
- 扩展能力
|
||||
- API 文档
|
||||
- SDK 下载
|
||||
- 页面调试
|
||||
- API 市场
|
||||
- 官网管理
|
||||
|
||||
- 监控告警
|
||||
- 请求数
|
||||
- 流量
|
||||
- 响应时间
|
||||
- 错误率
|
||||
- 异常告警(返回值/波动)
|
||||
- 日志监控
|
||||
- 日志分析
|
||||
- 调用统计
|
||||
- 故障注入
|
||||
- API 巡检
|
||||
- 故障分析(埋点)
|
||||
|
||||
|
||||
## 特点
|
||||
- 高性能
|
||||
- 数据压缩/协议转换,充分利用网络,保证传输效率与质量
|
||||
- 强安全
|
||||
- 加密、验签、认证、鉴权、流控
|
||||
- 高可靠
|
||||
- 充分测试验证,极端环境仍可保证服务响应可控
|
||||
- 高可用
|
||||
- 99.99%+,通过流量限制、引流转发、流量隔离、负载均衡、故障转移、降级、平滑升级等措施全方位避免服务宕机,极端情况仍可通过集群与灾备能力保证可用性。
|
||||
- API 管控
|
||||
- 提供可视化的完整管理方案
|
||||
- 易用性强
|
||||
- 配置、监控、维护通过可视化管理,极易维护
|
||||
|
||||
|
||||
## 其他可选依赖
|
||||
- 用户中心
|
||||
- 开放中心(授权服务器、认证服务器)
|
||||
- (硬件加解密服务器)
|
||||
- (沙箱)
|
||||
- 缓存
|
||||
|
||||
|
||||
|
||||
|
||||
- 脚本语言选型
|
||||
- Groovy,JIT后最快
|
||||
- Aviator 被编译成字节码,不JIT最快,JIT 次之 √
|
||||
- IKExpression 超轻量级
|
||||
- Drools 较重,功能完善,企业级
|
||||
|
||||
|
||||
上线流程 DEV、SIT/TEST、PRE、GRAY、PROD
|
||||
@@ -15,7 +15,7 @@
|
||||
<name>${project.artifactId}</name>
|
||||
|
||||
<properties>
|
||||
<shoulder.version>0.6-SNAPSHOT</shoulder.version><!-- shoulder-version -->
|
||||
<shoulder.version>0.6</shoulder.version><!-- shoulder-version -->
|
||||
<spring-boot.version>2.3.6.RELEASE</spring-boot.version>
|
||||
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
|
||||
<spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.itlym.shoulder.platform.gateway;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
import org.shoulder.core.exception.CommonErrorCodeEnum;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@@ -21,7 +21,7 @@ public class ShoulderApiGateway {
|
||||
}
|
||||
|
||||
@RequestMapping("/fallback")
|
||||
public Mono<RestResult> fallback() {
|
||||
return Mono.just(RestResult.error(CommonErrorCodeEnum.REQUEST_TIMEOUT));
|
||||
public Mono<BaseResult> fallback() {
|
||||
return Mono.just(BaseResult.error(CommonErrorCodeEnum.REQUEST_TIMEOUT));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package cn.itlym.shoulder.platform.gateway.client.impl;
|
||||
import cn.itlym.shoulder.platform.gateway.client.ServiceTokenClient;
|
||||
import cn.itlym.shoulder.platform.gateway.client.dto.param.DeleteServiceTokenParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
import org.shoulder.core.exception.BaseRuntimeException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -55,8 +55,8 @@ public class ServiceTokenClientImpl implements ServiceTokenClient {
|
||||
.post().uri(String.format(GET_ST_BY_ACCESS_TOKEN_URI, accessToken, appId))
|
||||
.accept(APPLICATION_JSON)
|
||||
.retrieve()
|
||||
.bodyToMono(RestResult.class)
|
||||
.map(RestResult::getData)
|
||||
.bodyToMono(BaseResult.class)
|
||||
.map(BaseResult::getData)
|
||||
.cast(Map.class)
|
||||
.map(map -> map.get("st"))
|
||||
.cast(String.class)
|
||||
|
||||
@@ -2,7 +2,7 @@ package cn.itlym.shoulder.platform.gateway.config;
|
||||
|
||||
import cn.itlym.shoulder.platform.gateway.ex.ShoulderGatewayException;
|
||||
import lombok.extern.shoulder.SLog;
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
import org.shoulder.core.exception.ErrorCode;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.web.ResourceProperties;
|
||||
@@ -70,7 +70,7 @@ public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
|
||||
* @param response 如何响应
|
||||
* @return {"httpStatus": 500, "shoulderResponseBody": {"code":"xxx", "msg":"xxx", "data":xxx}}
|
||||
*/
|
||||
public static Map<String, Object> buildErrorAttributes(int httpStatus, RestResult response) {
|
||||
public static Map<String, Object> buildErrorAttributes(int httpStatus, BaseResult response) {
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put(ATTRIBUTE_NAME_HTTP_STATUS, httpStatus);
|
||||
map.put(ATTRIBUTE_NAME_RESPONSE, response);
|
||||
@@ -139,9 +139,9 @@ public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
|
||||
* @param ex 异常
|
||||
* @return 异常信息
|
||||
*/
|
||||
protected RestResult buildResponse(ServerRequest request, Throwable ex) {
|
||||
protected BaseResult buildResponse(ServerRequest request, Throwable ex) {
|
||||
ShoulderGatewayException exception = new ShoulderGatewayException(request, ex);
|
||||
log.error(exception);
|
||||
return RestResult.error(exception);
|
||||
return BaseResult.error(exception);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.itlym.shoulder.platform.gateway.ex;
|
||||
|
||||
public enum CommonError {
|
||||
|
||||
// 配置错误:网关扩展模块加载失败
|
||||
|
||||
// 参数缺失
|
||||
|
||||
// 参数非法
|
||||
|
||||
// 扩展模块处理失败
|
||||
|
||||
// 扩展模块处理异常
|
||||
|
||||
// 集成身份缺失
|
||||
|
||||
// 签名参数缺失
|
||||
|
||||
// 加签失败
|
||||
|
||||
// 验签失败
|
||||
|
||||
// 密钥不存在
|
||||
|
||||
// 加密失败
|
||||
|
||||
// 解密失败
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.itlym.shoulder.platform.gateway.ex;
|
||||
|
||||
/**
|
||||
* 流量类型
|
||||
* @author Admin
|
||||
*/
|
||||
public enum FlowType {
|
||||
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
LOAD_TEST,
|
||||
|
||||
REPLAY,
|
||||
|
||||
SANDBOX,
|
||||
|
||||
SECURITY_SCAN,
|
||||
|
||||
OFFLINE_SCAN,
|
||||
|
||||
;
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>cn.itlym</groupId>
|
||||
<artifactId>shoulder-parent</artifactId>
|
||||
<version>0.6-SNAPSHOT</version><!-- shoulder-version -->
|
||||
<version>0.6</version><!-- shoulder-version -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ import cn.itlym.shoulder.generator.service.SysGeneratorService;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.shoulder.core.dto.response.ListResult;
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
import org.shoulder.core.util.StringUtils;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@@ -49,8 +49,8 @@ public class GeneratorApp {
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping("list")
|
||||
public RestResult<ListResult> list(@RequestParam Map<String, Object> params) {
|
||||
return RestResult.success(sysGeneratorService.queryList(params));
|
||||
public BaseResult<ListResult> list(@RequestParam Map<String, Object> params) {
|
||||
return BaseResult.success(sysGeneratorService.queryList(params));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
#end
|
||||
import org.shoulder.core.dto.response.PageResult;
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import ${package}.${pkgName}.convert.${className}Converter;
|
||||
import ${package}.${pkgName}.dto.${className}DTO;
|
||||
@@ -50,7 +50,7 @@ public interface ${className}Controller {
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:save')")
|
||||
#end
|
||||
public RestResult save(@RequestBody ${className}DTO ${lowClassName}DTO);
|
||||
public BaseResult save(@RequestBody ${className}DTO ${lowClassName}DTO);
|
||||
|
||||
/**
|
||||
* 单个修改
|
||||
@@ -62,7 +62,7 @@ public interface ${className}Controller {
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:update')")
|
||||
#end
|
||||
public RestResult update(@RequestBody ${className}DTO ${lowClassName}DTO);
|
||||
public BaseResult update(@RequestBody ${className}DTO ${lowClassName}DTO);
|
||||
|
||||
/**
|
||||
* 根据 id 删除单个
|
||||
@@ -74,7 +74,7 @@ public interface ${className}Controller {
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:delete')")
|
||||
#end
|
||||
public RestResult delete(@PathVariable Long ${pk.attributeName});
|
||||
public BaseResult delete(@PathVariable Long ${pk.attributeName});
|
||||
|
||||
/**
|
||||
* 根据 id 批量删除
|
||||
@@ -86,7 +86,7 @@ public interface ${className}Controller {
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:delete')")
|
||||
#end
|
||||
public RestResult delete(List<Long> idList);
|
||||
public BaseResult delete(List<Long> idList);
|
||||
|
||||
|
||||
#if(${asyncBatch})
|
||||
@@ -104,7 +104,7 @@ public interface ${className}Controller {
|
||||
@ApiImplicitParam(paramType = "body", required = true, name = "addDtoList", dataType = "list",
|
||||
value = "${comments}列表", example = "[{\"id\":\"12345\",\"name\":\"foo\"}]"),
|
||||
})
|
||||
RestResult<String> validateAdd(@RequestBody List<${className}DTO> addDtoList);
|
||||
BaseResult<String> validateAdd(@RequestBody List<${className}DTO> addDtoList);
|
||||
|
||||
/**
|
||||
* 批量修改 ${comments} - 校验
|
||||
@@ -119,7 +119,7 @@ public interface ${className}Controller {
|
||||
value = "${comments}列表", example = "[{\"id\":\"12345\",\"name\":\"foo\"}]"),
|
||||
|
||||
})
|
||||
RestResult<String> validateUpdate(@RequestBody List<${className}DTO> updatedDtoList);
|
||||
BaseResult<String> validateUpdate(@RequestBody List<${className}DTO> updatedDtoList);
|
||||
|
||||
|
||||
/**
|
||||
@@ -132,7 +132,7 @@ public interface ${className}Controller {
|
||||
@PostMapping("validateProgress")
|
||||
@ApiImplicitParam(paramType = "query", required = true, name = "clientId", dataType = "String",
|
||||
value = "批量校验标识", example = "50c77859-a670-47a8-a666-fff12816d832")
|
||||
RestResult<ImportProcessDTO> batchValidateProgress(@RequestBody ProgressParam progressParam);
|
||||
BaseResult<ImportProcessDTO> batchValidateProgress(@RequestBody ProgressParam progressParam);
|
||||
|
||||
/**
|
||||
* 批量添加
|
||||
@@ -144,7 +144,7 @@ public interface ${className}Controller {
|
||||
**/
|
||||
@ApiOperation(value = "批量添加 ${comments}", notes = "根据 异步任务标识 从缓存中取出对应的校验通过数据执行批量添加")
|
||||
@PostMapping("addBatch")
|
||||
RestResult<Object> addBatch(@RequestBody BatchAddOperationParam batchAddOperationParam) throws Exception;
|
||||
BaseResult<Object> addBatch(@RequestBody BatchAddOperationParam batchAddOperationParam) throws Exception;
|
||||
|
||||
/**
|
||||
* 批量更新
|
||||
@@ -159,7 +159,7 @@ public interface ${className}Controller {
|
||||
@ApiImplicitParam(paramType = "body", required = true, name = "deviceBatchManageDto", dataType =
|
||||
"DeviceBatchManageDto", value = "批量修改DTO",
|
||||
example = "{\"taskId\":\"716acbae-f407-43ed-bbac-c36dd7df7094\"}")
|
||||
RestResult<Object> updateBatch(@RequestBody BatchAddOperationParam batchAddOperationParam) throws Exception;
|
||||
BaseResult<Object> updateBatch(@RequestBody BatchAddOperationParam batchAddOperationParam) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
@@ -172,7 +172,7 @@ public interface ${className}Controller {
|
||||
@PostMapping("operationProgress")
|
||||
@ApiImplicitParam(paramType = "query", required = true, name = "clientId", dataType = "String",
|
||||
value = "批量操作标识", example = "649b545c-0edd-425b-b6b6-e1bc9ba6583f")
|
||||
RestResult<ImportProcessResult> batchOperationProgress(@RequestBody ProgressParam progressParam)
|
||||
BaseResult<ImportProcessResult> batchOperationProgress(@RequestBody ProgressParam progressParam)
|
||||
throws Exception;
|
||||
#end
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
#end
|
||||
import org.shoulder.core.dto.response.PageResult;
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import ${package}.${pkgName}.convert.${className}Converter;
|
||||
import ${package}.${pkgName}.dto.${className}DTO;
|
||||
@@ -25,7 +25,7 @@ import ${package}.${pkgName}.service.${className}Service;
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("${pathName}")
|
||||
@Api(tags = "${comments}")
|
||||
@Api(tags = {"${comments} Restful Http 接口"})
|
||||
public class ${className}Controller {
|
||||
|
||||
@Autowired
|
||||
@@ -36,7 +36,6 @@ public class ${className}Controller {
|
||||
* @param condition 查询条件
|
||||
* @return 分页结果
|
||||
*/
|
||||
@RequestMapping("list")
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('${tableName}:${pathName}:list')")
|
||||
#end
|
||||
@@ -56,15 +55,14 @@ public class ${className}Controller {
|
||||
* @param ${lowClassName}DTO 新增数据
|
||||
* @return 保存成功
|
||||
*/
|
||||
@RequestMapping(value = "save", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:save')")
|
||||
#end
|
||||
public RestResult save(@RequestBody ${className}DTO ${lowClassName}DTO){
|
||||
public BaseResult save(@RequestBody ${className}DTO ${lowClassName}DTO){
|
||||
${className} ${lowClassName} = ${className}Converter.CONVERTER.fromDTO(${lowClassName}DTO);
|
||||
${lowClassName}Service.save(${lowClassName});
|
||||
|
||||
return RestResult.success();
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,15 +71,14 @@ public class ${className}Controller {
|
||||
* @param ${lowClassName}DTO 修改属性
|
||||
* @return 修改成功
|
||||
*/
|
||||
@PostMapping("update")
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:update')")
|
||||
#end
|
||||
public RestResult update(@RequestBody ${className}DTO ${lowClassName}DTO){
|
||||
public BaseResult update(@RequestBody ${className}DTO ${lowClassName}DTO){
|
||||
${className} ${lowClassName} = ${className}Converter.CONVERTER.fromDTO(${lowClassName}DTO);
|
||||
${lowClassName}Service.update(${lowClassName});
|
||||
|
||||
return RestResult.success();
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,13 +87,12 @@ public class ${className}Controller {
|
||||
* @param ${pk.attributeName} id
|
||||
* @return 删除成功
|
||||
*/
|
||||
@RequestMapping(value = "delete/{id}", method = {RequestMethod.DELETE, RequestMethod.POST})
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:delete')")
|
||||
#end
|
||||
public RestResult delete(@PathVariable Long ${pk.attributeName}){
|
||||
public BaseResult delete(@PathVariable Long ${pk.attributeName}){
|
||||
${lowClassName}Service.deleteById(${pk.attributeName});
|
||||
return RestResult.success();
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,73 +101,15 @@ public class ${className}Controller {
|
||||
* @param idList ids
|
||||
* @return 删除成功
|
||||
*/
|
||||
@RequestMapping(value = "delete", method = {RequestMethod.DELETE, RequestMethod.POST})
|
||||
#if(${checkAuth})
|
||||
@PreAuthorize("hasAnyAuthority('resource:sysroleuser:delete')")
|
||||
#end
|
||||
public RestResult delete(List<Long> idList){
|
||||
public BaseResult delete(List<Long> idList){
|
||||
if(CollectionUtils.isEmpty(idList)){
|
||||
return RestResult.success();
|
||||
return BaseResult.success();
|
||||
}
|
||||
${lowClassName}Service.deleteByIds(idList);
|
||||
return RestResult.success();
|
||||
return BaseResult.success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 批量新增 ${comments} - 校验
|
||||
*
|
||||
* @param deviceList
|
||||
* @return ControllerResultDTO<java.lang.String>
|
||||
**/
|
||||
@ApiOperation(value = "校验批量新增设备", notes = "校验批量新增设备")
|
||||
@PostMapping("service/rs/v1/deviceService/validateImpDeviceData")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(paramType = "body", required = true, name = "deviceList", dataType = "list", value =
|
||||
"设备集合", example = "[{\"driver\":\"23123123\",\"name\":\"报警设备\"}]"),
|
||||
})
|
||||
ControllerResultDTO<String> validateImpDeviceData(@RequestBody List<Map<String, String>> deviceList);
|
||||
|
||||
/**
|
||||
* 校验批量修改设备
|
||||
*
|
||||
* @param deviceList
|
||||
* @return ControllerResultDTO<java.lang.String>
|
||||
**/
|
||||
@ApiOperation(value = "校验批量修改设备", notes = "校验批量修改设备")
|
||||
@PostMapping("service/rs/v1/deviceService/validateUpdateDeviceData")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(paramType = "body", required = true, name = "deviceList", dataType = "list", value =
|
||||
"设备集合", example = "[{\"driver\":\"23123123\",\"name\":\"报警设备\"}]"),
|
||||
|
||||
})
|
||||
ControllerResultDTO<String> validateUpdateDeviceData(@RequestBody List<Map<String, String>> deviceList);
|
||||
|
||||
/**
|
||||
* 设备批量添加
|
||||
*
|
||||
* @param deviceBatchManageDto
|
||||
* @return ControllerResultDTO<java.lang.Object>
|
||||
**/
|
||||
@ApiOperation(value = "设备批量添加", notes = "批量添加同一资源类型的设备,异步获取该批设备的设备和通道信息。")
|
||||
@PostMapping("service/rs/v1/deviceService/addBatch")
|
||||
ControllerResultDTO<Object> addBatch(@RequestBody DeviceBatchManageDto deviceBatchManageDto);
|
||||
|
||||
/**
|
||||
* 设备批量更新
|
||||
*
|
||||
* @param deviceBatchManageDto
|
||||
* @return ControllerResultDTO<java.lang.Object>
|
||||
**/
|
||||
@ApiOperation(value = "设备批量更新", notes = "批量更新设备信息")
|
||||
@PostMapping("service/rs/v1/deviceService/updateBatch")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(paramType = "body", required = true, name = "deviceBatchManageDto", dataType =
|
||||
"DeviceBatchManageDto", value = "批量修改设备DTO", example = ""),
|
||||
})
|
||||
ControllerResultDTO<Object> updateBatch(@RequestBody DeviceBatchManageDto deviceBatchManageDto) throws Exception;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import ${package}.${pkgName}.entity.${className};
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.Page;
|
||||
import org.springframework.data.domain;
|
||||
|
||||
import ${package}.${pkgName}.entity.${className}Entity;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package ${package}.${pkgName}.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
#if(${checkAuth})
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
#end
|
||||
import org.shoulder.core.dto.response.PageResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import ${package}.${pkgName}.convert.${className}Converter;
|
||||
import ${package}.${pkgName}.dto.${className}DTO;
|
||||
import ${package}.${pkgName}.model.${className};
|
||||
import ${package}.${pkgName}.service.${className}Service;
|
||||
|
||||
/**
|
||||
* ${comments} RestfulApi
|
||||
*
|
||||
* @author ${author}
|
||||
* @date ${datetime}
|
||||
*/
|
||||
@RequestMapping("rest/{${lowClassName}}/v1")
|
||||
public interface ${className}RestApi {
|
||||
|
||||
/**
|
||||
* 条件查询,分页
|
||||
* @param condition 查询条件
|
||||
* @return 分页结果,若客户端支持缓存,则在请求头中添加 if-Modify-Since,若未修改,则返回 304
|
||||
*/
|
||||
@GetMapping("list")
|
||||
PageResult<${className}> list(@RequestParam Map<String, Object> condition);
|
||||
|
||||
|
||||
/**
|
||||
* 保存单个,推荐使用幂等的 PUT 方法,体现接口幂等性。为了方便习惯,也开放了 POST
|
||||
*
|
||||
* @param ${lowClassName}DTO 新增数据
|
||||
* @return 创建成功返回 201,修改成功返回 200
|
||||
*/
|
||||
@RequestMapping(value = "save", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
BaseResult save(@RequestBody ${className}DTO ${lowClassName}DTO);
|
||||
|
||||
/**
|
||||
* 单个修改
|
||||
*
|
||||
* @param ${lowClassName}DTO 修改属性
|
||||
* @return 修改成功 200
|
||||
*/
|
||||
@PostMapping("update")
|
||||
BaseResult update(@RequestBody ${className}DTO ${lowClassName}DTO);
|
||||
|
||||
|
||||
/**
|
||||
* 根据 id 批量删除
|
||||
*
|
||||
* @param idList ids
|
||||
* @return 删除成功 200,异步删除 202
|
||||
*/
|
||||
@RequestMapping(value = "delete", method = {RequestMethod.DELETE, RequestMethod.POST})
|
||||
BaseResult deleteBatch(List<Long> idList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
dao接口
|
||||
|
||||
DO
|
||||
MybatiesDAOImpl
|
||||
jpaEntity
|
||||
jpaRepository
|
||||
|
||||
copyright
|
||||
@@ -0,0 +1 @@
|
||||
fieldsInfo (fields getter/setter )
|
||||
@@ -30,7 +30,7 @@
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<shoulder.version>0.6-SNAPSHOT</shoulder.version><!-- shoulder-version -->
|
||||
<shoulder.version>0.6</shoulder.version><!-- shoulder-version -->
|
||||
<shoulder-platform.version>1.0-SNAPSHOT</shoulder-platform.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -133,11 +133,13 @@ mvn archetype:generate\
|
||||
* 这里最好定义方法名约束,如 query/find/select/get、queryList/queryAll
|
||||
* 定义baseRepository,将常用的类注入,如转换器,DAO、其他 Repository
|
||||
* 按业务分包存放具体各个领域对应的存储接口与impl实现类,负责领域对象的 CRUD
|
||||
* coreService 核心服务在这里定义接口,供上层 business 模块使用
|
||||
* 入参出参往往都是 model
|
||||
|
||||
* `business-modules` : `具体业务模块` (可选)一个系统中可能包含多类小业务,可以在这里按照业务划分,分为不同的业务,如 `NACOS` 包含 `naming` 和 `config` 两个子模块。
|
||||
* share 公共**业务**逻辑
|
||||
* `business-modules` : `具体业务模块` (可选)
|
||||
一个系统中可能包含多类小业务,可以在这里按照业务划分,分为不同的业务,如 `NACOS` 包含 `naming` 和 `config` 两个子模块。
|
||||
* share 公共业务模块,按理说这块应该下沉至 core
|
||||
* assembler 装配工,用于不同模块间创建 request,从而调用 queryService
|
||||
* 共同的业务逻辑承载,如 managerComponent
|
||||
* modules 实现 facade
|
||||
* AbstractService 包含所有 core / biz-share 中的所有接口注入(`Query`/`Manager`CoreService、reference、biz-share中的)
|
||||
* log 包含调用日志(只打印入口和正常出口日志,用于追踪,可降级)、操作日志(追溯操作)
|
||||
@@ -235,27 +237,7 @@ xxx
|
||||
- 存储接口
|
||||
- 从 `领域Entity` 到存储层 `DO/PO` 的转换
|
||||
- 主键、创建时间、更新时间、创建人、修改人等填充,组装完整的数据对象
|
||||
- 部分 `分库分表`/`读` 判决
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
逻辑
|
||||
- 部分 `分库分表`/`读` 判决逻辑
|
||||
- `DAO`
|
||||
- 数据访问层,包含 `CRUD`
|
||||
- 方法一般只包含 queryByXXX、updateByXXX、insert、insertBatchForXXX、deleteByXXX、
|
||||
@@ -274,6 +256,20 @@ xxx
|
||||
| StartClassName | 启动类名 | ShoulderApplication |
|
||||
| author | 作者名 | shoulder |
|
||||
|
||||
## gitflow
|
||||
|
||||
- base env
|
||||
- linux
|
||||
- sdkman
|
||||
- graalvm
|
||||
- install native-image
|
||||
- install mvn
|
||||
- run compile.sh
|
||||
- release docker image
|
||||
- docker build the image with `Dockerfile.template` TODO 部署流程模板
|
||||
- push image to registry
|
||||
- release at self/pub dockerhub
|
||||
deploy
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
# Log file
|
||||
*.log
|
||||
*.log.*
|
||||
/**/*.log.*
|
||||
/logs
|
||||
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#set( $symbol_escape = '\' )
|
||||
package ${package}.api;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
@@ -27,6 +27,6 @@ public interface DemoRestfulApi {
|
||||
*/
|
||||
@GET
|
||||
@Path("/hi/{key}")
|
||||
RestResult configItem(@PathParam("key") String key);
|
||||
BaseResult configItem(@PathParam("key") String key);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#set( $symbol_escape = '\' )
|
||||
package ${package}.api;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
@@ -23,6 +23,6 @@ public interface DemoService {
|
||||
*
|
||||
* @return BaseResult
|
||||
*/
|
||||
RestResult configItem(String key);
|
||||
BaseResult configItem(String key);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#set( $symbol_escape = '\' )
|
||||
package ${package}.api.impl;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
import ${package}.api.DemoService;
|
||||
|
||||
/**
|
||||
@@ -18,7 +18,7 @@ public class DemoServiceClient implements DemoService {
|
||||
*
|
||||
* @return BaseResult
|
||||
*/
|
||||
public RestResult configItem(String key) {
|
||||
public BaseResult configItem(String key) {
|
||||
System.out.print("假装调了一次接口");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>cn.itlym</groupId>
|
||||
<artifactId>shoulder-parent</artifactId>
|
||||
<version>0.6-SNAPSHOT</version><!-- shoulder-version -->
|
||||
<version>0.6</version><!-- shoulder-version -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<properties>
|
||||
<!-- =============== Shoulder 版本 =============== -->
|
||||
|
||||
<shoulder.version>0.6-SNAPSHOT</shoulder.version><!-- shoulder-version -->
|
||||
<shoulder.version>0.6</shoulder.version><!-- shoulder-version -->
|
||||
<shoulder-platform.version>1.0-SNAPSHOT</shoulder-platform.version><!-- shoulder-platform-version -->
|
||||
|
||||
<shoulder-sms-aliyun.version>1.0-SNAPSHOT</shoulder-sms-aliyun.version><!-- shoulder-sms-aliyun.version -->
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>cn.itlym</groupId>
|
||||
<artifactId>shoulder-parent</artifactId>
|
||||
<version>0.6-SNAPSHOT</version><!-- shoulder-version -->
|
||||
<version>0.6</version><!-- shoulder-version -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.itlym.shoulder.platform.system.api;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
@@ -24,6 +24,6 @@ public interface SysConfigRestfulApi {
|
||||
*/
|
||||
@GET
|
||||
@Path("/item/{key}")
|
||||
RestResult configItem(@PathParam("key") String key);
|
||||
BaseResult configItem(@PathParam("key") String key);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.itlym.shoulder.platform.system.api;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
@@ -24,6 +24,6 @@ public interface SysDictionaryRestfulApi {
|
||||
*/
|
||||
@GET
|
||||
@Path("/item/{key}")
|
||||
RestResult configItem(@PathParam("key") String key);
|
||||
BaseResult configItem(@PathParam("key") String key);
|
||||
|
||||
}
|
||||
|
||||
25
shoulder-universal/pom.xml
Normal file
25
shoulder-universal/pom.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<groupId>cn.itlym.platform</groupId>
|
||||
<artifactId>shoulder-platform</artifactId>
|
||||
<version>1.0-SNAPSHOT</version><!-- shoulder-platform-version -->
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<name>shoulder-universal</name>
|
||||
<artifactId>shoulder-universal</artifactId>
|
||||
<description>通用系统</description>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<!-- universal.version -->
|
||||
|
||||
|
||||
<modules>
|
||||
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.itlym.platform.uaa.api;
|
||||
|
||||
import org.shoulder.core.dto.response.RestResult;
|
||||
import org.shoulder.core.dto.response.BaseResult;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
@@ -24,6 +24,6 @@ public interface DemoRestfulApi {
|
||||
*/
|
||||
@GET
|
||||
@Path("/hi/{key}")
|
||||
RestResult configItem(@PathParam("key") String key);
|
||||
BaseResult configItem(@PathParam("key") String key);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user