新增工作流暂停功能,更新相关组件以支持暂停状态的管理和显示。

This commit is contained in:
北枳 2025-08-06 17:07:37 +08:00
parent ddbe2bde4e
commit 6bcd8b0118
3 changed files with 70 additions and 66 deletions

View File

@ -125,6 +125,7 @@ export default function WorkFlow() {
currentLoadingText={currentLoadingText} currentLoadingText={currentLoadingText}
dataLoadError={dataLoadError} dataLoadError={dataLoadError}
roles={roles} roles={roles}
isPauseWorkFlow={isPauseWorkFlow}
/> />
</ErrorBoundary> </ErrorBoundary>
</div> </div>

View File

@ -17,6 +17,7 @@ interface TaskInfoProps {
currentLoadingText: string; currentLoadingText: string;
dataLoadError?: string | null; dataLoadError?: string | null;
roles: any[]; roles: any[];
isPauseWorkFlow: boolean;
} }
const stageIconMap = { const stageIconMap = {
@ -41,7 +42,7 @@ const stageIconMap = {
const TAG_COLORS = ['#FF5733', '#126821', '#8d3913', '#FF33A1', '#A133FF', '#FF3333', '#3333FF', '#A1A1A1', '#a1115e', '#30527f']; const TAG_COLORS = ['#FF5733', '#126821', '#8d3913', '#FF33A1', '#A133FF', '#FF3333', '#3333FF', '#A1A1A1', '#a1115e', '#30527f'];
// 阶段图标组件 // 阶段图标组件
const StageIcons = ({ currentStage, isExpanded }: { currentStage: number, isExpanded: boolean }) => { const StageIcons = ({ currentStage, isExpanded, isPauseWorkFlow }: { currentStage: number, isExpanded: boolean, isPauseWorkFlow: boolean }) => {
// 根据当前阶段重新排序图标 // 根据当前阶段重新排序图标
const orderedStages = useMemo(() => { const orderedStages = useMemo(() => {
const stages = Object.entries(stageIconMap).map(([stage, data]) => ({ const stages = Object.entries(stageIconMap).map(([stage, data]) => ({
@ -97,7 +98,7 @@ const StageIcons = ({ currentStage, isExpanded }: { currentStage: number, isExpa
> >
<motion.div <motion.div
className={`relative rounded-full p-1 ${isCurrentStage ? 'bg-opacity-20' : 'bg-opacity-10'}`} className={`relative rounded-full p-1 ${isCurrentStage ? 'bg-opacity-20' : 'bg-opacity-10'}`}
animate={isCurrentStage ? { animate={(isCurrentStage && !isPauseWorkFlow) ? {
rotate: [0, 360], rotate: [0, 360],
scale: [1, 1.2, 1], scale: [1, 1.2, 1],
transition: { transition: {
@ -124,7 +125,8 @@ export function TaskInfo({
taskObject, taskObject,
currentLoadingText, currentLoadingText,
dataLoadError, dataLoadError,
roles roles,
isPauseWorkFlow
}: TaskInfoProps) { }: TaskInfoProps) {
const [isScriptModalOpen, setIsScriptModalOpen] = useState(false); const [isScriptModalOpen, setIsScriptModalOpen] = useState(false);
const [currentStage, setCurrentStage] = useState(0); const [currentStage, setCurrentStage] = useState(0);
@ -299,15 +301,15 @@ export function TaskInfo({
<motion.div <motion.div
className="w-1.5 h-1.5 rounded-full" className="w-1.5 h-1.5 rounded-full"
style={{ backgroundColor: stageColor }} style={{ backgroundColor: stageColor }}
animate={{ animate={!isPauseWorkFlow ? {
scale: [1, 1.5, 1], scale: [1, 1.5, 1],
opacity: [1, 0.5, 1] opacity: [1, 0.5, 1],
}} transition: {
transition={{ duration: 1,
duration: 1, repeat: Infinity,
repeat: Infinity, repeatDelay: 0.2
repeatDelay: 0.2 }
}} } : {}}
/> />
{/* 阶段图标 */} {/* 阶段图标 */}
@ -321,7 +323,7 @@ export function TaskInfo({
onMouseEnter={() => setIsStageIconsExpanded(true)} onMouseEnter={() => setIsStageIconsExpanded(true)}
onMouseLeave={() => setIsStageIconsExpanded(false)} onMouseLeave={() => setIsStageIconsExpanded(false)}
> >
<StageIcons currentStage={currentStage} isExpanded={isStageIconsExpanded} /> <StageIcons currentStage={currentStage} isExpanded={isStageIconsExpanded} isPauseWorkFlow={isPauseWorkFlow} />
<motion.div <motion.div
className="relative" className="relative"
@ -333,43 +335,43 @@ export function TaskInfo({
{/* 背景发光效果 */} {/* 背景发光效果 */}
<motion.div <motion.div
className="absolute inset-0 text-transparent bg-clip-text bg-gradient-to-r from-blue-400 via-cyan-400 to-purple-400 blur-sm" className="absolute inset-0 text-transparent bg-clip-text bg-gradient-to-r from-blue-400 via-cyan-400 to-purple-400 blur-sm"
animate={{ animate={!isPauseWorkFlow ? {
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"], backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
}} transition: {
transition={{ duration: 2,
duration: 2, repeat: Infinity,
repeat: Infinity, ease: "linear"
ease: "linear" }
}} }: {}}
style={{ style={{
backgroundSize: "200% 200%", backgroundSize: "200% 200%",
}} }}
> >
<span className="normalS400 subtitle-had8uE">{currentLoadingText}</span> <span className="normalS400 subtitle-had8uE">{isPauseWorkFlow ? 'workflow paused' : currentLoadingText}</span>
</motion.div> </motion.div>
{/* 主文字 - 颜色填充动画 */} {/* 主文字 - 颜色填充动画 */}
<motion.div <motion.div
className="relative z-10" className="relative z-10"
animate={{ animate={!isPauseWorkFlow ? {
scale: [1, 1.02, 1], scale: [1, 1.02, 1],
}} transition: {
transition={{ duration: 1.5,
duration: 1.5, repeat: Infinity,
repeat: Infinity, ease: "easeInOut"
ease: "easeInOut" }
}} }: {}}
> >
<motion.span <motion.span
className="normalS400 subtitle-had8uE text-transparent bg-clip-text bg-gradient-to-r from-blue-600 via-cyan-500 to-purple-600" className="normalS400 subtitle-had8uE text-transparent bg-clip-text bg-gradient-to-r from-blue-600 via-cyan-500 to-purple-600"
animate={{ animate={!isPauseWorkFlow ? {
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"], backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
}} transition: {
transition={{
duration: 3, duration: 3,
repeat: Infinity, repeat: Infinity,
ease: "linear" ease: "linear"
}} }
}: {}}
style={{ style={{
backgroundSize: "300% 300%", backgroundSize: "300% 300%",
}} }}
@ -381,16 +383,16 @@ export function TaskInfo({
{/* 动态光点效果 */} {/* 动态光点效果 */}
<motion.div <motion.div
className="absolute left-0 top-1/2 transform -translate-y-1/2 w-2 h-2 bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full blur-sm" className="absolute left-0 top-1/2 transform -translate-y-1/2 w-2 h-2 bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full blur-sm"
animate={{ animate={!isPauseWorkFlow ? {
x: [0, 200, 0], x: [0, 200, 0],
opacity: [0, 1, 0], opacity: [0, 1, 0],
scale: [0.5, 1, 0.5], scale: [0.5, 1, 0.5],
}} transition: {
transition={{ duration: 2.5,
duration: 2.5, repeat: Infinity,
repeat: Infinity, ease: "easeInOut",
ease: "easeInOut", }
}} }: {}}
/> />
{/* 文字底部装饰线 */} {/* 文字底部装饰线 */}
@ -399,12 +401,12 @@ export function TaskInfo({
style={{ style={{
background: `linear-gradient(to right, ${stageColor}, rgb(34 211 238), rgb(168 85 247))`, background: `linear-gradient(to right, ${stageColor}, rgb(34 211 238), rgb(168 85 247))`,
}} }}
animate={{ animate={!isPauseWorkFlow ? {
width: ["0%", "100%", "0%"] width: ["0%", "100%", "0%"],
}} transition: {
transition={{ width: { duration: 2, repeat: Infinity, ease: "easeInOut" }
width: { duration: 2, repeat: Infinity, ease: "easeInOut" } }
}} } : {}}
/> />
</motion.div> </motion.div>
</motion.div> </motion.div>
@ -412,30 +414,30 @@ export function TaskInfo({
<motion.div <motion.div
className="w-1.5 h-1.5 rounded-full" className="w-1.5 h-1.5 rounded-full"
style={{ backgroundColor: stageColor }} style={{ backgroundColor: stageColor }}
animate={{ animate={!isPauseWorkFlow ? {
scale: [1, 1.5, 1], scale: [1, 1.5, 1],
opacity: [1, 0.5, 1] opacity: [1, 0.5, 1],
}} transition: {
transition={{ duration: 1,
duration: 1, repeat: Infinity,
repeat: Infinity, repeatDelay: 0.2,
repeatDelay: 0.2, delay: 0.3
delay: 0.3 }
}} } : {}}
/> />
<motion.div <motion.div
className="w-1.5 h-1.5 rounded-full" className="w-1.5 h-1.5 rounded-full"
style={{ backgroundColor: stageColor }} style={{ backgroundColor: stageColor }}
animate={{ animate={!isPauseWorkFlow ? {
scale: [1, 1.5, 1], scale: [1, 1.5, 1],
opacity: [1, 0.5, 1] opacity: [1, 0.5, 1],
}} transition: {
transition={{ duration: 1,
duration: 1, repeat: Infinity,
repeat: Infinity, repeatDelay: 0.2,
repeatDelay: 0.2, delay: 0.3
delay: 0.6 }
}} } : {}}
/> />
</motion.div> </motion.div>
)} )}

View File

@ -75,7 +75,7 @@ export function useWorkflowData() {
const [dataLoadError, setDataLoadError] = useState<string | null>(null); const [dataLoadError, setDataLoadError] = useState<string | null>(null);
const [needStreamData, setNeedStreamData] = useState(false); const [needStreamData, setNeedStreamData] = useState(false);
const [isPauseWorkFlow, setIsPauseWorkFlow] = useState(false); const [isPauseWorkFlow, setIsPauseWorkFlow] = useState(false);
const [mode, setMode] = useState<'auto' | 'manual'>('manual'); const [mode, setMode] = useState<'auto' | 'manual'>('auto');
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { sketchCount, videoCount } = useAppSelector((state) => state.workflow); const { sketchCount, videoCount } = useAppSelector((state) => state.workflow);
@ -356,7 +356,8 @@ export function useWorkflowData() {
throw new Error(response.message); throw new Error(response.message);
} }
const { name, status, data, tags } = response.data; const { name, status, data, tags, mode } = response.data;
setMode(mode);
setIsLoading(false); setIsLoading(false);
// 设置初始数据 // 设置初始数据