forked from Gitlink/forgeplus-react
Compare commits
74 Commits
master
...
develop_ed
| Author | SHA1 | Date |
|---|---|---|
|
|
d4550d44e9 | |
|
|
0138eb2f1e | |
|
|
e1aef30b9d | |
|
|
277ba72f91 | |
|
|
6a58a468f9 | |
|
|
14486724fa | |
|
|
3201b7265b | |
|
|
f774ce974d | |
|
|
fdca717eeb | |
|
|
4b304ead34 | |
|
|
67d914ddb6 | |
|
|
e6020c3e13 | |
|
|
af2feeb34f | |
|
|
40918bf1d7 | |
|
|
8a5a7a0647 | |
|
|
93ba9c6a98 | |
|
|
12322f8785 | |
|
|
8c1bebcfdc | |
|
|
04bdbd7c30 | |
|
|
f57ee7fd99 | |
|
|
1e0f522f4a | |
|
|
798d919447 | |
|
|
1f6a4bda6c | |
|
|
0d546f4789 | |
|
|
44996b5dea | |
|
|
134d79faa3 | |
|
|
2677efec83 | |
|
|
7482d1184c | |
|
|
58fb71b324 | |
|
|
5517b28062 | |
|
|
0bd7f7d900 | |
|
|
9cfe2c186e | |
|
|
e4c54622b8 | |
|
|
21902543f4 | |
|
|
e541e91a06 | |
|
|
b6dc01b0be | |
|
|
f0858e7ecc | |
|
|
f9f79e0365 | |
|
|
8903363695 | |
|
|
b9a8becec3 | |
|
|
2fcd2fd066 | |
|
|
898ad15343 | |
|
|
1cf7655e63 | |
|
|
2383710c54 | |
|
|
3b3d6dc8b1 | |
|
|
c74c40b73e | |
|
|
c5bbcd9c1d | |
|
|
74deb640a9 | |
|
|
534da2115a | |
|
|
f2ef3183ea | |
|
|
1182a45cdc | |
|
|
29f37b9760 | |
|
|
f5fa45e1ce | |
|
|
97bf4a5a46 | |
|
|
5e4d3a92a1 | |
|
|
29f25a585d | |
|
|
6bd57d8877 | |
|
|
e7aa871b53 | |
|
|
9c22457249 | |
|
|
68b1296652 | |
|
|
0f7c8a4b5d | |
|
|
98289b05aa | |
|
|
83086e7d61 | |
|
|
76c88a659a | |
|
|
ae8ece2695 | |
|
|
93994cb785 | |
|
|
917958c880 | |
|
|
65b906f49f | |
|
|
90be5ad793 | |
|
|
eeaefc5810 | |
|
|
284bf67f82 | |
|
|
fbdde52651 | |
|
|
64dcdce51b | |
|
|
741a461f7e |
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "forge",
|
"name": "educoder",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
|
|
@ -3888,6 +3888,11 @@
|
||||||
"randomfill": "^1.0.3"
|
"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": {
|
"crypto-random-string": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
||||||
|
|
@ -20475,16 +20480,6 @@
|
||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"xterm": {
|
|
||||||
"version": "4.8.1",
|
|
||||||
"resolved": "https://registry.npm.taobao.org/xterm/download/xterm-4.8.1.tgz",
|
|
||||||
"integrity": "sha1-FVoXKaQ+Gom0BlJOIsVjQznjnKE="
|
|
||||||
},
|
|
||||||
"xterm-addon-fit": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npm.taobao.org/xterm-addon-fit/download/xterm-addon-fit-0.4.0.tgz",
|
|
||||||
"integrity": "sha1-BuDF0KaqrPsAnvVl76HIHpPZAZM="
|
|
||||||
},
|
|
||||||
"y18n": {
|
"y18n": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,7 @@
|
||||||
"webpack-dev-server": "^3.10.3",
|
"webpack-dev-server": "^3.10.3",
|
||||||
"webpack-manifest-plugin": "^2.2.0",
|
"webpack-manifest-plugin": "^2.2.0",
|
||||||
"whatwg-fetch": "2.0.3",
|
"whatwg-fetch": "2.0.3",
|
||||||
"wrap-md-editor": "^0.2.20",
|
"wrap-md-editor": "^0.2.20"
|
||||||
"xterm": "4.8.1",
|
|
||||||
"xterm-addon-fit": "0.4.0"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --max_old_space_size=15360 scripts/start.js",
|
"start": "node --max_old_space_size=15360 scripts/start.js",
|
||||||
|
|
|
||||||
|
|
@ -48,55 +48,6 @@
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
}
|
}
|
||||||
|
|
||||||
.head-nav ul#header-nav li a {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
color: #fff
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li a:hover {
|
|
||||||
color: #cccccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li:last-child {
|
|
||||||
margin-right: 0px
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active a {
|
|
||||||
color: #459be5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active p {
|
|
||||||
color: #459be5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li p:hover {
|
|
||||||
color: #cccccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li p {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
color: #fff
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active div ul li a {
|
|
||||||
color: #000 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active div ul li a:hover {
|
|
||||||
color: #FFF !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active ul li a {
|
|
||||||
color: #000 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active ul li a:hover {
|
|
||||||
color: #FFF !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-nav ul#header-nav li.active:after {
|
.head-nav ul#header-nav li.active:after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
@ -341,10 +292,6 @@ em.vertical-line {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*底部*/
|
|
||||||
.newFooter {
|
|
||||||
max-height: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newFooter {
|
.newFooter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,6 @@ html {
|
||||||
min-width: 1200px
|
min-width: 1200px
|
||||||
}
|
}
|
||||||
|
|
||||||
.newFooter {
|
|
||||||
max-height: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newFooter {
|
.newFooter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import axios from 'axios';
|
||||||
import { requestProxy } from "./indexEduplus2RequestProxy";
|
import { requestProxy } from "./indexEduplus2RequestProxy";
|
||||||
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
||||||
import { notification } from 'antd';
|
import { notification } from 'antd';
|
||||||
|
import cookie from 'react-cookies';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
let message501 = false;
|
let message501 = false;
|
||||||
|
|
@ -11,7 +11,9 @@ broadcastChannelOnmessage('refreshPage', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
function locationurl(list) {
|
function locationurl(list) {
|
||||||
if (window.location.port !== "3007") {
|
if (window.location.port === "3007") {
|
||||||
|
|
||||||
|
} else {
|
||||||
window.location.href = list
|
window.location.href = list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,19 +29,50 @@ if (isDev) {
|
||||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||||
}
|
}
|
||||||
|
function clearAllCookie() {
|
||||||
|
cookie.remove('_educoder_session', { path: '/' });
|
||||||
|
cookie.remove('autologin_trustie', { path: '/' });
|
||||||
|
setpostcookie()
|
||||||
|
}
|
||||||
|
clearAllCookie();
|
||||||
|
function setpostcookie() {
|
||||||
|
const str = window.location.pathname;
|
||||||
|
if (str.indexOf("/wxcode") !== -1) {
|
||||||
|
cookie.remove('_educoder_session', { path: '/' });
|
||||||
|
cookie.remove('autologin_trustie', { path: '/' });
|
||||||
|
const _params = window.location.search;
|
||||||
|
if (_params) {
|
||||||
|
let _search = _params.split('?')[1];
|
||||||
|
let _educoder_sessions = _search.split('&')[0].split('=');
|
||||||
|
cookie.save('_educoder_session', _educoder_sessions[1], { domain: '.educoder.net', path: '/' });
|
||||||
|
let autologin_trusties = _search.split('&')[1].split('=');
|
||||||
|
cookie.save('autologin_trustie', autologin_trusties[1], { domain: '.educoder.net', path: '/' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setpostcookie();
|
||||||
|
|
||||||
window._debugType = debugType;
|
window._debugType = debugType;
|
||||||
export function initAxiosInterceptors(props) {
|
export function initAxiosInterceptors(props) {
|
||||||
// 判断网络是否连接
|
|
||||||
initOnlineOfflineListener();
|
initOnlineOfflineListener();
|
||||||
|
var proxy = "http://localhost:3000";
|
||||||
|
proxy = "https://testforgeplus.educoder.net";
|
||||||
|
|
||||||
var proxy = "https://testforgeplus.trustie.net";
|
const requestMap = {};
|
||||||
|
window.setfalseInRequestMap = function (keyName) {
|
||||||
|
requestMap[keyName] = false;
|
||||||
|
}
|
||||||
//响应前的设置
|
//响应前的设置
|
||||||
axios.interceptors.request.use(
|
axios.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
if(config.url.indexOf("http") !== -1) {
|
setpostcookie()
|
||||||
|
clearAllCookie()
|
||||||
|
|
||||||
|
if (config.url.indexOf(proxy) !== -1) {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
requestProxy(config);
|
requestProxy(config)
|
||||||
|
|
||||||
let url = `/api${config.url}`;
|
let url = `/api${config.url}`;
|
||||||
|
|
||||||
if (`${config[0]}` !== `true`) {
|
if (`${config[0]}` !== `true`) {
|
||||||
|
|
@ -53,6 +86,12 @@ export function initAxiosInterceptors(props) {
|
||||||
} else {
|
} else {
|
||||||
config.url = url;
|
config.url = url;
|
||||||
}
|
}
|
||||||
|
setpostcookie();
|
||||||
|
}
|
||||||
|
if (config.url.indexOf('update_file') === -1) {
|
||||||
|
requestMap[config.url] = true;
|
||||||
|
|
||||||
|
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
|
@ -107,6 +146,8 @@ export function initAxiosInterceptors(props) {
|
||||||
message501 = false
|
message501 = false
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
requestMap[response.config.url] = false;
|
||||||
|
setpostcookie();
|
||||||
return response;
|
return response;
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
|
|
|
||||||
|
|
@ -162,28 +162,28 @@ export function getmyUrl(geturl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadActionUrl(path, goTest) {
|
export function getUploadActionUrl(path, goTest) {
|
||||||
return `${getUrl()}/api/attachments.json${isDev ?`${isDev ?`?debug=${window._debugType || 'admin'}` : ""}` : ""}`;
|
return `${getUrl()}/api/attachments.json`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadLogoActionUrl() {
|
export function getUploadLogoActionUrl() {
|
||||||
return `${getUrl()}/api/resumes/logo.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`;
|
return `${getUrl()}/api/resumes/logo.json?debug=${window._debugType || 'admin'}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadActionUrltwo(id) {
|
export function getUploadActionUrltwo(id) {
|
||||||
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadActionUrlthree() {
|
export function getUploadActionUrlthree() {
|
||||||
return `${getUrlmys()}/api/jupyters/import_with_tpm.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrlmys()}/api/jupyters/import_with_tpm.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getupload_git_file(id) {
|
export function getupload_git_file(id) {
|
||||||
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getUploadActionUrlOfAuth(id) {
|
export function getUploadActionUrlOfAuth(id) {
|
||||||
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRandomNumber(type) {
|
export function getRandomNumber(type) {
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ export default (({ projectsId , branch , owner , changeBranch , branchList , tag
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return(
|
return(
|
||||||
<Popover placement='bottomLeft' visible={flag} content={menu} onClick={()=>setFlag(!flag)} overlayClassName="branch-tagBox-list">
|
<Popover placement="bottom" visible={flag} content={menu} onClick={()=>setFlag(!flag)} overlayClassName="branch-tagBox-list">
|
||||||
<div className="branch-tagBox">
|
<div className="branch-tagBox">
|
||||||
{/* {nav === 0 ?"分支":"标签"} */}
|
{/* {nav === 0 ?"分支":"标签"} */}
|
||||||
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
||||||
|
|
|
||||||
|
|
@ -112,9 +112,6 @@ li.ant-menu-item{
|
||||||
right:240px;
|
right:240px;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
.laterest{
|
|
||||||
color: #05690d;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1800px){
|
@media screen and (max-width: 1800px){
|
||||||
.handleBox{
|
.handleBox{
|
||||||
|
|
|
||||||
|
|
@ -35,21 +35,26 @@ function EducoderAccount({form , visible , onOk , email}){
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<p className="mb15 edu-txt-center" style={{maxWidth:"350px",margin:"0px auto"}}>
|
<p className="mb15 edu-txt-center" style={{maxWidth:"350px",margin:"0px auto"}}>
|
||||||
为确保您能正常使用平台功能,请确认以下信息:
|
{
|
||||||
|
email ?
|
||||||
|
`平台已检测到您已绑定邮箱${email},请您确认如下操作`
|
||||||
|
:
|
||||||
|
"平台已检测到您未绑定邮箱,为不影响使用协同开发功能,请先绑定邮箱"
|
||||||
|
}
|
||||||
</p>
|
</p>
|
||||||
<Form {...layout}>
|
<Form {...layout}>
|
||||||
<Form.Item label="邮箱">
|
<Form.Item label="邮箱">
|
||||||
{getFieldDecorator("email",{
|
{getFieldDecorator("email",{
|
||||||
rules:[{required:true,message:"请输入邮箱账号"}]
|
rules:[{required:true,message:"请输入邮箱账号"}]
|
||||||
})(
|
})(
|
||||||
<Input placeholder="请输入您的邮箱账号" width="220px"/>
|
<Input placeholder="请输入您的邮箱账号" width="220px" disabled={email}/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="密码">
|
<Form.Item label="密码">
|
||||||
{getFieldDecorator("password",{
|
{getFieldDecorator("password",{
|
||||||
rules:[{required:true,message:"请输入邮箱密码"}]
|
rules:[{required:true,message:"请输入您的平台密码"}]
|
||||||
})(
|
})(
|
||||||
<Input.Password placeholder="请输入您的邮箱密码" width="220px"/>
|
<Input.Password placeholder="请输入您的平台密码" width="220px"/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,10 @@ function Releases({owner,projectsId,releaseVersions}){
|
||||||
releaseVersions && releaseVersions.total_count>0 ?
|
releaseVersions && releaseVersions.total_count>0 ?
|
||||||
releaseVersions.list.map((item,key)=>{
|
releaseVersions.list.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
key === 0 &&<AlignTop className="mt10">
|
<AlignTop className="mt10">
|
||||||
<i className="iconfont icon-biaoqian3 color-grey-6 font-18 mr10"></i>
|
<i className="iconfont icon-biaoqian3 color-grey-6 font-18 mr10"></i>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-16 color-grey-6">
|
<p className="font-16 color-grey-6"><Link to={`/projects/${owner}/${projectsId}/releases/8/update`}>{item.name}</Link></p>
|
||||||
<Link to={`/projects/${owner}/${projectsId}/releases/8/update`}>{item.name}</Link>
|
|
||||||
<span className="font-12 laterest ml5">最新</span>
|
|
||||||
</p>
|
|
||||||
<p className="color-grey-9 font-13">{item.created_at}</p>
|
<p className="color-grey-9 font-13">{item.created_at}</p>
|
||||||
</div>
|
</div>
|
||||||
</AlignTop>
|
</AlignTop>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
export default ({ url , name , column , id , login })=>{
|
|
||||||
|
export default ({ url , name , column })=>{
|
||||||
const Img = styled.span`
|
const Img = styled.span`
|
||||||
display:flex;
|
display:flex;
|
||||||
${column && "flex-direction: column;text-align:center;"}
|
${column && "flex-direction: column;text-align:center;"}
|
||||||
|
|
@ -19,14 +19,6 @@ export default ({ url , name , column , id , login })=>{
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return(
|
return(
|
||||||
id?
|
|
||||||
<Link to={`/users/${login}`}>
|
|
||||||
<Img>
|
|
||||||
{ url && <img src={url} alt=""/> }
|
|
||||||
<span>{name}</span>
|
|
||||||
</Img>
|
|
||||||
</Link>
|
|
||||||
:
|
|
||||||
<Img>
|
<Img>
|
||||||
{ url && <img src={url} alt=""/> }
|
{ url && <img src={url} alt=""/> }
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ function About(props, ref) {
|
||||||
const [ disabled, setDisabled ] = useState(false);
|
const [ disabled, setDisabled ] = useState(false);
|
||||||
const [ typeFlag, setTypeFlag] = useState(false);
|
const [ typeFlag, setTypeFlag] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const AuthorLogin = props.projectDetail && props.projectDetail.author && props.projectDetail.author.login;
|
const AuthorLogin = props.projectDetail && props.projectDetail.author && props.projectDetail.author.login;
|
||||||
const CurrentLogin = props.current_user && props.current_user.login;
|
const CurrentLogin = props.current_user && props.current_user.login;
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
|
|
@ -55,6 +56,11 @@ function About(props, ref) {
|
||||||
setIsSpining(false);
|
setIsSpining(false);
|
||||||
if(result && result.data ){
|
if(result && result.data ){
|
||||||
setStep(result.data.step);
|
setStep(result.data.step);
|
||||||
|
// setStep(0);
|
||||||
|
// setFieldsValue({...result.data.cloud_account});
|
||||||
|
// if(result.data.cloud_account){
|
||||||
|
// setDisabled(true);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}).catch(error=>{
|
}).catch(error=>{
|
||||||
setIsSpining(false);
|
setIsSpining(false);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Spin , Menu } from "antd";
|
import { Spin } from "antd";
|
||||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import CodeSSH from './ssh/Index';
|
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
data,
|
data,
|
||||||
|
|
@ -18,8 +17,6 @@ export default ({
|
||||||
const [spining, setSpining] = useState(true);
|
const [spining, setSpining] = useState(true);
|
||||||
const [stage, setStage] = useState(undefined);
|
const [stage, setStage] = useState(undefined);
|
||||||
const [step, setStep] = useState(undefined);
|
const [step, setStep] = useState(undefined);
|
||||||
const [nav, setNav] = useState("0");
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSpining(rightSpin);
|
setSpining(rightSpin);
|
||||||
}, [rightSpin]);
|
}, [rightSpin]);
|
||||||
|
|
@ -38,7 +35,6 @@ export default ({
|
||||||
: p[0];
|
: p[0];
|
||||||
|
|
||||||
setStep(sub);
|
setStep(sub);
|
||||||
setNav("0");
|
|
||||||
if (sub && sub.status !== "skipped") {
|
if (sub && sub.status !== "skipped") {
|
||||||
getStep(pre.number, sub.number);
|
getStep(pre.number, sub.number);
|
||||||
}
|
}
|
||||||
|
|
@ -69,13 +65,6 @@ export default ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
|
||||||
{/* <Menu className="devopsNav" onClick={(e)=>{setNav(e.key)}} selectedKeys={[nav]} mode="horizontal">
|
|
||||||
<Menu.Item key={'0'} value="0">开发流水线</Menu.Item>
|
|
||||||
<Menu.Item key={'1'} value="1">命令行</Menu.Item>
|
|
||||||
</Menu> */}
|
|
||||||
{
|
|
||||||
nav === "0" &&
|
|
||||||
<Spin spinning={spining}>
|
<Spin spinning={spining}>
|
||||||
<div className="rightMainContent">
|
<div className="rightMainContent">
|
||||||
{data && data.status !== "error" ? (
|
{data && data.status !== "error" ? (
|
||||||
|
|
@ -114,10 +103,5 @@ export default ({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
</Spin>
|
||||||
}
|
|
||||||
{
|
|
||||||
nav === "1" && <CodeSSH />
|
|
||||||
}
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ function ServiceModal({sureModal}){
|
||||||
<div className="mt30" style={{textAlign:"center"}}>
|
<div className="mt30" style={{textAlign:"center"}}>
|
||||||
<Radio.Group value={type} onChange={changeType}>
|
<Radio.Group value={type} onChange={changeType}>
|
||||||
<Radio value={1}>自有服务器</Radio>
|
<Radio value={1}>自有服务器</Radio>
|
||||||
<Radio value={2}>Trustie服务器</Radio>
|
<Radio value={2}>EduCoder服务器</Radio>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
<p className="mt30"><Button type="primary" onClick={()=>sureModal(type)}>下一步</Button></p>
|
<p className="mt30"><Button type="primary" onClick={()=>sureModal(type)}>下一步</Button></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -194,18 +194,6 @@
|
||||||
&.rightSection{
|
&.rightSection{
|
||||||
width:100%;
|
width:100%;
|
||||||
background-color: #081930;
|
background-color: #081930;
|
||||||
.devopsNav{
|
|
||||||
background-color: #111c24;
|
|
||||||
border-bottom: none;
|
|
||||||
.ant-menu-item{
|
|
||||||
color: #ccc;
|
|
||||||
padding:0px;
|
|
||||||
margin:0px 20px!important;
|
|
||||||
}
|
|
||||||
.ant-menu-item.ant-menu-item-selected{
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.rightMainContent{
|
.rightMainContent{
|
||||||
padding:24px 30px;
|
padding:24px 30px;
|
||||||
height:100vh;
|
height:100vh;
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import XmlPanel from "./XmlPanel";
|
|
||||||
import mediator from "./mediator";
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
// const defaulturl = `http://47.111.130.18:48088`;
|
|
||||||
const defaultValue = {
|
|
||||||
host: "106.75.231.63",
|
|
||||||
port: "2021",
|
|
||||||
ws_url: "wss://pre-webssh.educoder.net/ws",
|
|
||||||
username: "root",
|
|
||||||
secret: "Dron_123123",
|
|
||||||
};
|
|
||||||
function Index() {
|
|
||||||
const [sshConfigData, setSshConfigData] = useState(undefined);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!sshConfigData) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
mediator.publish("create-socket", 1);
|
|
||||||
}, 300);
|
|
||||||
}, [sshConfigData]);
|
|
||||||
|
|
||||||
// 获取服务器连接信息
|
|
||||||
function init() {
|
|
||||||
const url = `/api/ci/pipelines/ssh_server.json`;
|
|
||||||
axios.get(url).then(result=>{
|
|
||||||
if(result && result.data){
|
|
||||||
setSshConfigData({...result.data})
|
|
||||||
}
|
|
||||||
}).catch(error=>{})
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<XmlPanel
|
|
||||||
sshConfigData={sshConfigData||{}}
|
|
||||||
sid={1}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default Index;
|
|
||||||
|
|
@ -1,219 +0,0 @@
|
||||||
import React, { useRef, useEffect, useState } from 'react';
|
|
||||||
import { Base64 } from 'js-base64';
|
|
||||||
|
|
||||||
import { Terminal } from 'xterm';
|
|
||||||
import 'xterm/css/xterm.css';
|
|
||||||
import mediator from './mediator';
|
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
|
||||||
|
|
||||||
function getColsAndRows(width, height, term) {
|
|
||||||
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
|
|
||||||
let h = term._core._renderService.dimensions.actualCellHeight || 18;
|
|
||||||
const rows = Math.floor(height / h);
|
|
||||||
const cols = Math.floor(width / w);
|
|
||||||
return [cols, rows];
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLayout(term, el) {
|
|
||||||
const ro = new ResizeObserver(entries => {
|
|
||||||
console.log(entries);
|
|
||||||
for (let entry of entries) {
|
|
||||||
if (entry.target.offsetHeight > 0 || entry.target.offsetWidth > 0) {
|
|
||||||
const [cols, rows] = getColsAndRows(
|
|
||||||
entry.target.offsetWidth,
|
|
||||||
entry.target.offsetHeight,
|
|
||||||
term,
|
|
||||||
);
|
|
||||||
console.log('cols, rows', cols, rows);
|
|
||||||
term.resize(cols, rows);
|
|
||||||
mediator.publish('ssh-xterm-resize', {
|
|
||||||
columns: cols,
|
|
||||||
rows: rows,
|
|
||||||
width: entry.target.offsetWidth,
|
|
||||||
height: entry.target.offsetHeight,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ro.observe(el);
|
|
||||||
return ro;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TimeTicket = 30000;
|
|
||||||
|
|
||||||
//建立 websockt 来交互
|
|
||||||
//根据容器大小计算行数和列数并做到自适应
|
|
||||||
//socket 与 term 需要分开初始化 因为socket 可能重置连接
|
|
||||||
//mediator 监听消息,如果和id匹配,则建立连接,重置,或关闭连接
|
|
||||||
|
|
||||||
export default ({ sshConfigData, sid }) => {
|
|
||||||
const [term, setTerm] = useState(null);
|
|
||||||
|
|
||||||
const { ws_url, password, port, secret } = sshConfigData;
|
|
||||||
const el = useRef();
|
|
||||||
const socket = useRef();
|
|
||||||
const isFirstConnected = useRef(false);
|
|
||||||
|
|
||||||
//term init
|
|
||||||
useEffect(() => {
|
|
||||||
if (el.current && ws_url) {
|
|
||||||
const term = new Terminal({ fontSize: 16, rendererType: 'dom' });
|
|
||||||
term.open(el.current);
|
|
||||||
|
|
||||||
term.onData(data => {
|
|
||||||
if (socket.current) {
|
|
||||||
if (socket.current.readyState === 1) {
|
|
||||||
socket.current.send(JSON.stringify({ tp: 'client', data: data }));
|
|
||||||
mediator.publish('on-operating-ssh'); //有操作则自动延时
|
|
||||||
} else {
|
|
||||||
//断开连接后重连
|
|
||||||
// socket.current = null
|
|
||||||
// mediator.publish('create-socket', sid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
term.write('Connecting...');
|
|
||||||
setTerm(term);
|
|
||||||
const ro = onLayout(term, el.current);
|
|
||||||
return () => {
|
|
||||||
term.dispose();
|
|
||||||
ro.unobserve(el.current);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [ws_url, el.current]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (term && ws_url) {
|
|
||||||
function createSocket() {
|
|
||||||
const socketInstance = new WebSocket(ws_url);
|
|
||||||
socket.current = socketInstance;
|
|
||||||
|
|
||||||
socketInstance.onopen = () => {
|
|
||||||
let container = term.element.parentElement;
|
|
||||||
if (container) {
|
|
||||||
let width = container.offsetWidth;
|
|
||||||
let height = container.offsetHeight;
|
|
||||||
console.log('init', {
|
|
||||||
tp: 'init',
|
|
||||||
data: {
|
|
||||||
...sshConfigData,
|
|
||||||
secret: secret,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
rows: term.rows,
|
|
||||||
columns: term.cols,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
socketInstance.send(
|
|
||||||
JSON.stringify({
|
|
||||||
tp: 'init',
|
|
||||||
data: {
|
|
||||||
...sshConfigData,
|
|
||||||
secret: secret,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
rows: term.rows,
|
|
||||||
columns: term.cols,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
term.focus();
|
|
||||||
};
|
|
||||||
socketInstance.onerror = error => {
|
|
||||||
console.log(
|
|
||||||
'------in socket error----',
|
|
||||||
error,
|
|
||||||
socketInstance,
|
|
||||||
ws_url,
|
|
||||||
);
|
|
||||||
//连接报错后,重新请求资源
|
|
||||||
// mediator.publish('on-recreate-socket')
|
|
||||||
};
|
|
||||||
socketInstance.onmessage = event => {
|
|
||||||
if (!isFirstConnected.current) {
|
|
||||||
term.write('\r');
|
|
||||||
// term.focus()
|
|
||||||
setTimeout(() => {
|
|
||||||
// term.clear();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
isFirstConnected.current = true;
|
|
||||||
console.log('event:', event);
|
|
||||||
|
|
||||||
const data = Base64.decode(event.data.toString());
|
|
||||||
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
|
|
||||||
|
|
||||||
console.log('data:', data, w, term);
|
|
||||||
term.write(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
socketInstance.onclose = evt => {
|
|
||||||
if (tid) {
|
|
||||||
clearInterval(tid);
|
|
||||||
}
|
|
||||||
term.write('\r\nconnection closed');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const tid = setInterval(() => {
|
|
||||||
if (socket.current) {
|
|
||||||
socket.current.send(JSON.stringify({ tp: 'h' }));
|
|
||||||
}
|
|
||||||
}, TimeTicket);
|
|
||||||
|
|
||||||
const unSubCreate = mediator.subscribe('create-socket', id => {
|
|
||||||
if (sid === id) {
|
|
||||||
if (socket.current && socket.current.readyState === 1) {
|
|
||||||
term.focus();
|
|
||||||
} else {
|
|
||||||
createSocket();
|
|
||||||
}
|
|
||||||
term.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const unSubClose = mediator.subscribe('close-socket', id => {
|
|
||||||
if (sid === id) {
|
|
||||||
if (socket.current) {
|
|
||||||
socket.current.close();
|
|
||||||
isFirstConnected.current = false;
|
|
||||||
term.clear();
|
|
||||||
}
|
|
||||||
socket.current = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const unSubResize = mediator.subscribe('ssh-xterm-resize', option => {
|
|
||||||
if (socket.current && socket.current.readyState === 1) {
|
|
||||||
socket.current.send(
|
|
||||||
JSON.stringify({ tp: 'resize', data: { ...option } }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const unSubAddTime = mediator.subscribe('ssh-add-connect-time', () => {
|
|
||||||
if (socket.current && socket.current.readyState === 1) {
|
|
||||||
socket.current.send(JSON.stringify({ tp: 'overtime' }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
unSubClose();
|
|
||||||
unSubCreate();
|
|
||||||
unSubResize();
|
|
||||||
unSubAddTime();
|
|
||||||
if (socket.current) {
|
|
||||||
socket.current.close();
|
|
||||||
isFirstConnected.current = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [term, ws_url, port]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={el} className="xterm-panel" style={{height:"100%"}}>
|
|
||||||
{!ws_url ? <p style={{ color: '#fff' }}>正在连接命令行服务...</p> : null}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
function Mediator(obj) {
|
|
||||||
const channels = {};
|
|
||||||
|
|
||||||
const mediator = {
|
|
||||||
subscribe: function(channel, cb) {
|
|
||||||
if (!channels[channel]) {
|
|
||||||
channels[channel] = [];
|
|
||||||
}
|
|
||||||
channels[channel].push(cb);
|
|
||||||
return this.unsubscribe.bind(null, channel, cb);
|
|
||||||
},
|
|
||||||
|
|
||||||
unsubscribe: function(channel, cb) {
|
|
||||||
let rs = channels[channel];
|
|
||||||
let index = -1;
|
|
||||||
if (rs) {
|
|
||||||
for (let i = 0; i < rs.length; i++) {
|
|
||||||
if (rs[i].name === cb.name) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index >= 0) {
|
|
||||||
channels[channel].splice(index, 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
publish: function(channel) {
|
|
||||||
if (!channels[channel]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
channels[channel].forEach(subscription => {
|
|
||||||
subscription.apply(null, args);
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return obj ? Object.assign(obj, mediator) : mediator;
|
|
||||||
}
|
|
||||||
const mediator = new Mediator();
|
|
||||||
export default mediator;
|
|
||||||
|
|
@ -104,7 +104,7 @@ class NewHeader extends Component {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}else{
|
}else{
|
||||||
return <i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
|
return <i className="iconfont icon-sousuo font-18 color-white ml30" onClick={() => {
|
||||||
this.setState({openSearch:true})
|
this.setState({openSearch:true})
|
||||||
}} />
|
}} />
|
||||||
}
|
}
|
||||||
|
|
@ -600,14 +600,14 @@ class NewHeader extends Component {
|
||||||
<GotoQQgroup {...this.state} {...this.props} setgoshowqqgtounp={(bool) => this.setgoshowqqgtounp(bool)}></GotoQQgroup>
|
<GotoQQgroup {...this.state} {...this.props} setgoshowqqgtounp={(bool) => this.setgoshowqqgtounp(bool)}></GotoQQgroup>
|
||||||
:""
|
:""
|
||||||
}
|
}
|
||||||
<a href={settings && settings.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
|
|
||||||
{
|
{
|
||||||
settings && settings.nav_logo_url ?
|
settings && settings.nav_logo_url ?
|
||||||
|
<a href={settings && settings.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
|
||||||
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
|
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
|
||||||
:
|
|
||||||
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={logo}></img>
|
|
||||||
}
|
|
||||||
</a>
|
</a>
|
||||||
|
:
|
||||||
|
""
|
||||||
|
}
|
||||||
<div className="head-nav pr" id={"head-navpre1"}>
|
<div className="head-nav pr" id={"head-navpre1"}>
|
||||||
{
|
{
|
||||||
settings && settings.navbar && settings.navbar.length > 0 ?
|
settings && settings.navbar && settings.navbar.length > 0 ?
|
||||||
|
|
@ -650,7 +650,7 @@ class NewHeader extends Component {
|
||||||
{
|
{
|
||||||
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
||||||
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
||||||
<i className="iconfont icon-tianjiafangda color-grey-6 ml30"></i>
|
<i className="iconfont icon-tianjiafangda color-white ml30"></i>
|
||||||
</Dropdown>:""
|
</Dropdown>:""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -658,7 +658,7 @@ class NewHeader extends Component {
|
||||||
<div className="ml30 edu-menu-panel">
|
<div className="ml30 edu-menu-panel">
|
||||||
{user && user.login &&
|
{user && user.login &&
|
||||||
<a href={`${notice_url}`} style={{ position: 'relative' }}>
|
<a href={`${notice_url}`} style={{ position: 'relative' }}>
|
||||||
<i className="iconfont icon-xiaoxilingdang color-grey-6"></i>
|
<i className="iconfont icon-xiaoxilingdang color-white"></i>
|
||||||
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
|
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -694,10 +694,10 @@ class NewHeader extends Component {
|
||||||
</div>
|
</div>
|
||||||
{!user || (user && !user.login) ?
|
{!user || (user && !user.login) ?
|
||||||
<span className="font-15 ml30">
|
<span className="font-15 ml30">
|
||||||
<a onClick={() => this.educoderlogin()} className="mr5 color-grey-6">登录</a>
|
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
|
||||||
{
|
{
|
||||||
settings && settings.common && settings.common.register &&
|
settings && settings.common && settings.common.register &&
|
||||||
<span><em className="vertical-line"></em><a className="ml5 color-grey-6" href={`${settings.common.register}`} target="_blank">注册</a></span>
|
<span><em className="vertical-line"></em><a className="ml5 color-white" href={`${settings.common.register}`} target="_blank">注册</a></span>
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
:
|
:
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,7 @@ import DrawerPanel from '../Component/DrawerPanel';
|
||||||
import UpdateDescModal from './sub/UpdateDescModal';
|
import UpdateDescModal from './sub/UpdateDescModal';
|
||||||
import Nodata from '../Nodata';
|
import Nodata from '../Nodata';
|
||||||
|
|
||||||
/**
|
|
||||||
* projectDetail.type:0是托管项目,1是镜像项目,2是同步镜像项目(为2时不支持在线创建、在线上传、在线修改、在线删除、创建合并请求等功能)
|
|
||||||
*/
|
|
||||||
function CoderDepot(props){
|
function CoderDepot(props){
|
||||||
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
||||||
const [ treeValue , setTreeValue ] = useState(undefined);
|
const [ treeValue , setTreeValue ] = useState(undefined);
|
||||||
|
|
@ -95,7 +93,7 @@ function CoderDepot(props){
|
||||||
setZip_url(result.data.zip_url);
|
setZip_url(result.data.zip_url);
|
||||||
let c = result.data.last_commit
|
let c = result.data.last_commit
|
||||||
setLastCommit(c && c.commit);
|
setLastCommit(c && c.commit);
|
||||||
setLastCommitAuthor(c && c.committer);
|
setLastCommitAuthor(c && (c.author || (c.commit && c.commit.author)));
|
||||||
setMainFlag(true);
|
setMainFlag(true);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +135,7 @@ function CoderDepot(props){
|
||||||
}
|
}
|
||||||
let c = result.data.last_commit
|
let c = result.data.last_commit
|
||||||
setLastCommit(c && c.commit);
|
setLastCommit(c && c.commit);
|
||||||
setLastCommitAuthor(c && c.committer);
|
setLastCommitAuthor(c && (c.author || (c.commit && c.commit.author)));
|
||||||
setMainFlag(false);
|
setMainFlag(false);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +217,6 @@ function CoderDepot(props){
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
// 确认修改简介、website、实践课程链接
|
|
||||||
function okUpdate(d,w,l){
|
function okUpdate(d,w,l){
|
||||||
const url = `/${owner}/${projectsId}.json`;
|
const url = `/${owner}/${projectsId}.json`;
|
||||||
axios.put(url,{
|
axios.put(url,{
|
||||||
|
|
@ -298,18 +295,14 @@ function CoderDepot(props){
|
||||||
</AlignCenter>
|
</AlignCenter>
|
||||||
<AlignCenter>
|
<AlignCenter>
|
||||||
<div className="mr20 addOptionBtn">
|
<div className="mr20 addOptionBtn">
|
||||||
{
|
|
||||||
projectDetail.type !== 2 &&
|
|
||||||
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} >+ 合并请求</a>
|
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} >+ 合并请求</a>
|
||||||
}
|
|
||||||
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} >+ 任务</a>
|
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} >+ 任务</a>
|
||||||
</div>
|
</div>
|
||||||
{ type === "dir" && projectDetail.type !== 2 &&
|
{ type === "dir" &&
|
||||||
<Dropdown overlay={fileMenu} className="mr20">
|
<Dropdown overlay={fileMenu} className="mr20">
|
||||||
<Button type="default">文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-9"></i></Button>
|
<Button type="default">文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-9"></i></Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
}
|
}
|
||||||
|
|
||||||
<Dropdown overlay={downloadMenu} placement="bottomRight">
|
<Dropdown overlay={downloadMenu} placement="bottomRight">
|
||||||
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white"></i></Button>
|
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white"></i></Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
@ -321,7 +314,7 @@ function CoderDepot(props){
|
||||||
{
|
{
|
||||||
lastCommit &&
|
lastCommit &&
|
||||||
<div className="listtablehead">
|
<div className="listtablehead">
|
||||||
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} id={lastCommitAuthor && lastCommitAuthor.id} login={lastCommitAuthor && lastCommitAuthor.login}/>
|
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} />
|
||||||
<div className={hideBtn && hide ? "ellipsistxt hide" :"ellipsistxt"}><p id="ptxt">{lastCommit && lastCommit.message}</p></div>
|
<div className={hideBtn && hide ? "ellipsistxt hide" :"ellipsistxt"}><p id="ptxt">{lastCommit && lastCommit.message}</p></div>
|
||||||
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
||||||
|
|
||||||
|
|
@ -362,7 +355,6 @@ function CoderDepot(props){
|
||||||
md={mdFlag}
|
md={mdFlag}
|
||||||
onEdit={onEdit}
|
onEdit={onEdit}
|
||||||
currentBranch={branchName || (projectDetail && projectDetail.default_branch)}
|
currentBranch={branchName || (projectDetail && projectDetail.default_branch)}
|
||||||
type={projectDetail.type}
|
|
||||||
></CoderRootFileDetail>
|
></CoderRootFileDetail>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -373,7 +365,7 @@ function CoderDepot(props){
|
||||||
(dirInfo && dirInfo.length === 0) && (fileInfo && fileInfo.length === 0) ? <Nodata _html="暂未发现文件"/> :""
|
(dirInfo && dirInfo.length === 0) && (fileInfo && fileInfo.length === 0) ? <Nodata _html="暂未发现文件"/> :""
|
||||||
}
|
}
|
||||||
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
||||||
{ dirInfo && (projectDetail && projectDetail.readme) ? <ReadMe ChangeFile={ChangeFile} readme={projectDetail && projectDetail.readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
|
{ dirInfo && (projectDetail && projectDetail.readme) ? <ReadMe ChangeFile={ChangeFile} readme={projectDetail && projectDetail.readme} operate={props && (props.isManager || props.isDeveloper)} history={props.history} /> :"" }
|
||||||
</div>
|
</div>
|
||||||
</LongWidth>
|
</LongWidth>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class CoderRootFileDetail extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount = () => {
|
componentDidMount = () => {
|
||||||
const { detail , mdFlag } = this.props;
|
const { detail } = this.props;
|
||||||
this.setState({
|
this.setState({
|
||||||
value: detail.content,
|
value: detail.content,
|
||||||
});
|
});
|
||||||
|
|
@ -178,8 +178,7 @@ class CoderRootFileDetail extends Component {
|
||||||
isDeveloper,
|
isDeveloper,
|
||||||
currentBranch,
|
currentBranch,
|
||||||
platform,
|
platform,
|
||||||
md,
|
md
|
||||||
type
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { language, languages, description } = this.state;
|
const { language, languages, description } = this.state;
|
||||||
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
||||||
|
|
@ -198,18 +197,17 @@ class CoderRootFileDetail extends Component {
|
||||||
{readOnly ? (
|
{readOnly ? (
|
||||||
<span>
|
<span>
|
||||||
{
|
{
|
||||||
!detail.direct_download?
|
detail.direct_download ?
|
||||||
|
""
|
||||||
|
:
|
||||||
<span>
|
<span>
|
||||||
<a onClick={() => this.DownLoadFile(detail.download_url)} className="ml20">
|
<a onClick={() => this.DownLoadFile(detail.download_url)} className="ml20">
|
||||||
<i className="iconfont icon-xiazai1 font-15 color-grey-6"></i>
|
<i className="iconfont icon-xiazai1 font-15 color-grey-6"></i>
|
||||||
</a>
|
</a>
|
||||||
{
|
|
||||||
type !==2 &&
|
|
||||||
<a onClick={() => this.EditFile(false)} className="ml20">
|
<a onClick={() => this.EditFile(false)} className="ml20">
|
||||||
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
||||||
</a>
|
</a>
|
||||||
}
|
</span>
|
||||||
</span>:""
|
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -240,8 +238,7 @@ class CoderRootFileDetail extends Component {
|
||||||
</button>
|
</button>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
{
|
|
||||||
type !==2 &&
|
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title="确认删除这个文件?"
|
title="确认删除这个文件?"
|
||||||
className="ml20"
|
className="ml20"
|
||||||
|
|
@ -253,8 +250,6 @@ class CoderRootFileDetail extends Component {
|
||||||
<i className="iconfont icon-shanchu font-15 color-grey-6"></i>
|
<i className="iconfont icon-shanchu font-15 color-grey-6"></i>
|
||||||
</a>
|
</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -95,9 +95,6 @@
|
||||||
& > a:first-child{
|
& > a:first-child{
|
||||||
border-right: 1px solid #d9d9d9;
|
border-right: 1px solid #d9d9d9;
|
||||||
}
|
}
|
||||||
& > a:last-child{
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.infoCount{
|
.infoCount{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
||||||
</li>
|
</li>
|
||||||
:""
|
:""
|
||||||
}
|
}
|
||||||
{/* {
|
{
|
||||||
item.menu_name === "resources" &&
|
item.menu_name === "resources" &&
|
||||||
<li className={pathname==="source" ? "active" : ""}>
|
<li className={pathname==="source" ? "active" : ""}>
|
||||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/source`, state }}>
|
<Link to={{ pathname: `/projects/${owner}/${projectsId}/source`, state }}>
|
||||||
|
|
@ -84,7 +84,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
||||||
{projectDetail && projectDetail.source_count ? <span className="num">{projectDetail.source_count}</span> :""}
|
{projectDetail && projectDetail.source_count ? <span className="num">{projectDetail.source_count}</span> :""}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
} */}
|
}
|
||||||
{
|
{
|
||||||
item.menu_name === "versions" &&
|
item.menu_name === "versions" &&
|
||||||
<li className={pathname==="milestones" ? "active" : ""}>
|
<li className={pathname==="milestones" ? "active" : ""}>
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ class NewMerge extends Component {
|
||||||
let arr = projects_names && projects_names.filter(item=>item.id===value);
|
let arr = projects_names && projects_names.filter(item=>item.id===value);
|
||||||
let identifier = arr && arr[0].project_id;
|
let identifier = arr && arr[0].project_id;
|
||||||
let login = arr && arr[0].project_user_login;
|
let login = arr && arr[0].project_user_login;
|
||||||
let is_fork_id = parseInt(value) !== parseInt(id)
|
let is_fork_id = parseInt(value) !== parseInt(id);
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin: true,
|
isSpin: true,
|
||||||
merge_head: is_fork_id,
|
merge_head: is_fork_id,
|
||||||
|
|
|
||||||
|
|
@ -34,17 +34,19 @@ class MergeForm extends Component {
|
||||||
this.set_defatul();
|
this.set_defatul();
|
||||||
};
|
};
|
||||||
componentDidUpdate=(prevPros)=>{
|
componentDidUpdate=(prevPros)=>{
|
||||||
|
const { projectsId ,owner } = this.props.match.params;
|
||||||
|
const pId = prevPros.match.params.projectsId;
|
||||||
|
const oId = prevPros.match.params.owner;
|
||||||
|
if(pId !== projectsId || oId !== owner ){
|
||||||
|
// console.log("切换了项目分支···········");
|
||||||
|
this.get_default_selects();
|
||||||
|
}
|
||||||
if(prevPros && this.props && !this.props.checkIfLogin()){
|
if(prevPros && this.props && !this.props.checkIfLogin()){
|
||||||
this.props.history.push("/403")
|
this.props.history.push("/403")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check_is_login =() =>{
|
|
||||||
// if(!this.props.checkIfLogin()){
|
|
||||||
// this.props.history.push("/403")
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
get_default_selects = () => {
|
get_default_selects = () => {
|
||||||
const { projectsId ,owner } = this.props.match.params;
|
const { projectsId ,owner } = this.props.match.params;
|
||||||
this.setState({ isSpin: true });
|
this.setState({ isSpin: true });
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ class MilepostDetail extends Component {
|
||||||
</span>
|
</span>
|
||||||
<div className="milepostdiv">
|
<div className="milepostdiv">
|
||||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${meilid}/edit`} className="topWrapper_btn" style={{ marginRight: 15 }} >编辑里程碑</Link>
|
<Link to={`/projects/${owner}/${projectsId}/milestones/${meilid}/edit`} className="topWrapper_btn" style={{ marginRight: 15 }} >编辑里程碑</Link>
|
||||||
<Link to={`/projects/${owner}/${projectsId}/issues/${meilid}/new`} className="topWrapper_btn">创建任务</Link>
|
<Link to={`/projects/${owner}/${projectsId}/issues/${meilid}/new`} className="topWrapper_btn">创建易修</Link>
|
||||||
</div>
|
</div>
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -352,12 +352,12 @@ class order extends Component {
|
||||||
if (this.props.checkIfLogin()) {
|
if (this.props.checkIfLogin()) {
|
||||||
return(
|
return(
|
||||||
<Link className="topWrapper_btn ml10" target="_blank" to={`/projects/${owner}/${projectsId}/issues/new`}>
|
<Link className="topWrapper_btn ml10" target="_blank" to={`/projects/${owner}/${projectsId}/issues/new`}>
|
||||||
+ 创建任务
|
+ 创建易修
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}else{
|
}else{
|
||||||
return(
|
return(
|
||||||
<a className="topWrapper_btn ml10" onClick={this.islogin}>+ 创建任务</a>
|
<a className="topWrapper_btn ml10" onClick={this.islogin}>+ 创建易修</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,14 +310,14 @@ class order_form extends Component {
|
||||||
<div className="list-right">
|
<div className="list-right">
|
||||||
<div className="pd20">
|
<div className="pd20">
|
||||||
<h3 className="mb15">
|
<h3 className="mb15">
|
||||||
{form_type === "new" ? "新建" :( form_type === "copy" ? "复制" : "编辑")}任务
|
{form_type === "new" ? "新建" :( form_type === "copy" ? "复制" : "编辑")}易修
|
||||||
</h3>
|
</h3>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{getFieldDecorator("subject", {
|
{getFieldDecorator("subject", {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: "请填写任务标题",
|
message: "请填写易修标题",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
})(<Input placeholder="标题" size="large" />)}
|
})(<Input placeholder="标题" size="large" />)}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const menu = [
|
||||||
{name:"易修 (Issue)",index:"issues"},
|
{name:"易修 (Issue)",index:"issues"},
|
||||||
{name:"合并请求",index:"pulls"},
|
{name:"合并请求",index:"pulls"},
|
||||||
{name:"工作流(beta版)",index:"devops"},
|
{name:"工作流(beta版)",index:"devops"},
|
||||||
// {name:"资源库",index:"resources"},
|
{name:"资源库",index:"resources"},
|
||||||
{name:"里程碑",index:"versions"},
|
{name:"里程碑",index:"versions"},
|
||||||
{name:"动态",index:"activity"},
|
{name:"动态",index:"activity"},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -85,25 +85,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.versionTable{
|
|
||||||
.currentTip{
|
|
||||||
display: block;
|
|
||||||
padding:0px 3px;
|
|
||||||
border-radius: 2px;
|
|
||||||
border:1px solid #68c7ec;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #68c7ec;
|
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
.ant-table-body{
|
|
||||||
margin:0px!important;
|
|
||||||
thead{
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
thead >tr >th,tbody > tr > td{
|
|
||||||
padding:4px 5px!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,7 +10,6 @@ export default (({ data , current_user , successFunc }) => {
|
||||||
data.map((item, key) => {
|
data.map((item, key) => {
|
||||||
return (
|
return (
|
||||||
<Cards
|
<Cards
|
||||||
user={item.user}
|
|
||||||
img={item.user.image_url}
|
img={item.user.image_url}
|
||||||
name={item.user.name}
|
name={item.user.name}
|
||||||
time={item.created_at}
|
time={item.created_at}
|
||||||
|
|
|
||||||
|
|
@ -84,11 +84,12 @@ export default ((props) => {
|
||||||
|
|
||||||
// 移除成员
|
// 移除成员
|
||||||
function removeUser(username) {
|
function removeUser(username) {
|
||||||
const url = `/organizations/${OIdentifier}/teams/${groupId}/team_users/${username}.json`;
|
|
||||||
if (username) {
|
if (username) {
|
||||||
|
const url = `/organizations/${OIdentifier}/teams/${groupId}/team_users/quit.json`;
|
||||||
axios.delete(url).then((result) => {
|
axios.delete(url).then((result) => {
|
||||||
if (result && result.data) {
|
if (result && result.data) {
|
||||||
|
props.showNotification(`已成功退出团队!`);
|
||||||
|
props.history.push(`/organize/${OIdentifier}`);
|
||||||
}
|
}
|
||||||
}).catch((error) => { });
|
}).catch((error) => { });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,8 @@ export default Form.create()(
|
||||||
if(!value){
|
if(!value){
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
if(value && !value.match(/^[a-zA-Z][a-zA-Z0-9_-]{3,19}$/)){
|
if(value && !value.match(/^[a-zA-Z][a-zA-Z\d]{3,14}$/)){
|
||||||
callback("只能使用以字母开头,包含字母、数字、下划线、横杠等,长度4到20个字符");
|
callback("只能使用英文字母和数字,以字母开头,长度为4到15个字符");
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +119,7 @@ export default Form.create()(
|
||||||
validator:checkname
|
validator:checkname
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
<Input placeholder="请输入组织账号" disabled/>,true
|
<Input placeholder="请输入组织账号" />,true
|
||||||
)}
|
)}
|
||||||
{helper(
|
{helper(
|
||||||
"组织名称:",
|
"组织名称:",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ ul,ol,dl{
|
||||||
}
|
}
|
||||||
.newMain{
|
.newMain{
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
padding-bottom: 810px;
|
||||||
}
|
}
|
||||||
.color-black{
|
.color-black{
|
||||||
color: #333;
|
color: #333;
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
|
|
@ -17,6 +17,21 @@ const paramRequestOldUrlArray = [
|
||||||
|
|
||||||
]
|
]
|
||||||
const paramRequestNewUrlArray = [
|
const paramRequestNewUrlArray = [
|
||||||
|
// 获取代码内容
|
||||||
|
// (matchResult) => {
|
||||||
|
// const stageId = matchResult[1]
|
||||||
|
// return `/tasks/${stageId}/rep_content.json`
|
||||||
|
// },
|
||||||
|
|
||||||
|
// 获取版本库目录、文件
|
||||||
|
// http://testeduplus2.educoder.net/tasks/se79x25pzfwo/git_entries.json?path=&dev=master&gpid=3441
|
||||||
|
// (matchResult) => {
|
||||||
|
// const stageId = matchResult[1]
|
||||||
|
// // return `/tasks/${stageId}/git_entries.json`
|
||||||
|
// return `/myshixuns/${stageId}/repository.json`
|
||||||
|
// },
|
||||||
|
|
||||||
|
// `/tasks/tonblikwzj78/choose_build.json`
|
||||||
(matchResult) => {
|
(matchResult) => {
|
||||||
const stageId = matchResult[1]
|
const stageId = matchResult[1]
|
||||||
return `/tasks/${stageId}/choose_build.json`
|
return `/tasks/${stageId}/choose_build.json`
|
||||||
|
|
@ -51,3 +66,19 @@ export function requestProxy(config) {
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
('/api/v1/careers/qweqw/edit/').match(/\/api\/v1\/careers\/(\w*)\/edit/i)
|
||||||
|
0: "/api/v1/careers/qweqw/edit"
|
||||||
|
1: "qweqw"
|
||||||
|
|
||||||
|
example:
|
||||||
|
`/api/v1/games/${this.props.game.identifier}/answer_grade` ->
|
||||||
|
`/tasks/${this.props.game.identifier}/answer_grade.json`
|
||||||
|
|
||||||
|
|
||||||
|
https://testeduplus2.educoder.net/api/v1/games/feguz4tiqpvx/rep_content
|
||||||
|
?path=src/step2/CLnkQueue.cpp&shixun_gpid=2791&status=0&retry=0 ->
|
||||||
|
http://testeduplus2.educoder.net/tasks/tonblikwzj78/rep_content.json
|
||||||
|
?path=1-4.py&shixun_gpid=2448&status=0
|
||||||
|
*/
|
||||||
|
|
@ -2,13 +2,33 @@ import React, {Component} from "react";
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { getImageUrl } from 'educoder';
|
import { getImageUrl } from 'educoder';
|
||||||
import '../courses/css/members.css';
|
import '../courses/css/members.css';
|
||||||
import "../courses/common/formCommon.css";
|
import "../courses/common/formCommon.css"
|
||||||
import '../courses/css/Courses.css';
|
import '../courses/css/Courses.css';
|
||||||
import beijintulogontwo from '../../../src/images/login/beijintulogontwo.png';
|
import beijintulogontwo from '../../../src/images/login/beijintulogontwo.png';
|
||||||
import educodernet from '../../../src/images/login/educodernet.png';
|
import educodernet from '../../../src/images/login/logo.png';
|
||||||
import LoginRegisterComponent from '../user/LoginRegisterComponent';
|
import LoginRegisterComponent from '../user/LoginRegisterComponent';
|
||||||
import FindPasswordComponent from '../user/FindPasswordComponent';
|
import FindPasswordComponent from '../user/FindPasswordComponent';
|
||||||
|
import passopen from "../../images/login/passopen.png";
|
||||||
//educoder登入页面
|
//educoder登入页面
|
||||||
|
var sectionStyle = {
|
||||||
|
"height": "100%",
|
||||||
|
"width": "100%",
|
||||||
|
"min-width": "1000px",
|
||||||
|
// makesure here is String确保这里是一个字符串,以下是es6写法
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
var imgback = {
|
||||||
|
" background-size":"cover",
|
||||||
|
"background-repeat":"no-repeat",
|
||||||
|
backgroundImage: `url(${beijintulogontwo})`,
|
||||||
|
}
|
||||||
|
var imgmian ={
|
||||||
|
width: "100%",
|
||||||
|
background: `url(${beijintulogontwo})`,
|
||||||
|
position: "relative",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var newContainer={
|
var newContainer={
|
||||||
background: `url(${beijintulogontwo})`,
|
background: `url(${beijintulogontwo})`,
|
||||||
|
|
@ -69,6 +89,11 @@ class EducoderLogin extends Component {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
// console.log("EducoderLogin");
|
||||||
|
// console.log(this.props);
|
||||||
|
}
|
||||||
|
|
||||||
Setlogins=(i)=>{
|
Setlogins=(i)=>{
|
||||||
console.log("96ye");
|
console.log("96ye");
|
||||||
console.log(i)
|
console.log(i)
|
||||||
|
|
@ -94,29 +119,18 @@ class EducoderLogin extends Component {
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {showbool,loginstatus,logini} = this.state;
|
let { showbool } = this.state;
|
||||||
|
const { settings } = this.props;
|
||||||
return (
|
return (
|
||||||
<div style={newContainer} className=" clearfix" >
|
<div style={newContainer} className=" clearfix" >
|
||||||
|
<div style={{"justify-content": "center","align-items": "center","width": "100%",textAlign:"center"}}>
|
||||||
<div >
|
|
||||||
<div style={{
|
|
||||||
"display": "flex",
|
|
||||||
"justify-content": "center",
|
|
||||||
"align-items": "center",
|
|
||||||
"width": "100%"
|
|
||||||
}}>
|
|
||||||
<div style={{cursor:"pointer"}}>
|
<div style={{cursor:"pointer"}}>
|
||||||
{this.props.mygetHelmetapi === null ? ""
|
{
|
||||||
|
settings && settings.login_logo_url ?
|
||||||
|
<img style={{cursor:"pointer"}} alt="" onClick={()=>this.gohome()} width="80px" src={getImageUrl(settings.login_logo_url)}/>
|
||||||
:
|
:
|
||||||
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.login_logo_url===null|| this.props.mygetHelmetapi.login_logo_url===undefined?
|
<img style={{cursor:"pointer"}} alt="" onClick={()=>this.gohome()} src={educodernet} width="80px"/>
|
||||||
<img style={{cursor:"pointer"}} onClick={()=>this.gohome()} src={educodernet}/>
|
|
||||||
:
|
|
||||||
<img style={{cursor:"pointer"}} onClick={()=>this.gohome()} src={getImageUrl(this.props.mygetHelmetapi.login_logo_url)}/>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
showbool === 1 ?
|
showbool === 1 ?
|
||||||
|
|
@ -127,51 +141,17 @@ class EducoderLogin extends Component {
|
||||||
marginTop: "25px",
|
marginTop: "25px",
|
||||||
}}>
|
}}>
|
||||||
<div>
|
<div>
|
||||||
|
<LoginRegisterComponent {...this.props} {...this.state} Setshowbool={(e)=>this.Setshowbool(e)} ></LoginRegisterComponent>
|
||||||
<LoginRegisterComponent {...this.props} {...this.state}
|
|
||||||
Setshowbool={(e)=>this.Setshowbool(e)} ></LoginRegisterComponent>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div style={{
|
<div style={{display: "flex",justifyContent: "center",width: "100%",marginTop: "25px",}}>
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
marginTop: "25px",
|
|
||||||
}}>
|
|
||||||
<div>
|
<div>
|
||||||
<FindPasswordComponent {...this.props} {...this.state}
|
<FindPasswordComponent {...this.props} {...this.state} Setshowbool={(e)=>this.Setshowbool(e)}></FindPasswordComponent>
|
||||||
Setshowbool={(e)=>this.Setshowbool(e)}></FindPasswordComponent>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{this.props.mygetHelmetapi === null ? <div style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
}}>
|
|
||||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||||
</div>:
|
|
||||||
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.main_site===null|| this.props.mygetHelmetapi.main_site===undefined? <div style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
}}>
|
|
||||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
|
||||||
</div>:this.props.mygetHelmetapi.main_site===true?
|
|
||||||
<div style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
}}>
|
|
||||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
|
||||||
</div>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import Dialog from 'material-ui/Dialog';
|
||||||
import { notification } from 'antd';
|
import { notification } from 'antd';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import educoderLogo from './educoder.png';
|
|
||||||
|
|
||||||
import './LoginDialog.css';
|
import './LoginDialog.css';
|
||||||
import { broadcastChannelPostMessage } from 'educoder'
|
import { broadcastChannelPostMessage } from 'educoder'
|
||||||
|
|
@ -302,9 +301,12 @@ class LoginDialog extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isRender: nextProps.isRender
|
isRender: nextProps.isRender
|
||||||
})
|
})
|
||||||
|
// console.log(nextProps.isRender);
|
||||||
|
|
||||||
}
|
}
|
||||||
IsPC = () => {
|
IsPC = () => {
|
||||||
var userAgentInfo = navigator.userAgent;
|
var userAgentInfo = navigator.userAgent;
|
||||||
|
|
@ -321,8 +323,8 @@ class LoginDialog extends Component {
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
//true为PC端,false为手机端
|
|
||||||
let flag = this.IsPC();
|
let flag = this.IsPC(); //true为PC端,false为手机端
|
||||||
this.setState({
|
this.setState({
|
||||||
isphone: flag
|
isphone: flag
|
||||||
})
|
})
|
||||||
|
|
@ -354,6 +356,7 @@ class LoginDialog extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
loginEDU = () => {
|
loginEDU = () => {
|
||||||
|
|
||||||
let { loginValue, passValue, regular, isGoingValue } = this.state;
|
let { loginValue, passValue, regular, isGoingValue } = this.state;
|
||||||
if (regular === 1) {
|
if (regular === 1) {
|
||||||
return
|
return
|
||||||
|
|
@ -375,8 +378,15 @@ class LoginDialog extends Component {
|
||||||
if (response.data.message === "登录密码出错已达上限,账号已被锁定, 请10分钟后重新登录或找回密码") {
|
if (response.data.message === "登录密码出错已达上限,账号已被锁定, 请10分钟后重新登录或找回密码") {
|
||||||
const messge = (
|
const messge = (
|
||||||
<div>
|
<div>
|
||||||
<p>登录密码出错已达上限,账号已被锁定;</p>
|
<p>
|
||||||
<p className="mt10">请10分钟后重新登录或<a href={'https://www.trustie.net/account/lost_password'} style={{textDecoration: "underline",color: "#4CACFF"}}>找回密码</a></p>
|
登录密码出错已达上限,账号已被锁定;
|
||||||
|
</p>
|
||||||
|
<p className="mt10">
|
||||||
|
请10分钟后重新登录或<a href={'https://www.trustie.net/account/lost_password'} style={{
|
||||||
|
textDecoration: "underline",
|
||||||
|
color: "#4CACFF",
|
||||||
|
}}>找回密码</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
this.openNotifications(messge);
|
this.openNotifications(messge);
|
||||||
|
|
@ -420,6 +430,11 @@ class LoginDialog extends Component {
|
||||||
getloginurl = (url) => {
|
getloginurl = (url) => {
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
};
|
};
|
||||||
|
openweixinlogin = () => {
|
||||||
|
this.setState({
|
||||||
|
weixinlogin: true
|
||||||
|
})
|
||||||
|
}
|
||||||
openNotifications = (btn) => {
|
openNotifications = (btn) => {
|
||||||
// type 1 成功提示绿色 2提醒颜色黄色 3错误提示红色
|
// type 1 成功提示绿色 2提醒颜色黄色 3错误提示红色
|
||||||
notification.open({
|
notification.open({
|
||||||
|
|
@ -455,16 +470,18 @@ class LoginDialog extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { login, isGoing, isGoingValue, disabled , Phonenumberisnotco , dialogBox, isRender, weixinlogin } = this.state;
|
let { login, isGoing, isGoingValue, disabled, Phonenumberisnotco,
|
||||||
let { settings } = this.props;
|
dialogBox, isRender, weixinlogin } = this.state;
|
||||||
|
|
||||||
|
let { settings } = this.props;
|
||||||
if (isRender === undefined) {
|
if (isRender === undefined) {
|
||||||
isRender = false
|
isRender = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={true} id="DialogID"
|
<Dialog open={true} id="DialogID"
|
||||||
className="zindextest"
|
className="zindextest"
|
||||||
style={{ display: isRender === false ? 'none' : '' }}
|
style={{ display: isRender == false ? 'none' : '' }}
|
||||||
disableEscapeKeyDown={true}
|
disableEscapeKeyDown={true}
|
||||||
disableBackdropClick={true}
|
disableBackdropClick={true}
|
||||||
onClose={() => this.handleDialogClose()}
|
onClose={() => this.handleDialogClose()}
|
||||||
|
|
@ -495,7 +512,7 @@ class LoginDialog extends Component {
|
||||||
<li onClick={() => { this.enter(0) }}>登录</li>
|
<li onClick={() => { this.enter(0) }}>登录</li>
|
||||||
</ul>}
|
</ul>}
|
||||||
<div className="login-panel" id="login-panel-1" style={{ display: login == 0 ? 'block' : 'none' }}>
|
<div className="login-panel" id="login-panel-1" style={{ display: login == 0 ? 'block' : 'none' }}>
|
||||||
<form acceptCharset="UTF-8" action="/login" id="main_login_form" method="post">
|
{weixinlogin === true ? "" : <form acceptCharset="UTF-8" action="/login" id="main_login_form" method="post">
|
||||||
|
|
||||||
<div style={{ "display": "inline", "padding": "0", "margin": "0" }}>
|
<div style={{ "display": "inline", "padding": "0", "margin": "0" }}>
|
||||||
<input name="utf8" type="hidden" value="✓"></input>
|
<input name="utf8" type="hidden" value="✓"></input>
|
||||||
|
|
@ -520,10 +537,9 @@ class LoginDialog extends Component {
|
||||||
|
|
||||||
<div style={{ height: '25px' }}><p className="color-orange edu-txt-left none" id="username_error_notice"
|
<div style={{ height: '25px' }}><p className="color-orange edu-txt-left none" id="username_error_notice"
|
||||||
style={{ display: Phonenumberisnotco === undefined ? 'none' : 'block' }}>{Phonenumberisnotco}</p></div>
|
style={{ display: Phonenumberisnotco === undefined ? 'none' : 'block' }}>{Phonenumberisnotco}</p></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input type="password" id="password_loggin_input"
|
||||||
type="password"
|
|
||||||
id="password_loggin_input"
|
|
||||||
name="password"
|
name="password"
|
||||||
ref="passwordText"
|
ref="passwordText"
|
||||||
onInput={this.passwordChange}
|
onInput={this.passwordChange}
|
||||||
|
|
@ -533,8 +549,8 @@ class LoginDialog extends Component {
|
||||||
this.loginEDU : () => {
|
this.loginEDU : () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
placeholder="密码"
|
placeholder="密码" >
|
||||||
/>
|
</input>
|
||||||
<div style={{ height: '25px' }}>
|
<div style={{ height: '25px' }}>
|
||||||
<p className="color-orange edu-txt-left none" id="password_error_notice">
|
<p className="color-orange edu-txt-left none" id="password_error_notice">
|
||||||
请输入密码
|
请输入密码
|
||||||
|
|
@ -565,25 +581,38 @@ class LoginDialog extends Component {
|
||||||
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册</a>
|
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册</a>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{
|
|
||||||
settings && settings.third_party && settings.third_party.length > 0 ?
|
{this.props.user && this.props.user.main_site === true ? this.state.isphone === true ? <p className="clearfix mt20">
|
||||||
<p className="clearfix mt20">
|
|
||||||
<span className={"startlogin"}>———————— 快速登录 ————————</span>
|
<span className={"startlogin"}>———————— 快速登录 ————————</span>
|
||||||
<div className={"mt10"}>
|
<div className={"mt10"}>
|
||||||
{settings.third_party.map((item,key)=>{
|
<a onClick={() => this.openweixinlogin()}>
|
||||||
return(
|
<img src={require('./WeChat.png')} alt="微信登录" />
|
||||||
<a href={`${item.url}`}>
|
</a>
|
||||||
<img src={item.name === "educoder" ? educoderLogo : ""} width="46px" alt={`${item.name}登录`} />
|
<a onClick={() => this.openqqlogin()} className={"ml10"}>
|
||||||
|
<img src={require('./qq.png')} alt="qq登录" />
|
||||||
</a>
|
</a>
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p> : <p className="clearfix mt20">
|
||||||
:""
|
|
||||||
}
|
<span className={"startlogin"}>———————— 快速登录 ————————</span>
|
||||||
</form>
|
<div className={"mt10"}>
|
||||||
|
<a onClick={() => this.openphoneqqlogin()} className={"ml10"}>
|
||||||
|
<img src={require('./qq.png')} alt="qq登录" />
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</p> : ""}
|
||||||
|
</form>}
|
||||||
|
{weixinlogin === true ? <iframe
|
||||||
|
className={"weixinheight390"}
|
||||||
|
frameBorder="0"
|
||||||
|
sandbox="allow-scripts allow-same-origin allow-top-navigation"
|
||||||
|
scrolling="no"
|
||||||
|
src={`https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&response_type=code&scope=snsapi_login&state=null,${window.location.host}#wechat_redirect`}></iframe> : ""}
|
||||||
|
{weixinlogin === true ? <p className="clearfix ">
|
||||||
|
<a className={"startlogin color-blue"} onClick={() => this.hideweixinlogin()}>返回账号登录</a>
|
||||||
|
</p> : ""}
|
||||||
|
</div>
|
||||||
|
{/*快捷登录*/}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
: ""}
|
: ""}
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
|
|
@ -1068,11 +1068,6 @@ class NewMyShixunModel extends Component {
|
||||||
<style>
|
<style>
|
||||||
{
|
{
|
||||||
`
|
`
|
||||||
.newHeaders{
|
|
||||||
position: fixed;
|
|
||||||
top: 0px;
|
|
||||||
z-index: 999 !important;
|
|
||||||
}
|
|
||||||
.ant-drawer {
|
.ant-drawer {
|
||||||
z-index: 800 !important;
|
z-index: 800 !important;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1062,7 +1062,7 @@ class TPMBanner extends Component {
|
||||||
</div> :
|
</div> :
|
||||||
<div className="task-popup-content">
|
<div className="task-popup-content">
|
||||||
<p className="task-popup-text-center font-16 mt10 mb10">
|
<p className="task-popup-text-center font-16 mt10 mb10">
|
||||||
尚未创建任务的实训,不能申请发布
|
尚未创建易修的实训,不能申请发布
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,21 @@ body>.-task-title {
|
||||||
height:70px;
|
height:70px;
|
||||||
min-width: 1200px;
|
min-width: 1200px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
background:rgba(255,255,255,1);
|
background:#001529;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
box-shadow: 0px 0px 14px rgb(0 0 0 / 10%);
|
box-shadow: 0px 0px 14px rgb(0 0 0 / 10%);
|
||||||
}
|
}
|
||||||
|
.search-input {
|
||||||
|
width: 300px;
|
||||||
|
background: #373e3f !important;
|
||||||
|
border: 1px solid #373e3f !important;
|
||||||
|
}
|
||||||
|
.search-input .ant-input {
|
||||||
|
background: #373e3f !important;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
.headerContent{
|
.headerContent{
|
||||||
width:1200px;
|
padding:0px 25px;
|
||||||
margin:0px auto;
|
margin:0px auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -412,3 +421,136 @@ body>.-task-title {
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
.newFooter > div{
|
||||||
|
padding: 90px 20px;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
-ms-flex-align: start;
|
||||||
|
align-items: flex-start;
|
||||||
|
background: #242424;
|
||||||
|
min-width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newFooter .module-list{
|
||||||
|
width: 200px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.newFooter .module-list>.title{
|
||||||
|
font-size: 16px;
|
||||||
|
color: #ddd;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: 400;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
.newFooter .module-list a {
|
||||||
|
display: block;
|
||||||
|
color: #bbb;
|
||||||
|
line-height: 34px;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.newFooter .module-list a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.newFooter .module-introduce{
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 290px;
|
||||||
|
margin-top: -12px;
|
||||||
|
}
|
||||||
|
.newFooter .module-introduce p {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #bbb;
|
||||||
|
line-height: 32px;
|
||||||
|
margin-top: 12px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
.module-introduce ul {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-pack: distribute;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.module-introduce ul {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-pack: distribute;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.module-introduce ul li:first-child {
|
||||||
|
margin-right: 50px;
|
||||||
|
}
|
||||||
|
.module-introduce ul li {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.module-introduce ul li>span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #bbb;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
.module-introduce ol {
|
||||||
|
margin-top: 16px;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-pack: distribute;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 0;
|
||||||
|
height: 108px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.module-introduce ol li {
|
||||||
|
height: 100%;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
justify-content: space-between;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.module-introduce ol li a {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #bbb;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.module-introduce section {
|
||||||
|
width: 100%;
|
||||||
|
height: 115px;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
justify-content: space-between;
|
||||||
|
-ms-flex-align: start;
|
||||||
|
align-items: flex-start;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #bbb;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
.module-introduce .footer-line {
|
||||||
|
width: 310px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #3e4042;
|
||||||
|
margin: 32px 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue