This commit is contained in:
谢思 2026-01-16 10:36:31 +08:00
commit 16e975b084
12 changed files with 155 additions and 88 deletions

View File

@ -179,7 +179,7 @@
"<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"
],
"testEnvironment": "node",
"testURL": "https://testforgeplus.trustie.net",
"testURL": "http://172.20.32.203:4000",
"transform": {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
@ -204,7 +204,7 @@
"eslintConfig": {
"extends": "react-app"
},
"proxy": "https://testforgeplus.trustie.net/",
"proxy": "http://172.20.32.203:4000/",
"port": "3007",
"devDependencies": {
"@babel/core": "^7.23.6",

View File

@ -89,7 +89,7 @@
img {
width: 614px;
margin-top:48px;
margin-top: 48px;
}
&-gif {
@ -238,6 +238,11 @@
color: #091221;
font-size: 14px;
cursor: pointer;
&:hover {
border-color: #164ce4;
color: #164ce4;
}
}
}
}

View File

@ -85,8 +85,8 @@ const Resource = forwardRef(({ zoneId }, ref) => {
const animations = [
{ y: "-5%", scale: 0.85, duration: 1 },
{ y: "-50%", scale: 0.9, duration: 1 },
{ y: "-150%", scale: 0.95, duration: 1 },
{ y: "-230%", scale: 0.98, duration: 1.5 }
{ y: "-265%", scale: 0.95, duration: 1.2 },
{ y: "-415%", scale: 0.98, duration: 2 }
];
timelineRef.current.to(panel, {

View File

@ -1,6 +1,6 @@
.factory-resource {
position: relative;
min-height: 2300px;
min-height: 2800px;
overflow: hidden;
margin-top: 56px;
@ -47,10 +47,13 @@
width: 1600px;
border-radius: 30px;
// box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
// transition: transform 0.3s ease;
transition: z-index 0.3s ease;
padding: 50px;
z-index: 1;
// transform-origin: center center;
// &:hover {
// z-index: 100;
// }
}
.resource-2 {
@ -180,7 +183,7 @@
}
.resource-3 {
top: 1170px;
top: 1900px;
height: 622px;
background: #d5dfff;
z-index: 3;
@ -225,7 +228,7 @@
}
}
.resource-4 {
top: 1810px;
top: 3010px;
height: 622px;
background: #DFF0EC;
z-index: 4;

View File

@ -11,12 +11,11 @@ import manual1 from '../../images/factory/lessons/manual-1.webp'
import manual2 from '../../images/factory/lessons/manual-2.webp'
import '../common.scss'
import { Link } from "react-router-dom";
import Waves from '../components/Waves/index'
import moment from 'moment';
import { getSourceList, httpUrl } from '../api'
import { downloadFunc } from '../../forge/Utils/utils'
import chapterBg from '../../images/factory/lessons/chapter-bg.webp'
import { message } from 'antd';
import InfiniteScroll from 'react-infinite-scroller';
const backList = [back1, back2, back3]
@ -30,6 +29,11 @@ function Index(props) {
const [manualList, setManualList] = useState([]);
const [lesson, setLesson] = useState([])
const [docList, setDocList] = useState([])
const chapterListRef = useRef(null);
const pageSize = 10
const [pageNum, setPageNum] = useState(1)
const [loading, setLoading] = useState(false)
const hasMore = useRef(true)
useEffect(() => {
document.title = '学习专区-软件工厂专区';
@ -39,6 +43,12 @@ function Index(props) {
getDocList();
}, []);
useEffect(() => {
if (chapterListRef.current) {
chapterListRef.current.scrollTop = 88 * (chapterList.length - nowTop < 4 ? chapterList.length - 4 : nowTop)
}
}, [nowTop]);
const getLessonList = () => {
getSourceList({ id: factoryZoneId, keywords: lessonId }).then(res => {
const rows = []
@ -95,20 +105,38 @@ function Index(props) {
setManualList(rows);
});
}
const getDocList = (isMore = false) => {
if (!hasMore.current) return
let params = {
id: factoryZoneId,
keywords: docId,
pageNum: isMore ? isMore : pageNum,
pageSize
}
const getDocList = () => {
getSourceList({ id: factoryZoneId, keywords: docId }).then(res => {
const rows = []
res.data.rows.forEach(e => {
let extendData = {}
if (e.extendData) {
extendData = JSON.parse(e.extendData)
setLoading(true)
getSourceList(params).then(res => {
setLoading(false)
if (res.data.rows) {
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 })
});
if (isMore) {
setPageNum(isMore)
setDocList([...docList, ...rows])
} else {
setDocList(rows);
}
rows.push({ ...e, extendDataUrl: extendData.url, extendDataHeadImg: extendData.headImg })
});
setDocList(rows.slice(0, 6));
hasMore.current = res.data.total > [...docList, ...rows].length
}
});
}
};
return (
<div className={`lessons ${isVisible ? 'animate-active' : ''}`}>
@ -125,10 +153,13 @@ function Index(props) {
<h3>{lesson.name}</h3>
<p>{lesson.summary}</p>
<div className="chapter-wrapper">
<div className="chapter-list" style={{ marginTop: `-${88 * (chapterList.length - nowTop < 4 ? chapterList.length - 4 : nowTop)}px` }}>
<div className="chapter-list" ref={chapterListRef}>
{
chapterList.map((item, index) => {
return <div className={`chapter-item ${nowTop === index ? 'active' : ''}`} key={item.id}>
return <div
className={`chapter-item ${nowTop === index ? 'active' : ''}`}
key={item.id}
>
{
index < 10 ?
<span className="chapter-index">0{index + 1}</span> :
@ -247,7 +278,7 @@ function Index(props) {
<div className="line-3"></div>
</div>
<div className="chapter-body">
<p title={ item.summary }>{item.summary}</p>
<p title={item.summary}>{item.summary}</p>
<span>{moment(item.createTime).format('YYYY/MM/DD')}</span>
</div>
</div>
@ -265,9 +296,9 @@ function Index(props) {
<h4>{item.name}</h4>
<button onClick={() => {
if (item.fileIds) {
downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)
downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)
}
}} disabled={!item.fileIds} className={ !item.fileIds && 'disabled' } >{item.fileIds ? '下载' : '稍后下载'}</button>
}} disabled={!item.fileIds} className={!item.fileIds && 'disabled'} >{item.fileIds ? '下载' : '稍后下载'}</button>
</div>
<p title={item.summary}>{item.summary}</p>
<div className="standard-item-img">
@ -278,31 +309,6 @@ function Index(props) {
}
</div>
</div>
<div className="docs">
<h2>文档资料</h2>
<div className="docs-content">
{
docList.map((item, index) => {
return <div className="news-item" key={index}>
<div className="news-item-img">
<img src={item.extendDataHeadImg || backList[index % backList.length]} alt="" />
</div>
<div className="news-item-info">
<Link to={`/sf/lessons/${item.id}`}><h3>{item.name}</h3></Link>
<p>{item.summary}</p>
<div className="news-item-info-bottom">
<span>{moment(item.createTime).format('YYYY/MM/DD')}</span>
<Link to={`/sf/lessons/${item.id}`}>
<span>查看详情</span>
<KFIcon type="icon-icon_blackarrow_hover" font={40} />
</Link>
</div>
</div>
</div>
})
}
</div>
</div>
<div className="manual">
<h2>用户手册</h2>
<div className="manual-content">
@ -322,16 +328,49 @@ function Index(props) {
<p>{item.summary}</p>
<button onClick={() => {
if (item.fileIds) {
downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)
downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)
}
}} disabled={!item.fileIds} className={ !item.fileIds && 'disabled-button' } >{item.fileIds ? '下载' : '稍后下载'}</button>
}} disabled={!item.fileIds} className={!item.fileIds && 'disabled-button'} >{item.fileIds ? '下载' : '稍后下载'}</button>
</div>
})
}
</div>
</div>
<div className="docs">
<h2>文档资料</h2>
{
docList && docList.length > 0 && <InfiniteScroll
threshold={10}
initialLoad={false}
pageStart={1}
loadMore={(e) => { getDocList(e) }}
hasMore={!loading && hasMore.current}
>
<div className="docs-content">
{
docList.map((item, index) => {
return <div className="news-item" key={index}>
<div className="news-item-img">
<img src={item.extendDataHeadImg || backList[index % backList.length]} alt="" />
</div>
<div className="news-item-info">
<Link to={`/sf/lessons/${item.id}`}><h3>{item.name}</h3></Link>
<p>{item.summary}</p>
<div className="news-item-info-bottom">
<span>{moment(item.createTime).format('YYYY/MM/DD')}</span>
<Link to={`/sf/lessons/${item.id}`}>
<span>查看详情</span>
<KFIcon type="icon-icon_blackarrow_hover" font={40} />
</Link>
</div>
</div>
</div>
})
}
</div>
</InfiniteScroll>
}
</div>
</div>
)

View File

@ -116,11 +116,18 @@
.chapter-wrapper {
height: 387px;
overflow: hidden;
.chapter-list {
transition: all .4s cubic-bezier(.25, .46, .45, .94);
margin-right: -7px;
margin-left: 36px;
height: 387px;
overflow-y: scroll;
overflow-x: hidden;
transition: all .4s cubic-bezier(.25, .46, .45, .94);
&:hover {
margin-right: 0px;
}
.active {

View File

@ -40,7 +40,7 @@
.header-content {
margin-top: 30px;
width: 1600px;
height: 481px;
// height: 481px;
position: relative;
border-radius: 16px;
padding: 60px 45px;
@ -140,10 +140,11 @@
.more-tools {
display: flex;
margin-top: 20px;
margin-top: 5px;
max-width: 800px;
flex-wrap: wrap;
span {
max-width: 200px;
cursor: pointer;
display: inline-block;
background: #e9f2ff;
@ -154,9 +155,7 @@
font-family: alibaba;
color: #091221;
font-size: 15px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-top: 15px !important;
img {
width: 19px;

View File

@ -53,31 +53,33 @@ function Index(props) {
<h5>生产线安装包</h5>
<p>标准化生产线快速迭代版本和稳定支持版本</p>
</div>
<div className="version-content">
{
versionList.map((item, index) => {
return <div key={item.id} className="version-item">
<div className="version-item-left">
<img src={dot} alt="" />
<div></div>
</div>
<div className="version-item-right">
<div className="version-item-title">
<h4>{item.name}</h4>
{index === 0 && <img className="new-tag" src={versionNew} />}
<div className="scroller-wrapper">
<div className="version-content">
{
versionList.map((item, index) => {
return <div key={item.id} className="version-item">
<div className="version-item-left">
<img src={dot} alt="" />
<div></div>
</div>
<div className="version-item-content">
<p>{item.summary}</p>
<div className="item-data">
<span><i className="iconfont-factory icon-shijian mr5 font-12" />{item.createTime}</span>
<div className="version-item-right">
<div className="version-item-title">
<h4>{item.name}</h4>
{index === 0 && <img className="new-tag" src={versionNew} />}
</div>
<div className="version-item-content">
<p>{item.summary}</p>
<div className="item-data">
<span><i className="iconfont-factory icon-shijian mr5 font-12" />{item.createTime}</span>
</div>
</div>
<button onClick={() => { item.fileIds && downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`) }} className={index === 0 ? "shiny-button" : "version-btn"}>{item.fileIds ? '立即下载' : '暂未开放'}</button>
</div>
<button onClick={() => { item.fileIds && downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}} className={index === 0 ? "shiny-button" : "version-btn"}>{ item.fileIds ? '立即下载' : '暂未开放'}</button>
</div>
</div>
})
}
})
}
</div>
</div>
<div className="manual">
<h2>用户手册</h2>

View File

@ -29,13 +29,22 @@
font-size: 14px;
}
}
.scroller-wrapper {
margin-top: 59px;
margin-bottom: 90px;
height: 331px;
overflow: hidden;
transition: all 0.2s ease-in-out;
&:hover {
height: 341px;
margin-bottom: 80px;
}
}
.version-content {
width: 1600px;
display: flex;
margin-top: 59px;
justify-content: flex-start;
margin-bottom: 90px;
overflow-x: auto;
.version-item {

View File

@ -132,7 +132,7 @@ function Index(props) {
{
typeMap.map(item => (
<div key={item.key} className={selectedType === item.key? "switch-item switch-item-active" : "switch-item"} onClick={() => setSelectedType(item.key)}>
<KFIcon type={item.icon} font={22} />
<i className={`iconfont-factory ${ item.icon } font-22`} />
<span>{item.name}</span>
</div>
))

View File

@ -224,6 +224,7 @@
.switch-item-active {
background: #ffffff;
box-shadow: 0px 0px 15px rgba(0, 74, 168, 0.05);
color: #164ce4;
}
}
}

View File

@ -192,6 +192,8 @@
height: 38px;
border-radius: 50%;
margin-right: 14px;
background-color: #ffffff;
}
.item-title {