mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-13 14:57:16 +08:00
feat: 新增能力开放模块应用管理功能
This commit is contained in:
23
continew-admin-open/pom.xml
Normal file
23
continew-admin-open/pom.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>continew-admin-open</artifactId>
|
||||
<description>能力开放模块(包括应用管理、API开放授权、API开发等)</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 公共模块(存放公共工具类,公共配置等) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-common</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.handler;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.handler.SaAnnotationHandlerInterface;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.continew.admin.open.util.ApiSignCheckUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static cn.dev33.satoken.annotation.handler.SaCheckPermissionHandler._checkMethod;
|
||||
|
||||
/**
|
||||
* 重定义注解 SaCheckPermission 的处理器
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/25 12:03
|
||||
*/
|
||||
@Component
|
||||
public class SaCheckPermissionHandler implements SaAnnotationHandlerInterface<SaCheckPermission> {
|
||||
|
||||
@Override
|
||||
public Class<SaCheckPermission> getHandlerAnnotationClass() {
|
||||
return SaCheckPermission.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkMethod(SaCheckPermission at, Method method) {
|
||||
if (!ApiSignCheckUtils.isExistSignParam()) {
|
||||
_checkMethod(at.type(), at.value(), at.mode(), at.orRole());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.mapper;
|
||||
|
||||
import top.continew.starter.data.mp.base.BaseMapper;
|
||||
import top.continew.admin.open.model.entity.AppDO;
|
||||
|
||||
/**
|
||||
* 应用 Mapper
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
public interface AppMapper extends BaseMapper<AppDO> {}
|
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.model.entity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import top.continew.starter.extension.crud.model.entity.BaseDO;
|
||||
|
||||
/**
|
||||
* 应用实体
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_app")
|
||||
public class AppDO extends BaseDO {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* APPKEY
|
||||
*/
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* APPSECRET
|
||||
*/
|
||||
private String appSecret;
|
||||
|
||||
/**
|
||||
* 应用状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 失效时间
|
||||
*/
|
||||
private LocalDateTime expirationTime;
|
||||
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
private String appDesc;
|
||||
|
||||
/**
|
||||
* secret查看状态
|
||||
*/
|
||||
private String secretStatus;
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.model.query;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.continew.starter.data.core.annotation.Query;
|
||||
import top.continew.starter.data.core.enums.QueryType;
|
||||
|
||||
/**
|
||||
* 应用查询条件
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "应用查询条件")
|
||||
public class AppQuery implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
@Schema(description = "应用名称")
|
||||
@Query(type = QueryType.LIKE)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* APPKEY
|
||||
*/
|
||||
@Schema(description = "APPKEY")
|
||||
@Query(type = QueryType.LIKE)
|
||||
private String appKey;
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.model.req;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.*;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import top.continew.starter.extension.crud.model.req.BaseReq;
|
||||
|
||||
/**
|
||||
* 创建或修改应用信息
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "创建或修改应用信息")
|
||||
public class AppReq extends BaseReq {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
@Schema(description = "应用名称")
|
||||
@NotBlank(message = "应用名称不能为空")
|
||||
@Length(max = 255, message = "应用名称长度不能超过 {max} 个字符")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* APPKEY
|
||||
*/
|
||||
@Schema(description = "应用密钥")
|
||||
@NotBlank(message = "应用密钥不能为空")
|
||||
@Length(max = 255, message = "应用密钥长度不能超过 {max} 个字符")
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 应用状态
|
||||
*/
|
||||
@Schema(description = "应用状态")
|
||||
@NotBlank(message = "应用状态不能为空")
|
||||
@Length(max = 255, message = "应用状态长度不能超过 {max} 个字符")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 失效时间
|
||||
*/
|
||||
@Schema(description = "失效时间")
|
||||
@NotNull(message = "失效时间不能为空")
|
||||
private LocalDateTime expirationTime;
|
||||
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
@Schema(description = "应用描述")
|
||||
@Length(max = 255, message = "应用描述长度不能超过 {max} 个字符")
|
||||
private String appDesc;
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.model.resp;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
import top.continew.starter.extension.crud.model.resp.BaseDetailResp;
|
||||
|
||||
/**
|
||||
* 应用详情信息
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@Schema(description = "应用详情信息")
|
||||
public class AppDetailResp extends BaseDetailResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
@Schema(description = "应用名称")
|
||||
@ExcelProperty(value = "应用名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 应用密钥
|
||||
*/
|
||||
@Schema(description = "应用密钥")
|
||||
@ExcelProperty(value = "应用密钥")
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 应用状态
|
||||
*/
|
||||
@Schema(description = "应用状态")
|
||||
@ExcelProperty(value = "应用状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 失效时间
|
||||
*/
|
||||
@Schema(description = "失效时间")
|
||||
@ExcelProperty(value = "失效时间")
|
||||
private LocalDateTime expirationTime;
|
||||
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
@Schema(description = "应用描述")
|
||||
@ExcelProperty(value = "应用描述")
|
||||
private String appDesc;
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.model.resp;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.continew.starter.extension.crud.model.resp.BaseResp;
|
||||
|
||||
/**
|
||||
* 应用信息
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "应用信息")
|
||||
public class AppResp extends BaseResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
@Schema(description = "应用名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* APPKEY
|
||||
*/
|
||||
@Schema(description = "应用密钥")
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 应用状态
|
||||
*/
|
||||
@Schema(description = "应用状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 失效时间
|
||||
*/
|
||||
@Schema(description = "失效时间")
|
||||
private LocalDateTime expirationTime;
|
||||
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
@Schema(description = "应用描述")
|
||||
private String appDesc;
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.model.resp;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 应用密钥/密码信息
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "应用密钥/密码信息")
|
||||
public class AppSecretGetResp {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 应用密钥
|
||||
*/
|
||||
@Schema(description = "应用密钥")
|
||||
private String appKey;
|
||||
|
||||
/**
|
||||
* 应用密码
|
||||
*/
|
||||
@Schema(description = "应用密码")
|
||||
private String appSecret;
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.service;
|
||||
|
||||
import top.continew.admin.open.model.resp.AppSecretGetResp;
|
||||
import top.continew.starter.extension.crud.service.BaseService;
|
||||
import top.continew.admin.open.model.query.AppQuery;
|
||||
import top.continew.admin.open.model.req.AppReq;
|
||||
import top.continew.admin.open.model.resp.AppDetailResp;
|
||||
import top.continew.admin.open.model.resp.AppResp;
|
||||
|
||||
/**
|
||||
* 应用业务接口
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
public interface AppService extends BaseService<AppResp, AppDetailResp, AppQuery, AppReq> {
|
||||
/**
|
||||
* 根据ID查询应用密码
|
||||
*
|
||||
* @param id ID
|
||||
* @return 应用密码
|
||||
*/
|
||||
AppSecretGetResp getAppSecretById(Long id);
|
||||
|
||||
/**
|
||||
* 根据ID重置应用密码查看状态
|
||||
*
|
||||
* @param id ID
|
||||
*/
|
||||
void resetAppSecretStatusById(Long id, String status);
|
||||
|
||||
/**
|
||||
* 根据应用密钥重置应用密码查看状态
|
||||
*
|
||||
* @param appKey 应用密钥
|
||||
*/
|
||||
void resetAppSecretStatusByAppkey(String appKey, String status);
|
||||
|
||||
/**
|
||||
* 根据ID刷新应用密码
|
||||
*
|
||||
* @param id ID
|
||||
*/
|
||||
void refreshAppSecretByID(Long id);
|
||||
|
||||
/**
|
||||
* 根据应用密钥获取应用密码
|
||||
*
|
||||
* @param appKey 应用密钥
|
||||
* @return 应用密码
|
||||
*/
|
||||
String getAppSecretByAppKey(String appKey);
|
||||
|
||||
/**
|
||||
* 判断应用密钥是否存在
|
||||
*
|
||||
* @param appKey 应用密钥
|
||||
* @return 是否存在(true:存在;false:不存在)
|
||||
*/
|
||||
boolean isExistAppKey(String appKey);
|
||||
|
||||
/**
|
||||
* 判断应用密钥是否过期
|
||||
*
|
||||
* @param appKey 应用密钥
|
||||
* @return 是否过期(true:已过期;false:未过期)
|
||||
*/
|
||||
boolean isExpireAppKey(String appKey);
|
||||
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import top.continew.admin.open.model.resp.AppSecretGetResp;
|
||||
import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;
|
||||
import top.continew.admin.open.mapper.AppMapper;
|
||||
import top.continew.admin.open.model.entity.AppDO;
|
||||
import top.continew.admin.open.model.query.AppQuery;
|
||||
import top.continew.admin.open.model.req.AppReq;
|
||||
import top.continew.admin.open.model.resp.AppDetailResp;
|
||||
import top.continew.admin.open.model.resp.AppResp;
|
||||
import top.continew.admin.open.service.AppService;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 应用业务实现
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AppServiceImpl extends BaseServiceImpl<AppMapper, AppDO, AppResp, AppDetailResp, AppQuery, AppReq> implements AppService {
|
||||
|
||||
// 已激活
|
||||
private final static String APP_ENABLED_KEY = "1";
|
||||
// 未激活
|
||||
private final static String APP_DISABLED_KEY = "0";
|
||||
|
||||
@Override
|
||||
public AppSecretGetResp getAppSecretById(Long id) {
|
||||
AppDO app = baseMapper.lambdaQuery().eq(AppDO::getId, id).one();
|
||||
String appSecret = "********";
|
||||
if (app.getSecretStatus().equals(APP_DISABLED_KEY)) {
|
||||
appSecret = app.getAppSecret();
|
||||
this.resetAppSecretStatusById(id, APP_ENABLED_KEY);
|
||||
}
|
||||
AppSecretGetResp appSecretGetResp = new AppSecretGetResp();
|
||||
appSecretGetResp.setAppKey(app.getAppKey());
|
||||
appSecretGetResp.setAppSecret(appSecret);
|
||||
return appSecretGetResp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAppSecretStatusById(Long id, String status) {
|
||||
baseMapper.lambdaUpdate().set(AppDO::getSecretStatus, status).eq(AppDO::getId, id).update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAppSecretStatusByAppkey(String appKey, String status) {
|
||||
baseMapper.lambdaUpdate().set(AppDO::getSecretStatus, status).eq(AppDO::getAppKey, appKey).update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshAppSecretByID(Long id) {
|
||||
baseMapper.lambdaUpdate().set(AppDO::getAppSecret, IdUtil.simpleUUID()).eq(AppDO::getId, id).update();
|
||||
this.resetAppSecretStatusById(id, APP_DISABLED_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAppSecretByAppKey(String appKey) {
|
||||
return baseMapper.lambdaQuery().select(AppDO::getAppSecret).eq(AppDO::getAppKey, appKey).one().getAppSecret();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExistAppKey(String appKey) {
|
||||
return baseMapper.lambdaQuery().eq(AppDO::getAppKey, appKey).exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpireAppKey(String appKey) {
|
||||
LocalDateTime expirationTime = baseMapper.lambdaQuery()
|
||||
.select(AppDO::getExpirationTime)
|
||||
.eq(AppDO::getAppKey, appKey)
|
||||
.one()
|
||||
.getExpirationTime();
|
||||
return expirationTime.isBefore(LocalDateTimeUtil.of(DateUtil.date()));
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.sign;
|
||||
|
||||
import cn.dev33.satoken.error.SaErrorCode;
|
||||
import cn.dev33.satoken.exception.SaSignException;
|
||||
import cn.dev33.satoken.sign.SaSignTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.continew.admin.open.service.AppService;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static cn.dev33.satoken.SaManager.log;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OpenSignTemplate extends SaSignTemplate {
|
||||
|
||||
private final AppService appService;
|
||||
public static String appKey = "appkey";
|
||||
|
||||
@Override
|
||||
public void checkParamMap(Map<String, String> paramMap) {
|
||||
// 获取必须的参数
|
||||
String timestampValue = paramMap.get(timestamp);
|
||||
String nonceValue = paramMap.get(nonce);
|
||||
String signValue = paramMap.get(sign);
|
||||
String appKeyValue = paramMap.get(appKey);
|
||||
|
||||
// 参数非空校验
|
||||
SaSignException.notEmpty(timestampValue, "缺少 timestamp 字段");
|
||||
SaSignException.notEmpty(nonceValue, "缺少 nonce 字段");
|
||||
SaSignException.notEmpty(signValue, "缺少 sign 字段");
|
||||
SaSignException.notEmpty(appKeyValue, "缺少 appkey 字段");
|
||||
|
||||
// 应用存在性校验
|
||||
SaSignException.notTrue(!appService.isExistAppKey(appKeyValue), "应用不存在");
|
||||
|
||||
// 应用是否过期校验
|
||||
SaSignException.notTrue(appService.isExpireAppKey(appKeyValue), "应用已过期");
|
||||
|
||||
// 依次校验三个参数
|
||||
checkTimestamp(Long.parseLong(timestampValue));
|
||||
checkNonce(nonceValue);
|
||||
checkSign(paramMap, signValue);
|
||||
|
||||
// 通过 √
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createSign(Map<String, ?> paramsMap) {
|
||||
// 根据应用密钥获取对应的应用密码
|
||||
String appKey = (String)((Map)paramsMap).get("appkey");
|
||||
String secretKey = this.appService.getAppSecretByAppKey(appKey);
|
||||
SaSignException.notEmpty(secretKey, "参与参数签名的秘钥不可为空", SaErrorCode.CODE_12201);
|
||||
|
||||
// 如果调用者不小心传入了 sign 参数,则此处需要将 sign 参数排除在外
|
||||
if (paramsMap.containsKey(sign)) {
|
||||
// 为了保证不影响原有的 paramsMap,此处需要再复制一份
|
||||
paramsMap = new TreeMap<>(paramsMap);
|
||||
paramsMap.remove(sign);
|
||||
}
|
||||
|
||||
// 计算签名
|
||||
String paramsStr = joinParamsDictSort(paramsMap);
|
||||
String fullStr = paramsStr + "&" + key + "=" + secretKey;
|
||||
String signStr = abstractStr(fullStr);
|
||||
|
||||
// 输入日志,方便调试
|
||||
log.debug("fullStr:{}", fullStr);
|
||||
log.debug("signStr:{}", signStr);
|
||||
|
||||
// 返回
|
||||
return signStr;
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.open.util;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* API签名验证工具类
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/25 15:31
|
||||
*/
|
||||
public class ApiSignCheckUtils {
|
||||
|
||||
private ApiSignCheckUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断请求是否包含sign参数
|
||||
*
|
||||
* @return 是否包含sign参数(true:包含;false:不包含)
|
||||
*/
|
||||
public static boolean isExistSignParam() {
|
||||
SaRequest saRequest = SaHolder.getRequest();
|
||||
List<String> paramNames = saRequest.getParamNames();
|
||||
return paramNames.stream().anyMatch(paramName -> paramName.equals("sign"));
|
||||
}
|
||||
|
||||
}
|
@@ -50,6 +50,12 @@
|
||||
<artifactId>continew-admin-generator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 能力开放模块(包括应用管理、API开放授权、API开发等) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-open</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Liquibase(用于管理数据库版本,跟踪、管理和应用数据库变化) -->
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
|
@@ -16,8 +16,12 @@
|
||||
|
||||
package top.continew.admin.config.satoken;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.sign.SaSignUtil;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -25,10 +29,13 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import top.continew.admin.common.context.UserContext;
|
||||
import top.continew.admin.common.context.UserContextHolder;
|
||||
import top.continew.admin.open.sign.OpenSignTemplate;
|
||||
import top.continew.starter.auth.satoken.autoconfigure.SaTokenExtensionProperties;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.validate.CheckUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sa-Token 配置
|
||||
*
|
||||
@@ -41,6 +48,7 @@ public class SaTokenConfiguration {
|
||||
|
||||
private final SaTokenExtensionProperties properties;
|
||||
private final LoginPasswordProperties loginPasswordProperties;
|
||||
private final OpenSignTemplate openSignTemplate;
|
||||
|
||||
/**
|
||||
* Sa-Token 权限认证配置
|
||||
@@ -55,15 +63,31 @@ public class SaTokenConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
public SaInterceptor saInterceptor() {
|
||||
SaManager.setSaSignTemplate(openSignTemplate);
|
||||
return new SaExtensionInterceptor(handle -> SaRouter.match(StringConstants.PATH_PATTERN)
|
||||
.notMatch(properties.getSecurity().getExcludes())
|
||||
.check(r -> {
|
||||
StpUtil.checkLogin();
|
||||
if (SaRouter.isMatchCurrURI(loginPasswordProperties.getExcludes())) {
|
||||
return;
|
||||
// 拦截验证sign
|
||||
// 判断是否包含sign参数
|
||||
SaRequest saRequest = SaHolder.getRequest();
|
||||
List<String> paramNames = saRequest.getParamNames();
|
||||
boolean matchParamSign = paramNames.stream().anyMatch(paramName -> paramName.equals("sign"));
|
||||
// 如果包含sign参数走SaToken API接口参数签名验证
|
||||
if (matchParamSign) {
|
||||
try {
|
||||
SaSignUtil.checkRequest(saRequest);
|
||||
} catch (Exception e) {
|
||||
CheckUtils.throwIf(true, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
// 如果不包含sign参数走登录token验证
|
||||
StpUtil.checkLogin();
|
||||
if (SaRouter.isMatchCurrURI(loginPasswordProperties.getExcludes())) {
|
||||
return;
|
||||
}
|
||||
UserContext userContext = UserContextHolder.getContext();
|
||||
CheckUtils.throwIf(userContext.isPasswordExpired(), "密码已过期,请修改密码");
|
||||
}
|
||||
UserContext userContext = UserContextHolder.getContext();
|
||||
CheckUtils.throwIf(userContext.isPasswordExpired(), "密码已过期,请修改密码");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.controller.open;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import top.continew.admin.open.model.resp.AppSecretGetResp;
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.continew.starter.extension.crud.controller.BaseController;
|
||||
import top.continew.admin.open.model.query.AppQuery;
|
||||
import top.continew.admin.open.model.req.AppReq;
|
||||
import top.continew.admin.open.model.resp.AppDetailResp;
|
||||
import top.continew.admin.open.model.resp.AppResp;
|
||||
import top.continew.admin.open.service.AppService;
|
||||
import top.continew.starter.extension.crud.model.resp.BaseIdResp;
|
||||
|
||||
/**
|
||||
* 应用管理 API
|
||||
*
|
||||
* @author chengzi
|
||||
* @since 2024/10/17 16:03
|
||||
*/
|
||||
@Tag(name = "应用管理 API")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@CrudRequestMapping(value = "/open/app", api = {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
|
||||
public class AppController extends BaseController<AppService, AppResp, AppDetailResp, AppQuery, AppReq> {
|
||||
|
||||
private final AppService appService;
|
||||
private final static String APP_DISABLED_KEY = "0";
|
||||
|
||||
@Operation(summary = "刷新应用密码", description = "刷新应用密码")
|
||||
@Parameter(name = "id", description = "ID", example = "test", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("open:app:refreshas")
|
||||
@GetMapping(value = "/{id}/refreshas")
|
||||
public void refreshAppSecret(@PathVariable Long id) {
|
||||
appService.refreshAppSecretByID(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取应用密码", description = "获取应用密码")
|
||||
@Parameter(name = "appKey", description = "应用密钥", example = "test", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("open:app:getas")
|
||||
@GetMapping("/{id}/appsecret")
|
||||
public AppSecretGetResp getAppSecret(@PathVariable Long id) {
|
||||
return appService.getAppSecretById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseIdResp<Long> add(AppReq req) {
|
||||
BaseIdResp<Long> baseIdResp = super.add(req);
|
||||
Long appId = baseIdResp.getId();
|
||||
appService.refreshAppSecretByID(appId);
|
||||
appService.resetAppSecretStatusById(appId, APP_DISABLED_KEY);
|
||||
return baseIdResp;
|
||||
}
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import com.feiniaojin.gracefulresponse.api.ExcludeFromGracefulResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import top.continew.admin.open.util.ApiSignCheckUtils;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||
import top.continew.starter.extension.crud.model.req.BaseReq;
|
||||
import top.continew.starter.extension.crud.model.resp.BaseIdResp;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
import top.continew.starter.extension.crud.service.BaseService;
|
||||
import top.continew.starter.extension.crud.util.ValidateGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 控制器基类
|
||||
*
|
||||
* @param <S> 业务接口
|
||||
* @param <L> 列表类型
|
||||
* @param <D> 详情类型
|
||||
* @param <Q> 查询条件
|
||||
* @param <C> 创建或修改类型
|
||||
* @author Charles7c
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q, C extends BaseReq> {
|
||||
|
||||
@Autowired
|
||||
protected S baseService;
|
||||
|
||||
/**
|
||||
* 分页查询列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param pageQuery 分页查询条件
|
||||
* @return 分页信息
|
||||
*/
|
||||
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
||||
@ResponseBody
|
||||
@GetMapping
|
||||
public PageResp<L> page(Q query, @Validated PageQuery pageQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.page(query, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询树列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 树列表信息
|
||||
*/
|
||||
@Operation(summary = "查询树列表", description = "查询树列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/tree")
|
||||
public List<Tree<Long>> tree(Q query, SortQuery sortQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.tree(query, sortQuery, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 列表信息
|
||||
*/
|
||||
@Operation(summary = "查询列表", description = "查询列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
public List<L> list(Q query, SortQuery sortQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.list(query, sortQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询详情
|
||||
*
|
||||
* @param id ID
|
||||
* @return 详情信息
|
||||
*/
|
||||
@Operation(summary = "查询详情", description = "查询详情")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@GetMapping("/{id}")
|
||||
public D get(@PathVariable("id") Long id) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
* @param req 创建信息
|
||||
* @return 自增 ID
|
||||
*/
|
||||
@Operation(summary = "新增数据", description = "新增数据")
|
||||
@ResponseBody
|
||||
@PostMapping
|
||||
public BaseIdResp<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody C req) {
|
||||
this.checkPermission(Api.ADD);
|
||||
return BaseIdResp.<Long>builder().id(baseService.add(req)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param req 修改信息
|
||||
* @param id ID
|
||||
*/
|
||||
@Operation(summary = "修改数据", description = "修改数据")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@PutMapping("/{id}")
|
||||
public void update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody C req, @PathVariable("id") Long id) {
|
||||
this.checkPermission(Api.UPDATE);
|
||||
baseService.update(req, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param ids ID 列表
|
||||
*/
|
||||
@Operation(summary = "删除数据", description = "删除数据")
|
||||
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@DeleteMapping("/{ids}")
|
||||
public void delete(@PathVariable("ids") List<Long> ids) {
|
||||
this.checkPermission(Api.DELETE);
|
||||
baseService.delete(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @param response 响应对象
|
||||
*/
|
||||
@ExcludeFromGracefulResponse
|
||||
@Operation(summary = "导出数据", description = "导出数据")
|
||||
@GetMapping("/export")
|
||||
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
|
||||
this.checkPermission(Api.EXPORT);
|
||||
baseService.export(query, sortQuery, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 API 类型进行权限验证
|
||||
*
|
||||
* @param api API 类型
|
||||
*/
|
||||
protected void checkPermission(Api api) {
|
||||
// 判断是否包含sign参数
|
||||
if (!ApiSignCheckUtils.isExistSignParam()) {
|
||||
CrudRequestMapping crudRequestMapping = this.getClass().getDeclaredAnnotation(CrudRequestMapping.class);
|
||||
String path = crudRequestMapping.value();
|
||||
String permissionPrefix = String.join(StringConstants.COLON, CharSequenceUtil
|
||||
.splitTrim(path, StringConstants.SLASH));
|
||||
StpUtil.checkPermission("%s:%s".formatted(permissionPrefix, api.name().toLowerCase()));
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,3 +4,34 @@ ALTER TABLE sys_notice
|
||||
ADD COLUMN notice_scope INT NOT NULL COMMENT '通知范围' AFTER terminate_time,
|
||||
ADD COLUMN notice_users JSON DEFAULT NULL COMMENT '通知用户' AFTER notice_scope;
|
||||
COMMIT;
|
||||
|
||||
-- changeset chengzi
|
||||
-- comment 新增应用表
|
||||
CREATE TABLE IF NOT EXISTS `sys_app` (
|
||||
`id` bigint(0) NOT NULL COMMENT 'ID',
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用名称',
|
||||
`app_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用密钥',
|
||||
`app_secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用密码',
|
||||
`status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用状态(0:未激活;1:激活)',
|
||||
`expiration_time` datetime(0) NULL DEFAULT NULL COMMENT '失效时间',
|
||||
`app_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用描述',
|
||||
`secret_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用密码查看状态(0:未查看;1:已查看)',
|
||||
`create_user` bigint(0) NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
|
||||
`update_user` bigint(0) NULL DEFAULT NULL COMMENT '修改人',
|
||||
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用表';
|
||||
INSERT INTO `sys_app` VALUES (639144999463690263, 'ContiNewAdmin', 'admin', '9efcf8859d754288941e61adc72cd250', '1', '2024-10-31 16:53:52', 'ContiNew Admin(Continue New Admin)持续迭代优化的前后端分离中后台管理系统框架。开箱即用,重视每一处代码规范,重视每一种解决方案细节,持续提供舒适的前、后端开发体验。', '1', 1, '2024-10-22 16:54:03', NULL, NULL);
|
||||
-- 应用管理菜单数据
|
||||
INSERT INTO `sys_menu` VALUES (635516486647025735, '能力开放', 0, 1, '/open', 'Open', 'Layout', NULL, 'expand', b'0', b'0', b'0', NULL, 2, 1, 1, '2024-10-12 16:35:38', 1, '2024-10-12 16:35:53');
|
||||
INSERT INTO `sys_menu` VALUES (635516794676711501, '应用管理', 635516486647025735, 2, '/open/app', 'OpenApp', 'open/app/index', NULL, 'common', b'0', b'0', b'0', NULL, 1, 1, 1, '2024-10-12 16:36:51', 1, '2024-10-12 16:49:11');
|
||||
INSERT INTO `sys_menu` VALUES (636598391530328174, '新增', 635516794676711501, 3, NULL, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'open:app:add', 1, 1, 1, '2024-10-15 16:14:44', 1, '2024-10-15 16:45:36');
|
||||
INSERT INTO `sys_menu` VALUES (636599310447808642, '查看', 635516794676711501, 3, NULL, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'open:app:list', 999, 1, 1, '2024-10-15 16:18:23', NULL, NULL);
|
||||
INSERT INTO `sys_menu` VALUES (636599448054534277, '导出', 635516794676711501, 3, NULL, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'open:app:export', 999, 1, 1, '2024-10-15 16:18:56', NULL, NULL);
|
||||
INSERT INTO `sys_menu` VALUES (637299919924760580, '删除', 635516794676711501, 3, NULL, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'open:app:delete', 1, 1, 1, '2024-10-17 14:42:21', NULL, NULL);
|
||||
INSERT INTO `sys_menu` VALUES (637300206014042119, '修改', 635516794676711501, 3, NULL, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'open:app:update', 1, 1, 1, '2024-10-17 14:43:30', NULL, NULL);
|
||||
-- 应用管理字典数据
|
||||
INSERT INTO `sys_dict` VALUES (639152724557963332, '应用状态', 'app_type', NULL, b'0', 1, '2024-10-22 17:24:44', NULL, NULL);
|
||||
INSERT INTO `sys_dict_item` VALUES (639152915579150411, '禁用', '0', 'blue', 999, NULL, 1, 639152724557963332, 1, '2024-10-22 17:25:30', NULL, NULL);
|
||||
INSERT INTO `sys_dict_item` VALUES (639153003290435665, '启用', '1', 'green', 999, NULL, 1, 639152724557963332, 1, '2024-10-22 17:25:51', NULL, NULL);
|
8
pom.xml
8
pom.xml
@@ -29,6 +29,7 @@
|
||||
<module>continew-admin-system</module>
|
||||
<module>continew-admin-common</module>
|
||||
<module>continew-admin-extension</module>
|
||||
<module>continew-admin-open</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
@@ -73,6 +74,13 @@
|
||||
<artifactId>continew-admin-generator</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 能力开放模块 -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-open</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
Reference in New Issue
Block a user