Browse Source

加matrix后台接口

master
nili 7 months ago
parent
commit
18eb334453
  1. 13
      game-dao/src/main/java/awesome/group/game/dao/bean/MatrixAdmin.java
  2. 15
      game-dao/src/main/java/awesome/group/game/dao/bean/MatrixApp.java
  3. 12
      game-dao/src/main/java/awesome/group/game/dao/config/MybatisGeneralConfig.java
  4. 10
      game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixAdminMapper.java
  5. 7
      game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixAppMapper.java
  6. 86
      game-service/src/main/java/awesome/group/game/service/AdminService.java
  7. 4
      game-service/src/main/java/awesome/group/game/service/MatrixService.java
  8. 7
      game-service/src/main/java/awesome/group/game/service/bo/AdvRecordQuery.java
  9. 32
      game-service/src/main/java/awesome/group/game/service/bo/MatrixAdvRecordBo.java
  10. 15
      game-service/src/main/java/awesome/group/game/service/bo/MatrixAdvRecordEditBo.java
  11. 6
      game-service/src/main/java/awesome/group/game/service/bo/PageParam.java
  12. 8
      game-service/src/main/java/awesome/group/game/service/bo/PageResult.java
  13. 6
      game-web/pom.xml
  14. 19
      game-web/src/main/java/awesome/group/RequestContext.java
  15. 34
      game-web/src/main/java/awesome/group/config/SwaggerConfig.java
  16. 52
      game-web/src/main/java/awesome/group/config/SwaggerProperties.java
  17. 4
      game-web/src/main/java/awesome/group/controller/MatrixController.java
  18. 87
      game-web/src/main/java/awesome/group/filter/AdminLoginFilter.java
  19. 2
      game-web/src/main/java/awesome/group/filter/LoginFilter.java
  20. 46
      game-web/src/main/java/awesome/group/rest/matrix/AdminController.java
  21. 14
      game-web/src/main/resources/application-default.yml
  22. 8
      pom.xml

13
game-dao/src/main/java/awesome/group/game/dao/bean/MatrixAdmin.java

@ -0,0 +1,13 @@
package awesome.group.game.dao.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
@Data
public class MatrixAdmin {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private String password;
}

15
game-dao/src/main/java/awesome/group/game/dao/bean/MatrixApp.java

@ -0,0 +1,15 @@
package awesome.group.game.dao.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
@Data
public class MatrixApp {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private String code;
private String url;
private Integer ownerId;
}

12
game-dao/src/main/java/awesome/group/game/dao/config/MybatisGeneralConfig.java

@ -1,6 +1,9 @@
package awesome.group.game.dao.config; package awesome.group.game.dao.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -19,4 +22,13 @@ public class MybatisGeneralConfig {
return new MybatisConfiguration(); return new MybatisConfiguration();
} }
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
return interceptor;
}
} }

10
game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixAdminMapper.java

@ -0,0 +1,10 @@
package awesome.group.game.dao.mapper;
import awesome.group.game.dao.bean.MatrixAdmin;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
public interface MatrixAdminMapper extends BaseMapper<MatrixAdmin> {
@Select("select * from matrix_admin where name = #{name}")
MatrixAdmin query(String name);
}

7
game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixAppMapper.java

@ -0,0 +1,7 @@
package awesome.group.game.dao.mapper;
import awesome.group.game.dao.bean.MatrixApp;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface MatrixAppMapper extends BaseMapper<MatrixApp> {
}

86
game-service/src/main/java/awesome/group/game/service/AdminService.java

@ -0,0 +1,86 @@
package awesome.group.game.service;
import awesome.group.game.dao.bean.MatrixAdmin;
import awesome.group.game.dao.bean.MatrixAdvRecord;
import awesome.group.game.dao.bean.MatrixApp;
import awesome.group.game.dao.mapper.MatrixAdminMapper;
import awesome.group.game.dao.mapper.MatrixAdvRecordMapper;
import awesome.group.game.dao.mapper.MatrixAppMapper;
import awesome.group.game.service.bo.AdvRecordQuery;
import awesome.group.game.service.bo.MatrixAdvRecordBo;
import awesome.group.game.service.bo.PageParam;
import awesome.group.game.service.bo.PageResult;
import awesome.group.game.service.common.exception.PaganiException;
import awesome.group.game.service.common.exception.PaganiExceptionCode;
import awesome.group.game.service.util.EncryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class AdminService {
@Autowired
private MatrixAdminMapper adminMapper;
@Autowired
private MatrixAdvRecordMapper advRecordMapper;
@Autowired
private MatrixAppMapper appMapper;
public MatrixAdmin login(String name, String pwd) {
MatrixAdmin admin = adminMapper.query(name);
if (admin == null) {
throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, "用户名或密码不正确");
}
String password = EncryptUtil.sha1(pwd);
if (!password.equals(admin.getPassword())) {
throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, "用户名或密码不正确");
}
return admin;
}
public MatrixAdmin getAdmin(Integer id) {
return adminMapper.selectById(id);
}
public PageResult<MatrixAdvRecordBo> advList(AdvRecordQuery param, int ownerId) {
List<MatrixApp> appList = appMapper.selectList(null);
LambdaQueryWrapper<MatrixAdvRecord> wrapper = Wrappers.lambdaQuery();
if (param.advType != null) {
wrapper.eq(MatrixAdvRecord::getAdvType, param.advType);
}
if (param.platform != null) {
wrapper.eq(MatrixAdvRecord::getPlatform, param.platform);
}
if (param.deviceId != null) {
wrapper.eq(MatrixAdvRecord::getDeviceId, param.deviceId);
}
wrapper.orderByDesc(MatrixAdvRecord::getId);
if (ownerId != 1) {
List<Integer> appIds = appList.stream().filter(x -> x.getOwnerId() == ownerId).map(MatrixApp::getId).toList();
wrapper.in(MatrixAdvRecord::getAppId, appIds);
}
int page = param.current;
int pageSize = param.current;
IPage<MatrixAdvRecord> iPage = advRecordMapper.selectPage(new Page<>(page, pageSize), wrapper);
PageResult<MatrixAdvRecordBo> res = new PageResult<>();
Map<Integer, MatrixApp> appMap = appList.stream().collect(Collectors.toMap(MatrixApp::getId, x -> x));
res.total = iPage.getTotal();
res.data = iPage.getRecords().stream().map(x -> {
MatrixAdvRecordBo bo = new MatrixAdvRecordBo(x, appMap.get(x.getAppId()));
BeanUtils.copyProperties(x, bo);
return bo;
}).toList();
return res;
}
}

4
game-service/src/main/java/awesome/group/game/service/MatrixService.java

@ -2,7 +2,7 @@ package awesome.group.game.service;
import awesome.group.game.dao.bean.MatrixAdvRecord; import awesome.group.game.dao.bean.MatrixAdvRecord;
import awesome.group.game.dao.mapper.MatrixAdvRecordMapper; import awesome.group.game.dao.mapper.MatrixAdvRecordMapper;
import awesome.group.game.service.bo.MatrixAdvRecordBo; import awesome.group.game.service.bo.MatrixAdvRecordEditBo;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -14,7 +14,7 @@ public class MatrixService {
@Resource @Resource
private MatrixAdvRecordMapper mapper; private MatrixAdvRecordMapper mapper;
public void saveRecord(MatrixAdvRecordBo bo, String ip) { public void saveRecord(MatrixAdvRecordEditBo bo, String ip) {
Assert.isTrue(StringUtils.hasText(bo.appCode), "appCode不能为空"); Assert.isTrue(StringUtils.hasText(bo.appCode), "appCode不能为空");
Integer appId = mapper.queryAppId(bo.appCode); Integer appId = mapper.queryAppId(bo.appCode);
if (appId == null) { if (appId == null) {

7
game-service/src/main/java/awesome/group/game/service/bo/AdvRecordQuery.java

@ -0,0 +1,7 @@
package awesome.group.game.service.bo;
public class AdvRecordQuery extends PageParam {
public Integer advType = 3;//默认展示激励视频
public Integer platform;
public String deviceId;
}

32
game-service/src/main/java/awesome/group/game/service/bo/MatrixAdvRecordBo.java

@ -1,12 +1,26 @@
package awesome.group.game.service.bo; package awesome.group.game.service.bo;
public class MatrixAdvRecordBo { import awesome.group.game.dao.bean.MatrixAdvRecord;
public String deviceId; import awesome.group.game.dao.bean.MatrixApp;
public String appCode;
public Integer platform;//1穿山甲,2腾讯,3百度联盟,4 Mintegral,5 快手,6游可赢,7 Sigmob,8 Admob public class MatrixAdvRecordBo extends MatrixAdvRecordEditBo {
public Integer advType;//1横幅,2插页,3激励视频 public String appName;
public Integer ecpm;//单位:分 public Integer appId;
public String deviceBrand; public long createdAt;
public String deviceName; public Integer id;
public String ip;
public MatrixAdvRecordBo(MatrixAdvRecord r, MatrixApp app) {
this.advType = r.getAdvType();
this.deviceId = r.getDeviceId();
this.platform = r.getPlatform();
this.ecpm = r.getEcpm();
this.deviceBrand = r.getDeviceBrand();
this.deviceName = r.getDeviceName();
this.ip = r.getIp();
this.appName = app.getName();
this.appId = app.getId();
this.appCode = app.getCode();
this.createdAt = r.getCreatedAt().getTime();
this.id = r.getId();
}
} }

15
game-service/src/main/java/awesome/group/game/service/bo/MatrixAdvRecordEditBo.java

@ -0,0 +1,15 @@
package awesome.group.game.service.bo;
public class MatrixAdvRecordEditBo {
public String deviceId;
public String appCode;
public Integer platform;//1穿山甲,2腾讯,3百度联盟,4 Mintegral,5 快手,6游可赢,7 Sigmob,8 Admob
public Integer advType;//1横幅,2插页,3激励视频
public Integer ecpm;//单位:分
public String deviceBrand;
public String deviceName;
public String ip;
public MatrixAdvRecordEditBo() {
}
}

6
game-service/src/main/java/awesome/group/game/service/bo/PageParam.java

@ -0,0 +1,6 @@
package awesome.group.game.service.bo;
public class PageParam {
public int current;
public int pageSize;
}

8
game-service/src/main/java/awesome/group/game/service/bo/PageResult.java

@ -0,0 +1,8 @@
package awesome.group.game.service.bo;
import java.util.List;
public class PageResult<T> {
public List<T> data;
public long total;
}

6
game-web/pom.xml

@ -37,7 +37,11 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

19
game-web/src/main/java/awesome/group/RequestContext.java

@ -16,6 +16,8 @@ public class RequestContext {
private static final String KEY_UID = "uid"; private static final String KEY_UID = "uid";
public static final String ADMIN_ID = "adminId";
private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>(); private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>();
@ -27,6 +29,14 @@ public class RequestContext {
THREAD_LOCAL.set(context); THREAD_LOCAL.set(context);
} }
public static void initAdmin(HttpServletRequest request, HttpServletResponse response, Integer userId) {
Map<String, Object> context = new HashMap<>();
context.put(KEY_REQUEST, request);
context.put(KEY_RESPONSE, response);
context.put(ADMIN_ID, userId);
THREAD_LOCAL.set(context);
}
public static HttpServletRequest getRequest() { public static HttpServletRequest getRequest() {
return (HttpServletRequest) THREAD_LOCAL.get().get(KEY_REQUEST); return (HttpServletRequest) THREAD_LOCAL.get().get(KEY_REQUEST);
@ -45,6 +55,13 @@ public class RequestContext {
return (Integer) THREAD_LOCAL.get().get(KEY_UID); return (Integer) THREAD_LOCAL.get().get(KEY_UID);
} }
public static Integer getAdminID() {
if (THREAD_LOCAL.get() == null) {
return null;
}
return (Integer) THREAD_LOCAL.get().get(ADMIN_ID);
}
public static void clear() { public static void clear() {
THREAD_LOCAL.remove(); THREAD_LOCAL.remove();
} }
@ -80,7 +97,7 @@ public class RequestContext {
} }
} }
} catch (Exception e) { } catch (Exception e) {
ipAddress=""; ipAddress = "";
} }
// ipAddress = this.getRequest().getRemoteAddr(); // ipAddress = this.getRequest().getRemoteAddr();

34
game-web/src/main/java/awesome/group/config/SwaggerConfig.java

@ -0,0 +1,34 @@
package awesome.group.config;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author nidaren
*/
@Configuration
public class SwaggerConfig implements WebMvcConfigurer {
private final SwaggerProperties swaggerProperties;
public SwaggerConfig(SwaggerProperties swaggerProperties) {
this.swaggerProperties = swaggerProperties;
}
@Bean
public OpenAPI swaggerOpenApi() {
return new OpenAPI()
.info(new Info().title("matrix后台")
.description("乌啦啦")
.version("v1.0.0"))
.externalDocs(new ExternalDocumentation()
.description("")
.url(""));
}
}

52
game-web/src/main/java/awesome/group/config/SwaggerProperties.java

@ -0,0 +1,52 @@
package awesome.group.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author nidaren
*/
@Component
@ConfigurationProperties("swagger")
public class SwaggerProperties {
private Boolean enable;
private String applicationName;
private String applicationVersion;
private String applicationDescription;
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
public String getApplicationName() {
return applicationName;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public String getApplicationVersion() {
return applicationVersion;
}
public void setApplicationVersion(String applicationVersion) {
this.applicationVersion = applicationVersion;
}
public String getApplicationDescription() {
return applicationDescription;
}
public void setApplicationDescription(String applicationDescription) {
this.applicationDescription = applicationDescription;
}
}

4
game-web/src/main/java/awesome/group/controller/MatrixController.java

@ -3,7 +3,7 @@ package awesome.group.controller;
import awesome.group.RequestContext; import awesome.group.RequestContext;
import awesome.group.aop.RestApi; import awesome.group.aop.RestApi;
import awesome.group.game.service.MatrixService; import awesome.group.game.service.MatrixService;
import awesome.group.game.service.bo.MatrixAdvRecordBo; import awesome.group.game.service.bo.MatrixAdvRecordEditBo;
import awesome.group.game.service.common.response.R; import awesome.group.game.service.common.response.R;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -19,7 +19,7 @@ public class MatrixController {
@PostMapping("/saveAdvRecord") @PostMapping("/saveAdvRecord")
@RestApi @RestApi
public R<Void> saveAdvRecord(@RequestBody MatrixAdvRecordBo bo) { public R<Void> saveAdvRecord(@RequestBody MatrixAdvRecordEditBo bo) {
matrixService.saveRecord(bo, RequestContext.getIpAddr(RequestContext.getRequest())); matrixService.saveRecord(bo, RequestContext.getIpAddr(RequestContext.getRequest()));
return new R<>(R.CODE_SUCCESS, "ok", null); return new R<>(R.CODE_SUCCESS, "ok", null);
} }

87
game-web/src/main/java/awesome/group/filter/AdminLoginFilter.java

@ -0,0 +1,87 @@
package awesome.group.filter;
import awesome.group.RequestContext;
import awesome.group.game.service.common.log.L;
import awesome.group.game.service.common.response.R;
import awesome.group.game.service.util.JwtUtils;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.google.gson.Gson;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.List;
/**
* @author nidaren
*/
@WebFilter(filterName = "AdminLoginFilter", urlPatterns = {"/api/admin/*"})
public class AdminLoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String token = "";
for (Cookie c : httpRequest.getCookies()) {
if (c.getName().equals("MatrixToken")) {
token = c.getValue();
}
}
List<String> openApi = List.of(
"/api/admin/login",
"/api/admin/swagger/v3/api-docs"
);
boolean pass = false;
Integer adminId = null;
try {
if (StringUtils.hasText(token)) {
adminId = JwtUtils.parseToken(token);
pass = true;
}
} catch (TokenExpiredException e) {
//忽略
} catch (Exception e) {
L.trace("parseTokenError", "token:" + token, e);
}
String path = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()).replaceAll("[/]+$", "");
for (String s : openApi) {
if (path.startsWith(s)) {
pass = true;
}
}
if (pass) {
RequestContext.initAdmin(httpRequest, (HttpServletResponse) response, adminId);
chain.doFilter(request, response);
} else {
authFail(response);
}
} finally {
RequestContext.clear();
}
}
private void authFail(ServletResponse response) throws IOException {
R<String> res = new R<>(-88888, "not login ", null);
Gson gson = new Gson();
response.setContentType("application/json;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(gson.toJson(res));
response.getWriter().flush();
}
@Override
public void destroy() {
}
}

2
game-web/src/main/java/awesome/group/filter/LoginFilter.java

@ -18,7 +18,7 @@ import java.util.List;
/** /**
* @author nidaren * @author nidaren
*/ */
@WebFilter(filterName = "ContextFilter", urlPatterns = {"/api/*"}) @WebFilter(filterName = "ContextFilter", urlPatterns = {"/api/game/*"})
public class LoginFilter implements Filter { public class LoginFilter implements Filter {

46
game-web/src/main/java/awesome/group/rest/matrix/AdminController.java

@ -0,0 +1,46 @@
package awesome.group.rest.matrix;
import awesome.group.RequestContext;
import awesome.group.aop.RestApi;
import awesome.group.game.dao.bean.MatrixAdmin;
import awesome.group.game.service.AdminService;
import awesome.group.game.service.bo.*;
import awesome.group.game.service.common.response.R;
import awesome.group.game.service.util.JwtUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.Cookie;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/admin")
@Tag(name = "admin")
public class AdminController {
@Resource
private AdminService adminService;
@PostMapping("/login")
@RestApi
public R<Void> adminLogin(@RequestParam String name, @RequestParam String pwd) {
MatrixAdmin data = adminService.login(name, pwd);
String token = JwtUtils.generatorToken(data.getId() + "", 15 * 86400);
Cookie cookie = new Cookie("MatrixToken", token);
RequestContext.getResponse().addCookie(cookie);
return new R<>(R.CODE_SUCCESS, "ok", null);
}
@GetMapping("/current")
@RestApi
public R<MatrixAdmin> current() {
MatrixAdmin data = adminService.getAdmin(RequestContext.getAdminID());
return new R<>(R.CODE_SUCCESS, "ok", data);
}
@PostMapping("/advList")
@RestApi
public R<PageResult<MatrixAdvRecordBo>> advList(@RequestBody AdvRecordQuery query) {
PageResult<MatrixAdvRecordBo> data = adminService.advList(query, RequestContext.getAdminID());
return new R<>(R.CODE_SUCCESS, "ok", data);
}
}

14
game-web/src/main/resources/application-default.yml

@ -25,6 +25,20 @@ mybatis-plus:
configuration: configuration:
map-underscore-to-camel-case: true #数据库字段下划线映射java对象属性用驼峰命名 map-underscore-to-camel-case: true #数据库字段下划线映射java对象属性用驼峰命名
springdoc:
api-docs:
enabled: true # 开启OpenApi接口
path: /api/v3/api-docs # 自定义路径,默认为 "/v3/api-docs"
swagger-ui:
enabled: true # 开启swagger界面,依赖OpenApi,需要OpenApi同时开启
path: /api/swagger-ui/index.html # 自定义路径,默认为"/swagger-ui/index.html"
swagger:
enable: true
applicationName: matrix
applicationDescription: matrix后台
applicationVersion: 1.0
server: server:
port: 9001 port: 9001
tomcat: tomcat:

8
pom.xml

@ -52,8 +52,12 @@
<version>2.6</version> <version>2.6</version>
</dependency> </dependency>
<!-- swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

Loading…
Cancel
Save