forgeplus-react/src/factory/components/Resource/index.jsx

236 lines
8.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useRef, useState, forwardRef } from 'react';
import './index.scss';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import KFIcon from '../../../components/KFIcon';
import { Link } from 'react-router-dom';
import { getProjectsLists, getSourceList, httpUrl } from '../../api';
import { factoryZoneId, lessonId, versionId, toolId } from '../../../constants/factory'
import { downloadFunc } from '../../../forge/Utils/utils'
import '../../common.scss'
gsap.registerPlugin(ScrollTrigger);
const resourceInfo = [
{ name: '项目', title: '软件项目', icon: 'icon-xiangmu', desc: '汇聚用户需求,形成开发任务,设置质量门槛,提升软件质量,快速构建软件版本,高效应对市场变化。', path: '/softwareFactory/resource/softwareProject' },
{ name: '版本', title: '软件工厂基座', icon: 'icon-banben', desc: '按照敏捷开发快速迭代的思路形成解决微小问题的小版本提供长期支持版本LTS版。', path: '/softwareFactory/resource/factoryVersion' },
{ name: '工具', title: '开发工具', icon: 'icon-gongju', desc: '提供开发者所需的各类软件开发工具包括IDE、Git工具、命令行终端工具、数据库设计工具、图像编辑工具等。', path: '/softwareFactory/resource/developmentTools' },
]
const Resource = forwardRef(({ zoneId }, ref) => {
const r1Ref = useRef(null);
const r2Ref = useRef(null);
const r3Ref = useRef(null);
const containerRef = useRef(null);
const timelineRef = useRef(null);
const [isVisible, setIsVisible] = useState(false);
const [resourceList1, setResourceList1] = useState([]);
const [resourceList2, setResourceList2] = useState([]);
const [resourceList3, setResourceList3] = useState([]);
useEffect(() => {
if (!zoneId) return;
getToolsList();
getVersionList();
getProjectsLists(zoneId, { isHomePage: 1 }).then(res => {
if (res.data && res.data.code === 200) {
setResourceList1(res.data.rows.slice(0, 6));
}
});
}, [zoneId]);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
setIsVisible(true);
observer.disconnect();
}
}, { threshold: 0.1 });
if (ref.current) {
observer.observe(ref.current);
}
return () => observer.disconnect();
}, []);
// 初始化GSAP动画
useEffect(() => {
if (!containerRef.current) return;
// 获取面板元素
const panels = [r1Ref.current, r2Ref.current, r3Ref.current];
// 创建时间轴动画
timelineRef.current = gsap.timeline({
scrollTrigger: {
trigger: containerRef.current,
start: "top top",
end: "+=800",
scrub: 1,
pin: false,
anticipatePin: 1,
markers: false,
}
});
// 第一个面板:逐渐缩小
timelineRef.current.to(panels[0], {
scale: 0.85,
duration: 1
}, 0);
// 第二个面板:向上移动并缩小
timelineRef.current.to(panels[1], {
y: "-175%",
scale: 0.9,
duration: 1
}, 0);
// 第三个面板向上移动最多v
timelineRef.current.to(panels[2], {
y: "-150%",
scale: 0.95,
duration: 1.25
}, 0);
// 清理函数
return () => {
if (timelineRef.current) {
timelineRef.current.kill();
}
ScrollTrigger.getAll().forEach(trigger => trigger.kill());
};
}, []);
const getLeftContent = (index) => {
const item = resourceInfo[index];
return <div className="content-left">
<div className="icon-container">
<KFIcon type={`${item.icon}`} font={30} />
</div>
<h3>{item.title}</h3>
<p>{item.desc}</p>
<Link to={`${item.path}`}>
<span>进入{item.name}广场 <KFIcon type="icon-icon_blackarrow_hover" font={30} /></span>
</Link>
</div>
}
const getVersionList = () => {
getSourceList({ id: factoryZoneId, keywords: versionId }).then(res => {
setResourceList2(res.data.rows.slice(0, 4));
});
}
const getToolsList = () => {
getSourceList({ id: factoryZoneId, keywords: toolId }).then(res => {
const rows = []
res.data.rows.forEach(e => {
let extendData = {}
if (e.extendData) {
extendData = JSON.parse(e.extendData)
}
rows.push({ ...e, extendDataUrl: extendData.url, extendDataHeadImg: extendData.headImg })
});
setResourceList3(rows.slice(0, 6));
});
}
return (
<div
className={`factory-resource factory-module ${isVisible ? 'animate-active' : ''}`}
ref={ref}
>
<div className="resource-container" ref={containerRef}>
<h1 className="module-title">资源中枢共享复用释放生态力量</h1>
<div className="panels-stack">
<div ref={r1Ref} className="resource-1">
<div className="panel-content">
{
getLeftContent(0)
}
<div className="content-right">
{
resourceList1 && resourceList1.length > 0 && resourceList1.map((item, index) => {
const { projectProperties } = item;
let imageUrl = projectProperties.authorImageUrl.split(':4000/') && projectProperties.authorImageUrl.split(':4000/')[1]
const authorImageUrl = imageUrl ? `${window.location.origin}/${ imageUrl }` : projectProperties.authorImageUrl
// projectProperties.praisesCount = Math.floor(Math.random(0, 1) * 50)
// projectProperties.forkedCount = Math.floor(Math.random(0, 1) * 50)
const tags = projectProperties.topics && projectProperties.topics.split(',');
return <div key={index} className="content-item1">
<div className="item-head">
<img src={authorImageUrl} alt="" />
<Link to={`/${projectProperties.fullName}`}><div className="item-name">{projectProperties.name.split('/')[1]}</div></Link>
</div>
{
tags && tags.length > 0 && <div className="item-tags">
{
tags && tags.map((tag, index) => {
return <span key={index} className="item-tags-item">{tag}</span>
})
}
</div>
}
<div className="item-desc">{projectProperties.description}</div>
<div className="item-data">
<span><i className="iconfont-factory icon-guanzhu mr5 font-12" />{projectProperties.forkedCount}</span>
<span><i className="iconfont-factory icon-dianzan mr5 font-12" />{projectProperties.praisesCount}</span>
</div>
</div>
})
}
</div>
</div>
</div>
<div ref={r2Ref} className="resource-2">
<div className="panel-content">
{
getLeftContent(1)
}
<div className="content-right">
{
resourceList2.length > 0 && resourceList2.map((item, index) => {
return <div className="content-item2" key={index}>
<div className="item-name">{item.name}</div>
<div className="item-desc">{item.summary}</div>
<button onClick={() => { downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`) }}>下载</button>
</div>
})
}
</div>
</div>
</div>
<div ref={r3Ref} className="resource-3">
<div className="panel-content">
{
getLeftContent(2)
}
<div className="content-right">
{
resourceList3.length > 0 && resourceList3.map((item, index) => {
return <div className="content-item3" key={index}>
<div className="item-name">{item.name}</div>
<div className="item-desc">{item.summary}</div>
<div className="item-btn">
<Link to={`/softwareFactory/resource/developmentTools/${item.id}`}><button className="shiny-button">查看</button></Link>
<button onClick={() => { downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`) }}>下载</button>
</div>
</div>
})
}
</div>
</div>
</div>
</div>
</div>
</div>
);
});
export default Resource;