feat(private): 新增内部维护接口自动处理积压 PENDING 申请

- SecurityConfig: 放开 /api/private/admin/** 无需 JWT
- FeatureServiceManager.autoApproveAllPending(): 批量审批所有 PENDING 记录
- OpsController: POST /api/private/admin/approve-pending-requests
  仅私有化模式可用,upgrade.sh 重启后自动调用,无需手动操作

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-05-20 18:45:07 +08:00
父节点 6ca0dcbe74
当前提交 897326ff0f
共有 3 个文件被更改,包括 33 次插入0 次删除

查看文件

@ -40,6 +40,7 @@ public class SecurityConfig {
"/api/private/deployment/status",
"/api/migrate/export", // key-based auth, no JWT
"/api/private/deployment/migrate/import", // private deployment only, no JWT
"/api/private/admin/**", // private deployment internal maintenance, no JWT
"/actuator/health",
"/actuator/info"
).permitAll()

查看文件

@ -303,4 +303,15 @@ public class OpsController {
riskControlService.deleteWord(id);
return ResponseEntity.ok(ApiResponse.ok());
}
/* ---------- 私有化部署维护接口(无需 JWT,仅私有化模式可用 ---------- */
@PostMapping("/api/private/admin/approve-pending-requests")
public ResponseEntity<ApiResponse<Map<String, Object>>> approvePendingRequests() {
if (!deploymentProperties.isPrivate()) {
return ResponseEntity.notFound().build();
}
int approved = featureServiceManager.autoApproveAllPending();
return ResponseEntity.ok(ApiResponse.success(Map.of("approved", approved)));
}
}

查看文件

@ -668,4 +668,25 @@ public class FeatureServiceManager {
appKey, serviceType, status, e.getMessage());
}
}
/**
* 私有化部署维护接口将所有 PENDING 申请自动审批upgrade.sh 重启后调用
*/
@Transactional
public int autoApproveAllPending() {
org.springframework.data.domain.Pageable all =
org.springframework.data.domain.PageRequest.of(0, 1000);
List<ServiceActivationRequestEntity> pendingList =
requestRepository.findByStatusOrderByCreatedAtDesc(Status.PENDING, all).getContent();
int count = 0;
for (ServiceActivationRequestEntity req : pendingList) {
try {
approveRequest(req.getId(), "私有化部署自动开通");
count++;
} catch (Exception e) {
log.warn("Auto-approve failed for request {}: {}", req.getId(), e.getMessage());
}
}
return count;
}
}