Compare commits
23 Commits
Author | SHA1 | Date |
---|---|---|
caishi | 114cda0830 | |
caishi | 9d387511e0 | |
caishi | 54b9bd4535 | |
caishi | 088fd09fa6 | |
caishi | 3a46d81e98 | |
caishi | 3321dad83e | |
caishi | fdf342da42 | |
caishi | b89789ac98 | |
caishi | 4d28abaaf1 | |
caishi | edf55d5466 | |
caishi | f2ef8d4843 | |
caishi | 523c8b36e4 | |
caishi | 0717ec8fbb | |
caishi | 941a89cecc | |
caishi | 1b3284cd1d | |
caishi | bea187c1f9 | |
caishi | ccb1dd8216 | |
caishi | 8544c7df86 | |
caishi | 88f56c7160 | |
caishi | f05c3f322f | |
caishi | 087d089705 | |
caishi | d86b07ae4a | |
caishi | 3f01ac4ccb |
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "educoder",
|
||||
"name": "forge",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
|
@ -3888,11 +3888,6 @@
|
|||
"randomfill": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw="
|
||||
},
|
||||
"crypto-random-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
||||
|
@ -4852,7 +4847,7 @@
|
|||
},
|
||||
"dom-closest": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-closest/-/dom-closest-0.2.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/dom-closest/download/dom-closest-0.2.0.tgz",
|
||||
"integrity": "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8=",
|
||||
"requires": {
|
||||
"dom-matches": ">=1.0.1"
|
||||
|
@ -4896,7 +4891,7 @@
|
|||
},
|
||||
"dom-matches": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-matches/-/dom-matches-2.0.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/dom-matches/download/dom-matches-2.0.0.tgz",
|
||||
"integrity": "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw="
|
||||
},
|
||||
"dom-scroll-into-view": {
|
||||
|
@ -5149,7 +5144,7 @@
|
|||
},
|
||||
"enquire.js": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/enquire.js/download/enquire.js-2.1.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fenquire.js%2Fdownload%2Fenquire.js-2.1.6.tgz",
|
||||
"integrity": "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ="
|
||||
},
|
||||
"entities": {
|
||||
|
@ -5668,7 +5663,7 @@
|
|||
},
|
||||
"eventlistener": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventlistener/-/eventlistener-0.0.1.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/eventlistener/download/eventlistener-0.0.1.tgz",
|
||||
"integrity": "sha1-7Suqu4UiJ68rz4iRUscsY8pTLrg="
|
||||
},
|
||||
"events": {
|
||||
|
@ -7925,7 +7920,7 @@
|
|||
},
|
||||
"hammerjs": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/hammerjs/download/hammerjs-2.0.8.tgz",
|
||||
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
|
||||
},
|
||||
"handle-thing": {
|
||||
|
@ -8766,7 +8761,7 @@
|
|||
},
|
||||
"immutable": {
|
||||
"version": "3.7.6",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/immutable/download/immutable-3.7.6.tgz",
|
||||
"integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks="
|
||||
},
|
||||
"import-fresh": {
|
||||
|
@ -10354,7 +10349,7 @@
|
|||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/lodash.throttle/download/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
|
||||
},
|
||||
"lodash.uniq": {
|
||||
|
|
|
@ -5,6 +5,48 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "14835599",
|
||||
"name": "右箭头",
|
||||
"font_class": "arrowRight",
|
||||
"unicode": "e863",
|
||||
"unicode_decimal": 59491
|
||||
},
|
||||
{
|
||||
"icon_id": "21151489",
|
||||
"name": "箭头镂空-左",
|
||||
"font_class": "jiantouloukong-zuo",
|
||||
"unicode": "e861",
|
||||
"unicode_decimal": 59489
|
||||
},
|
||||
{
|
||||
"icon_id": "21151557",
|
||||
"name": "箭头镂空-右",
|
||||
"font_class": "jiantouloukong-you",
|
||||
"unicode": "e862",
|
||||
"unicode_decimal": 59490
|
||||
},
|
||||
{
|
||||
"icon_id": "21568989",
|
||||
"name": "分享",
|
||||
"font_class": "fenxiang1",
|
||||
"unicode": "e89c",
|
||||
"unicode_decimal": 59548
|
||||
},
|
||||
{
|
||||
"icon_id": "21568990",
|
||||
"name": "回到顶部",
|
||||
"font_class": "huidaodingbu1",
|
||||
"unicode": "e89d",
|
||||
"unicode_decimal": 59549
|
||||
},
|
||||
{
|
||||
"icon_id": "21568993",
|
||||
"name": "帮助",
|
||||
"font_class": "bangzhu",
|
||||
"unicode": "e8a0",
|
||||
"unicode_decimal": 59552
|
||||
},
|
||||
{
|
||||
"icon_id": "991344",
|
||||
"name": "提交",
|
||||
|
|
After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 66 KiB |
185
src/App.js
|
@ -35,14 +35,24 @@ const theme = createMuiTheme({
|
|||
secondary: { main: '#4CACFF' }, // #11cb5f This is just green.A700 as hex.
|
||||
},
|
||||
});
|
||||
//forge项目
|
||||
const Projects = Loadable({
|
||||
loader: () => import('./forge/Index'),
|
||||
//首页
|
||||
const Index = Loadable({
|
||||
loader: () => import('./mulan/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
//forge项目-devOps详情
|
||||
const OpsDetail = Loadable({
|
||||
loader: () => import('./forge/DevOps/opsDetail'),
|
||||
//首页
|
||||
const License = Loadable({
|
||||
loader: () => import('./mulan/license/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
//开源活动
|
||||
const Activity = Loadable({
|
||||
loader: () => import('./mulan/Activity/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
//关于我们
|
||||
const About = Loadable({
|
||||
loader: () => import('./mulan/About/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
//403页面
|
||||
|
@ -55,26 +65,15 @@ const Shixunnopage = Loadable({
|
|||
loader: () => import('./modules/404/Shixunnopage'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const Projects =Loadable({
|
||||
loader: () => import('./mulan/Projects/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
//500页面
|
||||
const http500 = Loadable({
|
||||
loader: () => import('./modules/500/http500'),
|
||||
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 {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -131,7 +130,7 @@ class App extends Component {
|
|||
});
|
||||
|
||||
initAxiosInterceptors(this.props);
|
||||
this.getAppdata();
|
||||
this.getSetting();
|
||||
|
||||
window.addEventListener('error', (event) => {
|
||||
const msg = `${event.type}: ${event.message}`;
|
||||
|
@ -144,67 +143,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) => {
|
||||
document.title = response.data.setting.name;
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
document.title = response.name;
|
||||
var link = document.createElement('link'),oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = '/' + response.data.setting.tab_logo_url;
|
||||
link.href = '/' + response.tab_logo_url;
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink);
|
||||
}
|
||||
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() {
|
||||
return (
|
||||
|
@ -214,60 +176,45 @@ class App extends Component {
|
|||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
<Router>
|
||||
<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="/500" component={http500} />
|
||||
<Route path={"/organize"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/*404*/}
|
||||
<Route path="/nopage" component={Shixunnopage} />
|
||||
{/* 个人主页 */}
|
||||
<Route path="/users/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}></Route>
|
||||
<Route exact path="/"
|
||||
|
||||
<Route path="/projects"
|
||||
render={
|
||||
(props) => (
|
||||
<Projects {...this.props} {...props} {...this.state}></Projects>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route component={Shixunnopage} />
|
||||
<Route path="/activity"
|
||||
render={
|
||||
(props) => (
|
||||
<Activity {...this.props} {...props} {...this.state}></Activity>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<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>
|
||||
</Router>
|
||||
</MuiThemeProvider>
|
||||
|
|
|
@ -34,7 +34,7 @@ function clearAllCookie() {
|
|||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
setpostcookie()
|
||||
}
|
||||
clearAllCookie();
|
||||
// clearAllCookie();
|
||||
function setpostcookie() {
|
||||
const str = window.location.pathname;
|
||||
if (str.indexOf("/wxcode") !== -1) {
|
||||
|
@ -50,13 +50,13 @@ function setpostcookie() {
|
|||
}
|
||||
}
|
||||
}
|
||||
setpostcookie();
|
||||
// setpostcookie();
|
||||
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
initOnlineOfflineListener();
|
||||
var proxy = "http://localhost:3000";
|
||||
proxy = "https://testforgeplus.trustie.net";
|
||||
proxy = "https://mulan.trustie.net";
|
||||
|
||||
const requestMap = {};
|
||||
window.setfalseInRequestMap = function (keyName) {
|
||||
|
@ -65,10 +65,10 @@ export function initAxiosInterceptors(props) {
|
|||
//响应前的设置
|
||||
axios.interceptors.request.use(
|
||||
config => {
|
||||
setpostcookie()
|
||||
clearAllCookie()
|
||||
// clearAllCookie()
|
||||
// setpostcookie()
|
||||
|
||||
if (config.url.indexOf(proxy) !== -1) {
|
||||
if (config.url.indexOf("http") !== -1) {
|
||||
return config
|
||||
}
|
||||
requestProxy(config)
|
||||
|
@ -79,20 +79,20 @@ export function initAxiosInterceptors(props) {
|
|||
if (window.location.port === "3007") {
|
||||
config.url = `${proxy}${url}`;
|
||||
if (config.url.indexOf('?') === -1) {
|
||||
config.url = `${config.url}?debug=${debugType}`;
|
||||
config.url = `${config.url}`;
|
||||
} else {
|
||||
config.url = `${config.url}&debug=${debugType}`;
|
||||
config.url = `${config.url}`;
|
||||
}
|
||||
} else {
|
||||
config.url = url;
|
||||
}
|
||||
setpostcookie();
|
||||
// setpostcookie();
|
||||
}
|
||||
if (config.url.indexOf('update_file') === -1) {
|
||||
requestMap[config.url] = true;
|
||||
// if (config.url.indexOf('update_file') === -1) {
|
||||
// requestMap[config.url] = true;
|
||||
|
||||
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||
}
|
||||
// window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||
// }
|
||||
return config;
|
||||
},
|
||||
err => {
|
||||
|
@ -147,7 +147,7 @@ export function initAxiosInterceptors(props) {
|
|||
}, 2000);
|
||||
}
|
||||
requestMap[response.config.url] = false;
|
||||
setpostcookie();
|
||||
// setpostcookie();
|
||||
return response;
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
|
|
|
@ -6,12 +6,12 @@ const { Search } = Input;
|
|||
const $ = window.$;
|
||||
const isDev = window.location.port == 3007;
|
||||
const isdev2= window.location.hostname ==='www.educoder.net'
|
||||
export const TEST_HOST = "https://testforgeplus.trustie.net/"
|
||||
export const TEST_HOST = "https://mulan.trustie.net/"
|
||||
export function getImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net';
|
||||
const local = 'https://mulan.trustie.net';
|
||||
if (isDev) {
|
||||
return `${local}/${path}`
|
||||
}
|
||||
|
@ -19,10 +19,7 @@ export function getImageUrl(path) {
|
|||
}
|
||||
|
||||
export function getImage(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net/';
|
||||
const local = 'https://mulan.trustie.net/';
|
||||
if(path.indexOf("http://")===-1){
|
||||
if (isDev) {
|
||||
return `${local}/images/${path}`
|
||||
|
@ -34,9 +31,6 @@ export function getImage(path) {
|
|||
}
|
||||
|
||||
export function getcdnImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const testlocal = 'https://testali-cdn.educoder.net'
|
||||
const local='https://ali-cdn.educoder.net'
|
||||
let firstStr=path.substr(0,1);
|
||||
|
@ -93,7 +87,7 @@ export function setImagesUrl(path){
|
|||
}
|
||||
|
||||
export function getUrl(path, goTest) {
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
const local = 'https://mulan.trustie.net'
|
||||
if (isDev) {
|
||||
return `${local}${path?path:''}`
|
||||
}
|
||||
|
|
|
@ -44,6 +44,11 @@ export const Long = styled.div`{
|
|||
border-radius:5px;
|
||||
margin-bottom:30px;
|
||||
}`
|
||||
export const Longdata = styled.div`{
|
||||
width:69%;
|
||||
border-radius:5px;
|
||||
margin-bottom:30px;
|
||||
}`
|
||||
export const ShortWidth = styled.div`{
|
||||
width:300px;
|
||||
border-radius:5px;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React , { Component } from 'react';
|
||||
|
||||
import nodata from './Images/nodata.png';
|
||||
import './css/nodata.scss';
|
||||
|
||||
class Nodata extends Component{
|
||||
render(){
|
||||
|
|
|
@ -5,7 +5,7 @@ import axios from "axios";
|
|||
import Upload from "../Upload/Index";
|
||||
import UploadImg from "../Images/upload.png";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { List, Popconfirm, Pagination, Button, Tabs, Avatar } from "antd";
|
||||
import { List, Popconfirm, Pagination, Button, Tabs } from "antd";
|
||||
import Attachments from "../Upload/attachment";
|
||||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import RenderHtml from "../../components/render-html";
|
||||
|
|
|
@ -84,26 +84,6 @@ ul,ol,dl{
|
|||
background-color: #f4f4f4;
|
||||
line-height: 18px;
|
||||
}
|
||||
.none_panels{
|
||||
text-align: center;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&.small{
|
||||
height: 120px;
|
||||
img{
|
||||
width:50px;
|
||||
}
|
||||
}
|
||||
img{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.none_p_title{
|
||||
font-size: 16px;
|
||||
color: #999;
|
||||
}
|
||||
form.ant-form{
|
||||
color:#333;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
.none_panels{
|
||||
text-align: center;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&.small{
|
||||
height: 120px;
|
||||
img{
|
||||
width:50px;
|
||||
}
|
||||
}
|
||||
img{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.none_p_title{
|
||||
font-size: 16px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
|
@ -66,19 +66,3 @@ export function requestProxy(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,31 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { Banner } from '../../forge/Component/layout';
|
||||
import { Skeleton } from 'antd';
|
||||
|
||||
|
||||
function About(props){
|
||||
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>
|
||||
<Banner>关于我们</Banner>
|
||||
<div className="desc">
|
||||
{about ? about.content : <Skeleton />}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default About;
|
|
@ -0,0 +1,67 @@
|
|||
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';
|
||||
import'./Index.scss';
|
||||
|
||||
const About = Loadable({
|
||||
loader: () => import('./About'),
|
||||
loading: Loading,
|
||||
})
|
||||
const TOC = Loadable({
|
||||
loader: () => import('./TOC'),
|
||||
loading: Loading,
|
||||
})
|
||||
function Index(props){
|
||||
const [ nav , setNav ] = useState("0");
|
||||
|
||||
const pathname = props.history.location.pathname;
|
||||
useEffect(()=>{
|
||||
if(pathname){
|
||||
if(pathname === `/about`){
|
||||
setNav("0");
|
||||
}
|
||||
if(pathname === `/about/TOC`){
|
||||
setNav("1");
|
||||
}
|
||||
}
|
||||
},[pathname])
|
||||
|
||||
return(
|
||||
<div className="aboutboxs">
|
||||
<Box>
|
||||
<Short>
|
||||
<Menu selectedKeys={[nav]} mode="inline" className="menus">
|
||||
<Menu.Item key="0"><Link to={`/about`}>关于我们</Link></Menu.Item>
|
||||
<Menu.Item key="1"><Link to={`/about/TOC`}>TOC</Link></Menu.Item>
|
||||
</Menu>
|
||||
</Short>
|
||||
<Long>
|
||||
<Gap>
|
||||
<div className="boxshadow">
|
||||
<Switch {...props}>
|
||||
<Route
|
||||
path="/about/TOC"
|
||||
render={(p) => (
|
||||
<TOC {...props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/about"
|
||||
render={(p) => (
|
||||
<About {...props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
</Gap>
|
||||
</Long>
|
||||
</Box>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default HomeHoc(Index);
|
|
@ -0,0 +1,56 @@
|
|||
.aboutboxs{
|
||||
width: 1200px;
|
||||
margin:20px auto;
|
||||
.menus.ant-menu-inline {
|
||||
border-right: none;
|
||||
box-shadow: 0px 0px 8px 0px #f1f1f1;
|
||||
}
|
||||
.boxshadow {
|
||||
box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
.desc{
|
||||
line-height: 26px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
text-indent: 2em;
|
||||
text-align: justify;
|
||||
padding:40px;
|
||||
}
|
||||
}
|
||||
.descTOC{
|
||||
padding:20px;
|
||||
.descUl{
|
||||
text-indent: 0px;
|
||||
margin-left: 20px;
|
||||
padding-left: 0px;
|
||||
li{
|
||||
list-style-type: disc;
|
||||
margin-left:20px;
|
||||
}
|
||||
}
|
||||
.descPerson{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding:10px 0px;
|
||||
align-items: flex-start;
|
||||
li{
|
||||
width: 25%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin:20px 4%!important;
|
||||
text-align: center;
|
||||
img{
|
||||
margin-bottom: 15px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
border-radius: 50%;
|
||||
cursor: default;
|
||||
}
|
||||
span.school{
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { Banner } from '../../forge/Component/layout';
|
||||
import { Skeleton } from 'antd';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
|
||||
function TOC(props){
|
||||
const [ data , setData ] = useState(undefined);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
getAbout();
|
||||
},[])
|
||||
|
||||
function getAbout(){
|
||||
const url = `/helps/toc.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setData(result.data.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
<Banner>木兰开源社区技术委员会</Banner>
|
||||
{
|
||||
data ?
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={data.content} url={props.history.location}/>
|
||||
// <div className="descTOC">
|
||||
// <ul className="descUl">主要为木兰开源社区旗下的开源项目提供技术指导,具体职责如下:
|
||||
// <li>对孵化项目进行批准及毕业审核;</li>
|
||||
// <li>促进项目“产学研用”之间的生态联系;</li>
|
||||
// <li>为项目提供国际化的视野与技术指导。</li>
|
||||
// </ul>
|
||||
// <ul className="descPerson">
|
||||
// <li>
|
||||
// <img src="" alt="" />
|
||||
// <span className="name">梅院士</span>
|
||||
// <span className="school">北京大学院士</span>
|
||||
// </li>
|
||||
// <li>
|
||||
// <img src="" alt="" />
|
||||
// <span className="name">梅院士</span>
|
||||
// <span className="school">北京大学院士</span>
|
||||
// </li>
|
||||
// <li>
|
||||
// <img src="" alt="" />
|
||||
// <span className="name">梅院士</span>
|
||||
// <span className="school">北京大学院士</span>
|
||||
// </li>
|
||||
// <li>
|
||||
// <img src="" alt="" />
|
||||
// <span className="name">梅院士</span>
|
||||
// <span className="school">北京大学院士</span>
|
||||
// </li>
|
||||
// <li>
|
||||
// <img src="" alt="" />
|
||||
// <span className="name">梅院士</span>
|
||||
// <span className="school">北京大学院士</span>
|
||||
// </li>
|
||||
// </ul>
|
||||
// </div>
|
||||
:<Skeleton />
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default TOC;
|
|
@ -0,0 +1,115 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Skeleton } from 'antd';
|
||||
import { Box , Longdata , Short , Gap , AlignCenter } from '../../forge/Component/layout';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import Axios from 'axios';
|
||||
import { getUrlHead } from '../Data/getUrl';
|
||||
import Comments from '../comments/Index';
|
||||
|
||||
function Detail(props){
|
||||
const id = props.match.params.id;
|
||||
|
||||
const [ data , setData ] = useState(undefined);
|
||||
useEffect(()=>{
|
||||
if(id){
|
||||
getDetail();
|
||||
}
|
||||
},[id])
|
||||
function getDetail(){
|
||||
const url = `/topics/${id}.json`;
|
||||
Axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setData(result.data.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="detailpanels">
|
||||
<div className="panels">
|
||||
{
|
||||
data ?
|
||||
<div className="detailinfo">
|
||||
<img src={getUrlHead(data.cover)} className="cover" alt=""/>
|
||||
<div className="detailvalue">
|
||||
<p className="task-hide-2 name">{data.title}</p>
|
||||
{ data.created_at && <p><span className="tag">时间:</span><span className="value">{data.created_at}</span></p>}
|
||||
{ data.city && <p><span className="tag">地点:</span><span className="value">{data.city}</span></p>}
|
||||
{ data.viewers_count && <p><i className="iconfont icon-dianjiliang"></i><span className="value" style={{color:"#999"}}>{data.viewers_count}</span></p>}
|
||||
</div>
|
||||
</div>
|
||||
:<Skeleton />
|
||||
}
|
||||
|
||||
<Box>
|
||||
<Longdata>
|
||||
{
|
||||
data ?
|
||||
<div className="detailContents">
|
||||
<h2>活动详情</h2>
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={data.content} url={props.history.location}/>
|
||||
{
|
||||
data.attachments && data.attachments.length>0&&
|
||||
<ul className="mt20">
|
||||
{
|
||||
data.attachments.map((i,k)=>{
|
||||
return(
|
||||
<li><a href={getUrlHead(i.url)}><i className="iconfont icon-wenjia mr5 font-14 color-grey-9"></i>{i.filename}</a></li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
:<Skeleton />
|
||||
}
|
||||
<Comments id={id} users={props.users} mainShowLogin={props && props.mainShowLogin}/>
|
||||
</Longdata>
|
||||
<Short>
|
||||
<Gap>
|
||||
{
|
||||
data && data.author ?
|
||||
<div className="detailAuthor">
|
||||
<h2>发布者</h2>
|
||||
<AlignCenter>
|
||||
<img src={getUrlHead(data.author.image_url)} alt="" className="authorImg"/>
|
||||
<span className="authorName">{data.author.name}</span>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
{
|
||||
data && data.recommend_topics && data.recommend_topics.length>0 ?
|
||||
<div className="detailRecommand">
|
||||
<h2>推荐活动</h2>
|
||||
<ul className="recommandslist">
|
||||
{
|
||||
data.recommend_topics.map((i,k)=>{
|
||||
return(
|
||||
<li onClick={()=>{props.history.push(`/activity/1`)}}>
|
||||
<img src={getUrlHead(i.cover)} alt="" />
|
||||
<div className="numInfo">
|
||||
<p className="task-hide-2 name">{i.title}</p>
|
||||
<div className="number">
|
||||
{ i.created_at && <span><i className="iconfont icon-timefill"></i><span>{i.created_at}</span></span> }
|
||||
{ i.city && <span><i className="iconfont icon-weizhi"></i><span>{i.city}</span></span> }
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
|
||||
</Gap>
|
||||
</Short>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Detail;
|
|
@ -0,0 +1,36 @@
|
|||
import React from 'react';
|
||||
import { HomeHoc } from '../HOC/HomeHoc';
|
||||
import {Route, Switch } from 'react-router-dom';
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../Loading';
|
||||
import './Index.scss';
|
||||
import'./Index.scss';
|
||||
|
||||
const Detail = Loadable({
|
||||
loader: () => import('./Detail'),
|
||||
loading: Loading,
|
||||
})
|
||||
const List = Loadable({
|
||||
loader: () => import('./List'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
function Index(props){
|
||||
return(
|
||||
<Switch {...props}>
|
||||
<Route
|
||||
path="/activity/:id"
|
||||
render={(p) => (
|
||||
<Detail {...props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/activity"
|
||||
render={(p) => (
|
||||
<List {...props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
export default HomeHoc(Index);
|
|
@ -0,0 +1,226 @@
|
|||
.panels{
|
||||
width: 1200px;
|
||||
margin:0px auto;
|
||||
.sortPanel{
|
||||
border-radius: 2px;
|
||||
border: 1px solid #EEEEEE;
|
||||
padding:25px 0px 0px 35px;
|
||||
margin:30px 0px 20px;
|
||||
& > div{
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
& > span{
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
& >ul {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0px;
|
||||
& > li{
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
padding:0px 14px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
&.active{
|
||||
background-color: #1890FF;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menus{
|
||||
margin-bottom: 10px;
|
||||
.ant-menu-item{
|
||||
padding:10px 0px;
|
||||
margin:0px 40px 0px 0px;
|
||||
font-size: 18px;
|
||||
position: relative;
|
||||
&.ant-menu-item-selected,&.ant-menu-item-active,&:hover{
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
&.ant-menu-item-selected::after{
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
left: 50%;
|
||||
margin-left: -20px;
|
||||
bottom: -2px;
|
||||
content: "";
|
||||
background-color: #1890ff;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lists{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
min-height: 400px;
|
||||
li{
|
||||
cursor: pointer;
|
||||
width: 270px;
|
||||
margin:20px 40px 20px 0px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px #F1F1F1;
|
||||
border-radius: 0px 0px 8px 8px;
|
||||
&:nth-child(4n){
|
||||
margin-right: 0px;
|
||||
}
|
||||
.imgCover{
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
border-radius: 8px 8px 0px 0px;
|
||||
}
|
||||
.infos{
|
||||
padding:20px 16px;
|
||||
.infoName{
|
||||
color: #666;
|
||||
line-height: 22px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.infosItem{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 12px;
|
||||
color: #888888;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
&>span{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
i{
|
||||
font-size: 15px!important;
|
||||
margin-right: 7px;
|
||||
color: #B9DDFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.detailpanels{
|
||||
padding:40px 0px;
|
||||
background-color: #fafafa;
|
||||
.detailinfo{
|
||||
margin-bottom: 30px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius:4px;
|
||||
.cover{
|
||||
width: 500px;
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
}
|
||||
.detailvalue{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
padding:30px 20px;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
& > p{
|
||||
margin-bottom: 10px;
|
||||
line-height: 22px;
|
||||
.tag{
|
||||
color: #888888;
|
||||
}
|
||||
.value{
|
||||
color: #666;
|
||||
}
|
||||
&>i{
|
||||
font-size: 12px!important;
|
||||
color: #888888;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.name{
|
||||
font-size: 22px;
|
||||
color: #333;
|
||||
line-height: 30px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detailContents{
|
||||
background-color: #fff;
|
||||
padding:38px;
|
||||
}
|
||||
.detailAuthor{
|
||||
background-color: #fff;
|
||||
padding:20px 20px 30px;
|
||||
.authorImg{
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
margin-right: 50px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.authorName{
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.detailRecommand{
|
||||
margin-top: 24px;
|
||||
background-color: #fff;
|
||||
padding:20px;
|
||||
.recommandslist{
|
||||
li{
|
||||
display: flex;
|
||||
margin-top:28px ;
|
||||
cursor: pointer;
|
||||
img{
|
||||
max-width: 150px;
|
||||
height: 90px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.name{
|
||||
color: #333;
|
||||
line-height: 18px;
|
||||
margin-bottom: 8px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.numInfo{
|
||||
flex:1;
|
||||
width: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.number{
|
||||
& > span{
|
||||
display: flex;
|
||||
line-height: 18px;
|
||||
font-size: 12px;
|
||||
height: 18px;
|
||||
align-items: center;
|
||||
span{
|
||||
color: #888;
|
||||
}
|
||||
i{
|
||||
margin-right: 8px;
|
||||
font-size: 14px!important;
|
||||
color: #B9DDFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
import React, { useState , useEffect } from 'react';
|
||||
import { Menu , Pagination , Spin } from 'antd';
|
||||
import { getUrlHead } from '../Data/getUrl';
|
||||
import Cards from '../images/cards.png';
|
||||
import Axios from 'axios';
|
||||
import Nodata from '../../forge/Nodata';
|
||||
|
||||
const timeArray=[
|
||||
{name:"今天",id:"today"},
|
||||
{name:"明天",id:"tomorrow"},
|
||||
{name:"本周",id:"toweek"},
|
||||
{name:"本月",id:"tomonth"}
|
||||
]
|
||||
const cityArray=[
|
||||
{name:"北京",id:"北京"},
|
||||
{name:"上海",id:"上海"},
|
||||
{name:"广州",id:"广州"},
|
||||
{name:"深圳",id:"深圳"},
|
||||
{name:"杭州",id:"杭州"},
|
||||
{name:"成都",id:"成都"},
|
||||
{name:"南京",id:"南京"},
|
||||
{name:"苏州",id:"苏州"},
|
||||
{name:"武汉",id:"武汉"},
|
||||
{name:"天津",id:"天津"},
|
||||
{name:"重庆",id:"重庆"},
|
||||
{name:"西安",id:"西安"},
|
||||
{name:"厦门",id:"厦门"},
|
||||
{name:"宁波",id:"宁波"},
|
||||
{name:"郑州",id:"郑州"},
|
||||
{name:"青岛",id:"青岛"},
|
||||
{name:"东莞",id:"东莞"},
|
||||
{name:"佛山",id:"佛山"},
|
||||
{name:"长沙",id:"长沙"},
|
||||
{name:"石家庄",id:"石家庄"},
|
||||
{name:"昆明",id:"昆明"},
|
||||
];
|
||||
const limit = 16;
|
||||
function List(props){
|
||||
|
||||
const [ sort , setSort ] = useState(undefined);
|
||||
const [ sortArray ,setSortArray ] = useState(undefined);
|
||||
const [ time , setTime ] = useState(undefined);
|
||||
const [ city , setCity ] = useState(undefined);
|
||||
const [ menu , setMenu ] = useState("start_time");
|
||||
|
||||
const [ isSpin , setIsSpin ] =useState(false);
|
||||
const [ page ,setPage ]= useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ list , setList ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
getSort();
|
||||
},[])
|
||||
|
||||
function getSort(){
|
||||
const url = `/topic_categories.json`
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
topic_type:"activity"
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setSortArray(result.data.topic_categories)
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
setIsSpin(true);
|
||||
getList();
|
||||
},[sort,time,city,menu])
|
||||
|
||||
function getList(){
|
||||
const url = `/topics.json`;
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
topic_type:"activity",
|
||||
time_type:time,
|
||||
city,
|
||||
sort_by:menu,
|
||||
sort_direction:"desc",
|
||||
topic_category_id:sort
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setList(result.data.data);
|
||||
setTotal(result.data.total_count);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function renderMenu(data,func,name){
|
||||
return(
|
||||
data.map((i,k)=>{
|
||||
return(
|
||||
<li onClick={()=>func(i.id)} className={name===i.id?"active":""}>{i.name}</li>
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="panels">
|
||||
<div className="sortPanel">
|
||||
<div>
|
||||
<span>分类:</span>
|
||||
<ul>
|
||||
<li className={!sort ? "active":""} onClick={()=>setSort(undefined)}>全部</li>
|
||||
{ sortArray && renderMenu(sortArray,setSort,sort)}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<span>时间:</span>
|
||||
<ul>
|
||||
<li className={!time ? "active":""} onClick={()=>setTime(undefined)}>全部</li>
|
||||
{ renderMenu(timeArray,setTime,time)}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<span>城市:</span>
|
||||
<ul>
|
||||
<li className={!city ? "active":""} onClick={()=>setCity(undefined)}>全部</li>
|
||||
{ renderMenu(cityArray,setCity,city)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Menu selectedKeys={[menu]} mode={"horizontal"} className="menus" onSelect={(e)=>{setIsSpin(true);setMenu(e.key)}}>
|
||||
<Menu.Item key="start_time">最新发布</Menu.Item>
|
||||
<Menu.Item key="viewers_count">热门活动</Menu.Item>
|
||||
</Menu>
|
||||
<Spin spinning={isSpin}>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<ul className="lists">
|
||||
{
|
||||
list.map((i,k)=>{
|
||||
return(
|
||||
<li onClick={()=>{props.history.push(`/activity/${i.id}`)}}>
|
||||
<img src={getUrlHead(i.cover)} className="imgCover"/>
|
||||
<div className="infos">
|
||||
<p className="task-hide-2 infoName">{i.title}</p>
|
||||
<div className="infosItem">
|
||||
{ i.created_at && <span><i className="iconfont icon-timefill"></i><span>{i.created_at}</span></span> }
|
||||
{ i.city && <span><i className="iconfont icon-weizhi"></i><span>{i.city}</span></span> }
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>:""
|
||||
}
|
||||
{
|
||||
list && list.length === 0 && <Nodata _html="暂无活动~"/>
|
||||
}
|
||||
</Spin>
|
||||
{
|
||||
total > limit &&
|
||||
<div>
|
||||
<Pagination showQuickJumper pageSize={limit} current={page} total={total} onChange={e=>{setPage(e)}}/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default List;
|
|
@ -0,0 +1,45 @@
|
|||
.loginModal{
|
||||
.homeHOCLoginmenu{
|
||||
.ant-menu-item{
|
||||
padding:0px;
|
||||
margin:0px 30px;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
}
|
||||
}
|
||||
.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 } 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="请输入登录账号" onBlur={changeInput} onChange={changeInput}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{getFieldDecorator("password",{
|
||||
rules:[{required:true,message:"请输入登录密码"}]
|
||||
})(
|
||||
<Input.Password placeholder="请输入登录密码" onBlur={changeInput} 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"} className="homeHOCLoginmenu">
|
||||
<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, mainShowLogin , quitFunc , match }){
|
||||
return(
|
||||
<div className="headsnav">
|
||||
<Nav
|
||||
match={match}
|
||||
users={users}
|
||||
headData={headData}
|
||||
mainShowLogin={mainShowLogin}
|
||||
quitFunc={quitFunc}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Header;
|
|
@ -0,0 +1,80 @@
|
|||
import React, { Component } from 'react';
|
||||
import Header from './Header';
|
||||
import Footer from './Footer';
|
||||
import './Index.scss';
|
||||
import axios from 'axios';
|
||||
import LoginModal from '../Components/Login/LoginModal';
|
||||
|
||||
|
||||
export function HomeHoc(Sub){
|
||||
return class II extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
users:undefined,
|
||||
visible:false
|
||||
}
|
||||
}
|
||||
|
||||
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)=> {
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
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=>{})
|
||||
}
|
||||
|
||||
mainShowLogin=()=>{
|
||||
this.setState({
|
||||
visible:true
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
const { users , visible } = this.state;
|
||||
const { headData } = this.props;
|
||||
return(
|
||||
<div style={{height:"100%",overflow:"auto",position:"relative"}}>
|
||||
<LoginModal visible={visible} onCancel={()=>{this.setState({visible:false})}} successFunc={this.successFunc}/>
|
||||
<Header {...this.props} {...this.state} users={users} headData={headData} mainShowLogin={this.mainShowLogin} quitFunc={this.quitFunc}/>
|
||||
<div className="homebody">
|
||||
<Sub {...this.props} {...this.state} users={users} mainShowLogin={this.mainShowLogin}/>
|
||||
<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 , mainShowLogin , 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 && 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={mainShowLogin}>登录/注册</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Nav;
|
|
@ -0,0 +1,341 @@
|
|||
import React, { useEffect, useState , useRef } 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 , Spin } from 'antd';
|
||||
import { getUrlHead } from './Data/getUrl';
|
||||
import axios from 'axios';
|
||||
|
||||
function Index(props){
|
||||
const Carousels = useRef(null);
|
||||
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 [ newActivity ,setNewActivity ] =useState(undefined);
|
||||
const [ cooperatersMenus ,setCooperatersMenus ] =useState(undefined);
|
||||
const [ cooperatersMenusValue ,setCooperatersMenusValue ] =useState(undefined);
|
||||
const [ cooperaters ,setCooperaters ] =useState(undefined);
|
||||
const [ lectures ,setLectures ] =useState(undefined);
|
||||
const [ isSpin ,setIsSpin ] =useState(false);
|
||||
useEffect(()=>{
|
||||
getRecommand();
|
||||
getAbout();
|
||||
getNews();
|
||||
getActivity();
|
||||
getCooperatersMenu();
|
||||
getLectures();
|
||||
getNewActivity();
|
||||
},[])
|
||||
// 专家寄语
|
||||
function getLectures(){
|
||||
const url = `/lectures.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setLectures(result.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 关于我们
|
||||
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:{topic_type:"activity",page:1,limit:4,order_by:"created_at",order_direction:"desc"}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setNews(result.data.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
// 最新动态
|
||||
function getNewActivity(){
|
||||
const url = `/topics.json`;
|
||||
axios.get(url,{
|
||||
params:{topic_type:"moment",page:1,limit:4,order_by:"created_at",order_direction:"desc"}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setNewActivity(result.data.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
// 开源资讯
|
||||
function getActivity(){
|
||||
const url = `/topics.json`;
|
||||
axios.get(url,{
|
||||
params:{topic_type:"news",page:1,limit:6,order_by:"created_at",order_direction:"desc"}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setActivity(result.data.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 合作伙伴-menu
|
||||
function getCooperatersMenu(){
|
||||
const url = `/cooperater_categories.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
let data = result.data.data;
|
||||
if(data && data.length>0){
|
||||
setCooperatersMenus(data);
|
||||
setCooperatersMenusValue(data[0].id);
|
||||
}
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(cooperatersMenusValue){
|
||||
setIsSpin(true);
|
||||
getCooperaters(cooperatersMenusValue);
|
||||
}
|
||||
},[cooperatersMenusValue])
|
||||
|
||||
// 合作伙伴
|
||||
function getCooperaters(cateId){
|
||||
const url = `/cooperaters.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
cooperater_category_id:cateId
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setCooperaters(result.data.data);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).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>
|
||||
{
|
||||
newActivity && newActivity.length > 0 &&
|
||||
<div>
|
||||
<div class="tit">最新动态</div>
|
||||
<ul className="newActivity">
|
||||
{
|
||||
newActivity.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<a href={i.url}>
|
||||
<img src={getUrlHead(i.cover)} alt="" />
|
||||
<div className="infobox">
|
||||
<span className="time">{i.created_at}</span>
|
||||
<p className="name">{i.title}</p>
|
||||
<div className="desc">{i.content}</div>
|
||||
<a href={i.url} className="color-blue">了解详情<i className="iconfont icon-arrowRight ml5 font-14 color-blue"></i></a>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</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} className="task-hide" style={{display:"block"}} 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>
|
||||
<div>
|
||||
<div class="tit">专家寄语</div>
|
||||
<div className="professional">
|
||||
<Carousel
|
||||
ref={Carousels}
|
||||
autoplay
|
||||
pauseOnDotsHover
|
||||
arrows={lectures && lectures.total_count && lectures.total_count > 1}
|
||||
speed={1500}
|
||||
prevArrow={<button type='button' className='slick-prev slick-arrow'><i className='iconfont icon-jiantouloukong-zuo'></i></button>}
|
||||
nextArrow={<button type='button' className='slick-next slick-arrow'><i className='iconfont icon-jiantouloukong-you'></i></button>}
|
||||
>
|
||||
{
|
||||
lectures && lectures.data && lectures.data.length>0 &&
|
||||
lectures.data.map((i,k)=>{
|
||||
return(
|
||||
<div className="professionalItem">
|
||||
<img src={getUrlHead(i.avatar_url)} alt="" className="professionalImg"/>
|
||||
<span className="name">{i.expert_name}</span>
|
||||
<span className="school">{i.expert_title}</span>
|
||||
<p className="content">{i.content}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Carousel>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tit">合作伙伴</div>
|
||||
{
|
||||
cooperatersMenus && cooperatersMenusValue &&
|
||||
<ul className="cooperatersMenus">
|
||||
{
|
||||
cooperatersMenus.map((i,k)=>{
|
||||
return(
|
||||
<li className={cooperatersMenusValue === i.id ?"active":""} onClick={()=>setCooperatersMenusValue(i.id)}>{i.name}</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
<Spin spinning={isSpin}>
|
||||
{
|
||||
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>
|
||||
}
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default HomeHoc(Index);
|
|
@ -0,0 +1,404 @@
|
|||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.professional{
|
||||
width: 1300px;
|
||||
height: 434px;
|
||||
margin: 0px auto;
|
||||
background-image: url(./images/professional.png);
|
||||
background-repeat: no-repeat;
|
||||
margin-bottom: 60px;
|
||||
.ant-carousel,.slick-slider,.slick-list,.slick-track,.slick-slide>div{
|
||||
height: 100%;
|
||||
}
|
||||
.slick-slider{
|
||||
&:hover .slick-arrow{
|
||||
display: block!important;
|
||||
}
|
||||
.slick-arrow{
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
z-index: 10;
|
||||
display: none!important;
|
||||
&:hover i{
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
.slick-arrow > i{
|
||||
color: rgb(236, 236, 236);
|
||||
font-size: 46px!important;
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
line-height: 46px;
|
||||
}
|
||||
.slick-prev{
|
||||
left: 70px;
|
||||
}
|
||||
.slick-next{
|
||||
right: 70px;
|
||||
}
|
||||
}
|
||||
.professionalItem{
|
||||
display: flex!important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
.professionalImg{
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 25px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.name{
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
line-height: 40px;
|
||||
display: block;
|
||||
}
|
||||
.school{
|
||||
color: #888;
|
||||
display: block;
|
||||
line-height: 30px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.content{
|
||||
max-width: 1000px;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.homeFooterParter{
|
||||
padding:40px 0px;
|
||||
width: 1200px;
|
||||
margin:0px auto!important;
|
||||
}
|
||||
|
||||
.newActivity{
|
||||
width: 1240px;
|
||||
margin:40px auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
li{
|
||||
width: 280px;
|
||||
margin:0px 30px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px #F1F1F1;
|
||||
&:hover{
|
||||
box-shadow: 0px 0px 40px 0px rgba(24, 144, 255, 0.3);
|
||||
}
|
||||
& >a img{
|
||||
max-height: 150px;
|
||||
width: 100%;
|
||||
}
|
||||
.infobox{
|
||||
padding:20px;
|
||||
.time{
|
||||
color:#666666;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.name{
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.desc{
|
||||
line-height: 20px;
|
||||
color: #666;
|
||||
height: 100px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 5;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.homeFooterUl{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0px;
|
||||
flex-wrap: wrap;
|
||||
li{
|
||||
padding:0px 40px 20px 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cooperatersMenus{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
li{
|
||||
padding:0px 50px;
|
||||
font-size: 18px;
|
||||
color: #333333;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
&.active{
|
||||
color: #1890FF;
|
||||
}
|
||||
&.active::after{
|
||||
position: absolute;
|
||||
content: "";
|
||||
background-color: #1890FF;
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
left: 50%;
|
||||
margin-left: -25px;
|
||||
bottom: -5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 &&
|
||||
<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,153 @@
|
|||
.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;
|
||||
min-height: 49px;
|
||||
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;
|
||||
&:hover{
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
.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>
|
||||
<a href={i.project_url} className="name task-hide">{i.project_full_name}</a>
|
||||
<span className="num">{i.commits}</span>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
:<Skeleton />
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Ranking;
|
|
@ -0,0 +1,143 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import Axios from 'axios';
|
||||
import './Index.scss';
|
||||
import ReplayBox from './ReplyBox';
|
||||
import List from './List';
|
||||
|
||||
function Index({id,users,mainShowLogin}){
|
||||
|
||||
const [ data , setData ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ limit , setLimit ] = useState(6);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ yu , setYu ] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
if(id){
|
||||
getAllComments(1,page*limit);
|
||||
}
|
||||
},[id,page])
|
||||
|
||||
function getAllComments(p,l){
|
||||
const url = `/comments.json`;
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
commentable_type:"Topic",
|
||||
commentable_id:id,
|
||||
page:p,limit:l
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setData(result.data.data);
|
||||
setTotal(result.data.total_count);
|
||||
let size = parseInt(result.data.total_count/limit);
|
||||
if(result.data.total_count%limit>0){
|
||||
size++;
|
||||
}
|
||||
setYu(size);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 评论活动或者评论上一级(是否有parent_id)
|
||||
function submit(v,pareid){
|
||||
const params={
|
||||
comment:{
|
||||
commentable_type:"Topic",
|
||||
commentable_id:id,
|
||||
content:v,
|
||||
parent_id:pareid
|
||||
}
|
||||
}
|
||||
const url = `/comments.json`;
|
||||
Axios.post(url,params).then(result=>{
|
||||
if(result && result.data){
|
||||
getAllComments(1,page*limit);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 评论
|
||||
function commentFunc(flag,index){
|
||||
var lists = data.concat();
|
||||
lists.map(i=>i.flag = false);
|
||||
lists[index].flag = !flag ? true : false;
|
||||
lists.splice();
|
||||
setData(lists);
|
||||
}
|
||||
|
||||
// 点赞、取消点赞
|
||||
function pariseFunc(id,is_like,count,index){
|
||||
let url = '';
|
||||
const params={
|
||||
likable_type:"Comment",likable_id:id
|
||||
}
|
||||
if(is_like){
|
||||
url = `/likes/unlike.json`;
|
||||
}else{
|
||||
url = `/likes/like.json`;
|
||||
}
|
||||
Axios.get(url,{
|
||||
params
|
||||
}).then(result=>{
|
||||
if(result && result.data && result.data.status === 0){
|
||||
var lists = data.concat();
|
||||
lists.map(i=>i.flag = false);
|
||||
lists[index].likers_count = is_like ? count-1 : count+1;
|
||||
lists[index].is_like = !is_like;
|
||||
lists.splice();
|
||||
setData(lists);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function deleteFunc(id,index,subIndex){
|
||||
const url = `/comments/${id}.json`;
|
||||
Axios.delete(url).then(result=>{
|
||||
if(result && result.data && result.data.status === 0){
|
||||
var lists = data.concat();
|
||||
if(subIndex>=0){
|
||||
let chid = lists[index].children
|
||||
if(chid && chid.length>0){
|
||||
chid[subIndex].is_delete = true;
|
||||
lists[index].children_comments_count=lists[index].children_comments_count-1;
|
||||
if(!chid.find(i=>i.is_delete === undefined)){
|
||||
lists[index].children = undefined;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
lists[index].is_delete = true;
|
||||
setTotal(total-1);
|
||||
}
|
||||
lists.splice();
|
||||
setData(lists);
|
||||
// getAllComments(1,page*limit);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="replay">
|
||||
<h3>全部回复{total && total > 0 ? `(${total})`:""}</h3>
|
||||
<ReplayBox users={users} submit={submit} mainShowLogin={mainShowLogin}/>
|
||||
{
|
||||
total && total > 0 ?
|
||||
<List
|
||||
users={users}
|
||||
list={data}
|
||||
commentFunc={commentFunc}
|
||||
pariseFunc={pariseFunc}
|
||||
deleteFunc={deleteFunc}
|
||||
submit={submit}
|
||||
mainShowLogin={mainShowLogin}
|
||||
/>
|
||||
:""
|
||||
}
|
||||
{
|
||||
total > limit && (page<yu) &&
|
||||
<p className="edu-txt-center color-grey-8"><a onClick={()=>setPage(page+1)}>查看更多评论</a></p>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,64 @@
|
|||
.replay{
|
||||
padding:30px;
|
||||
background-color: #fff;
|
||||
margin-top: 20px;
|
||||
.replybox{
|
||||
margin-top: 15px;
|
||||
}
|
||||
.replayImg{
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #DDDDDD;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.replyContent{
|
||||
flex:1;
|
||||
}
|
||||
.replylistItem{
|
||||
margin-top: 30px;
|
||||
&>div{
|
||||
padding:38px 0px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
.replyInfo{
|
||||
flex: 1;
|
||||
.replyInfoMain{
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
margin-bottom: 8px;
|
||||
&>div{
|
||||
&>span{
|
||||
margin-right: 15px;
|
||||
color: #333;
|
||||
}
|
||||
&>a{
|
||||
margin-left: 15px;
|
||||
color:#BBBBBB;
|
||||
i{
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subReply{
|
||||
padding:5px 30px 20px;
|
||||
background-color: #fafafa;
|
||||
position: relative;
|
||||
margin-top: 20px;
|
||||
&::before{
|
||||
position: absolute;
|
||||
top:-10px;
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid #fafafa;
|
||||
left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
import React from 'react';
|
||||
import { AlignTop , FlexAJ , AlignCenter } from '../../forge/Component/layout';
|
||||
import { getUrlHead } from '../Data/getUrl';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import ReplayBox from './ReplyBox';
|
||||
import SubList from './SubList';
|
||||
import { Popconfirm } from 'antd';
|
||||
|
||||
|
||||
function List({list , deleteFunc , commentFunc , pariseFunc , users , submit , mainShowLogin}){
|
||||
return(
|
||||
<div className="replylistItem">
|
||||
{
|
||||
list && list.map((i,k)=>{
|
||||
return(
|
||||
!i.is_delete && <AlignTop>
|
||||
<img src={getUrlHead(i.commenter && i.commenter.image_url)} alt='' className="replayImg"/>
|
||||
<div className="replyInfo">
|
||||
<FlexAJ className="replyInfoMain">
|
||||
<AlignCenter>
|
||||
<span>{i.commenter && i.commenter.name}</span>
|
||||
<span style={{color:"#888"}}>{i.created_at}</span>
|
||||
</AlignCenter>
|
||||
|
||||
<AlignCenter>
|
||||
{ users && users.admin &&
|
||||
<Popconfirm title="是否确定删除此条评论?" okText="确定" cancelText="取消" onConfirm={()=>{deleteFunc(i.id,k)}}>
|
||||
<a><i className="iconfont icon-lajitong1 font-14"></i></a>
|
||||
</Popconfirm>
|
||||
}
|
||||
<a onClick={()=>{(users && users.login) ? commentFunc(i.flag,k) : mainShowLogin()}}>
|
||||
<i className="iconfont icon-huifu1 font-16"></i>
|
||||
{i.children_comments_count && i.children_comments_count > 0 && <span>{i.children_comments_count}</span>}
|
||||
</a>
|
||||
<a onClick={()=>{(users && users.login) ? pariseFunc(i.id,i.is_like,i.likers_count,k) : mainShowLogin()}}>
|
||||
<i className={i.is_like===true ? "iconfont icon-dianzan":"iconfont icon-dianzan-xian"}></i>
|
||||
{ i.likers_count && i.likers_count > 0 && <span>{i.likers_count}</span>}
|
||||
</a>
|
||||
</AlignCenter>
|
||||
</FlexAJ>
|
||||
<div>
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={i.content}/>
|
||||
{ i.children && i.children.length > 0 && <SubList children={i.children} users={users} deleteFunc={deleteFunc} prek={k}/> }
|
||||
{
|
||||
i.flag && <ReplayBox k={k} users={users} submit={submit} pareid={i.id} commentFunc={commentFunc}/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</AlignTop>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default List;
|
|
@ -0,0 +1,64 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { AlignTop } from '../../forge/Component/layout';
|
||||
import { getUrlHead } from '../Data/getUrl';
|
||||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import { Button, Input } from 'antd';
|
||||
|
||||
function ReplayBox({users,submit,pareid,k,commentFunc , mainShowLogin}){
|
||||
const [ value , setValue ] = useState("");
|
||||
const [ valueFlag , setValueFlag ] = useState(false);
|
||||
const [ inputFlag , setInputFlag ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if((users && !users.login) || !users){
|
||||
setValue("");
|
||||
setValueFlag(false);
|
||||
setInputFlag(false);
|
||||
}
|
||||
},[users])
|
||||
|
||||
useEffect(()=>{
|
||||
if(k!==undefined){
|
||||
setInputFlag(true);
|
||||
}
|
||||
},[k])
|
||||
|
||||
function submitPre(){
|
||||
if(value){
|
||||
setValueFlag(false);
|
||||
submit && submit(value,pareid);
|
||||
setValue("");
|
||||
}else{
|
||||
setValueFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<AlignTop className="replybox">
|
||||
{ users && users.image_url && <img src={getUrlHead(users.image_url)} alt='' className="replayImg"/>}
|
||||
{
|
||||
!inputFlag ?
|
||||
<div className="replyContent" onClick={()=>{users && users.login ?setInputFlag(true) : mainShowLogin()}}>
|
||||
<Input placeholder="添加评论" disabled style={{marginTop:"9px",cursor:"default"}}/>
|
||||
</div>
|
||||
:
|
||||
<div className="replyContent">
|
||||
<MDEditor
|
||||
placeholder={"请输入评论内容"}
|
||||
height={240}
|
||||
mdID={`replyContent_${users && users.login}_${k}`}
|
||||
initValue={value}
|
||||
onChange={(e)=>setValue(e)}
|
||||
></MDEditor>
|
||||
<div className="clearfix" style={{textAlign:"right"}}>
|
||||
{ valueFlag && <span className="color-red mr20">评论内容不能为空</span> }
|
||||
<Button type="default" className="mr20" onClick={()=>{commentFunc ? commentFunc(true,k) : setInputFlag(false)}}>取消</Button>
|
||||
<Button type="primary" onClick={submitPre}>提交</Button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</AlignTop>
|
||||
)
|
||||
}
|
||||
export default ReplayBox;
|
|
@ -0,0 +1,32 @@
|
|||
import React from 'react';
|
||||
import { FlexAJ } from '../../forge/Component/layout';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import { Popconfirm } from 'antd';
|
||||
|
||||
function SubList({ children , deleteFunc , users ,prek}){
|
||||
return(
|
||||
<div className="subReply">
|
||||
{
|
||||
children.map((i,k)=>{
|
||||
return(
|
||||
!i.is_delete &&<div className="mt10">
|
||||
<FlexAJ>
|
||||
<span>
|
||||
<span className="font-16 color-grey-3">{i.commenter && i.commenter.name}</span>
|
||||
<span className="ml10" style={{color:"#888"}}>{i.created_at}</span>
|
||||
</span>
|
||||
{ users && users.admin &&
|
||||
<Popconfirm title="是否确定删除此条评论?" okText="确定" cancelText="取消" onConfirm={()=>{deleteFunc(i.id,prek,k)}}>
|
||||
<a><i className="iconfont icon-lajitong1 font-14 color-grey-9"></i></a>
|
||||
</Popconfirm>
|
||||
}
|
||||
</FlexAJ>
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={i.content}/>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default SubList;
|
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 |
After Width: | Height: | Size: 24 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,44 @@
|
|||
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));
|
||||
}
|
||||
},[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;
|