Merge branch 'dev' into test
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -205,8 +205,13 @@
|
||||
<name>中铜 ZStack 私服</name>
|
||||
<url>http://172.16.46.63:30708/repository/test/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>warn</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
33
sql/dm/数据总线API版本历史菜单权限_备忘录模式_20251030.sql
Normal file
33
sql/dm/数据总线API版本历史菜单权限_备忘录模式_20251030.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
-- =============================================
|
||||
-- 数据总线 API 版本历史菜单权限(备忘录模式)
|
||||
-- 功能说明:
|
||||
-- 1. 查看版本历史
|
||||
-- 2. 查看版本详情
|
||||
-- 3. 版本回滚
|
||||
-- 4. 版本对比
|
||||
-- =============================================
|
||||
|
||||
-- 删除旧的版本管理菜单权限
|
||||
DELETE FROM system_menu WHERE id IN (650107, 650108, 650109, 650110);
|
||||
|
||||
-- 插入新的版本历史管理权限
|
||||
INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name,
|
||||
status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
|
||||
VALUES
|
||||
-- 查询版本历史列表
|
||||
(650107, 'API版本历史', 'databus:gateway:version:query', 3, 7, 6501, '', '', '', '',
|
||||
0, '1', '1', '1', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '0'),
|
||||
-- 查看版本详情
|
||||
(650108, 'API版本详情', 'databus:gateway:version:detail', 3, 8, 6501, '', '', '', '',
|
||||
0, '1', '1', '1', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '0'),
|
||||
-- 版本回滚
|
||||
(650109, 'API版本回滚', 'databus:gateway:version:rollback', 3, 9, 6501, '', '', '', '',
|
||||
0, '1', '1', '1', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '0'),
|
||||
-- 版本对比
|
||||
(650110, 'API版本对比', 'databus:gateway:version:compare', 3, 10, 6501, '', '', '', '',
|
||||
0, '1', '1', '1', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '0');
|
||||
|
||||
-- 说明
|
||||
-- 1. 不再需要"创建版本"权限,因为系统自动创建
|
||||
-- 2. 不再需要"删除版本"权限,版本历史不可删除
|
||||
-- 3. 保留查询、详情、回滚、对比四个核心功能
|
||||
52
sql/dm/数据总线API版本历史表结构_备忘录模式_20251030.sql
Normal file
52
sql/dm/数据总线API版本历史表结构_备忘录模式_20251030.sql
Normal file
@@ -0,0 +1,52 @@
|
||||
-- =============================================
|
||||
-- 数据总线 API 版本历史表(备忘录模式)
|
||||
-- 功能说明:
|
||||
-- 1. 每次保存 API 配置时自动创建版本记录
|
||||
-- 2. 版本号自动递增(v1, v2, v3...)
|
||||
-- 3. 保留完整历史链,不可删除
|
||||
-- 4. 支持一键回滚到任意历史版本
|
||||
-- 5. 支持版本对比功能
|
||||
-- =============================================
|
||||
|
||||
-- 如果表已存在则删除
|
||||
DROP TABLE IF EXISTS databus_api_version;
|
||||
|
||||
-- 创建版本历史表(DM8 语法)
|
||||
CREATE TABLE databus_api_version (
|
||||
id BIGINT NOT NULL,
|
||||
api_id BIGINT NOT NULL,
|
||||
version_number INTEGER NOT NULL,
|
||||
snapshot_data CLOB NOT NULL,
|
||||
description VARCHAR(500),
|
||||
is_current NUMBER(1) DEFAULT 0 NOT NULL,
|
||||
operator VARCHAR(64),
|
||||
creator VARCHAR(64) DEFAULT '' NOT NULL,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updater VARCHAR(64) DEFAULT '' NOT NULL,
|
||||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
deleted NUMBER(1) DEFAULT 0 NOT NULL,
|
||||
tenant_id BIGINT DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT pk_databus_api_version PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
-- 创建索引
|
||||
CREATE INDEX idx_databus_api_version_api_id ON databus_api_version (api_id);
|
||||
CREATE INDEX idx_databus_api_version_version_number ON databus_api_version (api_id, version_number);
|
||||
CREATE INDEX idx_databus_api_version_is_current ON databus_api_version (api_id, is_current);
|
||||
CREATE INDEX idx_databus_api_version_create_time ON databus_api_version (create_time);
|
||||
CREATE INDEX idx_databus_api_version_operator ON databus_api_version (operator);
|
||||
|
||||
COMMENT ON TABLE databus_api_version IS '数据总线API版本历史表:采用备忘录模式,每次保存API时自动创建版本快照,支持完整的版本历史追溯和回滚';
|
||||
COMMENT ON COLUMN databus_api_version.id IS '主键ID';
|
||||
COMMENT ON COLUMN databus_api_version.api_id IS 'API定义ID,关联databus_api_definition表';
|
||||
COMMENT ON COLUMN databus_api_version.version_number IS '版本号,同一API下自动递增(1,2,3...)';
|
||||
COMMENT ON COLUMN databus_api_version.snapshot_data IS 'API完整配置快照(JSON格式),包含definition、steps、transforms等所有信息';
|
||||
COMMENT ON COLUMN databus_api_version.description IS '变更说明,记录本次修改的内容';
|
||||
COMMENT ON COLUMN databus_api_version.is_current IS '是否为当前版本(1=是,0=否),同一API只有一个当前版本';
|
||||
COMMENT ON COLUMN databus_api_version.operator IS '操作人,记录谁创建了这个版本';
|
||||
COMMENT ON COLUMN databus_api_version.creator IS '创建者';
|
||||
COMMENT ON COLUMN databus_api_version.create_time IS '创建时间(版本创建时间)';
|
||||
COMMENT ON COLUMN databus_api_version.updater IS '更新者';
|
||||
COMMENT ON COLUMN databus_api_version.update_time IS '更新时间';
|
||||
COMMENT ON COLUMN databus_api_version.deleted IS '是否删除(逻辑删除,实际不删除版本历史)';
|
||||
COMMENT ON COLUMN databus_api_version.tenant_id IS '租户ID';
|
||||
13
sql/dm/数据总线API访问日志菜单权限_20251028.sql
Normal file
13
sql/dm/数据总线API访问日志菜单权限_20251028.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- 数据总线 API 访问日志菜单权限初始化(DM8)
|
||||
-- 创建访问日志页面及查询按钮权限。如已存在将先行移除再新增。
|
||||
DELETE FROM system_menu WHERE id IN (6504, 650401);
|
||||
|
||||
INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name,
|
||||
status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
|
||||
VALUES (6504, '访问日志', 'databus:gateway:access-log:query', 2, 40, 6500, 'access-log', 'ep:document', 'databus/accesslog/index', 'DatabusAccessLog',
|
||||
0, '1', '1', '1', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '0');
|
||||
|
||||
INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name,
|
||||
status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted)
|
||||
VALUES (650401, '访问日志查询', 'databus:gateway:access-log:query', 3, 1, 6504, '', '', '', '',
|
||||
0, '1', '1', '1', 'admin', CURRENT_TIMESTAMP, 'admin', CURRENT_TIMESTAMP, '0');
|
||||
0
sql/dm/数据总线API访问日志表结构_20251028.sql
Normal file
0
sql/dm/数据总线API访问日志表结构_20251028.sql
Normal file
52
sql/dm/权限监督功能.sql
Normal file
52
sql/dm/权限监督功能.sql
Normal file
@@ -0,0 +1,52 @@
|
||||
-- 权限监督按钮及接口权限(DM8 专用)
|
||||
-- 执行前请确认未占用 1068 主键
|
||||
|
||||
DELETE FROM system_menu WHERE id = 1068;
|
||||
|
||||
INSERT INTO system_menu (
|
||||
id,
|
||||
name,
|
||||
permission,
|
||||
type,
|
||||
sort,
|
||||
parent_id,
|
||||
path,
|
||||
icon,
|
||||
component,
|
||||
component_name,
|
||||
status,
|
||||
visible,
|
||||
keep_alive,
|
||||
always_show,
|
||||
creator,
|
||||
create_time,
|
||||
updater,
|
||||
update_time,
|
||||
deleted
|
||||
)
|
||||
SELECT
|
||||
1068,
|
||||
'权限监督',
|
||||
'system:permission:user-permission-supervision',
|
||||
3,
|
||||
9,
|
||||
101,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
NULL,
|
||||
0,
|
||||
'1',
|
||||
'1',
|
||||
'1',
|
||||
'admin',
|
||||
'2025-10-29 00:00:00',
|
||||
'',
|
||||
'2025-10-29 00:00:00',
|
||||
'0'
|
||||
FROM dual
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM system_menu
|
||||
WHERE id = 1068
|
||||
);
|
||||
@@ -31,6 +31,11 @@
|
||||
<artifactId>zt-spring-boot-starter-biz-data-permission</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
<artifactId>zt-spring-boot-starter-biz-tenant</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>com.zt.plat</groupId>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,30 +20,68 @@ public class CompanyVisitContextInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
// 解析 header 并设置 visitCompanyId
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
|
||||
Long companyId = WebFrameworkUtils.getCompanyId(request);
|
||||
// 优先使用请求头上的公司信息,若缺失则回退到请求属性或当前登录用户已缓存的访问公司
|
||||
if (companyId == null || companyId <= 0L) {
|
||||
Long attrCompanyId = resolveLong(request.getAttribute(WebFrameworkUtils.HEADER_VISIT_COMPANY_ID));
|
||||
if (attrCompanyId != null && attrCompanyId > 0L) {
|
||||
companyId = attrCompanyId;
|
||||
} else if (loginUser != null && loginUser.getVisitCompanyId() != null && loginUser.getVisitCompanyId() > 0L) {
|
||||
companyId = loginUser.getVisitCompanyId();
|
||||
}
|
||||
}
|
||||
|
||||
String companyName = WebFrameworkUtils.getCompanyName(request);
|
||||
if (companyId <= 0L) {
|
||||
// 如果没有设置 companyId,则忽略
|
||||
if (companyName == null || companyName.isEmpty()) {
|
||||
Object attrCompanyName = request.getAttribute(WebFrameworkUtils.HEADER_VISIT_COMPANY_NAME);
|
||||
if (attrCompanyName instanceof String) {
|
||||
companyName = (String) attrCompanyName;
|
||||
} else if (loginUser != null) {
|
||||
companyName = loginUser.getVisitCompanyName();
|
||||
}
|
||||
}
|
||||
|
||||
Long deptId = WebFrameworkUtils.getDeptId(request);
|
||||
// 部门信息同样遵循“请求头 -> 请求属性 -> 登录缓存”的回退顺序
|
||||
if (deptId == null || deptId <= 0L) {
|
||||
Long attrDeptId = resolveLong(request.getAttribute(WebFrameworkUtils.HEADER_VISIT_DEPT_ID));
|
||||
if (attrDeptId != null && attrDeptId > 0L) {
|
||||
deptId = attrDeptId;
|
||||
} else if (loginUser != null && loginUser.getVisitDeptId() != null && loginUser.getVisitDeptId() > 0L) {
|
||||
deptId = loginUser.getVisitDeptId();
|
||||
}
|
||||
}
|
||||
|
||||
String deptName = WebFrameworkUtils.getDeptName(request);
|
||||
if (deptName == null || deptName.isEmpty()) {
|
||||
Object attrDeptName = request.getAttribute(WebFrameworkUtils.HEADER_VISIT_DEPT_NAME);
|
||||
if (attrDeptName instanceof String) {
|
||||
deptName = (String) attrDeptName;
|
||||
} else if (loginUser != null) {
|
||||
deptName = loginUser.getVisitDeptName();
|
||||
}
|
||||
}
|
||||
|
||||
if (companyId == null || companyId <= 0L) {
|
||||
CompanyContextHolder.setIgnore(true);
|
||||
return true;
|
||||
}
|
||||
Long deptId = WebFrameworkUtils.getDeptId(request);
|
||||
String deptName = WebFrameworkUtils.getDeptName(request);
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
|
||||
CompanyContextHolder.setIgnore(false);
|
||||
CompanyContextHolder.setCompanyId(companyId);
|
||||
if (loginUser == null) {
|
||||
return true;
|
||||
}
|
||||
if (deptId > 0L) {
|
||||
|
||||
// 同步最新的访问公司/部门到登录用户对象,供后续数据权限及上下文读取
|
||||
loginUser.setVisitCompanyId(companyId);
|
||||
loginUser.setVisitCompanyName(companyName);
|
||||
if (deptId != null && deptId > 0L) {
|
||||
loginUser.setVisitDeptId(deptId);
|
||||
loginUser.setVisitDeptName(deptName);
|
||||
}
|
||||
// if (!securityFrameworkService.hasAnyPermissions(PERMISSION)) {
|
||||
// throw exception0(GlobalErrorCodeConstants.FORBIDDEN.getCode(), "您无权切换部门");
|
||||
// }
|
||||
loginUser.setVisitCompanyId(companyId);
|
||||
loginUser.setVisitCompanyName(companyName);
|
||||
CompanyContextHolder.setCompanyId(companyId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -55,4 +93,18 @@ public class CompanyVisitContextInterceptor implements HandlerInterceptor {
|
||||
loginUser.setVisitCompanyId(0L);
|
||||
}
|
||||
}
|
||||
|
||||
private Long resolveLong(Object value) {
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
if (value instanceof String) {
|
||||
try {
|
||||
return Long.parseLong(((String) value).trim());
|
||||
} catch (NumberFormatException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.zt.plat.module.databus.controller.admin.gateway;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.module.databus.controller.admin.gateway.convert.ApiAccessLogConvert;
|
||||
import com.zt.plat.module.databus.controller.admin.gateway.vo.accesslog.ApiAccessLogPageReqVO;
|
||||
import com.zt.plat.module.databus.controller.admin.gateway.vo.accesslog.ApiAccessLogRespVO;
|
||||
import com.zt.plat.module.databus.dal.dataobject.gateway.ApiAccessLogDO;
|
||||
import com.zt.plat.module.databus.service.gateway.ApiAccessLogService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* Databus API 访问日志控制器。
|
||||
*/
|
||||
@Tag(name = "管理后台 - Databus API 访问日志")
|
||||
@RestController
|
||||
@RequestMapping("/databus/gateway/access-log")
|
||||
@Validated
|
||||
public class ApiAccessLogController {
|
||||
|
||||
@Resource
|
||||
private ApiAccessLogService apiAccessLogService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获取访问日志详情")
|
||||
@Parameter(name = "id", description = "日志编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('databus:gateway:access-log:query')")
|
||||
public CommonResult<ApiAccessLogRespVO> get(@RequestParam("id") Long id) {
|
||||
ApiAccessLogDO logDO = apiAccessLogService.get(id);
|
||||
return success(ApiAccessLogConvert.INSTANCE.convert(logDO));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "分页查询访问日志")
|
||||
@PreAuthorize("@ss.hasPermission('databus:gateway:access-log:query')")
|
||||
public CommonResult<PageResult<ApiAccessLogRespVO>> page(@Valid ApiAccessLogPageReqVO pageReqVO) {
|
||||
PageResult<ApiAccessLogDO> pageResult = apiAccessLogService.getPage(pageReqVO);
|
||||
return success(ApiAccessLogConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user