Compare commits
12 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
523c8b36e4 | |
|
|
0717ec8fbb | |
|
|
941a89cecc | |
|
|
1b3284cd1d | |
|
|
bea187c1f9 | |
|
|
ccb1dd8216 | |
|
|
8544c7df86 | |
|
|
88f56c7160 | |
|
|
f05c3f322f | |
|
|
087d089705 | |
|
|
d86b07ae4a | |
|
|
3f01ac4ccb |
|
After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 66 KiB |
173
src/App.js
|
|
@ -35,14 +35,19 @@ const theme = createMuiTheme({
|
||||||
secondary: { main: '#4CACFF' }, // #11cb5f This is just green.A700 as hex.
|
secondary: { main: '#4CACFF' }, // #11cb5f This is just green.A700 as hex.
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
//forge项目
|
//首页
|
||||||
const Projects = Loadable({
|
const Index = Loadable({
|
||||||
loader: () => import('./forge/Index'),
|
loader: () => import('./mulan/Index'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
//forge项目-devOps详情
|
//首页
|
||||||
const OpsDetail = Loadable({
|
const License = Loadable({
|
||||||
loader: () => import('./forge/DevOps/opsDetail'),
|
loader: () => import('./mulan/license/Index'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
//关于我们
|
||||||
|
const About = Loadable({
|
||||||
|
loader: () => import('./mulan/About/Index'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
//403页面
|
//403页面
|
||||||
|
|
@ -55,26 +60,15 @@ const Shixunnopage = Loadable({
|
||||||
loader: () => import('./modules/404/Shixunnopage'),
|
loader: () => import('./modules/404/Shixunnopage'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
const Projects =Loadable({
|
||||||
|
loader: () => import('./mulan/Projects/Index'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
//500页面
|
//500页面
|
||||||
const http500 = Loadable({
|
const http500 = Loadable({
|
||||||
loader: () => import('./modules/500/http500'),
|
loader: () => import('./modules/500/http500'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const InfosIndex = Loadable({
|
|
||||||
loader: () => import('./forge/users/Index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
// 组织
|
|
||||||
const OrganizeIndex = Loadable({
|
|
||||||
loader: () => import('./forge/Team/Index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const EducoderLogin = Loadable({
|
|
||||||
loader: () => import('./modules/login/EducoderLogin'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
@ -131,7 +125,7 @@ class App extends Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
initAxiosInterceptors(this.props);
|
initAxiosInterceptors(this.props);
|
||||||
this.getAppdata();
|
this.getSetting();
|
||||||
|
|
||||||
window.addEventListener('error', (event) => {
|
window.addEventListener('error', (event) => {
|
||||||
const msg = `${event.type}: ${event.message}`;
|
const msg = `${event.type}: ${event.message}`;
|
||||||
|
|
@ -144,67 +138,30 @@ class App extends Component {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
//获取数据为空的时候
|
|
||||||
gettablogourlnull = () => {
|
|
||||||
this.setState({
|
|
||||||
mygetHelmetapi: undefined
|
|
||||||
});
|
|
||||||
document.title = "Forge";
|
|
||||||
var link = document.createElement('link'),
|
|
||||||
oldLink = document.getElementById('dynamic-favicon');
|
|
||||||
link.id = 'dynamic-favicon';
|
|
||||||
link.rel = 'shortcut icon';
|
|
||||||
link.href = "/react/build/./favicon.ico";
|
|
||||||
if (oldLink) {
|
|
||||||
document.head.removeChild(oldLink);
|
|
||||||
}
|
|
||||||
document.head.appendChild(link);
|
|
||||||
};
|
|
||||||
|
|
||||||
//获取数据的时候
|
getSetting=()=>{
|
||||||
|
const url = `/setting.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result){
|
||||||
|
this.setState({
|
||||||
|
headData:result.data.data
|
||||||
|
})
|
||||||
|
this.gettablogourldata(result.data.data)
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
|
||||||
gettablogourldata = (response) => {
|
gettablogourldata = (response) => {
|
||||||
document.title = response.data.setting.name;
|
document.title = response.name;
|
||||||
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';
|
||||||
link.rel = 'shortcut icon';
|
link.rel = 'shortcut icon';
|
||||||
link.href = '/' + response.data.setting.tab_logo_url;
|
link.href = '/' + response.tab_logo_url;
|
||||||
if (oldLink) {
|
if (oldLink) {
|
||||||
document.head.removeChild(oldLink);
|
document.head.removeChild(oldLink);
|
||||||
}
|
}
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
//获取当前定制信息
|
|
||||||
getAppdata = () => {
|
|
||||||
let url = "/setting.json";
|
|
||||||
axios.get(url).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data) {
|
|
||||||
this.setState({
|
|
||||||
mygetHelmetapi: response.data.setting
|
|
||||||
});
|
|
||||||
//存储配置到游览器
|
|
||||||
localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
|
|
||||||
localStorage.setItem('chromesettingresponse', JSON.stringify(response));
|
|
||||||
try {
|
|
||||||
if (response.data.setting.tab_logo_url) {
|
|
||||||
this.gettablogourldata(response);
|
|
||||||
} else {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -214,60 +171,38 @@ class App extends Component {
|
||||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||||
<Router>
|
<Router>
|
||||||
<Switch>
|
<Switch>
|
||||||
{/*项目*/}
|
|
||||||
<Route
|
|
||||||
path={"/projects/:owner/:projectId/devops/:opsId/detail"}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
</Route>
|
|
||||||
{/*项目*/}
|
|
||||||
<Route
|
|
||||||
path={"/projects"}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<Projects {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
</Route>
|
|
||||||
<Route
|
|
||||||
path="/register"
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{/*403*/}
|
|
||||||
<Route path="/403" component={Shixunauthority} />
|
<Route path="/403" component={Shixunauthority} />
|
||||||
|
|
||||||
<Route path="/500" component={http500} />
|
<Route path="/500" component={http500} />
|
||||||
<Route path={"/organize"}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
</Route>
|
|
||||||
{/*404*/}
|
|
||||||
<Route path="/nopage" component={Shixunnopage} />
|
<Route path="/nopage" component={Shixunnopage} />
|
||||||
{/* 个人主页 */}
|
|
||||||
<Route path="/users/:username"
|
<Route path="/projects"
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<InfosIndex {...this.props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}></Route>
|
|
||||||
<Route exact path="/"
|
|
||||||
render={
|
render={
|
||||||
(props) => (
|
(props) => (
|
||||||
<Projects {...this.props} {...props} {...this.state}></Projects>
|
<Projects {...this.props} {...props} {...this.state}></Projects>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route component={Shixunnopage} />
|
<Route path="/About"
|
||||||
|
render={
|
||||||
|
(props) => (
|
||||||
|
<About {...this.props} {...props} {...this.state}></About>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route path="/license"
|
||||||
|
render={
|
||||||
|
(props) => (
|
||||||
|
<License {...this.props} {...props} {...this.state}></License>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Route exact path="/"
|
||||||
|
render={
|
||||||
|
(props) => (
|
||||||
|
<Index {...this.props} {...props} {...this.state}></Index>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Router>
|
</Router>
|
||||||
</MuiThemeProvider>
|
</MuiThemeProvider>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ function clearAllCookie() {
|
||||||
cookie.remove('autologin_trustie', { path: '/' });
|
cookie.remove('autologin_trustie', { path: '/' });
|
||||||
setpostcookie()
|
setpostcookie()
|
||||||
}
|
}
|
||||||
clearAllCookie();
|
// clearAllCookie();
|
||||||
function setpostcookie() {
|
function setpostcookie() {
|
||||||
const str = window.location.pathname;
|
const str = window.location.pathname;
|
||||||
if (str.indexOf("/wxcode") !== -1) {
|
if (str.indexOf("/wxcode") !== -1) {
|
||||||
|
|
@ -50,13 +50,13 @@ function setpostcookie() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setpostcookie();
|
// setpostcookie();
|
||||||
|
|
||||||
window._debugType = debugType;
|
window._debugType = debugType;
|
||||||
export function initAxiosInterceptors(props) {
|
export function initAxiosInterceptors(props) {
|
||||||
initOnlineOfflineListener();
|
initOnlineOfflineListener();
|
||||||
var proxy = "http://localhost:3000";
|
var proxy = "http://localhost:3000";
|
||||||
proxy = "https://testforgeplus.trustie.net";
|
proxy = "https://mulan.trustie.net";
|
||||||
|
|
||||||
const requestMap = {};
|
const requestMap = {};
|
||||||
window.setfalseInRequestMap = function (keyName) {
|
window.setfalseInRequestMap = function (keyName) {
|
||||||
|
|
@ -65,10 +65,10 @@ export function initAxiosInterceptors(props) {
|
||||||
//响应前的设置
|
//响应前的设置
|
||||||
axios.interceptors.request.use(
|
axios.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
setpostcookie()
|
// clearAllCookie()
|
||||||
clearAllCookie()
|
// setpostcookie()
|
||||||
|
|
||||||
if (config.url.indexOf(proxy) !== -1) {
|
if (config.url.indexOf("http") !== -1) {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
requestProxy(config)
|
requestProxy(config)
|
||||||
|
|
@ -79,20 +79,20 @@ export function initAxiosInterceptors(props) {
|
||||||
if (window.location.port === "3007") {
|
if (window.location.port === "3007") {
|
||||||
config.url = `${proxy}${url}`;
|
config.url = `${proxy}${url}`;
|
||||||
if (config.url.indexOf('?') === -1) {
|
if (config.url.indexOf('?') === -1) {
|
||||||
config.url = `${config.url}?debug=${debugType}`;
|
config.url = `${config.url}`;
|
||||||
} else {
|
} else {
|
||||||
config.url = `${config.url}&debug=${debugType}`;
|
config.url = `${config.url}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
config.url = url;
|
config.url = url;
|
||||||
}
|
}
|
||||||
setpostcookie();
|
// setpostcookie();
|
||||||
}
|
}
|
||||||
if (config.url.indexOf('update_file') === -1) {
|
// if (config.url.indexOf('update_file') === -1) {
|
||||||
requestMap[config.url] = true;
|
// requestMap[config.url] = true;
|
||||||
|
|
||||||
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
// window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||||
}
|
// }
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
|
|
@ -147,7 +147,7 @@ export function initAxiosInterceptors(props) {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
requestMap[response.config.url] = false;
|
requestMap[response.config.url] = false;
|
||||||
setpostcookie();
|
// setpostcookie();
|
||||||
return response;
|
return response;
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
|
|
|
||||||
|
|
@ -66,19 +66,3 @@ export function requestProxy(config) {
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
('/api/v1/careers/qweqw/edit/').match(/\/api\/v1\/careers\/(\w*)\/edit/i)
|
|
||||||
0: "/api/v1/careers/qweqw/edit"
|
|
||||||
1: "qweqw"
|
|
||||||
|
|
||||||
example:
|
|
||||||
`/api/v1/games/${this.props.game.identifier}/answer_grade` ->
|
|
||||||
`/tasks/${this.props.game.identifier}/answer_grade.json`
|
|
||||||
|
|
||||||
|
|
||||||
https://testeduplus2.educoder.net/api/v1/games/feguz4tiqpvx/rep_content
|
|
||||||
?path=src/step2/CLnkQueue.cpp&shixun_gpid=2791&status=0&retry=0 ->
|
|
||||||
http://testeduplus2.educoder.net/tasks/tonblikwzj78/rep_content.json
|
|
||||||
?path=1-4.py&shixun_gpid=2448&status=0
|
|
||||||
*/
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { HomeHoc } from '../HOC/HomeHoc';
|
||||||
|
import'./Index.scss';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
function Index(){
|
||||||
|
const [ about , setAbout ] = useState(undefined);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
getAbout();
|
||||||
|
},[])
|
||||||
|
|
||||||
|
function getAbout(){
|
||||||
|
const url = `/helps/about.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setAbout(result.data.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div className="aboutBox">
|
||||||
|
<p className="aboutTitle">关于我们</p>
|
||||||
|
<div className="desc">
|
||||||
|
{about && about.content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default HomeHoc(Index);
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
.aboutBox{
|
||||||
|
max-width: 1200px;
|
||||||
|
margin:20px auto;
|
||||||
|
border:1px solid #eee;
|
||||||
|
border-radius: 4px;
|
||||||
|
.aboutTitle{
|
||||||
|
font-size: 20px;
|
||||||
|
padding:10px 0px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom:1px solid #eee;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
.desc{
|
||||||
|
line-height: 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
text-indent: 2em;
|
||||||
|
text-align: justify;
|
||||||
|
padding:40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
.loginModal{
|
||||||
|
.ant-modal-close{
|
||||||
|
top:0px!important;
|
||||||
|
height: 48px;
|
||||||
|
line-height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.ant-modal-body{
|
||||||
|
padding:0px;
|
||||||
|
.ant-menu{
|
||||||
|
border-radius: 8px 8px 0px 0px;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
.content{
|
||||||
|
padding:40px 50px;
|
||||||
|
.subbtn{
|
||||||
|
display: block;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #ccc;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size:16px;
|
||||||
|
&.activeBtn{
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.saveitem{
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
import React, { useState , forwardRef, useEffect } from 'react';
|
||||||
|
import { Form , Input , Checkbox, Button } from 'antd';
|
||||||
|
import "./Index.scss";
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
function LoginModal({form , successFunc , visible}){
|
||||||
|
const [ active , setActive ] = useState(false);
|
||||||
|
const [ loading , setLoading ] = useState(false);
|
||||||
|
|
||||||
|
const { getFieldDecorator, validateFields , setFieldsValue , getFieldsValue } = form;
|
||||||
|
|
||||||
|
|
||||||
|
function changeInput(){
|
||||||
|
const { login , password } = getFieldsValue();
|
||||||
|
if(login && password){
|
||||||
|
setActive(true);
|
||||||
|
}else{
|
||||||
|
setActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function loginFunc() {
|
||||||
|
validateFields((error,values)=>{
|
||||||
|
if(!error){
|
||||||
|
setLoading(true);
|
||||||
|
const url = `/accounts/login.json`;
|
||||||
|
axios.post(url,{
|
||||||
|
...values
|
||||||
|
}).then(result=>{
|
||||||
|
successFunc(result.data.data);
|
||||||
|
setLoading(false);
|
||||||
|
if(!values.savePass){
|
||||||
|
setFieldsValue({
|
||||||
|
login:undefined,
|
||||||
|
password:undefined,
|
||||||
|
savePass:false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<Form>
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator("login",{
|
||||||
|
rules:[{required:true,message:"请输入登录账号"}]
|
||||||
|
})(
|
||||||
|
<Input placeholder="请输入登录账号" onChange={changeInput}/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator("password",{
|
||||||
|
rules:[{required:true,message:"请输入登录密码"}]
|
||||||
|
})(
|
||||||
|
<Input.Password placeholder="请输入登录密码" onChange={changeInput}/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
{
|
||||||
|
active ?
|
||||||
|
<Button className="subbtn activeBtn" loading={loading} onClick={loginFunc}>登录</Button>
|
||||||
|
:
|
||||||
|
<span className="subbtn">登录</span>
|
||||||
|
}
|
||||||
|
<Form.Item className="saveitem">
|
||||||
|
{getFieldDecorator("savePass",
|
||||||
|
{rules:[]},{valuePropName:"checked"}
|
||||||
|
)(
|
||||||
|
<Checkbox>记住密码</Checkbox>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Form.create()(forwardRef(LoginModal));
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Modal , Menu } from 'antd';
|
||||||
|
import "./Index.scss";
|
||||||
|
import Login from './Login';
|
||||||
|
import Register from './Register';
|
||||||
|
|
||||||
|
function LoginModal({visible,onCancel,successFunc}){
|
||||||
|
const [ n , setN ] = useState("0");
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Modal
|
||||||
|
visible={visible}
|
||||||
|
closable={true}
|
||||||
|
width="440px"
|
||||||
|
title={false}
|
||||||
|
footer={false}
|
||||||
|
className="loginModal"
|
||||||
|
centered
|
||||||
|
onCancel={onCancel}
|
||||||
|
>
|
||||||
|
<Menu defaultSelectedKeys={[n]} mode={"horizontal"}>
|
||||||
|
<Menu.Item key="0" onClick={(e)=>setN(e.key)}>登录</Menu.Item>
|
||||||
|
<Menu.Item key="1" onClick={(e)=>setN(e.key)}>注册</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
<div className="content">
|
||||||
|
{
|
||||||
|
n === "0"?
|
||||||
|
<Login successFunc={successFunc} visible={visible}/>
|
||||||
|
:
|
||||||
|
<Register successFunc={successFunc} visible={visible}/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default LoginModal;
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import React, { useState , forwardRef , useEffect } from 'react';
|
||||||
|
import { Form , Input , Button } from 'antd';
|
||||||
|
import "./Index.scss";
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
function Register({ form , successFunc , visible }){
|
||||||
|
const [ active , setActive ] = useState(false);
|
||||||
|
const [ loading , setLoading ] = useState(false);
|
||||||
|
|
||||||
|
const { getFieldDecorator, validateFields , setFieldsValue , getFieldsValue } = form;
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(!visible){
|
||||||
|
setFieldsValue({
|
||||||
|
mail:undefined,
|
||||||
|
password:undefined,
|
||||||
|
passwordAgain:undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},[visible])
|
||||||
|
|
||||||
|
function changeInput(){
|
||||||
|
const { mail , password , passwordAgain } = getFieldsValue();
|
||||||
|
if(mail && password && passwordAgain){
|
||||||
|
setActive(true);
|
||||||
|
}else{
|
||||||
|
setActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerFunc(){
|
||||||
|
validateFields((error,values)=>{
|
||||||
|
if(!error){
|
||||||
|
setLoading(true);
|
||||||
|
const url = `/accounts/register.json`;
|
||||||
|
axios.post(url,{
|
||||||
|
...values
|
||||||
|
}).then(result=>{
|
||||||
|
if(result && result.data && result.data.status === 0){
|
||||||
|
successFunc(result.data.data);
|
||||||
|
setLoading(false);
|
||||||
|
setFieldsValue({
|
||||||
|
mail:undefined,
|
||||||
|
password:undefined,
|
||||||
|
passwordAgain:undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkRepeat(rule, value, callback){
|
||||||
|
const { password } = getFieldsValue();
|
||||||
|
if(!value){
|
||||||
|
callback();
|
||||||
|
}else if(value !== password){
|
||||||
|
callback("两次输入的密码不一致!");
|
||||||
|
}else{
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<Form>
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator("mail",{
|
||||||
|
rules:[{required:true,message:"请输入注册账号"}]
|
||||||
|
})(
|
||||||
|
<Input placeholder="请输入邮箱账号" onChange={changeInput}/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item >
|
||||||
|
{getFieldDecorator("password",{
|
||||||
|
rules:[{required:true,message:"请输入注册密码"}]
|
||||||
|
})(
|
||||||
|
<Input.Password placeholder="请输入注册密码" onChange={changeInput}/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item >
|
||||||
|
{getFieldDecorator("passwordAgain",{
|
||||||
|
rules:[
|
||||||
|
{required:true,message:"请再次输入密码"},
|
||||||
|
{validator:checkRepeat}
|
||||||
|
]
|
||||||
|
})(
|
||||||
|
<Input.Password placeholder="请再次输入密码" onChange={changeInput}/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
{
|
||||||
|
active ?
|
||||||
|
<Button className="subbtn activeBtn" loading={loading} onClick={registerFunc}>注册</Button>
|
||||||
|
:
|
||||||
|
<span className="subbtn">注册</span>
|
||||||
|
}
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Form.create()(forwardRef(Register));
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
const local = 'https://mulan.trustie.net';
|
||||||
|
const isDev = window.location.port === "3007";
|
||||||
|
|
||||||
|
export function getUrlHead(path) {
|
||||||
|
if (isDev) {
|
||||||
|
return `${local}/${path}`;
|
||||||
|
}
|
||||||
|
return `${path}`;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
function Footer(props){
|
||||||
|
return(
|
||||||
|
<div className="homefooterbase">
|
||||||
|
<ul className="homeFooterUl">
|
||||||
|
<li><Link to={``}>关于我们</Link></li>
|
||||||
|
<li><Link to={``}>帮助中心</Link></li>
|
||||||
|
<li><Link to={``}>合作伙伴</Link></li>
|
||||||
|
<li><Link to={``}>服务协议</Link></li>
|
||||||
|
</ul>
|
||||||
|
<div>
|
||||||
|
<span>木兰开源社区版权所有 ©2020 技术支持:长沙智擎科技</span>
|
||||||
|
<a href="http://www.beian.miit.gov.cn/" target="_blank" style={{color:"#666"}}>粤ICP备12009483号</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Footer;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Nav from './Nav';
|
||||||
|
|
||||||
|
function Header({ users,headData, successFunc , quitFunc , match }){
|
||||||
|
return(
|
||||||
|
<div className="headsnav">
|
||||||
|
<Nav
|
||||||
|
match={match}
|
||||||
|
users={users}
|
||||||
|
headData={headData}
|
||||||
|
successFunc={successFunc}
|
||||||
|
quitFunc={quitFunc}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Header;
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
import React, { Component, useState } from 'react';
|
||||||
|
import Header from './Header';
|
||||||
|
import Footer from './Footer';
|
||||||
|
import './Index.scss';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export function HomeHoc(Sub){
|
||||||
|
return class II extends Component {
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
this.state={
|
||||||
|
users:undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount=()=>{
|
||||||
|
this.getUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUser=()=>{
|
||||||
|
const url = `/users/get_user_info.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result){
|
||||||
|
this.setState({
|
||||||
|
users:result.data.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
successFunc=(data)=> {
|
||||||
|
if(data){
|
||||||
|
this.setState({
|
||||||
|
users:data
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
this.getUser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quitFunc =()=>{
|
||||||
|
const url = `/accounts/logout.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
this.setState({
|
||||||
|
users:undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
const { users } = this.state;
|
||||||
|
const { headData } = this.props;
|
||||||
|
console.log(this.props);
|
||||||
|
return(
|
||||||
|
<div style={{height:"100%",overflow:"auto",position:"relative"}}>
|
||||||
|
<Header {...this.props} {...this.state} users={users} headData={headData} successFunc={this.successFunc} quitFunc={this.quitFunc}/>
|
||||||
|
<div className="homebody">
|
||||||
|
<Sub {...this.props} {...this.state} users={users}/>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default HomeHoc;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import Header from './Header';
|
||||||
|
import Footer from './Footer';
|
||||||
|
import './Index.scss';
|
||||||
|
|
||||||
|
export function HOC(Sub){
|
||||||
|
return class II extends Component {
|
||||||
|
render(){
|
||||||
|
return(
|
||||||
|
<div style={{height:"100%",overflow:"auto"}}>
|
||||||
|
<Header {...this.props} {...this.state}/>
|
||||||
|
<div className="homebody"><Sub {...this.props} {...this.state}/></div>
|
||||||
|
<Footer {...this.props} {...this.state}/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
.headsnav{
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
left: 0px;
|
||||||
|
top:0px;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
.homeHeader{
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
left: 0px;
|
||||||
|
top:0px;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0px 0px 3px rgba(0,0,0,0.1);
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
ul{
|
||||||
|
li{
|
||||||
|
a{
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.headDiv{
|
||||||
|
margin: 0px auto;
|
||||||
|
padding:0px 60px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.headerNav{
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
li{
|
||||||
|
padding-right:30px;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.headUserInfo{
|
||||||
|
a{
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.homebody{
|
||||||
|
padding-top: 60px;
|
||||||
|
padding-bottom: 136px;
|
||||||
|
min-height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.footsnav{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom:10px;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homefooterbase{
|
||||||
|
background: #DEDEDE;
|
||||||
|
line-height: 38px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
padding:30px 0px;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
.homeFooterUl{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin:0px;
|
||||||
|
li{
|
||||||
|
padding:0px 40px;
|
||||||
|
a{
|
||||||
|
color: #666666;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.menuItems{
|
||||||
|
.ant-dropdown-menu-item{
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.ant-dropdown-menu-item:last-child{
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.ant-dropdown-menu-item:first-child:hover{
|
||||||
|
color: #333;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.ant-dropdown-menu-item:hover{
|
||||||
|
background-color: #fff;
|
||||||
|
color: #aac5fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { getUrlHead } from '../Data/getUrl';
|
||||||
|
import { Dropdown , Menu } from 'antd';
|
||||||
|
import logo from '../images/logo.png';
|
||||||
|
import LoginModal from '../Components/Login/LoginModal';
|
||||||
|
|
||||||
|
function Nav({ users, headData , successFunc , quitFunc , match }){
|
||||||
|
const [ visible ,setVisible ] = useState(false);
|
||||||
|
const [ navs , setNavs ] = useState(undefined);
|
||||||
|
useEffect(()=>{
|
||||||
|
if(headData){
|
||||||
|
setNavs(headData.navbar);
|
||||||
|
}
|
||||||
|
},[headData])
|
||||||
|
|
||||||
|
function success(data) {
|
||||||
|
setVisible(false);
|
||||||
|
successFunc(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const menus =(
|
||||||
|
<Menu className="menuItems">
|
||||||
|
<Menu.Item>{users && users.real_name}</Menu.Item>
|
||||||
|
<Menu.Item><a href="/admins">后台管理</a></Menu.Item>
|
||||||
|
<Menu.Item onClick={quitFunc}>退出</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
)
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="headDiv">
|
||||||
|
<LoginModal visible={visible} onCancel={()=>setVisible(false)} successFunc={success}/>
|
||||||
|
<ul className="headerNav">
|
||||||
|
<li><img src={logo} alt="" width="110px" style={{marginRight:"100px"}}/></li>
|
||||||
|
{
|
||||||
|
navs && navs.length>0 && navs.map((i,k)=>{
|
||||||
|
return(
|
||||||
|
<li>
|
||||||
|
{
|
||||||
|
i.link.indexOf("http") > -1 ?
|
||||||
|
<a href={i.link} target="_blank">{i.name}</a>
|
||||||
|
:
|
||||||
|
<Link to={i.link} className={i.link===(match && match.url) ? "color-blue":""}>{i.name}</Link>
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
<div className="headUserInfo">
|
||||||
|
{
|
||||||
|
users && users.login ?
|
||||||
|
<Dropdown overlay={menus} placement={"bottomRight"}>
|
||||||
|
<img src={users && getUrlHead(users.image_url)} alt="" width="48px" height="48px" style={{borderRadius:"50%"}}/>
|
||||||
|
</Dropdown>
|
||||||
|
:
|
||||||
|
<a onClick={()=>setVisible(true)}>登录/注册</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Nav;
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { HomeHoc } from './HOC/HomeHoc';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import './Index.scss';
|
||||||
|
import main from './images/320.jpg';
|
||||||
|
import icon1 from './images/icon1.png';
|
||||||
|
import icon2 from './images/icon2.png';
|
||||||
|
import active1 from './images/active1.jpg';
|
||||||
|
import active2 from './images/active2.png';
|
||||||
|
import DefaultImg from './images/default.png';
|
||||||
|
import { Carousel } from 'antd';
|
||||||
|
import { getUrlHead } from './Data/getUrl';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
function Index(props){
|
||||||
|
const [ about ,setAbout ] =useState(undefined);
|
||||||
|
const [ covers ,setCovers ] =useState(undefined);
|
||||||
|
const [ recommand ,setRecommand ] =useState(undefined);
|
||||||
|
const [ news ,setNews ] =useState(undefined);
|
||||||
|
const [ activity ,setActivity ] =useState(undefined);
|
||||||
|
const [ cooperaters ,setCooperaters ] =useState(undefined);
|
||||||
|
useEffect(()=>{
|
||||||
|
getRecommand();
|
||||||
|
getAbout();
|
||||||
|
getNews();
|
||||||
|
getActivity();
|
||||||
|
getCooperaters();
|
||||||
|
},[])
|
||||||
|
|
||||||
|
// 关于我们
|
||||||
|
function getAbout(){
|
||||||
|
const url = `/helps/about.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setAbout(result.data.data);
|
||||||
|
setCovers(result.data.data.covers);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
// 开源软件推荐
|
||||||
|
function getRecommand(){
|
||||||
|
const url = `/projects/recommend.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setRecommand(result.data.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
// 开源活动
|
||||||
|
function getNews(){
|
||||||
|
const url = `/topics.json`;
|
||||||
|
axios.get(url,{
|
||||||
|
params:{type:"activity"}
|
||||||
|
}).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setNews(result.data.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
// 开源资讯
|
||||||
|
function getActivity(){
|
||||||
|
const url = `/topics.json`;
|
||||||
|
axios.get(url,{
|
||||||
|
params:{type:"news"}
|
||||||
|
}).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setActivity(result.data.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
// 合作伙伴
|
||||||
|
function getCooperaters(){
|
||||||
|
const url = `/cooperaters.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setCooperaters(result.data.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<div className="homebase">
|
||||||
|
<Carousel
|
||||||
|
autoplay
|
||||||
|
pauseOnDotsHover
|
||||||
|
>
|
||||||
|
{
|
||||||
|
covers && covers.length>0?
|
||||||
|
covers.map((i,k)=>{
|
||||||
|
return(
|
||||||
|
<a href={i.path}><img src={getUrlHead(i.image_url) } alt="" /></a>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
:<img src={main} alt="" />
|
||||||
|
}
|
||||||
|
</Carousel>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
recommand && recommand.length > 0 &&
|
||||||
|
<div className="homeproject">
|
||||||
|
<div class="tit">开源软件推荐</div>
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
recommand.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<li>
|
||||||
|
<a href={item.url}>
|
||||||
|
<div className="p_head">
|
||||||
|
<p className="p_name task-hide-2">{item.full_name}</p>
|
||||||
|
<img src={item.author && item.author.image_url ? getUrlHead(item.author.image_url) : DefaultImg } alt="" style={{maxHeight:"50px"}}/>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<p className="p_author">{item.author && item.author.name}</p>
|
||||||
|
<p className="p_desc task-hide-2">{item.description}</p>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
<Link to={`/projects`} className="color-blue">查看更多<i className="iconfont icon-youjiantou ml8 font-12 color-blue"></i></Link>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
about &&
|
||||||
|
<div className="homeFirst">
|
||||||
|
<div className="firstPanel">
|
||||||
|
<div className="firstPanelBox">
|
||||||
|
<div class="tit" style={{marginBottom:"30px"}}>{about.name}</div>
|
||||||
|
<div className="desc">
|
||||||
|
{about.content}<Link to={`/about`} className="color-blue">查看更多</Link>
|
||||||
|
</div>
|
||||||
|
<ul className="aboutul">
|
||||||
|
<li>
|
||||||
|
<img src={icon1} alt="" width="186px"/>
|
||||||
|
<font>开源项目总数</font>
|
||||||
|
<span>{about.total_projects_count}</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<img src={icon2} alt="" width="186px"/>
|
||||||
|
<font>科技项目开源成果</font>
|
||||||
|
<span>{about.science_projects_count}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<div className="sourceAbout">
|
||||||
|
<div class="tit">开源活动</div>
|
||||||
|
{
|
||||||
|
news && news.length>0 ?
|
||||||
|
<div className="sourceactive">
|
||||||
|
{
|
||||||
|
news.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
key < 2 &&<a href={item.url} style={{backgroundImage:`url(${getUrlHead(item.cover)})`}}></a>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<div className="sourceactive">
|
||||||
|
<li style={{backgroundImage:`url(${active1})`}}></li>
|
||||||
|
<li style={{backgroundImage:`url(${active2})`}}></li>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{/* <Link to={`/projects`} className="color-blue">查看更多<i className="iconfont icon-youjiantou ml8 font-12 color-blue"></i></Link> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={"homenews"}>
|
||||||
|
<div class="tit">开源资讯</div>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
activity && activity.length> 0 &&
|
||||||
|
<ul className="newsul">
|
||||||
|
{
|
||||||
|
activity.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<li>
|
||||||
|
<div className="imgBox"><img src={getUrlHead(item.cover)} alt="" width="145px" height="96px"/></div>
|
||||||
|
<div className="news-info">
|
||||||
|
<p className="news-title"><a href={item.url} target="_blank">{item.title}</a></p>
|
||||||
|
<div className="news-desc task-hide-2">{item.content}</div>
|
||||||
|
<div className="news-time">{item.created_at}</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
cooperaters && cooperaters.length > 0 &&
|
||||||
|
<ul className="homeFooterUl homeFooterParter">
|
||||||
|
{
|
||||||
|
cooperaters.map((i,k)=>{
|
||||||
|
return(
|
||||||
|
<li><a href={i.website_url} target="_blank"><img src={getUrlHead(i.logo_url) } alt="" width="200px"/></a></li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default HomeHoc(Index);
|
||||||
|
|
@ -0,0 +1,253 @@
|
||||||
|
.homeFirst{
|
||||||
|
background:url(./images/bg2.jpg)center center no-repeat;
|
||||||
|
min-height: 480px;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 90px;
|
||||||
|
.firstPanel{
|
||||||
|
position: absolute;
|
||||||
|
top:60px;
|
||||||
|
width: 100%;
|
||||||
|
.firstPanelBox{
|
||||||
|
width: 1300px;
|
||||||
|
margin:0px auto;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 498px;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-top:50px;
|
||||||
|
background:url(./images/1_1.png) no-repeat;
|
||||||
|
.desc{
|
||||||
|
margin:0px auto 50px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
width: 1030px;
|
||||||
|
text-indent: 2em;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
.aboutul{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
li{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
span{
|
||||||
|
font-size: 28px;
|
||||||
|
line-height: 42px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1890FF;
|
||||||
|
}
|
||||||
|
font{
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.homeFooterParter{
|
||||||
|
padding:30px 0px;
|
||||||
|
width: 1200px;
|
||||||
|
margin:0px auto!important;
|
||||||
|
}
|
||||||
|
.homeFooterUl{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin:0px;
|
||||||
|
li{
|
||||||
|
padding:0px 40px;
|
||||||
|
a{
|
||||||
|
color: #666666;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.homeFooter{
|
||||||
|
background: #fff;
|
||||||
|
.homefooterbase{
|
||||||
|
background: #DEDEDE;
|
||||||
|
line-height: 38px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
padding:30px 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.homebase{
|
||||||
|
position: relative;
|
||||||
|
min-height: 480px;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
color:#fff;
|
||||||
|
font-size: 60px;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.ant-carousel{
|
||||||
|
width: 100%;
|
||||||
|
a{
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
img{
|
||||||
|
height: 480px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p{
|
||||||
|
margin-bottom:20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.sub{
|
||||||
|
font-size: 28px;
|
||||||
|
margin:0px;
|
||||||
|
span{
|
||||||
|
margin:0px 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.homeproject{
|
||||||
|
padding:60px 0px 100px 0px;
|
||||||
|
text-align: center;
|
||||||
|
ul{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 1200px;
|
||||||
|
margin:0px auto;
|
||||||
|
li{
|
||||||
|
width: 22%;
|
||||||
|
margin:0px 1.5%;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0px 0px 4px rgba(0,0,0,0.1);
|
||||||
|
margin-bottom: 40px;
|
||||||
|
text-align: left;
|
||||||
|
.p_head{
|
||||||
|
padding:25px 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-image: url('./images/cards.png');
|
||||||
|
border-radius: 6px 6px 0px 0px;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.p_author{
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
padding:0px 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.p_desc{
|
||||||
|
line-height: 18px;
|
||||||
|
color: #666;
|
||||||
|
padding:0px 15px;
|
||||||
|
margin: 10px 0px 18px 0px;
|
||||||
|
}
|
||||||
|
.p_name{
|
||||||
|
font-size: 18px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sourceAbout{
|
||||||
|
padding:60px 0px 100px 0px;
|
||||||
|
text-align: center;
|
||||||
|
.sourceactive{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin:40px 0px;
|
||||||
|
a{
|
||||||
|
width: 600px;
|
||||||
|
height: 300px;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin:0px 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tit {
|
||||||
|
font-size: 22px;
|
||||||
|
color: #444;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
text-align: center;
|
||||||
|
em{
|
||||||
|
display: block;
|
||||||
|
width: 50px;
|
||||||
|
height: 1px;
|
||||||
|
background: #ccc;
|
||||||
|
margin: 18px auto 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.homenews{
|
||||||
|
padding:60px 0px;
|
||||||
|
.newsul{
|
||||||
|
width: 1200px;
|
||||||
|
margin:0px auto;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
li{
|
||||||
|
display:flex;
|
||||||
|
width: 48%;
|
||||||
|
margin-right: 2%;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
&:nth-child(2n){
|
||||||
|
margin-right: 0px;
|
||||||
|
flex-flow: row-reverse;
|
||||||
|
img{
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(2n+1){
|
||||||
|
img{
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.imgBox{
|
||||||
|
width: 145px;
|
||||||
|
height: 90px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
img{
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.news-title{
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom:5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.news-time{
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.news-desc{
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
.news-info{
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { HomeHoc } from '../HOC/HomeHoc';
|
||||||
|
import { Box , Long , Short , Gap } from '../../forge/Component/layout';
|
||||||
|
import { AlignCenter ,FlexAJ } from '../../forge/Component/layout';
|
||||||
|
import './Index.scss';
|
||||||
|
import DefaultImg from '../images/default.png';
|
||||||
|
import { getUrlHead } from '../Data/getUrl';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { Skeleton , Pagination } from 'antd';
|
||||||
|
import Ranking from './Ranking';
|
||||||
|
|
||||||
|
const data =[
|
||||||
|
{
|
||||||
|
index:1,
|
||||||
|
name:"Trustie社区 / Mini-Kernel",
|
||||||
|
count:123223123
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index:2,
|
||||||
|
name:"Trustie社区 / Mini-Kernel",
|
||||||
|
count:123223122
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index:3,
|
||||||
|
name:"Trustie社区 / Mini-Kernel",
|
||||||
|
count:123223121
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const limit = 12;
|
||||||
|
function Index(props){
|
||||||
|
const [ list , setList ] = useState([]);
|
||||||
|
const [ date ,setDate ] = useState("week");
|
||||||
|
const [ page ,setPage ] = useState(1);
|
||||||
|
const [ total ,setTotal ] = useState(0);
|
||||||
|
const [ rankList ,setRankList ] = useState([]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
getData();
|
||||||
|
},[page])
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
getRank();
|
||||||
|
},[date])
|
||||||
|
|
||||||
|
// 获取项目列表
|
||||||
|
function getData() {
|
||||||
|
const url = `/projects/science.josn`;
|
||||||
|
axios.get(url,{
|
||||||
|
params:{page,limit}
|
||||||
|
}).then(result=>{
|
||||||
|
if(result){
|
||||||
|
setList(result.data.data);
|
||||||
|
setTotal(result.data.total_count);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取排行列表
|
||||||
|
function getRank(){
|
||||||
|
const url = `/projects/liveness.json`;
|
||||||
|
axios.get(url,{
|
||||||
|
params:{time_type:date,type:"commits"}
|
||||||
|
}).then(result=>{
|
||||||
|
if(result){
|
||||||
|
setRankList(result.data.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Box className="panels">
|
||||||
|
<Long>
|
||||||
|
<div className="projectsList">
|
||||||
|
<p className="font-16">基础类开源软件</p>
|
||||||
|
{
|
||||||
|
list && list.length > 0 ?
|
||||||
|
<div className="lists">
|
||||||
|
{
|
||||||
|
list.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<a href={item.url} >
|
||||||
|
<li>
|
||||||
|
<div className="listinfo">
|
||||||
|
<p className="listName">{item.full_name}</p>
|
||||||
|
<div className="listNum">
|
||||||
|
{/* <span>代码行数:20.43K</span> */}
|
||||||
|
<span>仓库大小:{item.size ||"0kB"}</span>
|
||||||
|
<span>commits数:{item.commits_count}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<AlignCenter className="listMain">
|
||||||
|
<p className="listInfoDesc task-hide-2">{item.description}</p>
|
||||||
|
<img src={(item.author && getUrlHead(item.author.image_url)) || DefaultImg} alt="" width="48px" className="ml10"/>
|
||||||
|
</AlignCenter>
|
||||||
|
{
|
||||||
|
item.project_tags && item.project_tags.length>0 &&
|
||||||
|
<div className="listTag">
|
||||||
|
{
|
||||||
|
item.project_tags.map((i,k)=>{
|
||||||
|
return(
|
||||||
|
<span>{i}</span>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div className="projectNum">
|
||||||
|
<AlignCenter><i className="iconfont icon-liulanyan font-12 mr2"></i>{item.visits}</AlignCenter>
|
||||||
|
<AlignCenter><i className="iconfont icon-kongxing font-12 mr2"></i>{item.praises_count}</AlignCenter>
|
||||||
|
<AlignCenter><i className="iconfont icon-fork font-12 mr2"></i>{item.forked_count}</AlignCenter>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
:""
|
||||||
|
}
|
||||||
|
{
|
||||||
|
list && list.length === 0 && <Skeleton />
|
||||||
|
}
|
||||||
|
{
|
||||||
|
total > limit &&
|
||||||
|
<div className="edu-txt-center">
|
||||||
|
<Pagination showQuickJumper current={page} total={total} pageSize={limit} onChange={(p)=>{setPage(p)}}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Long>
|
||||||
|
<Short>
|
||||||
|
<Gap>
|
||||||
|
<FlexAJ>
|
||||||
|
<p className="font-16">活跃度排名</p>
|
||||||
|
<ul>
|
||||||
|
<a className={date === "week"?"color-blue":"color-grey-9"} onClick={()=>setDate("week")}>周</a>
|
||||||
|
<a className={date === "month"?"ml15 color-blue":"ml15 color-grey-9"} onClick={()=>setDate("month")}>月</a>
|
||||||
|
<a className={date === "year"?"ml15 color-blue":"ml15 color-grey-9"} onClick={()=>setDate("year")}>年</a>
|
||||||
|
</ul>
|
||||||
|
</FlexAJ>
|
||||||
|
<Ranking data={rankList}/>
|
||||||
|
</Gap>
|
||||||
|
</Short>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default HomeHoc(Index);
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
.panels{
|
||||||
|
width: 1200px;
|
||||||
|
margin:40px auto 60px;
|
||||||
|
.projectsList{
|
||||||
|
.lists{
|
||||||
|
min-height:500px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;;
|
||||||
|
& >a{
|
||||||
|
margin-right: 2%;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
width: 32%;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-height: 200px;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(95,101,105,0.1);
|
||||||
|
&:hover{
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 12px 20px 0 rgba(95,101,105,0.15);
|
||||||
|
}
|
||||||
|
&:nth-child(3n){
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
.listinfo{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding:0px 20px;
|
||||||
|
height: 90px;
|
||||||
|
background-image: url('../images/cards.png');
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px 4px 0px 0px;
|
||||||
|
.listName{
|
||||||
|
font-size: 18px;
|
||||||
|
margin:0px;
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
word-break: break-all;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width:100%
|
||||||
|
}
|
||||||
|
.listNum{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
span{
|
||||||
|
display:block;
|
||||||
|
width: 50%;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #fff;
|
||||||
|
height: 18px;
|
||||||
|
line-height: 18px;
|
||||||
|
&:nth-child(2n){
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listMain{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding:10px 20px 0px 20px;
|
||||||
|
align-items: center;
|
||||||
|
.listInfoDesc{
|
||||||
|
line-height: 20px;
|
||||||
|
margin:0px;
|
||||||
|
color:#666666;
|
||||||
|
max-width: 182px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listTag{
|
||||||
|
padding:10px 0px;
|
||||||
|
margin:0px 20px;
|
||||||
|
border-bottom: 1px solid #F1F1F1;
|
||||||
|
span{
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
background-color: #B9DDFF;
|
||||||
|
color: #1890FF;
|
||||||
|
padding:0px 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.projectNum{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
color:#999999;
|
||||||
|
font-size: 12px;
|
||||||
|
padding:10px 20px;
|
||||||
|
i{
|
||||||
|
margin-right: 3px;
|
||||||
|
color: #666666!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.arrayList{
|
||||||
|
padding:20px 20px 20px 10px;
|
||||||
|
box-shadow: 0px 0px 8px 0px #F1F1F1;
|
||||||
|
min-height: 400px;
|
||||||
|
ul {
|
||||||
|
margin:0px;
|
||||||
|
&>li{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
&:first-child .index{
|
||||||
|
color: #E53333;
|
||||||
|
}
|
||||||
|
&:nth-child(2) .index{
|
||||||
|
color: #FF8C29;
|
||||||
|
}
|
||||||
|
&:nth-child(3) .index{
|
||||||
|
color: #F7B500;
|
||||||
|
}
|
||||||
|
.index{
|
||||||
|
display: block;
|
||||||
|
width: 20px;
|
||||||
|
text-align: center;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.name{
|
||||||
|
margin-left: 10px;
|
||||||
|
flex:1;
|
||||||
|
text-align: left;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
max-width: 170px;
|
||||||
|
}
|
||||||
|
.num{
|
||||||
|
text-align: right;
|
||||||
|
margin-left: 15px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import {Skeleton} from 'antd';
|
||||||
|
|
||||||
|
function Ranking({data}){
|
||||||
|
const [list ,setList ]= useState([]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
setList(data);
|
||||||
|
},[data])
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="arrayList">
|
||||||
|
{
|
||||||
|
list && list.length >0?
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
list.map((i,k)=>{
|
||||||
|
return(
|
||||||
|
<li>
|
||||||
|
<span className="index">{i.no}</span>
|
||||||
|
<p className="name task-hide">{i.project_full_name}</p>
|
||||||
|
<span className="num">{i.commits}</span>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
:<Skeleton />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Ranking;
|
||||||
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 824 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -0,0 +1,34 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import Title from '../../forge/Component/Title';
|
||||||
|
import RenderHtml from '../../components/render-html';
|
||||||
|
import { Skeleton } from 'antd';
|
||||||
|
import Axios from 'axios';
|
||||||
|
|
||||||
|
function FAQ(props){
|
||||||
|
const [ value , setValue ] = useState(undefined);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
const url = `/helps/faq.json`;
|
||||||
|
Axios.get(url).then(result=>{
|
||||||
|
if(result){
|
||||||
|
setValue(result.data.data.content);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
},[])
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<Title>常见问题</Title>
|
||||||
|
<div class="contents">
|
||||||
|
<div className="pre">
|
||||||
|
{
|
||||||
|
value ?
|
||||||
|
<RenderHtml className="break_word_comments imageLayerParent" value={value} url={props.history.location}/>
|
||||||
|
:
|
||||||
|
<Skeleton />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default FAQ;
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { HomeHoc } from '../HOC/HomeHoc';
|
||||||
|
import {Route, Switch , Link } from 'react-router-dom';
|
||||||
|
import Loadable from 'react-loadable';
|
||||||
|
import Loading from '../../Loading';
|
||||||
|
import { Box , Long , Short , Gap } from '../../forge/Component/layout';
|
||||||
|
import './Index.scss';
|
||||||
|
import { Menu } from 'antd';
|
||||||
|
|
||||||
|
const Preface = Loadable({
|
||||||
|
loader: () => import('./Preface'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const PSL = Loadable({
|
||||||
|
loader: () => import('./PSL'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const Public = Loadable({
|
||||||
|
loader: () => import('./Public'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const FAQ = Loadable({
|
||||||
|
loader: () => import('./FAQ'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
function Index(props){
|
||||||
|
const [ nav , setNav ] = useState("0");
|
||||||
|
|
||||||
|
const pathname = props.history.location.pathname;
|
||||||
|
useEffect(()=>{
|
||||||
|
if(pathname){
|
||||||
|
if(pathname === `/license/preface`){
|
||||||
|
setNav("0");
|
||||||
|
}
|
||||||
|
if(pathname === `/license/psl/mulanpsl-v1`){
|
||||||
|
setNav("1");
|
||||||
|
}
|
||||||
|
if(pathname === `/license/psl/mulanpsl-v2`){
|
||||||
|
setNav("2");
|
||||||
|
}
|
||||||
|
if(pathname === `/license/public/MulanPubL-V1`){
|
||||||
|
setNav("3");
|
||||||
|
}
|
||||||
|
if(pathname === `/license/faq`){
|
||||||
|
setNav("4");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},[pathname])
|
||||||
|
return(
|
||||||
|
<div className="panelsBox">
|
||||||
|
<Box>
|
||||||
|
<Short>
|
||||||
|
<Menu selectedKeys={[nav]} mode="inline" className="menus" defaultOpenKeys={["2_1"]}>
|
||||||
|
<Menu.Item key="0"><Link to={`/license/preface`}>引言</Link></Menu.Item>
|
||||||
|
<Menu.SubMenu key="2_1" title={"木兰宽松许可证"}>
|
||||||
|
<Menu.Item key="1"><Link to={`/license/psl/mulanpsl-v1`}>第一版</Link></Menu.Item>
|
||||||
|
<Menu.Item key="2"><Link to={`/license/psl/mulanpsl-v2`}>第二版</Link></Menu.Item>
|
||||||
|
</Menu.SubMenu>
|
||||||
|
<Menu.Item key="3"><Link to={`/license/public/MulanPubL-V1`}>木兰公共许可证</Link></Menu.Item>
|
||||||
|
<Menu.Item key="4"><Link to={`/license/faq`}>常见问题</Link></Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
</Short>
|
||||||
|
<Long>
|
||||||
|
<Gap>
|
||||||
|
<div className="boxshadow">
|
||||||
|
<Switch {...props}>
|
||||||
|
<Route
|
||||||
|
path="/license/preface"
|
||||||
|
render={(p) => (
|
||||||
|
<Preface {...props} {...p} />
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
|
<Route
|
||||||
|
path="/license/psl/:id"
|
||||||
|
render={(p) => (
|
||||||
|
<PSL {...props} {...p} />
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
|
<Route
|
||||||
|
path="/license/public/:id"
|
||||||
|
render={(p) => (
|
||||||
|
<Public {...props} {...p} />
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
|
<Route
|
||||||
|
path="/license/faq"
|
||||||
|
render={(p) => (
|
||||||
|
<FAQ {...props} {...p} />
|
||||||
|
)}
|
||||||
|
></Route>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
</Gap>
|
||||||
|
</Long>
|
||||||
|
</Box>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default HomeHoc(Index);
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
.panelsBox{
|
||||||
|
width: 1200px;
|
||||||
|
margin: 20px auto;
|
||||||
|
.menus.ant-menu-inline{
|
||||||
|
border-right: none;
|
||||||
|
box-shadow: 0px 0px 8px 0px #F1F1F1;
|
||||||
|
.ant-menu-submenu-arrow{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ant-menu-item-selected{
|
||||||
|
background-color: #fff;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
.ant-menu-item::after{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.boxshadow{
|
||||||
|
box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.contents{
|
||||||
|
padding:15px 30px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 24px;
|
||||||
|
text-indent: 2em;
|
||||||
|
color: #333;
|
||||||
|
.pre > pre {
|
||||||
|
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.markdown-body table td{
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
.markdown-body table{
|
||||||
|
width: 100%!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import Title from '../../forge/Component/Title';
|
||||||
|
import RenderHtml from '../../components/render-html';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import { Skeleton } from 'antd';
|
||||||
|
import Axios from 'axios';
|
||||||
|
|
||||||
|
function PSL(props){
|
||||||
|
const [value , setValue ] = useState(undefined);
|
||||||
|
const id = props.match.params.id;
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(id && id!==value){
|
||||||
|
setValue(parseInt(id));
|
||||||
|
}
|
||||||
|
},[id])
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
const url = `/helps/${id}.josn`;
|
||||||
|
Axios.get(url).then(result=>{
|
||||||
|
if(result){
|
||||||
|
setValue(result.data.data.content);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
},[id])
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<Title>木兰宽松许可证
|
||||||
|
{/* <Button type={"primary"}>下载</Button> */}
|
||||||
|
</Title>
|
||||||
|
<div class="contents">
|
||||||
|
<div className="pre">
|
||||||
|
{
|
||||||
|
value ?
|
||||||
|
<RenderHtml className="break_word_comments imageLayerParent" value={value} url={props.history.location}/>
|
||||||
|
:
|
||||||
|
<Skeleton />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default PSL;
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import React,{useState,useEffect} from 'react';
|
||||||
|
import Title from '../../forge/Component/Title';
|
||||||
|
import Axios from 'axios';
|
||||||
|
import RenderHtml from '../../components/render-html';
|
||||||
|
import { Skeleton } from 'antd';
|
||||||
|
|
||||||
|
function Preface(props){
|
||||||
|
const [ value , setValue ] = useState(undefined);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
const url = `/helps/introduction.json`;
|
||||||
|
Axios.get(url).then(result=>{
|
||||||
|
if(result){
|
||||||
|
setValue(result.data.data.content);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
},[])
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<Title>引言</Title>
|
||||||
|
<div class="contents">
|
||||||
|
{
|
||||||
|
value ?
|
||||||
|
<RenderHtml className="break_word_comments imageLayerParent" value={value} url={props.history.location}/>
|
||||||
|
:
|
||||||
|
<Skeleton />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Preface;
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import Title from '../../forge/Component/Title';
|
||||||
|
import RenderHtml from '../../components/render-html';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import { Skeleton } from 'antd';
|
||||||
|
import Axios from 'axios';
|
||||||
|
|
||||||
|
function Public(props){
|
||||||
|
const [value , setValue ] = useState(undefined);
|
||||||
|
const id = props.match.params.id;
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(id && id!==value){
|
||||||
|
setValue(parseInt(id));
|
||||||
|
console.log(id);
|
||||||
|
}
|
||||||
|
},[id])
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
const url = `/helps/${id}.josn`;
|
||||||
|
Axios.get(url).then(result=>{
|
||||||
|
if(result){
|
||||||
|
setValue(result.data.data.content);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
},[id])
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
{/* <Button type={"primary"}>下载</Button> */}
|
||||||
|
<Title>木兰公共许可证</Title>
|
||||||
|
<div class="contents">
|
||||||
|
<div className="pre">
|
||||||
|
{
|
||||||
|
value ?
|
||||||
|
<RenderHtml className="break_word_comments imageLayerParent" value={value} url={props.history.location}/>
|
||||||
|
:
|
||||||
|
<Skeleton />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Public;
|
||||||