diff --git a/public/css/gitlink.min.css b/public/css/gitlink.min.css index 963d570c7..40f3ec412 100644 --- a/public/css/gitlink.min.css +++ b/public/css/gitlink.min.css @@ -1474,6 +1474,10 @@ a.decoration { font-weight: 400 } +.mt-5{ + margin-top: -5px; +} + .mt-8{ margin-top: -8px; } @@ -1894,6 +1898,10 @@ a.decoration { padding-top: 5px !important } +.pt8 { + padding-top: 8px !important +} + .pt10 { padding-top: 10px } @@ -2078,6 +2086,10 @@ a.decoration { padding-left: 40px } +.pl45 { + padding-left: 45px +} + .pl50 { padding-left: 50px } diff --git a/public/css/iconfont.css b/public/css/iconfont.css index cfc629a76..1af2903d4 100644 --- a/public/css/iconfont.css +++ b/public/css/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 2340181 */ - src: url('iconfont.woff2?t=1765510650736') format('woff2'), - url('iconfont.woff?t=1765510650736') format('woff'), - url('iconfont.ttf?t=1765510650736') format('truetype'); + src: url('iconfont.woff2?t=1765938619495') format('woff2'), + url('iconfont.woff?t=1765938619495') format('woff'), + url('iconfont.ttf?t=1765938619495') format('truetype'); } .iconfont { @@ -13,6 +13,14 @@ -moz-osx-font-smoothing: grayscale; } +.icon-svg_jiantou1:before { + content: "\e9c3"; +} + +.icon-zuojiantou1:before { + content: "\e9c4"; +} + .icon-jiantou4:before { content: "\e9c2"; } diff --git a/public/css/iconfont.js b/public/css/iconfont.js index ae9581b3e..548738c34 100644 --- a/public/css/iconfont.js +++ b/public/css/iconfont.js @@ -1 +1 @@ -window._iconfont_svg_string_2340181='',(c=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,i,o,z,t,p=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}h=function(){var a,l=document.createElement("div");l.innerHTML=c._iconfont_svg_string_2340181,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?p(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),h()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(o=h,z=c.document,t=!1,m(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,v())})}function v(){t||(t=!0,o())}function m(){try{z.documentElement.doScroll("left")}catch(a){return void setTimeout(m,50)}v()}})(window); \ No newline at end of file +window._iconfont_svg_string_2340181='',(c=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var h,i,o,z,t,p=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}h=function(){var a,l=document.createElement("div");l.innerHTML=c._iconfont_svg_string_2340181,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?p(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(h,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),h()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(o=h,z=c.document,t=!1,m(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,v())})}function v(){t||(t=!0,o())}function m(){try{z.documentElement.doScroll("left")}catch(a){return void setTimeout(m,50)}v()}})(window); \ No newline at end of file diff --git a/public/css/iconfont.json b/public/css/iconfont.json index 2731cd761..ac9ae795a 100644 --- a/public/css/iconfont.json +++ b/public/css/iconfont.json @@ -5,6 +5,20 @@ "css_prefix_text": "icon-", "description": "", "glyphs": [ + { + "icon_id": "46370299", + "name": "svg_箭头1", + "font_class": "svg_jiantou1", + "unicode": "e9c3", + "unicode_decimal": 59843 + }, + { + "icon_id": "46370300", + "name": "左箭头", + "font_class": "zuojiantou1", + "unicode": "e9c4", + "unicode_decimal": 59844 + }, { "icon_id": "46329189", "name": "箭头", diff --git a/public/css/iconfont.ttf b/public/css/iconfont.ttf index 507edca72..ae09e439f 100644 Binary files a/public/css/iconfont.ttf and b/public/css/iconfont.ttf differ diff --git a/public/css/iconfont.woff b/public/css/iconfont.woff index e620421e5..a1ebdfd2d 100644 Binary files a/public/css/iconfont.woff and b/public/css/iconfont.woff differ diff --git a/public/css/iconfont.woff2 b/public/css/iconfont.woff2 index 0b85edd71..2f02631b0 100644 Binary files a/public/css/iconfont.woff2 and b/public/css/iconfont.woff2 differ diff --git a/src/App.css b/src/App.css index cf3d5ee41..57580bf85 100644 --- a/src/App.css +++ b/src/App.css @@ -151,12 +151,18 @@ body { width: 1600px; margin: 0 auto; } -.opacity7 { - opacity: 0.7; +.opacity9 { + opacity: 0.9; } .opacity8 { opacity: 0.8; } +.opacity7 { + opacity: 0.7; +} +.opacity6 { + opacity: 0.6; +} .opacity4 { opacity: 0.4; } \ No newline at end of file diff --git a/src/App.js b/src/App.js index a384cd830..b5103caba 100644 --- a/src/App.js +++ b/src/App.js @@ -510,20 +510,6 @@ class App extends Component { {/* 项目标签列表页 */} - ( - - ) - } - /> - ( - - ) - } - /> { @@ -603,6 +589,13 @@ class App extends Component { } }> + ( + + ) + } + /> import("./Main/Index"), + loader: () => import("./projectHome/projectList"), loading: Loading, }); const ProjectHome = Loadable({ - loader: () => import("./Main/projecthome/Index"), + loader: () => import("./projectHome/explore"), loading: Loading, }); @@ -60,7 +60,7 @@ class Index extends Component { )} > ( )} diff --git a/src/forge/Main/projectHomeNew/v2/index.jsx b/src/forge/Main/projectHomeNew/v2/index.jsx index 3bf7dec2e..4abd6c3b0 100644 --- a/src/forge/Main/projectHomeNew/v2/index.jsx +++ b/src/forge/Main/projectHomeNew/v2/index.jsx @@ -52,7 +52,7 @@ function ProjectHomePage(props) { getCate(); // getList(); getCateTopic(); - document.title = '军用开源软件仓库'; + document.title = 'JY开源软件仓库'; // 获取总数 getInitCount(); }, []) @@ -121,7 +121,9 @@ function ProjectHomePage(props) { params.language_id = topicId.split(",") params.topic_id = undefined } - cateID && axios.get(url, { params }).then(result => { + console.log('params', params); + + axios.get(url, { params }).then(result => { if (result && result.data) { setTotal(result.data.total_count); setProjectsList(result.data.projects); @@ -152,7 +154,7 @@ function ProjectHomePage(props) {
-
军用开源软件仓库
+
JY开源软件仓库
汇聚全球顶尖开源力量,构建安全、协同、创新的软件生态,赋能军事数字化转型与智能化升级
diff --git a/src/forge/Main/projecthome/components/Banner.jsx b/src/forge/Main/projecthome/components/Banner.jsx index 7ee4fadff..b6edd86b2 100644 --- a/src/forge/Main/projecthome/components/Banner.jsx +++ b/src/forge/Main/projecthome/components/Banner.jsx @@ -6,7 +6,7 @@ import banner3 from '../../img/home/banner3.webp'; import { Link } from "react-router-dom"; const BANNER_DATA = [ - { key: 1, keyword: '仓库', name: '军用开源软件仓库', title: '军用开源软件仓库', content: '提供软件源码的集中托管与协作、编译构建后的制品统一管理,并支持一键搜索与下载成熟可用的应用程序,为军事软件的全生命周期提供一站式管理与分发服务', img: banner1 }, + { key: 1, keyword: '仓库', name: 'JY开源软件仓库', title: 'JY开源软件仓库', content: '提供软件源码的集中托管与协作、编译构建后的制品统一管理,并支持一键搜索与下载成熟可用的应用程序,为军事软件的全生命周期提供一站式管理与分发服务', img: banner1 }, { key: 2, keyword: '供应链', name: '供应链监测', title: '供应链监测', content: '实现供应链全流程可视化与智能决策。通过实时数据监控、需求预测与风险预警,优化库存与资源配置,助力精准掌控供应链动态,实现降本增效', img: banner2 }, // { key: 3, keyword: '软件工厂', name: '软件工厂专区', title: '软件工厂专区', content: '为您提供从需求到部署的一站式项目工程化管理。通过标准化流程、自动化流水线与统一制品库,赋能团队高效协作、规范交付,全面提升软件生产质量与效率', img: banner3 } ] diff --git a/src/forge/Main/projecthome/components/Factory.jsx b/src/forge/Main/projecthome/components/Factory.jsx index f555bb736..a8911bc0b 100644 --- a/src/forge/Main/projecthome/components/Factory.jsx +++ b/src/forge/Main/projecthome/components/Factory.jsx @@ -71,7 +71,7 @@ function Factory(props) { return (

软件工厂专区

-

面向军用软件开发的高效项目工程化系统管理与平台支撑

+

面向JY软件开发的高效项目工程化系统管理与平台支撑

{ Item1.map((e, index) => { diff --git a/src/forge/Main/projecthome/components/Store.jsx b/src/forge/Main/projecthome/components/Store.jsx index a92724c07..4c68316f6 100644 --- a/src/forge/Main/projecthome/components/Store.jsx +++ b/src/forge/Main/projecthome/components/Store.jsx @@ -49,7 +49,7 @@ function Store(props) { return (
-

军用开源软件仓库

+

JY开源软件仓库

一站式软件资源服务中心

{ diff --git a/src/forge/Main/projecthome/v2/components/banner.jsx b/src/forge/Main/projecthome/v2/components/banner.jsx index aa3b3037c..ba5d2c52c 100644 --- a/src/forge/Main/projecthome/v2/components/banner.jsx +++ b/src/forge/Main/projecthome/v2/components/banner.jsx @@ -1,8 +1,38 @@ import { Divider } from 'antd'; import React from 'react'; -import TerminalAnimation from './terminalAnimation'; +import TerminalAnimation from './terminalAnimation2'; +import ActionItem from '../../../../../factory/resource/components/ActionItem'; function Banner() { + const lines1 = [ + 'if(!isVisible)', + ' return', + '', + 'const interval = ', + 'setInterval(() => {', + ' setActive(prev => {', + ' return prev + 1', + ' });', + '}, 6000);', + '', + 'return () => {', + ' clearInterval', + ' (interval);', + '};', + ]; + + const lines2 = [ + 'const params = {', + ' id: id,', + ' ...values', + '}', + '', + 'addComment(params)', + ' if(res){', + ' reloadComment();', + ' }', + '})', + ] return (
{/* 主要内容区域 */} @@ -19,13 +49,28 @@ function Banner() {
-

持续汇聚多源需求,开放共享可信资源,协同创新核心技术,聚智赋能软件生态

+

持续汇聚多源需求,开放共享可信资源,协同创新核心技术,聚智赋能软件生态

{/* 中央展示图 */} -
- +
+ +
+
+ + + +
+ +
+
+
+ +
+
+ +
- {/* */} + {/* */}
{/* 底部统计数据 */} diff --git a/src/forge/Main/projecthome/v2/components/communityDynamic.jsx b/src/forge/Main/projecthome/v2/components/communityDynamic.jsx index 00f211fdb..5ccee5d7e 100644 --- a/src/forge/Main/projecthome/v2/components/communityDynamic.jsx +++ b/src/forge/Main/projecthome/v2/components/communityDynamic.jsx @@ -53,7 +53,10 @@ const CommunityDynamic = () => {

{firstByList1.summary}

- 了解更多 + + 了解更多 + 了解更多 +
{/* 新闻列表 */} @@ -61,7 +64,7 @@ const CommunityDynamic = () => { {list1.slice(1,5).map((item, index) => (
-
{item.name}
+
{item.name}

{item.summary}

{index < 3 && } @@ -80,7 +83,10 @@ const CommunityDynamic = () => {
    {list2.slice(0,4).map((item, index) => (
  • - {item.summary}{item.tag && {item.tag}} + + {item.summary} + {index === 1 && HOT} + {/* {moment(item.publishTime).format('MM月DD日')} */} {item.name}
  • @@ -97,7 +103,10 @@ const CommunityDynamic = () => {
      {list3.slice(0,4).map((item, index) => (
    • - {item.name}{item.tag && {item.tag}} + + {item.name} + {index === 0 && NEW} + {moment(item.publishTime).format('YYYY-MM-DD')}
    • ))} diff --git a/src/forge/Main/projecthome/v2/components/ecosystemAlliance.jsx b/src/forge/Main/projecthome/v2/components/ecosystemAlliance.jsx index 4f9946b4a..0911e6e4a 100644 --- a/src/forge/Main/projecthome/v2/components/ecosystemAlliance.jsx +++ b/src/forge/Main/projecthome/v2/components/ecosystemAlliance.jsx @@ -9,24 +9,58 @@ const EcosystemAlliance = () => { rootMargin: '0px 0px -50px 0px' }); - const partners = [ - { name: '国防科技大学', logo: require('../image/logo1.png') }, - { name: '航天工程大学', logo: require('../image/logo3.png').default }, - { name: '信息工程大学', logo: require('../image/logo4.png').default }, - { name: '海军工程大学', logo: require('../image/logo5.png') }, - { name: '陆军工程大学', logo: require('../image/logo6.png') }, - { name: '中国电子北京中软', logo: require('../image/logo7.png').default }, - { name: '中国电科第十五研究所', logo: require('../image/logo8.png').default }, - { name: '华为', logo: require('../image/logo2.png') }, - { name: '麒麟', logo: require('../image/logo9.png') }, - { name: '飞腾', logo: require('../image/logo10.png') }, - { name: '阿里云', logo: require('../image/logo11.png') }, - { name: '中国电子云', logo: require('../image/logo12.png') }, - { name: '中国移动云', logo: require('../image/logo13.png').default } - ]; + // const partners = [ + // { name: '国防科技大学', logo: require('../image/logo1.png') }, + // { name: '航天工程大学', logo: require('../image/logo3.png').default }, + // { name: '信息工程大学', logo: require('../image/logo4.png').default }, + // { name: '海军工程大学', logo: require('../image/logo5.png') }, + // { name: '陆军工程大学', logo: require('../image/logo6.png') }, + // { name: '中国电子北京中软', logo: require('../image/logo7.png').default }, + // { name: '中国电科第十五研究所', logo: require('../image/logo8.png').default }, + // { name: '华为', logo: require('../image/logo2.png') }, + // { name: '麒麟', logo: require('../image/logo9.png') }, + // { name: '飞腾', logo: require('../image/logo10.png') }, + // { name: '阿里云', logo: require('../image/logo11.png') }, + // { name: '中国电子云', logo: require('../image/logo12.png') }, + // { name: '中国移动云', logo: require('../image/logo13.png').default } + // ]; // 将合作伙伴数据分成两部分 - const firstRowPartners = partners.slice(0, Math.ceil(partners.length / 2)); - const secondRowPartners = partners.slice(Math.ceil(partners.length / 2)); + // const firstRowPartners = partners.slice(0, Math.ceil(partners.length / 2)); + // const secondRowPartners = partners.slice(Math.ceil(partners.length / 2)); + + const partners1 = [ + {title: "合作高校", children: [ + { name: '国防科技大学', logo: require('../image/logo1.png') }, + { name: '海军工程大学', logo: require('../image/logo5.png').default }, + { name: '南京信息工程大学', logo: require('../image/logo4.png').default }, + { name: '陆军工程大学', logo: require('../image/logo6.png').default }, + { name: '航天工程大学', logo: require('../image/logo3.png').default }, + { name: '信息工程大学', logo: require('../image/logo14.png').default }, + ]}, + {title: "合作企业", children: [ + { name: '中电太极', logo: require('../image/logo7.png').default }, + { name: '中国电科第十五研究所', logo: require('../image/logo8.png').default }, + { name: '华为', logo: require('../image/logo2.png') }, + { name: '阿里云', logo: require('../image/logo11.png') }, + { name: '飞腾', logo: require('../image/logo10.png') }, + { name: '航天706所', logo: require('../image/logo15.png') }, + { name: '麒麟', logo: require('../image/logo9.png') }, + { name: '中国电子云', logo: require('../image/logo12.png') }, + { name: '中国移动云', logo: require('../image/logo13.png').default } + ]}, + {title: "合作社区", children: [ + { name: 'GitLink', logo: require('../image/logo16.png') }, + { name: '红山开源', logo: require('../image/logo17.png') }, + { name: '麒麟社区', logo: require('../image/logo18.png') }, + { name: '鸿蒙社区', logo: require('../image/logo19.png') }, + { name: '鸥栖社区', logo: require('../image/logo20.png') }, + { name: '木兰开源社区', logo: require('../image/logo21.png').default }, + { name: '魔搭社区', logo: require('../image/logo22.png') }, + { name: '魔乐社区', logo: require('../image/logo25.png') }, + { name: '启智社区', logo: require('../image/logo23.png') }, + { name: '欧拉社区', logo: require('../image/logo24.png') }, + ]} + ] // 标签切换处理 const handleTabChange = (tab) => { @@ -48,19 +82,34 @@ const EcosystemAlliance = () => {
-
-
一站式协作平台
-
5G自组网技术联盟是5G自组网技术学术交流平台(非社会团体、非实体机构),由5G自组网领域单位组成,
遵循公开、公平、公正的原则,开展5G自组网技术体制与标准研究制定,促进成员单位深入交流...
- +
+
生态聚力 智创共赢
+
开放协作,与合作伙伴共拓市场蓝海。链接前沿技术,共建智慧产业新生态。赋能合作伙伴,
共筑可持续发展平台
+ +
+ +
+ {partners1.map((i,key)=>{ + return
+
{i.title}
+
+ {i.children.map((partner, index)=>{ + return
+ {partner.name} +
+ })} +
+
+ })}
-
+ + {/*
- {/* 复制两份数据实现无缝循环 */} {[...firstRowPartners, ...firstRowPartners].map((partner, index) => (
@@ -74,7 +123,6 @@ const EcosystemAlliance = () => {
- {/* 复制两份数据实现无缝循环 */}
{[...secondRowPartners, ...secondRowPartners].map((partner, index) => (
@@ -86,7 +134,7 @@ const EcosystemAlliance = () => { ))}
-
+
*/}
); }; diff --git a/src/forge/Main/projecthome/v2/components/terminalAnimation2.jsx b/src/forge/Main/projecthome/v2/components/terminalAnimation2.jsx new file mode 100644 index 000000000..5f5a740c5 --- /dev/null +++ b/src/forge/Main/projecthome/v2/components/terminalAnimation2.jsx @@ -0,0 +1,253 @@ +import React, { useEffect, useRef, useState } from 'react'; + +const TerminalAnimation = ({startAnimation=true, lines, width, height, class_name}) => { + const [animationState, setAnimationState] = useState({ + lineI: 0, + charI: 0, + curOn: true + }); + + const animationRef = useRef(null); + + const keyColor = { + 'git clone': '#fff700', + 'git commit': '#fff700', + 'git log': '#fff700', + 'git merge': '#fff700', + 'git remote': '#fff700', + 'git pull': '#d24a6f', + 'git push': '#d24a6f', + 'git status': '#2977ff', + 'git fetch': '#2977ff', + 'git add': '#9aff41', + 'cd forgeplus': '#9aff41', + 'git checkout': '#9aff41' + }; + + const fontSize = 12; + const lineH = 20; + const startY = 10; + const charGap = 30; + const lineGap = 300; + const lineNumberWidth = 0; // 序号列宽度 + + // 字符宽度估算函数(更准确) + const getCharWidth = (charCount) => charCount * 9.6; + + // 渲染带颜色的文本段 + const renderColoredText = (text, x, y, availableChars) => { + const elements = []; + let currentX = x; + let charsRendered = 0; + + // 按优先级检查关键字 + const sortedKeys = Object.keys(keyColor).sort((a, b) => b.length - a.length); + + let remainingText = text; + + while (remainingText.length > 0 && charsRendered < availableChars) { + let colored = false; + + // 查找匹配的关键字 + for (const key of sortedKeys) { + if (remainingText.startsWith(key)) { + const charsToRender = Math.min(key.length, availableChars - charsRendered); + if (charsToRender > 0) { + const displayText = key.substring(0, charsToRender); + elements.push( + + {displayText} + + ); + currentX += getCharWidth(displayText.length); + charsRendered += charsToRender; + remainingText = remainingText.substring(charsToRender); + colored = true; + } + break; + } + } + + // 如果没找到关键字,渲染普通文本 + if (!colored && remainingText.length > 0) { + const charsToRender = Math.min(1, availableChars - charsRendered); + if (charsToRender > 0) { + const char = remainingText[0]; + elements.push( + + {char} + + ); + currentX += getCharWidth(1); + charsRendered += charsToRender; + remainingText = remainingText.substring(charsToRender); + } + } + + if (charsRendered >= availableChars) break; + } + + return { elements, currentX, charsRendered }; + }; + + // 渲染文本行 +const renderTextSegments = (line, charLimit, y, isCurrentLine, lineIndex) => { + let x = lineNumberWidth; // 从序号列之后开始 + + // 渲染行号 + const lineNumberElement = ( + + {lineIndex + 1}. + + ); + + // 计算可用字符数 + const availableChars = charLimit; + + // 渲染命令部分(直接渲染整行,不再分离提示符) + const { elements: commandElements } = renderColoredText( + line, + x, + y, + availableChars + ); + + const allElements = [...commandElements]; + + // 如果是当前行且需要光标 + if (isCurrentLine && animationState.curOn) { + const cursorX = x + getCharWidth(charLimit); + allElements.push( + + ); + } + + return allElements; +}; + + // 动画逻辑 + useEffect(() => { + if (!startAnimation) { + setAnimationState({ + lineI: 0, + charI: 0, + curOn: true + }); + return; + } + let lastCharTime = Date.now(); + let lastLineTime = Date.now(); + let lastBlinkTime = Date.now(); + + const animate = () => { + const now = Date.now(); + let shouldUpdate = false; + let newState = { ...animationState }; + + // 光标闪烁 + if (now - lastBlinkTime > 500) { + newState.curOn = !newState.curOn; + lastBlinkTime = now; + shouldUpdate = true; + } + + // 第一行字符逐个显示 + if (newState.lineI === 0 && newState.charI < lines[0].length && now - lastCharTime > charGap) { + newState.charI++; + lastCharTime = now; + shouldUpdate = true; + } + // 第一行完成后,后续行整行显示 + else if (newState.lineI === 0 && newState.charI >= lines[0].length && now - lastLineTime > lineGap) { + newState.lineI++; + newState.charI = lines[newState.lineI] ? lines[newState.lineI].length : 0; // 整行显示 + lastLineTime = now; + shouldUpdate = true; + } + // 后续行之间的间隔 + else if (newState.lineI > 0 && newState.lineI < lines.length && now - lastLineTime > lineGap) { + newState.lineI++; + newState.charI = newState.lineI < lines.length ? lines[newState.lineI].length : 0; // 整行显示 + lastLineTime = now; + shouldUpdate = true; + } + + if (shouldUpdate) { + setAnimationState(newState); + } + + animationRef.current = requestAnimationFrame(animate); + }; + + animationRef.current = requestAnimationFrame(animate); + + return () => { + if (animationRef.current) { + cancelAnimationFrame(animationRef.current); + } + }; + }, [animationState, startAnimation]); + + return ( +
+ + {/* 渲染已完成的行 */} + {lines.slice(0, animationState.lineI).map((line, index) => ( + + {renderTextSegments(line, line.length, startY + index * lineH, false, index)} + + ))} + + {/* 渲染当前正在输入的行 */} + {animationState.lineI < lines.length && ( + + {renderTextSegments(lines[animationState.lineI], animationState.charI, startY + animationState.lineI * lineH, true, animationState.lineI)} + + )} + +
+ ); +}; + +export default TerminalAnimation; \ No newline at end of file diff --git a/src/forge/Main/projecthome/v2/image/banner-bk.png b/src/forge/Main/projecthome/v2/image/banner-bk.png new file mode 100644 index 000000000..98c0cd059 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/banner-bk.png differ diff --git a/src/forge/Main/projecthome/v2/image/bk3.png b/src/forge/Main/projecthome/v2/image/bk3.png index 324e291bb..348151216 100644 Binary files a/src/forge/Main/projecthome/v2/image/bk3.png and b/src/forge/Main/projecthome/v2/image/bk3.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo1.png b/src/forge/Main/projecthome/v2/image/logo1.png index fb54b446b..ee7e73798 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo1.png and b/src/forge/Main/projecthome/v2/image/logo1.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo14.png b/src/forge/Main/projecthome/v2/image/logo14.png new file mode 100644 index 000000000..3f88b694b Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo14.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo15.png b/src/forge/Main/projecthome/v2/image/logo15.png new file mode 100644 index 000000000..9295745c3 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo15.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo16.png b/src/forge/Main/projecthome/v2/image/logo16.png new file mode 100644 index 000000000..a9ebc2eb9 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo16.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo17.png b/src/forge/Main/projecthome/v2/image/logo17.png new file mode 100644 index 000000000..e8fc22e8d Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo17.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo18.png b/src/forge/Main/projecthome/v2/image/logo18.png new file mode 100644 index 000000000..9ceb98c22 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo18.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo19.png b/src/forge/Main/projecthome/v2/image/logo19.png new file mode 100644 index 000000000..6d9cff593 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo19.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo20.png b/src/forge/Main/projecthome/v2/image/logo20.png new file mode 100644 index 000000000..1009dcc9b Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo20.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo21.png b/src/forge/Main/projecthome/v2/image/logo21.png new file mode 100644 index 000000000..101c478f3 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo21.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo22.png b/src/forge/Main/projecthome/v2/image/logo22.png new file mode 100644 index 000000000..305640ae2 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo22.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo23.png b/src/forge/Main/projecthome/v2/image/logo23.png new file mode 100644 index 000000000..f51c0dfb9 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo23.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo24.png b/src/forge/Main/projecthome/v2/image/logo24.png new file mode 100644 index 000000000..cdf588f54 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo24.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo25.png b/src/forge/Main/projecthome/v2/image/logo25.png new file mode 100644 index 000000000..a2c525858 Binary files /dev/null and b/src/forge/Main/projecthome/v2/image/logo25.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo3.png b/src/forge/Main/projecthome/v2/image/logo3.png index f7e5ae8f5..fd30447a1 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo3.png and b/src/forge/Main/projecthome/v2/image/logo3.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo4.png b/src/forge/Main/projecthome/v2/image/logo4.png index ef72c221b..ebd4a7293 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo4.png and b/src/forge/Main/projecthome/v2/image/logo4.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo5.png b/src/forge/Main/projecthome/v2/image/logo5.png index 005527723..a2d776615 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo5.png and b/src/forge/Main/projecthome/v2/image/logo5.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo6.png b/src/forge/Main/projecthome/v2/image/logo6.png index fea024463..da36b1ca8 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo6.png and b/src/forge/Main/projecthome/v2/image/logo6.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo7.png b/src/forge/Main/projecthome/v2/image/logo7.png index d93c03009..ceaab84cd 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo7.png and b/src/forge/Main/projecthome/v2/image/logo7.png differ diff --git a/src/forge/Main/projecthome/v2/image/logo8.png b/src/forge/Main/projecthome/v2/image/logo8.png index 276b55e80..43dd51aa6 100644 Binary files a/src/forge/Main/projecthome/v2/image/logo8.png and b/src/forge/Main/projecthome/v2/image/logo8.png differ diff --git a/src/forge/Main/projecthome/v2/index.scss b/src/forge/Main/projecthome/v2/index.scss index 5ee50fe3e..1bbaf92af 100644 --- a/src/forge/Main/projecthome/v2/index.scss +++ b/src/forge/Main/projecthome/v2/index.scss @@ -9,6 +9,10 @@ color: #091221; font-family: "alibabaReg"; + a:not(.blackBut):hover, a:not(.blackBut):focus{ + color: #2149d4; + } + .title_v2 { font-family: 'DouyinSansBold'; font-size: 40px; @@ -27,11 +31,39 @@ border: none; height: 36px; line-height: 36px; + overflow: hidden; + -webkit-backdrop-filter: blur(24px); + backdrop-filter: blur(24px); + transition: background-color .4s ease-in-out; + position: relative; + &::before{ + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(120deg, rgba(255,255,255,0)0%, rgba(255,255,255,0.5)50%,rgba(255,255,255,0)100%); + transition: left 0.5s ease-in-out; + transition-delay: 0.5s; + } &.white { background-color: #ffffff; color: #091221; } + span{ + display: block; + transition: transform 0.5s; + } + &:hover{ + span{ + transform: translateY(-36px); + } + &::before{ + left: 100%; + } + } } .but-to-right { @@ -58,6 +90,39 @@ } } + // 标题悬停:下划线从左到右滑出 + .title-border-to-right{ + display: inline-block; + max-width: 100%; + position: relative; + &::after{ + position: absolute; + bottom: 0; + left: 0; + content: ''; + width: 0; + height: 1px; + background-color: #2149d4; + transition: all 0.5s ease; + } + &:hover{ + padding-right: 25px; + &+.hot-tag{ + display: none; + } + } + &:hover::after{ + width: 100%; + } + &:hover::before{ + content: "\e9c4"; + font-family: 'iconfont'; + font-weight: normal; + position: absolute; + right: 0; + } + } + } .banner_v2 { @@ -149,6 +214,81 @@ font-family: "ziyouwenyihei"; } } + .center-image-container{ + position: relative; + .center-left-bk{ + background-image:linear-gradient(91.39deg,rgba(255, 255, 255, 0.04) 0%,rgba(255, 255, 255, 0.05) 30%,rgba(255, 255, 255, 0.15) 100%); + border-radius:15px; + padding: 10px; + position: absolute; + top: 15%; + left: 8%; + } + .center-left-code{ + border-radius: 10px; + position: relative; + padding: 20px; + &::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: inherit; + padding: 2px; + background: linear-gradient(90deg, #434C9F 0%, rgba(255, 255, 255, 0) 100%); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + mask-composite: exclude; + } + } + .center-right-bk{ + background-image:linear-gradient(178.97deg,rgba(91, 99, 187, 0.23) 0%,rgba(78, 87, 171, 0.14) 13.39%,rgba(255, 255, 255, 0) 100%); + border-radius:0px 15px 15px 15px; + padding: 10px; + position: absolute; + bottom: 8%; + right: 9.5%; + } + } + .center-1-bk-wrapper{ + display: inline-block; + &:before { + animation-delay: 1s; + animation: rotate 8s linear infinite; + background: conic-gradient( + from 180deg at 50% 50%, + #e3ffca 0deg, + #43bfff 45deg, + transparent 90deg, + transparent 180deg, + #e3ffca 180deg, + #43bfff 225deg, + transparent 270deg + ); + z-index: 0; + } + } + .center-1-bk{ + + width:866px; + height:512px; + border-radius:15px; + background-image: url('./image/banner-bk.png'); + background-size: 100% 100%; + .center-1-circle{ + display: inline-block; + width: 12px; + height: 12px; + border-radius: 50%; + background-color:#ffffff; + &.active{ + background-color:#e5caff; + } + } + } } .community-dynamic { @@ -509,8 +649,9 @@ .ecosystem-alliance { background-image: url('./image/bk3.png'); - background-size: 100% 100%; - padding: 60px 20px; + background-size: 100% auto; + background-repeat: no-repeat; + padding: 90px 20px 60px 20px; .tabs_v2 { display: inline-block; @@ -597,6 +738,23 @@ } } } + .partner1-list{ + gap: 20px; + display: grid; + grid-template-columns: repeat(5, 1fr); + + .partner1-item { + height: 101px; + background-color: #ffffff; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + img{ + max-width: 80%; + } + } + } } .open-source-collaboration-container { diff --git a/src/forge/projectHome/explore/index.jsx b/src/forge/projectHome/explore/index.jsx new file mode 100644 index 000000000..bc9362859 --- /dev/null +++ b/src/forge/projectHome/explore/index.jsx @@ -0,0 +1,296 @@ +import React, { useEffect, useState } from "react"; +import axios from "axios"; +import { Button, Divider, Input, Pagination, Popover, Spin, Tooltip } from "antd"; +import { Link } from "react-router-dom"; +import Nodata from "../../Nodata"; +import { getImageUrl } from "../../../common/UrlTool"; +import { TPMIndexHOC } from "../../../modules/tpm/TPMIndexHOC"; +import RenderHtml from "../../../components/render-html"; +import FeedBack from "../../../forge/Component/feedBack"; +import './index.scss'; +import ActionItem from "../../../factory/resource/components/ActionItem"; +const { Search } = Input; +function ProjectHomePage(props) { + const [cateList, setCateList] = useState(undefined); + const [projectsList, setProjectsList] = useState(undefined); + const [search, setSearch] = useState(undefined); + const [cateID, setCateID] = useState(undefined); + const [isSpin, setIsSpin] = useState(true); + const [monthList, setMonthList] = useState(undefined); + const [total, setTotal] = useState(0); + const [page, setPage] = useState(1); + const [cateTopics, setCateTopics] = useState(undefined); + const [topicId, setTopicId] = useState(undefined); + const [topicDetail, setTopicDetail] = useState(undefined); + const [count, setCount] = useState({}); + const { countByGHM, countByOther, countByGHMType, countByMX, countByRQ } = count; + // const topicsByCateId = cateTopics && cateTopics[cateID]; + const topicsByCateId = cateTopics && cateTopics[cateID] || [ + { + "id": "1,2", + "name": "Maven", + "icon": "icon-maven", + "intro": "配置使用本站maven仓库,首先请定位 **settings.xml** 文件,通常位于本地 Maven 安装目录的 **conf/settings.xml** 或用户目录下的 **m2/settings.xml**。\n\n然后,在`settings.xml`​文件中` `​ 标签中添加私有仓库地址:\n\n```xml\n\n \n xzgd-repo-mirror\n *\n http://172.16.6.110:8081/repository/maven-repo/\n \n\n```\n\n\n在`settings.xml`​文件中``​标签中添加以下内容:\n\n\n```xml\n \n \n xzgd-maven-mirror-profile\n \n \n xzgd-maven-mirror\n http://172.16.6.110:8081/repository/maven-repo/\n \n \n \n \n xzgd-maven-mirror\n http://172.16.6.110:8081/repository/maven-repo/ \n \n \n \n\n```\n\n在`settings.xml`​文件中``​标签中添加以下内容:\n\n```xml\n\n xzgd-maven-mirror-profile\n\n```\n" + }, + { + "id": "2,4", + "name": "Python", + "icon": "icon-python", + "intro": "**方法一**:通过命令配置\n\n运行以下命令:\n```xml\npip config set global.index-url https://mirrors.aliyun.com/pypi/simple\npip config set install.trusted-host mirrors.aliyun.com\n```\n\n**方法二**:手动修改配置文件\n\n根据操作系统不同,修改 pip 配置文件:\n\n**Windows** 在用户目录下创建或编辑 pip.ini 文件(路径如:C:\\Users\\<用户名>\\pip\\pip.ini),内容如下:\n```xml\n[global]\nindex-url = https://mirrors.aliyun.com/pypi/simple/\n[install]\ntrusted-host = mirrors.aliyun.com\n```\n\n**Linux/Mac** 编辑或创建 ~/.config/pip/pip.conf 文件,内容如下:\n```xml\n[global]\nindex-url = https://mirrors.aliyun.com/pypi/simple\n[install]\ntrusted-host = mirrors.aliyun.com\n```\n\n验证配置,运行以下命令检查是否成功:\n```xml\npip config list\n```" + }, + { + "id": "4,5", + "name": "Npm", + "icon": "icon-npm", + "intro": "通过使用npm config set registry命令切换npm的镜像源\n\n使用示例:\n可以在命令行工具中输入以下命令:\n```xml\nnpm config set registry https://registry.npm.taobao.org\n```\n\n切换镜像源后,可以通过以下命令验证是否切换成功:\n```xml\nnpm config get registry\n```\n\n如果输出结果显示镜像源已切换到淘宝的npm镜像源,则表示切换成功。" + } + ]; + + const topicsLength = topicsByCateId && topicsByCateId.length + const LIMIT = !topicsLength ? 30 : 25; + + useEffect(() => { + getCate(); + // getList(); + getCateTopic(); + document.title = 'JY开源软件仓库'; + // 获取总数 + getInitCount(); + }, []) + + useEffect(() => { + setIsSpin(true); + getProject(); + }, [cateID, search, page, topicId]) + + function getInitCount() { + const obj = { + countByGHM: 20000, + countByOther: 0, + countByGHMType: 10 + } + axios.get(`/organizations/gh_mirrors/projects.json?page=1&limit=15&sort_by=updated_on&sort_direction=desc`).then(result => { + if (result && result.data) { + obj.countByGHM = result.data.total_count || 0 + } + return axios.get(`/projects.json?pinned=d&limit=1`) + }).then(result => { + if (result && result.data) { + obj.countByOther = result.data.total_count - obj.countByGHM + } + }).finally(() => { + // cateTopics && cateTopics[39] && (obj.countByGHMType = cateTopics[39].length) + setCount({ + countByGHM: 20000, + countByOther: obj.countByOther, + countByGHMType: 10, + countByMX: 99, + countByRQ: 10 + }); + }) + } + + function getCateTopic() { + fetch('/cate_topic.json').then(r => r.json()).then(res => { + setCateTopics(res); + }); + } + + function getCate() { + const url = `/project_categories/pinned_index.json`; + axios.get(url).then(result => { + if (result && result.data) { + const { project_categories = [] } = result.data; + setCateList(project_categories); + // project_categories[0] && setCateID(project_categories[0].id); + } + }).catch(error => { }) + } + + function getProject() { + const url = `/projects.json`; + let params = { + pinned: "d", + category_id: cateID, + limit: LIMIT, + search: search, + page: page, + topic_id: topicId, + sort_by: cateID ? undefined : "praises_count", + language_id: undefined + }; + if (cateID === 39 && topicId) { + // 三方组件,topicId要作为language_id参数进行查询,查询maven、python、npm的语言仓库列表 + params.language_id = topicId.split(",") + params.topic_id = undefined + } + console.log('params', params); + + axios.get(url, { params }).then(result => { + if (result && result.data) { + setTotal(result.data.total_count); + setProjectsList(result.data.projects); + setIsSpin(false); + } + }).catch(error => { }) + } + + function getList() { + // const url = `/project_rank.json`; + const url = `/projects/banner_recommend.json` + axios.get(url, { + // params: { + // time: 30, + // page: 1, + // limit: 16 + // } + }).then(result => { + if (result && result.data) { + setMonthList(result.data.projects); + } + }).catch(error => { }) + } + + return
+ {/* banner区域内容 */} +
+
开源软件仓库·护航J事数智
+
汇聚全球顶尖开源力量,构建安全、协同、创新的软件生态,赋能J事数字化转型与智能化升级
+
+
+
+

{countByOther}+

+ 应用软件 +
+ +
+

{countByGHMType}+

+ 三方组件 +
+ +
+

{countByGHM}+

+ 数据集 +
+ +
+

{countByMX}+

+ 智能模型 +
+ +
+

{countByRQ}+

+ 容器镜像 +
+
+
+
反馈需求,共建优质体验
+
欢迎大家随时通过官方渠道提出宝贵建议
+ +
+
+
+
+
+
+
+ 软件分类: + {cateList && !!cateList.length && cateList.map(cate => { + const isActive = cate.id === cateID; + return { setPage(1); setCateID(cate.id); setTopicId(undefined) }}>{cate.name} + })} +
+
+ +
+ {topicsByCateId && !!topicsByCateId.length &&
+
    +
  • { setPage(1); setTopicId(undefined) }}> + + 全部类别 +
  • + {topicsByCateId.map((item, index) => { + const uniqueKey = `${cateID}-${index}`; + const isActive = item.id === topicId; + const imageName = `${item.icon}${isActive ? '-1' : ''}.png`; + + return
  • { setPage(1); setTopicId(item.id); setTopicDetail(item) }}> + + {item.name} +
  • + })} +
+
} +
+ {/* 推荐仓库 */} +
推荐仓库
+
+ { setPage(1); setSearch(value); }} + className="mlat custom-search" + style={{ width: "320px", marginLeft: "auto", height: "32px", marginTop: "8px" }} + allowClear + /> +
+ + {projectsList && !!projectsList.length ?
+ {projectsList.map(i => { + const url = i.author ? `/${i.author.login}/${i.identifier}${i.author.login === "gh_mirrors" ? "/about" : "/about"}` : `` + return
+
+ {i.lesson_url && } + {!i.lesson_url && } +
+
{i.name}
+ {/* 项目标签 */} + {i.topics &&
+ {/* {i.author && i.author.login === "gh_mirrors" && i.topics && !i.topics.length && 华中科技大学} */} + {i.topics.slice(0, 2).map(item => {item.name})} +
} +
+
+ {/* {i.description && +
+ {i.description} +
+
} */} + {i.author && i.author.login !== "gh_mirrors" && 下载} + +
+ })} +
: } +
+ {cateID && { setPage(page) }} className='center mt30' />} +
+
+
+ {/* 二级分类以及仓库列表(左右布局) */} +
+ {/* 二级分类,即标签列表 */} + + {/* 项目列表 */} +
+ {/* 三方组件下的提示信息
*/} + {cateID === 39 && topicId && topicDetail && topicDetail.intro && trigger.parentNode} + content={ +
+ +
+ } + trigger="click" + placement="bottomLeft" + overlayClassName="tipByCate_Popover" + > +
{`设置${topicDetail.name}包管理器仓库地址,`}查看更多
+
} + +
+
+
+
+} + +export default ProjectHomePage \ No newline at end of file diff --git a/src/forge/projectHome/explore/index.scss b/src/forge/projectHome/explore/index.scss new file mode 100644 index 000000000..47273f809 --- /dev/null +++ b/src/forge/projectHome/explore/index.scss @@ -0,0 +1,226 @@ +.homepage-box { + font-family: "alibabaReg"; + color: #091221; + background-image: url('../image/banner.png'); + background-size: 100% auto; + background-repeat: no-repeat; + background-color: #f1f6fd; + padding-bottom: 200px; + + .p_h_title { + font-family: "DouyinSansBold"; + letter-spacing: 4px; + line-height: normal; + } + + .p_h_title_text { + background-image: linear-gradient(313.07deg, #eda62a 0%, #352eff 46.85%, #091221 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + .project_count { + padding: 0 80px; + height: 145px; + background-image: url('../image/bk4.png'); + background-size: 100% 100%; + + .ant-divider-vertical { + height: 52px; + background-color: rgba(255, 255, 255, 0.3); + } + + .project_count_item p { + font-size: 30px; + font-family: "YouSheBiaoTiHei"; + line-height: normal; + } + } + + .feedBackBox { + padding: 17px 30px; + background-image: linear-gradient(145.03deg, #f2e8e9 0%, #f2e8e9 19.38%, #a7b0ff 76.71%, #b3a7ff 100%); + border-radius: 15px; + } + + .needApplyBut { + display: inline-block; + width: 83px; + height: 32px; + border: 1px solid #091221; + border-radius: 18px; + text-align: center; + line-height: 32px; + color: #091221; + transition: all 0.3s ease; + + &:hover, + &:active, + &:focus { + color: #ffffff; + background-color: #091221; + } + } + + .homepage_content_v3 { + background-image: linear-gradient(179.88deg, #ffffff 0%, #F3F7FD 100%); + border-radius: 40px 40px 0 0; + + .cate_list_box { + display: flex; + gap: 15px; + flex-wrap: wrap; + } + + .cate_item { + cursor: pointer; + padding: 2px 25px; + background-color: #f5f7fb; + border-radius: 16px; + + &.active { + font-weight: normal; + font-size: 16px; + color: #ffffff; + background-color: #091221; + } + } + + .left_cate2 { + width: 200px; + background-color: #ffffff; + border-radius: 10px; + box-shadow: 0px 0px 6px rgba(92, 102, 193, 0.05); + padding: 25px 10px; + + li { + color: #42464e; + font-size: 16px; + padding: 10px 20px; + cursor: pointer; + + &.active { + background-color: #f7f9fd; + border-radius: 6px; + font-weight: bold; + } + } + } + + .home_project_list { + flex-wrap: wrap; + gap: 15px; + + &.sixItemBox { + .home_project { + flex: 0 0 calc(16.6% - 13px); + } + } + + .home_project { + padding: 20px 20px 60px 20px; + flex: 0 0 calc(20% - 13px); + background-color:#ffffff; + border-radius:8px; + display: flex; + flex-direction: column; + justify-content: space-between; + width: 0; + background-image: url('../image/bk5.png'); + background-size: 100% 100%; + border:1px solid transparent; + position: relative; + box-shadow: 0 0 12px rgba(92, 102, 193, 0.05); + + .task-hide-2 { + word-break: break-all; + } + + .color-424 { + color: #42464e; + } + + .a-i-center { + align-items: center; + } + + .author_img { + width: 54px; + height: 54px; + margin-right: 15px; + border-radius: 6px; + } + + .download-icon { + color:#8284a4; + position: absolute; + bottom: 10px; + } + + .hover-light.color-grey-6, + .hover-light.color-grey-6 a { + color: #666 !important; + } + + &:hover { + border-color:#2149d4; + } + + .proListTopics { + display: flex; + + .proListTopic { + background-color:#f7f9fd; + border-radius: 4px; + max-width: 158px; + padding: 0 10px; + height: 22px; + line-height: 22px; + color: #737a87; + &:first-of-type{ + color:#2149d4; + background-color:rgba(33, 73, 212, 0.05); + } + } + } + .detail-but-black{ + width: 88%; + color:#ffffff; + background-color:#2149d4; + border: none; + display: none; + position: absolute; + bottom: 10px; + } + &:hover{ + .download-icon{ + display: none; + } + .detail-but-black{ + display: block; + } + .detail-but-black::after{ + content: ''; + position: absolute; + top: 0; + left: -150%; + width: 100%; + height: 100%; + background: linear-gradient(120deg, rgba(255,255,255,0)0%, rgba(255,255,255,0.5)50%,rgba(255,255,255,0)100%); + animation: flowLight 0.5s ease-in-out; + } + } + } + } + } +} + +@keyframes flowLight { + 0% { + left: -150%; + } + + 100% { + left: 100%; + } +} \ No newline at end of file diff --git a/src/forge/projectHome/image/banner.png b/src/forge/projectHome/image/banner.png new file mode 100644 index 000000000..15ab89f34 Binary files /dev/null and b/src/forge/projectHome/image/banner.png differ diff --git a/src/forge/projectHome/image/bk1.png b/src/forge/projectHome/image/bk1.png new file mode 100644 index 000000000..b061dc6f2 Binary files /dev/null and b/src/forge/projectHome/image/bk1.png differ diff --git a/src/forge/projectHome/image/bk2.png b/src/forge/projectHome/image/bk2.png new file mode 100644 index 000000000..991602b66 Binary files /dev/null and b/src/forge/projectHome/image/bk2.png differ diff --git a/src/forge/projectHome/image/bk3.png b/src/forge/projectHome/image/bk3.png new file mode 100644 index 000000000..5a6f9cb7b Binary files /dev/null and b/src/forge/projectHome/image/bk3.png differ diff --git a/src/forge/projectHome/image/bk4.png b/src/forge/projectHome/image/bk4.png new file mode 100644 index 000000000..4de2bbbe2 Binary files /dev/null and b/src/forge/projectHome/image/bk4.png differ diff --git a/src/forge/projectHome/image/bk5.png b/src/forge/projectHome/image/bk5.png new file mode 100644 index 000000000..615f75cca Binary files /dev/null and b/src/forge/projectHome/image/bk5.png differ diff --git a/src/forge/projectHome/image/icon1.png b/src/forge/projectHome/image/icon1.png new file mode 100644 index 000000000..ba96e2a7d Binary files /dev/null and b/src/forge/projectHome/image/icon1.png differ diff --git a/src/forge/projectHome/image/icon10.png b/src/forge/projectHome/image/icon10.png new file mode 100644 index 000000000..4e06c6dea Binary files /dev/null and b/src/forge/projectHome/image/icon10.png differ diff --git a/src/forge/projectHome/image/icon11.png b/src/forge/projectHome/image/icon11.png new file mode 100644 index 000000000..04d13aaf0 Binary files /dev/null and b/src/forge/projectHome/image/icon11.png differ diff --git a/src/forge/projectHome/image/icon12.png b/src/forge/projectHome/image/icon12.png new file mode 100644 index 000000000..9410e299f Binary files /dev/null and b/src/forge/projectHome/image/icon12.png differ diff --git a/src/forge/projectHome/image/icon13.png b/src/forge/projectHome/image/icon13.png new file mode 100644 index 000000000..e48c1628e Binary files /dev/null and b/src/forge/projectHome/image/icon13.png differ diff --git a/src/forge/projectHome/image/icon14.png b/src/forge/projectHome/image/icon14.png new file mode 100644 index 000000000..74b08edc6 Binary files /dev/null and b/src/forge/projectHome/image/icon14.png differ diff --git a/src/forge/projectHome/image/icon2.png b/src/forge/projectHome/image/icon2.png new file mode 100644 index 000000000..1e5fa2bd1 Binary files /dev/null and b/src/forge/projectHome/image/icon2.png differ diff --git a/src/forge/projectHome/image/icon3.png b/src/forge/projectHome/image/icon3.png new file mode 100644 index 000000000..c866a4a87 Binary files /dev/null and b/src/forge/projectHome/image/icon3.png differ diff --git a/src/forge/projectHome/image/icon4.png b/src/forge/projectHome/image/icon4.png new file mode 100644 index 000000000..2dec4a133 Binary files /dev/null and b/src/forge/projectHome/image/icon4.png differ diff --git a/src/forge/projectHome/image/icon5.png b/src/forge/projectHome/image/icon5.png new file mode 100644 index 000000000..6384a0680 Binary files /dev/null and b/src/forge/projectHome/image/icon5.png differ diff --git a/src/forge/projectHome/image/icon6.png b/src/forge/projectHome/image/icon6.png new file mode 100644 index 000000000..d43f1507c Binary files /dev/null and b/src/forge/projectHome/image/icon6.png differ diff --git a/src/forge/projectHome/image/icon7.png b/src/forge/projectHome/image/icon7.png new file mode 100644 index 000000000..1e4cf6fc5 Binary files /dev/null and b/src/forge/projectHome/image/icon7.png differ diff --git a/src/forge/projectHome/image/icon8.png b/src/forge/projectHome/image/icon8.png new file mode 100644 index 000000000..9085111a9 Binary files /dev/null and b/src/forge/projectHome/image/icon8.png differ diff --git a/src/forge/projectHome/image/icon9.png b/src/forge/projectHome/image/icon9.png new file mode 100644 index 000000000..d27a21468 Binary files /dev/null and b/src/forge/projectHome/image/icon9.png differ diff --git a/src/forge/projectHome/image/pro_item1.png b/src/forge/projectHome/image/pro_item1.png new file mode 100644 index 000000000..e88eb9f36 Binary files /dev/null and b/src/forge/projectHome/image/pro_item1.png differ diff --git a/src/forge/projectHome/image/pro_item2.png b/src/forge/projectHome/image/pro_item2.png new file mode 100644 index 000000000..700fdc4cb Binary files /dev/null and b/src/forge/projectHome/image/pro_item2.png differ diff --git a/src/forge/projectHome/image/pro_item3.png b/src/forge/projectHome/image/pro_item3.png new file mode 100644 index 000000000..7648ef30d Binary files /dev/null and b/src/forge/projectHome/image/pro_item3.png differ diff --git a/src/forge/projectHome/projectList/index.jsx b/src/forge/projectHome/projectList/index.jsx new file mode 100644 index 000000000..987fa1d64 --- /dev/null +++ b/src/forge/projectHome/projectList/index.jsx @@ -0,0 +1,262 @@ +import React, { Fragment, useEffect, useState } from "react"; +import './index.scss' +import { Badge, Collapse, Divider, Input, Pagination, Tooltip, Spin } from "antd"; +import axios from "axios"; +import { Link } from "react-router-dom"; +import { getImageUrl, timeAgo } from "educoder"; +import Nodata from "../../Nodata"; +const { Panel } = Collapse; + +// 开源协作首页 +function ProjectList() { + const LIMIT = 10; + const [cateList, setCateList] = useState([]); + const [projectsList, setProjectsList] = useState([]); + const [searchValue, setSearchValue] = useState(undefined); + const [search, setSearch] = useState(undefined); + const [cateID, setCateID] = useState(undefined); + const [isSpin, setIsSpin] = useState(true); + const [bannerActiveId, setBannerActiveId] = useState(undefined); + const [bannerProjects, setBannerProjects] = useState([]); + const [total, setTotal] = useState(0); + const [page, setPage] = useState(1); + const [userList, setUserList] = useState([]); + const [projectsListByHot, setProjectsListByHot] = useState([]); + const [hotTime, setHotTime] = useState(7); + + const bannerProjects2 = bannerProjects.slice(4, 7); + console.log('bannerProjects2', bannerProjects2, bannerProjects); + + useEffect(() => { + getCate(); + getList(); + getUserList(); + document.title = `开源协作` + }, []) + + useEffect(() => { + setIsSpin(true); + getProject(); + }, [cateID, search, page]) + + useEffect(() => { + axios.get(`/project_rank.json`, { params: { time: hotTime } }).then(result => { + if (result && result.data) { + setProjectsListByHot(result.data.projects); + } + }).catch(error => { }) + }, [hotTime]) + + function getCate() { + const url = `/project_categories/pinned_index.json`; + axios.get(url).then(result => { + if (result && result.data) { + setCateList(result.data.project_categories); + } + }).catch(error => { }) + } + + function getList() { + axios.get(`/projects/banner_recommend.json`).then(result => { + if (result && result.data) { + setBannerProjects(result.data.projects); + if (result.data.projects[0]) { + setBannerActiveId(result.data.projects[1].id) + } + } + }).catch(error => { }) + } + + function getUserList() { + axios.get(`/user_rank.json`, { params: { time: 7 } }).then(result => { + if (result && result.data) { + setUserList(result.data.users); + } + }).catch(error => { }) + } + + function getProject() { + const url = `/projects.json`; + let params = { + pinned: "d", + category_id: cateID, + limit: LIMIT, + search: search, + page: page, + sort_by: cateID ? undefined : "praises_count", + language_id: undefined + }; + axios.get(url, { params }).then(result => { + if (result && result.data) { + setTotal(result.data.total_count); + setProjectsList(result.data.projects); + setIsSpin(false); + } + }).catch(error => { }) + } + + const bannerProject = (detail) => { + return
+ 66 +
{detail.author.name}/{detail.name}
+
{detail.description}
+
+ } + return
+ {/* 推荐仓库 */} +
+
开源协作·共建生态
+ {setSearchValue(e.target.value)}} suffix={{setSearch(searchValue)}}> + + } onSearch={(value)=>{ + setSearch(value) + }}/> + + + {bannerProjects[0] &&
+ + {bannerProject(bannerProjects[0])} +
+ {bannerProjects[0].author && } +
+
} + {bannerProjects[1] &&
+ {bannerProject(bannerProjects[1])} + {bannerProjects[1].author && } + +
} + {bannerProjects[2] &&
+ {bannerProject(bannerProjects[2])} +
+ {bannerProjects[2].author && } +
+ +
} + {bannerProjects[3] &&
+ {bannerProject(bannerProjects[3])} + {bannerProjects[3].author && } + +
} +
+ {/* 推荐仓库列表一行三个 */} + {bannerProjects2 && !!bannerProjects2.length &&
+ {bannerProjects2.map((i, index) => { + const url = i.author ? `/${i.author.login}/${i.identifier}${i.author.login === "gh_mirrors" ? "/about" : "/about"}` : `` + const { author = {} } = i; + return
+ {i.topics &&
+ {i.topics.map(item => {item.name})} +
} +
{author.name}/{i.name}
+ {i.description && +
+ {i.description} +
+
} + {author &&
+ {author.image_url && } + {author.name}   + {timeAgo(i.updated_on)}更新 + {(i.parises_count > 0 || i.forked_count > 0) && } + {/* 点赞数 */} + {i.parises_count > 0 ? {i.parises_count} : ""} + {/* fork数 */} + {i.forked_count > 0 ? {i.forked_count} : ""} +
} +
+ })} +
} + + {/* 项目列表 */} +
+
+
+ {setPage(1); setCateID(undefined) }}>最近更新 + {cateList.map(cate => { + const isActive = cate.id === cateID; + return {setPage(1); setCateID(cate.id) }}>{cate.name} + })} +
+
+
+
+
开源项目
+
+ + {projectsList.map(i => { + const { author = {} } = i; + const url = i.author ? `/${i.author.login}/${i.identifier}${i.author.login === "gh_mirrors" ? "/about" : "/about"}` : `` + return
+
+
+ {author.image_url && } + {author.name}/{i.name} +
+ + {/* 点赞数 */} + {i.praises_count > 0 ? 赞{i.praises_count} : ""} + {/* fork数 */} + {i.forked_count > 0 ? fork{i.forked_count} : ""} + +
+
+ {i.description} +
+
+ {i.language && + + {i.language.name} + } + {timeAgo(i.last_update_time)}更新 +
+ +
+ })} + {!isSpin && projectsList && !projectsList.length &&
} +
+
+ { setPage(page) }} className='center mt10' /> +
+
+ {/* 热门开发者 */} +
+
+ + 热门开发者 +
+ {userList.map(user => { + return
+ + {user.name} +
+ })} +
+ {/* 热门项目 */} +
+
+ + 热门项目 + + {[{ key: 7, name: "本周" }, { key: 31, name: "本月" }].map((item, index) => { + return + setHotTime(item.key)}>{item.name} + {index < 1 && } + + })} + +
+ + {projectsListByHot.map(project => { + return +
{project.description || '暂无数据'}
+
+ })} +
+
+
+
+
+
+} + +export default ProjectList; \ No newline at end of file diff --git a/src/forge/projectHome/projectList/index.scss b/src/forge/projectHome/projectList/index.scss new file mode 100644 index 000000000..205f545f2 --- /dev/null +++ b/src/forge/projectHome/projectList/index.scss @@ -0,0 +1,433 @@ +.project_home { + font-family: "alibabaReg"; + color: #091221; + background-color: #f1f6fd; + background-image: url('../image/bk1.png'); + background-size: 100% auto; + background-repeat: no-repeat; + + a:hover { + color: #2149d4; + } + + // 标题悬停:下划线从左到右滑出 + .title-border-to-right { + display: inline-block; + max-width: 100%; + position: relative; + + &::after { + position: absolute; + bottom: 0; + left: 0; + content: ''; + width: 0; + height: 1px; + background-color: #2149d4; + transition: all 0.5s ease; + } + + &:hover { + padding-right: 30px; + + &+.hot-tag { + display: none; + } + } + + &:hover::after { + width: 100%; + } + + &:hover::before { + content: "\e9c4"; + font-family: 'iconfont'; + font-weight: normal; + position: absolute; + right: 0px; + font-size: 16px; + top: 5px; + } + } + + .author_img { + width: 24px; + height: 24px; + border-radius: 50%; + } + + .p_h_title { + font-family: "DouyinSansBold"; + letter-spacing: 4px; + } + + .p_h_title_text { + background-image: linear-gradient(313.07deg, #27d1ff 0%, #352eff 46.85%, #091221 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + + .search_p_h { + width: 660px; + height: 52px; + + .ant-input { + padding-left: 20px; + border-radius: 26px; + border: none; + color: #091221; + &:focus::placeholder{ + opacity: 0.6; + } + + &::placeholder { + color: #091221; + } + } + + .ant-input-search-icon { + display: none; + } + + .search_icon { + width: 32px; + height: 32px; + background-color: #091221; + border-radius: 50%; + color: white; + text-align: center; + line-height: 32px; + } + } + + .project_home_banner { + position: relative; + + &_img1 { + position: absolute; + top: 5%; + left: 18%; + } + + &_img2 { + position: absolute; + top: 45%; + right: 14%; + } + + &_project1 { + position: absolute; + top: 43%; + left: 10%; + + .bannerProject { + right: 45px; + top: 44px; + } + } + + &_project2 { + position: absolute; + bottom: -10%; + left: 21.3%; + + .bannerProject { + right: 90px; + top: 0px; + animation-delay: 4s !important; + } + .author_img{ + animation-delay: 4s !important; + } + } + + &_project3 { + position: absolute; + top: 22%; + right: 22%; + + .icon8_img { + margin-top: -20px; + } + + .bannerProject { + left: 47px; + top: 0px; + animation-delay: 8s !important; + } + .author_img{ + animation-delay: 8s !important; + } + } + + &_project4 { + position: absolute; + bottom: -10%; + right: 20.3%; + + .bannerProject { + left: 47px; + top: 0px; + animation-delay: 12s !important; + } + .author_img{ + animation-delay: 12s !important; + } + } + + .author_img { + width: 38px; + height: 38px; + border: 1.5px solid white; + background-color: #F6F6F6; + animation: scalemax 2s forwards; + } + + .bannerProject { + position: absolute; + background-color: #ffffff; + border-radius: 15px 6px 15px 15px; + padding: 10px 12px; + width: 238px; + opacity: 0; + animation: slideLeftFadeIn 3s forwards; + + .icon-66 { + background-image: linear-gradient(180deg, rgba(33, 73, 212, 0.04) 0%, rgba(33, 73, 212, 0.14) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + position: absolute; + top: 0px; + left: 10px; + font-family: "DouyinSansBold"; + font-size: 22px; + } + } + } + + .project_list_top { + display: grid; + gap: 20px; + grid-template-columns: repeat(3, 1fr); + } + + .project_list_top_item { + padding: 30px; + background-image: url('../image/pro_item1.png'); + background-size: 100% 100%; + overflow: hidden; + + &:nth-of-type(3n+1), + &:nth-of-type(3n+1) a { + color: #ffffff; + } + + &:nth-of-type(3n+2) { + background-image: url('../image/pro_item2.png'); + } + + &:nth-of-type(3n+3) { + background-image: url('../image/pro_item3.png'); + } + + .proListTopics { + gap: 7px; + } + + .proListTopic { + height: 24px; + line-height: 24px; + padding: 0 10px; + background-color: rgba(255, 255, 255, 0.4); + border-radius: 4px; + } + + .ant-divider-vertical { + width: 1.5px; + height: 0.8em; + background-color: #d8d8d8; + } + } +} + +.project_list_all_box { + min-height: 50vh; + padding: 40px 0 100px; + background-image: linear-gradient(179.88deg, #ffffff 0%, rgba(255, 255, 255, 0.62) 16.1%, rgba(255, 255, 255, 0) 100%); + border-radius: 40px 40px 0 0; + + .cate_list_box { + display: flex; + gap: 18px; + flex-wrap: wrap; + } + + .cate_item { + cursor: pointer; + padding: 2px 25px; + background-color: #f7f9fd; + border-radius: 17px; + + &.active { + font-weight: normal; + font-size: 16px; + color: #ffffff; + background-color: #091221; + } + } +} + +.project_home_right { + width: 21%; + + &-title { + padding: 14px 20px; + background-image: url('../image/bk2.png'); + background-size: 100% 100%; + } + + &-user { + background-color: #ffffff; + border-radius: 8px; + box-shadow: 0px 0px 10px rgba(35, 44, 121, 0.07); + + &-item { + padding: 15px 22px; + + &:hover { + background-color: #f7f9fd; + font-weight: bold; + } + + &:not(:last-of-type) { + position: relative; + + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 22px; + right: 22px; + height: 1px; + border-bottom: 1px dashed rgba(130, 132, 164, 0.4); + } + } + } + } + + .hot_project_Collapse { + border: none; + padding: 0 20px; + background: none; + + .ant-collapse-item { + background-color: white; + border-radius: 6px; + margin-top: 20px; + border: 1px solid rgba(130, 132, 164, 0.18); + transition: all 0.5s; + + .ant-collapse-header { + color: #091221; + opacity: 0.8; + font-size: 15px; + } + + &-active { + background-image: url('../image/bk3.png'); + background-size: 100% 100%; + border: none; + + .ant-collapse-header { + font-weight: 700; + opacity: 1; + } + } + } + + .ant-collapse-content { + border-top: none; + background: none; + color: #091221; + opacity: 0.7; + + .ant-collapse-content-box { + padding-top: 0; + } + } + } +} + +.project_list_all { + .project_list_all_title { + padding: 5px 0 40px 30px; + background-image: linear-gradient(135.72deg, #f2e8e9 0%, #b3a7ff 100%); + border-radius: 15px 15px 0px 0px; + } + + &_list { + background-color: #ffffff; + border-radius: 15px; + position: relative; + top: -34px; + padding: 30px; + min-height: 800px; + + &_item { + .author_img { + width: 30px; + height: 30px; + border-radius: 6px; + } + + .count_box span { + padding: 4px 12px; + background-color: #f7f9fd; + border-radius: 12px; + + .icon-dianzan1 { + color: #d18733; + } + + .icon-yifuke_icon { + color: #5545BD; + } + } + + &:not(:last-of-type) { + margin-bottom: 10px; + padding-bottom: 12px; + border-bottom: 1px dashed rgba(130, 132, 164, 0.4); + + } + } + } +} + +@keyframes scalemax { + 0%{ + scale: 1; + } + 40%{ + scale: 1.28; + } + 100%{ + scale: 1; + } +} + +@keyframes slideLeftFadeIn { + 0%{ + opacity: 0.4; + width: 200px; + } + 20%{ + width: 238px; + } + 50%{ + opacity: 1; + } + 100%{ + opacity: 0; + } +} \ No newline at end of file diff --git a/src/home/Index.jsx b/src/home/Index.jsx index 3db7672e1..bec531e51 100644 --- a/src/home/Index.jsx +++ b/src/home/Index.jsx @@ -98,7 +98,7 @@ function Index(props) {
    { ['《全军软件供应链安全治理指南》正式发布,我院牵头打造首个统一治理平台', - '重磅发布:平台首批“可信军用级”基础软件镜像库上线,护航关键系统开发', + '重磅发布:平台首批“可信JY级”基础软件镜像库上线,护航关键系统开发', '案例深度解析:“雷霆”后勤保障信息系统如何通过平台实现依赖组件100%可信治理' ].map((i,k)=>{ return( diff --git a/src/home/SecondEdition.jsx b/src/home/SecondEdition.jsx index dd9fa9e3b..105b12b3b 100644 --- a/src/home/SecondEdition.jsx +++ b/src/home/SecondEdition.jsx @@ -185,7 +185,7 @@ function SecondEdition({setValue}) {
    军事数智生态市场
    -

    汇聚国内优秀的可信智能应用,构建开放、创新的军用软件在线体验与推广平台,助力军事智能化成果快速转化和部署。

    +

    汇聚国内优秀的可信智能应用,构建开放、创新的JY软件在线体验与推广平台,助力军事智能化成果快速转化和部署。

    diff --git a/src/news/detail/index.jsx b/src/news/detail/index.jsx index b72057946..c2bf3f0d3 100644 --- a/src/news/detail/index.jsx +++ b/src/news/detail/index.jsx @@ -50,9 +50,9 @@ function detail(props) { 社区动态 {detail.name}
    -
    +
    {/* 正文 */} -
    +
    {detail.name}