航天院基础版本,服务模块需增加sonaqube的,其它都要隐藏

This commit is contained in:
caishi 2024-06-20 08:56:30 +08:00
parent a77ddeec08
commit ef129ed7ad
196 changed files with 2132 additions and 10668 deletions

View File

@ -1,6 +1,4 @@
# gitlink-ssr版本 ####星云版本2024-6-20 更新版本包含开通工作台、代码库、issue、等模块的版本更新基本与forge一直属于内网版本邮件、协议签订等均已隐藏。
#### node版本 #### node版本
12.x/14.x 12.x/14.x
#### ng配置 #### ng配置

View File

@ -17,7 +17,7 @@ const TerserWebpackPlugin = require('terser-webpack-plugin');
const paths = require("./paths"); const paths = require("./paths");
const getClientEnvironment = require("./env"); const getClientEnvironment = require("./env");
let publicPath = "/build/"; let publicPath = "/react/build/";
const publicUrl = publicPath.slice(0, -1); const publicUrl = publicPath.slice(0, -1);
// const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false"; // const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";

View File

@ -2,24 +2,24 @@
<html lang="zh-hans-CN" class="notranslate translated-ltr" translate="no"> <html lang="zh-hans-CN" class="notranslate translated-ltr" translate="no">
<head> <head>
<title>GitLink | 新一代开源创新服务平台</title> <title>星云协同开发平台</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="Keywords" content="GitLink, git, 开源, 代码托管, 项目管理, 版本控制, 代码分享, 项目协作, 协同开发平台"> <meta name="Keywords" content="星云协同开发平台, git, 开源, 代码托管, 项目管理, 版本控制, 代码分享, 项目协作, 协同开发平台">
<meta name="description" content="GitLink 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。"> <meta name="description" content="星云 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。">
<meta property="og:title" content="GitLink | 确实开源" /> <meta property="og:title" content="星云协同开发平台" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content="https://gitlink.org.cn/" /> <meta property="og:url" content="https://gitlink.org.cn/" />
<meta property="og:image" content="https://www.gitlink.org.cn/images/logo.png" /> <meta property="og:image" content="https://www.gitlink.org.cn/images/logo.png" />
<meta property="og:image:alt" content="GitLink | 确实开源" /> <meta property="og:image:alt" content="星云协同开发平台" />
<meta property="og:site_name" content="GitLink" /> <meta property="og:site_name" content="星云协同开发平台" />
<meta property="og:description" content="GitLink 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。" /> <meta property="og:description" content="星云 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。" />
<meta name="hostname" content="gitlink.org.cn"> <meta name="hostname" content="gitlink.org.cn">
<meta name="keyboard-shortcuts-preference" content="all"> <meta name="keyboard-shortcuts-preference" content="all">
<meta name="expected-hostname" content="gitlink.org.cn"> <meta name="expected-hostname" content="gitlink.org.cn">
<meta name="go-import" content="gitlink.org.cn git https://gitlink.org.cn"> <meta name="go-import" content="gitlink.org.cn git https://gitlink.org.cn">
<meta name="octolytics-dimension-user_login" content="GitLink"></meta> <meta name="octolytics-dimension-user_login" content="星云协同开发平台"></meta>
<meta name="octolytics-dimension-repository_nwo" content="GitLink"></meta> <meta name="octolytics-dimension-repository_nwo" content="星云协同开发平台"></meta>
<meta name="octolytics-dimension-repository_network_root_nwo" content="GitLink"></meta> <meta name="octolytics-dimension-repository_network_root_nwo" content="星云协同开发平台"></meta>
<meta name="theme-color" content="#000000"> <meta name="theme-color" content="#000000">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="referrer" content="always"> <meta name="referrer" content="always">

View File

@ -47,10 +47,10 @@ const ProjectDetail = Loadable({
loader: () => import("./forge/Main/DetailAdaptor"), loader: () => import("./forge/Main/DetailAdaptor"),
loading: Loading, loading: Loading,
}); });
const Information = Loadable({ // const Information = Loadable({
loader: () => import('./forge/Information/index'), // loader: () => import('./forge/Information/index'),
loading: Loading, // loading: Loading,
}) // })
//forge安全设置 //forge安全设置
const Security = Loadable({ const Security = Loadable({
loader: () => import('./forge/SecuritySetting/Index'), loader: () => import('./forge/SecuritySetting/Index'),
@ -93,7 +93,7 @@ const Search = Loadable({
}) })
const WikiPreview = Loadable({ const WikiPreview = Loadable({
loader: () => import('./forge/Wiki/Preview'), loader: () => import('./forge/Wiki/page/preview'),
loading: Loading, loading: Loading,
}) })
@ -127,10 +127,10 @@ const Teaching = Loadable({
loading: Loading, loading: Loading,
}) })
const Glcc = Loadable({ // const Glcc = Loadable({
loader : () => import("./glcc"), // loader : () => import("./glcc"),
loading: Loading, // loading: Loading,
}) // })
const ConfigurateBot = Loadable({ const ConfigurateBot = Loadable({
loader: () => import("./forge/SecuritySetting/bot/exploit/configuration"), loader: () => import("./forge/SecuritySetting/bot/exploit/configuration"),
loading: Loading, loading: Loading,
@ -268,7 +268,6 @@ class App extends Component {
this.setState({ this.setState({
mygetHelmetapi: undefined mygetHelmetapi: undefined
}); });
// document.title = "GitLink | 确实开源";
var link = document.createElement('link'), var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon'); oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon'; link.id = 'dynamic-favicon';
@ -339,11 +338,11 @@ class App extends Component {
{/* <Router> */} {/* <Router> */}
<Switch> <Switch>
{/* wiki预览 */} {/* wiki预览 */}
<Route path="/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={ <Route path="/:owner/:proIdentity/:projectId/wiki/preview" render={
(props) => { (props) => {
return (<WikiPreview {...this.props} {...props} {...this.state} />) return (<WikiPreview {...this.props} {...props} {...this.state} />)
} }
} /> } />
{/* svg */} {/* svg */}
<Route path="/:owner/:projectsId/badge/:type" render={ <Route path="/:owner/:projectsId/badge/:type" render={
@ -382,14 +381,14 @@ class App extends Component {
<ConfigurateBot {...this.props} {...p}/> <ConfigurateBot {...this.props} {...p}/>
)} )}
></Route> ></Route>
<Route {/* <Route
path={"/zone/:deptId"} path={"/zone/:deptId"}
render={ render={
(props) => { (props) => {
return (<Information {...this.props} {...props} {...this.state} />) return (<Information {...this.props} {...props} {...this.state} />)
} }
}> }>
</Route> </Route> */}
<Route <Route
path={"/settings"} path={"/settings"}
render={ render={
@ -463,14 +462,14 @@ class App extends Component {
></Route> ></Route>
{/*glcc */} {/*glcc */}
<Route {/* <Route
path="/glcc/:id" path="/glcc/:id"
render={(props) => <Glcc {...this.props} {...props} />} render={(props) => <Glcc {...this.props} {...props} />}
></Route> ></Route>
<Route <Route
path="/glcc" path="/glcc"
render={(props) => <Glcc {...this.props} {...props} />} render={(props) => <Glcc {...this.props} {...props} />}
></Route> ></Route> */}
{/* soft市场页 */} {/* soft市场页 */}
<Route <Route

View File

@ -32,7 +32,7 @@ export function initAxiosInterceptors(props) {
// 判断网络是否连接 // 判断网络是否连接
initOnlineOfflineListener(); initOnlineOfflineListener();
var proxy = "https://testforgeplus.trustie.net"; var proxy = "https://pre.gitlink.org.cn";
// var proxy = "https://www.gitlink.org.cn"; // var proxy = "https://www.gitlink.org.cn";
//响应前的设置 //响应前的设置

View File

@ -9,13 +9,13 @@ if (!__SERVER__) {
} }
const isDev = __SERVER__ ? false : window.location.port == 3007; const isDev = __SERVER__ ? false : window.location.port == 3007;
const isdev2= __SERVER__ ? false : window.location.hostname ==='www.educoder.net' const isdev2= __SERVER__ ? false : window.location.hostname ==='www.educoder.net'
export const TEST_HOST = "https://testforgeplus.trustie.net" export const TEST_HOST = "http://172.20.32.202:4000/"
export function getImageUrl(path) { export function getImageUrl(path) {
// https://www.educoder.net // https://www.educoder.net
// https://testbdweb.trustie.net // https://testbdweb.trustie.net
// const local = 'http://localhost:3000' // const local = 'http://localhost:3000'
path && !path.startsWith('/') && !path.startsWith('http') && (path = '/'.concat(path)); path && !path.startsWith('/') && !path.startsWith('http') && (path = '/'.concat(path));
const local = 'https://testforgeplus.trustie.net'; const local = 'http://172.20.32.202:4000/';
if (isDev) { if (isDev) {
return `${local}${path}` return `${local}${path}`
} }
@ -42,7 +42,7 @@ export function getImageUrlAbsolute(path) {
// https://testbdweb.trustie.net // https://testbdweb.trustie.net
// const local = 'http://localhost:3000' // const local = 'http://localhost:3000'
path && !path.startsWith('/') && !path.startsWith('http') && (path = '/'.concat(path)); path && !path.startsWith('/') && !path.startsWith('http') && (path = '/'.concat(path));
const local = 'https://testforgeplus.trustie.net'; const local = 'http://172.20.32.202:4000/';
const prod = __SERVER__ ? local : window.location.origin; const prod = __SERVER__ ? local : window.location.origin;
if (isDev) { if (isDev) {
return `${local}${path}` return `${local}${path}`
@ -72,7 +72,7 @@ export function getImage(path) {
// https://www.educoder.net // https://www.educoder.net
// https://testbdweb.trustie.net // https://testbdweb.trustie.net
// const local = 'http://localhost:3000' // const local = 'http://localhost:3000'
const local = 'https://testforgeplus.trustie.net/'; const local = 'http://172.20.32.202:4000//';
if(path.indexOf("http://")===-1){ if(path.indexOf("http://")===-1){
if (isDev) { if (isDev) {
return `${local}/images/${path}` return `${local}/images/${path}`
@ -361,7 +361,7 @@ export function setSeoMeta(keyWords, title, description, url, owner, projectId)
document.querySelector(`meta[property='og:url']`).content = origin + url; document.querySelector(`meta[property='og:url']`).content = origin + url;
document.querySelector(`meta[property='og:description']`).content = description; document.querySelector(`meta[property='og:description']`).content = description;
document.querySelector(`meta[property='og:image:alt']`).content = description; document.querySelector(`meta[property='og:image:alt']`).content = description;
document.querySelector('meta[name="Keywords"]').content= `${ keyWords }${ keyWords ? '' : 'GitLink, git, 开源, 代码托管, 项目管理, 版本控制, 代码分享, 项目协作, 协同开发平台' }` ; document.querySelector('meta[name="Keywords"]').content= `${ keyWords }${ keyWords ? '' : 'git, 开源, 代码托管, 项目管理, 版本控制, 代码分享, 项目协作, 协同开发平台' }` ;
document.querySelector(`meta[name='description']`).content = description; document.querySelector(`meta[name='description']`).content = description;
document.querySelector(`meta[name='go-import']`).content = host + url + ' git ' + origin + url; document.querySelector(`meta[name='go-import']`).content = host + url + ' git ' + origin + url;
document.querySelector(`meta[name='octolytics-dimension-user_login']`).content = owner; document.querySelector(`meta[name='octolytics-dimension-user_login']`).content = owner;
@ -378,10 +378,10 @@ export function setDefaultMeta() {
document = domObj.window.document document = domObj.window.document
} }
document.querySelector(`title`).textContent = 'GitLink | 新一代开源创新服务平台'; document.querySelector(`title`).textContent = 'GitLink | 新一代开源创新服务平台';
document.querySelector(`meta[property='og:title']`).content = 'GitLink | 确实开源'; document.querySelector(`meta[property='og:title']`).content = '星云协同开发平台';
document.querySelector(`meta[property='og:url']`).content = 'https://GitLink.org.cn/'; document.querySelector(`meta[property='og:url']`).content = 'https://GitLink.org.cn/';
document.querySelector(`meta[property='og:description']`).content = 'GitLink 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。'; document.querySelector(`meta[property='og:description']`).content = 'GitLink 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。';
document.querySelector(`meta[property='og:image:alt']`).content = 'GitLink | 确实开源'; document.querySelector(`meta[property='og:image:alt']`).content = '星云协同开发平台';
document.querySelector('meta[name="Keywords"]').content= 'GitLink, git, 开源, 代码托管, 项目管理, 版本控制, 代码分享, 项目协作, 协同开发平台'; document.querySelector('meta[name="Keywords"]').content= 'GitLink, git, 开源, 代码托管, 项目管理, 版本控制, 代码分享, 项目协作, 协同开发平台';
document.querySelector(`meta[name='description']`).content = 'GitLink 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。'; document.querySelector(`meta[name='description']`).content = 'GitLink 是一个新一代的开源创新服务平台,提供分布式协作开发、流水线运维、代码分析等功能,基于 Git 打造分布式代码托管环境。';
document.querySelector(`meta[name='go-import']`).content ='GitLink.org.cn git https://GitLink.org.cn'; document.querySelector(`meta[name='go-import']`).content ='GitLink.org.cn git https://GitLink.org.cn';

View File

@ -3,7 +3,7 @@ const host = window.location.protocol + '//' + window.location.host
const wx = window.wx const wx = window.wx
const appId = 'wxf8debe756b4a0309' const appId = 'wxf8debe756b4a0309'
let settings = localStorage.chromesetting&&JSON.parse(localStorage.chromesetting); let settings = localStorage.chromesetting && localStorage.chromesetting !=="undefined" && JSON.parse(localStorage.chromesetting);
let actionUrl = settings && settings.common.zone +'/api'; let actionUrl = settings && settings.common.zone +'/api';
const service = axios.create({ const service = axios.create({
@ -130,8 +130,8 @@ export function configShareForCustom (title, desc, imgUrl, path) {
console.log('configShareForCustom', host) console.log('configShareForCustom', host)
const _url = window.location.href.split('#')[0]; const _url = window.location.href.split('#')[0];
var shareData = { var shareData = {
title: title || 'GitLink | 确实开源', title: title || '星云协同开发平台',
desc: desc || 'GitLink,新一代开源创新服务平台', desc: desc || '星云,新一代开源创新服务平台',
link: path ? `${host}/${path}` : _url, link: path ? `${host}/${path}` : _url,
imgUrl: imgUrl || host + '/build/images/share_logo_icon.png' imgUrl: imgUrl || host + '/build/images/share_logo_icon.png'
}; };

View File

@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
/** /**
* nav:{list:[],active:0} */ * nav:{list:[],active:0} */
export default(({ header , nav })=>{ export default(({ header , nav, history })=>{
return( return(
<ul className="list-l-Menu"> <ul className="list-l-Menu">
{header} {header}
@ -13,11 +13,11 @@ export default(({ header , nav })=>{
return( return(
!item.hide &&<li key={key} className={nav.active === key?"active":''}> !item.hide &&<li key={key} className={nav.active === key?"active":''}>
<p> <p>
<Link to={item.href}> <a onClick={()=>{ item.href.indexOf("https") !== -1 ? window.location.href = item.href : history.push(item.href)}}>
{item.icon && <i className={`iconfont ${item.icon || 'icon-huabanfuben'} font-18 mr10`}></i>} {item.icon && <i className={`iconfont ${item.icon || 'icon-huabanfuben'} font-18 mr10`}></i>}
{item.img && <img src={item.img} alt="" width="20px" className="mr10"/>} {item.img && <img src={item.img} alt="" width="20px" className="mr10"/>}
{item.name} {item.name}
</Link> </a>
</p> </p>
</li> </li>
) )

View File

@ -159,7 +159,6 @@ function SiderBar(props) {
<Input.TextArea autoSize={{minRows: 9}} placeholder='请在此处填写您的宝贵意见,若经采纳,我们将通过邮件与您沟通' className={`feedBackText ${failApply ? 'errorInput' : ''}`} maxLength={500} value={feedBackValue} onChange={(e)=>{setFeedBackValue(e.target.value); e.target.value && e.target.value.length && setFailApply(undefined);}}/> <Input.TextArea autoSize={{minRows: 9}} placeholder='请在此处填写您的宝贵意见,若经采纳,我们将通过邮件与您沟通' className={`feedBackText ${failApply ? 'errorInput' : ''}`} maxLength={500} value={feedBackValue} onChange={(e)=>{setFeedBackValue(e.target.value); e.target.value && e.target.value.length && setFailApply(undefined);}}/>
<span className='countNumBox'>{(feedBackValue && feedBackValue.length) || 0}/500</span> <span className='countNumBox'>{(feedBackValue && feedBackValue.length) || 0}/500</span>
</div> </div>
{/* /Gitlink/forgeplus */}
{failApply && <div className='mt10' style={{color: '#f60011'}}>{failApply}</div>} {failApply && <div className='mt10' style={{color: '#f60011'}}>{failApply}</div>}
<div className='mt15 font-15 pln'>若需上传截图<a onClick={()=>{setFeedBackModal(false); history.push('/Gitlink/forgeplus/issues/new?type=feedback')}} className='gotoIssueFeedBack'>点击此处</a></div> <div className='mt15 font-15 pln'>若需上传截图<a onClick={()=>{setFeedBackModal(false); history.push('/Gitlink/forgeplus/issues/new?type=feedback')}} className='gotoIssueFeedBack'>点击此处</a></div>
</Modal> </Modal>

View File

@ -7,7 +7,7 @@ import { notification , Dropdown ,Popover, Menu,Badge } from 'antd';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import LoginDialog from '../../modules/login/LoginDialog'; import LoginDialog from '../../modules/login/LoginDialog';
import HeadSearch from '../Component/HeadSearch'; // import HeadSearch from '../Component/HeadSearch';
import AddProjectModal from './AddProjectModal'; import AddProjectModal from './AddProjectModal';
import '../../modules/tpm/TPMIndex.css'; import '../../modules/tpm/TPMIndex.css';
@ -302,7 +302,7 @@ class NewHeader extends Component {
showSubMenu, showSubMenu,
zoneList zoneList
} = this.state; } = this.state;
let search_url = settings && settings.common && settings.common.search; // let search_url = settings && settings.common && settings.common.search;
return ( return (
<div className={publicNav ? `newHeaders publicNav`:`newHeaders`} id="nHeader"> <div className={publicNav ? `newHeaders publicNav`:`newHeaders`} id="nHeader">
<div className="headerContent"> <div className="headerContent">
@ -319,14 +319,14 @@ class NewHeader extends Component {
{...this.props} {...this.props}
{...this.state} {...this.state}
/> : ""} /> : ""}
<div style={{width:"78px"}}> {/* <div style={{width:"78px"}}>
{ {
publicNav && publicNav &&
<a href={'https://www.ccf.org.cn/'} className={"fl"}> <a href={'https://www.ccf.org.cn/'} className={"fl"}>
<img src={MainLogo} alt="ccf" width="63px"/> <img src={MainLogo} alt="ccf" width="63px"/>
</a> </a>
} }
</div> </div> */}
{ {
settings && settings.nav_logo_url ? settings && settings.nav_logo_url ?
<a href={settings && settings.new_course.default_url} className={"fl mr30"}> <a href={settings && settings.new_course.default_url} className={"fl mr30"}>
@ -379,7 +379,7 @@ class NewHeader extends Component {
} }
{/* </div> */} {/* </div> */}
<div className="head-right"> <div className="head-right">
{ search_url && <HeadSearch {...this.props}/>} {/* { search_url && <HeadSearch {...this.props}/>} */}
{ {
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)? current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight"> <Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">

View File

@ -60,18 +60,18 @@ class Index extends Component {
)} )}
></Route> ></Route>
<Route <Route
path="/explore/all" path="/explore"
render={(props) => ( render={(props) => (
<ProjectIndex {...this.props} {...props} /> <ProjectIndex {...this.props} {...props} />
)} )}
></Route> ></Route>
<Route {/* <Route
path="/explore" path="/explore"
render={(props) => ( render={(props) => (
<ProjectHome {...this.props} {...props} /> <ProjectHome {...this.props} {...props} />
)} )}
></Route> ></Route> */}
</Switch> </Switch>
</div> </div>
); );

View File

@ -1,46 +0,0 @@
import React from 'react';
import Slider from 'react-slick';
import { getImageUrl } from 'educoder';
import Left from '../../../home/Img/left.png';
import Right from '../../../home/Img/right.png';
import banner from '../img/mainbanner.png'
let setting={
dots:true,
infinite: true,
speed: 2000,
slidesToShow: 1,
slidesToScroll: 1,
pauseOnDotsHover:true,
autoplaySpeed:5000,
pauseOnFocus:true,
autoplay:true,
arrows:true,
prevArrow: <img className='slick-prev slick-arrow' src={Left} width="70px" alt=""/>,
nextArrow: <img className='slick-prev slick-arrow' src={Right} width="70px" alt=""/>
}
function TopEdition(props) {
const { bannerList } = props
return(
<Slider {...setting}>
{
bannerList && bannerList.length > 0 ?
bannerList.map((i,k)=>{
return(
<div className={`regform`} key={ k }>
<div style={{backgroundImage:`url(${i})`}}></div>
</div>
)
})
:
<div className={`regform`} style={{backgroundImage:`url(${banner})`}}>
</div>
}
</Slider>
)
}
export default TopEdition;

View File

@ -1,167 +0,0 @@
import React from 'react';
import { Button, message } from 'antd';
import { getImageUrl } from 'educoder';
import MDEditor from "../../../../modules/tpm/challengesnew/tpm-md-editor";
import Upload from "../../../../forge/Upload/Index";
import Attachments from "../../../../forge/Upload/attachment";
import UploadImg from "../../../../forge/Images/upload.png";
import './list.scss';
import '../../../../forge/Order/order.scss';
import { useState } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { addComment, editComment } from '../../api'
function EditComment(props){
const {owner, projectsId, index} = props.match.params;
const {current_user, current_user:{login}, docId, showNotification, reloadComment, cancelMd, parentId, replyId, updateId, showUserImg=true} = props;
const [content, setContent] = useState(props.content);
const [quillFlag, setQuillFlag] = useState(false);
// loading
const [journalSpin, setJournalSpin] = useState(false);
const [atWhoLoginList, setAtWhoLoginList] = useState(undefined);
const [fileList, setFileList] = useState(undefined);
const [attachmentClean, setAttachmentClean] = useState(true);
const [ save , setSave ] = useState(undefined);
useState(()=>{
setSave(props.defaultFileList);
},[props.defaultFileList])
//
function addJournals(){
if(!content){
setQuillFlag(true);
return
}
setJournalSpin(true);
console.log(updateId)
if(updateId){
//
const params = {
id: updateId,
notes: content,
attachmentIds: fileList,
receivers_login:atWhoLoginList
}
editComment(docId, params).then(res=>{
if(res && res.data && res.data.data){
//
reloadComment();
message.success('评论成功');
cancelMd();
setContent(undefined);
}
setJournalSpin(false);
})
}else{
//
const params = {
parentId: parentId,
replyId: replyId,
notes: content,
attachmentIds: fileList,
}
addComment(docId, params).then(res=>{
if(res && res.data && res.data.data){
//
reloadComment();
message.success('评论成功');
cancelMd();
setContent(undefined);
}
setJournalSpin(false);
})
}
};
function deleteLoad(id){
let arr = [];
let list = save;
if(list && list.length>0 ){
arr = list.filter(i=>i.id !== id);
}
setFileList(arr.map(i=>{return i.id}));
setSave(arr);
}
function UploadFunc(f){
let list = [];
let arr = [];
if(save && save.length>0 ){
arr = save.map(i=>{return i.id});
}
list = arr && arr.length>0 ? f.concat(arr) : f ;
setFileList(list);
};
return(
<div className="grid-item-top pb10">
<Link
to={`/${current_user && current_user.login}`}
className="show-user-link mr10"
>
<img
className="radius"
src={getImageUrl(
`/${current_user && current_user.image_url}`
)}
alt=""
width="30"
height="30"
style={{display: showUserImg ? '' : 'none'}}
/>
</Link>
<div style={{position:"relative"}}>
<MDEditor
placeholder={"添加评论..."}
height={300}
mdID={"orderdetail-add-descriptions" + replyId}
initValue={content}
onChange={(value)=>{setQuillFlag(false);setContent(value);}}
changeAtWhoLoginList = {(loginList)=>{setAtWhoLoginList(loginList); setAttachmentClean(true)}}
owner = {owner}
projectsId = {projectsId}
></MDEditor>
<p className="quillFlagBox">
{quillFlag && <span>请输入评论内容</span>}
</p>
<Upload
className="commentStyle"
isComplete={attachmentClean}
load={UploadFunc}
icon={
<img
src={UploadImg}
width="58"
alt=""
style={{ marginBottom: 15 }}
/>
}
size={100}
showNotification={showNotification}
// defaultFileList={props.defaultFileList}
/>
{props.defaultFileList && props.defaultFileList.length > 0 &&
<Attachments
attachments={props.defaultFileList}
showNotification={props.showNotification}
canDelete={true}
deleteLoad={deleteLoad}
></Attachments>
}
<p className="clearfix mt20">
<Button
type="primary"
onClick={addJournals}
loading={journalSpin}
className="mr15 colorButton"
>
评论
</Button>
<Button className="colorButton2" onClick={()=>{cancelMd()}}>取消</Button>
</p>
</div>
</div>
)
}
export default EditComment;

View File

@ -1,226 +0,0 @@
import React, { useEffect, useState } from 'react';
import { Button, Popconfirm, Radio, Input, message, Tooltip, Spin, Pagination } from 'antd';
import axios from 'axios';
import { getImageUrl, timeAgo, isPhone } from 'educoder';
import RenderHtml from '../../../../components/render-html';
import Attachment from '../../../Upload/attachment';
import EditComment from './editComment';
import Nodata from '../../../Nodata';
import CheckProfile from '../../../Component/ProfileModal/Profile';
import './list.scss';
import { Link } from 'react-router-dom';
import { getCommentList, deleteComment } from '../../api'
function IssueCommentList(props){
const{docId, history: {location}, reload, reloadComment, showNotification, current_user:{login, admin, image_url, username}, isManager, showLoginDialog, author} = props;
const {owner, projectsId, index} = props.match.params;
const [category, setCategory] = useState('comment');
const [journals, setJournals] = useState(undefined);
// /markdown1 2 3 4 5
const [showEdit, setShowEdit] = useState(false);
const [parentId, setParentId] = useState(undefined);
const [replyId, setReplyId] = useState(undefined);
// id
const [updateId, setUpdateId] = useState(undefined);
//
const [open, setOpen] = useState(undefined);
// css 线
const [spin, setSpin] = useState(false);
// issue
const [journalsCount, setJournalsCount] = useState(undefined);
//
const limit = 50;
const [page, setPage] = useState(1);
const [totalCount, setTotalCount] = useState(undefined);
// icon
const journalsIcon ={
'issue': 'icon-chuangjianqianbao',
'branch_name': 'icon-fenzhi3',
'assigner': 'icon-chengyuan2',
'status_id': 'icon-xiugaibaobiaomoban',
'fixed_version_id': 'icon-lichengbeiicon2',
'due_date': 'icon-riqi',
'issue_tag': 'icon-biaoji2',
'description': 'icon-xiugaibaobiaomoban',
'subject': 'icon-xiugaibaobiaomoban',
'start_date': 'icon-riqi',
'priority_id': 'icon-youxian',
'attachment': 'icon-xiugaibaobiaomoban'
}
useEffect(()=>{
setSpin(true);
let params = {
limit: limit,
page: page
}
getCommentList(docId, params).then(res=>{
if(res && res.data && res.data.data){
const {journals, total_comment_journals_count, total_count} = res.data.data;
if(category === 'all'){
const array = [];
let start = undefined;
let isJournalCount = 0;
journals.map((item, index)=>{
!isJournalCount && (start = index)
item.is_journal_detail && (isJournalCount++)
if(!item.is_journal_detail && isJournalCount < 10){
isJournalCount = 0;
return
}
if(isJournalCount >= 10 && (!item.is_journal_detail || journals.length-1 === index)){
array.push({start, count: isJournalCount});
isJournalCount = 0;
}
})
array.map((item, i)=>{
journals[item.start].numCount = item.count-1;
for (let index = 0; index < item.count; index++) {
journals[item.start+index].start = journals[item.start].id;
journals[item.start+index].closeAndSpan = true;
}
})
}
setTotalCount(total_count);
setJournalsCount(total_comment_journals_count);
setJournals(journals);
setSpin(false)
}
})
}, [reload, category, page])
function commentCtx(v){
return <RenderHtml owner={owner} projectsId={projectsId} className="break_word_comments imageLayerParent commentRenderHtml" value={v} url={location}/>;
};
//
function deleteCommentFunc(id){
deleteComment(docId, id).then(res=>{
if(res && res.data && !res.data.data.status){
reloadComment();
message.success('删除成功');
}
})
}
// markdown
function cancelMd(){
setShowEdit(false);
}
return(
(isPhone() && journalsCount === 0) ? '' : <div className="commentListBox info_text mt30">
{/* 评论 */}
<div className={`${!login && journalsCount > 0 && 'pb15'}`}>
<div className='typeActionBox mb20'>
<div className='line'></div>
<div>评论{ journalsCount > 0 && `(共${ journalsCount }条评论)` }</div>
</div>
</div>
{/* 评论快速入口-仅有评论且登录时展示 */}
{login && category !== 'operate' && journalsCount > 0 && !isPhone() && <div className={`pb30 ${journalsCount > 0 && 'pt15'}`}><div className='gotoComment'>点击<a className='ml5' href='#addComments'>添加评论</a></div></div>}
{/* 评论/操作日志 展示列表 */}
<Spin spinning={spin}>
<div className={`issueCommentsBox ${category === 'comment' && !spin && 'justComment'}`}>
{journals && (journals.length > 0 && journals.map(item=>{return <div key={item.id} className='commentContentBox pb30'>
{/* 评论 */}
<div className='commentOperationBor'></div>
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></Link>
<div className='commentContentRight'>
{/* 判断是否是编辑状态 */}
{(showEdit === 2 && updateId === item.id) ? <div className='mt15 mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={item.notes} defaultFileList={item.attachments} showUserImg={false}/></div> : <div>
<div className='commentContent'>
<div className='flexCenter font-14'>
<div>
<Link to={`/${item.user.login}`}>{item.user.name}</Link>
<span className='ml15 timeAgo font-14'>{timeAgo(item.created_at)}</span>
</div>
{login && !isPhone() && <div>
{/* 平台管理员/仓库管理员/发布评论者/issue创建者 */}
{(admin || isManager || login === item.user.login || username === author) && <Popconfirm
placement="bottom"
title={`确定要删除此条评论吗?${item.children_journals.length > 0 ? '子评论也将被一起删除。' : ''}`}
okText="是"
cancelText="否"
onConfirm={() => deleteCommentFunc(item.id)}
>
<Button type='link' className='color-grey-89'><i className='iconfont icon-fuzhi-shanchu font-14 mr8'></i>删除</Button>
</Popconfirm>}
{/* 仅评论者可修改 */}
{login === item.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(item.id); setShowEdit(2)}}><i className='iconfont icon-a-bianji12 font-14 mr8'></i>修改</Button>}
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id); setReplyId(item.id); setShowEdit(3)}}><Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-14 mr8'></i>回复</Button></CheckProfile>
</div>}
</div>
<div className='contentHtml mb5'>{commentCtx(item.notes)}</div>
{item && item.attachments && item.attachments.length > 0 && <div className='attachmentBox mb5'><Attachment
attachments={item.attachments}
showNotification={showNotification}
canDelete={false}
/></div>}
</div>
</div>}
{showEdit === 3 && replyId === item.id && <div className='contentHtml mr20'><EditComment {...props} cancelMd={cancelMd} parentId={parentId} replyId={replyId} reloadComment={reloadComment}/></div>}
{/* 评论回复部分 */}
{item.children_journals.map(i =>{
return <div className='commentReply' key={i.id}>
{(showEdit === 4 && updateId === i.id) ? <div className='mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={i.notes} defaultFileList={i.attachments}/></div> : <div>
<div className='flexCenter'>
<div>
<Link to={`/${i.user.login}`}><img src={getImageUrl(i.user.image_url)} alt="" className='commentUserImg mr8'/></Link>
<Link to={`/${i.user.login}`}>{i.user.name}</Link>
{i.reply_user && <span className='ml5 timeAgo mr3'>回复</span>}
<span>{i.reply_user && i.reply_user.name}</span>
<span className='ml15 timeAgo font-14'>{timeAgo(i.created_at)}</span>
</div>
{login && !isPhone() && <div>
{/* 平台管理员/仓库管理员/发布评论者/回复评论者/issue创建者 */}
{(admin || isManager || login === i.user.login || (i.reply_user && login === i.reply_user.login) || username === author) && <Popconfirm
placement="bottom"
title={"确定要删除当前回复吗?"}
okText="是"
cancelText="否"
onConfirm={() => deleteCommentFunc(i.id)}
>
<Button type='link' className='color-grey-89'><i className='iconfont icon-fuzhi-shanchu font-14 mr8'></i>删除</Button>
</Popconfirm>}
{/* 仅回复评论者可修改 */}
{login === i.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(i.id); setShowEdit(4)}}><i className='iconfont icon-a-bianji12 font-14 mr8'></i>修改</Button>}
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id);setReplyId(i.id); setShowEdit(5)}}>
<Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-14 mr8'></i>回复</Button>
</CheckProfile>
</div>}
</div>
<div className='contentHtml mt5 mb10'>{commentCtx(i.notes)}</div>
{i && i.attachments && i.attachments.length > 0 && <div className='attachmentBox'><Attachment
attachments={i.attachments}
showNotification={showNotification}
canDelete={false}
/></div>}
</div>}
{showEdit === 5 && replyId === i.id && <div className='contentHtml mr20'><EditComment {...props} cancelMd={cancelMd} parentId={parentId} replyId={replyId} reloadComment={reloadComment}/></div>}
</div>})}
</div>
</div>}))}
</div>
</Spin>
{totalCount>limit && <div className='mt20 paginationIssueComment mb20'>
<Pagination simple current={page} pageSize={limit} total={totalCount} onChange={(page)=>setPage(page)}/>
</div>}
{/* 添加评论 */}
{category !== 'operate' && !isPhone() && <div className="pb30" style={{marginTop: journalsCount ? '-5px' : '30px'}}>
{login ? showEdit === 1 ? <EditComment {...props} cancelMd={cancelMd}/> : <div className="addComments" id='addComments'>
<img src={getImageUrl(image_url)} alt="" />
<div style={{flex:1}}>
<CheckProfile {...props} sureFunc={()=>{setShowEdit(1)}}>
<Input className='addCommentBox' placeholder="添加评论"/>
</CheckProfile>
</div>
</div> : <div className='unLoginComment font-15 pl20'>
{/* 未登录用户 */}
<a className='mr5 loginBtn' onClick={()=>{showLoginDialog()}}>登录</a>并参与评论与回复
</div>}
</div>}
</div>
)
}
export default IssueCommentList;

View File

@ -1,217 +0,0 @@
.typeActionBox{
display: flex;
align-items: center;
font-size: 16px;
.line {
width: 3px;
height: 14px;
background: var(--primary-color);
margin-right: 13px;
}
}
.commentUserImg{
height: 28px;
width: 28px;
border-radius: 50%;
object-fit: cover;
}
.issueCommentsBox{
.operationLog, .commentContentBox{
position: relative;
min-height: 62px;
display: flex;
>.flexCenter, >a{
z-index: 2;
}
&::before, &::after{
content: '';
width: 1px;
height: 50%;
position: absolute;
background: #eee;
left: 12px;
z-index: 1;
}
&::after{
background: #eee;
top: 50%;
}
}
.commentContentBox+.operationLog .operationCommentBor, .operationLog+.commentContentBox .commentOperationBor{
border-top: 1px solid #eee;
width: 98.5%;
position: absolute;
left: 12px;
}
.operationLog+.commentContentBox{
&>a, &>.commentContentRight{
margin-top: 25px;
}
}
.timeAgo{
color:#acb0bf;
}
.operationLog:last-child::after, .operationLog:first-child::before, .commentContentBox:last-child::after, &.justComment .commentContentBox::before, &.justComment .commentContentBox::after{
display: none;
}
.operationLog:first-child, .commentContentBox+.operationLog{
margin-top: -15px;
}
.commentContentBox:last-child::before{
height: 35%;
}
.flexCenter{
display: flex;
align-items: center;
justify-content: space-between;
}
.commentRenderHtml.markdown-body p{
font-size: 14px !important;
}
.commentReply{
padding: 15px 0 0 20px;
background-color: hsla(225, 31%, 95%, 0.41);
&>div{
padding-bottom: 5px;
}
&+.commentReply>div{
margin-top: -15px;
padding-top: 15px;
border-top: 1px dashed #eee;
}
}
.opBox{
justify-content: flex-start;
// flex: 1;
// width: 100%;
}
.commentContentBox{
display: flex;
align-items: flex-start;
}
.commentContentRight{
flex: 1;
background-color:#fafafc;
// border:1px solid var(--light-color-2);
border:1px solid rgba(42, 97, 255, 0.23);
border-radius:6px;
position: relative;
top: -6px;
padding: 10px 15px 16px;
width: 0;
&::before{
content: '';
display: block;
position: absolute;
top: 13px;
left: -14px;
width: 0;
height: 0;
overflow: hidden;
font-size: 0;
line-height: 0;
border: 7px;
border-style: solid;
border-color: transparent rgba(42, 97, 255, 0.23) transparent transparent;
}
&::after{
content: '';
display: block;
width: 0;
height: 0;
overflow: hidden;
font-size: 0;
line-height: 0;
border: 6px;
border-style: solid;
border-color: transparent #fafafc transparent transparent;
position: absolute;
top: 14px;
left: -11px;
}
}
}
.attachmentBox{
margin-top: -8px;
}
.color-grey-89{
color: #898d9d;
// &:hover {
// color: var(--primary-color);
// }
}
// 添加评论样式
.unLoginComment{
height:58px;
line-height: 58px;
background-color:var(--more-light-color);
border-radius:4px;
color: rgba(84, 87, 103, 1);
.loginBtn{
color: var(--primary-color);
}
}
.quillFlagBox{
color: red;
margin-bottom: 5px !important;
height: 28px;
}
.addComments{
display: flex;
align-items: center;
background-color:var(--more-light-color);
border-radius:4px;
padding:7px 10px;
&>img{
height: 28px;
width: 28px;
border-radius: 50%;
margin-right: 13px;
}
}
.addCommentBox{
width: 100%;
height: 30px;
border: none;
&:focus {
border-color: var(--primary-color) !important;
}
}
.paginationIssueComment{
text-align: center;
}
.gotoComment{
// background-color:var(--more-light-color);
background-color:rgba(241, 243, 252, 0.55);
border-radius:4px;
color: rgba(172, 176, 191, 1);
padding: 8px 20px;
margin-top: -10px;
&>a{color: var(--primary-color);}
}
// .commentStyle {
// &:hover {
// border-color: var(--primary-color) !important;
// }
// }
.colorButton {
background-color: var(--primary-color);
border-color: var(--primary-color);
&:hover {
background-color: var(--light-color);
border-color: var(--primary-color);
}
&:focus {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
}
.colorButton2 {
&:hover {
border-color: var(--primary-color);
color: var(--light-color);
}
&:focus {
color: var(--primary-color);
}
}

View File

@ -1,58 +0,0 @@
import React , { useEffect, useState } from 'react';
import Slider from 'react-slick';
import { Link } from 'react-router-dom';
const settings = {
dots: true,
infinite: false,
speed: 500,
slidesToShow: 3,
slidesToScroll: 3,
arrows: false,
adaptiveHeight: true,
};
function Contributor(props) {
const { personList } = props
const [ showList, setShowList] = useState([]);
function initList() {
if (personList.length % 3 !== 0) {
setShowList([].concat(personList, new Array(personList.length % 3 - 1).fill({})))
} else {
setShowList( personList )
}
}
useEffect(()=>{
initList();
},[personList])
return(
<div className="boxmain zone_c_lists pt40">
{
showList && showList.length > 0 ?
<Slider {...settings}>
{
showList.map((i,k)=>{
return(
<div className="container" key={ k }>
{ i.name &&
<div className="c_item">
<Link to={`/${i.login}`}><img src={i.imageUrl} alt="" /></Link>
<div className="c_name task-hide">{i.name}</div>
<p className="c_desc task-hide-2" style={{display:i.introduction?"":"flex"}}>{i.introduction || "暂无~"}</p>
</div>
}
</div>
)
})
}
</Slider>
:""
}
</div>
)
}
export default Contributor;

View File

@ -1,22 +0,0 @@
import React from 'react';
function DefaultImg({name,title}){
function randomNumberInRange(min, max) {
// ? min max
return Math.floor(Math.random() * (max - min + 1)) + min;
}
return(
<div className="defaultBox">
<img src={require(`../img/back${randomNumberInRange(1,3)}.png`).default} alt="" className="back" />
<img src={require(`../img/color${randomNumberInRange(1,4)}.png`).default} alt="" className="color" />
<span className="d_name">
<span>{name}</span>
{/* <span>{title}</span> */}
</span>
</div>
)
}
export default DefaultImg;

View File

@ -1,26 +0,0 @@
import React from 'react';
import { Link } from 'react-router-dom';
function Hot({list , title, deptId, temp}){
return(
<div>
<p className="hot_title">{title}</p>
{
list && list.length>0 &&
<ul>
{
list.map((i,k)=>{
return(
<li>
<span style={{opacity:k<3 ? `${1-((k+1)/10)}` :"0.3"}}>{k+1}</span>
<Link to={`/zone/${deptId}/newdetail/${i.id}`}>{i.name}</Link>
</li>
)
})
}
</ul>
}
</div>
)
}
export default Hot;

View File

@ -1,80 +0,0 @@
import React , {forwardRef, useEffect, useState} from 'react';
import { Modal , Form , Input , Button, Icon } from 'antd';
import UploadImage from '../../Team/Component/UploadImage';
import { getImageUrlAbsolute, getZoneUrl } from 'educoder';
const { TextArea } = Input;
function MemberApply(props){
const { getFieldDecorator, validateFields , setFieldsValue } = props.form;
const { current_user, onOk, visible, onCancel } = props
const [imageUrl, setImageUrl] = useState(undefined)
useEffect(()=>{
if (current_user) {
setImageUrl(getImageUrlAbsolute(`/${current_user.image_url}`));
}
},[current_user])
function onSure(){
validateFields((error,values)=>{
if(!error){
values.imageUrl = imageUrl
onOk(values)
}
})
}
const layout = {
labelCol: { span: 5 },
wrapperCol: { span: 18 },
};
return(
<Modal
visible={visible}
title="加入专区会员"
width="650px"
closable={false}
destroyOnClose
className="apply-modal"
footer={
<div className="flexCenterJustify">
<Button className="mr20 cancel-button" type="default" onClick={onCancel}>取消</Button>
<Button type="primary" className="sure-button" onClick={onSure}>确定</Button>
</div>
}
centered
>
<div>
<Form {...layout }>
<Form.Item label="会员名称" name="name">
{getFieldDecorator("name", {
initialValue: current_user.nickname,
rules:[{ required:true,message:"请输入申请原因" }]
})(
<Input placeholder="请输入会员名称" maxLength={ 10 } width="220px"/>
)}
</Form.Item>
<Form.Item label="会员头像" name="imageUrl" required>
<UploadImage maxSize={ 5 } getImageUrl={ (url) => setImageUrl(url) } url={ getImageUrlAbsolute(`/${current_user.image_url}`)} action={ getZoneUrl(`/api/cms/common/upload`) } />
</Form.Item>
<Form.Item label="会员简介" name="introduction">
{getFieldDecorator("introduction",{
rules:[{ required:true,message:"请输入会员简介" }]
})(
<TextArea autoSize={{ minRows: 2, maxRows: 6 }} maxLength={ 130 } placeholder="请输入会员简介" width="220px"/>
)}
</Form.Item>
<Form.Item label="申请原因" name="remark">
{getFieldDecorator("remark",{
rules:[{ required:true,message:"请输入申请原因" }]
})(
<TextArea autoSize={{ minRows: 2, maxRows: 6 }} maxLength={ 300 } placeholder="请输入申请原因" width="220px"/>
)}
</Form.Item>
</Form>
</div>
</Modal>
)
}
export default Form.create()(forwardRef(MemberApply));

View File

@ -1,58 +0,0 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { tempEnum } from '../tempInfo';
import Crown from '../img/crown.png';
import Nodata from '../../Nodata';
import nodata from '../img/nodata.png';
function Member(props) {
const { vipLists, temp } = props;
return(
<div className="vip_list">
{
vipLists.map((i,k)=>{
return(
<div className="vip_list_card">
<div className="card_title">
<img src={Crown} alt="" width="37px" style={{marginBottom:5,marginRight:5}}/>
<div>
<div>
{i.typeName}
</div>
{ temp === tempEnum.zone1 && <div className="linear_gradient">{i.typeName}</div> }
</div>
</div>
<p className="card_desc">{i.typeIntroduction}</p>
{
i.zoneMemberList && i.zoneMemberList.length > 0 ?
<ul className="card_ul">
{
i.zoneMemberList.map((j,key)=>{
return(
<li className="card_u_li">
<div className="card_u_wrap">
<Link to={`/${j.login}`} ><img src={j.imageUrl} alt="" /></Link>
<div className="card_u_info">
<div className="card_u_up"><span className="card_name task-hide">{j.name}</span>{j.memberLevel && <span className="card_tag">{j.memberLevel}</span> }</div>
<p className="card_u_down task-hide-2">{j.introduction}</p>
</div>
</div>
</li>
)
})
}
</ul>
:
(
temp === tempEnum.zone1 ? <Nodata _html="暂无数据" img={ nodata }/> : <Nodata _html="暂无数据" />
)
}
</div>
)
})
}
</div>
)
}
export default Member;

View File

@ -1,36 +0,0 @@
import React from 'react';
import './index.scss';
import publicImg from '../../img/gitlink-gz.png';
import qqImg from '../../img/gitlink-qq.png';
function acce({type}){
return(
type === "head" ?
<div className="head_zone">
<a href="/"><img src={require('../../img/logo.png')} alt=""/></a>
</div>
:
<div>
<div style={{height: "26em"}}></div>
<div className="foot_zone">
<p style={{fontSize:'1.6em',color:"#141519"}}>欢迎加入GitLink</p>
<ul className="foot_ewm">
<li>
<img src={publicImg} alt="" />
<span>开源发展委员会<br/>公众号</span>
</li>
<li>
<img src={qqImg} alt="" />
<span>GitLink官方<br/>QQ群</span>
</li>
</ul>
<p className="foot_copyright">
<span>©Copyright 2023 CCF 开源发展委员会</span>
<span>Powered by Trustie& IntelliDE </span>
<span>京ICP备13000930号</span>
</p>
</div>
</div>
)
}
export default acce;

View File

@ -1,74 +0,0 @@
@media screen and (max-width: 750px){
#root{
width: 100%;
}
.newContainers{
min-width: unset;
}
}
.head_zone{
height: 4.4em;
background-color:#183553;
width: 100%;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
position: fixed;
top: 0px;
width: 100%;
z-index: 10;
img{
height: 2em;
}
}
.foot_zone{
background-image: url(../../img/f_banner.png);
background-size: 100% 100%;
height: 26em;
position: absolute;
bottom: 0px;
width: 100%;
left: 0px;
padding:1.6em 1.2em 0em 1.2em;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.foot_ewm{
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
padding:1.2em;
li{
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
img{
width: 7em;
height: 7em;
margin-bottom: 0.8em;
border-radius: 3px;
}
span{
display: block;
color:#444549;
text-align: center;
line-height: 1.5em;
}
}
}
.foot_copyright{
padding:1em 0;
border-top: 1px solid rgba(129, 131, 138, 0.15);
color:#63687a;
font-size: 1em;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 100%;
}
}

View File

@ -1,50 +0,0 @@
import React , { useState } from 'react';
function PublicBanner(props){
const [ key , setKey ] = useState("1");
const { deptId } = props.match.params;
const { pathname } = props.history.location;
const { data , adminUrl } = props;
return(
<div className="zone_news">
<p className="in_title mb40">新闻动态</p>
<div className="boxmain" style={{display:"flex"}}>
<div className="zone_new_first">
<img src={newsList[0].headImg || img1} alt="" height="302px" style={{width:"100%",objectFit:"cover"}} className="mb30"/>
<Link to={`/zone/${deptId}/newdetail/${newsList[0].id}`} className="zone_n_title task-hide">{newsList[0].name}</Link>
<p className="zone_n_desc task-hide-2">{newsList[0].summary}</p>
<p className="font-13 mt10 flexCenter" style={{color:"#8d95a3"}}>
<img src={shijian} alt="" className="mr3" />
{newsList[0].publishTime}
</p>
<p className="mt15">
<Link to={`/zone/${deptId}/newdetail/${newsList[0].id}`} className="color-blue flexCenter zone_btn">查看详情<img src={guideArrow} alt="" width="14px" className="ml3"/></Link>
</p>
</div>
<ul className={`zone_new_three ${newsList.length <4 ? "flexStart" : "spaceeTween"}`}>
{
newsList.map((i,k)=>{
return(
k > 0 && <li>
<Link className="zone_n_title task-hide" to={`/zone/${deptId}/newdetail/${i.id}`}>{i.name}</Link>
<p className="zone_n_desc task-hide-2 mt10">{i.summary}</p>
<p className="zone_n_value">
<span className="font-13" style={{color:"#8d95a3"}}>
<img src={shijian} alt="" className="mr3" />
{i.publishTime}
</span>
<Link to={`/zone/${deptId}/newdetail/${i.id}`} className="color-blue flexCenter zone_btn">查看详情<img src={guideArrow} alt="" width="14px"/></Link>
</p>
</li>
)
})
}
</ul>
</div>
</div>
)
}
export default newBox;

View File

@ -1,66 +0,0 @@
import React , { useEffect } from 'react';
// import Slider from 'react-slick';
import { httpUrl } from '../fetch';
import axios from 'axios';
import { useState } from 'react';
const settings = {
dots: false,
infinite: true,
slidesToShow: 1,
slidesToScroll: 1,
vertical: true,
verticalSwiping: true,
autoplay:true,
arrows:false
};
function Partner(props) {
const [ topics ,setTopics ] = useState(undefined);
const [ moreTypes ,setMoreTypes ] = useState(false);
const { id, partnerList } = props;
useEffect(()=>{
getUnit(partnerList);
},[id])
function getUnit(array){
const newArray = array
setMoreTypes(array.length > 1)
while(newArray[1] && newArray[1].length + newArray[0].length <= 5) {
newArray[0] = [...newArray[0], ...newArray.splice(1, 1)[0]]
}
setTopics(newArray)
}
return(
<ul className="boxmain zone_part_lists">
{
topics && topics.length>0 ?
topics.map((i, k)=>{
return(
<li key={ k }>
{
i.map((j,k1)=>{
return(
<div className="zone_part_item" key={ k1 }>
{ j.typeName && moreTypes && <span className="task-hide">{j.typeName}</span>}
{
j.link ? <a key={ k1 } href={ j.link } target="_blank" ><img src={j.logo} alt=""/></a>
:
<div><img src={j.logo} alt=""/></div>
}
</div>
)
})
}
</li>
)
})
:
""
}
</ul>
)
}
export default Partner;

View File

@ -1,83 +0,0 @@
import React , { useEffect, useRef, useState } from 'react';
import Slider from 'react-slick';
import projectRight from '../img/projectRight.png';
import projectLeft from '../img/projectLeft.png';
function SampleNextArrow(props) {
const { className, activeSlide, total , onClick } = props;
return (
activeSlide !== (total - 3) && <img src={projectRight} className={`right_arraw ${className}`} onClick={onClick}></img>
);
}
function SamplePrevArrow(props) {
const { className, activeSlide, total , onClick } = props;
return (
activeSlide !== 0 && <img src={projectLeft} className={`left_arraw ${className}`} onClick={onClick}></img>
);
}
function Projects(props) {
const { projectList } = props;
const sliderRef = useRef(null)
const [ activeSlide , setActiveSlide ] = useState(undefined);
const settings = {
className: "center",
centerMode: true,
infinite: false,
centerPadding: "100px",
slidesToShow: 3,
speed: 500,
nextArrow: <SampleNextArrow className="right_arraw" activeSlide={ activeSlide } total={ projectList.length }/>,
prevArrow: <SamplePrevArrow className="left_arraw" activeSlide={ activeSlide } total={ projectList.length }/>,
afterChange: current => { setActiveSlide(current) }
};
useEffect(()=>{
if(sliderRef && projectList && projectList.length > 2){
sliderRef.current.slickNext()
}
},[sliderRef])
return(
<div className={`boxmain ${ projectList.length !== 3 && 'not_three_project' } ${ projectList.length < 3 && 'less_three_project' }`}>
{
projectList && projectList.length > 0 ?
(projectList.length < 3 ?
projectList.map((i,k)=>{
return(
<div className="container" key={ k }>
<div className="zone_p_item">
{i.projectProperties && i.projectProperties.authorImageUrl && <img className="info_img" src={i.projectProperties.authorImageUrl} alt="" /> }
<p className="z_p_title task-hide" onClick={()=>window.open(i.projectURL)}>{i.projectProperties && i.projectProperties.name}</p>
<p className="z_p_desc task-hide-2">{i.projectProperties && i.projectProperties.description ? i.projectProperties.description : "暂无~"}</p>
</div>
</div>
)
})
:
<Slider ref={sliderRef} {...settings}>
{
projectList.map((i,k)=>{
return(
<div className="container" key={ k }>
<div className="zone_p_item">
{i.projectProperties && i.projectProperties.authorImageUrl && <img className="info_img" src={i.projectProperties.authorImageUrl} alt="" /> }
<p className="z_p_title task-hide" onClick={()=>window.open(i.projectURL)}>{i.projectProperties && i.projectProperties.name}</p>
<p className="z_p_desc task-hide-2">{i.projectProperties && i.projectProperties.description ? i.projectProperties.description : "暂无~"}</p>
</div>
</div>
)
})
}
</Slider>
)
:""
}
</div>
)
}
export default Projects;

View File

@ -1,74 +0,0 @@
import React , { useState , useEffect } from 'react';
import { Menu } from 'antd';
import { Link } from 'react-router-dom';
import { tempConfig } from '../tempInfo';
import TopEdition from './TopEdition'
function PublicBanner(props){
const [ key , setKey ] = useState("1");
const { deptId } = props.match.params;
const { pathname } = props.history.location;
const { data:{sectionHomepageShow, sectionHomepageTitle, sectionProjectShow,sectionDataSetShow,sectionDataSetTitle, sectionProjectTitle, sectionResourceShow, sectionResourceTitle, sectionCmsShow, sectionCmsTitle, sectionMemberShow, sectionMemberTitle, sectionHelperShow, sectionHelperTitle}, data , adminUrl, temp } = props;
useEffect(()=>{
if(pathname){
const info = /[A-Za-z0-9]{0,}\/news/g;
const infodetail = /[A-Za-z0-9]{0,}\/newdetail/g;
const project = /[A-Za-z0-9]{0,}\/projects/g;
const source = /[A-Za-z0-9]{0,}\/source/g;
const vip = /[A-Za-z0-9]{0,}\/VIP/g;
const help = /[A-Za-z0-9]{0,}\/help/g;
const dataset = /[A-Za-z0-9]{0,}\/dataset/g;
if(pathname === `/zone/${deptId}`){
setKey("1");
}
else if(project.test(pathname)){
setKey("2");
}
else if(source.test(pathname)){
setKey("3");
}
else if(info.test(pathname) || infodetail.test(pathname)){
setKey("4");
}
else if(vip.test(pathname)){
setKey("6");
}
else if(help.test(pathname)){
setKey("8");
}
else if(dataset.test(pathname)){
setKey("9");
}
}
},[pathname])
return(
<div className="in_banner">
<TopEdition bannerList={ data && data.bannerList && data.bannerList.split(",") }></TopEdition>
{
data &&
<div className="zone_content">
<p className="main_t">{data.mainTitle}</p>
<p className="sub_t" dangerouslySetInnerHTML={{ __html: data.subTitle }}></p>
</div>
}
<div className="bannerMenus">
<Menu mode={"horizontal"} selectedKeys={[key]}>
{sectionHomepageShow && <Menu.Item key={"1"}><Link to={`/zone/${deptId}`}><img src={require(`../img/${temp}Menu1.png`)} alt="" width="29px"/>{sectionHomepageTitle}</Link></Menu.Item>}
{sectionProjectShow && <Menu.Item key={"2"}><Link to={`/zone/${deptId}/projects`}><img src={require(`../img/${temp}Menu2.png`)} alt="" width="34px"/>{sectionProjectTitle}</Link></Menu.Item>}
{sectionDataSetShow && <Menu.Item key={"9"}><Link to={`/zone/${deptId}/dataset`}><img src={require(`../img/${temp}Menu9.png`)} alt="" width="34px"/>{sectionDataSetTitle}</Link></Menu.Item>}
{sectionResourceShow && <Menu.Item key={"3"}><Link to={`/zone/${deptId}/source`}><img src={require(`../img/${temp}Menu3.png`)} alt="" width="33px"/>{sectionResourceTitle}</Link></Menu.Item>}
{sectionCmsShow && <Menu.Item key={"4"}><Link to={`/zone/${deptId}/news`}><img src={require(`../img/${temp}Menu4.png`)} alt="" width="32px"/>{sectionCmsTitle}</Link></Menu.Item>}
{/* <Menu.Item key={"5"}><img src={Menu5} alt="" width="27px"/>Sig小组</Menu.Item> */}
{sectionMemberShow && <Menu.Item key={"6"}><Link to={`/zone/${deptId}/VIP`}><img src={require(`../img/${temp}Menu6.png`)} alt="" width="36px"/>{ sectionMemberTitle }</Link></Menu.Item>}
{sectionHelperShow && <Menu.Item key={"8"}><Link to={`/zone/${deptId}/help`}><img src={require(`../img/${temp}Menu8.png`)} alt="" width="36px"/>{data.sectionHelperTitle}</Link></Menu.Item>}
{ adminUrl && <Menu.Item key={"7"}><a onClick={()=>{window.location.href=adminUrl}}><img src={require(`../img/${temp}Menu7.png`)} alt="" width="34px"/>后台管理</a></Menu.Item> }
</Menu>
</div>
</div>
)
}
export default PublicBanner;

View File

@ -1,58 +0,0 @@
.partner_jcc{
.grow_path {
height: 100px;
display: flex;
justify-content: space-around;
align-items: center;
.grow_path_item {
z-index: 10;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
align-self: self-start;
cursor: pointer;
transition: 1s;
.grow_path_type {
// width: 82px;
height: 58px;
// color: black;
font-size: 15px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
}
.dot {
width:28px;
height:28px;
background-color:#ffffff;
border:7px solid;
border-color:#0d8dfd52;
border-radius: 50%;
transition: .5s;
}
}
.line {
height: 0px;
width: 1200px;
border-bottom: solid 1px #ddd;
transform: translate(0, -87px);
}
.zone_part_lists{
margin-top: 40px;
li {
max-height: 414px;
overflow-y: auto;
align-items: flex-start;
}
}
.type_active{
border-color: #0d8ffd !important;
}
::-webkit-scrollbar
{
display: none;
}
}

View File

@ -1,81 +0,0 @@
import React , { useEffect } from 'react';
import { useState } from 'react';
import './index.scss'
function Partner(props) {
const [ topics ,setTopics ] = useState(undefined);
const [ moreTypes ,setMoreTypes ] = useState(false);
const [ currentPartner ,setPartner] = useState(undefined);
const { id, partnerList } = props;
useEffect(()=>{
getUnit(partnerList);
},[id])
function getUnit(array){
const newArray = array
setMoreTypes(array.length > 1)
while(newArray[1] && newArray[1].length + newArray[0].length <= 5) {
newArray[0] = [...newArray[0], ...newArray.splice(1, 1)[0]]
}
setTopics(newArray)
setPartner(newArray[0][0].typeName)
}
return(
<div className='partner_jcc boxmain pt60 pb60'>
{
moreTypes &&
<div className="grow_path">
{
topics && topics.length>0 ?
topics.map((i, k) => {
return (
<div className="grow_path_item" key={ k } onClick={()=> setPartner(i[0].typeName)}>
<div className={`dot ${i[0].typeName === currentPartner ? 'type_active' : ''}`}></div>
<div className="grow_path_type">
{ i[0].typeName }
</div>
</div>
)
})
:
""
}
</div>
}
{
moreTypes && <div className="line"></div>
}
<ul className="zone_part_lists">
{
topics && topics.length>0 ?
topics.map((i, k)=>{
return(
<li key={ k } >
{
i[0].typeName === currentPartner ?
i.map((j,k1)=>{
return(
<div className="zone_part_item" key={ k1 }>
{
j.link ? <a key={ k1 } href={ j.link } target="_blank" ><img src={j.logo} alt=""/></a>
:
<div><img src={j.logo} alt=""/></div>
}
</div>
)
})
:
""
}
</li>
)
})
:
""
}
</ul>
</div>
)
}
export default Partner;

View File

@ -1,234 +0,0 @@
import React,{ useState, useRef, useEffect } from 'react';
import { httpUrl } from '../../fetch';
import img1 from '../../img/img1.png';
import visionFw from '../../img/vision-fw.png';
import visionYj from '../../img/vision-yj.png';
import visionZy from '../../img/vision-zy.png';
import visionJz from '../../img/vision-jz.png';
import guideArrow from '../../img/guideArrow1.png';
import { Link } from 'react-router-dom';
import shijian from '../../img/shijian.png';
import axios from 'axios';
import Projects from '../../Component/projects';
import PartnerJcc from './Component/partnerJcc';
import '../../indexZone1.scss'
import './index.scss'
import { Popover, Tabs } from 'antd';
let tabTimer = undefined;
function HeaderPageJCC(props){
const [ projectList , setProjectList ] = useState(undefined);
const [ personList , setPersonList ] = useState(undefined);
const [ newsList, setNewsList ] = useState(undefined);
const [ partnerList, setParterList ] = useState(undefined);
const { deptId } = props.match.params;
const { data, id, history } = props;
const [ activeKey, setActiveKey ] = useState(undefined);
const vision = [
{imageUrl: visionFw, title: '服务无边界'},
{imageUrl: visionYj, title: '云间有协作'},
{imageUrl: visionZy, title: '资源易共享'},
{imageUrl: visionJz, title: '价值可交换'}
]
useEffect(()=>{
if(id){
getProjectList();
getNewsList();
getPersonList();
getPartnerList();
}
return componentWillUnmount;
},[id])
function componentWillUnmount() {
clearInterval(tabTimer)
}
function getPersonList(){
const url = `${httpUrl}/zone/open/${id}/member/homePageList`;
axios.get(url).then(result=>{
if(result){
setPersonList(result.data.rows);
}
}).catch(error=>{})
}
function getNewsList(){
const url = `${httpUrl}/cms/doc/open/zone/${id}/homePageDocList`;
axios.get(url).then(result=>{
if(result){
setNewsList(result.data.rows);
clearInterval(tabTimer)
tabTimer = setInterval(() => {
handle(result.data.rows && result.data.rows[0].id, result.data.rows)
}, 4000)
}
}).catch(error=>{})
}
function getProjectList(){
const url = `${httpUrl}/zone/open/${id}/project/list`;
axios.get(url,{params:{
isHomepage:1
}}).then(result=>{
if(result){
if (result.data.rows.length < 3) {
setProjectList(result.data.rows)
} else {
setProjectList([...result.data.rows, {}]);
}
}
}).catch(console.error())
}
function getPartnerList(){
const url = `${httpUrl}/zone/open/${id}/partners/list`;
axios.get(url).then(result=>{
if(result){
const array = result.data.rows;
const newArray = [];
for(let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if ( e.zonePartnersList.length > 0 ) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
}).catch(error=>{})
}
function handle(value, rows){
// id
let idList = rows ? rows.map(obj => obj.id) : []
// tab
let tabs = document.querySelectorAll('.zone_news .ant-tabs-tab')
const tabIndex = idList.indexOf(Number(value))
if(tabIndex !== -1 ){
if(tabIndex !== idList.length -1){
tabs[tabIndex + 1].click()
}else{
tabs[0].click()
}
}
}
function handleTabChange(key) {
setTimeout(()=>{
setActiveKey(key)
},100)
clearInterval(tabTimer)
tabTimer = setInterval(() => {
handle(key, newsList)
}, 4000)
}
return(
<div className="zone_jcc_box">
{
//
data && (data.introductionTitle || data.introductionContent || data.introductionImage) &&
<div className="boxmain zone_infos mb30">
<div className="zone_infos_desc">
{data && <p className="in_title tleft">{data.firstTitle}</p>}
<p className="z_name">{data.introductionTitle}</p>
<p className="z_desc task-hide-2" dangerouslySetInnerHTML={{ __html: data.introductionContent }} ></p>
</div>
{
data.introductionImage &&
<img src={data.introductionImage} alt="" width="600px" height="361px"/>
}
</div>
}
<div className="zone_vision pt40 pb100">
<p className="in_title mb40">宗旨及愿景</p>
<div className='boxmain'>
{
vision.map((i, k) => {
return (
<div className="vision_item" key={ k }>
<div className="vision_icon">
<img src={i.imageUrl} alt="" />
</div>
<p className="vision_title">{ i.title }</p>
</div>
)
})
}
</div>
</div>
{
//
data && data.cmsShow === 1 && newsList && newsList.length>0 &&
<div className="zone_news">
<div className="boxmain" style={{display:"flex"}}>
<p className="news_title">{ data.homepageCmsTitle }</p>
<Tabs className='news_tab' tabPosition="left" onChange={handleTabChange} >
{
newsList.map((i,k)=>{
return(
<Tabs.TabPane tab={i.name} key={i.id}>
<div className='tab-content'>
<Link to={`/zone/${deptId}/newdetail/${i.id}`}><div className='title_JCC'>{i.name}</div>
<p><img src={shijian} alt="" className="mr3 photo" />{i.publishTime}</p>
<p className='new_desc'>{i.summary || '-'}</p>
<img src={newsList[k].headImg || img1} alt="" height="260px" style={{width:"100%",objectFit:"cover"}}/></Link>
</div>
</Tabs.TabPane>
)
})
}
</Tabs>
</div>
</div>
}
{
//
data && data.projectShow === 1 && projectList && projectList.length > 0 &&
<div className="zone_projects pt50 pb30">
<p className="in_title mb40">{ data.homepageProjectTitle }</p>
<Projects projectList={projectList}></Projects>
</div>
}
{
//
data && data.memberShow === 1 && personList && personList.length > 0 &&
<div className="zone_contributor">
<p className="in_title">{ data.homepageMemberTitle }</p>
{
<ul className="boxmain zone_c_lists">
{
personList.map((i,k)=>{
return(
<li key={k}>
<Popover overlayClassName="zone_popover" content={i.introduction || "暂无~"} title={i.name} trigger="hover">
<Link to={`/${i.login}`}><img src={i.imageUrl} alt="" /></Link>
</Popover>
</li>
)
})
}
</ul>
}
</div>
}
{
//
data && data.partnersShow === 1 && partnerList && partnerList.length > 0 &&
<div className="zone_parter">
<p className="in_title">{ data.homepagePartnersTitle }</p>
<PartnerJcc id={ id } partnerList={ partnerList }></PartnerJcc>
</div>
}
</div>
)
}
export default HeaderPageJCC;

View File

@ -1,361 +0,0 @@
@import '../../theme.scss';
.zone_jcc_box{
background-color: #f7f7f7;
padding-top:70px;
.zone_infos{
display: flex;
align-items: center;
margin-top: 54px;
padding:27px 24px;
position: relative;
&>img{
position: absolute;
right: 0;
top: 0;
border-radius: 4px;
object-fit: contain;
}
.zone_infos_desc{
position: relative;
padding:0px 34px 0px 10px;
flex: 1;
.tleft{
text-align: left;
margin-bottom: 25px !important;
}
.z_name{
color:#1f2329;
font-size:26px;
height: 28px;
line-height: 28px;
margin-bottom: 28px!important;
font-size: 20px;
}
.z_desc{
color:#3d485d;
font-size:14px;
line-height:32px;
word-break: break-all;
-webkit-line-clamp: 4;
white-space: pre-wrap;
background: white;
padding: 50px 250px 50px 50px;
margin-right: 350px;
color: inherit;
}
}
}
.zone_vision {
background-color: #ffffff;
.boxmain {
display: flex;
justify-content: space-between;
}
.vision_item {
width: 244px;
display: flex;
align-items: center;
flex-direction: column;
.vision_icon {
height: 162px;
width: 162px;
background-image: url(../../img/visionBack.png);
background-size: 100% 100%;
position: relative;
img {
width: 50%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
.vision_icon:hover {
background-image: url(../../img/visionBackActive.png);
}
.vision_title {
font-weight:700;
color:#1f2329;
font-size:17px;
line-height:27px;
text-align:center;
margin-top: 39px;
margin-top: 0;
font-weight: 600;
}
.vision_content {
margin-top: 21px;
color:#4c5876;
font-size:14px;
line-height:27px;
text-align:center;
}
}
}
.zone_news{
height: 30.2vw;
min-height: 475px;
background-color: #273144;
background-image: url(../../img/bgJccNews.png);
background-repeat: no-repeat;
background-size: cover;
.boxmain {
width: 1200px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.news_title {
height: 44px;
font-weight: 500;
color: #ffffff;
font-size: 32px;
text-align: center;
}
.photo {
margin-bottom: 3px;
margin-right: 5px;
}
.news_tab{
color: #fff;
height: 380px;
.ant-tabs-bar{
background-color: rgba(33, 84, 118, 0.5);
}
.ant-tabs-left-bar {
border-right-color: transparent !important;
}
.ant-tabs-nav-container{
font-size: 18px;
}
.ant-tabs-left-bar .ant-tabs-tab, .ant-tabs-right-bar .ant-tabs-tab {
padding: 34px 24px;
margin: 0;
text-align: left;
width: 260px;
overflow-x: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ant-tabs-left-content {
padding-left: 100px;
border-left-color: transparent !important;
}
.ant-tabs-tab-active{
background-color: #04BBF7;
color: white;
}
.ant-tabs-nav .ant-tabs-tab:active {
color: white;
}
.ant-tabs-ink-bar{
display: none !important;
}
.ant-tabs-nav .ant-tabs-tab:hover {
color: white;
}
.tab-content{
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.title_JCC{
font-size: 20px;
margin: 10px 0;
}
a:link, a:visited {
color: white;
}
.new_desc{
height: 48px;
font-size: 15px;
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
margin-top: 10px;
}
}
}
.zone_projects{
background-image:linear-gradient(180deg,#f1f4fa 0%,#ffffff 100%);
.right_arraw {
width: 48px;
height: 48px;
right: 0;
}
.left_arraw {
width: 48px;
height: 48px;
left: 0;
z-index: 100;
}
.slick-track {
display: flex;
align-items: center;
height: 435px;
.slick-slide {
height: auto;
}
}
.less_three_project {
display: flex;
justify-content: center;
.container {
.zone_p_item {
background: #fefefe;
}
margin: 10px;
}
}
.not_three_project {
.slick-track {
.slick-slide[aria-hidden="true"] {
opacity: 0;
}
}
}
.slick-current {
z-index: 100;
}
.slick-current .zone_p_item {
width:364px;
height:395px;
background:#fefefe;
}
.zone_p_item {
width: 364px;
height: 320px;
border-radius:16px;
padding: 42px 42px 35px 42px;
box-shadow:0px 0px 20px rgba(35, 54, 185, 0.06);
background: url(../../img/projectBg.png) no-repeat;
background-size: 100% 100%;
border-color:#ffffff;
transition: 0.3s;
display: flex;
flex-direction: column;
align-items: center;
.info_img {
width:74px;
height: 74px;
border-radius: 50%;
}
.z_p_title {
font-weight: 700;
color: #1f2329;
font-size: 16px;
text-align: center;
margin-top: 10px;
cursor: pointer;
width: 90%;
}
.z_p_desc{
margin-top: 18px;
color:#4c5876;
font-size:14px;
line-height:22px;
word-break: break-all;
-webkit-line-clamp: 5
}
}
.zone_p_item:hover {
.z_p_title {
color: #07a583;
}
}
}
.zone_contributor{
min-height: 466px;
background-color: #F7F9FC;
padding:44px 0px 30px;
.container {
height: 220px;
}
.zone_c_lists{
display: flex;
align-items: center;
margin-top: 50px;
flex-wrap: wrap;
li{
// background-image: url(./img/contributebg.png);
box-shadow:0px 0px 15px rgba(49,61,113,0.06);
background-size: 100% 100%;
width:80px;
height: 80px;
border:1px solid #fff;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 50%;
margin-bottom: 40px!important;
margin-right: 40px;
& img{
width: 80px;
height: 80px;
border-radius: 50%;
margin-bottom: 16px;
}
}
.slick-track {
display: flex;
}
.c_item {
margin-top: 40px;
margin-left: 10px;
width: 380px;
height: 165px;
background-image: url(../../img/cbg.png);
background-size: 100% 100%;
position: relative;
background-color:#f6f7fa;
border:2px solid;
border-color:#ffffff;
border-radius:4px;
box-shadow:0px 0px 10px rgba(7, 70, 165, 0.11);
padding: 30px 35px;
img {
position: absolute;
width:80px;
height:80px;
border-radius: 50%;
border: solid 2px #ffffff;
right: 27px;
top: -40px;
object-fit: cover;
}
.c_name {
color: #000000;
font-size: 16px;
text-align: center;
max-width: 240px;
}
.c_desc {
color: #4c5876;
font-size: 15px;
line-height: 26px;
}
}
.c_item:hover {
box-shadow:0px 0px 35px rgba(7, 70, 165, 0.11);
}
}
}
}
.zone_popover{
width: 300px;
:global{
.ant-popover-title{
font-weight: 600;
}
.ant-popover-content{
width: 300px;
}
}
}

View File

@ -1,184 +0,0 @@
import React, { useEffect } from 'react';
import { Form , Input , Row , Col, Button, message } from 'antd';
import '../index.scss';
import { postCreateZone } from '../api';
import axios from 'axios';
const { TextArea } = Input;
const phonereg = /^([1][3456789])\d{9}$/
function Apply(props){
const { form , current_user } = props;
const { getFieldDecorator , validateFields } = form;
useEffect(()=>{
document.title = '申请创建专区';
},[])
useEffect(()=>{
if(!(current_user && current_user.login)){
props.history.push("/403");
}
},[current_user])
function submitFunc(){
validateFields((error,values)=>{
if(!error){
const zoneApplication = {...values};
postCreateZone(zoneApplication).then(response=>{
if(response && response.data && response.data.code===200){
message.success("您的专区申请已提交,请耐心等待管理员与您联系!");
setTimeout(() => {
window.location.href="/";
}, 1000);
}
}).catch(error=>{})
}
})
}
function checkPhone(rule, value, callback){
if(!value){
callback();
}
if(!phonereg.test(value)){
callback("请输入正确的手机号码");
}
callback();
}
function checkId(rule,value,callback){
value ? axios.post(`/accounts/check_keywords`, {
text:value
}).then(response => {
if(response && response.data.data===false){
callback("与系统标识重复,请更改标识");
}
callback();
}):callback();
}
return(
<div className="applyBox">
<div className="applyContent">
<p className="apply-t">申请创建专区</p>
<div className="apply-tips">
<h5>申请说明</h5>
<p>1如果您想要创建自己的专区请填写下方页面中的信息来提交专区申请</p>
<p>2管理员在收到您的专区申请后将会通过您提供的联系方式与您进行沟通请您留意查收信息</p>
<p>3如果您的专区建设情况出色希望在官方专区列表中展示请发送邮件至官方邮箱 gitlink@ccf.org.cn并在邮件中注明推荐专区+您的专区链接经官方审核后您的专区将会被推荐展示</p>
</div>
<Form className="applyForm">
<Form.Item
label="专区名称"
>
{getFieldDecorator("name",{
rules:[
{required:true,message:"请输入专区名称"},
{pattern: /^[a-zA-Z0-9\u4e00-\u9fa5\\_.-]{1,31}$/, message: "长度1-30,支持中文,英文,数字,可包含下划线(_),中划线(-),英文句号(.)"}
]
})(
<Input placeholder="请输入专区名称" maxLength={30} style={{height:"36px"}}/>
)}
</Form.Item>
<Form.Item
label="专区介绍"
>
{getFieldDecorator("introduction",{
rules:[{required:true,message:"请输入专区介绍"}]
})(
<TextArea placeholder="请输入专区介绍内容" maxLength={200} rows={5}/>
)}
</Form.Item>
<Form.Item
label="专区用途"
>
{getFieldDecorator("purpose",{
rules:[]
})(
<TextArea placeholder="请输入专区用途内容" maxLength={200} rows={5}/>
)}
</Form.Item>
<Row type="flex" justify="space-between">
<Col span={11}>
<Form.Item
label="专区英文标识"
>
{getFieldDecorator("key",{
rules:[
// { required: true,message:"" },
{ pattern: /^[a-zA-Z][a-zA-Z0-9_-]{0,18}[a-zA-Z]$/, message: "长度2-20只能包含数字、字母、下划线、中划线必须以字母开头结尾"},
{ validator:checkId }
],
validateTrigger:"onBlur",
validateFirst: true,
})(
<Input placeholder="请输入专区域名标识,若未填写系统将根据专区名称自动生成" maxLength={20} style={{height:"36px"}}/>
)}
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
label="联系人"
>
{getFieldDecorator("contactPerson",{
rules:[{required:true,message:"请输入联系人"}]
})(
<Input placeholder="请输入联系人" maxLength={50} style={{height:"36px"}}/>
)}
</Form.Item>
</Col>
</Row>
<Row type="flex" justify="space-between">
<Col span={11}>
<Form.Item
label="联系人电话"
>
{getFieldDecorator("contactPhone",{
rules:[
{required:true,message:"请输入联系人电话"},
{
validator: (rule, value, callback) => { checkPhone(rule, value, callback) }
}
],
validateTrigger:"onBlur",
validateFirst: true,
})(
<Input placeholder="请输入联系人电话" maxLength={50} style={{height:"36px"}}/>
)}
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
label="联系人微信号"
>
{getFieldDecorator("contactWechat",{
rules:[]
})(
<Input placeholder="请输入联系人微信号" maxLength={50} style={{height:"36px"}}/>
)}
</Form.Item>
</Col>
</Row>
<Form.Item
label="希望平台提供的服务"
>
{getFieldDecorator("servicesProvided",{
rules:[]
})(
<TextArea placeholder="请输入您希望平台提供的服务" maxLength={200} rows={5}/>
)}
</Form.Item>
<div className="mt20">
<Button style={{height:"36px",width:"100px"}} type="primary" onClick={submitFunc}>提交</Button>
<Button style={{marginLeft:"30px",height:"36px",width:"100px"}} onClick={()=>{window.location.href="/"}}>取消</Button>
</div>
</Form>
</div>
</div>
)
}
export default Form.create({ name: 'ApplyNew' })(Apply);

View File

@ -1,126 +0,0 @@
import React,{ useState, useEffect } from 'react';
import { Breadcrumb , Tooltip , Table , Spin } from 'antd';
import paperImg from '../../img/paperImg.png';
import '../../index.scss';
import { Link } from 'react-router-dom';
import { getImageUrl } from 'educoder';
import { getDataSetdetail } from '../../api';
const defaultList=[
{title:"数据集名称数据集名称数据集名称数据集名称数据集名称",description:"描述描述内容",creator:{login:"innov",image_url:""},created_on:"2024-4-9 9:15",filesize:"15mb",url:"http://testforgeplus.trustie.net/"}
]
function Index(props){
const { deptId , datasetId } = props.match.params;
const [ detail , setDetail ] = useState(undefined);
const [ dataSource , setDataSource ] = useState(defaultList);
const [ total , setTotal ] = useState(0);
const [ page , setPage ] = useState(1);
const [ spinning , setSpinning ] = useState(true);
const pageSize = 10;
useEffect(()=>{
window.scrollTo(0,0);
},[datasetId])
useEffect(()=>{
Init();
},[page])
function Init(){
getDataSetdetail(datasetId,{limit:pageSize,page}).then(response=>{
if(response && response.data){
let data = response.data.data;
setDetail(data);
setDataSource(data.attachments);
setTotal(data.attachment_total_count);
setSpinning(false)
}
}).catch(error=>{})
}
const columns=[
{
title:"文件名称",
dataIndex:"title",
key:1,
ellipsis:true,
width:"25%"
},
{
title:"描述",
dataIndex:"description",
key:2,
ellipsis:true,
width:"27%",
render:(value)=>{
return <Tooltip title={value}>{value}</Tooltip>
}
},
{
title:"创建者",
dataIndex:"creator",
key:3,
width:"10%",
render:(value,item)=>{
return <Link to={`/${value.login}`}><img src={getImageUrl(`/${value.image_url}`)} alt="" style={{borderRadius:"50%"}} width="32px" height="32px" /></Link>
}
},
{
title:"上传时间",
dataIndex:"created_on",
key:4,
width:"15%"
},
{
title:"大小",
dataIndex:"filesize",
key:5,
},
{
title:"操作",
dataIndex:"url",
key:6,
width:"15%",
render:(value,item)=>{
return <a href={value} className="primaryColor" download={value}>下载</a>
}
},
]
return(
<div style={{background:"#fff"}}>
<Spin spinning={spinning}>
<div className='boxmain fileslist'>
<Breadcrumb separator=">">
<Breadcrumb.Item><Link className="primaryColor" to={`/zone/${deptId}/dataset`}>数据集</Link></Breadcrumb.Item>
<Breadcrumb.Item>文件</Breadcrumb.Item>
</Breadcrumb>
<div className='mnistData'>
<React.Fragment>
<div style={{width:0,flex:1}} className="mr20">
<div className="df mb15" style={{alignItems:"center"}}><p className="font-16 weight500 task-hide">{detail && detail.title}</p>{detail && detail.license_name ? <span className="license ml20">许可证 : {detail.license_name}</span> :""}</div>
<p style={{wordBreak:"break-all"}}>{detail && detail.description}</p>
</div>
<a href={detail && detail.repository_url} className="operateButton">进入项目</a>
</React.Fragment>
</div>
<Table
className={`datasetTable`}
columns={columns}
dataSource={dataSource}
pagination={{total,pageSize,current:page,hideOnSinglePage:true,onChange:(p)=>setPage(p)}}
/>
{
detail && detail.paper_content ?
<div className="mt25">
<p className="mb15 df" style={{alignItems:'center'}}><img src={paperImg} width={24} className="mr10" alt="" /><span className="font-16">研究论文</span></p>
<div className={`mnistData`}>{detail && detail.paper_content}</div>
</div>
:""
}
</div>
</Spin>
</div>
)
}
export default Index;

View File

@ -1,69 +0,0 @@
import React,{ useState, useEffect } from 'react';
import { Input } from 'antd';
import { Link } from 'react-router-dom';
import '../../index.scss';
import { getDataSet } from '../../api';
import Nodata from '../../../Nodata';
const { Search } = Input;
function Index(props){
const { deptId } = props.match.params;
const { id , temp, history, role, sectionResourceTitle } = props;
const [ data , setData ] = useState(undefined);
const [ search , setSearch ] = useState(undefined);
useEffect(()=>{
id && Init();
},[id, search])
function Init(){
getDataSet({id,search}).then(response=>{
if(response && response.data){
setData(response.data.rows);
}
}).catch(error=>{})
}
function onSourceSearch(e){
setSearch(e);
}
return(
<div className='zone_source_box'>
<div className='source_h'>
<p className='in_title'>数据集</p>
<div style={{marginTop:"30px",textAlign:"center"}} className='titleButBox'>
<Search
placeholder="请输入数据集名称"
onSearch={onSourceSearch}
style={{width:'645px',borderColor:"#fff",boxShadow:"0px 0px 10px rgba(61, 85, 183, 0.1)"}}
size="large"
className="source_search_box"
allowClear
enterButton={ <span><i className="iconfont icon-sousuo5 font-15"/>搜索</span> }
/>
</div>
</div>
<div className='sources datasetList'>
{
data && data.length > 0 ?
data.map((item,key)=>{
return(
<li>
<Link to={`/zone/${deptId}/dataset/${item.id}`}>
<p className='titile task-hide'>{item.dataSetName}</p>
<p className='task-hide-2 desc'>{item.dataSetDescription}</p>
{/* <span className='time'><i className='iconfont icon-a-31shijian'/>2023-09-08 15:54:23</span> */}
<span className='time task-hide'><i className='iconfont icon-daimakuicon1 font-14 mr8'/>{item.repositoryName}</span>
</Link>
</li>
)
}):""
}
{
data && data.length === 0 ?<div style={{textAlign:"center",width:"100%"}}><Nodata _html="暂无数据"/></div>:""
}
</div>
</div>
)
}
export default Index;

View File

@ -1,186 +0,0 @@
import React,{ useState, useEffect } from 'react';
import img1 from '../img/img1.png';
import { httpUrl } from '../fetch';
import guideArrow from '../img/guideArrow.png';
import { Link } from 'react-router-dom';
import shijian from '../img/shijian.png';
import { getHomePageList , gethomePageDocList , getAllList, getPartnerList } from '../api';
import axios from 'axios';
import Partner from '../Component/partner';
function HeaderPage(props){
const [ projectList , setProjectList ] = useState(undefined);
const [ personList , setPersonList ] = useState(undefined);
const [ newsList, setNewsList ] = useState(undefined);
const [ partnerList, setParterList ] = useState(undefined);
const { deptId } = props.match.params;
const { data, id, temp } = props;
useEffect(()=>{
if(id){
getProjectList();
getNewsList();
getPersonList();
getPartner();
}
},[id])
function getPersonList(){
getHomePageList(id).then(result=>{
if(result){
setPersonList(result.data.rows);
}
}).catch(error=>{})
}
function getNewsList(){
gethomePageDocList(id).then(result=>{
if(result){
setNewsList(result.data.rows);
}
}).catch(error=>{})
}
function getProjectList(){
getAllList(id,{isHomepage:1}).then(result=>{
if(result){
setProjectList(result.data.rows);
}
}).catch(console.error())
}
function getPartner(){
getPartnerList(id).then(result => {
if(result){
const array = result.data.rows;
const newArray = [];
for(let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if ( e.zonePartnersList.length > 0 ) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
})
}
return(
<div className="zone_box">
{data && <p className="in_title">{data.firstTitle}</p> }
{
//
data && (data.introductionTitle || data.introductionContent || data.introductionImage) &&
<div className="boxmain zone_infos">
<div className="zone_infos_desc">
{data.introductionTitle && <p className="z_name">{data.introductionTitle}</p>}
<p className="z_desc task-hide-2" style={{WebkitLineClamp:data.introductionTitle?"4":"7"}} dangerouslySetInnerHTML={{ __html: data.introductionContent }} ></p>
</div>
{
data.introductionImage &&
<img src={data.introductionImage} alt="" width="300px"/>
}
</div>
}
{
//
data && data.cmsShow === 1 && newsList && newsList.length>0 &&
<div className="zone_news">
<p className="in_title mb40">{ data.homepageCmsTitle }</p>
<div className="boxmain" style={{display:"flex"}}>
<div className="zone_new_first">
<img src={newsList[0].headImg || img1} alt="" height="302px" style={{width:"100%",objectFit:"cover"}} className="mb30"/>
<Link to={`/zone/${deptId}/newdetail/${newsList[0].id}`} className="zone_n_title task-hide">{newsList[0].name}</Link>
<p className="zone_n_desc task-hide-2">{newsList[0].summary}</p>
<p className="font-13 mt10 flexCenter" style={{color:"#8d95a3"}}>
<img src={shijian} alt="" className="mr3" />
{newsList[0].publishTime}
</p>
<p className="mt15">
<Link to={`/zone/${deptId}/newdetail/${newsList[0].id}`} className="color-blue flexCenter zone_btn">查看详情<img src={guideArrow} alt="" width="14px" className="ml3"/></Link>
</p>
</div>
<ul className={`zone_new_three ${newsList.length <4 ? "flexStart" : "spaceeTween"}`}>
{
newsList.map((i,k)=>{
return(
k > 0 && <li key={ k }>
<Link className="zone_n_title task-hide" to={`/zone/${deptId}/newdetail/${i.id}`}>{i.name}</Link>
<p className="zone_n_desc task-hide-2 mt10">{i.summary}</p>
<p className="zone_n_value">
<span className="font-13" style={{color:"#8d95a3"}}>
<img src={shijian} alt="" className="mr3" />
{i.publishTime}
</span>
<Link to={`/zone/${deptId}/newdetail/${i.id}`} className="color-blue flexCenter zone_btn">查看详情<img src={guideArrow} alt="" width="14px"/></Link>
</p>
</li>
)
})
}
</ul>
</div>
</div>
}
{
//
data && data.projectShow === 1 && projectList && projectList.length>0 &&
<div className="zone_projects">
<p className="in_title mb40">{ data.homepageProjectTitle }</p>
{
<div className="boxmain zone_p_lists">
{
projectList.map((i,k)=>{
return(
<li key={ k }>
<div className="imgBox">{i.projectProperties && i.projectProperties.authorImageUrl && <img src={i.projectProperties.authorImageUrl} alt="" /> }</div>
<div className="infosBox">
<a onClick={()=>window.open(i.projectURL)} className="z_p_title task-hide">{i.projectProperties && i.projectProperties.name}</a>
<p className="z_p_desc task-hide-2">{i.projectProperties && i.projectProperties.description ? i.projectProperties.description : "暂无~"}</p>
</div>
</li>
)
})
}
</div>
}
</div>
}
{
//
data && data.memberShow === 1 && personList && personList.length > 0 &&
<div className="zone_contributor">
<p className="in_title">{ data.homepageMemberTitle }</p>
{
<ul className="boxmain zone_c_lists">
{
personList.map((i,k)=>{
return(
<li key={ k }>
<Link to={`/${i.login}`}><img src={i.imageUrl} alt="" /></Link>
<span>{i.name}</span>
<p className="task-hide-2" style={{display:i.introduction?"":"flex"}}>{i.introduction || "暂无~"}</p>
</li>
)
})
}
</ul>
}
</div>
}
{
//
data && data.partnersShow === 1 && partnerList && partnerList.length > 0 &&
<div className="zone_parter">
<p className="in_title">{ data.homepagePartnersTitle }</p>
<Partner id={ id } partnerList={ partnerList }></Partner>
</div>
}
</div>
)
}
export default HeaderPage;

View File

@ -1,295 +0,0 @@
import React,{ useState, useEffect } from 'react';
import { httpUrl } from '../fetch';
import img1 from '../img/img1.png';
import img2 from '../img/img2.png';
import vision0 from '../img/vision0.png';
import vision1 from '../img/vision1.png';
import vision2 from '../img/vision2.png';
import vision3 from '../img/vision3.png';
import intro1 from '../img/intro1.png';
import intro2 from '../img/intro2.png';
import intro3 from '../img/intro3.png';
import intro4 from '../img/intro4.png';
import guideArrow from '../img/guideArrow1.png';
import ra from '../img/ra.png'
import title from '../img/title.png'
import { Link } from 'react-router-dom';
import shijian from '../img/shijian.png';
import Nodata from '../../Nodata';
import Projects from '../Component/projects';
import Contributor from '../Component/contributor';
import Partner from '../Component/partner';
import '../indexZone1.scss'
import { getProjectsLists, getPartnerList, getHomePageList, gethomePageDocList } from '../api'
function HeaderPage(props){
const [ projectList , setProjectList ] = useState(undefined);
const [ personList , setPersonList ] = useState(undefined);
const [ newsList, setNewsList ] = useState(undefined);
const [ partnerList, setParterList ] = useState(undefined);
const { deptId } = props.match.params;
const { data, id, temp, history } = props;
const vision = [
{imageUrl: vision0, title: '促进技术创新和应用', content: '通过开源芯片社区的建设,可以让更多的人参与到硬件开发中来,激发大众的创造力和创新精神,从而推动硬件领域的技术创新和实际应用。'},
{imageUrl: vision1, title: '降低硬件开发成本', content: '通过共享开源芯片设计和资源,可以帮助个人和小型企业降低硬件开发的成本,打破品牌垄断,促进市场竞争。'},
{imageUrl: vision2, title: '推广教育和普及知识', content: '通过开源芯片社区的建设,可以提供更多的硬件开发教育和知识普及资源,为学生、教师和爱好者等不同群体提供更多的学习机会和平台。'},
{imageUrl: vision3, title: '加强国际合作和交流', content: '开源芯片社区可以促进国内外的交流和合作,扩大中国在全球开源芯片领域的影响力,推动中外企业和机构之间的技术合作和交流。'}
]
const communityInfo = [
{ level: '普通用户', todo: '寻找项目或SIG组' },
{ level: '项目贡献者', todo: '参与项目贡献' },
{ level: '项目开发者', todo: '推动项目发展' },
{ level: '项目管理者', todo: '成为项目领军人物' }
]
const growPathInfo = [
{ type: '计划一', plan: '保留chisel语言学习学习' },
{ type: '计划二', plan: '小核、SoC快速开发初级、中级、高级' },
{ type: '计划三', plan: '果壳项目(初级、中级、高级)' },
{ type: '计划四', plan: '香山贡献参与' }
]
const introDetail = [
{ title: '能力阶梯', icon: intro1, desc: '成长体系按照开发者从⼊门到进阶再到⾹⼭顶级项⽬设⽴了⽤户能⼒提升的阶梯式真实项⽬' },
{ title: '贡献分级', icon: intro2, desc: '所有开源项⽬全部为开芯院开源开放的真实项⽬开发者参与开源项⽬的所有贡献将作为成长等级、知产授权、加⼊⾼级别项⽬悬赏、获得offer等、成为核⼼贡献者的参与 依据' },
{ title: '成长认证', icon: intro3, desc: '开发者可以通过完成开源项⽬对应的任务赢取对应能⼒成长认证开源项⽬对应的⾼级任务将获得对应等级L2或⾼级别的知识产权授权同时解锁下⼀级别成长任务' },
{ title: '顶级认证', icon: intro4, desc: '参与顶级项⽬“⾹⼭”的贡献者将获得中国科学院计算技术研究所副所长、研究员北京开源芯⽚研究院⾸席科学家RISC-V国际基⾦会理事会成员包云岗签名贡献者证书' }
]
useEffect(()=>{
if(id){
getProjectList();
getNewsList();
getPersonList();
getPartner();
}
},[id])
function getPersonList(){
getHomePageList(id).then(result=>{
if(result){
setPersonList(result.data.rows);
}
}).catch(error=>{})
}
function getNewsList(){
gethomePageDocList(id).then(result=>{
if(result){
setNewsList(result.data.rows);
}
}).catch(error=>{})
}
function getProjectList(){
getProjectsLists(id,{ isHomepage:1 }).then(result=>{
if(result){
if (result.data.rows.length < 3) {
setProjectList(result.data.rows)
} else {
setProjectList([...result.data.rows, {}]);
}
}
}).catch(error=>{})
}
function getPartner(){
getPartnerList(id).then(result => {
if(result){
const array = result.data.rows;
const newArray = [];
for(let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if ( e.zonePartnersList.length > 0 ) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
})
}
return(
<div className="zone1_box">
{
//
data && (data.introductionTitle || data.introductionContent || data.introductionImage) &&
<div className="boxmain zone_infos mb30">
<div className="zone_infos_desc">
<p className="z_name">{data.introductionTitle}</p>
<p className="z_desc task-hide-2" dangerouslySetInnerHTML={{ __html: data.introductionContent }} ></p>
</div>
{
data.introductionImage &&
<img src={data.introductionImage} alt="" width="600px" height="361px"/>
}
</div>
}
<div className="zone_vision pt40 pb60">
<p className="in_title mb40">宗旨及愿景</p>
<div className='boxmain'>
{
vision.map((i, k) => {
return (
<div className="vision_item" key={ k }>
<div className="vision_icon">
<img src={i.imageUrl} alt="" />
</div>
<p className="vision_title">{ i.title }</p>
<p className="vision_content">{ i.content }</p>
</div>
)
})
}
</div>
</div>
{
//
data && data.cmsShow === 1 && newsList && newsList.length>0 &&
<div className="zone_news">
<div className="boxmain" style={{display:"flex"}}>
<p className="news_title">{ data.homepageCmsTitle }</p>
<div className="zone_new_first">
<p className="task-hide">
<span className="item_index">1</span>
<Link to={`/zone/${deptId}/newdetail/${newsList[0].id}`} className="new_first_title task-hide">{newsList[0].name}</Link>
</p>
<p className="new_first_desc mt20 task-hide">{newsList[0].summary}</p>
<p className="font-13 zone_n_value mt20" style={{color:"#8d95a3"}}>
<span className="flexCenter">
<img src={shijian} alt="" className="mr3" />
{newsList[0].publishTime}
</span>
<Link to={`/zone/${deptId}/newdetail/${newsList[0].id}`} className="zone_btn">查看更多<img src={guideArrow} alt="" width="14px" className="ml3"/></Link>
</p>
</div>
<ul className={ `zone_new_three ${ newsList && (newsList.length < 4) ? 'zone_new_two' : '' }`}>
{
newsList.map((i,k)=>{
return(
k > 0 &&
<div onClick={() => { history.push(`/zone/${deptId}/newdetail/${i.id}`) }}>
<li className="new_item" style={{ display: 'inline-block' }}>
<p className="task-hide">
<span className="item_index">{k + 1}</span>
<Link className="zone_n_title" to={`/zone/${deptId}/newdetail/${i.id}`}>{i.name}</Link>
</p>
<p className="zone_n_desc task-hide-2">{i.summary}</p>
<p className="zone_n_value">
<span className="font-13 flexCenter" style={{color:"#8d95a3"}}>
<img src={shijian} alt="" className="mr3" />
{i.publishTime}
</span>
<span className="flexCenter zone_btn">查看详情<img src={guideArrow} alt="" width="14px"/></span>
</p>
</li>
</div>
)
})
}
</ul>
</div>
</div>
}
{
//
data && data.projectShow === 1 && projectList && projectList.length > 0 &&
<div className="zone_projects pt50 pb30">
<p className="in_title mb40">{ data.homepageProjectTitle }</p>
<Projects projectList={projectList}></Projects>
</div>
}
{
//
data && data.memberShow === 1 && personList && personList.length > 0 &&
<div className="zone_contributor">
<p className="in_title">{ data.homepageMemberTitle }</p>
<Contributor personList={personList}></Contributor>
</div>
}
<div className="zone_community pt60 pb60">
<p className="in_title mb20">参与社区</p>
<p className="sub_title mb50"><img src={ra} alt="" className="mr5" />成为社区成员尽情发挥您的创意</p>
<div className="c_role boxmain">
{
communityInfo.map((i, k) => {
return (
<div className="c_role_item" key={ k }>
<p className="role_level">{ i.level }</p>
<p className="role_todo">{ i.todo }</p>
<div className="dot"></div>
</div>
)
})
}
</div>
<div className="dot_line"></div>
</div>
<div className="zone_grow pt60 pb60">
{/* <p className="in_title mb20">开源芯<b>⽚⽤</b>户成长体系介绍</p> */}
<p className="in_title mb20"><img src={ title } alt="" /></p>
<p className="sub_title">参与开源芯的开发者需要签署开源贡献者协议</p>
<p className="sub_title mb50">建议开发者按照开源项成长路径进参与稳步提升能降低跳级参与带来的挑战</p>
<div className="grow_path boxmain">
{
growPathInfo.map((i, k) => {
return (
<div className="grow_path_item" key={ k }>
{ k % 2 === 1 && <div className="dot"></div> }
<div className="grow_path_type">
<div></div>
<div></div>
<div></div>
{ i.type }
</div>
<p className="grow_path_plan">{ i.plan }</p>
{ k % 2 === 0 && <div className="dot"></div> }
</div>
)
})
}
</div>
<div className="line"></div>
<div className="grow_introduction boxmain pt40">
{
introDetail.map((i, k) => {
return (
<div className="intro_item" key={ k }>
<p className="intro_title">
<img src={i.icon} alt="" className="mr3" />
{ i.title }
</p>
<p className="intro_desc">{ i.desc }</p>
</div>
)
})
}
</div>
<div className="dot_line"></div>
</div>
<div className="zone_communicate">
<p className="in_title">集萃群智经验 交流心得体会</p>
<button onClick={() => { window.location.href = 'https://forum.gitlink.org.cn/forums/theme/135' }}>立即加入</button>
</div>
{
//
data && data.partnersShow === 1 && partnerList && partnerList.length > 0 &&
<div className="zone_parter">
<p className="in_title">{ data.homepagePartnersTitle }</p>
<Partner id={ id } partnerList={ partnerList }></Partner>
</div>
}
</div>
)
}
export default HeaderPage;

View File

@ -1,286 +0,0 @@
import React, { useState, useEffect } from 'react';
import img1 from '../img/img1.png';
import { httpUrl } from '../fetch';
import { Link } from 'react-router-dom';
import shijian from '../img/shijian.png';
import xuexi from '../img/xuexiguanli.png';
import { getHomePageList, gethomePageDocList, getAllList, getNewsAllList, getVIPLists } from '../api';
import axios from 'axios';
import Partner from '../Component/partner';
import MemberList from '../Component/memberList';
import '../indexZonebyCCF.scss';
import '../indexZone1.scss';
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import Slider from 'react-slick';
import Left from '../../../home/Img/left.png';
import Right from '../../../home/Img/right.png';
function HeaderPageCCF(props) {
const [projectList, setProjectList] = useState(undefined);
const [personList, setPersonList] = useState(undefined);
const [newsList, setNewsList] = useState(undefined);
const [partnerList, setParterList] = useState(undefined);
const { deptId, cateId } = props.match.params;
const { data, id, temp } = props;
const [mainList, setMainList] = useState(undefined);
const [tag,setTag] = useState(0);
const setting = {
dots: true,
infinite: true,
speed: 2000,
slidesToShow: 1,
slidesToScroll: 1,
pauseOnDotsHover: true,
autoplaySpeed: 5000,
pauseOnFocus: true,
autoplay: true,
arrows: true,
prevArrow: <img className='slick-prev slick-arrow' src={Left} width="70px" alt="" />,
nextArrow: <img className='slick-prev slick-arrow' src={Right} width="70px" alt="" />,
afterChange: (index)=> setTag(index)
}
useEffect(() => {
if (id||cateId) {
getProjectList();
getNewsList();
getPersonList();
getPartnerList();
getMainList();
}
}, [id,cateId])
function getPersonList() {
//
// getHomePageList(id).then(result => {
// if (result) {
// setPersonList(result.data.rows);
// }
// }).catch(error => { })
//
getVIPLists(id, {isHomepage: 1}).then(response=>{
if(response){
const list = response.data.rows && response.data.rows.filter(item=>item.zoneMemberList);
setPersonList(list);
}
})
}
function getNewsList() {
gethomePageDocList(id).then(result => {
if (result) {
setNewsList(result.data.rows);
}
}).catch(error => { })
}
function getProjectList() {
getAllList(id, { isHomepage: 1 }).then(result => {
if (result) {
setProjectList(result.data.rows);
}
}).catch(console.error())
}
function getPartnerList() {
const url = `${httpUrl}/zone/open/${id}/partners/list`;
axios.get(url).then(result => {
if (result) {
const array = result.data.rows;
const newArray = [];
for (let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if (e.zonePartnersList.length > 0) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
}).catch(error => { })
}
function getMainList() {
getNewsAllList(id).then(result => {
if (result) {
let rows = result.data.rows;
setMainList(rows);
}
}).catch(error => { })
}
return (
<div className="zone_box pb100">
{
//
data && data.cmsShow === 1 && newsList && newsList.length >= 0 &&
<div className="zone_news zone_news_ccf">
<p className="in_title mb50">{data.homepageCmsTitle}</p>
<div className="boxmain mb100" style={{ display: "flex" }}>
<div className="zone_new_first">
<Slider {...setting}>
{
newsList && newsList.length > 0 ?
newsList.map((i, k) => {
return (
<div className="regform" key={k}>
<div className="newsBannerBox">
<img src={i.headImg || img1} alt="" className='newsImg' onClick={()=>{window.location.href=`/zone/${deptId}/newdetail/${i.id}`}} />
</div>
</div>
)
})
:
""
}
</Slider>
</div>
<ul className={`zone_new_three_ccf ${newsList.length < 4 ? "flexStart" : "spaceeTween"}`}>
{
newsList.map((i, k) => {
return (
<li key={k} style={{boxShadow:"0px 0px 20px rgba(35, 54, 185, 0.06)"}}>
<Link className="zone_n_title" to={`/zone/${deptId}/newdetail/${i.id}`} style={{color:k===tag?"#466aff":""}} >{i.name}</Link>
<p className="zone_n_value">
<span className="font-15" style={{ color: "#8d95a3" }}>
<img src={shijian} alt="" className="mr3 photo" />
{i.publishTime}
</span>
<p className="font-15 flexCenter zone_btn" style={{ color: '#8d95a3' }} key={k} ><i className="iconfont icon-liulan font-15 lg ml7 mr5 lh26 icontianjiadaohangcolors" style={{ color: "#8d95a3" }} ></i>{i.visits}</p>
</p>
</li>
)
})
}
</ul>
</div>
{/* 图片下三个栏目 */}
<div className="List">
{
mainList && mainList.length > 0 ?
mainList.map((i, k) => {
if (i.name === "开源业内资讯" || i.name === "开源战略工作组" || i.name === "开源活动")
return (
<ul className="mainlist radius4">
<p className="font-17">
<img src={xuexi} alt="" className="mr10"></img>
{i.name}
<Link to={`/zone/${deptId}/news/${i.id}`}><i className="iconfont icon-youhua font-12 lg lh26 icontianjiadaohangcolors you " ></i></Link></p>
{
i.cmsDocList && i.cmsDocList.length > 0 ?
i.cmsDocList.map((j, k) => {
return (
<li key={k} className="task-hide font-14">
<Link to={`/zone/${deptId}/newdetail/${j.id}`} className="mt10">{j.name}</Link>
</li>
)
})
: ""
}
</ul>
)
})
:
""
}
</div>
</div>
}
{
//
data && data.projectShow === 1 && projectList && projectList.length > 0 &&
<div className="zone_projects">
<p className="in_title mb40">{data.homepageProjectTitle}</p>
{
<div className="boxmain zone_p_lists">
{
projectList.map((i, k) => {
return (
<li key={k}>
<div className="imgBox">{i.projectProperties && i.projectProperties.authorImageUrl && <img src={i.projectProperties.authorImageUrl} alt="" />}</div>
<div className="infosBox">
<a onClick={() => window.open(i.projectURL)} className="z_p_title task-hide">{i.projectProperties && i.projectProperties.name}</a>
<p className="z_p_desc task-hide-2">{i.projectProperties && i.projectProperties.description ? i.projectProperties.description : "暂无~"}</p>
<div className="z_p_language">
{
i.projectProperties.topics &&
<ul className="tag task-hide" key={k}>
{
i.projectProperties.topics.split(",").map(t => {
return (
<li className="tag_li">{t}</li>
)
})
}
</ul>
}
</div>
</div>
</li>
)
})
}
</div>
}
</div>
}
{data && <p className="in_title_a">{data.firstTitle}</p>}
{
//
data && (data.introductionTitle || data.introductionContent || data.introductionImage) &&
<div className="boxmain zone_infos">
<div className="zone_infos_desc">
{data.introductionTitle && <p className="z_name">{data.introductionTitle}</p>}
<p className="z_desc task-hide-2" style={{ WebkitLineClamp: data.introductionTitle ? "4" : "7" }} dangerouslySetInnerHTML={{ __html: data.introductionContent }} ></p>
</div>
{
data.introductionImage &&
<img src={data.introductionImage} alt="" width="300px" />
}
</div>
}
{
//
data && data.memberShow === 1 && personList && personList.length > 0 &&
<div className={`zone_contributor boxmain ${temp}_VIP_box`}>
<p className="in_title mb50">{data.homepageMemberTitle}</p>
{/* <MemberList vipLists={personList} temp={temp}/> */}
{personList && personList.map(item=>{
return <div>
<p className='font-18'>{item.typeName}</p>
<ul className="boxmain zone_c_lists mt20">
{
item.zoneMemberList.map((i, k) => {
return (
<li key={k}>
<Link to={`/${i.login}`}><img src={i.imageUrl} alt="" /></Link>
<div className='mb10'>
<span>{i.name}</span>
{i.memberLevel && <span className="memberLevel_tag ml10">{i.memberLevel}</span> }
</div>
<p className="task-hide-2" style={{ display: i.introduction ? "" : "flex" }}>{i.introduction || "暂无~"}</p>
</li>
)
})
}
</ul>
</div>
})}
</div>
}
{
//
data && data.partnersShow === 1 && partnerList && partnerList.length > 0 &&
<div className="zone_parter">
<p className="in_title">{data.homepagePartnersTitle}</p>
<Partner id={id} partnerList={partnerList}></Partner>
</div>
}
</div>
)
}
export default HeaderPageCCF;

View File

@ -1,254 +0,0 @@
import React, { useEffect, useState } from 'react';
import { Box, LongWidth, FlexAJ } from '../../Component/layout';
import { Affix, Button, Input, message, Spin, Tree } from 'antd';
import Nodata from '../../Nodata';
import nodata from '../img/nodata.png';
import { tempEnum } from '../tempInfo';
import { findFirstWiki, generateList, getParentKey, getWiki, parseSidebar, wikiPages } from '../../Wiki/api';
import RenderHtml from '../../../components/render-html';
import { Base64 } from 'js-base64';
import { getTocContent } from '../../../common/marked';
import { splitAndCombine } from '../../Wiki/utils';
const { Search } = Input;
const { DirectoryTree, TreeNode } = Tree;
function ProjectSource(props) {
const [loading, setLoading] = useState(false);
const [wikiList, setWikiList] = useState(undefined);
const [flattenedMenuList, setFlattenedMenuList] = useState([]);
const [initMenuList, setInitMenuList] = useState([]);
const [expandedKeys, setExpandedKeys] = useState(undefined);
const [wiki, setWiki] = useState(undefined);
const [wikiDetail, setWikiDetail] = useState(undefined);
const [autoExpandParent, setAutoExpandParent] = useState(false);
const [searchValue, setSearchValue] = useState("");
const [wikiContMenu, setWikiContMenu] = useState(undefined);
const { temp, history, data, adminUrl } = props;
let scroller = undefined;
const { owner, identifier, projectId } = (data && data.gitlinkProject) || {};
const wikiParams = {
owner,
repo: identifier,
projectId
};
const reg = /[.,/#!$%^&*;:{}=\-_`~():,。¥;「」|?》《~·【】‘、!]/g;
useEffect(() => {
if(!owner) return
// wiki
wikiPages(wikiParams).then(async res => {
if (res && res.message === "200") {
setWikiList(res.data);
// sidebarlist
const info = await parseSidebar(res.data, wikiParams);
if (!info) return
const { menuList } = info;
// wiki
const firstWiki = findFirstWiki(menuList);
if(firstWiki){
setExpandedKeys(splitAndCombine(firstWiki.key+""));
setWiki(firstWiki);
}
setFlattenedMenuList(generateList(menuList));
setInitMenuList(menuList);
} else {
setWikiList([]);
}
})
}, [owner])
useEffect(() =>{
if(!wiki){
return
}
// wiki
setLoading(true);
getWiki({
pageName: wiki.title_sub,
...wikiParams
}).then(res=>{
setLoading(false);
if (res && res.message === "200") {
setWikiDetail(res.data);
const tocContent = getTocContent();
setWikiContMenu(tocContent);
} else {
message.error("加载失败")
}
})
}, [wiki && wiki.title_sub])
useEffect(() => {
if (scroller) {
scroller.destroy();
}
if (!document.querySelector('.wikiContentHC .markdown_anchors')) {
return;
}
require('intersection-observer');
//
setTimeout(() => {
const linkNode = document.querySelectorAll(`.wikiContMenuBox li a`)[0];
linkNode && (linkNode.className = 'current');
}, 100);
const scrollama = require('scrollama');
scroller = scrollama();
scroller
.setup({
step: '.wikiContentHC .markdown_anchors',
offset: 0.2,
})
.onStepEnter(({ element }) => {
[].forEach.call(document.querySelectorAll('.wikiContMenuBox li a'), node => {
node.className = '';
});
const currentNode = document.querySelectorAll(`.wikiContMenuBox li a[href="#${element.textContent.toLocaleLowerCase()}"]`)[0];
if (currentNode) {
currentNode.className = 'current';
}
})
}, [wikiDetail])
useEffect(() =>{
//
const handleClick = (event) => {
let target = event.target;
if (target.tagName.toUpperCase() === 'A') {
let ancher = target.getAttribute('href');
if (ancher && ancher.startsWith('#')) {
event.preventDefault()
let viewEl = document.getElementById(ancher.replace(reg,""))
if (viewEl) {
viewEl.scrollIntoView(true);
// 170
window.scrollBy(0,-170);
}
}
}
};
//
const scroll = () =>{
var element = document.getElementById('wikiContMenuBox');
var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
var scrollHeight = document.documentElement.scrollHeight||document.body.scrollHeight;
if(scrollHeight-scrollTop <= windowHeight*1.2){
const maxElementHeight = (scrollHeight-scrollTop)/2-200;
element && (element.style.maxHeight = maxElementHeight + 'px');
}else if(scrollHeight-scrollTop <= windowHeight*1.5){
const maxElementHeight = (scrollHeight-scrollTop)/2-100;
element && (element.style.maxHeight = maxElementHeight + 'px');
}else{
element && (element.style.maxHeight = '80vh');
}
}
document.addEventListener("click", handleClick);
document.addEventListener("scroll", scroll);
return () => {
document.removeEventListener("click", handleClick);
document.removeEventListener("scroll", scroll);
};
}, [])
function changeSearchValue(value) {
if (value) {
const va = value.trim();
// item
const expandedKeys = flattenedMenuList.map(item => {
if (item.title.match(new RegExp(va, 'i'))) {
return getParentKey(item.key, initMenuList);
}
return null;
}).filter((item, i, self) => item && self.indexOf(item) === i);
setSearchValue(va);
setExpandedKeys(splitAndCombine(expandedKeys[0]));
} else {
setSearchValue("");
}
}
//
function onExpand(expandedKeys) {
setAutoExpandParent(false);
setExpandedKeys(expandedKeys);
}
//
function selectTree(keys,event){
let {isFile} = event.node.props.dataRef;
if(isFile){
setWiki(event.node.props.dataRef);
}
}
function renderTreeNodes(data) {
return data && data.length > 0 && data.map((item) => {
const matchResult = item.titleStr.match(new RegExp(searchValue, 'i'));
const title = matchResult ? (
<span>
{item.titleStr.substr(0, matchResult.index)}
<span style={{ color: '#f50' }}>{item.titleStr.substring(matchResult.index, matchResult.index+searchValue.length)}</span>
{item.titleStr.substr(matchResult.index+searchValue.length)}
</span>
) : (
<span>{item.titleStr}</span>
);
return (
<TreeNode title={title} key={item.key + ""} isLeaf={item.isFile} dataRef={item} className='menuHcNode font-15'>
{renderTreeNodes(item.children)}
</TreeNode>
);
});
}
const noDataText = adminUrl ? <a href={`${data && data.gitlinkProject.wiki_url}`} target="_blank" style={{color: '#466aff'}}>前往配置</a> : "正在建设中,敬请期待"
return (
<div className="in_pro">
<div className="boxmain" style={{ paddingTop: "56px" }}>
<p className="in_title mb30">{data && data.sectionHelperTitle}</p>
<Spin spinning={loading}>
{
wikiList && (wikiList.length > 0 ? <Box className='zoneHelpBox'>
{/* wiki目录导航 */}
<div className='leftMenuBox mr20'>
<div className='leftMenuHC'>
<Search
allowClear
placeholder="输入关键字搜索文件"
className="searchHC mb10"
onSearch={changeSearchValue}
/>
<DirectoryTree onSelect={selectTree} expandedKeys={expandedKeys} onExpand={onExpand} autoExpandParent={autoExpandParent} showIcon={false}>
{renderTreeNodes(initMenuList)}
</DirectoryTree>
</div>
</div>
{/* 内容区 */}
{wikiDetail && <LongWidth className='wikiContentBox'>
<Box>
<LongWidth>
<FlexAJ style={{alignItems: 'stretch'}}>
<div>
<div className='wikiTitleHC font-20 mb5'>{wikiDetail.name}</div>
{wikiDetail.commit && <div className='wikiUpdateTimeHC font-15'>更新时间{wikiDetail.commit.author.date || '刚刚'}</div>}
</div>
{adminUrl && <Button onClick={()=>{wiki && window.open(`${data && data.gitlinkProject.wiki_url}/${wiki.title_sub}/${wiki.key}`)}} className='zone_apply_button' style={{width: '90px', height: '34px'}}>配置内容</Button>}
</FlexAJ>
{wikiDetail.md_content && <RenderHtml className="wikiContentHC editor-content-panel mt20 imageLayerParent" value={ Base64.decode(wikiDetail.md_content) } url={history.location}/>}
</LongWidth>
{wikiContMenu && wikiContMenu !== "<ul></ul>" && <Affix offsetTop={80}>
<div id="wikiContMenuBox" className='wikiContMenuBox font-15' dangerouslySetInnerHTML={{ __html: wikiContMenu }}></div>
</Affix>}
</Box>
</LongWidth>}
</Box> : (temp === tempEnum.zone1 ? <Nodata _html={noDataText} img={nodata} /> : <Nodata _html={noDataText} />))}
</Spin>
</div>
</div>
)
}
export default ProjectSource;

View File

@ -1,238 +0,0 @@
import React , { useState , useEffect } from 'react';
import { Menu , Spin , Skeleton, Button, Dropdown } from 'antd';
import Hot from '../Component/hot';
import { Box , FlexAJ, LongWidth } from '../../Component/layout';
import { Link } from 'react-router-dom';
import Lists from './newsList';
import guideArrow from '../img/guideArrow.png';
import axios from 'axios';
import shijian from '../img/shijian.png';
import liulan from '../img/liulan.png';
import emptydata from '../../Images/nodata.png';
import DefaultImg from '../Component/defaultImg';
import { getNewsAllList , getNewsHotList } from '../api';
import { tempConfig, tempEnum } from '../tempInfo';
import { httpUrl } from '../fetch';
function Main(props){
const [ key , setKey ] = useState("1");
const [ mainList , setMainList ] = useState(undefined);
const [ name , setName] = useState(undefined);
const [ menuH , setMenuH ] = useState(true);
const [ hotList , setHotList ] = useState(undefined);
const [ isSpin , setIsSpin ] = useState(true);
const [ newCateId , setNewCateId ] = useState(undefined);
const { deptId , cateId } = props.match.params;
const { id, temp, role, history, sectionCmsTitle } = props;
const menu = (
<Menu>
<Menu.Item>
<a onClick={()=>{history.push(`/zone/${deptId}/news/add?type=richEditor`)}}>富文本编辑器</a>
</Menu.Item>
<Menu.Item>
<a onClick={()=>{history.push(`/zone/${deptId}/news/add?type=mdEditor`)}}>MD编辑器</a>
</Menu.Item>
</Menu>
);
useEffect(()=>{
if(id) {
setIsSpin(true);
if (temp === tempEnum.zone) {
getMainList();
} else {
getCateList();
}
getHotList();
}
},[id])
useEffect(() => {
if (newCateId) {
getSubHotList()
}
}, [newCateId])
function getMainList(){
getNewsAllList(id).then(result=>{
if(result){
let rows = result.data.rows;
setMainList(rows);
if (temp !== tempEnum.zone) {
selectCate(rows[0].id)
}
setTimeout(() => {
let ele = document.getElementById("menus");
if(ele){
let h = ele.clientHeight;
setMenuH(h>56);
}
setIsSpin(false);
}, 100);
}
}).catch(error=>{})
}
function getCateList() {
const url = `${httpUrl}/cms/doc/open/zone/${id}/dirList`;
axios.get(url).then(result=>{
if(result){
let rows = result.data.rows;
setMainList(rows);
if (temp !== tempEnum.zone) {
selectCate(rows[0].id)
}
setIsSpin(false);
}
}).catch(error=>{})
}
function getHotList(){
getNewsHotList(id,{
pageSize:15,pageNum:1
}).then(result=>{
if(result){
setHotList(result.data.rows);
}
}).catch(error=>{})
}
function getSubHotList() {
const url = `${httpUrl}/cms/doc/open/dir/${newCateId}/hotDocList`;
axios.get(url,{
params:{pageSize:15,pageNum:1}
}).then(result=>{
if(result){
setHotList(result.data.rows);
}
}).catch(error=>{})
}
function selectCate(id) {
setNewCateId(id)
props.history.push(`/zone/${deptId}/news/${id}`)
}
return(
<div>
<div className="main_content">
<div className="boxmain">
<div className='titleButBox'>
<p className="in_title">{sectionCmsTitle}</p>
{role && role.role !== "None" && <div className='createButs mt10'>
{role.role === "Member" && <Button type="primary" ghost className='mr20'>
<Link to={`/zone/${deptId}/news/self`}>我的文章</Link>
</Button>}
{role.role === "Member" ? <Dropdown overlay={menu}>
<Button icon='plus' type="primary" ghost>新建</Button>
</Dropdown> : <Button type="primary" ghost onClick={()=>{window.open(role.docManageUrl)}}>管理资讯</Button>}
</div>}
</div>
{
mainList && mainList.length>0 &&
(
temp === tempEnum.zone ?
<Menu mode={"horizontal"} id="menus" selectedKeys={[cateId||"0"]} style={{justifyContent:menuH?"flex-start":"center"}}>
<Menu.Item key={"0"}><Link to={`/zone/${deptId}/news`}>全部</Link></Menu.Item>
{
mainList.map((i,k)=>{
return(
<Menu.Item key={`${i.id}`}><Link to={`/zone/${deptId}/news/${i.id}`}>{i.name}</Link></Menu.Item>
)
})
}
</Menu>
:
<div className="main_tag">
{
mainList.map((i,k)=>{
if (k <= 4) {
return(
<div className={`main_tag_item task-hide ${newCateId === i.id ? 'main_tag_selected' : ''}`} key={`${i.id}`} onClick={() => selectCate(i.id)} >{i.name}</div>
)
}
})
}
</div>
)
}
{
!mainList && <div style={{height:105}}><Skeleton /></div>
}
</div>
<div style={{width:'1200px',margin:"0px auto"}}>
<Box>
<LongWidth>
<Spin spinning={isSpin}>
{
cateId ?
<Lists {...props}/>
:
<div style={{minHeight:"400px"}}>
{
mainList && mainList.length>0 &&
mainList.map((i,k)=>{
return(
<div className="main_card radius4" style={{paddingTop:"25px"}}>
<div className="guide">
<span className="task-hide">{i.name}</span>
{ i.cmsDocList && i.cmsDocList.length> 0 && <Link className="flexCenter" to={`/zone/${deptId}/news/${i.id}`} onClick={()=>{window.scrollTo(0,400)}}>更多<img src={guideArrow} alt="" width="14px"/></Link> }
</div>
<div>
{
i.cmsDocList && i.cmsDocList.length>0 ?
i.cmsDocList.map((j,e)=>{
return(
<div className="main_card_item" onClick={()=>{props.history.push(`/zone/${deptId}/newdetail/${j.id}`)}}>
{e===0 &&
(
j.headImg ?
<img src={j.headImg} alt=""/>
:
<DefaultImg name="GitLink" title={i.name} />
)
}
<div style={{flex:1,width:0}}>
<Link to={`/zone/${deptId}/newdetail/${j.id}`} className={`sub_name task-hide ${e===0? "":"sub_i"}`}>{j.name}</Link>
<p className={`sub_desc ${e===0? "task-hide-2":"task-hide"}`}>
{j.summary}
</p>
<div className="sub_info">
<span><img src={shijian} alt="" />{j.publishTime}</span>
<span><img src={liulan} alt="" />{j.visits}</span>
</div>
</div>
</div>
)
})
:
<div style={{display:"flex",justifyContent:"center",alignItems:"center",flexDirection:"column",height:300}}>
<img src={emptydata} alt="" width="230"/>
<p className="font-15 color-grey-6 mt20">暂无数据~</p>
</div>
}
</div>
</div>
)
})
}
</div>
}
</Spin>
</LongWidth>
{
hotList && hotList.length>0 &&
<div className="short_width radius4">
<Hot temp={ temp } title={ tempConfig[temp].hotTitle } list={hotList} deptId={deptId}/>
</div>
}
</Box>
</div>
</div>
</div>
)
}
export default Main;

View File

@ -1,186 +0,0 @@
import React,{ useState , useEffect } from 'react';
import { Breadcrumb, Button, Form, Input, message, Select } from 'antd';
import { getZoneUrl } from 'educoder';
import MdEditor from '../../../modules/tpm/challengesnew/tpm-md-editor';
import RichEditor from '../../Component/RichEditor';
import UploadImage from '../../Team/Component/UploadImage';
import { tempConfig } from '../tempInfo';
import '../index.scss';
import { Base64 } from 'js-base64';
import { addNewsByDirId, getDirListById, getNewsDetailByAu, updateDoc } from '../api';
import { httpUrl } from '../fetch';
function NewsCreate(props){
const {history, id, role, current_user} = props;
const temp = props.temp;
const { getFieldDecorator, validateFields , setFieldsValue, setFields } = props.form;
const { deptId, id: newsId } = props.match.params;
const pathname = props.location.pathname;
const [type, setType] = useState(new URLSearchParams(props.location.search.substring(1)).get('type'));
const [value, setValue] = useState(undefined);
const [imageUrl, setImageUrl] = useState(undefined)
const [dirList, setDirList] = useState(undefined);
const [loading, setLoading] = useState(false);
const [isEdit, setIsEdit] = useState(false);
const { sectionCmsTitle } = props.data;
const layout = {
labelCol: { span: 2 },
wrapperCol: { span: 14 },
};
useEffect(()=>{
if((role && role.role === "None") || (current_user && !current_user.login)){
history.push(`/zone/${deptId}`);
}
}, [role])
useEffect(()=>{
id && getDircList();
},[id])
useEffect(()=>{
if(pathname){
if(pathname.endsWith("/edit")){
setIsEdit(true);
getNewsDetail();
}else{
setIsEdit(false);
}
}
},[pathname])
function getDircList(){
getDirListById(id).then(res=>{
if(res){
setDirList(res.data.rows);
}
})
}
function getNewsDetail() {
getNewsDetailByAu(newsId).then(res=>{
if(res && res.data){
const {name, summary, cmsDir, content, headImg, editorType} = res.data.data;
setType(editorType === "rich_editor" ? 'richEditor' : 'mdEditor')
setFieldsValue({
name,
summary,
dirId: cmsDir && cmsDir.id,
content: Base64.decode(content),
headImg
});
setImageUrl(headImg);
setValue(Base64.decode(content));
}
})
}
//
function submit(e){
e.preventDefault();
validateFields((err, fieldsValue)=>{
const hasContent = type === "richEditor" && fieldsValue.content === "<p><br></p>"
if(err || hasContent){
hasContent && setFields({content: {value:fieldsValue.content,errors:[new Error('请输入内容!')]}});
return;
}
setLoading(true);
const params = {
...fieldsValue,
editorType: type === "richEditor" ? "rich_editor" : "markdown_editor",
headImg: imageUrl,
content: Base64.encode(fieldsValue.content)
}
if(isEdit){
delete params.editorType;
return updateDoc(newsId, params).then(res=>{
const {data:{code, msg}} = res;
setLoading(false);
if(code === 200){
message.success("提交成功");
history.push(`/zone/${deptId}/newdetail/${newsId}`);
}else{
message.error(msg || '提交失败,请联系管理员!')
}
}).catch(e=>{
setLoading(false);
})
}
addNewsByDirId(fieldsValue.dirId, params).then(res=>{
const {data:{code, msg, data}} = res;
setLoading(false);
if(code === 200){
message.success("提交成功");
history.push(`/zone/${deptId}/newdetail/${data}`);
}else{
message.error(msg || '提交失败,请联系管理员!')
}
}).catch(e=>{
setLoading(false);
})
})
}
return(
<div className='boxmain pt30 newsCreateBox pb100'>
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{ sectionCmsTitle }</Breadcrumb.Item>
<Breadcrumb.Item>{isEdit ? '编辑' : '新建'}文章</Breadcrumb.Item>
</Breadcrumb>
<div className='formBox'>
<Form {...layout} onSubmit={submit}>
<Form.Item label="标题">
{getFieldDecorator("name", {
rules:[{ required:true,message:"请输入文章标题!" },
{type: 'string', max: 200, message: "最大长度200"},
{pattern: /^[^<>[\]/\\]+$/, message: "不能输入特殊字符:< > [ ] / \\"}]
})(
<Input placeholder="请输入文章标题" maxLength={ 200 } width="220px"/>
)}
</Form.Item>
<Form.Item label="概览">
{getFieldDecorator("summary", {
rules:[{ required:true,message:"请输入概览!" },
{type: 'string', max: 200, message: "最大长度200"}]
})(
<Input.TextArea placeholder="请输入概览" maxLength={ 200 } width="220px"/>
)}
</Form.Item>
<Form.Item label="栏目">
{getFieldDecorator("dirId", {
rules:[{ required:true,message:"请选择文章所属栏目!" }]
})(
<Select placeholder="请选择文章所属栏目">
{dirList && dirList.map(item=>{
return <Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>
})}
</Select>
)}
</Form.Item>
<Form.Item label="内容" wrapperCol={{span: 21}}>
{getFieldDecorator("content",{
rules:[{required:true,message:"请输入内容!"}],
})(
type === "richEditor" ? <RichEditor uploadUrl={`${httpUrl}/file/common/upload`} videoUploadUrl={`${httpUrl}/file/common/upload?type=cms`} setValue={(value)=>{setFieldsValue({"content": value})}}/> : <MdEditor
placeholder={"请输入详细介绍"}
height={500}
className='editNewsMd'
initValue={value}
onChange={(value)=>{setFieldsValue({"content": value})}}
imageExpand={false}
></MdEditor>
)}
</Form.Item>
<Form.Item label="首图" extra="建议图片比例宽为32上传jpg、jpeg、webp、png、svg、gif、bmp格式的图片">
<UploadImage maxSize={ 5 } getImageUrl={ (url) => setImageUrl(url) } url={ imageUrl ? imageUrl : undefined} action={ getZoneUrl(`/api/cms/common/upload`) } />
</Form.Item>
<Form.Item wrapperCol={{ offset: 2 }}>
<Button className='mr20 themeBut' onClick={()=>{history.go(-1)}}>取消</Button>
<Button type="primary" htmlType="submit" loading={loading} className='themeBut'>提交</Button>
</Form.Item>
</Form>
</div>
</div>
)
}
export default Form.create()(NewsCreate);

View File

@ -1,192 +0,0 @@
import React,{ useState , useEffect, useRef } from 'react';
import { Badge, Breadcrumb , Divider, Spin } from 'antd';
import liulan from '../img/liulan.png';
import RenderHtml from '../../../components/render-html';
import { Base64 } from 'js-base64';
import { getNewsDetail } from '../api';
import { isPhone } from 'educoder';
import { tempConfig } from '../tempInfo';
import Acce from '../Component/mobile/accessory';
import { addMeta, setSeoMeta, configShareForCustom } from 'educoder';
import CommentList from '../Component/comments/list'
import { connect } from 'react-redux';
import { withRouter } from "react-router";
import { setZoneDetail, setNewsDetail } from '../../../redux/actions/server';
function NewsDetail(props){
const { deptId , id } = props.match.params;
const [ detail , setDetail ] = useState(props.newsDetail || undefined);
const [ cmsDir , setCmsDir ] = useState(props.newsDetail ? props.newsDetail.cmsDir : undefined);
const [ content , setContent]=useState( props.newsDetail ? Base64.decode(props.newsDetail.content) : undefined);
const [ isSpin , setIsSpin]=useState(false);
const [ commentReload, setCommentReload] = useState(undefined);
const temp = props.temp;
const zonedetail = props.zoneDetail || props.data;
if (__SERVER__ && detail) {
setMeta()
}
useEffect(()=>{
let initialContent = undefined;
//
if(detail){
const { name, cmsDir} = detail;
document.title = `${ name }/${ cmsDir.name }`;
setMeta()
setTimeout(() => {
configShareForCustom(detail.name, detail.summary, detail.headImg)
}, 1000);
}
if(isPhone() && zonedetail){
setTimeout(()=>{
window.scrollTo(0,1);
if(detail)
document.title = detail.name;
},100);
initialContent = document.querySelector('meta[name="viewport"]').getAttribute('content');
document.querySelector('meta[name="viewport"]').setAttribute('content','width=device-width, user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0');
}
return()=>{
if(isPhone()){
document.querySelector('meta[name="viewport"]').setAttribute('content', initialContent);
}
if (zonedetail) {
setMeta(true)
}
}
},[zonedetail,detail])
useEffect(()=>{
if(id){
window.scrollTo(0,isPhone() ? 0 : 450);
getDetails();
}
},[id])
function setMeta(unmount = false) {
if (unmount) {
document.title= zonedetail.name;
setSeoMeta(`${zonedetail.name}`, zonedetail.name, zonedetail.subTitle, `/zone/${deptId}`)
} else {
const { name, cmsDir, summary, id} = detail;
const title = `${ name }/${ cmsDir.name }`;
const keywords = `${ name },${ cmsDir.name },${ zonedetail.name }`;
document.title = title;
setSeoMeta(keywords, title, summary, `/zone/${deptId}/newdetail/${ id }`)
}
}
function getDetails(){
setIsSpin(true)
getNewsDetail(id).then(result=>{
if(result){
let data = result.data.data;
setDetail(data);
setCmsDir(data.cmsDir);
setContent(Base64.decode(data.content));
setIsSpin(false)
}
}).catch(error=>{
props.history.push(`/zone/${deptId}/news`);
setIsSpin(false)
})
}
return(
<React.Fragment>
{
isPhone() && <Acce type="head"/>
}
<div className={isPhone() ? "detail_news_phone" :"detail_news_all"}>
<Spin spinning={isSpin} size="large">
{
detail &&
<div className="d_news_box">
{
isPhone() && zonedetail &&
<div className="p_title_box">
<p className="p_t_title"><a href={`/zone/${deptId}`}>{zonedetail.name}</a></p>
<p className="p_t_desc" dangerouslySetInnerHTML={{ __html: zonedetail.introductionContent }}></p>
</div>
}
{
!isPhone() &&
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{ zonedetail.sectionCmsTitle }</Breadcrumb.Item>
{ cmsDir && <Breadcrumb.Item href={`/zone/${deptId}/news/${cmsDir.id}`}>{cmsDir.name}</Breadcrumb.Item> }
<Breadcrumb.Item>正文</Breadcrumb.Item>
</Breadcrumb>
}
<div className="info_text">
<div className="info_text_main">
<p className="i_name">{detail.name}</p>
<ul className="i_ul_value">
{ cmsDir && <li><a href={ detail.publishUserUrl } ><img src={ detail.publishUserImage } alt="" className="headimg" /> { detail.publishUserNickname }</a></li> }
{ cmsDir && <li>{ detail.isFirstPublish ? '创建于' : '更新于' }{detail.publishTime}</li> }
{ !!detail.visits && <li><img src={liulan} alt="" className="mr5" />{detail.visits}</li> }
{ detail.auditStatus === '2' && <li><Badge color={temp === "zone" ? "#466aff" : "#089f7f"} text="待审核" className='pass'/></li>}
{ detail.auditStatus === '0' && <li><Badge color="#eb1212" text="未通过" className='failed'/></li>}
</ul>
</div>
{ !isPhone() && <Divider dashed={true} /> }
{
content ?
<RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
:
<span>暂无详情~</span>
}
</div>
{
//
detail.auditStatus === '1' && <div>
<CommentList {...props} docId={ id } reload={commentReload} author={ detail.createBy } reloadComment={()=>{setCommentReload(Math.random())}}/>
</div>
}
</div>
}
</Spin>
</div>
{
isPhone() && <Acce type="foot" />
}
</React.Fragment>
)
}
const mapStateToProps = (state) => {
const {
zoneDetail,
newsDetail
} = state.zoneReducer;
return {
zoneDetail,
newsDetail
};
}
const mapDispatchToProps = (dispatch) => ({
clearProject: (type) => dispatch(actions.clearProject(type)),
});
NewsDetail.preFetch = ({ store, match, query }) => {
return new Promise(async function(resolve, reject) {
let { dispatch } = store;
// const { owner,projectsId } = match.params
const promises = [
dispatch(setZoneDetail(match.params)),
dispatch(setNewsDetail(match.params)),
];
const data = await Promise.all(promises);
resolve({
code: 200,
});
});
};
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(NewsDetail));

View File

@ -1,173 +0,0 @@
import React , { useEffect , useState } from 'react';
import PublicBanner from '../Component/publicBanner';
import { Box , LongWidth } from '../../Component/layout';
import { Menu , Breadcrumb , Pagination , Spin , Tooltip } from 'antd';
import Hot from '../Component/hot';
import axios from 'axios';
import shijian from '../img/shijian.png';
import liulan from '../img/liulan.png';
import DefaultImg from '../Component/defaultImg';
import emptydata from '../../Images/nodata.png';
import nodata from '../img/nodata.png';
import { Link } from 'react-router-dom';
import { httpUrl } from '../fetch';
import { tempEnum } from '../tempInfo';
function NewsList(props){
const { deptId , cateId } = props.match.params;
const [ pageNum , setPageNum ] = useState(1);
const [ total , setTotal ] = useState(0);
const pageSize = 15;
const [ columnList , setColumnList ] = useState(undefined);
const [ hostList , setHotList ] = useState(undefined);
const [ mainList , setMainList ] = useState(undefined);
const [ details , setDetails ] = useState(undefined);
const [ menuSpin , setMenuSpin ] = useState(true);
const { id, temp } = props;
useEffect(()=>{
if(id && cateId ){
setMenuSpin(true);
getMainList();
}
},[id,cateId,pageNum])
// useEffect(()=>{
// if(pageNum){
// window.scrollTo(0,400);
// }
// },[pageNum])
function getColumnDetail(){
const url = `${httpUrl}/cms/doc/open/dir/${cateId}`;
axios.get(url).then(result=>{
if(result){
setDetails(result.data.data);
}
}).catch(error=>{})
}
function getColumnList(){
const url = `${httpUrl}/cms/doc/open/zone/${id}/dirList`;
axios.get(url).then(result=>{
if(result){
setColumnList(result.data.rows);
setTotal(result.data.total);
setMenuSpin(false);
}
}).catch(error=>{})
}
function getMainList(){
const url = `${httpUrl}/cms/doc/open/dir/${cateId}/docList`;
axios.get(url,{
params:{
pageNum,pageSize
}
}).then(result=>{
if(result){
setMainList(result.data.rows);
setTotal(result.data.total);
setMenuSpin(false);
}
}).catch(error=>{})
}
function getHotList(){
const url = `${httpUrl}/cms/doc/open/dir/${cateId}/hotDocList`;
axios.get(url,{
params:{
pageNum:1,pageSize:15
}
}).then(result=>{
if(result){
setHotList(result.data.rows);
}
}).catch(errror=>{})
}
return(
// <div className="info_news_list">
// <div style={{width:'1200px',margin:"0px auto",padding:"30px 0px"}}>
// <Breadcrumb separator=">">
// <Breadcrumb.Item href={`/zone/${deptId}/news`}></Breadcrumb.Item>
// <Breadcrumb.Item>{details && details.name}</Breadcrumb.Item>
// </Breadcrumb>
// <p className="in_title mb30">{details && details.name}</p>
// <Box>
// <Spin spinning={menuSpin}>
// <div className="column_menu">
// {
// columnList && columnList.length>0 &&
// <Menu selectedKeys={[cateId]}>
// {
// columnList.map((i,k)=>{
// return(
// <Menu.Item key={i.id} value={i.id} ><Tooltip placement={'left'} title={i.name}><Link className="task-hide" onClick={()=>{if(document.documentElement.scrollTop > 600)window.scrollTo(0,480);}} to={`/zone/${deptId}/news/${i.id}`} title={i.name}>{i.name}</Link></Tooltip></Menu.Item>
// )
// })
// }
// </Menu>
// }
// </div>
// </Spin>
// <div className="column_content">
// <LongWidth>
<Spin spinning={menuSpin}>
<div className="main_card">
{
mainList && mainList.length>0 &&
mainList.map((i,k)=>{
return(
<div className="main_card_item" onClick={()=>{props.history.push(`/zone/${deptId}/newdetail/${i.id}`)}} key={k}>
{
i.headImg ?
<img src={i.headImg} alt=""/>
:
<DefaultImg name="GitLink" title={details && details.name} />
}
<div style={{flex:1,width:0}}>
<Link to={`/zone/${deptId}/newdetail/${i.id}`} className={`sub_name task-hide`}>{i.name}</Link>
<p className={`sub_desc task-hide-2`}>
{i.summary}
</p>
<div className="sub_info">
<span><img src={shijian} alt="" />{i.publishTime}</span>
<span><img src={liulan} alt="" />{i.visits}</span>
</div>
</div>
</div>
)
})
}
{
mainList && mainList.length === 0 &&
<div style={{display:"flex",justifyContent:"center",alignItems:"center",flexDirection:"column",height:500}}>
<img src={ temp === tempEnum.zone1 ? nodata : emptydata } alt="" width="300"/>
<p className="font-15 color-grey-6 mt20">暂无数据~</p>
</div>
}
{
total > pageSize &&
<div style={{padding:"25px 0px"}}>
<Pagination current={pageNum} pageSize={pageSize} total={total} showQuickJumper onChange={p=>{setPageNum(p)}}/>
</div>
}
</div>
</Spin>
// </LongWidth>
/* {
hostList && hostList.length>0 &&
<div className="short_width">
<Hot title="热门领域资讯" list={hostList} />
</div>
} */
/* </div>
</Box>
</div> */
// </div>
)
}
export default NewsList;

View File

@ -1,182 +0,0 @@
import React , { useEffect , useState } from 'react';
import Banner from '../Component/publicBanner';
import { Box , LongWidth } from '../../Component/layout';
import { Input , Menu , Pagination , Spin } from 'antd';
import { Link } from 'react-router-dom';
import Nodata from '../../Nodata';
import axios from 'axios';
import { getProjectsLists , getProjectsTypeLists } from '../api';
import nodata from '../img/nodata.png';
import { tempEnum } from '../tempInfo';
const { Search } = Input;
function ProjectSource(props){
const { deptId } = props.match.params;
const [ typeId , setTypeId ] = useState(0);
const [ typeList , setTypeList ] = useState(undefined);
const [ lists , setLists ] = useState(undefined);
const [ page, setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const pageSize = 20;
const [ searchName , setSearchName ] = useState(undefined);
const [ value , setValue ] = useState(undefined);
const [ loading , setLoading ] = useState(false);
const { id, temp, sectionProjectTitle } = props;
useEffect(()=>{
if(id){
getTypeList();
}
},[id])
useEffect(()=>{
if(id){
setLoading(true);
getLists();
}
},[id,typeId,page,searchName])
function getLists(){
getProjectsLists(id,{
pageNum:page,
name:searchName,
pageSize,
projectTypeId:typeId===0?undefined:typeId
}).then(result=>{
if(result){
setLists(result.data.rows);
setTotal(result.data.total);
setLoading(false);
}
}).catch(error=>{})
}
function getTypeList(){
getProjectsTypeLists(id).then(result=>{
if(result){
setTypeList(result.data.rows);
}
}).catch(error=>{})
}
const menu = (
<Menu>
<Menu.Item>更新时间排序</Menu.Item>
<Menu.Item>创建时间排序</Menu.Item>
<Menu.Item>fork数量排序</Menu.Item>
<Menu.Item>点赞数量排序</Menu.Item>
</Menu>
)
function changeValue(e){
if(!e.target.value && e.target.value !==value){
setSearchName(e.target.value);
}
setValue(e.target.value);
}
return(
<div className="in_pro">
{/* <Banner {...props}/> */}
<div className="boxmain" style={{paddingTop:"56px"}}>
<p className="in_title">{sectionProjectTitle}</p>
{ temp === tempEnum.zone1 && <p className="project_sub_title">聚合开源特色项目搭建硬件开源服务桥梁</p> }
<Box>
<ul className="in_pro_menu">
<li className="u_t"><i className="iconfont icon-muluicon font-15 mr10 mt2" style={{color:"#1f2329"}} />项目分类</li>
<li className={0 === typeId ? "active":""} onClick={()=>{setTypeId(0)}}>全部分类</li>
{
typeList && typeList.length>0 &&
typeList.map((i,k)=>{
return(
<li className={i.id === typeId ? "active":""} onClick={()=>{setTypeId(i.id);window.scrollTo(0,400)}}>{i.name}</li>
)
})
}
</ul>
<LongWidth>
<div className="in_list">
<div className="in_list_menu">
<Search
value={value}
onChange={changeValue}
onSearch={()=>{setSearchName(value)}}
allowClear={true}
size={'large'}
placeholder="请输入项目名称"
style={{width:645}}
enterButton={<span><i className="iconfont icon-sousuo5 font-15"/>搜索</span>}
/>
{/* <Dropdown overlay={menu} placement={"bottomRight"}>
<a className="color-blue" style={{display:'flex',alignItems:'center'}}>排序<i className="iconfont icon-sanjiaoxing-down ml5"></i></a>
</Dropdown> */}
</div>
<Spin spinning={loading}>
<div className={`in_list_box ${total>pageSize ?"in_box_line":""}`}>
{
lists && lists.length>0 ?
lists.map((i,k)=>{
return(
<div>
{i.projectProperties && <img src={i.projectProperties.authorImageUrl} alt="" className="author_img"/> }
<div style={{flex:"1"}}>
<p className="in_b_main">
<a onClick={()=>window.open(i.projectURL)}>{i.projectProperties && i.projectProperties.name}</a>
{
i.projectProperties &&
<ul>
{/* <li><i className="iconfont icon-guanzhuicon mr4"></i>333</li> */}
{ i.projectProperties.praisesCount > 0 && <li><i className="iconfont icon-xingzhuang font-15 mr4"></i>{i.projectProperties.praisesCount}</li> }
{ i.projectProperties.forkedCount > 0 && <li><i className="iconfont icon-morenfuke_icon1 font-16 mr4"></i>{i.projectProperties.forkedCount}</li> }
</ul>
}
</p>
{
i.projectProperties && i.projectProperties.description &&
<div className="in_b_desc task-hide-2">
{i.projectProperties.description}
</div>
}
{
i.projectProperties && i.projectProperties.topics &&
<ul className="in_b_tag">
{
i.projectProperties.topics.split(",").map(t=>{
return(
<li>{t}</li>
)
})
}
</ul>
}
<ul className="in_b_infos">
{/* { i.deptName && <li className="infos_cate">{i.deptName}</li> } */}
{ i.projectType && <li className={`infos_cate ${ i.projectProperties && i.projectProperties.language && 'show_after' }`}>{i.projectType}</li> }
{ i.projectProperties && i.projectProperties.language && <li className=" infos_language">{i.projectProperties.language}</li> }
{ i.projectProperties && i.projectProperties.timeAgo && <li><i className="iconfont icon-a-31shijian font-13 mr3"></i> 更新于{i.projectProperties.timeAgo}</li>}
</ul>
</div>
</div>
)
})
:""
}
{
lists && lists.length === 0 && (temp === tempEnum.zone1 ? <Nodata _html="暂无数据" img={ nodata }/> : <Nodata _html="暂无数据" />)
}
</div>
</Spin>
{
total > pageSize &&
<div style={{padding:"30px 0px",textAlign:"right"}}>
<Pagination pageSize={pageSize} current={page} onChange={(page)=>{setPage(page);window.scrollTo(0,0)}} total={total} showQuickJumper/>
</div>
}
</div>
</LongWidth>
</Box>
</div>
</div>
)
}
export default ProjectSource;

View File

@ -1,199 +0,0 @@
import React,{ useState, useEffect } from 'react';
import { Breadcrumb , Spin , Pagination , Modal, Button } from 'antd';
import { Link } from 'react-router-dom';
import { getNewsMyList , getSourceMyList , delNewsMyList , delSourceMyList } from '../api';
import moment from 'moment';
import nodata from '../img/nodata.png';
import { tempEnum } from '../tempInfo';
import emptydata from '../../Images/nodata.png';
import '../index.scss';
function SelfList(props){
const [ status , setStatus ] = useState(1);
const [ isSpin , setIsSpin ] = useState(true);
const [ source , setSource ] = useState(undefined);
const [ list , setList ] = useState(undefined);
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const [ visible ,setVisible ] = useState(false);
const [ deleId , setDeleId] = useState(undefined);
const pathname = props.location.pathname;
const { deptId} = props.match.params;
const { id , temp , data } = props;
// const { sectionCmsTitle } = data;
const sectionCmsTitle = data && data.sectionCmsTitle;
const limit = 15;
useEffect(()=>{
if(id){
setIsSpin(true);
getFunc(source);
}
},[id,source,page])
useEffect(()=>{
if(page===1){
setIsSpin(true);
getFunc(source);
}else{
setPage(1);
}
},[status])
function getFunc(s){
if(s===true){
getSource();
}
if(s===false){
getNew();
}
}
useEffect(()=>{
if(pathname){
if(pathname.indexOf("/source/self")>-1){
setSource(true);
}else{
setSource(false);
}
}
},[pathname])
function getSource(){
getSourceMyList({
auditStatus:status,
zoneId:id,
pageSize:limit,
pageNum:page
}).then(result=>{
let rows = result.data && result.data.rows;
if(rows && rows.length>0){
setList(rows);
}else{
setList([]);
}
setTotal(result.data.total);
setIsSpin(false);
})
}
function getNew(){
getNewsMyList(id,{
auditStatus:status===0 ? 2 : status === 2 ? 0 : 1,
pageSize:limit,
pageNum:page
}).then(result=>{
let rows = result.data && result.data.rows;
if(rows && rows.length>0){
setList(rows);
}else{
setList([]);
}
setTotal(result.data.total);
setIsSpin(false);
})
}
function cancelFunc(){
setVisible(false);
setDeleId(undefined);
}
function sureFunc(){
if(source){
delSourceMyList(deleId).then(response=>{
setVisible(false);
props.showNotification("删除成功!");
getSource();
})
}else{
delNewsMyList(deleId).then(response=>{
setVisible(false);
if(status ===1){
props.showNotification("提交成功!");
}else{
props.showNotification("删除成功!");
getNew();
}
})
}
}
return(
<div className="selfBoxContent">
<Modal
visible={visible}
width="456px"
title={`申请删除${source?"资源":"文章"}`}
onCancel={cancelFunc}
footer={null}
className="delSModal"
>
<div className="delBoxCon">
<i className="iconfont icon-shanchu_tc_icon font-22 mr15" style={{color:"#ca0002"}}></i>
<div>
<p className="font-15 mb15 mt5" style={{color:"#202d40"}}>确定删除该{source?"资源":"文章"}?</p>
{(source || (!source && status === 1 && (data && data.docNeedAudit===1))) && <p style={{color:"#5f6872"}}>{source?"删除后所有资源文件将被清除,请谨慎操作":"此操作将提交删除申请,管理员同意申请后该文章将被删除"}</p> }
</div>
</div>
<div className="delBoxBtn">
<Button onClick={cancelFunc} style={{borderColor:"#d9d9d9",color:"rgba(0, 0, 0, 0.65)"}}>取消</Button>
<Button type="primary" onClick={sureFunc} style={{backgroundColor:"#fff"}}>确认</Button>
</div>
</Modal>
<Breadcrumb separator=">" style={{paddingTop:"20px"}}>
<Breadcrumb.Item><Link className="primaryColor" to={pathname.replace("/self","")}>{ sectionCmsTitle }</Link></Breadcrumb.Item>
<Breadcrumb.Item>我的{source ? "资源":"文章"}</Breadcrumb.Item>
</Breadcrumb>
<ul className="selfMenu">
<li onClick={()=>setStatus(1)} className={status===1?"active":""}>已发布</li>
<li onClick={()=>setStatus(0)} className={status===0?"active":""}>待审核</li>
<li onClick={()=>setStatus(2)} className={status===2?"active":""}>未通过</li>
</ul>
<Spin spinning={isSpin}>
<div style={{backgroundColor:"#fff",borderRadius:"4px"}}>
<ul className="selfListPanel">
{
list && list.length === 0 &&
<div style={{display:"flex",justifyContent:"center",alignItems:"center",flexDirection:"column",height:500}}>
<img src={ temp === tempEnum.zone1 ? nodata : emptydata } alt="" width="300"/>
<p className="font-15 color-grey-6 mt20">暂无数据~</p>
</div>
}
{
list && list.length > 0 && list.map((i,k)=>{
return(
<li>
<div>
<Link to={`/zone/${deptId}/${source?"source":"newdetail"}/${i.id}`} className="s-name task-hide">{i.name}</Link>
<div className="s-info">
<span>
<span>{i.domainName || i.dirName}</span>
<span className="ml10 mr15">|</span>
<span><i className="iconfont icon-a-31shijian mr5 font-15"></i>{moment(i.createTime).format("YYYY/MM/DD")}</span>
</span>
<span className="s-info-right">
<a href={`/zone/${deptId}/${source ? 'source' : 'news'}/${i.id}/edit`} style={{color:"#466aff"}}><i className="iconfont icon-a-bianji12 mr5 font-14"></i>编辑</a>
<a style={{color:"#d81017",marginLeft:"25px"}}onClick={()=>{setVisible(true);setDeleId(i.id)}}><i className="iconfont icon-fuzhi-shanchu mr5 font-14"></i>删除</a>
</span>
</div>
</div>
</li>
)
})
}
</ul>
{
total > limit &&
<div style={{padding:"20px",textAlign:"right"}}>
<Pagination showQuickJumper current={page} total={total} pageSize={limit} onChange={(p)=>{setPage(p);window.scrollTo(0,450)}}/>
</div>
}
</div>
</Spin>
</div>
)
}
export default SelfList;

View File

@ -1,194 +0,0 @@
import React , { useEffect , useState } from 'react';
import { Button, Input , Pagination, Spin, Tag } from 'antd';
import SourceIcon from '../img/sourceIcon.png';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { getSourceTypeList , getSourceList , getSourceZoneList } from '../api';
import Nodata from '../../Nodata';
import ImgGreen from '../img/green_nodata.png';
import '../indexZone1.scss';
import { FlexAJ } from '../../Component/layout';
const { Search } = Input;
function Source(props){
const { deptId } = props.match.params;
const [ sourceList , setSourceList ] = useState(undefined);
const [ zoneList , setZoneList ] = useState(undefined);
const [ typeList , setTypeList ] = useState(undefined);
const [ chooseZoneId , setChooseZoneId ] = useState(undefined);
const [ chooseTypeId , setChooseTypeId ] = useState(undefined);
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const [ search , setSearch ] = useState(undefined);
const [ isSpin , setIsSpin ] = useState(true);
const limit = 20;
const { id , temp, history, role, sectionResourceTitle } = props;
useEffect(()=>{
id && getLists();
},[id,chooseTypeId,chooseZoneId,page,search])
useEffect(()=>{
id && getZoneList();
id && getTypeList();
},[id])
function getZoneList(){
getSourceZoneList(id).then(response=>{
if(response && response.data){
setZoneList(response.data.rows);
}
}).catch(error=>{})
}
function getTypeList(){
getSourceTypeList(id).then(response=>{
if(response && response.data){
setTypeList(response.data.rows);
}
}).catch(error=>{})
}
function getLists(){
setIsSpin(true);
getSourceList({
id,pageSize:limit,pageNum:page,searchTypeId:chooseTypeId,domainId:chooseZoneId,name:search
}).then(response=>{
if(response){
setSourceList(response.data.rows);
setTotal(response.data.total);
setIsSpin(false);
}
}).catch(error=>{})
}
function onSourceSearch(value){
setSearch(value);
setPage(1);
}
function addSource(){
if(role && role.role === "Manager"){
window.open(role.resourceManageUrl);
}else{
history.push(`/zone/${deptId}/source/add`)
}
}
return(
<div className={`${temp}_source_box`}>
<div className="source_h">
<p className="in_title">{sectionResourceTitle}</p>
<div style={{marginTop:"30px",textAlign:"center"}} className='titleButBox'>
<Search
placeholder="请输入资源名称"
onSearch={onSourceSearch}
style={{width:'645px',borderColor:"#fff",boxShadow:"0px 0px 10px rgba(61, 85, 183, 0.1)"}}
size="large"
className="source_search_box"
allowClear
enterButton={temp === "zone" ? <span><i className="iconfont icon-sousuo5 font-15"/>搜索</span> :undefined}
/>
{role && role.role !== "None" && <div className='createButs'>
{role.role === "Member" && <Button size='large' type="primary" ghost className='mr20'>
<Link to={`/zone/${deptId}/source/self`}>我的资源</Link>
</Button>}
<Button size='large' icon={role.role === "Member" && 'plus'} type="primary" ghost onClick={addSource}>{role.role === "Member" ? '新建' : '管理资源'}</Button>
</div>}
</div>
</div>
<div className="sources">
{
(zoneList && zoneList.length>0 ) || (typeList && typeList.length >0 ) ?
<div className="source_left_ul">
{
zoneList && zoneList.length>0 &&
<ul className="source_l_u">
<p>资源领域</p>
<div>
<li onClick={()=>{setChooseZoneId(undefined);window.scrollTo(0,450)}} className={!chooseZoneId ?"active":""}>全部</li>
{
zoneList.map((i,k)=>{
return(
<li key={k} onClick={()=>{setChooseZoneId(i.id);window.scrollTo(0,450)}} className={`${chooseZoneId && chooseZoneId === i.id ? "active":""} task-hide`}>{i.name}</li>
)
})
}
</div>
</ul>
}
{
typeList && typeList.length>0 &&
<ul className="source_l_u">
<p className="borderRight">资源类别</p>
<div>
<li onClick={()=>{setChooseTypeId(undefined);window.scrollTo(0,450)}} className={!chooseTypeId ?"active":""}>全部</li>
{
typeList.map((i,k)=>{
return(
<li key={k} onClick={()=>{setChooseTypeId(i.id);window.scrollTo(0,450)}} className={`${chooseTypeId && chooseTypeId === i.id ? "active":""} task-hide`}>{i.name}</li>
)
})
}
</div>
</ul>
}
</div>
:""
}
<Spin spinning={isSpin}>
<div className="s_m_list">
{
sourceList && sourceList.length > 0 &&
<div className="source_lists">
{sourceList.map((i,k)=>{
return(
<div className="source_lists_card" key={k}>
<Link to={`/zone/${deptId}/source/${i.id}`} onClick={()=>{window.scrollTo(0,450)}} className="task-hide">{i.name}</Link>
<p className="task-hide-2 desc">
{i.summary}
</p>
<div className="s_infos">
<FlexAJ>
{temp === "zone" && <span className='domainNameBox task-hide'>{i.domainName}</span>}
<p className="load_count">
<img src={SourceIcon} alt="" width="18px" className="mr5" style={{marginTop: '-4px'}}/><span style={{color:"#5e6685"}}>{i.downloadCount}</span>
</p>
</FlexAJ>
{temp === "zone1" && <p className="load_source">
<span>{i.domainName}</span>
{i.zoneResourceTypeList && <span>
{i.zoneResourceTypeList.reduce((pre, cur)=>{
return pre ? `${pre}, ${cur.name}` : cur.name
}, '')}
</span>}
</p>
}
</div>
</div>
)
})
}
</div>
}
{sourceList && sourceList.length === 0 &&
<div style={{textAlign:'center'}}>
<Nodata _html="暂无数据" img={temp === "zone1" ? ImgGreen : undefined}/>
</div>
}
{
total > limit &&
<div style={{textAlign:'center',padding:"20px 0px"}}>
<Pagination pageSize={limit} total={total} current={page} onChange={(p)=>{setPage(p);window.scrollTo(0,450);}} showQuickJumper/>
</div>
}
</div>
</Spin>
</div>
</div>
)
}
export default Source;

View File

@ -1,241 +0,0 @@
import React,{ useState , useEffect } from 'react';
import { Breadcrumb, Button, Form, Icon, Input, message, Select, Upload } from 'antd';
import { getZoneUrl } from 'educoder';
import '../index.scss';
import { Link } from 'react-router-dom';
import { getTypeByFileId, getSourceZoneList, addResource, getSourceDetailByAu, updateMyResource } from '../api';
function SourceCreate(props){
const {history, id, role, current_user} = props;
const { getFieldDecorator, validateFields , setFieldsValue, setFields } = props.form;
const { deptId, sourceid} = props.match.params;
const pathname = props.location.pathname;
const [ zoneList , setZoneList ] = useState(undefined);
const [files, setFiles] = useState([]);
const [loadingBut, setLoadingBut] = useState(false);
const [isEdit, setIsEdit] = useState(false);
const layout = {
labelCol: { span: 2 },
wrapperCol: { span: 14 },
};
useEffect(()=>{
if((role && role.role === "None") || (current_user && !current_user.login)){
history.push(`/zone/${deptId}`);
}
}, [role])
useEffect(()=>{
id && getZoneList();
},[id])
useEffect(()=>{
if(pathname){
if(pathname.endsWith("/edit")){
setIsEdit(true);
getSourceDetail();
}else{
setIsEdit(false);
}
}
},[pathname])
function getSourceDetail() {
getSourceDetailByAu(sourceid).then(res=>{
if(res && res.data){
const {name, domainId, summary, fileList} = res.data.data;
const fileMap = fileList.map(item=>{
const {fileId, fileSizeInfo, fileOriginName, zoneResourceType: {id, name}} = item;
return {
uid: fileId,
status: "done",
response: {fileId: fileId, fileSize: fileSizeInfo},
name: fileOriginName,
zoneResourceType:{id, name}
}
})
setFiles(fileMap);
setFieldsValue({
name,
domainId,
summary,
fileList: fileMap
});
}
})
}
function getZoneList(){
getSourceZoneList(id).then(response=>{
if(response && response.data){
setZoneList(response.data.rows);
}
}).catch(error=>{})
}
// /
function submit(e){
e.preventDefault();
validateFields((err, fieldsValue)=>{
if(err || !files.length){
!files.length && setFields({fileList: {value:undefined,errors:[new Error('请上传资源附件!')]}});
return;
}
const fileIds = files.map(item=>{return item.response.fileId}).toString();
const params = {
...fieldsValue,
zoneId: id,
fileIds
}
delete params.fileList;
if(isEdit){
delete params.zoneId;
params.id= parseInt(sourceid, 10);
updateMyResource(params).then((res)=>{
const {data:{code, msg}} = res;
if(code === 200){
message.success("提交成功");
history.push(`/zone/${deptId}/source/${sourceid}`);
}else{
message.error(msg || '提交失败,请联系管理员!')
}
})
return;
}
addResource(params).then((res)=>{
const {data:{code, msg, data}} = res;
if(code === 200){
message.success("提交成功");
history.push(`/zone/${deptId}/source/${data.id}`);
}else{
message.error(msg || '提交失败,请联系管理员!')
}
})
})
}
function beforeUpload(file){
if (file.size > 200 * 1024 * 1024) {
message.error('单个文件限制200MB以内');
return false;
}
if(files){
const sameNameFIles = files.filter(item=>item.name === file.name);
if(sameNameFIles.length >= 1){
message.error("请不要重复上传同名文件!");
return false;
}
}
return true;
}
async function onChange({file, fileList: fileListByUpload}){
if(file && (file.status === "done" || file.status === 'uploading' || file.status === 'removed')){
setLoadingBut(true);
const fileList = [...files];
const index = fileList.findIndex(item=>item.uid === file.uid);
if(index !== -1){
fileList[index] = file;
}else{
fileList.push(file);
}
setFiles(fileList);
if(!file.response) return
if(file.response.code !== 200){
message.error(file.response.msg || '上传失败,请联系管理员!')
fileList.pop()
setFiles([...fileList]);
setLoadingBut(false);
}else{
//
await getTypeByFileId(id, file.response.fileId).then((res)=>{
const {data:{code, data: data1, msg}} = res;
if(code !== 200){
return message.error(msg);
}
fileList[fileList.length-1].zoneResourceType = {
id: data1.id,
name: data1.name
}
})
setFiles([...fileList]);
setLoadingBut(false);
}
}
}
function deleteFile(uid){
const fileList = files.filter(item=>item.uid !== uid);
setFiles(fileList);
}
return(
<div className='boxmain pt30 newsCreateBox pb100 sourceCreateBox'>
<Breadcrumb separator=">">
<Breadcrumb.Item><Link className="primaryColor" to={`/zone/${deptId}/source`}>资源列表</Link></Breadcrumb.Item>
<Breadcrumb.Item>{isEdit ? '编辑' : '新建'}资源</Breadcrumb.Item>
</Breadcrumb>
<div className='formBox'>
<Form {...layout} onSubmit={submit}>
<Form.Item label="资源名称">
{getFieldDecorator("name", {
rules:[{ required:true,message:"请输入资源名称!" },
{type: 'string', max: 200, message: "最大长度200"}]
})(
<Input placeholder="请输入资源名称" maxLength={ 200 } width="220px"/>
)}
</Form.Item>
<Form.Item label="资源领域">
{getFieldDecorator("domainId", {
rules:[{ required:true,message:"请选择资源领域!" }]
})(
<Select placeholder="请选择资源领域">
{zoneList && zoneList.map(item =>{
return <Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>
})}
</Select>
)}
</Form.Item>
<Form.Item label="资源简介">
{getFieldDecorator("summary", {
rules:[{ required:true,message:"请输入资源简介!" },
{type: 'string', max: 300, message: "最大长度300"}]
})(
<Input.TextArea placeholder="请输入资源简介" maxLength={ 200 } width="220px"/>
)}
</Form.Item>
<Form.Item label="资源附件" extra={ <span >可上传多个资源文件单个文件限制200MB以内</span> }>
{getFieldDecorator("fileList", {
rules:[{ required:true,message:"请上传资源附件!" }]
})(
<Upload action={getZoneUrl(`/api/file/common/upload?type=resource`)} showUploadList={false} beforeUpload={beforeUpload} onChange={onChange} withCredentials={true} headers={{Authorization: "3e33a5b0a35824f93666b1084488f0bd5f010025"}}>
<Button className='hoverThemeColorBut'>
<Icon type="upload" />单击上传
</Button>
</Upload>
)}
</Form.Item>
{/* 附件展示 */}
<div className="sourceFilesBox">
{files && files.map((item, index)=>{
const {uid, status, response, name, zoneResourceType} = item;
return <div key={index} className="sourseFileItem mb15">
{status === "uploading" ? <Icon type="loading" className='mr10'/> : <Icon type="file" className='mr10'/>}
<span className="fileName task-hide">{name}</span>
<span className='mr20 ml20' style={{width: '100px'}}>{response && response.fileSize}</span>
<span className='mr50'>{zoneResourceType && zoneResourceType.name}</span>
<Icon type="delete" onClick={()=>{deleteFile(uid)}}/>
</div>
})}
</div>
<Form.Item wrapperCol={{ offset: 2 }}>
<Button className='mr20 themeBut' onClick={()=>{history.go(-1)}}>取消</Button>
<Button type="primary" htmlType="submit" loading={loadingBut} className='themeBut'>提交</Button>
</Form.Item>
</Form>
</div>
</div>
)
}
export default Form.create()(SourceCreate);

View File

@ -1,98 +0,0 @@
import React , { useEffect , useState } from 'react';
import { Badge, Breadcrumb } from 'antd';
import SourceFile from '../img/sourceFile.png';
import { getSourceDetail } from '../api';
import { Link } from 'react-router-dom';
import { httpUrl } from '../fetch';
import { AlignCenter, FlexAJ } from '../../Component/layout';
import SourceIcon from '../img/sourceIcon.png';
import { addMeta, setSeoMeta } from 'educoder';
function SourceDetail(props){
const { deptId , sourceid } = props.match.params;
const [ detail , setDetail ] = useState(undefined);
const zonedetail = props.data;
const {temp} = props;
useEffect(()=>{
if(sourceid){
getDetails();
}
},[sourceid])
useEffect(()=>{
//
if(detail){
const { name, domainName, summary} = detail;
document.title = `${ name }/${ domainName }`;
addMeta('Keywords', `${ name },${ domainName },${ summary }`);
}
return componentWillUnmount
}, [detail])
function componentWillUnmount() {
if (zonedetail) {
document.title= zonedetail.mainTitle;
setSeoMeta(`${zonedetail.name},`, zonedetail.name, zonedetail.subTitle, `/zone/${deptId}`)
}
}
function getDetails(){
getSourceDetail(sourceid).then(response=>{
if(response){
setDetail(response.data.data);
}
}).catch(error=>{})
}
return(
<div className="boxmain"style={{paddingBottom:"40px"}}>
<Breadcrumb separator=">" style={{paddingTop:"20px"}}>
<Breadcrumb.Item><Link className="primaryColor" to={`/zone/${deptId}/source`}>资源列表</Link></Breadcrumb.Item>
<Breadcrumb.Item>详情页</Breadcrumb.Item>
</Breadcrumb>
{
detail &&
<div className="source_detail_box">
<div className="s_d_title">
<FlexAJ>
<AlignCenter style={{flex: 1}}>
<span className='domainNameBoxD font-13 mr15'>{detail.domainName}</span>
<span className='font-22' style={{flex: 1}}>{detail.name}</span>
</AlignCenter>
<div className="load_count">
<img src={SourceIcon} alt="" width="18px" className="mr5" style={{marginTop: '-4px'}}/><span style={{color:"#5e6685"}}>{detail.downloadCount}</span>
</div>
</FlexAJ>
{detail.createUser && detail.createUser.avatar && <Link to={`/${detail.createUser.userName}`}><img alt='' src={detail.createUser.avatar} className='publicUserAvatar mr10'/></Link>}
{detail.createUser && <Link className='mr20' to={`/${detail.createUser.userName}`}>{detail.createUser.nickName}</Link>}
<span className='mr20'>发布于{detail.updateTime || detail.createTime}</span>
{detail.auditStatus === '0' && <Badge color={temp === "zone" ? "#466aff" : "#089f7f"} text="待审核" className='pass'/> }
{detail.auditStatus === '2' && <Badge color="#eb1212" text="未通过" className='failed'/> }
</div>
<div className='pb20'>{detail.summary}</div>
{
detail.fileList && detail.fileList.length > 0 &&
<ul className="files_box">
{
detail.fileList.map((i,k)=>{
return(
<li>
<img src={SourceFile} alt="" width="20px" className="mr12"/>
<span className="task-hide">{i.fileOriginName}</span>
<span style={{width: '340px'}}>{i.zoneResourceType.name}</span>
<span>{i.fileSizeInfo}</span>
<a href={`${httpUrl}/file/open/download/${i.fileId}`} download className="f_b_load primaryColor">下载</a>
</li>
)
})
}
</ul>
}
</div>
}
</div>
)
}
export default SourceDetail;

View File

@ -1,97 +0,0 @@
import React , { useState , useEffect } from 'react';
import Crown from '../img/crown.png';
import Nodata from '../../Nodata';
import { Link } from 'react-router-dom';
import { Spin, Button, Icon } from 'antd';
import { tempConfig, tempEnum } from '../tempInfo'
import MemberApply from '../Component/memberApply';
import { getVIPLists, getAuditStatus, applyJoin } from '../api';
import nodata from '../img/nodata.png';
import MemberList from '../Component/memberList';
import '../indexZone1.scss';
const memberStatusEnum = {
applying: '0',
isMember: '1',
notMember: '2'
}
function ZoneVIP(props){
const { deptId } = props.match.params;
const [ vipLists , setVIPLists ] = useState(undefined);
const [ isSpin , setIsSpin ] = useState(true);
const [ applyVisible , setApplyVisible ] = useState(false);
const [ memberStatus , setMemberStatus] = useState(memberStatusEnum.notMember);
const { id, showNotification, checkIfLogin, showLoginDialog, temp, sectionMemberTitle } = props;
useEffect(()=>{
if(id){
setIsSpin(true);
getLists();
getMemberStatus();
}
},[id])
function getLists(){
getVIPLists(id).then(response=>{
if(response){
setVIPLists(response.data.rows);
setIsSpin(false);
}
}).catch(error=>{setIsSpin(false);})
}
function getMemberStatus() {
getAuditStatus(id).then(res => {
if (res && res.data && res.data.code === 200) {
setMemberStatus(res.data.data)
} else {
setMemberStatus(memberStatusEnum.notMember)
}
}).catch(() => { setMemberStatus(memberStatusEnum.notMember) })
}
function onOk(e) {
applyJoin(id, e).then(res => {
if (res && res.data) {
showNotification(res.data.msg)
setApplyVisible(!applyVisible)
if (res.data.code === 200) {
setMemberStatus(memberStatusEnum.applying)
}
}
})
}
function apply() {
if(checkIfLogin()===false){
showLoginDialog()
return false;
}
setApplyVisible(!applyVisible)
}
return(
<div className={`boxmain ${temp}_VIP_box`}>
<p className="in_title">{ sectionMemberTitle }</p>
<p className="vip_sub_title">{ tempConfig[temp].vipDesc }</p>
{ memberStatus === memberStatusEnum.notMember && <Button className="zone_apply_button" onClick={ apply }>申请加入</Button> }
{ memberStatus === memberStatusEnum.applying && <div className="mt20 tips" ><Icon type="check-circle" theme="filled" />您的申请已提交请耐心等待管理员审核!</div> }
<MemberApply visible={applyVisible} onOk={ onOk } onCancel={() => setApplyVisible(!applyVisible)} current_user={props.current_user}/>
<Spin spinning={isSpin}>
<div style={{minHeight:400}}>
{
vipLists && (vipLists.length > 0 ? <MemberList vipLists={vipLists} temp={temp}/> : <div style={{marginTop:30,padding:"20px"}}>
{
temp === tempEnum.zone1 ? <Nodata _html="暂无数据" img={ nodata }/> : <Nodata _html="暂无数据" />
}
</div>)
}
</div>
</Spin>
</div>
)
}
export default ZoneVIP;

View File

@ -1,315 +0,0 @@
import fetch from './fetch';
/**入口页接口***/
export function getMainInfos(deptId, params) {
return fetch({
url: `/zone/open/zoneKey/${deptId}`,
method: 'get',
params
});
}
export function getCheckZoneRole(id) {
return fetch({
url: `/zone/open/zone/${id}/checkZoneRole`,
method: 'get',
});
}
export function getCurrentRole(id) {
return fetch({
url: `/zone/zoneFront/${id}/checkCurrentRole`,
method: 'get',
});
}
/********首页接口******/
export function getHomePageList(id) {
return fetch({
url: `/zone/open/${id}/member/homePageList`,
method: 'get',
});
}
export function gethomePageDocList(id) {
return fetch({
url: `/cms/doc/open/zone/${id}/homePageDocList`,
method: 'get',
});
}
export function getAllList(id,params){
return fetch({
url:`/zone/open/${id}/project/list`,
method: 'get',
params
})
}
export function getPartnerList(id){
return fetch({
url:`/zone/open/${id}/partners/list`,
method: 'get',
})
}
/**领域资讯 */
export function getNewsAllList(id,params){
return fetch({
url:`/cms/doc/open/zone/${id}/docOverviewList`,
method: 'get',
params
})
}
export function getNewsHotList(id,params){
return fetch({
url:`/cms/doc/open/zone/${id}/hotDocList`,
method: 'get',
params
})
}
export function getNewsDetail(id){
return fetch({
url:`/cms/doc/open/${id}`,
method: 'get',
})
}
export function getNewsMyList(id,params){
return fetch({
url:`/cms/doc/zone/${id}/myDocList`,
method:"get",
params
})
}
export function delNewsMyList(id){
return fetch({
url:`/cms/doc/${id}`,
method:"delete"
})
}
/**开源项目 */
export function getProjectsLists(id,params){
return fetch({
url:`/zone/open/${id}/project/list`,
method: 'get',
params
})
}
export function getProjectsTypeLists(id){
return fetch({
url:`/zone/open/${id}/projectType/list`,
method: 'get',
})
}
/**专区会员 */
export function getVIPLists(id, params){
return fetch({
url:`/zone/open/${id}/member/overviewList`,
method: 'get',
params
})
}
/**会员申请状态 */
export function getAuditStatus(id){
return fetch({
url:`/zone/member/zone/${id}/auditStatus`,
method: 'get',
})
}
/**会员申请状态 */
export function applyJoin(id,data) {
return fetch({
url: `/zone/member/applyToJoin/zone/${id}`,
method: 'post',
data: data
});
}
// 资源模块
export function addResource(data) {
return fetch({
url: `/zone/zoneFront/addResource`,
method: 'post',
data: data
});
}
export function getSourceTypeList(id){
return fetch({
url:`/zone/open/${id}/resourceType/list`,
method: 'get',
})
}
export function getSourceZoneList(id){
return fetch({
url:`/zone/open/${id}/resourceDomain/list`,
method: 'get',
})
}
export function getSourceList(params){
return fetch({
url:`/zone/open/${params.id}/resource/list`,
method: 'get',
params
})
}
export function getSourceDetail(id){
return fetch({
url:`/zone/open/resource/detail/${id}`,
method: 'get'
})
}
export function getSourceMyList(params){
return fetch({
url:`/zone/zoneFront/myResourceList`,
method:"get",
params
})
}
export function delSourceMyList(id){
return fetch({
url:`/zone/zoneFront/removeResource/${id}`,
method:"delete"
})
}
// 创建专区
export function postCreateZone(data) {
return fetch({
url: `/zone/application`,
method: 'post',
data: data
})
}
// 根据文件id获取专区下资源类别
export function getTypeByFileId(zoneId, fileId){
return fetch({
url:`/zone/resourceType/zone/${zoneId}/getResourceTypeByFileId/${fileId}`,
method: 'get'
})
}
// 新增领域
export function addSourceType(data) {
return fetch({
url: `/zone/resourceType`,
method: 'post',
data: data
});
}
// 修改当前文件对应的资源类别
export function updateResourceTypeByFileId(data) {
return fetch({
url: '/zone/resourceType/updateResourceTypeByFileId',
method: 'PUT',
data: data
});
}
// 获取文章领域列表
export function getDirListById(id){
return fetch({
url:`/cms/doc/open/zone/${id}/dirList`,
method: 'get'
})
}
// 新增文章
export function addNewsByDirId(dirId, data) {
return fetch({
url: `/cms/doc/dir/${dirId}`,
method: 'post',
data: data
});
}
// 获取文章详细信息(需要用户权限)
export function getNewsDetailByAu(id){
return fetch({
url:`/cms/doc/${id}`,
method: 'get',
})
}
// 修改文章详细信息(需要用户权限)
export function updateDoc(id, data) {
return fetch({
url: `/cms/doc/${id}`,
method: 'PUT',
data: data
});
}
// 获取资源详细信息(需要用户权限)
export function getSourceDetailByAu(id){
return fetch({
url:`/zone/zoneFront/myResource/${id}`,
method: 'get',
})
}
// 修改资源详细信息(需要用户权限)
export function updateMyResource(data) {
return fetch({
url: `/zone/zoneFront/editResource`,
method: 'PUT',
data: data
});
}
// 评论相关
// 评论列表
export function getCommentList(id, params) {
return fetch({
url: `cms/doc/open/${ id }/journalList`,
method: 'GET',
params
})
}
// 新增评论
export function addComment(id, data) {
return fetch({
url: `cms/docComment/${ id }`,
method: 'POST',
data: data
})
}
// 编辑评论
export function editComment(id, data) {
return fetch({
url: `cms/docComment/${ id }/${ data.id }`,
method: 'PUT',
data: data
})
}
// 删除评论
export function deleteComment(docId, id) {
return fetch({
url: `cms/docComment/${ docId }/${ id }`,
method: 'DELETE',
})
}
// 数据集
export function getDataSet(params) {
return fetch({
url: `/zone/open/${params.id}/dataSet/projectList`,
method: 'GET',
params
})
}
// /open/dataSet/{projectId}
export function getDataSetdetail(datasetId,params) {
return fetch({
url: `/zone/open/dataSet/${datasetId}`,
method: 'GET',
params
})
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 KiB

Some files were not shown because too many files have changed in this diff Show More