fix: 移除Header Tab栏(与侧边栏重复); 修复approve/reject 400(ApproveRequest去掉required binding)
This commit is contained in:
1 parent
e4958feb1b
commit
925348e583
3 files changed
+38
-9
No files matched your search
@@ -94,7 +94,7 @@ type CreateApprovalProcessRequest struct {
|
|||||||
|
|
||||||
// ApproveRequest 审批请求
|
// ApproveRequest 审批请求
|
||||||
type ApproveRequest struct {
|
type ApproveRequest struct {
|
||||||
Status string `json:"status" binding:"required,oneof=approved rejected"`
|
Status string `json:"status"`
|
||||||
Comment string `json:"comment"`
|
Comment string `json:"comment"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,35 @@ interface AuditRule {
|
|||||||
category: string;
|
category: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mapRecord = (r: any): SQLAuditRecord => ({
|
||||||
|
id: String(r.id),
|
||||||
|
sqlContent: r.sql_content || '',
|
||||||
|
sqlType: r.sql_type || '',
|
||||||
|
databaseName: r.database_name || '',
|
||||||
|
tableName: r.table_name || '',
|
||||||
|
riskLevel: (r.risk_level || 'safe') as SQLAuditRecord['riskLevel'],
|
||||||
|
riskRules: (() => { try { return JSON.parse(r.risk_rules || '[]'); } catch { return []; } })(),
|
||||||
|
status: (r.status || 'pending') as SQLAuditRecord['status'],
|
||||||
|
executor: r.executor || '',
|
||||||
|
approver: r.approver || '',
|
||||||
|
executeTime: r.execute_time || undefined,
|
||||||
|
createdAt: r.created_at ? new Date(r.created_at).toLocaleString('zh-CN') : '',
|
||||||
|
affectedRows: r.affected_rows || 0,
|
||||||
|
executionTime: r.execution_time || undefined,
|
||||||
|
sourceIP: r.source_ip || '',
|
||||||
|
application: r.application || '',
|
||||||
|
ticketId: r.ticket_id || '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapRule = (r: any): AuditRule => ({
|
||||||
|
id: String(r.id),
|
||||||
|
name: r.name || '',
|
||||||
|
description: r.description || '',
|
||||||
|
enabled: r.enabled ?? true,
|
||||||
|
severity: (r.severity || 'medium') as AuditRule['severity'],
|
||||||
|
category: r.category || '',
|
||||||
|
});
|
||||||
|
|
||||||
const SQLAuditManager: React.FC = () => {
|
const SQLAuditManager: React.FC = () => {
|
||||||
const [records, setRecords] = useState<SQLAuditRecord[]>([]);
|
const [records, setRecords] = useState<SQLAuditRecord[]>([]);
|
||||||
const [rules, setRules] = useState<AuditRule[]>([]);
|
const [rules, setRules] = useState<AuditRule[]>([]);
|
||||||
@@ -74,7 +103,7 @@ const SQLAuditManager: React.FC = () => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await sqlAuditApi.getRecords();
|
const res = await sqlAuditApi.getRecords();
|
||||||
setRecords(res.data || []);
|
setRecords((res.list || []).map(mapRecord));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error('获取SQL审计记录失败');
|
toast.error('获取SQL审计记录失败');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -85,7 +114,7 @@ const SQLAuditManager: React.FC = () => {
|
|||||||
const fetchRules = async () => {
|
const fetchRules = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await sqlAuditApi.getRules();
|
const res = await sqlAuditApi.getRules();
|
||||||
setRules(res.data || []);
|
setRules((res.list || []).map(mapRule));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error('获取审计规则失败');
|
toast.error('获取审计规则失败');
|
||||||
}
|
}
|
||||||
@@ -97,7 +126,7 @@ const SQLAuditManager: React.FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await sqlAuditApi.analyzeSQL({ sql: sqlContent });
|
await sqlAuditApi.analyzeSQL({ sql: sqlContent });
|
||||||
toast.success('SQL分析完成');
|
toast.success('SQL分析完成');
|
||||||
setNewAuditOpen(false);
|
setNewAuditOpen(false);
|
||||||
setSqlContent('');
|
setSqlContent('');
|
||||||
@@ -137,10 +166,10 @@ const SQLAuditManager: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleRule = async (ruleId: string, enabled: boolean) => {
|
const toggleRule = async (ruleId: string) => {
|
||||||
try {
|
try {
|
||||||
await sqlAuditApi.toggleRule(ruleId, enabled);
|
await sqlAuditApi.toggleRule(ruleId);
|
||||||
setRules(rules.map(r => r.id === ruleId ? { ...r, enabled } : r));
|
fetchRules();
|
||||||
toast.success('规则状态已更新');
|
toast.success('规则状态已更新');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error('更新规则失败');
|
toast.error('更新规则失败');
|
||||||
@@ -432,7 +461,7 @@ const SQLAuditManager: React.FC = () => {
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Switch
|
<Switch
|
||||||
checked={rule.enabled}
|
checked={rule.enabled}
|
||||||
onCheckedChange={(checked) => toggleRule(rule.id, checked)}
|
onCheckedChange={() => toggleRule(rule.id)}
|
||||||
/>
|
/>
|
||||||
<Label className="text-sm">{rule.enabled ? '已启用' : '已禁用'}</Label>
|
<Label className="text-sm">{rule.enabled ? '已启用' : '已禁用'}</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ export const auditApi = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== SQL 审计 API(暂无后端,返回空结果优雅降级) ====================
|
// ==================== SQL 审计 API ====================
|
||||||
export const sqlAuditApi = {
|
export const sqlAuditApi = {
|
||||||
getRecords: async (params?: Record<string, string>) => {
|
getRecords: async (params?: Record<string, string>) => {
|
||||||
return http.get<ListResponse>('/sql-audit/records', params);
|
return http.get<ListResponse>('/sql-audit/records', params);
|
||||||
|
|||||||
Reference in new issue
Block a user