feat: 工单权限过滤+仪表盘优化+LDAP登录+审批流程+待处理工单

后端:
- ticket_statistics/list_tickets 按用户身份过滤(admin全部, dba/auditor审批相关, developer自己的)
- 新增 /dashboard/my-tickets 接口(按角色返回待处理工单)
- auth.py 本地优先+LDAP fallback 登录认证
- ldap_config.py LDAPS 证书验证修复
- instance_detail.py developer/auditor 权限修复

前端:
- Dashboard 仪表盘: 3核心大数字指标+公告+我的待处理工单
- 删除 ECharts 趋势图(无真实数据)
- TicketDetailPage 审批流程时间线展示
- TicketsPage 工单统计按用户过滤+关联列(我提交的/待我审批)
- types 新增 TicketApproval 等类型定义
This commit is contained in:
logan committed 2026-05-25 20:47:15 +08:00
1 parent be2d6f3894
commit 43d1f3a234
10 files changed
+587 -440

No files matched your search

+25 -6
View File
@@ -15,6 +15,13 @@ import { ticketApi } from '@/api/ticket';
/* ------------------------------------------------------------------ */
/* Types */
/* ------------------------------------------------------------------ */
interface PendingStep {
step_number: number;
step_name: string;
step_type: string;
approver_names: string[];
}
interface TicketItem {
id: number;
ticket_no: string | null;
@@ -31,6 +38,7 @@ interface TicketItem {
approver_id: number | null;
approver_name: string | null;
current_approver_name: string | null;
pending_steps: PendingStep[];
reason: string | null;
audit_result: string | null;
execute_result: string | null;
@@ -285,7 +293,7 @@ export default function TicketsPage() {
<th className="text-left px-4 py-3 font-semibold">工单编号</th>
<th className="text-left px-4 py-3 font-semibold">实例名称</th>
<th className="text-left px-4 py-3 font-semibold">提交人</th>
<th className="text-left px-4 py-3 font-semibold">当前审核人</th>
<th className="text-left px-4 py-3 font-semibold">待处理</th>
<th className="text-left px-4 py-3 font-semibold">状态</th>
<th className="text-left px-4 py-3 font-semibold">
<button onClick={() => setSortAsc(!sortAsc)} className="flex items-center gap-1 hover:text-blue-400 transition-colors">
@@ -310,7 +318,7 @@ export default function TicketsPage() {
<th className="text-left px-4 py-3 font-semibold">工单编号</th>
<th className="text-left px-4 py-3 font-semibold">实例名称</th>
<th className="text-left px-4 py-3 font-semibold">提交人</th>
<th className="text-left px-4 py-3 font-semibold">当前审核人</th>
<th className="text-left px-4 py-3 font-semibold">待处理</th>
<th className="text-left px-4 py-3 font-semibold">状态</th>
<th className="text-left px-4 py-3 font-semibold">
<button onClick={() => setSortAsc(!sortAsc)} className="flex items-center gap-1 hover:text-blue-400 transition-colors">
@@ -352,11 +360,22 @@ export default function TicketsPage() {
</div>
</td>
{/* 当前审核人 */}
{/* 待处理 */}
<td className="px-4 py-3.5">
<span className="text-sm text-[var(--dg-text-secondary)]">
{ticket.current_approver_name || (ticket.status === 'approved' ? '待执行' : '-')}
</span>
{ticket.pending_steps?.length > 0 ? (
<div className="flex flex-col gap-1">
{ticket.pending_steps.map((ps) => (
<div key={ps.step_number} className="flex items-center gap-1.5 text-xs">
<span className="text-[var(--dg-text-muted)] shrink-0">{ps.step_name}:</span>
<span className="text-[var(--dg-text-primary)] font-medium">{ps.approver_names.join(', ')}</span>
</div>
))}
</div>
) : (
<span className="text-sm text-[var(--dg-text-muted)]">
{['success', 'failed', 'rejected', 'rollback'].includes(ticket.status) ? '-' : '-'}
</span>
)}
</td>
{/* 状态 */}