重构前端逻辑
This commit is contained in:
parent
dc01b87943
commit
f75a4b5f7e
@ -39,12 +39,16 @@ interface PendingApprovalModalProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
workflowDefinitionKeys?: string[]; // 工作流定义键列表
|
||||
teamId?: number; // 团队ID,用于筛选指定团队的审批任务
|
||||
environmentId?: number; // 环境ID,用于筛选指定环境的审批任务
|
||||
}
|
||||
|
||||
export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
|
||||
open,
|
||||
onOpenChange,
|
||||
workflowDefinitionKeys,
|
||||
teamId,
|
||||
environmentId,
|
||||
}) => {
|
||||
const { toast } = useToast();
|
||||
const [loading, setLoading] = useState(false);
|
||||
@ -61,7 +65,7 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
|
||||
const loadApprovalList = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await getMyApprovalTasks(workflowDefinitionKeys);
|
||||
const response = await getMyApprovalTasks(workflowDefinitionKeys, teamId, environmentId);
|
||||
if (response) {
|
||||
setApprovalList(response || []);
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import type { DeployTeam } from '../types';
|
||||
|
||||
interface UsePendingApprovalOptions {
|
||||
teams: DeployTeam[];
|
||||
currentTeamId?: number | null; // 当前选中的团队ID
|
||||
currentEnvId?: number | null; // 当前选中的环境ID
|
||||
pollingEnabled?: boolean;
|
||||
pollingInterval?: number; // 轮询间隔,默认30秒
|
||||
}
|
||||
@ -12,9 +14,12 @@ interface UsePendingApprovalOptions {
|
||||
* 待审批数据管理 Hook
|
||||
* 负责管理待审批任务的加载和刷新
|
||||
* 优化:添加智能轮询,与部署数据同步刷新
|
||||
* 支持按团队和环境筛选待审批任务
|
||||
*/
|
||||
export function usePendingApproval({
|
||||
teams,
|
||||
currentTeamId,
|
||||
currentEnvId,
|
||||
pollingEnabled = true,
|
||||
pollingInterval = 30000 // 默认30秒
|
||||
}: UsePendingApprovalOptions) {
|
||||
@ -41,7 +46,12 @@ export function usePendingApproval({
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await getMyApprovalTasks(workflowDefinitionKeys);
|
||||
// 传递 teamId 和 environmentId 参数精确筛选
|
||||
const response = await getMyApprovalTasks(
|
||||
workflowDefinitionKeys,
|
||||
currentTeamId || undefined,
|
||||
currentEnvId || undefined
|
||||
);
|
||||
if (response) {
|
||||
setPendingApprovalCount(response.length || 0);
|
||||
}
|
||||
@ -49,7 +59,7 @@ export function usePendingApproval({
|
||||
// 静默失败,不影响主页面
|
||||
console.error('Failed to load pending approval count:', error);
|
||||
}
|
||||
}, [workflowDefinitionKeys, pollingEnabled]);
|
||||
}, [workflowDefinitionKeys, currentTeamId, currentEnvId, pollingEnabled]);
|
||||
|
||||
// 轮询待审批数量
|
||||
useEffect(() => {
|
||||
|
||||
@ -49,6 +49,8 @@ const Dashboard: React.FC = () => {
|
||||
|
||||
const approvalData = usePendingApproval({
|
||||
teams: deploymentData.teams,
|
||||
currentTeamId: deploymentData.currentTeamId,
|
||||
currentEnvId: deploymentData.currentEnvId,
|
||||
pollingEnabled: !deploymentData.loading
|
||||
});
|
||||
|
||||
@ -60,6 +62,14 @@ const Dashboard: React.FC = () => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [deploymentData.teams.length]);
|
||||
|
||||
// 监听团队/环境切换,自动刷新待审批数量
|
||||
useEffect(() => {
|
||||
if (deploymentData.currentTeamId && deploymentData.currentEnvId) {
|
||||
approvalData.loadPendingApprovalCount();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [deploymentData.currentTeamId, deploymentData.currentEnvId]);
|
||||
|
||||
// 计算当前环境是否应该显示待审批按钮
|
||||
// 逻辑:当前环境需要审批 且 用户是该环境的审批人
|
||||
const shouldShowApprovalButton = React.useMemo(() => {
|
||||
@ -160,6 +170,8 @@ const Dashboard: React.FC = () => {
|
||||
open={approvalData.approvalModalOpen}
|
||||
onOpenChange={approvalData.setApprovalModalOpen}
|
||||
workflowDefinitionKeys={approvalData.workflowDefinitionKeys}
|
||||
teamId={deploymentData.currentTeamId || undefined}
|
||||
environmentId={deploymentData.currentEnvId || undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -26,11 +26,28 @@ export const getDeployRecordFlowGraph = (deployRecordId: number) =>
|
||||
/**
|
||||
* 获取我的待审批任务列表
|
||||
* @param workflowDefinitionKeys 工作流定义键列表(可选)
|
||||
* @param teamId 团队ID,用于筛选指定团队的审批任务(可选)
|
||||
* @param environmentId 环境ID,用于筛选指定环境的审批任务(可选)
|
||||
*/
|
||||
export const getMyApprovalTasks = (workflowDefinitionKeys?: string[]) => {
|
||||
const params = workflowDefinitionKeys && workflowDefinitionKeys.length > 0
|
||||
? { workflowDefinitionKeys: workflowDefinitionKeys.join(',') }
|
||||
: {};
|
||||
export const getMyApprovalTasks = (
|
||||
workflowDefinitionKeys?: string[],
|
||||
teamId?: number,
|
||||
environmentId?: number
|
||||
) => {
|
||||
const params: Record<string, any> = {};
|
||||
|
||||
if (workflowDefinitionKeys && workflowDefinitionKeys.length > 0) {
|
||||
params.workflowDefinitionKeys = workflowDefinitionKeys.join(',');
|
||||
}
|
||||
|
||||
if (teamId !== undefined) {
|
||||
params.teamId = teamId;
|
||||
}
|
||||
|
||||
if (environmentId !== undefined) {
|
||||
params.environmentId = environmentId;
|
||||
}
|
||||
|
||||
return request.get<PendingApprovalTask[]>(`${DEPLOY_URL}/my-approval-tasks`, { params });
|
||||
};
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ import {
|
||||
createTeamApplication,
|
||||
updateTeamApplication,
|
||||
} from '../service';
|
||||
import { getRepositoryBranches } from '@/pages/Resource/Git/List/service';
|
||||
import { getRepositoryBranchesList } from '@/pages/Resource/Git/List/service';
|
||||
import TeamApplicationDialog from './TeamApplicationDialog';
|
||||
|
||||
interface TeamApplicationManageDialogProps {
|
||||
@ -167,12 +167,13 @@ export const TeamApplicationManageDialog: React.FC<
|
||||
if (!app.repoProjectId || !app.externalSystemId) {
|
||||
return [];
|
||||
}
|
||||
const result = await getRepositoryBranches({
|
||||
// 使用不分页的列表接口
|
||||
const result = await getRepositoryBranchesList({
|
||||
externalSystemId: app.externalSystemId,
|
||||
repoProjectId: app.repoProjectId,
|
||||
});
|
||||
// getRepositoryBranches 返回 Page 类型,需要提取 content
|
||||
return Array.isArray(result) ? result : (result as any).content || [];
|
||||
// getRepositoryBranchesList 直接返回数组,不需要提取 content
|
||||
return Array.isArray(result) ? result : [];
|
||||
};
|
||||
|
||||
const handleLoadJenkinsJobs = async (systemId: number) => {
|
||||
|
||||
109
frontend/src/pages/Error/NoPermission.tsx
Normal file
109
frontend/src/pages/Error/NoPermission.tsx
Normal file
@ -0,0 +1,109 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { ShieldOff, LogOut, RefreshCw, Mail } from 'lucide-react';
|
||||
import { logout } from '@/store/userSlice';
|
||||
|
||||
/**
|
||||
* 无权限欢迎页
|
||||
* 当用户登录成功但没有分配任何菜单权限时显示
|
||||
*/
|
||||
const NoPermission: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleLogout = () => {
|
||||
dispatch(logout());
|
||||
navigate('/login', { replace: true });
|
||||
};
|
||||
|
||||
const handleRefresh = () => {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 flex flex-col items-center justify-center bg-slate-50 p-8 overflow-hidden">
|
||||
<div className="max-w-2xl text-center">
|
||||
{/* 图标 */}
|
||||
<div className="mb-6 flex justify-center">
|
||||
<div className="rounded-full bg-blue-100 p-6">
|
||||
<ShieldOff className="h-16 w-16 text-blue-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 标题 */}
|
||||
<div className="mb-6">
|
||||
<h1 className="text-3xl font-bold text-slate-800">
|
||||
欢迎使用链宇Deploy Ease平台
|
||||
</h1>
|
||||
<h2 className="mt-3 text-xl font-medium text-slate-600">
|
||||
您的账户已成功创建
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{/* 描述 */}
|
||||
<div className="mb-8 space-y-3 text-slate-600">
|
||||
<p className="text-base">
|
||||
您的账户暂时没有分配任何权限,无法访问系统功能。
|
||||
</p>
|
||||
<p className="text-base">
|
||||
请联系系统管理员为您分配角色和权限后,即可开始使用。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 信息卡片 */}
|
||||
<div className="mb-8 rounded-lg bg-white border border-slate-200 p-6 text-left">
|
||||
<h3 className="mb-3 text-sm font-semibold text-slate-800">
|
||||
下一步操作
|
||||
</h3>
|
||||
<ul className="space-y-2 text-sm text-slate-600">
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="mt-0.5 text-blue-600">•</span>
|
||||
<span>联系系统管理员为您分配角色权限</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="mt-0.5 text-blue-600">•</span>
|
||||
<span>通过企业内部通讯工具联系管理员</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2">
|
||||
<span className="mt-0.5 text-blue-600">•</span>
|
||||
<span>权限分配完成后,点击下方"刷新权限"按钮</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="mt-4 pt-4 border-t border-slate-100 flex items-center gap-2 text-sm">
|
||||
<Mail className="h-4 w-4 text-slate-400" />
|
||||
<span className="text-slate-500">
|
||||
企业微信联系 <span className="font-medium text-slate-700">杨帆</span>、<span className="font-medium text-slate-700">宋伟</span> 开通
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div className="flex justify-center gap-4">
|
||||
<button
|
||||
onClick={handleRefresh}
|
||||
className="inline-flex items-center gap-2 rounded-lg border border-slate-300 bg-white px-6 py-3 text-slate-700 transition-colors hover:bg-slate-50"
|
||||
>
|
||||
<RefreshCw className="h-5 w-5" />
|
||||
刷新权限
|
||||
</button>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-6 py-3 text-white transition-colors hover:bg-blue-700"
|
||||
>
|
||||
<LogOut className="h-5 w-5" />
|
||||
退出登录
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 提示文本 */}
|
||||
<p className="mt-6 text-xs text-slate-400">
|
||||
提示:权限分配后需要刷新页面或重新登录生效
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NoPermission;
|
||||
Loading…
Reference in New Issue
Block a user