This commit is contained in:
黄心宇 2025-12-17 20:30:38 +08:00
parent d51c87a613
commit 5fb7d07cc1
46 changed files with 1547 additions and 176 deletions

View File

@ -58,12 +58,23 @@ const SoftwareFactoryResource = Loadable({
loading: Loading,
})
const SoftwareFactoryResourceDetail= Loadable({
loader: () => import('./factory/resource/developmentTools/detail/index'),
loading: Loading,
})
const SoftwareFactoryNews = Loadable({
loader: () => import('./factory/news/index'),
loading: Loading,
})
const SoftwareFactoryNewsDetail= Loadable({
loader: () => import('./factory/news/detail/index'),
loading: Loading,
})
const SoftwareFactoryLessons = Loadable({
loader: () => import('./factory/lessons/index'),
loading: Loading,
@ -450,6 +461,15 @@ class App extends Component {
}>
</Route>
<Route
path={"/softwareFactory/resource/developmentTools/:id"}
render={
(props) => {
return (<SoftwareFactoryResourceDetail {...this.props} {...props} {...this.state} />)
}
}>
</Route>
<Route
path={"/softwareFactory/resource"}
render={
@ -459,6 +479,15 @@ class App extends Component {
}>
</Route>
<Route
path={"/softwareFactory/news/:id"}
render={
(props) => {
return (<SoftwareFactoryNewsDetail {...this.props} {...props} {...this.state} />)
}
}>
</Route>
<Route
path={"/softwareFactory/news"}
render={
@ -467,7 +496,7 @@ class App extends Component {
}
}>
</Route>
<Route
path={"/softwareFactory/lessons"}
render={

View File

@ -1 +1,4 @@
export const factoryZoneId = 201
export const factoryZoneId = 2
export const dirId = 9
export const versionId = 5
export const lessonId = 6

View File

@ -1,5 +1,7 @@
import fetch, { httpUrl } from '../forge/Information/fetch';
export { httpUrl }
export function getNewsHotList(id,params){
return fetch({
url:`/cms/doc/open/zone/${id}/hotDocList`,
@ -16,6 +18,15 @@ export function getDocList(id, params){
})
}
// 获取文章列表
export function getSubDocList(id,params){
return fetch({
url:`/cms/doc/open/dir/${id}/docList`,
method: 'get',
params
})
}
export function getProjectsLists(id,params){
return fetch({
url:`/zone/open/${id}/project/list`,
@ -55,3 +66,17 @@ export function gethomePageDocList(id) {
method: 'get',
});
}
export function getNewsDetail(id){
return fetch({
url:`/cms/doc/open/${id}`,
method: 'get',
})
}
export function getSourceDetail(id){
return fetch({
url:`/zone/open/resource/detail/${id}`,
method: 'get'
})
}

View File

@ -3,6 +3,9 @@ import './index.scss';
import featureLeft1 from '../../../images/factory/feature-left-1.webp';
import featureright1 from '../../../images/factory/feature-right-1.webp';
import featureBottom1 from '../../../images/factory/feature-bottom-1.webp';
import gif1 from '../../../images/factory/feature-gif-1.webp'
import gif2 from '../../../images/factory/feature-gif-2.gif'
import gif3 from '../../../images/factory/feature-gif-3.webp'
import { Link } from 'react-router-dom';
@ -42,11 +45,13 @@ function Feature(props) {
<div className="content-top-left">
<h3>智能化驱动释放研发新效能</h3>
<p>AI深度融入需求分析代码生成测试验证等关键环节大幅提升开发效率</p>
<img className="content-top-left-gif" src={gif1} alt="" />
<img src={featureLeft1} alt="" />
</div>
<div className="content-top-right">
<h3>数字化纳管掌控研发全链路</h3>
<p>研发活动及制品全流程数字化纳管支持精准决策和持续优化</p>
{/* <img className="content-top-right-gif" src={gif2} alt="" /> */}
<img src={featureright1} alt="" />
</div>
</div>
@ -55,6 +60,7 @@ function Feature(props) {
<h3>敏捷化协同实现能力极速交付</h3>
<p>打破用户-研发团队-运维团队协作壁垒大幅缩短交付周期</p>
</div>
<img className="content-bottom-gif" src={gif3} alt="" />
<img src={ featureBottom1 } alt="" />
</div>
</div>

View File

@ -64,22 +64,39 @@
width: 787.5px;
height: 506px;
margin-right: 25px;
position: relative;
img {
width: 614px;
height: 320.54px;
}
&-gif {
width: 108px !important;
height: 111px !important;
position: absolute;
left: 270px;
top: 260px
}
}
&-right {
width: 787.5px;
height: 502px;
position: relative;
img {
width: 770px;
height: 291px;
margin-top: 35px;
}
&-gif {
width: 160px !important;
height: 120px !important;
position: absolute;
left: 180px;
top: 120px
}
}
}
@ -88,6 +105,7 @@
height: 313px;
display: flex;
align-items: center;
position: relative;
h3 {
margin-left: 50px;
@ -102,6 +120,13 @@
width: 1016px;
height: 315px;
}
&-gif {
width: 72px !important;
height: 57px !important;
position: absolute;
left: 620px;
top: 130px
}
}
}
}

View File

@ -1,12 +1,14 @@
import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { Anchor, Carousel } from 'antd';
import { getNewsHotList, getDocList } from '../../api'
import { gethomePageDocList, getSubDocList } from '../../api'
import back1 from '../../../images/factory/back1.png'
import back2 from '../../../images/factory/back2.png'
import back3 from '../../../images/factory/back3.png'
import { Link } from 'react-router-dom';
import KFIcon from '../../../components/KFIcon';
import { factoryZoneId, dirId } from '../../../constants/factory'
const backList = [back1, back2, back3]
@ -36,7 +38,7 @@ function News(props) {
if (contentRef.current) {
observer.observe(contentRef.current);
}
getTopList()
getNewsList()
return () => {
@ -44,12 +46,18 @@ function News(props) {
};
}, []);
const getTopList = () => {
gethomePageDocList(factoryZoneId).then(res => {
setMainList(res.data.rows)
})
}
const getNewsList = () => {
getDocList(props.zoneId).then(result => {
if (result) {
setMainList(result.data.rows[0].cmsDocList);
setSubList(result.data.rows[1].cmsDocList);
setNews(result.data.rows[3].cmsDocList[0]);
getSubDocList(dirId, { isHomepage: 0 }).then(res => {
if (res) {
const rows = res.data.rows
setNews(rows.sort((a, b) => { return b.visits - a.visits })[0]);
setSubList(rows);
}
}).catch(error => { })
}
@ -77,7 +85,7 @@ function News(props) {
</div>
<div className="news-1-item-content">
<h3>{item.name}</h3>
<Link to={`/softwareFactory/news/${item.id}`}><h3>{item.name}</h3></Link>
<p>{item.summary}</p>
</div>
</div>
@ -90,8 +98,8 @@ function News(props) {
<img src={news.headImg || backList[1]} alt="" />
</div>
<div className="news-1-right-title">
<h5>{news.name}</h5>
<KFIcon type="icon-icon_blackarrow_hover" font={46}/>
<Link to={`/softwareFactory/news/${news.id}`}><h5>{news.name}</h5></Link>
<KFIcon type="icon-icon_blackarrow_hover" font={46} />
</div>
<p>{news.summary}</p>
</div>
@ -101,15 +109,15 @@ function News(props) {
subList.slice(0, 4).map(item => {
return <div className="news-2-item">
<div className="news-2-item-title">
<h3>{item.name}</h3>
<KFIcon type="icon-icon_blackarrow_hover" font={48}/>
<Link to={`/softwareFactory/news/${item.id}`}><h3>{item.name}</h3></Link>
<KFIcon type="icon-icon_blackarrow_hover" font={48} />
</div>
<p>{item.summary}</p>
</div>
})
}
</div>
<Link to="/softwareFactory/news" className="news-more">探索更多新闻动态<KFIcon type="icon-icon_blackarrow_hover" font={40}/></Link>
<Link to="/softwareFactory/news" className="news-more">探索更多新闻动态<KFIcon type="icon-icon_blackarrow_hover" font={40} /></Link>
</div>
);
}

View File

@ -139,6 +139,7 @@
img {
width: 610px;
height: 334px;
object-fit: cover;
transition: transform .4s cubic-bezier(.25, .46, .45, .94);
}
@ -196,6 +197,9 @@
}
img {
width: 360px;
height: 201px;
object-fit: cover;
transition: transform .4s cubic-bezier(.25, .46, .45, .94);
}
@ -210,6 +214,9 @@
&-title {
margin-top: 27px;
display: flex;
a {
width: 90%;
}
i {
flex-shrink: 0;
@ -264,7 +271,7 @@
background: #ffffff;
border-radius: 16px;
box-shadow: 0px 0px 6px rgba(0, 74, 168, 0.03);
padding: 50px;
padding: 23px 50px 50px 50px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;

View File

@ -4,7 +4,9 @@ import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import KFIcon from '../../../components/KFIcon';
import { Link } from 'react-router-dom';
import { getProjectsLists } from '../../api';
import { getProjectsLists, getSourceList, httpUrl } from '../../api';
import { factoryZoneId, lessonId , versionId } from '../../../constants/factory'
import { downloadFunc } from '../../../forge/Utils/utils'
gsap.registerPlugin(ScrollTrigger);
@ -28,11 +30,11 @@ const Resource = forwardRef(({ zoneId }, ref) => {
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));
setResourceList2(res.data.rows.slice(0, 4));
setResourceList3(res.data.rows.slice(0, 6));
}
});
}, [zoneId]);
@ -114,6 +116,21 @@ const Resource = forwardRef(({ zoneId }, ref) => {
</div>
}
const getVersionList = () => {
getSourceList({ id: factoryZoneId, domainId: versionId }).then(res => {
setResourceList2(res.data.rows.slice(0, 4));
});
}
const getToolsList = () => {
getSourceList({ id: factoryZoneId }).then(res => {
if (res.data.rows) {
const rows = res.data.rows.filter(e => e.domainId !== lessonId && e.domainId !== versionId)
setResourceList3(rows.slice(0, 6));
}
});
}
return (
<div
className={`factory-resource factory-module ${isVisible ? 'animate-active' : ''}`}
@ -136,7 +153,7 @@ const Resource = forwardRef(({ zoneId }, ref) => {
return <div key={index} className="content-item1">
<div className="item-head">
<img src={projectProperties.authorImageUrl} alt="" />
<div className="item-name">{projectProperties.name}</div>
<Link to={`/${projectProperties.fullName}`}><div className="item-name">{projectProperties.name}</div></Link>
</div>
{
tags && tags.length > 0 && <div className="item-tags">
@ -171,11 +188,10 @@ const Resource = forwardRef(({ zoneId }, ref) => {
<div className="content-right">
{
resourceList2.length > 0 && resourceList2.map((item, index) => {
const { projectProperties } = item;
return <div className="content-item2" key={index}>
<div className="item-name">{projectProperties.name}</div>
<div className="item-desc">{projectProperties.description}</div>
<button>下载</button>
<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>
})
}
@ -191,13 +207,12 @@ const Resource = forwardRef(({ zoneId }, ref) => {
<div className="content-right">
{
resourceList3.length > 0 && resourceList3.map((item, index) => {
const { projectProperties } = item;
return <div className="content-item3" key={index}>
<div className="item-name">{projectProperties.name}</div>
<div className="item-desc">{projectProperties.description}</div>
<div className="item-name">{item.name}</div>
<div className="item-desc">{item.summary}</div>
<div className="item-btn">
<Link to="/"><button>查看</button></Link>
<button>下载</button>
<Link to={`/softwareFactory/resource/developmentTools/${item.id}`}><button>查看</button></Link>
<button onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}}>下载</button>
</div>
</div>
})

View File

@ -68,6 +68,7 @@
padding: 25px 35px;
display: flex;
flex-direction: column;
margin-right: 15px;
.item-head {
display: flex;
@ -156,6 +157,7 @@
flex-direction: column;
align-items: center;
padding: 30px 35px;
margin-right: 18px;
.item-name {
max-width: 210px;
@ -183,6 +185,7 @@
padding: 48px 35px 35px 35px;
display: flex;
flex-direction: column;
margin-right: 15px;
.item-desc {
margin-top: 27px;
}
@ -190,6 +193,10 @@
margin-top: auto;
button {
margin-right: 20px;
&:nth-child(1) {
background: #091221;
color: #ffffff;
}
}
}
}
@ -266,7 +273,7 @@
.content-right {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
justify-content: flex-start;
width: 100%;
.item-name {
@ -305,10 +312,10 @@
font-size: 14px;
cursor: pointer;
&:hover {
background: #091221;
color: #ffffff;
}
// &:hover {
// background: #091221;
// color: #ffffff;
// }
}
}
}

View File

@ -9,6 +9,7 @@ import Resource2 from './components/Resource2';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import Scene from './components/Scene';
import { factoryZoneId } from '../constants/factory';
gsap.registerPlugin(ScrollTrigger);
@ -18,8 +19,6 @@ const bannerInfo = {
link: '/'
}
const zoneId = 199
function Index(props) {
const contentRef = useRef(null);
const resourceRef = useRef(null);
@ -77,13 +76,13 @@ function Index(props) {
return (
<div className="factory">
<div className="factory-banner">
<div className="banner-content">
{/* <div className="banner-content">
<h1>{bannerInfo.title}</h1>
<p>{bannerInfo.desc}</p>
<Link to={`${bannerInfo.link}`}>
<div className="banner-content-button">立即体验</div>
</Link>
</div>
</div> */}
{/* <div className="banner-data">
{
bannerData.map(e => {
@ -99,14 +98,14 @@ function Index(props) {
</div>
<div className={`factory-video factory-module ${isVisible ? 'animate-active' : ''}`} ref={contentRef}>
<h1 className="module-title">软件工厂 宣传视频</h1>
<video src=""></video>
<video controls autoPlay muted src="http://172.20.32.203:4000/api/attachments/598dbdfe-a767-46d6-aafa-6c3329edccba"></video>
</div>
<News zoneId={zoneId} />
<News zoneId={factoryZoneId} />
<Feature />
<Resource zoneId={zoneId} ref={resourceRef} />
<Resource2 zoneId={zoneId} ref={resource2Ref} />
<Scene zoneId={zoneId} />
<Resource zoneId={factoryZoneId} ref={resourceRef} />
<Resource2 zoneId={factoryZoneId} ref={resource2Ref} />
<Scene zoneId={factoryZoneId} />
</div>
)
}

View File

@ -10,8 +10,8 @@
flex-direction: column;
align-items: center;
height: 52vw;
background-image: url("../images/factory/banner.png");
background-size: contain;
background-image: url("../images/factory/banner1.png");
background-size: cover;
/* 确保图片完整显示不被拉伸 */
background-repeat: no-repeat;
background-position: top center;
@ -22,6 +22,7 @@
display: flex;
flex-direction: column;
align-items: center;
h1 {
line-height: normal;
font-family: shuheiTi;
@ -162,14 +163,19 @@
margin-top: 83px;
video {
margin-top: 31px;
width: 1144px;
height: 654px;
border-radius: 20px;
overflow: hidden;
object-fit: cover;
}
}
.pin-spacer {
overflow: hidden !important;
}
}
@keyframes fadeInUp {
@ -182,4 +188,4 @@
opacity: 1;
transform: translateY(0);
}
}
}

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import KFIcon from '../../components/KFIcon/index';
// import { factoryZoneId } from '../../constants/factory'
import { factoryZoneId, lessonId } from '../../constants/factory'
import { Carousel } from 'antd';
import back1 from '../../images/factory/back1.png'
import back2 from '../../images/factory/back2.png'
@ -12,13 +12,11 @@ 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';
const backList = [back1, back2, back3]
import { getSourceList } from '../api'
const factoryZoneId = 199
function Index(props) {
const [nowTop, setNowTop] = useState({})
const [isVisible, setIsVisible] = useState(false);
@ -32,8 +30,8 @@ function Index(props) {
const getFullList = () => {
getSourceList({ id: factoryZoneId }).then(res => {
setChapterList(res.data.rows.slice(0, 7));
getSourceList({ id: factoryZoneId, domainId: lessonId }).then(res => {
setChapterList(res.data.rows);
});
};
@ -146,9 +144,12 @@ function Index(props) {
<div className="chapter-info">
<h4>{item.name}</h4>
<p>{item.summary}</p>
<div>
<div className="chapter-tag">
<span>{item.domainName}</span>
</div>
<div className="button-wrapper">
<button>查看详情</button>
</div>
</div>
</div>
})
@ -156,7 +157,7 @@ function Index(props) {
</div>
<div className="chapter-chapter2">
{
chapterList.slice(4).map((item, index) => {
chapterList.slice(3).map((item, index) => {
return <div className="chapter-chapter2-item" key={item.id}>
<div className="chapter-head">
<h4>{item.name}</h4>
@ -166,6 +167,7 @@ function Index(props) {
</div>
<div className="chapter-body">
<p>{item.summary}</p>
<span>{ moment(item.createTime).format('YYYY/MM/DD')}</span>
</div>
</div>
})
@ -180,6 +182,7 @@ function Index(props) {
return <div className="standard-item" key={index}>
<div className="standard-item-head">
<h4>XXXXXXX标准规范</h4>
<button>下载</button>
</div>
<p>我是标准规范的副文案占一行我是标准规范的副文案占一行</p>
<div className="standard-item-img">

View File

@ -285,6 +285,7 @@
padding: 45px 35px 35px 35px;
display: flex;
flex-direction: column;
transition: all .4s cubic-bezier(.25, .46, .45, .94);
h4 {
line-height: 30px;
@ -302,7 +303,7 @@
margin-top: 23px;
}
div {
.chapter-tag {
margin-top: auto;
span {
@ -316,6 +317,41 @@
font-size: 16px;
}
}
.button-wrapper {
width: 100%;
height: 80px;
background-color: #ffffff;
align-items: flex-end;
justify-content: center;
display: none;
margin-top: auto;
button {
cursor: pointer;
width: 449px;
height: 46px;
background: #091221;
border-radius: 9px;
line-height: 46px;
font-family: alibaba;
font-weight: 500;
color: #ffffff;
font-size: 14px;
text-align: center;
}
}
}
&:hover {
.chapter-info {
height: 302px;
background: #ffffff;
margin-top: -73px;
}
.chapter-tag {
display: none;
}
.button-wrapper {
display: flex;
}
}
}
}
@ -334,9 +370,37 @@
&-item {
width: 390px;
display: flex;
flex-direction: column;
.chapter-head {
border-bottom: 1px dashed rgba(9, 18, 33, 0.11);
display: flex;
align-items: center;
cursor: pointer;
&:hover {
h4 {
color: #164ce4;
}
&:hover {
.line-1,.line-2,.line-3 {
opacity: 1;
}
.line-1 {
animation: wave1 1.2s ease-in-out infinite;
}
.line-2 {
animation: wave2 1.2s ease-in-out infinite 0.1s;
}
.line-3 {
animation: wave3 1.2s ease-in-out infinite 0.2s;
}
}
}
h4 {
max-width: 340px;
@ -350,16 +414,102 @@
white-space: nowrap;
margin-bottom: 35px !important;
}
.line-1,
.line-2,
.line-3 {
flex-shrink: 0;
width: 2px;
background: #164ce4;
margin-right: 2px;
margin-bottom: 35px !important;
opacity: 0;
}
.line-1 {
height: 8px;
margin-left: auto;
}
.line-2 {
height: 12px;
}
.line-3 {
height: 6px;
margin-right: 8px;
}
@keyframes wave1 {
0%,
100% {
height: 8px;
}
50% {
height: 12px;
}
}
@keyframes wave2 {
0%,
100% {
height: 12px;
}
50% {
height: 16px;
}
}
@keyframes wave3 {
0%,
100% {
height: 6px;
}
50% {
height: 10px;
}
}
}
.chapter-body {
margin-top: 25px;
display: flex;
flex-direction: column;
margin-right: 35px;
flex-grow: 1;
position: relative;
&::before {
content: "";
background-image: url('../../images/factory/lessons/triangle.webp');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 10px;
height: 9px;
top: -30px;
left: 0;
display: inline-block;
position: absolute;
transform: rotate(180deg);
}
p {
max-width: 356px;
-webkit-line-clamp: 2;
}
span {
margin-top: auto;
}
}
}
}
@ -403,6 +553,7 @@
}
&-head {
display: flex;
h4 {
line-height: 33px;
font-family: alibaba;
@ -410,6 +561,21 @@
color: #091221;
font-size: 24px;
}
button {
cursor: pointer;
margin-left: auto;
margin-right: 88px;
opacity: 0;
width: 80px;
height: 32px;
background: #091221;
border-radius: 9px;
line-height: 32px;
font-family: alibaba;
font-weight: 500;
color: #ffffff;
font-size: 14px;
}
}
p {
@ -438,6 +604,9 @@
transform: scale(1.1);
}
}
button {
opacity: 1;
}
}
}
}
@ -474,7 +643,7 @@
}
p {
margin-bottom: 30px;
margin-bottom: 30px !important;
display: flex;
align-items: center;
@ -499,7 +668,7 @@
margin-right: 52px;
display: flex;
flex-direction: column;
border-radius:16px;
border-radius: 16px;
position: relative;
overflow: hidden;
z-index: 1;
@ -544,6 +713,7 @@
}
button {
cursor: pointer;
margin-top: auto;
width: 84px;
height: 36px;

View File

@ -0,0 +1,62 @@
import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { TPMIndexHOC } from '../../../modules/tpm/TPMIndexHOC';
import imageBack1 from '../../../images/factory/news/news-default.webp'
import { Link } from 'react-router-dom';
import RenderHtml from '../../../components/render-html';
import { Breadcrumb } from 'antd';
import { getNewsDetail } from '../../api';
import headerMp4 from '../../../images/factory/news/detail-head-bg.mp4';
function Index(props) {
const id = props.match.params.id
const [detail, setDetail] = useState({})
const [content, setContent] = useState();
useEffect(() => {
// setContent(Base64.decode(detail.content));
getDetail()
}, []);
const getDetail = () => {
getNewsDetail(id).then(res => {
if (res.data && res.data.data) {
setDetail(res.data.data)
setContent(Base64.decode(res.data.data.content))
}
})
}
return (
<div className="news-detail">
<div className="news-detail-header">
<video src={headerMp4} autoPlay></video>
<div className="header-content">
<h3>新闻动态</h3>
<p>实时汇聚前沿技术项目进展与开发者故事助你第一时间掌握社区脉搏不错过每一次灵感与成长机会</p>
<div className="header-img">
<div className="header-img-wrapper">
<img src={detail.headImg || imageBack1} alt="" />
</div>
</div>
</div>
</div>
<div className="news-detail-content">
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/softwareFactory`}>首页</Breadcrumb.Item>
<Breadcrumb.Item href={`/softwareFactory/news`}>新闻</Breadcrumb.Item>
<Breadcrumb.Item>详情</Breadcrumb.Item>
</Breadcrumb>
<div className="news-detail-content-wrapper">
<h4 className="news-detail-content-title">{detail.name}</h4>
{
content && <RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
}
</div>
</div>
</div>
)
}
export default TPMIndexHOC(Index)

View File

@ -0,0 +1,112 @@
.news-detail {
min-height: calc(100vh - 58px);
.news-detail-header {
height: 450px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
video {
height: 450px;
width: 100%;
position: absolute;
}
.header-content {
width: 1600px;
height: 300px;
position: relative;
border-radius: 16px;
padding: 60px;
h3 {
line-height: 47px;
font-family: alibaba;
font-weight: 700;
color: #091221;
font-size: 34px;
}
p {
margin-top: 19px;
max-width: 594px;
line-height: 32px;
font-family: alibabareg;
color: #091221;
font-size: 16px;
}
.header-img {
position: absolute;
top: -30px;
right: 0;
width: 600px;
height: 360px;
background: linear-gradient(180deg, #ffffff 0%, #f1f7ff 100%);
border-radius: 10px;
box-shadow: 0px 0px 18px rgba(0, 74, 168, 0.05);
display: flex;
align-items: center;
justify-content: center;
&-wrapper {
width: 526px;
height: 300px;
border-radius: 10px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 10px;
}
}
}
&:hover {
.header-img .header-img-wrapper img {
transform: scale(1.1);
transition: transform .4s cubic-bezier(.25, .46, .45, .94);
}
}
}
}
.news-detail-content {
width: 1600px;
height: 100%;
margin: 52px auto;
.ant-breadcrumb {
line-height: 20px;
font-family: alibaba;
font-size: 14px;
margin-bottom: 20px;
a {
color: #1b58df;
}
span {
color: #091221;
}
}
.news-detail-content-wrapper {
width: 1600px;
float: left;
padding-bottom: 60px;
.news-detail-content-title {
line-height: 33px;
font-family: alibaba;
font-weight: 700;
color: #091221;
font-size: 24px;
}
.informations_detail {
margin-top: 23px;
}
}
}
}

View File

@ -2,8 +2,8 @@ import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import KFIcon from '../../components/KFIcon/index';
// import { factoryZoneId } from '../../constants/factory'
import { gethomePageDocList, getNewsHotList, getDocList } from '../api'
import { factoryZoneId, dirId } from '../../constants/factory'
import { gethomePageDocList, getNewsHotList, getSubDocList } from '../api'
import { Carousel } from 'antd';
import back1 from '../../images/factory/back1.png'
import back2 from '../../images/factory/back2.png'
@ -11,11 +11,10 @@ import back3 from '../../images/factory/back3.png'
import headerBottom from '../../images/factory/news/header-bottom.png'
import '../common.scss'
import { Link } from "react-router-dom";
import moment from "moment";
const backList = [back1, back2, back3]
const factoryZoneId = 199
function Index(props) {
const [topList, setTopList] = useState([])
@ -69,10 +68,11 @@ function Index(props) {
}
const getFullList = () => {
getDocList(factoryZoneId).then(res => {
setNewsList1(res.data.rows[0].cmsDocList.slice(0, 2))
setNewsList2(res.data.rows[1].cmsDocList.slice(0, 4))
setNewsList3(res.data.rows[2].cmsDocList || res.data.rows[3].cmsDocList)
getSubDocList(dirId, { isHomepage: 0 }).then(res => {
const rows = res.data.rows
setNewsList1(rows.slice(0, 2))
setNewsList2(rows.slice(2, 6))
setNewsList3(rows.splice(6))
})
}
@ -84,7 +84,9 @@ function Index(props) {
<div className="header-left">
<h3>{nowTop.name}</h3>
<p>{nowTop.summary}</p>
<button className="shiny-button">了解详情</button>
<Link to={`/softwareFactory/news/${nowTop.id}`}>
<button className="shiny-button">了解详情</button>
</Link>
</div>
<div className="header-right">
<Carousel
@ -150,7 +152,7 @@ function Index(props) {
<h3>{item.name}</h3>
<p>{item.summary}</p>
<Link to={`/softwareFactory/scene/${index + 1}`}>
<Link to={`/softwareFactory/news/${item.id}`}>
<span>查看详情</span>
<KFIcon type="icon-icon_blackarrow_hover" font={40} />
</Link>
@ -169,7 +171,7 @@ function Index(props) {
<div className="line-3"></div>
热门新闻
</div>
<h4>{item.name}</h4>
<Link to={`/softwareFactory/news/${item.id}`}><h4>{item.name}</h4></Link>
<p>{item.summary}</p>
</div>
})
@ -181,7 +183,7 @@ function Index(props) {
newsList2.map((item, index) => {
return <div className="news-item" key={index}>
<div className="news-item-title">
<h3>{item.name}</h3>
<Link to={`/softwareFactory/news/${item.id}`}><h3>{item.name}</h3></Link>
<KFIcon type="icon-icon_blackarrow_hover" font={48} />
</div>
<p>{item.summary}</p>
@ -197,11 +199,11 @@ function Index(props) {
<img src={item.headImg || backList[index % 3]} alt="" />
</div>
<div className="news-item-info">
<h3>{item.name}</h3>
<Link to={`/softwareFactory/news/${item.id}`}><h3>{item.name}</h3></Link>
<p>{item.summary}</p>
<div className="news-item-info-bottom">
<span>{item.publishTime}</span>
<Link to={`/softwareFactory/scene/${index + 1}`}>
<Link to={`/softwareFactory/news/${item.id}`}>
<span>查看详情</span>
<KFIcon type="icon-icon_blackarrow_hover" font={40} />
</Link>

View File

@ -34,7 +34,10 @@
margin-top: 60px;
.header-left {
width: 33vw;
width: 642px;
height: 230px;
display: flex;
flex-direction: column;
h3 {
line-height: 38px;
@ -45,9 +48,13 @@
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 642px;
}
p {
width: 642px;
margin-top: 27px;
line-height: 34px;
font-family: alibabareg;
@ -61,8 +68,11 @@
word-break: break-all;
}
a {
margin-top: auto;
}
button {
margin-top: 23px;
cursor: pointer;
width: 116px;
height: 42px;
@ -289,13 +299,18 @@
.body-item {
width: 470.5px;
height: 230px;
background-image: url('../../images/factory/news/body-3.webp');
background-color: #ffffff;
background-image: url('../../images/factory/news/body-4.png');
background-repeat: no-repeat;
background-size: 100% 100%;
padding: 26px 35px;
border-radius: 16px;
border: 1px solid;
border-color: rgba(22, 76, 228, 0.05);
&:nth-child(1) {
margin-bottom: 25px;
background-image: url('../../images/factory/news/body-3.webp');
}
@ -412,7 +427,7 @@
border-color: rgba(9, 18, 33, 0.07);
border-radius: 16px;
box-shadow: 0px 0px 6px rgba(0, 74, 168, 0.03);
padding: 50px;
padding: 23px 50px 50px 50px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;

View File

@ -0,0 +1,170 @@
import React, { useEffect, useState, useRef } from 'react';
import { styles } from './index.scss';
import { getSourceList, getProjectsLists } from '../../../api'
import { factoryZoneId } from '../../../../constants/factory'
import ActionItem from '../ActionItem';
import emptyImg from '../../../../images/factory/resource/empty.webp'
function Index(props) {
const searchValue = props.searchValue
const searchType = props.searchType
const [versionList, setVersionList] = useState([]);
const [versionTotal, setVersionTotal] = useState(0);
const [projectList, setProjectList] = useState([]);
const [projectTotal, setProjectTotal] = useState(0);
const [toolList, setToolList] = useState([]);
const [toolTotal, setToolTotal] = useState(0);
const [page, setPage] = useState(0);
const pageSize = 20
const totalSize = 6 //
useEffect(() => {
console.log(searchValue);
if (searchValue) {
getProjectsList(1)
console.log(versionTotal === projectTotal === toolTotal === 0);
}
// getFullList();
}, [searchValue]);
const getFullList = () => {
getSourceList({ id: factoryZoneId }).then(res => {
setVersionList(res.data.rows.slice(0, 4));
});
};
const getProjectsList = (page) => {
getProjectsLists(factoryZoneId, {
pageNum: page,
name: searchValue,
pageSize: searchType ? pageSize : totalSize,
}).then(result => {
if (result) {
// setProjectList(result.data.rows);
// setProjectTotal(result.data.total);
}
}).catch(error => { })
}
return (
<div className="search">
{
projectList.length > 0 && <div className="search-project">
<div className="search-header">
<h3>软件项目</h3>
<div><span>#</span>项目 <span>{projectTotal}</span></div>
</div>
<div className="search-content">
{
projectList.map((item, index) => {
const project = item.projectProperties || {}
project.praisesCount = 3
project.forkedCount = 3
return <ActionItem className="content-item-wrapper" key={index} padding="1px" borderRadius="23px">
<div className="content-project-item">
<div className="item-top">
<img src={project.authorImageUrl} alt="" className="item-img"></img>
<h5 className="item-title">{project.name}</h5>
</div>
<div className="item-desc">
{project.description}
</div>
<div className="item-tags">
{
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
return (
<span key={index} className="item-tag">{topic}</span>
)
})
}
</div>
<div className="item-data">
{
project.praisesCount > 0 && <span><i className="iconfont icon-liulanliang mr5 font-12" />{project.praisesCount}</span>
}
{
project.forkedCount > 0 && <span><i className="iconfont icon-shoucang mr5 font-12" />{project.forkedCount}</span>
}
</div>
</div>
<div className="content-project-btn">
<button className="shiny-button">查看详情</button>
</div>
</ActionItem>
})
}
</div>
</div>
}
{
toolList.length > 0 && <div className="search-tool">
<div className="search-header">
<h3>开发工具</h3>
<div><span>#</span>工具 <span>{projectTotal}</span></div>
</div>
<div className="search-content">
{
toolList.map((item, index) => {
const createUser = item.createUser || {}
return <ActionItem className="content-item-wrapper" key={index} padding="1px" borderRadius="23px">
<div className="content-tool-item">
<div className="item-top">
<img src={createUser.avatar} alt="" className="item-img"></img>
<h5 className="item-title">{item.name}</h5>
</div>
<div className="item-tags">
<span className="item-tag">{item.domainName}</span>
</div>
<div className="item-desc">
{item.summary}
</div>
<div className="item-data">
<span><i className="iconfont icon-xiazai mr5 font-12" />{item.downloadCount}</span>
</div>
</div>
<div className="two-btn">
<button className="shiny-button">查看</button>
<button className="shiny-button">下载</button>
</div>
</ActionItem>
})
}
</div>
</div>
}
{
versionList.length > 0 && <div className="search-version">
<div className="search-header">
<h3>工厂版本</h3>
<div><span>#</span>版本 <span>{projectTotal}</span></div>
</div>
<div className="search-content">
{
versionList.map((item, index) => {
return <div key={index} className="version-item">
<h5 className="item-title">{item.name}</h5>
<p className="item-desc">{item.summary}</p>
<div className="item-data">
<span><i className="iconfont icon-xiazai mr5 font-12" />{item.cteatetime}</span>
</div>
</div>
})
}
</div>
</div>
}
{
versionTotal + projectTotal + toolTotal === 0 && <div className="search-empty">
<img src={emptyImg} alt="" />
<p>抱歉暂无与{ searchValue }相关的数据</p>
</div>
}
</div>
)
}
export default Index

View File

@ -0,0 +1,265 @@
.search {
display: flex;
flex-direction: column;
align-items: center;
&-project,
&-tool,
&-version {
width: 1600px;
border-radius: 30px;
padding: 40px 50px;
margin-bottom: 50px;
.search-header {
display: flex;
align-items: center;
h3 {
line-height: 38px;
font-family: alibaba;
font-weight: 700;
color: #091221;
font-size: 28px;
margin-right: 18px;
}
div {
padding: 7px 15px;
background: #f8fbfd;
border: 1px solid;
border-color: #ffffff;
border-radius: 7px;
line-height: 25px;
font-family: alibabareg;
color: #091221;
font-size: 18px;
span {
&:nth-child(1) {
color: #164ce4;
margin-right: 8px;
}
&:nth-child(2) {
color: #7d899d;
margin-left: 8px;
}
}
}
}
.search-content {
margin-top: 40px;
display: flex;
flex-wrap: wrap;
.content-item-wrapper {
margin-bottom: 25px;
margin-right: 25px;
.item-title {
line-height: 30px;
font-family: alibaba;
font-weight: 500;
color: #091221;
font-size: 22px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin: 0;
}
.item-desc {
margin-top: 20px;
line-height: 21px;
font-family: alibabareg;
color: #091221;
font-size: 15px;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.item-data {
margin-top: auto;
span {
line-height: 18px;
font-family: alibabareg;
color: #5d6a80;
font-size: 13px;
position: relative;
}
span:not(:last-child) {
margin-right: 15px;
padding-right: 15px;
&::after {
position: absolute;
right: 0;
top: 50%;
transform: translate(0, -50%);
content: "";
width: 1px;
height: 9px;
background: rgba(9, 18, 33, 0.22);
}
}
}
.content-project-item,
.content-tool-item {
width: 483.3px;
background: #fcfefe;
border-radius: 23px;
z-index: 1;
position: relative;
padding: 25px 35px;
display: flex;
flex-direction: column;
.item-top {
display: flex;
align-items: center;
img {
width: 53px;
height: 53px;
border-radius: 50%;
margin-right: 18px;
}
}
.item-tags {
margin-top: 16px;
}
}
}
}
}
&-project {
background: #eef3fe;
.search-content {
.content-project-item {
height: 263px;
.item-desc {
-webkit-line-clamp: 2;
}
}
.content-project-btn {
width: 483.3px;
height: 94px;
background: linear-gradient(180deg, rgba(248, 251, 255, 0) 0%, #f3f6ff 23.71%, #f8fbff 100%);
border-radius: 0px 0px 23px 23px;
display: flex;
align-items: center;
justify-content: center;
button {
cursor: pointer;
width: 413px;
height: 44px;
background-color: #091221;
border-radius: 9px;
line-height: 44px;
font-family: alibaba;
font-weight: 500;
color: #ffffff;
font-size: 14px;
text-align: center;
}
}
}
}
&-tool {
background: #f3f9fc;
.search-content {
.content-tool-item {
height: 228px;
.item-desc {
-webkit-line-clamp: 2;
margin-top: 26px;
}
}
.two-btn {
width: 483px;
height: 83px;
background: linear-gradient(180deg, rgba(248, 251, 255, 0.13) 0%, rgba(248, 251, 255, 0.93) 23.71%, #f8fbff 100%);
border-radius: 0px 0px 16px 16px;
display: flex;
align-items: center;
justify-content: center;
button {
width: 125px;
height: 36px;
line-height: 36px;
cursor: pointer;
border-radius: 9px;
line-height: 20px;
font-family: alibaba;
font-weight: 500;
color: #ffffff;
font-size: 14px;
text-align: center;
background-color: #091221;
}
button:nth-child(2) {
margin-left: 21px;
color: #091221;
background-color: #ffffff;
background-image: none;
border: 1px solid #091221;
}
}
}
}
&-version {
background: #ecf6ff;
.search-content {
.version-item {
padding: 35px;
width: 483.3px;
height: 216px;
background: #fcfefe;
border-radius: 23px;
box-shadow: 0px 0px 18px rgba(0, 74, 168, 0.05);
margin-bottom: 25px;
margin-right: 25px;
}
}
}
&-empty {
display: flex;
flex-direction: column;
img {
width: 214.66px;
height: 146.73px;
}
p {
line-height: 22px;
font-family: alibabareg;
color: #091221;
font-size: 16px;
}
}
}

View File

@ -0,0 +1,105 @@
import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { TPMIndexHOC } from '../../../../modules/tpm/TPMIndexHOC';
import imageBack1 from '../../../../images/factory/resource/tools-detail-head-left.webp'
import imageGif from '../../../../images/factory/resource/tools-detail-head-left2.webp'
import headIcon from '../../../../images/factory/resource/tools-detail-head-icon.webp'
import { Link } from 'react-router-dom';
import RenderHtml from '../../../../components/render-html';
import { Breadcrumb } from 'antd';
import { getSourceDetail, httpUrl, getSourceList } from '../../../api';
import { downloadFunc } from '../../../../forge/Utils/utils'
import { factoryZoneId, } from '../../../../constants/factory'
import '../../../common.scss'
function Index(props) {
const id = props.match.params.id
const [detail, setDetail] = useState({})
const [content, setContent] = useState();
const [otherList, setOtherList] = useState([]);
useEffect(() => {
getDetail()
}, []);
useEffect(() => {
if (detail.id) {
getOtherList()
}
},[detail])
const getDetail = () => {
getSourceDetail(id).then(response=>{
if(response){
setDetail(response.data.data);
}
}).catch(error=>{})
}
const getOtherList = () => {
getSourceList({ id: factoryZoneId, domainId: detail.domainId }).then(res => {
setOtherList(res.data.rows.filter(e => e.id !== detail.id).slice(0, 3));
});
}
return (
<div className="news-detail">
<div className="news-detail-header">
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/softwareFactory`}>首页</Breadcrumb.Item>
<Breadcrumb.Item href={`/softwareFactory/resource/developmentTools`}>开发工具</Breadcrumb.Item>
<Breadcrumb.Item>{detail.name}</Breadcrumb.Item>
</Breadcrumb>
<div className="header-content">
<h3>{ detail.name }</h3>
<p>{ detail.summary }</p>
<div className="tools-info">
<div>
<span>{ detail.downloadCount }</span>
<span>下载量</span>
</div>
<div>
<span>{ detail.fileList && detail.fileList[0] && detail.fileList[0].fileSizeInfo }</span>
<span>文件大小</span>
</div>
<div>
<span>{ detail.domainName }</span>
<span>工具类型</span>
</div>
</div>
<button className="shiny-button" onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}}>立即下载</button>
<h6 className="more-title">更多热门工具</h6>
<div className="more-tools">
{
otherList.length > 0 && otherList.map((e, index) => {
return <Link to={`/softwareFactory/resource/developmentTools/${e.id}`} key={index}><span >
<img src={ headIcon } alt="" />
{e.name}
</span>
</Link>
})
}
</div>
<div className="header-img">
<div className="header-img-wrapper">
<img src={detail.img || imageBack1} alt="" />
<img src={ imageGif } alt="" />
</div>
</div>
</div>
</div>
<div className="news-detail-content">
<div className="news-detail-content-wrapper">
<h4>{detail.name}</h4>
{
content && <RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
}
</div>
</div>
</div>
)
}
export default TPMIndexHOC(Index)

View File

@ -0,0 +1,243 @@
.news-detail {
min-height: calc(100vh - 58px);
.news-detail-header {
height: 752px;
width: 100%;
background-image: url("../../../../images/factory/resource/tools-detail-head.webp");
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
.ant-breadcrumb {
align-self: flex-start;
margin-top: 30px;
margin-left: calc((100vw - 1600px) / 2);
}
.header-content {
margin-top: 30px;
width: 1600px;
height: 481px;
position: relative;
border-radius: 16px;
padding: 60px 45px;
background: linear-gradient(106.16deg, #f7fbff 2.47%, #f5faff 95.98%);
border: 2px solid;
border-color: #ffffff;
h3 {
line-height: 47px;
font-family: alibaba;
font-weight: 700;
color: #091221;
font-size: 34px;
}
p {
margin-top: 25px;
max-width: 650px;
line-height: 22px;
font-family: alibabareg;
color: #5d6a80;
font-size: 16px;
}
.tools-info {
display: flex;
margin-top: 35px;
div {
display: flex;
flex-direction: column;
position: relative;
margin-right: 78px;
span:nth-child(1) {
line-height: 32px;
font-family: alibaba;
font-weight: 700;
color: #164ce4;
font-size: 24px;
}
span:nth-child(2) {
line-height: 20px;
font-family: alibabareg;
color: #5d6a80;
font-size: 14px;
margin-top: 8px;
}
&:not(:last-child) {
&::after {
position: absolute;
content: "";
width: 0px;
height: 60px;
right: -39px;
border-right: 1px dashed;
border-color: rgba(22, 76, 228, 0.15);
}
}
}
}
button {
margin-top: 30px;
width: 110px;
height: 36px;
line-height: 36px;
cursor: pointer;
border-radius: 6px;
line-height: 20px;
font-family: alibaba;
font-weight: 500;
color: #ffffff;
font-size: 14px;
text-align: center;
background-color: #091221;
}
h6 {
margin-top: 34px;
line-height: 22px;
font-family: alibaba;
font-weight: 700;
color: #091221;
font-size: 16px;
}
.more-tools {
display: flex;
margin-top: 20px;
span {
cursor: pointer;
display: inline-block;
background: #e9f2ff;
border-radius: 4px;
padding: 13px 12px;
display: flex;
align-items: center;
margin-right: 15px;
line-height: 19px;
font-family: alibaba;
color: #091221;
font-size: 15px;
img {
width: 19px;
height: 19px;
margin-right: 15px;
}
}
}
.header-img {
position: absolute;
top: 60px;
right: 60px;
width: 600px;
height: 360px;
background: linear-gradient(180deg, #ffffff 0%, #ffffff 100%);
border-radius: 14px;
box-shadow: 0px 0px 18px rgba(0, 74, 168, 0.05);
display: flex;
align-items: center;
justify-content: center;
&-wrapper {
width: 526px;
height: 300px;
border-radius: 10px;
overflow: hidden;
position: relative;
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 10px;
&:nth-child(2) {
width: 120px;
height: 120px;
position: absolute;
right: 127px;
bottom: 15px;
}
}
}
}
&:hover {
.header-img .header-img-wrapper img {
&:nth-child(1) {
transform: scale(1.1);
transition: transform .4s cubic-bezier(.25, .46, .45, .94);
}
}
}
}
}
.news-detail-content {
width: 1600px;
height: 100%;
margin: 52px auto;
margin-top: -100px;
.ant-breadcrumb {
line-height: 20px;
font-family: alibaba;
font-size: 14px;
margin-bottom: 20px;
a {
color: #1b58df;
}
span {
color: #091221;
}
}
.news-detail-content-wrapper {
width: 1600px;
float: left;
padding-bottom: 60px;
}
.news-detail-content-others {
width: 300px;
float: right;
div {
background: #f2f6fa;
border-radius: 12px;
padding: 35px 30px;
h4 {
line-height: 22px;
font-family: alibaba;
font-weight: 500;
color: #091221;
font-size: 16px;
}
li {
line-height: 20px;
font-family: alibabareg;
color: #091221;
font-size: 14px;
margin-top: 20px;
}
}
}
}
}

View File

@ -1,24 +1,24 @@
import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { getSourceList, getSourceZoneList } from '../../api'
// import { factoryZoneId } from '../../../constants/factory'
import { getSourceList, getSourceZoneList, httpUrl } from '../../api'
import { factoryZoneId, lessonId , versionId } from '../../../constants/factory'
import KFIcon from '../../../components/KFIcon';
import bg1 from '../../../images/factory/resource/tools-top-1.webp';
import bg2 from '../../../images/factory/resource/tools-top-2.webp';
import bg3 from '../../../images/factory/resource/tools-top-3.webp';
import bg3 from '../../../images/factory/resource/tools-top-3.webp';
import bg4 from '../../../images/factory/resource/tools-bottom-1.webp';
import bg5 from '../../../images/factory/resource/tools-bottom-2.webp';
import ActionItem from '../components/ActionItem';
import '../../common.scss'
import { downloadFunc } from '../../../forge/Utils/utils'
import { Link } from "react-router-dom";
const bgList = [bg1, bg2, bg3]
const bg2List = [bg4, bg5]
const factoryZoneId = 199
function Index(props) {
const [topList, setTopList] = useState([]);
@ -33,34 +33,58 @@ function Index(props) {
getTypeList();
}, []);
useEffect(() => {
if (selectedType) {
getTypeSourceList()
} else {
getFullList()
}
}, [selectedType])
const getFullList = () => {
getSourceList({ id: factoryZoneId }).then(res => {
setTopList(res.data.rows.slice(0, 3));
setNewList(res.data.rows.slice(0, 2));
setContentList(res.data.rows.slice(3, 9));
setFullList(res.data.rows.slice(9));
if (res.data.rows) {
const rows = res.data.rows.filter(e => e.domainId !== lessonId && e.domainId !== versionId)
setTopList(rows.slice(0, 3));
setNewList(rows.slice(0, 2));
setContentList(rows.slice(3, 9));
setFullList(rows.slice(9));
}
});
};
const getTypeSourceList = () => {
getSourceList({ id: factoryZoneId, domainId: selectedType }).then(res => {
setContentList(res.data.rows.slice(0, 6));
setFullList(res.data.rows.slice(6));
});
}
const getTypeList = () => {
getSourceZoneList(factoryZoneId).then(response => {
if (response && response.data) {
setZoneList(response.data.rows);
setZoneList(response.data.rows.filter(e => e.name !== '工厂版本' && e.name !== '学习资源'));
}
}).catch(error => { })
}
const getBackgroundImage = (index) => {
const row = Math.floor(index / 4); //
const col = index % 4; //
// 0,1,0,1...
// 1,0,1,0...
return row % 2 === 0
? bg2List[col % 2] // 0,1,0,1
: bg2List[(col + 1) % 2]; // 1,0,1,0
};
const row = Math.floor(index / 4); //
const col = index % 4; //
return row % 2 === 0
? bg2List[col % 2] // 0,1,0,1
: bg2List[(col + 1) % 2]; // 1,0,1,0
};
const selectType = (type) => {
if (type !== selectedType) {
setSelectedType(type)
} else {
setSelectedType(null)
}
}
return (
<div className="tools">
@ -71,13 +95,15 @@ function Index(props) {
<div className="tools-top-item" key={index}>
<img src={bgList[index]} alt="" className="item-bg" />
<div className="item-info">
<h5 className="item-title">
{item.name}
</h5>
<Link to={`/softwareFactory/resource/developmentTools/${item.id}`}>
<h5 className="item-title">
{item.name}
</h5>
</Link>
<span className="item-tag">{item.domainName}</span>
<p className="item-desc">{item.summary}</p>
</div>
<button>立即下载</button>
<button onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}}>立即下载</button>
</div>
)
})
@ -89,7 +115,7 @@ function Index(props) {
{
zoneList.map((item, index) => {
return (
<span className={`type-item ${selectedType === item.id ? 'active' : ''}`} key={index} onClick={() => setSelectedType(item.id)}>{item.name}</span>
<span className={`type-item ${selectedType === item.id ? 'active' : ''}`} key={index} onClick={() => selectType(item.id)}>{item.name}</span>
)
})
}
@ -119,8 +145,8 @@ function Index(props) {
</div>
<div className="two-btn">
<button className="shiny-button">查看</button>
<button className="shiny-button">下载</button>
<Link to={`/softwareFactory/resource/developmentTools/${item.id}`}><button className="shiny-button">查看</button></Link>
<button onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}} className="shiny-button">下载</button>
</div>
</ActionItem>
})
@ -137,15 +163,17 @@ function Index(props) {
newList.map((item, index) => {
const createUser = item.createUser
return <div className="new-item">
<img src={createUser.avatar} alt="" className="item-img"></img>
<div className="item-info">
<img src={createUser.avatar} alt="" className="item-img"></img>
<div className="item-info">
<Link to={`/softwareFactory/resource/developmentTools/${item.id}`}>
<h5 className="item-title">{item.name}</h5>
<p className="item-desc">
{item.summary}
</p>
<button>下载</button>
</div>
</Link>
<p className="item-desc">
{item.summary}
</p>
<button onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}}>下载</button>
</div>
</div>
})
}
</div>
@ -159,7 +187,7 @@ function Index(props) {
return <ActionItem className="content-bottom-wrapper" key={index} backgroundColor="rgba(241, 247, 255, 0.48)" padding="1px" borderRadius="16px">
<div className="content-bottom-item">
<img src={getBackgroundImage(index)} alt="" className="item-bg" />
<img src={getBackgroundImage(index)} alt="" className="item-bg" />
<div className="item-top">
<img src={createUser.avatar} alt="" className="item-img"></img>
<h5 className="item-title">{item.name}</h5>
@ -173,8 +201,8 @@ function Index(props) {
</div>
<div className="content-bottom-btn">
<div className="two-btn">
<button className="shiny-button">查看</button>
<button className="shiny-button">下载</button>
<Link to={`/softwareFactory/resource/developmentTools/${item.id}`}><button className="shiny-button">查看</button></Link>
<button onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}} className="shiny-button">下载</button>
</div>
</div>
</ActionItem>

View File

@ -108,12 +108,14 @@
}
&:nth-child(2) {
color: #ffffff;
h5 {
color: #ffffff;
}
p {
color: #ffffff;
}
.item-tag {
color: #ffffff;
background: rgba(255, 255, 255, 0.13);
@ -396,13 +398,13 @@
width: 1600px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background: #ffffff;
border-radius: 16px;
padding: 40px 30px;
.content-bottom-wrapper {
margin-bottom: 26px;
margin-right: 16px;
}
.content-bottom-item {

View File

@ -1,12 +1,11 @@
import React, { useEffect, useState, useRef } from 'react';
import './index.scss';
import { getSourceList } from '../../api'
// import { factoryZoneId } from '../../../constants/factory'
import { getSourceList, httpUrl } from '../../api'
import { factoryZoneId, versionId } from '../../../constants/factory'
import dot from '../../../images/factory/resource/version-dot.webp'
import versionNew from '../../../images/factory/resource/version-new.webp'
import '../../common.scss'
const factoryZoneId = 199
import { downloadFunc } from '../../../forge/Utils/utils'
function Index(props) {
@ -18,7 +17,7 @@ function Index(props) {
const getFullList = () => {
getSourceList({ id: factoryZoneId }).then(res => {
getSourceList({ id: factoryZoneId, domainId: versionId }).then(res => {
setVersionList(res.data.rows.slice(0, 4));
});
};
@ -47,7 +46,7 @@ function Index(props) {
<div className="version-item-content">
{item.summary}
</div>
<button className={index === 0 ? "shiny-button" : "version-btn"}>立即下载</button>
<button onClick={() => {downloadFunc(`${httpUrl}/file/open/download/${item.fileIds}`)}} className={index === 0 ? "shiny-button" : "version-btn"}>立即下载</button>
</div>
</div>
})

View File

@ -3,6 +3,7 @@
flex-direction: column;
align-items: center;
margin-top: -50px;
background-color: #f1f6fd;
.version-top {
width: 1600px;

View File

@ -6,6 +6,8 @@ import searchBg from '../../images/factory/resource/search-bg.webp'
import { Route, Switch } from "react-router-dom";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import Search from './components/Search/index'
import { Input } from 'antd';
@ -35,16 +37,43 @@ const typeMap = [
function Index(props) {
const [selectedType, setSelectedType] = useState(typeMap[0].key)
const [selectedType, setSelectedType] = useState()
const [searchValue, setSearchValue] = useState('')
useEffect(() => {
props.history.push(`/softWareFactory/resource/${selectedType}`);
console.log(456);
if (selectedType) {
props.history.push(`/softWareFactory/resource/${selectedType}`);
} else {
props.history.push(`/softWareFactory/resource/`);
}
}, [selectedType]);
useEffect(() => {
useEffect(() => {
let matchPath = ''
for( let i of typeMap) {
if (props.location.pathname.includes(i.key)) matchPath = i.key
}
setSelectedType(matchPath || typeMap[0].key)
}, [])
const search = () => {
setSelectedType(null)
}
const cleanSearch = (e) => {
if (e.target && e.target.value) {
setSearchValue(e.target.value)
} else {
setSearchValue('')
setSelectedType(typeMap[0].key)
}
}
return (
<div className="resource">
<div className="resource-header">
@ -56,8 +85,9 @@ function Index(props) {
</div>
<h2><span>资源中枢</span>共享复用释放生态力量</h2>
<div className="search-box">
<input className="search-input" type="text" placeholder="搜索资源" />
<div className="search-icon">
<Input className="search-input" value={searchValue} placeholder="搜索资源" allowClear onChange={cleanSearch}></Input>
{/* <input className="search-input" type="text" placeholder="搜索资源" /> */}
<div className="search-icon" onClick={search}>
<KFIcon type="icon-sousuo" font={22} />
</div>
</div>
@ -91,6 +121,9 @@ function Index(props) {
<DevelopmentTools {...props} {...p}/>
)} />
</Switch>
{
!selectedType && <Search searchValue={ searchValue }/>
}
</div>
</div>
)

View File

@ -1,5 +1,6 @@
.resource {
background-color: #f1f6fd;
min-height: calc(100vh - 58px);
&-header {
height: 410px;
@ -115,12 +116,15 @@
.search-input {
margin-left: 30px;
width: 400px;
width: 100%;
height: 40px;
border: none;
line-height: 40px;
font-family: alibabareg;
font-size: 15px;
input {
border: none;
width: 100%;
}
&::placeholder {
color: #a2abbd;
@ -149,7 +153,6 @@
width: 178px;
height: 54px;
border-radius: 35px;
box-shadow: 0px 0px 15px rgba(0, 74, 168, 0.05);
display: flex;
align-items: center;
justify-content: center;
@ -172,6 +175,7 @@
.switch-item-active {
background: #ffffff;
box-shadow: 0px 0px 15px rgba(0, 74, 168, 0.05);
}
}
}

View File

@ -17,6 +17,7 @@ import bg8 from '../../../images/factory/resource/project-bottom-1.webp'
import ActionItem from '../components/ActionItem';
import '../../common.scss'
import { Link } from 'react-router-dom';
const bgList = [bg1, bg2, bg3]
@ -34,7 +35,7 @@ function Index(props) {
}, []);
const getTopList = () => {
getProjectsLists(factoryZoneId, { isHomepage: 1 }).then(res => {
getProjectsLists(factoryZoneId, { isHomepage: 1 }).then(res => {
setTopList(res.data.rows.slice(0, 3)); // topList
});
};
@ -55,7 +56,7 @@ function Index(props) {
topList.map((item, index) => {
const project = item.projectProperties
return (
<div className="project-top-item" key={index}>
<Link to={`/${project.fullName}`}><div className="project-top-item" key={index}>
<img src={bgList[index]} alt="" className="item-bg" />
<img src={project.authorImageUrl} alt="" className="item-img"></img>
<div className="item-info">
@ -71,18 +72,10 @@ function Index(props) {
})
}
</div>
<div className="item-bottom-data">
{
project.praisesCount > 0 && <span><i className="iconfont icon-liulanliang mr5 font-12" />{project.praisesCount}</span>
}
{
project.forkedCount > 0 && <span><i className="iconfont icon-shoucang mr5 font-12" />{project.forkedCount}</span>
}
</div>
</div>
</div>
</div>
</Link>
)
})
}
@ -99,7 +92,7 @@ function Index(props) {
const project = item.projectProperties
project.praisesCount = 3
project.forkedCount = 3
return <div key={index} className="content-top-item">
return <Link to={`/${project.fullName}`} className="content-top-item"><div key={index}>
<img className="item-bg" src={contentBgList[index]} alt="" />
<div className="item-top">
<img src={project.authorImageUrl} alt="" className="item-img"></img>
@ -126,7 +119,7 @@ function Index(props) {
project.forkedCount > 0 && <span><i className="iconfont icon-shoucang mr5 font-12" />{project.forkedCount}</span>
}
</div>
</div>
</div></Link>
})
}
</div>
@ -150,9 +143,12 @@ function Index(props) {
<img src={project.authorImageUrl} alt="" className="item-img"></img>
<h5 className="item-title">{project.name}</h5>
</div>
<div className="item-desc">
{project.description}
</div>
{
project.description && <div className="item-desc">
{project.description}
</div>
}
<div className="item-tags">
{
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
@ -174,7 +170,7 @@ function Index(props) {
</div>
</div>
<div className="content-bottom-btn">
<button className="shiny-button">查看详情</button>
<Link to={`/${project.fullName}`}><button className="shiny-button">查看详情</button></Link>
</div>
</ActionItem>
})

View File

@ -84,34 +84,6 @@
border-radius: 4px;
}
}
.item-bottom-data {
margin-left: auto;
span {
line-height: 18px;
font-family: alibabareg;
color: #ffffff;
font-size: 13px;
position: relative;
}
span:not(:last-child) {
margin-right: 15px;
padding-right: 15px;
&::after {
position: absolute;
right: 0;
top: 50%;
transform: translate(0, -50%);
content: "";
width: 1px;
height: 9px;
background: rgba(255, 255, 255, 0.22);
}
}
}
}
}
}
@ -223,13 +195,29 @@
background: linear-gradient(110.74deg, #f5f5fd 2.03%, #ddf0ff 98.5%);
border-radius: 16px;
display: flex;
align-items: center;
padding: 58px 0 32px 0;
margin-top: 25px;
&-left {
padding: 0 0 0 53px;
p {
position: relative;
padding-left: 33px;
&::before {
position: absolute;
content: "";
width: 16.48px;
height: 16.48px;
background-image: url("../../../images/factory/resource/star.png");
background-repeat: no-repeat;
background-size: 100% 100%;
left: 0;
top: 50%;
transform: translate(0,-50%);
}
}
.content-top-list {
display: flex;
flex-wrap: wrap;
@ -295,11 +283,13 @@
&-right {
width: 672px;
height: 516px;
margin-left: auto;
}
}
&-bottom {
margin-top: 40px;
margin-bottom: 80px;
width: 1600px;
display: flex;
flex-wrap: wrap;

View File

@ -5,6 +5,7 @@ import imageBack1 from '../../images/factory/back1.png'
import sceneIcon from '../../images/factory/scene/scene-icon.webp'
import { Link } from 'react-router-dom';
import RenderHtml from '../../components/render-html';
import { Breadcrumb } from 'antd';
@ -27,7 +28,7 @@ const otherList = [
function Index(props) {
const [detail, setDetail] = useState(Detail)
const [ content , setContent]=useState();
const [content, setContent] = useState();
useEffect(() => {
setContent(Base64.decode(detail.content));
@ -48,6 +49,10 @@ function Index(props) {
</div>
</div>
<div className="scene-content">
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/softwareFactory`}>首页</Breadcrumb.Item>
<Breadcrumb.Item>{detail.name}</Breadcrumb.Item>
</Breadcrumb>
<div className="scene-content-wrapper">
{
content && <RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />

View File

@ -86,6 +86,19 @@
height: 100%;
margin: 52px auto;
.ant-breadcrumb {
line-height: 20px;
font-family: alibaba;
font-size: 14px;
margin-bottom: 20px;
a {
color: #1b58df;
}
span {
color: #091221;
}
}
.scene-content-wrapper {
width: 1245px;
float: left;

View File

@ -13,4 +13,27 @@ export function formatNumber(num) {
export function formatNumberWithCommas(num) {
if (num === undefined || num === null) return
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
}
/**
* 下载
* @param url 下载地址
* @param name 下载名称
* @param msg 成功消息
*/
export const downloadFunc = (url, name) => {
const link = document.createElement('a')
link.href = url
link.download = name || 'download'
document.body.appendChild(link)
setTimeout(() => {
link.click()
if (url.startsWith('blob:')) {
URL.revokeObjectURL(url)
}
document.body.removeChild(link)
}, 50)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB