package com.iot.gateway.admin; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.iot.gateway.common.BizException; import com.iot.gateway.common.Result; import com.iot.gateway.entity.OpenClient; import com.iot.gateway.mapper.OpenClientMapper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.security.SecureRandom; import java.util.Map; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Slf4j @Tag(name = "开放平台管理 - 三方应用凭据管理") @RestController @RequestMapping("/api/open/client") public class OpenClientAdminController { @Autowired private OpenClientMapper clientMapper; private static final SecureRandom RANDOM = new SecureRandom(); @Operation(summary = "三方应用凭据分页列表") @GetMapping("/page") public Result> page( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(required = false) Long tenantId, @RequestParam(required = false) String keyword) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); if (tenantId != null) { qw.eq(OpenClient::getTenantId, tenantId); } if (StringUtils.hasText(keyword)) { qw.and(w -> w.like(OpenClient::getClientName, keyword) .or().like(OpenClient::getClientId, keyword)); } qw.orderByDesc(OpenClient::getCreateTime); return Result.success(clientMapper.selectPage(page, qw)); } @Operation(summary = "获取凭据详情") @GetMapping("/{id}") public Result getById(@PathVariable Long id) { OpenClient client = clientMapper.selectById(id); if (client == null) throw new BizException("客户端凭据不存在"); return Result.success(client); } @Operation(summary = "新建三方应用凭据 (自动生成 ClientId 与 Secret)") @PostMapping public Result create(@RequestBody OpenClient req) { req.setId(null); req.setClientId("client_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12)); req.setClientSecret("sec_" + UUID.randomUUID().toString().replace("-", "") + Long.toHexString(RANDOM.nextLong())); if (req.getTenantId() == null) req.setTenantId(1L); if (!StringUtils.hasText(req.getScopes())) req.setScopes("device.read"); if (req.getStatus() == null) req.setStatus(1); if (req.getRateLimit() == null) req.setRateLimit(60); clientMapper.insert(req); log.info("新建开放应用凭据: id={}, clientId={}", req.getId(), req.getClientId()); return Result.success(req); } @Operation(summary = "修改三方应用凭据") @PutMapping("/{id}") public Result update(@PathVariable Long id, @RequestBody OpenClient req) { OpenClient client = clientMapper.selectById(id); if (client == null) throw new BizException("客户端凭据不存在"); client.setClientName(req.getClientName()); if (req.getScopes() != null) client.setScopes(req.getScopes()); client.setIpWhitelist(req.getIpWhitelist()); if (req.getRateLimit() != null) client.setRateLimit(req.getRateLimit()); if (req.getStatus() != null) client.setStatus(req.getStatus()); client.setExpireTime(req.getExpireTime()); client.setRemark(req.getRemark()); clientMapper.updateById(client); return Result.success(); } @Operation(summary = "删除三方应用凭据") @DeleteMapping("/{id}") public Result delete(@PathVariable Long id) { clientMapper.deleteById(id); return Result.success(); } @Operation(summary = "重置客户端密钥 (Secret)") @PostMapping("/{id}/reset-secret") public Result> resetSecret(@PathVariable Long id) { OpenClient client = clientMapper.selectById(id); if (client == null) throw new BizException("客户端凭据不存在"); String newSecret = "sec_" + UUID.randomUUID().toString().replace("-", "") + Long.toHexString(RANDOM.nextLong()); client.setClientSecret(newSecret); clientMapper.updateById(client); return Result.success(Map.of("clientSecret", newSecret)); } @Operation(summary = "更新客户端状态") @PutMapping("/{id}/status") public Result updateStatus(@PathVariable Long id, @RequestParam Integer status) { OpenClient client = clientMapper.selectById(id); if (client == null) throw new BizException("客户端凭据不存在"); client.setStatus(status); clientMapper.updateById(client); return Result.success(); } }