Commit 019d49698fcf92c036a23bccb33faacbe387f94d

Authored by xp.Huang
1 parent 9359a39d

feat: 增加openApi应用管理

Showing 40 changed files with 1575 additions and 20 deletions
@@ -86,7 +86,7 @@ public class ThingsboardSecurityConfiguration { @@ -86,7 +86,7 @@ public class ThingsboardSecurityConfiguration {
86 86
87 public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public"; 87 public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public";
88 public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; 88 public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token";
89 - protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/assets/**", "/static/**", "/api/noauth/**", "/webjars/**", "/api/license/**", "/api/images/public/**"}; 89 + protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/assets/**", "/static/**", "/api/noauth/**", "/webjars/**", "/api/license/**", "/api/images/public/**", "/api/yt/openApi/getToken/**"};
90 public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; 90 public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**";
91 public static final String WS_ENTRY_POINT = "/api/ws/**"; 91 public static final String WS_ENTRY_POINT = "/api/ws/**";
92 public static final String MAIL_OAUTH2_PROCESSING_ENTRY_POINT = "/api/admin/mail/oauth2/code"; 92 public static final String MAIL_OAUTH2_PROCESSING_ENTRY_POINT = "/api/admin/mail/oauth2/code";
  1 +package org.thingsboard.server.controller.yunteng;
  2 +
  3 +import io.swagger.annotations.Api;
  4 +import lombok.RequiredArgsConstructor;
  5 +import org.springframework.http.ResponseEntity;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.*;
  9 +import org.thingsboard.server.common.data.StringUtils;
  10 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  11 +import org.thingsboard.server.common.data.yunteng.common.AddGroup;
  12 +import org.thingsboard.server.common.data.yunteng.common.DeleteGroup;
  13 +import org.thingsboard.server.common.data.yunteng.common.UpdateGroup;
  14 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  15 +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
  16 +import org.thingsboard.server.common.data.yunteng.dto.ApplicationDTO;
  17 +import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
  18 +import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult;
  19 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  20 +import org.thingsboard.server.controller.BaseController;
  21 +import org.thingsboard.server.dao.yunteng.service.ApplicationService;
  22 +import org.thingsboard.server.dao.yunteng.service.TkOrganizationService;
  23 +import org.thingsboard.server.queue.util.TbCoreComponent;
  24 +
  25 +import java.util.HashMap;
  26 +import java.util.List;
  27 +
  28 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*;
  29 +
  30 +
  31 +@Api(tags = "应用管理")
  32 +@RestController
  33 +@TbCoreComponent
  34 +@RequestMapping("api/yt/application")
  35 +@RequiredArgsConstructor
  36 +public class TkApplicationController extends BaseController {
  37 + private final ApplicationService applicationService;
  38 + private final TkOrganizationService tkOrganizationService;
  39 +
  40 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  41 + @GetMapping(params = {PAGE_SIZE, PAGE})
  42 + public TkPageData<ApplicationDTO> page(
  43 + @RequestParam(PAGE_SIZE) int pageSize,
  44 + @RequestParam(PAGE) int page,
  45 + @RequestParam(value = "name", required = false) String name,
  46 + @RequestParam(value = "organizationId", required = false) String organizationId,
  47 + @RequestParam(value = ORDER_FILED, required = false) String orderBy,
  48 + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) throws ThingsboardException {
  49 +
  50 + HashMap<String, Object> queryMap = new HashMap<>();
  51 + queryMap.put(PAGE_SIZE, pageSize);
  52 + queryMap.put(PAGE, page);
  53 + queryMap.put(ORDER_FILED, orderBy);
  54 + queryMap.put("name", name);
  55 + if(StringUtils.isNotEmpty(organizationId)){
  56 + List<String> organizationIds = tkOrganizationService.organizationAllIds(getCurrentUser().getCurrentTenantId(),organizationId);
  57 + queryMap.put("organizationIds", organizationIds);
  58 + }
  59 + if (orderType != null) {
  60 + queryMap.put(ORDER_TYPE, orderType.name());
  61 + }
  62 + return applicationService.page(queryMap);
  63 + }
  64 +
  65 + @PostMapping
  66 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  67 + public ResponseResult<ApplicationDTO> save(@RequestBody ApplicationDTO applicationDTO)
  68 + throws ThingsboardException {
  69 + ApplicationDTO newDTO =
  70 + applicationService.save(applicationDTO, getCurrentUser().getCurrentTenantId());
  71 + return ResponseResult.success(newDTO);
  72 + }
  73 +
  74 + @DeleteMapping
  75 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  76 + public ResponseResult<String> delete(@RequestBody DeleteDTO deleteDTO) {
  77 + return applicationService.delete(deleteDTO.getIds())
  78 + ? ResponseResult.success(FastIotConstants.StateValue.DELETE_SUCCESS)
  79 + : ResponseResult.failed(FastIotConstants.StateValue.DELETE_FAILED);
  80 + }
  81 +
  82 + @PutMapping
  83 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  84 + public ResponseResult<ApplicationDTO> update( @RequestBody ApplicationDTO applicationDTO)
  85 + throws ThingsboardException {
  86 + return ResponseResult.success(
  87 + applicationService.update(applicationDTO));
  88 + }
  89 +
  90 + @GetMapping("/find")
  91 + public ResponseEntity<ApplicationDTO> find(String id) {
  92 + return ResponseEntity.ok(applicationService.getDto(id));
  93 + }
  94 +}
@@ -238,7 +238,18 @@ public class TkDeviceController extends BaseController { @@ -238,7 +238,18 @@ public class TkDeviceController extends BaseController {
238 return ResponseEntity.of(tkdeviceService.getDevice(getCurrentUser().getTenantId().getId(), UUID.fromString(id))); 238 return ResponseEntity.of(tkdeviceService.getDevice(getCurrentUser().getTenantId().getId(), UUID.fromString(id)));
239 } 239 }
240 240
241 - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN','CUSTOMER_USER')") 241 +
  242 +
  243 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN','CUSTOMER_USER','OPENAPI_USER')")
  244 + @PostMapping(path = {"/page"})
  245 + @ApiOperation("查询")
  246 + public TkPageData<DeviceDTO> getPage(
  247 + @RequestBody Map<String, Object> queryMap)
  248 + throws ThingsboardException {
  249 + return pageDevice((Integer) queryMap.get("pageSize"),(Integer) queryMap.get("page"),queryMap);
  250 + }
  251 +
  252 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN','CUSTOMER_USER','OPENAPI_USER')")
242 @PostMapping(params = {PAGE_SIZE, PAGE}) 253 @PostMapping(params = {PAGE_SIZE, PAGE})
243 @ApiOperation("查询") 254 @ApiOperation("查询")
244 public TkPageData<DeviceDTO> pageDevice( 255 public TkPageData<DeviceDTO> pageDevice(
@@ -84,7 +84,7 @@ public class TkDeviceProfileController extends BaseController { @@ -84,7 +84,7 @@ public class TkDeviceProfileController extends BaseController {
84 84
85 @GetMapping(params = {PAGE_SIZE, PAGE}) 85 @GetMapping(params = {PAGE_SIZE, PAGE})
86 @ApiOperation("查询") 86 @ApiOperation("查询")
87 - @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER'},{})") 87 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN','CUSTOMER_USER','OPENAPI_USER'},{})")
88 public TkPageData<DeviceProfileDTO> pageDeviceProfile( 88 public TkPageData<DeviceProfileDTO> pageDeviceProfile(
89 @RequestParam(PAGE_SIZE) int pageSize, 89 @RequestParam(PAGE_SIZE) int pageSize,
90 @RequestParam(PAGE) int page, 90 @RequestParam(PAGE) int page,
  1 +package org.thingsboard.server.controller.yunteng;
  2 +
  3 +import io.swagger.annotations.Api;
  4 +import lombok.RequiredArgsConstructor;
  5 +import org.springframework.http.ResponseEntity;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.*;
  9 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  10 +import org.thingsboard.server.common.data.yunteng.common.AddGroup;
  11 +import org.thingsboard.server.common.data.yunteng.common.DeleteGroup;
  12 +import org.thingsboard.server.common.data.yunteng.common.UpdateGroup;
  13 +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
  14 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiDTO;
  15 +import org.thingsboard.server.common.data.yunteng.dto.ApiMenuDTO;
  16 +import org.thingsboard.server.common.data.yunteng.dto.DeleteDTO;
  17 +import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
  18 +import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult;
  19 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  20 +import org.thingsboard.server.controller.BaseController;
  21 +import org.thingsboard.server.dao.yunteng.service.OpenApiService;
  22 +import org.thingsboard.server.queue.util.TbCoreComponent;
  23 +
  24 +import java.util.HashMap;
  25 +import java.util.List;
  26 +
  27 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*;
  28 +
  29 +@Api(tags = "OpenApi管理")
  30 +@RestController
  31 +@TbCoreComponent
  32 +@RequestMapping("api/yt/openApi")
  33 +@RequiredArgsConstructor
  34 +public class TkOpenApiController extends BaseController {
  35 + private final OpenApiService apiService;
  36 +
  37 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  38 + @GetMapping(params = {PAGE_SIZE, PAGE})
  39 + public TkPageData<OpenApiDTO> page(
  40 + @RequestParam(PAGE_SIZE) int pageSize,
  41 + @RequestParam(PAGE) int page,
  42 + @RequestParam(value = "name", required = false) String name,
  43 + @RequestParam(value = "classify", required = false) String classify,
  44 + @RequestParam(value = ORDER_FILED, required = false) String orderBy,
  45 + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) {
  46 +
  47 + HashMap<String, Object> queryMap = new HashMap<>();
  48 + queryMap.put(PAGE_SIZE, pageSize);
  49 + queryMap.put(PAGE, page);
  50 + queryMap.put(ORDER_FILED, orderBy);
  51 + queryMap.put("name", name);
  52 + queryMap.put("classify", classify);
  53 + if (orderType != null) {
  54 + queryMap.put(ORDER_TYPE, orderType.name());
  55 + }
  56 + return apiService.page(queryMap);
  57 + }
  58 +
  59 + @PostMapping
  60 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  61 + public ResponseResult<OpenApiDTO> save(
  62 + @Validated({AddGroup.class}) @RequestBody OpenApiDTO ApiDTO)
  63 + throws ThingsboardException {
  64 + OpenApiDTO newDTO =
  65 + apiService.save(ApiDTO, getCurrentUser().getCurrentTenantId());
  66 + return ResponseResult.success(newDTO);
  67 + }
  68 +
  69 + @DeleteMapping
  70 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  71 + public ResponseResult<String> delete(
  72 + @Validated({DeleteGroup.class}) @RequestBody DeleteDTO deleteDTO) {
  73 + return apiService.delete(deleteDTO.getIds())
  74 + ? ResponseResult.success(FastIotConstants.StateValue.DELETE_SUCCESS)
  75 + : ResponseResult.failed(FastIotConstants.StateValue.DELETE_FAILED);
  76 + }
  77 +
  78 + @PutMapping
  79 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  80 + public ResponseResult<OpenApiDTO> update(
  81 + @Validated({UpdateGroup.class}) @RequestBody OpenApiDTO ApiDTO)
  82 + throws ThingsboardException {
  83 + return ResponseResult.success(
  84 + apiService.update(
  85 + ApiDTO, getCurrentUser().getCurrentTenantId()));
  86 + }
  87 +
  88 + @GetMapping("/find")
  89 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  90 + public ResponseEntity<OpenApiDTO> find(String id) {
  91 + return ResponseEntity.ok(apiService.getDto(id));
  92 + }
  93 +
  94 +
  95 + @GetMapping("/getMenu")
  96 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  97 + public ResponseEntity<List<ApiMenuDTO>> getMenu() throws ThingsboardException {
  98 + return ResponseEntity.ok(apiService.getMenu(getCurrentUser().getCurrentTenantId()));
  99 + }
  100 +
  101 +
  102 +}
  1 +package org.thingsboard.server.controller.yunteng;
  2 +
  3 +import io.swagger.annotations.Api;
  4 +import io.swagger.annotations.ApiImplicitParam;
  5 +import io.swagger.annotations.ApiImplicitParams;
  6 +import lombok.RequiredArgsConstructor;
  7 +import org.springframework.http.ResponseEntity;
  8 +import org.springframework.security.access.prepost.PreAuthorize;
  9 +import org.springframework.web.bind.annotation.*;
  10 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  11 +import org.thingsboard.server.common.data.yunteng.dto.*;
  12 +import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum;
  13 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  14 +import org.thingsboard.server.controller.BaseController;
  15 +import org.thingsboard.server.dao.yunteng.service.OpenApiRecordService;
  16 +import org.thingsboard.server.queue.util.TbCoreComponent;
  17 +
  18 +import java.util.HashMap;
  19 +import java.util.List;
  20 +
  21 +import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.*;
  22 +
  23 +@Api(tags = "调用记录管理")
  24 +@RestController
  25 +@TbCoreComponent
  26 +@RequestMapping("api/yt/openApiRecord")
  27 +@RequiredArgsConstructor
  28 +public class TkOpenApiRecordController extends BaseController {
  29 + private final OpenApiRecordService openApiRecordService;
  30 +
  31 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  32 + @GetMapping(params = {PAGE_SIZE, PAGE})
  33 + public TkPageData<OpenApiRecordDTO> page(
  34 + @RequestParam(PAGE_SIZE) int pageSize,
  35 + @RequestParam(PAGE) int page,
  36 + @RequestParam(value = "apiName", required = false) String apiName,
  37 + @RequestParam(value = "applicationName", required = false) String applicationName,
  38 + @RequestParam(value = "classify", required = false) String classify,
  39 + @RequestParam(value = "startTime", required = false) Long startTime,
  40 + @RequestParam(value = "endTime", required = false) Long endTime,
  41 + @RequestParam(value = "state", required = false) Integer state,
  42 + @RequestParam(value = ORDER_FILED, required = false) String orderBy,
  43 + @RequestParam(value = ORDER_TYPE, required = false) OrderTypeEnum orderType) throws ThingsboardException {
  44 +
  45 + HashMap<String, Object> queryMap = new HashMap<>();
  46 + queryMap.put(PAGE_SIZE, pageSize);
  47 + queryMap.put(PAGE, page);
  48 + queryMap.put(ORDER_FILED, orderBy);
  49 + queryMap.put("apiName", apiName);
  50 + queryMap.put("applicationName", applicationName);
  51 + queryMap.put("startTime", startTime);
  52 + queryMap.put("endTime", endTime);
  53 + queryMap.put("state", state);
  54 + queryMap.put("classify", classify);
  55 + queryMap.put("tenantId", getCurrentUser().getTenantId().toString());
  56 + checkTimeAndPut(queryMap,startTime,endTime);
  57 + if (orderType != null) {
  58 + queryMap.put(ORDER_TYPE, orderType.name());
  59 + }
  60 + return openApiRecordService.page(queryMap);
  61 + }
  62 +
  63 + @GetMapping("/find")
  64 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  65 + public ResponseEntity<OpenApiRecordDTO> find(String id) {
  66 + return ResponseEntity.ok(openApiRecordService.getDto(id));
  67 + }
  68 +
  69 + @GetMapping("/getTop")
  70 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  71 + public ResponseEntity<OpenApiRecordTopAllDTO> getTop() throws ThingsboardException {
  72 + return ResponseEntity.ok(openApiRecordService.getTop(getCurrentUser().getTenantId().toString()));
  73 + }
  74 +
  75 + @GetMapping("/getClassify")
  76 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
  77 + @ApiImplicitParams(value = {
  78 + @ApiImplicitParam(name = "type", value = "统计类型 hour按小时;week按7天;month按30天" ,required = true)
  79 + })
  80 + public ResponseEntity<List<OpenApiRecordClassifyAllDTO>> getClassify(
  81 + @RequestParam(value = "type" ) String type
  82 + ) throws ThingsboardException {
  83 + return ResponseEntity.ok(openApiRecordService.getClassify(getCurrentUser().getTenantId().toString(), type));
  84 + }
  85 +
  86 +
  87 + @GetMapping("/getPage")
  88 + public TkPageData<OpenApiRecordTopDTO> getPage(
  89 + @RequestParam(PAGE_SIZE) int pageSize,
  90 + @RequestParam(PAGE) int page) throws ThingsboardException {
  91 + return openApiRecordService.getPage(getCurrentUser().getTenantId().toString(),page, pageSize);
  92 + }
  93 +
  94 +}
@@ -4,11 +4,13 @@ import io.swagger.annotations.Api; @@ -4,11 +4,13 @@ import io.swagger.annotations.Api;
4 import io.swagger.annotations.ApiOperation; 4 import io.swagger.annotations.ApiOperation;
5 import io.swagger.annotations.ApiResponse; 5 import io.swagger.annotations.ApiResponse;
6 import io.swagger.annotations.ApiResponses; 6 import io.swagger.annotations.ApiResponses;
  7 +import org.apache.commons.lang3.RandomStringUtils;
7 import org.apache.commons.lang3.StringUtils; 8 import org.apache.commons.lang3.StringUtils;
8 import org.springframework.context.ApplicationEventPublisher; 9 import org.springframework.context.ApplicationEventPublisher;
9 import org.springframework.http.ResponseEntity; 10 import org.springframework.http.ResponseEntity;
10 import org.springframework.security.access.prepost.PreAuthorize; 11 import org.springframework.security.access.prepost.PreAuthorize;
11 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 12 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  13 +import org.springframework.transaction.annotation.Transactional;
12 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
13 import org.springframework.web.bind.annotation.*; 15 import org.springframework.web.bind.annotation.*;
14 import org.thingsboard.server.common.data.Customer; 16 import org.thingsboard.server.common.data.Customer;
@@ -256,7 +258,7 @@ public class TkUserController extends AbstractUserAccount { @@ -256,7 +258,7 @@ public class TkUserController extends AbstractUserAccount {
256 @PostMapping("save_tenant_admin") 258 @PostMapping("save_tenant_admin")
257 public UserDTO saveTenantAdmin(@Validated(AddGroup.class) @RequestBody UserDTO userDTO) 259 public UserDTO saveTenantAdmin(@Validated(AddGroup.class) @RequestBody UserDTO userDTO)
258 throws ThingsboardException { 260 throws ThingsboardException {
259 - return saveTenant(userDTO); 261 + return saveTenant(userDTO,false);
260 } 262 }
261 263
262 @PreAuthorize( 264 @PreAuthorize(
@@ -264,15 +266,19 @@ public class TkUserController extends AbstractUserAccount { @@ -264,15 +266,19 @@ public class TkUserController extends AbstractUserAccount {
264 @PostMapping("save_common_tenant") 266 @PostMapping("save_common_tenant")
265 public UserDTO saveCommonTenant(@Validated(AddGroup.class) @RequestBody UserDTO userDTO) 267 public UserDTO saveCommonTenant(@Validated(AddGroup.class) @RequestBody UserDTO userDTO)
266 throws ThingsboardException { 268 throws ThingsboardException {
267 - return saveTenant(userDTO); 269 + return saveTenant(userDTO,false);
268 } 270 }
269 271
270 - public UserDTO saveTenant(UserDTO userDTO) throws ThingsboardException { 272 + @Transactional
  273 + public UserDTO saveTenant(UserDTO userDTO,Boolean isOpenApi) throws ThingsboardException {
271 if (StringUtils.isEmpty(userDTO.getTenantId())) { 274 if (StringUtils.isEmpty(userDTO.getTenantId())) {
272 throw new TkDataValidationException(MessageUtils.message(ErrorMessage.INVALID_PARAMETER.getI18nCode())); 275 throw new TkDataValidationException(MessageUtils.message(ErrorMessage.INVALID_PARAMETER.getI18nCode()));
273 } 276 }
274 - userService.validateUserNameAndPhoneNumberAndEmail(userDTO);  
275 - userService.validateTenantRole(userDTO.getTenantId()); 277 + if(!isOpenApi){
  278 + userService.validateUserNameAndPhoneNumberAndEmail(userDTO);
  279 + userService.validateTenantRole(userDTO.getTenantId());
  280 + }
  281 +
276 // 租户角色不存在,会留存脏数据 282 // 租户角色不存在,会留存脏数据
277 TenantId tenantId = TenantId.fromUUID(UUID.fromString(userDTO.getTenantId())); 283 TenantId tenantId = TenantId.fromUUID(UUID.fromString(userDTO.getTenantId()));
278 // 创建TB的租户管理员 284 // 创建TB的租户管理员
@@ -280,15 +286,26 @@ public class TkUserController extends AbstractUserAccount { @@ -280,15 +286,26 @@ public class TkUserController extends AbstractUserAccount {
280 User tbUser = new User(); 286 User tbUser = new User();
281 // 只有新增才调用TB 287 // 只有新增才调用TB
282 if (null == userDTO.getId()) { 288 if (null == userDTO.getId()) {
283 - tbUser = createTBUser(tbUser, userDTO, tenantId, customerId, Authority.TENANT_ADMIN); 289 + Authority authority;
  290 + if(isOpenApi){
  291 + authority = Authority.OPENAPI_USER;
  292 + userDTO.setActivateToken(RandomStringUtils.randomAlphabetic(10));
  293 + }else{
  294 + authority = Authority.TENANT_ADMIN;
  295 + }
  296 + tbUser = createTBUser(tbUser, userDTO, tenantId, customerId,authority);
284 userDTO.setTbUser(tbUser.getId().toString()); 297 userDTO.setTbUser(tbUser.getId().toString());
285 // 激活租户管理员 298 // 激活租户管理员
286 activeTBUser( 299 activeTBUser(
287 tbUser.getId(), accountProperties.getDefaultPassword(), tbUser.getTenantId(), true); 300 tbUser.getId(), accountProperties.getDefaultPassword(), tbUser.getTenantId(), true);
288 } 301 }
  302 + boolean ptSysadmin = false;
  303 + if(!isOpenApi){
  304 + ptSysadmin =getCurrentUser().isPtSysadmin();
  305 + }
289 UserDTO result = 306 UserDTO result =
290 userService.saveTenantAdmin( 307 userService.saveTenantAdmin(
291 - userDTO, getCurrentUser().isPtSysadmin(), tenantId.getId().toString()); 308 + userDTO, ptSysadmin, tenantId.getId().toString());
292 userService.updateTenantAdminUserCredentials( 309 userService.updateTenantAdminUserCredentials(
293 List.of(new UserId(UUID.fromString(result.getTbUser()))), 310 List.of(new UserId(UUID.fromString(result.getTbUser()))),
294 userDTO.getTenantId(), 311 userDTO.getTenantId(),
@@ -443,7 +460,7 @@ public class TkUserController extends AbstractUserAccount { @@ -443,7 +460,7 @@ public class TkUserController extends AbstractUserAccount {
443 * @param userId 用户ID 460 * @param userId 用户ID
444 * @throws ThingsboardException tb运行异常 461 * @throws ThingsboardException tb运行异常
445 */ 462 */
446 - private void activeTBUser(UserId userId, String password, TenantId tenantId, boolean isPtAdmin) 463 + protected void activeTBUser(UserId userId, String password, TenantId tenantId, boolean isPtAdmin)
447 throws ThingsboardException { 464 throws ThingsboardException {
448 // 1、获取UserCredentials 并获取activateToken 465 // 1、获取UserCredentials 并获取activateToken
449 if (!isPtAdmin) { 466 if (!isPtAdmin) {
@@ -473,8 +490,8 @@ public class TkUserController extends AbstractUserAccount { @@ -473,8 +490,8 @@ public class TkUserController extends AbstractUserAccount {
473 * @return 用户 490 * @return 用户
474 * @throws ThingsboardException tb运行异常 491 * @throws ThingsboardException tb运行异常
475 */ 492 */
476 - private User createTBUser(  
477 - User tbUser, UserDTO userDTO, TenantId tenantId, CustomerId customerId, Authority authority){ 493 + protected User createTBUser(
  494 + User tbUser, UserDTO userDTO, TenantId tenantId, CustomerId customerId, Authority authority){
478 tbUser.setAuthority(authority); 495 tbUser.setAuthority(authority);
479 tbUser.setTenantId(tenantId); 496 tbUser.setTenantId(tenantId);
480 tbUser.setCustomerId(customerId); 497 tbUser.setCustomerId(customerId);
  1 +package org.thingsboard.server.controller.yunteng.openApi;
  2 +import io.swagger.annotations.Api;
  3 +import io.swagger.annotations.ApiOperation;
  4 +import lombok.RequiredArgsConstructor;
  5 +import lombok.Setter;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.http.*;
  9 +import org.springframework.security.core.Authentication;
  10 +import org.springframework.security.core.AuthenticationException;
  11 +import org.springframework.web.bind.annotation.*;
  12 +import org.springframework.web.client.RestTemplate;
  13 +import org.thingsboard.server.common.data.StringUtils;
  14 +import org.thingsboard.server.common.data.exception.ThingsboardException;
  15 +import org.thingsboard.server.common.data.yunteng.dto.ApplicationDTO;
  16 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiContrlooerDTO;
  17 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiDTO;
  18 +import org.thingsboard.server.common.data.yunteng.dto.UserDTO;
  19 +import org.thingsboard.server.controller.BaseController;
  20 +import org.thingsboard.server.controller.yunteng.TkThirdPlatformController;
  21 +import org.thingsboard.server.controller.yunteng.TkUserController;
  22 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiRecordEntity;
  23 +import org.thingsboard.server.dao.yunteng.service.ApplicationService;
  24 +import org.thingsboard.server.dao.yunteng.service.OpenApiRecordService;
  25 +import org.thingsboard.server.dao.yunteng.service.OpenApiService;
  26 +import org.thingsboard.server.queue.util.TbCoreComponent;
  27 +import org.thingsboard.server.service.security.auth.yunteng.TkLoginResponse;
  28 +import org.thingsboard.server.utils.MiscUtils;
  29 +
  30 +import javax.servlet.http.HttpServletRequest;
  31 +import java.time.LocalDateTime;
  32 +import java.util.List;
  33 +import java.util.Map;
  34 +
  35 +@Api(tags = "OpenApi接口")
  36 +@RestController
  37 +@TbCoreComponent
  38 +@RequestMapping("/api/yt/openApi")
  39 +@RequiredArgsConstructor
  40 +@Slf4j
  41 +public class OpenApiController extends BaseController {
  42 +
  43 + private final ApplicationService applicationService;
  44 + private final TkThirdPlatformController tkThirdPlatformController;
  45 + private final TkUserController tkUserController;
  46 + private final RestTemplate restTemplate = new RestTemplate();
  47 + private final OpenApiService openApiService;
  48 + private final OpenApiRecordService openApiRecordService;
  49 +
  50 +
  51 + @GetMapping("/getToken")
  52 + @ApiOperation(value = "获取token与刷新token")
  53 + public TkLoginResponse getToken(String key ,String secret) throws ThingsboardException {
  54 + ApplicationDTO app = applicationService.getByKeyAndSecret(key,secret);
  55 + String userId = null;
  56 + //如果第一次获取token则新建用户并且返回token
  57 + if(StringUtils.isEmpty(app.getUserId())){
  58 + UserDTO userDTO = new UserDTO().newOpenApiUser(app.getTenantId(),app.getKey());
  59 + tkUserController.saveTenant(userDTO,true);
  60 + userId =userDTO.getId();
  61 + app.setUserId(userId);
  62 + applicationService.update(app);
  63 + }else{
  64 + userId =app.getUserId();
  65 + }
  66 + return tkThirdPlatformController.unionidLogin(userId);
  67 + }
  68 +
  69 +
  70 + @PostMapping("/common/{method}/{apiId}")
  71 + @ApiOperation(value = "openApi公共接口")
  72 + public ResponseEntity<Object> callOtherController(
  73 + @PathVariable String method,
  74 + @PathVariable String apiId,
  75 + @RequestBody (required = false) Object body,// 支持对象或Map
  76 + HttpServletRequest request
  77 + ) throws ThingsboardException {
  78 + TkOpenApiRecordEntity record = new TkOpenApiRecordEntity("200", LocalDateTime.now(), 1, "");
  79 + try {
  80 + OpenApiDTO api = openApiService.getDto(apiId);
  81 + ApplicationDTO appDto = applicationService.getDtoByUserId(getCurrentUser().getCurrentUserId());
  82 + //记录日志
  83 + setRecord(api,appDto,record);
  84 + if (!appDto.getApiList().contains(api.getId())) {
  85 + throw new RuntimeException("没有权限");
  86 + }
  87 + // 构建URL
  88 + String url = MiscUtils.constructBaseUrl(request) + api.getUri();
  89 + // 如果是 GET 请求,附加查询参数
  90 + if (method.equals(HttpMethod.GET.name()) && body != null) {
  91 + StringBuilder queryBuilder = new StringBuilder("?");
  92 + Map<String, String> queryParams = (Map<String, String>) body;
  93 + queryParams.forEach((key, value) -> queryBuilder.append(key).append("=").append(value).append("&"));
  94 + url += queryBuilder.toString();
  95 + }
  96 + // 创建 HttpHeaders 对象并设置 token
  97 + HttpHeaders headers = new HttpHeaders();
  98 + // 从 Authorization header 中提取 token
  99 + String token = request.getHeader("x-authorization");
  100 + headers.set("x-authorization", token); // 设置 Authorization header
  101 + // 创建 HttpEntity 对象,将 headers 和请求体一起传递
  102 + HttpEntity<String> entity = new HttpEntity<>(headers);
  103 + // 根据请求类型判断处理逻辑
  104 + if (HttpMethod.GET.name().equalsIgnoreCase(method)) {
  105 + ResponseEntity<Object> response = restTemplate.exchange(
  106 + url,
  107 + HttpMethod.GET,
  108 + entity,
  109 + Object.class
  110 + );
  111 + return response;
  112 + } else if (HttpMethod.POST.name().equalsIgnoreCase(method)) {
  113 + //如果POST请求遇到url中拼接参数,需要自己重新写接口调用 自己拼接进去(API中配置自己写的接口)
  114 + headers.setContentType(MediaType.APPLICATION_JSON);
  115 + HttpEntity<Object> requestEntity = new HttpEntity<>(body, headers);
  116 + return restTemplate.postForEntity(url, requestEntity, Object.class);
  117 + }
  118 + } catch (Exception e) {
  119 + record.setCode(e.toString());
  120 + record.setState(0);
  121 + record.setMessage(e.getMessage());
  122 + return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
  123 + } finally {
  124 + openApiRecordService.save(record, getCurrentUser().getTenantId().toString());
  125 + }
  126 +
  127 + // 默认返回 405 Method Not Allowed
  128 + return new ResponseEntity<>(HttpStatus.METHOD_NOT_ALLOWED);
  129 + }
  130 +
  131 + @PostMapping("/getApi")
  132 + @ApiOperation(value = "获取可调用api")
  133 + public ResponseEntity<List<OpenApiContrlooerDTO>> callOtherController(HttpServletRequest request) throws ThingsboardException {
  134 + ApplicationDTO appDto = applicationService.getDtoByUserId(getCurrentUser().getCurrentUserId());
  135 + return ResponseEntity.ok(openApiService.getByListId(appDto.getApiList()));
  136 + }
  137 +
  138 + void setRecord(OpenApiDTO api,ApplicationDTO app,TkOpenApiRecordEntity record) throws ThingsboardException {
  139 + record.setApiId(api.getId());
  140 + record.setApiName(api.getName());
  141 + record.setApplicationId(app.getId());
  142 + record.setApplicationName(app.getName());
  143 + record.setClassify(api.getClassify());
  144 + record.setTenantId(getCurrentUser().getTenantId().toString());
  145 + }
  146 +
  147 +}
@@ -23,6 +23,7 @@ public enum Authority { @@ -23,6 +23,7 @@ public enum Authority {
23 //thingskit 23 //thingskit
24 PLATFORM_USER(3), 24 PLATFORM_USER(3),
25 COMMON_TENANT(4), 25 COMMON_TENANT(4),
  26 + OPENAPI_USER(5),
26 REFRESH_TOKEN(10), 27 REFRESH_TOKEN(10),
27 PRE_VERIFICATION_TOKEN(11); 28 PRE_VERIFICATION_TOKEN(11);
28 29
@@ -312,6 +312,7 @@ public interface FastIotConstants { @@ -312,6 +312,7 @@ public interface FastIotConstants {
312 public static final int TWO = 2; 312 public static final int TWO = 2;
313 public static final int THREE = 3; 313 public static final int THREE = 3;
314 public static final int FOUR = 4; 314 public static final int FOUR = 4;
  315 + public static final int FIVE = 5;
315 public static final int TEN = 10; 316 public static final int TEN = 10;
316 } 317 }
317 318
@@ -361,6 +362,8 @@ public interface FastIotConstants { @@ -361,6 +362,8 @@ public interface FastIotConstants {
361 public static final int IS_CUSTOMER_USER = 3; 362 public static final int IS_CUSTOMER_USER = 3;
362 /** 租户下的子管理员 */ 363 /** 租户下的子管理员 */
363 public static final int IS_CUSTOMER_TENANT = 4; 364 public static final int IS_CUSTOMER_TENANT = 4;
  365 + /** OpenApi用户 */
  366 + public static final int IS_OPENAPI_USER= 5;
364 } 367 }
365 class Rpc{ 368 class Rpc{
366 369
@@ -140,6 +140,20 @@ public final class ModelConstants { @@ -140,6 +140,20 @@ public final class ModelConstants {
140 140
141 /** 视频通道表 */ 141 /** 视频通道表 */
142 public static final String TK_VIDEO_CHANNEL_NAME = "tk_video_channel"; 142 public static final String TK_VIDEO_CHANNEL_NAME = "tk_video_channel";
  143 +
  144 + /** 应用表 */
  145 + public static final String TK_APPLICATION = "tk_application";
  146 +
  147 + /** api表 */
  148 + public static final String TK_OPEN_API = "tk_open_api";
  149 +
  150 + /** 应用api表 */
  151 + public static final String TK_APPLICATION_API = "tk_application_api";
  152 +
  153 + /** api调用记录表 */
  154 + public static final String TK_OPEN_API_RECORD = "tk_open_api_record";
  155 +
  156 +
143 } 157 }
144 158
145 public static class TableFields { 159 public static class TableFields {
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Data
  9 +public class ApiMenuDTO extends BaseDTO {
  10 +
  11 + @ApiModelProperty(value = "名称")
  12 + private String name;
  13 +
  14 + @ApiModelProperty(value = "api集合")
  15 + /**文档地址*/
  16 + private List<OpenApiDTO> apis;
  17 +
  18 + public ApiMenuDTO(String name, List<OpenApiDTO> apis) {
  19 + this.name = name;
  20 + this.apis = apis;
  21 + }
  22 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.common.AddGroup;
  6 +
  7 +import javax.validation.constraints.NotEmpty;
  8 +import java.util.List;
  9 +
  10 +@Data
  11 +public class ApplicationDTO extends BaseDTO {
  12 +
  13 + @ApiModelProperty(value = "名称")
  14 + /** 名称 */
  15 + private String name;
  16 + @ApiModelProperty(value = "key")
  17 + /** key */
  18 + private String key;
  19 +
  20 + @ApiModelProperty(value = "secret")
  21 + /** secret */
  22 + private String secret;
  23 + @ApiModelProperty(value = "组织id")
  24 + /**组织id*/
  25 + private String organizationId;
  26 + @ApiModelProperty(value = "组织名称")
  27 + /**组织名称*/
  28 + private String organizationName;
  29 +
  30 + @ApiModelProperty(value = "api集合")
  31 + /**组织名称*/
  32 + private List<String> apiList;
  33 +
  34 + private String userId;
  35 +
  36 + private String tenantId;
  37 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import com.fasterxml.jackson.databind.JsonNode;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  7 +
  8 +@Data
  9 +public class OpenApiContrlooerDTO extends BaseDTO {
  10 +
  11 + @ApiModelProperty(value = "名称")
  12 + private String name;
  13 + @ApiModelProperty(value = "请求方式")
  14 + /** 请求方式 */
  15 + private Integer requestMethod;
  16 +
  17 + @ApiModelProperty(value = "文档地址")
  18 + /**文档地址*/
  19 + private String documentUrl;
  20 +
  21 + @ApiModelProperty(value = "调用参数")
  22 + /**调用参数*/
  23 + private JsonNode param;
  24 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import com.fasterxml.jackson.databind.JsonNode;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  7 +
  8 +@Data
  9 +public class OpenApiDTO extends BaseDTO {
  10 +
  11 + @ApiModelProperty(value = "名称")
  12 + private String name;
  13 +
  14 + @ApiModelProperty(value = "所属分类")
  15 + /** 所属分类 */
  16 + private ApplicationApiEnum classify;
  17 +
  18 + @ApiModelProperty(value = "请求方式")
  19 + /** 请求方式 */
  20 + private Integer requestMethod;
  21 +
  22 + @ApiModelProperty(value = "请求路由")
  23 + /**请求路由*/
  24 + private String uri;
  25 +
  26 + @ApiModelProperty(value = "文档地址")
  27 + /**文档地址*/
  28 + private String documentUrl;
  29 +
  30 + @ApiModelProperty(value = "调用参数")
  31 + /**调用参数*/
  32 + private JsonNode param;
  33 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  6 +
  7 +import java.time.LocalDateTime;
  8 +import java.util.List;
  9 +
  10 +@Data
  11 +public class OpenApiRecordClassifyAllDTO {
  12 +
  13 + @ApiModelProperty(value = "类型")
  14 + private ApplicationApiEnum classify;
  15 +
  16 + @ApiModelProperty(value = "类型集合")
  17 + private List<OpenApiRecordClassifyDTO> dts;
  18 +
  19 + public OpenApiRecordClassifyAllDTO(ApplicationApiEnum classify, List<OpenApiRecordClassifyDTO> dts) {
  20 + this.classify = classify;
  21 + this.dts = dts;
  22 + }
  23 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Data
  10 +public class OpenApiRecordClassifyDTO {
  11 +
  12 + @ApiModelProperty(value = "类型")
  13 + private ApplicationApiEnum classify;
  14 +
  15 + @ApiModelProperty(value = "时间")
  16 + private LocalDateTime time;
  17 +
  18 + @ApiModelProperty(value = "调用数量")
  19 + private Integer count;
  20 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Data
  10 +public class OpenApiRecordDTO extends BaseDTO {
  11 +
  12 + @ApiModelProperty(value = "ApiId")
  13 + /** ApiId */
  14 + private String apiId;
  15 + @ApiModelProperty(value = "名称")
  16 + /** 名称 */
  17 + private String apiName;
  18 + @ApiModelProperty(value = "应用id")
  19 + /** 应用id */
  20 + private String applicationId;
  21 + @ApiModelProperty(value = "应用名称")
  22 + /** 应用名称 */
  23 + private String applicationName;
  24 + @ApiModelProperty(value = "所属分类")
  25 + /** 所属分类 */
  26 + private ApplicationApiEnum classify;
  27 + @ApiModelProperty(value = "相应code")
  28 + /**相应code*/
  29 + private String code;
  30 + @ApiModelProperty(value = "请求时间")
  31 + /**请求时间*/
  32 + private LocalDateTime requestTime;
  33 + @ApiModelProperty(value = "状态 0成功 1失败")
  34 + /**状态 0成功 1失败*/
  35 + private Integer state;
  36 + @ApiModelProperty(value = "错误信息")
  37 + /**错误信息*/
  38 + private String message;
  39 +
  40 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.dto.BaseDTO;
  6 +
  7 +import java.util.List;
  8 +
  9 +@Data
  10 +public class OpenApiRecordTopAllDTO extends BaseDTO {
  11 +
  12 + @ApiModelProperty(value = "调用总数")
  13 + private Integer count;
  14 +
  15 + @ApiModelProperty(value = "成功总数")
  16 + private Integer successCount;
  17 +
  18 + @ApiModelProperty(value = "失败总数")
  19 + private Integer failCount;
  20 +
  21 + @ApiModelProperty(value = "调用占比")
  22 + private List<OpenApiRecordTopDTO> tops;
  23 +}
  1 +package org.thingsboard.server.common.data.yunteng.dto;
  2 +
  3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  6 +
  7 +@Data
  8 +public class OpenApiRecordTopDTO extends BaseDTO {
  9 +
  10 + @ApiModelProperty(value = "应用名称")
  11 + private String name;
  12 +
  13 + @ApiModelProperty(value = "调用数量")
  14 + private Integer recordNum;
  15 +
  16 + @ApiModelProperty(value = "调用数量")
  17 + private Integer successCount;
  18 +
  19 + @ApiModelProperty(value = "调用数量")
  20 + private Integer failureCount;
  21 +
  22 +
  23 + @ApiModelProperty(value = "调用占比")
  24 + private Double recordProportion;
  25 +}
@@ -79,9 +79,21 @@ public class UserDTO extends BaseDTO { @@ -79,9 +79,21 @@ public class UserDTO extends BaseDTO {
79 @JsonInclude(JsonInclude.Include.NON_NULL) 79 @JsonInclude(JsonInclude.Include.NON_NULL)
80 private Set<PlainRolesDTO> roles; 80 private Set<PlainRolesDTO> roles;
81 81
82 - @ApiModelProperty(value = "角色级别:0:超级管理员;1:平台管理员 2:租户账号(租户管理员) 3:租户下的账号(客户) 4:普通租户") 82 + @ApiModelProperty(value = "角色级别:0:超级管理员;1:平台管理员 2:租户账号(租户管理员) 3:租户下的账号(客户) 4:普通租户 5:OpenApi用户")
83 private Integer level; 83 private Integer level;
84 84
85 @ApiModelProperty(value = "备注") 85 @ApiModelProperty(value = "备注")
86 private String remark; 86 private String remark;
  87 +
  88 + public UserDTO newOpenApiUser(String tenantId ,String userName){
  89 + UserDTO dto = new UserDTO();
  90 + dto.setTenantId(tenantId);
  91 + dto.setUsername(userName);
  92 + dto.setEnabled(true);
  93 + dto.setLevel(5);
  94 + String[] roleIds = { "ccf77a30-ad68-42a3-a313-312acd0c4083"};
  95 + dto.setRoleIds(roleIds);
  96 + return dto;
  97 + }
  98 +
87 } 99 }
  1 +package org.thingsboard.server.common.data.yunteng.enums;
  2 +
  3 +public enum ApplicationApiEnum {
  4 + DEVICE,//设备管理
  5 + ALARM,//告警管理
  6 + VIDEO,//视频管理
  7 + STATISTICS,//统计功能
  8 + SYSTEM//系统管理
  9 +}
@@ -16,5 +16,9 @@ public enum RoleEnum { @@ -16,5 +16,9 @@ public enum RoleEnum {
16 /** 16 /**
17 * 平台系统管理员 17 * 平台系统管理员
18 */ 18 */
19 - PLATFORM_ADMIN; 19 + PLATFORM_ADMIN,
  20 + /**
  21 + * openapi用户
  22 + */
  23 + OPENAPI_USER;
20 } 24 }
  1 +package org.thingsboard.server.dao.yunteng.entities;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  7 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  8 +
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = false)
  11 +@TableName(ModelConstants.Table.TK_APPLICATION_API)
  12 +public class TkApplicationApiEntity {
  13 +
  14 + /** 应用id */
  15 + private String applicationId;
  16 +
  17 + /** apiId */
  18 + private String apiId;
  19 +
  20 + public TkApplicationApiEntity(String applicationId, String apiId) {
  21 + this.applicationId = applicationId;
  22 + this.apiId = apiId;
  23 + }
  24 +}
  1 +package org.thingsboard.server.dao.yunteng.entities;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  7 +
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = false)
  10 +@TableName(ModelConstants.Table.TK_APPLICATION)
  11 +public class TkApplicationEntity extends TenantBaseEntity {
  12 +
  13 + private static final long serialVersionUID = -5381101569947327544L;
  14 +
  15 + /** 名称 */
  16 + private String name;
  17 +
  18 + /** key */
  19 + private String key;
  20 +
  21 + /** secret */
  22 + private String secret;
  23 +
  24 + /** userId */
  25 + private String userId;
  26 +
  27 + /**组织id*/
  28 + private String organizationId;
  29 +
  30 +}
  1 +package org.thingsboard.server.dao.yunteng.entities;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.fasterxml.jackson.databind.JsonNode;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  8 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  9 +
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = false)
  12 +@TableName(ModelConstants.Table.TK_OPEN_API)
  13 +public class TkOpenApiEntity extends TenantBaseEntity {
  14 +
  15 + private static final long serialVersionUID = -5381101569947327544L;
  16 +
  17 + /** 名称 */
  18 + private String name;
  19 +
  20 + /** 所属分类 */
  21 + private ApplicationApiEnum classify;
  22 +
  23 + /** 请求方式 */
  24 + private Integer requestMethod;
  25 +
  26 + /**请求路由*/
  27 + private String uri;
  28 +
  29 + /**文档地址*/
  30 + private String documentUrl;
  31 +
  32 + /**调用参数*/
  33 + private JsonNode param;
  34 +
  35 +}
  1 +package org.thingsboard.server.dao.yunteng.entities;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import org.thingsboard.server.common.data.yunteng.constant.ModelConstants;
  7 +import org.thingsboard.server.common.data.yunteng.enums.ApplicationApiEnum;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = false)
  13 +@TableName(ModelConstants.Table.TK_OPEN_API_RECORD)
  14 +public class TkOpenApiRecordEntity extends TenantBaseEntity {
  15 +
  16 + private static final long serialVersionUID = -5381101569947327544L;
  17 +
  18 + /** ApiId */
  19 + private String apiId;
  20 +
  21 + /** 名称 */
  22 + private String apiName;
  23 +
  24 + /** 应用id */
  25 + private String applicationId;
  26 +
  27 + /** 应用名称 */
  28 + private String applicationName;
  29 +
  30 + /** 所属分类 */
  31 + private ApplicationApiEnum classify;
  32 +
  33 + /**相应code*/
  34 + private String code;
  35 +
  36 + /**请求时间*/
  37 + private LocalDateTime requestTime;
  38 +
  39 + /**状态 0成功 1失败*/
  40 + private Integer state;
  41 +
  42 + /**错误信息*/
  43 + private String message;
  44 +
  45 + public TkOpenApiRecordEntity(String code, LocalDateTime requestTime, Integer state, String message) {
  46 + this.code = code;
  47 + this.requestTime = requestTime;
  48 + this.state = state;
  49 + this.message = message;
  50 + }
  51 + public TkOpenApiRecordEntity() {
  52 +
  53 + }
  54 +}
  1 +package org.thingsboard.server.dao.yunteng.impl;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5 +import com.baomidou.mybatisplus.core.metadata.IPage;
  6 +import lombok.RequiredArgsConstructor;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.transaction.annotation.Transactional;
  10 +import org.thingsboard.server.common.data.yunteng.dto.ApplicationDTO;
  11 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  12 +import org.thingsboard.server.dao.yunteng.entities.TkApplicationApiEntity;
  13 +import org.thingsboard.server.dao.yunteng.entities.TkApplicationEntity;
  14 +import org.thingsboard.server.dao.yunteng.mapper.ApplicationApiMapper;
  15 +import org.thingsboard.server.dao.yunteng.mapper.ApplicationMapper;
  16 +import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
  17 +import org.thingsboard.server.dao.yunteng.service.ApplicationService;
  18 +
  19 +import java.security.SecureRandom;
  20 +import java.util.*;
  21 +import java.util.stream.Collectors;
  22 +
  23 +@Slf4j
  24 +@Service
  25 +@RequiredArgsConstructor
  26 +public class ApplicationServiceImpl extends AbstractBaseService<ApplicationMapper, TkApplicationEntity>
  27 + implements ApplicationService {
  28 +
  29 + private final ApplicationApiMapper applicationApiMapper;
  30 + private static final int KEY_LENGTH = 32; // 32位字符
  31 + private static final SecureRandom secureRandom = new SecureRandom();
  32 + private static final Base64.Encoder base64Encoder = Base64.getUrlEncoder().withoutPadding();
  33 +
  34 +
  35 + @Override
  36 + public ApplicationDTO getDto(String id) {
  37 + TkApplicationEntity entity = baseMapper.selectById(id);
  38 + ApplicationDTO dto = new ApplicationDTO();
  39 + entity.copyToDTO(dto);
  40 + List<TkApplicationApiEntity> apis = applicationApiMapper.selectList(
  41 + new LambdaQueryWrapper<TkApplicationApiEntity>()
  42 + .eq(TkApplicationApiEntity::getApplicationId, id));
  43 + if(!apis.isEmpty()){
  44 + dto.setApiList(apis.stream().map(r -> r.getApiId()).collect(Collectors.toList()));
  45 + }
  46 + return dto;
  47 + }
  48 +
  49 + @Override
  50 + public TkPageData<ApplicationDTO> page(Map<String, Object> queryMap) {
  51 + IPage<TkApplicationEntity> iPage =
  52 + baseMapper.selectPage(
  53 + getPage(queryMap, "create_time", false),
  54 + new QueryWrapper<TkApplicationEntity>()
  55 + .lambda()
  56 + .eq(
  57 + queryMap.get("tenantId") != null,
  58 + TkApplicationEntity::getTenantId,
  59 + String.valueOf(queryMap.get("tenantId")))
  60 + .like(
  61 + queryMap.get("name") != null,
  62 + TkApplicationEntity::getName,
  63 + String.valueOf(queryMap.get("name")))
  64 + .in(
  65 + queryMap.get("organizationIds") != null,
  66 + TkApplicationEntity::getOrganizationId,
  67 + (List<String>)queryMap.get("organizationIds")));
  68 + return getPageData(iPage, ApplicationDTO.class);
  69 + }
  70 +
  71 + @Override
  72 + @Transactional
  73 + public ApplicationDTO save(ApplicationDTO dto, String tenantId) {
  74 + TkApplicationEntity application = new TkApplicationEntity();
  75 + dto.copyToEntity(application);
  76 + application.setTenantId(tenantId);
  77 + application.setKey(generateRandomString(KEY_LENGTH));
  78 + application.setSecret(generateRandomString(KEY_LENGTH));
  79 + baseMapper.insert(application);
  80 + if(null!=dto.getApiList()&&!dto.getApiList().isEmpty()){
  81 + dto.getApiList().stream().forEach(api -> {
  82 + applicationApiMapper.insert(new TkApplicationApiEntity(application.getId(),api));
  83 + });
  84 + }
  85 +
  86 + return dto;
  87 + }
  88 +
  89 + @Override
  90 + @Transactional
  91 + public boolean delete(Set<String> applicationIds) {
  92 + applicationApiMapper.deleteByAppIds(applicationIds);
  93 + return baseMapper.deleteBatchIds(applicationIds) > 0;
  94 + }
  95 +
  96 + @Override
  97 + @Transactional
  98 + public ApplicationDTO update(ApplicationDTO dto) {
  99 + TkApplicationEntity application = baseMapper.selectById(dto.getId());
  100 + dto.copyToEntity(application);
  101 + baseMapper.updateById(application);
  102 + //先删除关联关系再新增
  103 + applicationApiMapper.deleteByAppIds(Collections.singleton(dto.getId()));
  104 + if(null!=dto.getApiList()&&!dto.getApiList().isEmpty()){
  105 + dto.getApiList().stream().forEach(api -> {
  106 + applicationApiMapper.insert(new TkApplicationApiEntity(dto.getId(),api));
  107 + });
  108 + }
  109 + return dto;
  110 + }
  111 +
  112 + @Override
  113 + public ApplicationDTO getByKeyAndSecret(String key, String secret) {
  114 + TkApplicationEntity entity = baseMapper.selectOne(
  115 + new LambdaQueryWrapper<TkApplicationEntity>()
  116 + .eq(TkApplicationEntity::getKey, key)
  117 + .eq(TkApplicationEntity::getSecret,secret));
  118 + if(null == entity){
  119 + throw new RuntimeException("应用不存在");
  120 + }
  121 + ApplicationDTO dto = new ApplicationDTO();
  122 + entity.copyToDTO(dto);
  123 + return dto;
  124 + }
  125 +
  126 + @Override
  127 + public ApplicationDTO getDtoByUserId(String userId) {
  128 + TkApplicationEntity entity = baseMapper.selectOne(
  129 + new LambdaQueryWrapper<TkApplicationEntity>()
  130 + .eq(TkApplicationEntity::getUserId, userId));
  131 + if(null == entity){
  132 + throw new RuntimeException("应用不存在");
  133 + }
  134 + ApplicationDTO dto = new ApplicationDTO();
  135 + entity.copyToDTO(dto);
  136 + List<TkApplicationApiEntity> apis = applicationApiMapper.selectList(
  137 + new LambdaQueryWrapper<TkApplicationApiEntity>()
  138 + .eq(TkApplicationApiEntity::getApplicationId, entity.getId()));
  139 + if(!apis.isEmpty()){
  140 + dto.setApiList(apis.stream().map(r -> r.getApiId()).collect(Collectors.toList()));
  141 + }
  142 + return dto;
  143 + }
  144 + // 生成指定长度的随机字符串
  145 + private static String generateRandomString(int length) {
  146 + byte[] randomBytes = new byte[length];
  147 + secureRandom.nextBytes(randomBytes);
  148 + return base64Encoder.encodeToString(randomBytes).substring(0, length);
  149 + }
  150 +
  151 +}
  1 +package org.thingsboard.server.dao.yunteng.impl;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5 +import com.baomidou.mybatisplus.core.metadata.IPage;
  6 +import lombok.RequiredArgsConstructor;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.transaction.annotation.Transactional;
  10 +import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
  11 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiContrlooerDTO;
  12 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiDTO;
  13 +import org.thingsboard.server.common.data.yunteng.dto.ApiMenuDTO;
  14 +import org.thingsboard.server.common.data.yunteng.utils.CopyUtils;
  15 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  16 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiEntity;
  17 +import org.thingsboard.server.dao.yunteng.mapper.OpenApiMapper;
  18 +import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
  19 +import org.thingsboard.server.dao.yunteng.service.OpenApiService;
  20 +
  21 +import java.util.*;
  22 +import java.util.stream.Collectors;
  23 +
  24 +@Slf4j
  25 +@Service
  26 +@RequiredArgsConstructor
  27 +public class OpenApiImpl extends AbstractBaseService<OpenApiMapper, TkOpenApiEntity>
  28 + implements OpenApiService {
  29 +
  30 +
  31 + @Override
  32 + public OpenApiDTO getDto(String id) {
  33 + TkOpenApiEntity entity = baseMapper.selectById(id);
  34 + if(null == entity){
  35 + throw new RuntimeException("Api不存在");
  36 + }
  37 + OpenApiDTO dto = new OpenApiDTO();
  38 + entity.copyToDTO(dto);
  39 + return dto;
  40 + }
  41 +
  42 + @Override
  43 + public TkPageData<OpenApiDTO> page(Map<String, Object> queryMap) {
  44 + IPage<TkOpenApiEntity> iPage =
  45 + baseMapper.selectPage(
  46 + getPage(queryMap, "create_time", false),
  47 + new QueryWrapper<TkOpenApiEntity>()
  48 + .lambda()
  49 + .like(
  50 + queryMap.get("name") != null,
  51 + TkOpenApiEntity::getName,
  52 + String.valueOf(queryMap.get("name")))
  53 + .like(
  54 + queryMap.get("classify") != null,
  55 + TkOpenApiEntity::getClassify,
  56 + String.valueOf(queryMap.get("classify"))));
  57 + return getPageData(iPage, OpenApiDTO.class);
  58 + }
  59 +
  60 + @Override
  61 + @Transactional
  62 + public OpenApiDTO save(OpenApiDTO dto, String tenantId) {
  63 + TkOpenApiEntity openApi = new TkOpenApiEntity();
  64 + dto.copyToEntity(openApi);
  65 + openApi.setTenantId(tenantId);
  66 + baseMapper.insert(openApi);
  67 + return dto;
  68 + }
  69 +
  70 + @Override
  71 + @Transactional
  72 + public boolean delete(Set<String> apiIds) {
  73 + return baseMapper.deleteBatchIds(apiIds) > 0;
  74 + }
  75 +
  76 + @Override
  77 + @Transactional
  78 + public OpenApiDTO update(OpenApiDTO dto, String tenantId) {
  79 + TkOpenApiEntity openApi = baseMapper.selectById(dto.getId());
  80 + dto.copyToEntity(openApi);
  81 + baseMapper.updateById(openApi);
  82 + return dto;
  83 + }
  84 +
  85 + @Override
  86 + public List<ApiMenuDTO> getMenu(String tenantId) {
  87 + List<TkOpenApiEntity> list = baseMapper.selectList(new LambdaQueryWrapper<TkOpenApiEntity>()
  88 + .eq(TkOpenApiEntity::getTenantId,tenantId));
  89 + List<ApiMenuDTO> listDto = new ArrayList<>();
  90 + if(!list.isEmpty()){
  91 + for (TkOpenApiEntity entity: list) {
  92 + OpenApiDTO apiDTO = new OpenApiDTO();
  93 + entity.copyToDTO(apiDTO);
  94 + // 查找 listDto 中是否已有相同 enum 的 entity
  95 + ApiMenuDTO existingDto = listDto.stream()
  96 + .filter(dto -> dto.getName().equals(entity.getClassify().name()))
  97 + .findFirst()
  98 + .orElse(null);
  99 + if (existingDto != null) {
  100 + // 如果存在,则将 entity 添加到对应的 dto
  101 + existingDto.getApis().add(apiDTO);
  102 + } else {
  103 + // 如果不存在,则创建新的 dto 并添加到 dtoList
  104 + List<OpenApiDTO> newEntityList = new ArrayList<>();
  105 + newEntityList.add(apiDTO);
  106 + ApiMenuDTO newDto = new ApiMenuDTO(entity.getClassify().name(), newEntityList);
  107 + listDto.add(newDto);
  108 + }
  109 + }
  110 + }
  111 + return listDto;
  112 + }
  113 +
  114 + @Override
  115 + public List<OpenApiContrlooerDTO> getByListId(List<String> ids) {
  116 + List<TkOpenApiEntity> list = baseMapper.selectList(new LambdaQueryWrapper<TkOpenApiEntity>()
  117 + .in(TkOpenApiEntity::getId,ids));
  118 + return list.stream().map(entity -> {
  119 + return CopyUtils.copyAndReturn(entity, new OpenApiContrlooerDTO());
  120 + }
  121 + ).collect(Collectors.toList());
  122 + }
  123 +
  124 +}
  1 +package org.thingsboard.server.dao.yunteng.impl;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5 +import com.baomidou.mybatisplus.core.metadata.IPage;
  6 +import lombok.RequiredArgsConstructor;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.transaction.annotation.Transactional;
  10 +import org.thingsboard.server.common.data.yunteng.dto.*;
  11 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  12 +import org.thingsboard.server.dao.yunteng.entities.TkApplicationEntity;
  13 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiRecordEntity;
  14 +import org.thingsboard.server.dao.yunteng.mapper.ApplicationMapper;
  15 +import org.thingsboard.server.dao.yunteng.mapper.OpenApiRecordMapper;
  16 +import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
  17 +import org.thingsboard.server.dao.yunteng.service.OpenApiRecordService;
  18 +
  19 +import java.util.ArrayList;
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +import java.util.concurrent.atomic.AtomicInteger;
  23 +
  24 +@Slf4j
  25 +@Service
  26 +@RequiredArgsConstructor
  27 +public class OpenApiRecordImpl extends AbstractBaseService<OpenApiRecordMapper, TkOpenApiRecordEntity>
  28 + implements OpenApiRecordService {
  29 +
  30 + private final ApplicationMapper applicationMapper;
  31 + @Override
  32 + public OpenApiRecordDTO getDto(String id) {
  33 + TkOpenApiRecordEntity entity = baseMapper.selectById(id);
  34 + OpenApiRecordDTO dto = new OpenApiRecordDTO();
  35 + entity.copyToDTO(dto);
  36 + return dto;
  37 + }
  38 +
  39 + @Override
  40 + public TkPageData<OpenApiRecordDTO> page(Map<String, Object> queryMap) {
  41 + IPage<TkOpenApiRecordEntity> iPage =
  42 + baseMapper.selectPage(
  43 + getPage(queryMap, "request_time", false),
  44 + new QueryWrapper<TkOpenApiRecordEntity>()
  45 + .lambda()
  46 + .eq(
  47 + queryMap.get("tenantId") != null,
  48 + TkOpenApiRecordEntity::getTenantId,
  49 + String.valueOf(queryMap.get("tenantId")))
  50 + .like(
  51 + queryMap.get("apiName") != null,
  52 + TkOpenApiRecordEntity::getApiName,
  53 + String.valueOf(queryMap.get("apiName")))
  54 + .like(
  55 + queryMap.get("applicationName") != null,
  56 + TkOpenApiRecordEntity::getApplicationName,
  57 + String.valueOf(queryMap.get("applicationName")))
  58 + .eq(
  59 + queryMap.get("classify") != null,
  60 + TkOpenApiRecordEntity::getClassify,
  61 + String.valueOf(queryMap.get("classify")))
  62 + .ge(
  63 + queryMap.get("startTime") != null,
  64 + TkOpenApiRecordEntity::getRequestTime,
  65 + queryMap.get("startTime"))
  66 + .le(
  67 + queryMap.get("endTime") != null,
  68 + TkOpenApiRecordEntity::getRequestTime,
  69 + queryMap.get("endTime"))
  70 + .eq(
  71 + queryMap.get("state") != null,
  72 + TkOpenApiRecordEntity::getState,
  73 + queryMap.get("state")));
  74 + return getPageData(iPage, OpenApiRecordDTO.class);
  75 + }
  76 +
  77 +
  78 + @Override
  79 + @Transactional
  80 + public int save(TkOpenApiRecordEntity entity, String tenantId) {
  81 + entity.setTenantId(tenantId);
  82 + return baseMapper.insert(entity);
  83 + }
  84 +
  85 + @Override
  86 + public OpenApiRecordTopAllDTO getTop(String tenantId) {
  87 + List<OpenApiRecordTopDTO> tops = baseMapper.getTop(tenantId,null,null);
  88 + OpenApiRecordTopAllDTO dto = new OpenApiRecordTopAllDTO();
  89 + AtomicInteger count = new AtomicInteger();
  90 + AtomicInteger successCount = new AtomicInteger();
  91 + AtomicInteger failCount = new AtomicInteger();
  92 + if(null!=tops&&!tops.isEmpty()){
  93 + dto.setTops(tops);
  94 + tops.stream().forEach(top-> {
  95 + count.set(count.get() + top.getRecordNum());
  96 + successCount.set(successCount.get() + top.getSuccessCount());
  97 + failCount.set(failCount.get() + top.getFailureCount());
  98 + }
  99 + );
  100 + }
  101 + dto.setCount(count.get());
  102 + dto.setSuccessCount(successCount.get());
  103 + dto.setFailCount(failCount.get());
  104 + return dto;
  105 + }
  106 +
  107 + @Override
  108 + public TkPageData<OpenApiRecordTopDTO> getPage(String tenantId,Integer page,Integer pageSize) {
  109 + List<OpenApiRecordTopDTO> tops = baseMapper.getTop(tenantId,page,pageSize);
  110 + Long count = applicationMapper.selectCount(new LambdaQueryWrapper<TkApplicationEntity>()
  111 + .eq(TkApplicationEntity::getTenantId, tenantId));
  112 + return new TkPageData<>(tops, count);
  113 + }
  114 +
  115 + @Override
  116 + public List<OpenApiRecordClassifyAllDTO> getClassify(String tenantId,String type) {
  117 + List<OpenApiRecordClassifyDTO> tops = baseMapper.getClassify(tenantId,type);
  118 + List<OpenApiRecordClassifyAllDTO> allList =new ArrayList<>();
  119 + if(!tops.isEmpty()){
  120 + for (OpenApiRecordClassifyDTO entity: tops) {
  121 + // 查找 listDto 中是否已有相同 enum 的 entity
  122 + OpenApiRecordClassifyAllDTO existingDto = allList.stream()
  123 + .filter(dto -> dto.getClassify().name().equals(entity.getClassify().name()))
  124 + .findFirst()
  125 + .orElse(null);
  126 + if (existingDto != null) {
  127 + // 如果存在,则将 entity 添加到对应的 dto
  128 + existingDto.getDts().add(entity);
  129 + } else {
  130 + // 如果不存在,则创建新的 dto 并添加到 dtoList
  131 + List<OpenApiRecordClassifyDTO> newEntityList = new ArrayList<>();
  132 + newEntityList.add(entity);
  133 + OpenApiRecordClassifyAllDTO newDto = new OpenApiRecordClassifyAllDTO(entity.getClassify(), newEntityList);
  134 + allList.add(newDto);
  135 + }
  136 + }
  137 + }
  138 + return allList;
  139 + }
  140 +
  141 +}
@@ -562,8 +562,10 @@ public class SysUserServiceImpl extends AbstractBaseService<UserMapper, SysUserE @@ -562,8 +562,10 @@ public class SysUserServiceImpl extends AbstractBaseService<UserMapper, SysUserE
562 user.setPassword(passwordEncoder.encode(accountProperties.getDefaultPassword())); 562 user.setPassword(passwordEncoder.encode(accountProperties.getDefaultPassword()));
563 //判断是租户管理员还是普通租户 563 //判断是租户管理员还是普通租户
564 Integer level = null; 564 Integer level = null;
565 - if (null!=userDTO.getLevel()&&userDTO.getLevel()== FastIotConstants.MagicNumber.FOUR){ 565 + if (null!=userDTO.getLevel()&&userDTO.getLevel()== MagicNumber.FOUR){
566 level = FastIotConstants.LevelValue.IS_CUSTOMER_TENANT; 566 level = FastIotConstants.LevelValue.IS_CUSTOMER_TENANT;
  567 + }else if (null!=userDTO.getLevel()&&userDTO.getLevel()== MagicNumber.FIVE){
  568 + level = FastIotConstants.LevelValue.IS_OPENAPI_USER;
567 }else{ 569 }else{
568 level = FastIotConstants.LevelValue.IS_TENANT_ADMIN; 570 level = FastIotConstants.LevelValue.IS_TENANT_ADMIN;
569 } 571 }
@@ -578,12 +580,21 @@ public class SysUserServiceImpl extends AbstractBaseService<UserMapper, SysUserE @@ -578,12 +580,21 @@ public class SysUserServiceImpl extends AbstractBaseService<UserMapper, SysUserE
578 } 580 }
579 baseMapper.insert(user); 581 baseMapper.insert(user);
580 // 如果为普通租户绑定用户和组织的关系和角色 582 // 如果为普通租户绑定用户和组织的关系和角色
581 - if(null!=user.getLevel()&&user.getLevel()==FastIotConstants.LevelValue.IS_CUSTOMER_TENANT){ 583 + if(null!=level){
  584 + //如果是普通租户
  585 + if(level==FastIotConstants.LevelValue.IS_CUSTOMER_TENANT){
  586 + for (String tenantRole : userDTO.getRoleIds()) {
  587 + roleMapper.saveUserRoleMapping(user.getId(), tenantRole);
  588 + }
  589 + }
  590 + //如果是openapi用户
  591 + if(level==FastIotConstants.LevelValue.IS_OPENAPI_USER){
  592 + for (String tenantRole : userDTO.getRoleIds()) {
  593 + roleMapper.saveUserRoleMapping(user.getId(), tenantRole);
  594 + }
  595 + }
582 organizationService.bindUserToOrganization( 596 organizationService.bindUserToOrganization(
583 tenantId, user.getId(), userDTO.getOrganizationIds()); 597 tenantId, user.getId(), userDTO.getOrganizationIds());
584 - for (String tenantRole : userDTO.getRoleIds()) {  
585 - roleMapper.saveUserRoleMapping(user.getId(), tenantRole);  
586 - }  
587 }else{ 598 }else{
588 //查询租户的角色 599 //查询租户的角色
589 List<SysTenantRoleEntity> tenantRoleList = validateTenantRole(userDTO.getTenantId()); 600 List<SysTenantRoleEntity> tenantRoleList = validateTenantRole(userDTO.getTenantId());
  1 +package org.thingsboard.server.dao.yunteng.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import org.apache.ibatis.annotations.Mapper;
  5 +import org.apache.ibatis.annotations.Param;
  6 +import org.thingsboard.server.dao.yunteng.entities.TenantBaseEntity;
  7 +import org.thingsboard.server.dao.yunteng.entities.TkApplicationApiEntity;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +
  12 +@Mapper
  13 +public interface ApplicationApiMapper extends BaseMapper<TkApplicationApiEntity> {
  14 +
  15 + int deleteByAppIds(@Param("applicationIds") Collection<String> applicationId);
  16 +}
  1 +package org.thingsboard.server.dao.yunteng.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import org.apache.ibatis.annotations.Mapper;
  5 +import org.apache.ibatis.annotations.Param;
  6 +import org.thingsboard.server.common.data.yunteng.dto.SysDictItemDTO;
  7 +import org.thingsboard.server.dao.yunteng.entities.SysDictItemEntity;
  8 +import org.thingsboard.server.dao.yunteng.entities.TenantBaseEntity;
  9 +import org.thingsboard.server.dao.yunteng.entities.TkApplicationEntity;
  10 +
  11 +import java.util.List;
  12 +
  13 +@Mapper
  14 +public interface ApplicationMapper extends BaseMapper<TkApplicationEntity> {
  15 +
  16 +}
  1 +package org.thingsboard.server.dao.yunteng.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import org.apache.ibatis.annotations.Mapper;
  5 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiEntity;
  6 +
  7 +@Mapper
  8 +public interface OpenApiMapper extends BaseMapper<TkOpenApiEntity> {
  9 +
  10 +}
  1 +package org.thingsboard.server.dao.yunteng.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import org.apache.ibatis.annotations.Mapper;
  5 +import org.apache.ibatis.annotations.Param;
  6 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiRecordClassifyDTO;
  7 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiRecordTopDTO;
  8 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiRecordEntity;
  9 +
  10 +import java.util.List;
  11 +
  12 +@Mapper
  13 +public interface OpenApiRecordMapper extends BaseMapper<TkOpenApiRecordEntity> {
  14 +
  15 + List<OpenApiRecordTopDTO> getTop(@Param("tenantId") String tenantId,@Param("page")Integer page,@Param("pageSize")Integer pageSize);
  16 +
  17 + List<OpenApiRecordClassifyDTO> getClassify(@Param("tenantId") String tenantId,
  18 + @Param("type") String type);
  19 +}
  1 +package org.thingsboard.server.dao.yunteng.service;
  2 +
  3 +import org.thingsboard.server.common.data.yunteng.dto.ApplicationDTO;
  4 +import org.thingsboard.server.common.data.yunteng.dto.SysDictDTO;
  5 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  6 +import org.thingsboard.server.dao.yunteng.entities.TkApplicationEntity;
  7 +import org.thingsboard.server.dao.yunteng.entities.TkDeviceProfileEntity;
  8 +import org.thingsboard.server.dao.yunteng.entities.TkMessageLogEntity;
  9 +
  10 +import java.util.Map;
  11 +import java.util.Set;
  12 +
  13 +
  14 +public interface ApplicationService extends BaseService<TkApplicationEntity>{
  15 +
  16 + ApplicationDTO getDto(String id);
  17 +
  18 + TkPageData<ApplicationDTO> page(Map<String, Object> queryMap);
  19 +
  20 + ApplicationDTO save(ApplicationDTO dto,String tenantId);
  21 +
  22 + boolean delete(Set<String> applicationIds);
  23 +
  24 + ApplicationDTO update(ApplicationDTO dto);
  25 +
  26 + ApplicationDTO getByKeyAndSecret(String key,String Secret);
  27 +
  28 + ApplicationDTO getDtoByUserId(String userId);
  29 +
  30 +}
  1 +package org.thingsboard.server.dao.yunteng.service;
  2 +
  3 +import org.apache.ibatis.annotations.Param;
  4 +import org.thingsboard.server.common.data.yunteng.dto.*;
  5 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  6 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiRecordEntity;
  7 +
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +
  11 +public interface OpenApiRecordService extends BaseService<TkOpenApiRecordEntity>{
  12 +
  13 + OpenApiRecordDTO getDto(String id);
  14 +
  15 + TkPageData<OpenApiRecordDTO> page(Map<String, Object> queryMap);
  16 +
  17 + int save(TkOpenApiRecordEntity entity, String tenantId);
  18 +
  19 + OpenApiRecordTopAllDTO getTop(String tenantId);
  20 +
  21 + TkPageData<OpenApiRecordTopDTO> getPage(String tenantId,Integer page,Integer pageSize);
  22 +
  23 + List<OpenApiRecordClassifyAllDTO> getClassify(String tenantId,String type);
  24 +}
  1 +package org.thingsboard.server.dao.yunteng.service;
  2 +
  3 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiContrlooerDTO;
  4 +import org.thingsboard.server.common.data.yunteng.dto.OpenApiDTO;
  5 +import org.thingsboard.server.common.data.yunteng.dto.ApiMenuDTO;
  6 +import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData;
  7 +import org.thingsboard.server.dao.yunteng.entities.TkOpenApiEntity;
  8 +
  9 +import java.util.List;
  10 +import java.util.Map;
  11 +import java.util.Set;
  12 +
  13 +public interface OpenApiService extends BaseService<TkOpenApiEntity>{
  14 +
  15 + OpenApiDTO getDto(String id);
  16 +
  17 + TkPageData<OpenApiDTO> page(Map<String, Object> queryMap);
  18 +
  19 + OpenApiDTO save(OpenApiDTO dto, String tenantId);
  20 +
  21 + boolean delete(Set<String> applicationIds);
  22 +
  23 + OpenApiDTO update(OpenApiDTO dto, String tenantId);
  24 +
  25 + List<ApiMenuDTO> getMenu(String tenantId);
  26 +
  27 + List<OpenApiContrlooerDTO> getByListId(List<String> ids);
  28 +
  29 +
  30 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +
  4 +<mapper namespace="org.thingsboard.server.dao.yunteng.mapper.ApplicationApiMapper">
  5 + <resultMap type="org.thingsboard.server.dao.yunteng.entities.TkApplicationApiEntity" id="userRoleMap">
  6 + <result property="applicationId" column="application_id"/>
  7 + <result property="apiId" column="api_id"/>
  8 + </resultMap>
  9 +
  10 + <delete id="deleteByAppIds">
  11 + DELETE FROM tk_application_api WHERE application_id IN
  12 + <foreach collection="applicationIds" item="applicationId" open="(" separator="," close=")">
  13 + #{applicationId}
  14 + </foreach>
  15 + </delete>
  16 +
  17 +</mapper>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +
  4 +<mapper namespace="org.thingsboard.server.dao.yunteng.mapper.OpenApiRecordMapper">
  5 + <resultMap type="org.thingsboard.server.common.data.yunteng.dto.OpenApiRecordTopDTO" id="DTOMap">
  6 + <result property="name" column="application_name"/>
  7 + <result property="recordNum" column="recordNum"/>
  8 + <result property="successCount" column="success_count"/>
  9 + <result property="failureCount" column="failure_count"/>
  10 + <result property="recordProportion" column="recordProportion"/>
  11 + </resultMap>
  12 +
  13 + <resultMap type="org.thingsboard.server.common.data.yunteng.dto.OpenApiRecordClassifyDTO" id="map">
  14 + <result property="classify" column="classify"/>
  15 + <result property="time" column="time_period"/>
  16 + <result property="count" column="call_count"/>
  17 +
  18 + </resultMap>
  19 +
  20 + <select id="getTop" resultMap="DTOMap">
  21 + SELECT
  22 + application_name,
  23 + COUNT(*) AS recordNum,
  24 + ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM tk_open_api_record), 2) AS recordProportion,
  25 + SUM(CASE WHEN state = 0 THEN 1 ELSE 0 END) AS success_count,
  26 + SUM(CASE WHEN state = 1 THEN 1 ELSE 0 END) AS failure_count
  27 + FROM tk_open_api_record
  28 + WHERE tenant_id = #{tenantId}
  29 + GROUP BY application_name
  30 + ORDER BY recordNum desc
  31 + <if test="page != null">
  32 + LIMIT #{pageSize} OFFSET #{page}
  33 + </if>
  34 + </select>
  35 +
  36 + <select id="getClassify" resultMap="map">
  37 + SELECT
  38 + classify,
  39 + <if test="type == 'hour'">
  40 + DATE_TRUNC('hour', request_time) AS time_period,
  41 + </if>
  42 + <if test="type == 'week'">
  43 + DATE_TRUNC('week', request_time) AS time_period,
  44 + </if>
  45 + <if test="type == 'month'">
  46 + DATE_TRUNC('month', request_time) AS time_period,
  47 + </if>
  48 + COUNT(*) AS call_count
  49 + FROM
  50 + tk_open_api_record
  51 + WHERE tenant_id = #{tenantId}
  52 + GROUP BY
  53 + classify,
  54 + <if test="type == 'hour'">
  55 + DATE_TRUNC('hour', request_time)
  56 + </if>
  57 + <if test="type == 'week'">
  58 + DATE_TRUNC('week', request_time)
  59 + </if>
  60 + <if test="type == 'month'">
  61 + DATE_TRUNC('month', request_time)
  62 + </if>
  63 + ORDER BY
  64 + time_period
  65 + </select>
  66 +
  67 +
  68 +</mapper>