重构前端逻辑
This commit is contained in:
parent
dc01b87943
commit
f75a4b5f7e
@ -39,12 +39,16 @@ interface PendingApprovalModalProps {
|
|||||||
open: boolean;
|
open: boolean;
|
||||||
onOpenChange: (open: boolean) => void;
|
onOpenChange: (open: boolean) => void;
|
||||||
workflowDefinitionKeys?: string[]; // 工作流定义键列表
|
workflowDefinitionKeys?: string[]; // 工作流定义键列表
|
||||||
|
teamId?: number; // 团队ID,用于筛选指定团队的审批任务
|
||||||
|
environmentId?: number; // 环境ID,用于筛选指定环境的审批任务
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
|
export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
|
||||||
open,
|
open,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
workflowDefinitionKeys,
|
workflowDefinitionKeys,
|
||||||
|
teamId,
|
||||||
|
environmentId,
|
||||||
}) => {
|
}) => {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@ -61,7 +65,7 @@ export const PendingApprovalModal: React.FC<PendingApprovalModalProps> = ({
|
|||||||
const loadApprovalList = async () => {
|
const loadApprovalList = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const response = await getMyApprovalTasks(workflowDefinitionKeys);
|
const response = await getMyApprovalTasks(workflowDefinitionKeys, teamId, environmentId);
|
||||||
if (response) {
|
if (response) {
|
||||||
setApprovalList(response || []);
|
setApprovalList(response || []);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import type { DeployTeam } from '../types';
|
|||||||
|
|
||||||
interface UsePendingApprovalOptions {
|
interface UsePendingApprovalOptions {
|
||||||
teams: DeployTeam[];
|
teams: DeployTeam[];
|
||||||
|
currentTeamId?: number | null; // 当前选中的团队ID
|
||||||
|
currentEnvId?: number | null; // 当前选中的环境ID
|
||||||
pollingEnabled?: boolean;
|
pollingEnabled?: boolean;
|
||||||
pollingInterval?: number; // 轮询间隔,默认30秒
|
pollingInterval?: number; // 轮询间隔,默认30秒
|
||||||
}
|
}
|
||||||
@ -12,9 +14,12 @@ interface UsePendingApprovalOptions {
|
|||||||
* 待审批数据管理 Hook
|
* 待审批数据管理 Hook
|
||||||
* 负责管理待审批任务的加载和刷新
|
* 负责管理待审批任务的加载和刷新
|
||||||
* 优化:添加智能轮询,与部署数据同步刷新
|
* 优化:添加智能轮询,与部署数据同步刷新
|
||||||
|
* 支持按团队和环境筛选待审批任务
|
||||||
*/
|
*/
|
||||||
export function usePendingApproval({
|
export function usePendingApproval({
|
||||||
teams,
|
teams,
|
||||||
|
currentTeamId,
|
||||||
|
currentEnvId,
|
||||||
pollingEnabled = true,
|
pollingEnabled = true,
|
||||||
pollingInterval = 30000 // 默认30秒
|
pollingInterval = 30000 // 默认30秒
|
||||||
}: UsePendingApprovalOptions) {
|
}: UsePendingApprovalOptions) {
|
||||||
@ -41,7 +46,12 @@ export function usePendingApproval({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await getMyApprovalTasks(workflowDefinitionKeys);
|
// 传递 teamId 和 environmentId 参数精确筛选
|
||||||
|
const response = await getMyApprovalTasks(
|
||||||
|
workflowDefinitionKeys,
|
||||||
|
currentTeamId || undefined,
|
||||||
|
currentEnvId || undefined
|
||||||
|
);
|
||||||
if (response) {
|
if (response) {
|
||||||
setPendingApprovalCount(response.length || 0);
|
setPendingApprovalCount(response.length || 0);
|
||||||
}
|
}
|
||||||
@ -49,7 +59,7 @@ export function usePendingApproval({
|
|||||||
// 静默失败,不影响主页面
|
// 静默失败,不影响主页面
|
||||||
console.error('Failed to load pending approval count:', error);
|
console.error('Failed to load pending approval count:', error);
|
||||||
}
|
}
|
||||||
}, [workflowDefinitionKeys, pollingEnabled]);
|
}, [workflowDefinitionKeys, currentTeamId, currentEnvId, pollingEnabled]);
|
||||||
|
|
||||||
// 轮询待审批数量
|
// 轮询待审批数量
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -49,6 +49,8 @@ const Dashboard: React.FC = () => {
|
|||||||
|
|
||||||
const approvalData = usePendingApproval({
|
const approvalData = usePendingApproval({
|
||||||
teams: deploymentData.teams,
|
teams: deploymentData.teams,
|
||||||
|
currentTeamId: deploymentData.currentTeamId,
|
||||||
|
currentEnvId: deploymentData.currentEnvId,
|
||||||
pollingEnabled: !deploymentData.loading
|
pollingEnabled: !deploymentData.loading
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -60,6 +62,14 @@ const Dashboard: React.FC = () => {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [deploymentData.teams.length]);
|
}, [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(() => {
|
const shouldShowApprovalButton = React.useMemo(() => {
|
||||||
@ -160,6 +170,8 @@ const Dashboard: React.FC = () => {
|
|||||||
open={approvalData.approvalModalOpen}
|
open={approvalData.approvalModalOpen}
|
||||||
onOpenChange={approvalData.setApprovalModalOpen}
|
onOpenChange={approvalData.setApprovalModalOpen}
|
||||||
workflowDefinitionKeys={approvalData.workflowDefinitionKeys}
|
workflowDefinitionKeys={approvalData.workflowDefinitionKeys}
|
||||||
|
teamId={deploymentData.currentTeamId || undefined}
|
||||||
|
environmentId={deploymentData.currentEnvId || undefined}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -26,11 +26,28 @@ export const getDeployRecordFlowGraph = (deployRecordId: number) =>
|
|||||||
/**
|
/**
|
||||||
* 获取我的待审批任务列表
|
* 获取我的待审批任务列表
|
||||||
* @param workflowDefinitionKeys 工作流定义键列表(可选)
|
* @param workflowDefinitionKeys 工作流定义键列表(可选)
|
||||||
|
* @param teamId 团队ID,用于筛选指定团队的审批任务(可选)
|
||||||
|
* @param environmentId 环境ID,用于筛选指定环境的审批任务(可选)
|
||||||
*/
|
*/
|
||||||
export const getMyApprovalTasks = (workflowDefinitionKeys?: string[]) => {
|
export const getMyApprovalTasks = (
|
||||||
const params = workflowDefinitionKeys && workflowDefinitionKeys.length > 0
|
workflowDefinitionKeys?: string[],
|
||||||
? { workflowDefinitionKeys: workflowDefinitionKeys.join(',') }
|
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 });
|
return request.get<PendingApprovalTask[]>(`${DEPLOY_URL}/my-approval-tasks`, { params });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ import {
|
|||||||
createTeamApplication,
|
createTeamApplication,
|
||||||
updateTeamApplication,
|
updateTeamApplication,
|
||||||
} from '../service';
|
} from '../service';
|
||||||
import { getRepositoryBranches } from '@/pages/Resource/Git/List/service';
|
import { getRepositoryBranchesList } from '@/pages/Resource/Git/List/service';
|
||||||
import TeamApplicationDialog from './TeamApplicationDialog';
|
import TeamApplicationDialog from './TeamApplicationDialog';
|
||||||
|
|
||||||
interface TeamApplicationManageDialogProps {
|
interface TeamApplicationManageDialogProps {
|
||||||
@ -167,12 +167,13 @@ export const TeamApplicationManageDialog: React.FC<
|
|||||||
if (!app.repoProjectId || !app.externalSystemId) {
|
if (!app.repoProjectId || !app.externalSystemId) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const result = await getRepositoryBranches({
|
// 使用不分页的列表接口
|
||||||
|
const result = await getRepositoryBranchesList({
|
||||||
externalSystemId: app.externalSystemId,
|
externalSystemId: app.externalSystemId,
|
||||||
repoProjectId: app.repoProjectId,
|
repoProjectId: app.repoProjectId,
|
||||||
});
|
});
|
||||||
// getRepositoryBranches 返回 Page 类型,需要提取 content
|
// getRepositoryBranchesList 直接返回数组,不需要提取 content
|
||||||
return Array.isArray(result) ? result : (result as any).content || [];
|
return Array.isArray(result) ? result : [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLoadJenkinsJobs = async (systemId: number) => {
|
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