Merge pull request '2023-7-21周上线代码合并' (#567) from gitlink_server into pre_gitlink_server

This commit is contained in:
durian 2023-07-21 17:34:57 +08:00
commit f05b203252
40 changed files with 21726 additions and 189 deletions

20871
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
"fs-extra": "3.0.1",
"immutability-helper": "^2.6.6",
"install": "^0.12.2",
"intersection-observer": "^0.12.2",
"jest": "20.0.4",
"js-base64": "^2.5.2",
"js2wordcloud": "^1.1.12",
@ -92,12 +93,14 @@
"redux-thunk": "2.3.0",
"rsuite": "^4.3.4",
"scroll-into-view": "^1.14.2",
"scrollama": "^3.2.0",
"sha1": "^1.1.1",
"showdown": "^1.9.1",
"showdown-katex": "^0.8.0",
"slick-carousel": "^1.8.1",
"store": "^2.0.12",
"styled-components": "^4.4.1",
"weixin-js-sdk": "^1.6.0",
"whatwg-fetch": "2.0.3",
"wrap-md-editor": "^0.2.20",
"xss": "^1.0.14",

View File

@ -7854,12 +7854,6 @@ a.singlepublishtwo {
.markdown-body {
text-align: justify;
word-break: break-all;
}
.RightPaneDrawer .ant-drawer-content {
background: #070f1a;
overflow: hidden !important;

View File

@ -4200,10 +4200,6 @@ html>body #ajax-indicator {
color: #898989 !important;
}
.markdown-body {
text-align: justify;
word-break: break-all;
}
.RightPaneDrawer .ant-drawer-content {
background: #070f1a;

View File

@ -6635,13 +6635,6 @@ ul.count_ul li:not(:last-child):after {
}
.markdown-body {
text-align: justify;
word-break: break-all;
}
.RightPaneDrawer .ant-drawer-content {
background: #070f1a;
overflow: hidden !important;

View File

@ -55,7 +55,7 @@
<script src="%PUBLIC_URL%js/codemirror/merge/merge.js"></script>
<script src="%PUBLIC_URL%js/alex/moment.js"></script>
<script src="https://gw.alipayobjects.com/os/lib/alipay/alex/2.0.19/bundle/alex.all.global.min.js"></script>
<!-- <meta name="viewport" content="width=device-width, user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"> -->
<meta name="viewport" content="">
<%= htmlWebpackPlugin.tags.bodyTags %>
<script>
var _hmt = _hmt || [];
@ -73,11 +73,7 @@
window.location.hash = $(this).attr("name");
return false;
});
}
// window.addEventListener("popstate", function(e) {
// console.log("popstate",e);
// history.go(-2);
// }, false);
}
</script>
</body>

View File

@ -19,6 +19,21 @@ export function getImageUrl(path) {
return `${path}`;
}
export function IsPC(){
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
var flag = false;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = true;
break;
}
}
return flag;
}
export function getImageUrlAbsolute(path) {
// https://www.educoder.net
// https://testbdweb.trustie.net

View File

@ -7,7 +7,7 @@ export {
getImageUrl as getImageUrl,getImageUrlAbsolute as getImageUrlAbsolute,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, getZoneUrl as getZoneUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl,
turnbar,returnbar,setSeoMeta as setSeoMeta
turnbar,returnbar,setSeoMeta as setSeoMeta , IsPC as IsPC
} from './UrlTool';
export { setmiyah as setmiyah } from './Component';

View File

@ -120,6 +120,7 @@ export function configShareForCourses () {
// detail
export function configShareForCustom (title, desc, imgUrl, path) {
console.log('--------------------', title,desc)
requestForSignatrue(() => {
console.log('configShareForCustom', host)
const _url = window.location.href.split('#')[0];

View File

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

View File

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

View File

@ -19,6 +19,7 @@ function PublicBanner(props){
const project = /[A-Za-z0-9]{0,}\/projects/g;
const source = /[A-Za-z0-9]{0,}\/source/g;
const vip = /[A-Za-z0-9]{0,}\/VIP/g;
const help = /[A-Za-z0-9]{0,}\/help/g;
if(pathname === `/zone/${deptId}`){
setKey("1");
}
@ -34,6 +35,9 @@ function PublicBanner(props){
else if(vip.test(pathname)){
setKey("6");
}
else if(help.test(pathname)){
setKey("8");
}
}
},[pathname])
@ -55,6 +59,7 @@ function PublicBanner(props){
<Menu.Item key={"4"}><Link to={`/zone/${deptId}/news`}><img src={require(`../img/${temp}Menu4.png`)} alt="" width="32px"/>{ tempConfig[temp].mainTitle }</Link></Menu.Item>
{/* <Menu.Item key={"5"}><img src={Menu5} alt="" width="27px"/>Sig小组</Menu.Item> */}
<Menu.Item key={"6"}><Link to={`/zone/${deptId}/VIP`}><img src={require(`../img/${temp}Menu6.png`)} alt="" width="36px"/>{ tempConfig[temp].member }</Link></Menu.Item>
{data && data.helperShow === 1 && <Menu.Item key={"8"}><Link to={`/zone/${deptId}/help`}><img src={require(`../img/${temp}Menu8.png`)} alt="" width="36px"/>{data.helperTitle}</Link></Menu.Item>}
{ adminUrl && <Menu.Item key={"7"}><a onClick={()=>{window.location.href=adminUrl}}><img src={require(`../img/${temp}Menu7.png`)} alt="" width="34px"/>后台管理</a></Menu.Item> }
</Menu>
</div>

View File

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

View File

@ -3,9 +3,12 @@ import { Breadcrumb , Divider, Spin } from 'antd';
import liulan from '../img/liulan.png';
import RenderHtml from '../../../components/render-html';
import { Base64 } from 'js-base64';
import axios from 'axios';
import { getNewsDetail } from '../api';
import { IsPC } from 'educoder';
import { tempConfig } from '../tempInfo';
import Acce from '../Component/mobile/accessory';
function NewsDetail(props){
const { deptId , id } = props.match.params;
@ -13,11 +16,23 @@ function NewsDetail(props){
const [ cmsDir , setCmsDir ] = useState(undefined);
const [ content , setContent]=useState(undefined);
const [ isSpin , setIsSpin]=useState(false);
const temp = props.temp
const temp = props.temp;
const zonedetail = props.data;
useEffect(()=>{
if(IsPC() && zonedetail){
setTimeout(()=>{
window.scrollTo(0,1);
if(detail)
document.title = detail.name;
},100);
document.querySelector('meta[name="viewport"]').setAttribute('content','width=device-width, user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0');
}
},[zonedetail,detail])
useEffect(()=>{
if(id){
window.scrollTo(0,450);
window.scrollTo(0,IsPC() ? 0 : 450);
getDetails();
}
},[id])
@ -33,41 +48,60 @@ function NewsDetail(props){
setIsSpin(false)
}
}).catch(error=>{
props.history.push(`/zone/${deptId}/news`);
setIsSpin(false)
})
}
return(
<div className="detail_news_all">
<Spin spinning={isSpin} size="large">
{
detail &&
<div style={{width:'1200px',margin:"0px auto",padding:"30px 0px"}}>
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{tempConfig[temp].mainTitle}</Breadcrumb.Item>
{ cmsDir && <Breadcrumb.Item href={`/zone/${deptId}/news/${cmsDir.id}`}>{cmsDir.name}</Breadcrumb.Item> }
<Breadcrumb.Item>正文</Breadcrumb.Item>
</Breadcrumb>
<div className="info_text">
<div className="info_text_main">
<p className="i_name">{detail.name}</p>
<ul className="i_ul_value">
{ cmsDir && <li><a href={ detail.publishUserUrl } ><img src={ detail.publishUserImage } alt="" className="headimg" /> { detail.publishUserNickname }</a></li> }
{ cmsDir && <li>{ detail.isFirstPublish ? '创建于' : '更新于' }{detail.publishTime}</li> }
{ detail.visits && <li><img src={liulan} alt="" className="mr5" />{detail.visits}</li> }
</ul>
</div>
<Divider dashed={true} />
<React.Fragment>
{
IsPC() && <Acce type="head"/>
}
<div className={IsPC() ? "detail_news_phone" :"detail_news_all"}>
<Spin spinning={isSpin} size="large">
{
detail &&
<div className="d_news_box">
{
content ?
<RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
:
<span>暂无详情~</span>
IsPC() && zonedetail &&
<div className="p_title_box">
<p className="p_t_title"><a href={`/zone/${deptId}`}>{zonedetail.name}</a></p>
<p className="p_t_desc" dangerouslySetInnerHTML={{ __html: zonedetail.introductionContent }}></p>
</div>
}
{
!IsPC() &&
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{tempConfig[temp].mainTitle}</Breadcrumb.Item>
{ cmsDir && <Breadcrumb.Item href={`/zone/${deptId}/news/${cmsDir.id}`}>{cmsDir.name}</Breadcrumb.Item> }
<Breadcrumb.Item>正文</Breadcrumb.Item>
</Breadcrumb>
}
<div className="info_text">
<div className="info_text_main">
<p className="i_name">{detail.name}</p>
<ul className="i_ul_value">
{ cmsDir && <li><a href={ detail.publishUserUrl } ><img src={ detail.publishUserImage } alt="" className="headimg" /> { detail.publishUserNickname }</a></li> }
{ cmsDir && <li>{ detail.isFirstPublish ? '创建于' : '更新于' }{detail.publishTime}</li> }
{ detail.visits && <li><img src={liulan} alt="" className="mr5" />{detail.visits}</li> }
</ul>
</div>
{ !IsPC() && <Divider dashed={true} /> }
{
content ?
<RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
:
<span>暂无详情~</span>
}
</div>
</div>
</div>
}
</Spin>
</div>
}
</Spin>
</div>
{
IsPC() && <Acce type="foot" />
}
</React.Fragment>
)
}
export default NewsDetail;

View File

@ -86,40 +86,45 @@ function Source(props){
</div>
</div>
<div className="sources">
<div className="source_left_ul">
{
zoneList && zoneList.length>0&&
<ul className="source_l_u">
<p>资源领域</p>
<div>
<li onClick={()=>{setChooseZoneId(undefined);window.scrollTo(0,450)}} className={!chooseZoneId ?"active":""}>全部</li>
{
zoneList.map((i,k)=>{
return(
<li key={k} onClick={()=>{setChooseZoneId(i.id);window.scrollTo(0,450)}} className={chooseZoneId && chooseZoneId === i.id ? "active":"" }>{i.name}</li>
)
})
}
</div>
</ul>
}
{
typeList && typeList.length>0 &&
<ul className="source_l_u">
<p className="borderRight">资源类别</p>
<div>
<li onClick={()=>{setChooseTypeId(undefined);window.scrollTo(0,450)}} className={!chooseTypeId ?"active":""}>全部</li>
{
typeList.map((i,k)=>{
return(
<li key={k} onClick={()=>{setChooseTypeId(i.id);window.scrollTo(0,450)}} className={chooseTypeId && chooseTypeId === i.id ? "active":"" }>{i.name}</li>
)
})
}
</div>
</ul>
}
</div>
{
(zoneList && zoneList.length>0 ) || (typeList && typeList.length >0 ) ?
<div className="source_left_ul">
{
zoneList && zoneList.length>0 &&
<ul className="source_l_u">
<p>资源领域</p>
<div>
<li onClick={()=>{setChooseZoneId(undefined);window.scrollTo(0,450)}} className={!chooseZoneId ?"active":""}>全部</li>
{
zoneList.map((i,k)=>{
return(
<li key={k} onClick={()=>{setChooseZoneId(i.id);window.scrollTo(0,450)}} className={chooseZoneId && chooseZoneId === i.id ? "active":"" }>{i.name}</li>
)
})
}
</div>
</ul>
}
{
typeList && typeList.length>0 &&
<ul className="source_l_u">
<p className="borderRight">资源类别</p>
<div>
<li onClick={()=>{setChooseTypeId(undefined);window.scrollTo(0,450)}} className={!chooseTypeId ?"active":""}>全部</li>
{
typeList.map((i,k)=>{
return(
<li key={k} onClick={()=>{setChooseTypeId(i.id);window.scrollTo(0,450)}} className={chooseTypeId && chooseTypeId === i.id ? "active":"" }>{i.name}</li>
)
})
}
</div>
</ul>
}
</div>
:""
}
<Spin spinning={isSpin}>
<div className="s_m_list">
{

View File

@ -76,7 +76,7 @@ function ZoneVIP(props){
<div className={`boxmain ${temp}_VIP_box`}>
<p className="in_title">{ tempConfig[temp].member }</p>
<p className="vip_sub_title">{ tempConfig[temp].vipDesc }</p>
{ memberStatus === memberStatusEnum.notMember && <Button className="apply_button" onClick={ apply }>申请加入</Button> }
{ memberStatus === memberStatusEnum.notMember && <Button className="zone_apply_button" onClick={ apply }>申请加入</Button> }
{ memberStatus === memberStatusEnum.applying && <div className="mt20 tips" ><Icon type="check-circle" theme="filled" />您的申请已提交请耐心等待管理员审核!</div> }
<MemberApply visible={applyVisible} onOk={ onOk } onCancel={() => setApplyVisible(!applyVisible)} current_user={props.current_user}/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -11,9 +11,11 @@ import Loading from "../../Loading";
import { getMainInfos , getCheckZoneRole } from './api';
import PublicBanner from "./Component/publicBanner";
import './index.scss';
import { IsPC } from 'educoder';
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import { tempEnum } from "./tempInfo";
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
const SourceDetail = Loadable({
loader: () => import("./Pages/sourceDetail"),
@ -55,12 +57,19 @@ const Main = Loadable({
loading: Loading,
});
const Help = Loadable({
loader: () => import("./Pages/help"),
loading: Loading,
});
function Index(props){
const [ data , setData ] = useState(undefined);
const [ adminUrl , setAdminUrl ] = useState(undefined);
const { deptId } = props.match.params;
const [ id , setId ] = useState(undefined);
const [ temp , setTemp ] = useState(tempEnum.zone);
const { pathname } = props.history.location;
const sourcedetail = pathname.indexOf(`/zone/${deptId}/newdetail/`)>-1 && IsPC();
useEffect(()=>{
if(deptId){
@ -109,7 +118,7 @@ function Index(props){
}
return(
<div className="information_main">
{ id ? <PublicBanner {...props} data={data} temp={ temp } adminUrl={adminUrl}/> : <div style={{ width: '100%', height: '450px' }}></div>}
{ !sourcedetail && (id ? <PublicBanner {...props} data={data} temp={ temp } adminUrl={adminUrl}/> : <div style={{ width: '100%', height: '450px' }}></div>)}
<Switch>
<Route
path="/zone/:deptId/news/:cateId"
@ -120,7 +129,7 @@ function Index(props){
<Route
path="/zone/:deptId/newdetail/:id"
render={(p) => (
<NewsDetail {...props} {...p} id={id} temp={ temp }/>
<NewsDetail {...props} {...p} id={id} temp={ temp } data={data}/>
)}
></Route>
<Route
@ -153,6 +162,12 @@ function Index(props){
<Main {...props} {...p} id={id} temp={ temp }/>
)}
></Route>
{data && data.helperShow === 1 && <Route
path="/zone/:deptId/help"
render={(p) => (
<Help {...props} {...p} id={id} temp={ temp } data={data} adminUrl={adminUrl}/>
)}
></Route>}
<Route
path="/zone/:deptId"
render={(p) => (
@ -163,5 +178,8 @@ function Index(props){
</div>
)
}
export default withRouter((CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
export default withRouter((CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newContainer",
})(Index)))))
);

View File

@ -1,5 +1,20 @@
@import './theme.scss';
// 按钮
.zone_apply_button {
flex-grow: 0;
margin-top: 20px;
width: 111px;
height: 40px;
color: var(--primary-color);
border-color: var(--primary-color);
font-size: 15px;
&:hover, &:active, &:focus {
color: var(--primary-color);
border-color: var(--primary-color);
}
}
.information_main{
background-color:#f3f5f8;
min-height: 100vh;
@ -72,7 +87,7 @@
line-height: 88px;
border-bottom: none!important;
padding:0px ;
margin-right: 100px!important;
margin-right: 80px!important;
img{
margin-right: 10px;
}
@ -418,12 +433,75 @@
display: flex;
justify-content: center;
}
.detail_news_phone{
font-size: 62.5%;
padding:1.5em;
background-color: #E8EAF1;
.markdown-body p{
font-size: 1em!important;
}
.p_title_box{
padding:2em 1.5em;
min-height: 15em;
background-image: url('./img/p_banner.png');
background-size: 100% 100%;
margin-bottom: 2em;
.p_t_title{
font-weight:600;
color:#141519;
font-size:2em;
height: 2em;
line-height: 2em;
margin-bottom: 1.5em!important;
text-align: center;
}
.p_t_desc{
color:#75767a;
font-size:1.6em;
letter-spacing:2px;
line-height: 2em;
}
}
.info_text{
padding:1.5em;
background-image:linear-gradient(180deg,#f8f9fd 0%,#f8f9fd 100%);
border:1px solid #ffffff;
box-sizing: border-box;
}
.info_text_main{
margin-bottom: 2em;
.i_name{
font-size: 2.4em;
font-weight: 400;
}
.i_ul_value{
display: flex;
align-items: center;
margin-top: 1em;
font-size: 1.5em;
li{
margin-right: 1.5em;
}
.headimg{
width: 2em;
height: 2em;
border-radius: 50%;
margin-right: 0.2em;
}
}
}
}
.detail_news_all{
display: flex;
flex-direction: column;
align-items: center;
min-height: 600px;
justify-content: unset;
.d_news_box{
width:1200px;
margin:0px auto;
padding:30px 0px;
}
.ant-spin-spinning {
margin: auto;
}
@ -1010,19 +1088,6 @@
}
}
.zone_VIP_box, .zone1_VIP_box {
.apply_button {
flex-grow: 0;
margin-top: 20px;
width: 111px;
height: 40px;
color: var(--primary-color);
border-color: var(--primary-color);
font-size: 15px;
&:hover, &:active, &:focus {
color: var(--primary-color);
border-color: var(--primary-color);
}
}
.tips {
width: 100%;
font-size: 15px;
@ -1347,6 +1412,87 @@
}
}
}
// 帮助中心
.zoneHelpBox{
.leftMenuHC{
width: 290px;
min-height: 500px;
overflow-x: auto;
&::-webkit-scrollbar{
display: none;
}
background: #ffffff;
padding: 25px 15px;
.ant-tree.ant-tree-directory > .menuHcNode span.ant-tree-node-content-wrapper.ant-tree-node-selected, .ant-tree.ant-tree-directory .ant-tree-child-tree > .menuHcNode span.ant-tree-node-content-wrapper.ant-tree-node-selected{
color: var(--primary-color);
}
.ant-tree.ant-tree-directory > .menuHcNode.ant-tree-treenode-selected > span.ant-tree-switcher, .ant-tree.ant-tree-directory .ant-tree-child-tree > .menuHcNode.ant-tree-treenode-selected > span.ant-tree-switcher{
color: var(--primary-color);
}
.ant-tree.ant-tree-directory > .menuHcNode span.ant-tree-node-content-wrapper:hover::before, .ant-tree.ant-tree-directory .ant-tree-child-tree > .menuHcNode span.ant-tree-node-content-wrapper:hover::before{
background: var(--more-light-color);
}
.menuHcNode{
.ant-tree-node-selected::before{
background: none !important;
}
}
.searchHC.ant-input-affix-wrapper{
&:hover .ant-input, .ant-input:focus{
border-color: var(--primary-color) !important;
}
}
.searchHC .ant-input-search-icon:hover{
color: var(--primary-color);
}
}
.wikiTitleHC{
font-weight: 700;
}
.wikiUpdateTimeHC{
color:#6c7283;
}
.wikiContentBox{
min-height: 500px;
background-color: #fff;
padding: 20px 40px;
}
.wikiContMenuBox{
border-left: 3px solid #e6e8ef;
padding: 5px 0 5px 15px;
min-width: 100px;
max-width: 220px;
margin-left: 60px;
background-color: #fff;
max-height: 80vh;
overflow-y: auto;
overflow-x: hidden;
a{
color:#6c7283;
word-break: break-all;
overflow: hidden;
display: inline-block;
width: 190px;
white-space: nowrap;
text-overflow: ellipsis;
&.current{
color: var(--primary-color);
position: relative;
&::before{
content: "";
position: absolute;
left: -18px;
width:3px;
height:30px;
background-color: var(--primary-color);
}
}
&:hover{
color: var(--primary-color);
}
}
}
}
.primaryColor{
color: var(--primary-color)!important;
}

View File

@ -171,8 +171,8 @@
}
.quillFlagBox{
color: red;
margin-top: -10px;
margin-bottom: 5px !important;
height: 28px;
}
.addComments{
display: flex;

View File

@ -152,7 +152,6 @@
justify-content: space-between;
width: 100%;
height: 18px;
line-height: 18px;
margin-top: -5px;
}

View File

@ -368,6 +368,7 @@ class MessageCount extends Component {
</Menu>
);
const permission = projectDetail && (projectDetail.permission === "Admin" || projectDetail.permission === "Owner" || projectDetail.permission === "Manager");
const permissionByCodeReview = projectDetail && (projectDetail.permission === "Admin" || projectDetail.permission === "Owner" || projectDetail.permission === "Manager" || projectDetail.permission === "Developer")
const userLogin = current_user && current_user.login;
const operate = userLogin && projectDetail && pr_status === 0 && permission;
const open_blockchain = project && project.open_blockchain;
@ -507,7 +508,7 @@ class MessageCount extends Component {
</Button>
)}
{userLogin && projectDetail && permission && (
{userLogin && projectDetail && permissionByCodeReview && (
<Button
type="blue"
ghost

View File

@ -186,6 +186,8 @@ function MilepostDetail(props){
<CheckProfile {...props} sureFunc={()=>{history.push(`/${owner}/${projectsId}/issues/${mileId}/new`)}} checklogin className="operateButton ml20">+ 创建疑修</CheckProfile>
</div>
</FlexAJ>}
{/* 里程碑描述 */}
<div className="color-grey-89 mt10">{milepost && milepost.description}</div>
<div className="lists mt25">
<div className="listheader">
<div style={{display:"flex"}}>

View File

@ -332,6 +332,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
placeholder={"请输入标题"}
className="contact-input"
maxLength={50}
autoFocus
/>
)}
@ -343,6 +344,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
initValue={content}
onChange={onContentChange}
className="mt20 wikiMEDEditor"
isFocus={false}
></MDEditor>
{getFieldDecorator('md_content', {
rules: [{ required: true, message: "请输入wiki内容" }],

View File

@ -1,19 +1,19 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import { Button, Dropdown, Icon, Input, Menu, Tooltip, Select, Upload, message, Spin, Modal } from 'antd';
import React, { useEffect, useState } from 'react';
import { Button, Dropdown, Icon, Input, Menu, Select, message, Spin, Modal } from 'antd';
import { getImageUrl, timeAgo } from 'educoder';
import cookie from 'react-cookies';
import CopyTool from '../Component/CopyTool';
import Welcome from './Welcome';
import RenderHtml from "../../components/render-html";
import { wikiPages, getWiki, parseSidebar, updateWiki, treeToMd } from './api';
import { httpUrl, TokenKey } from './fetch';
import { httpUrl } from './fetch';
import './Index.scss';
import './components/ModalFun/index.scss';
import { isArray } from 'lodash';
import { Base64 } from 'js-base64';
import Sidebar from './components/sidebar';
import UploadWiki from './components/uploadWiki';
import axios from 'axios';
const InputGroup = Input.Group;
const { Option } = Select;
@ -38,9 +38,18 @@ export default (props) => {
const [addMenuError, setAddMenuError] = useState(undefined);
const [sidebar, setSidebar] = useState(undefined);
const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(undefined);
const [masterProtected, setMasterProtected] = useState(false);
useEffect(()=>{
window.scrollTo(0,0);
// master
if(projectsId && owner){
axios.get(`/v1/${owner}/${projectsId}/branches.json`, {keyword: 'master'}).then(res=>{
if(res && res.data && res.data.total_count === 1){
setMasterProtected(res.data.branches[0].protected);
}
})
}
}, [])
useEffect(()=>{
@ -292,7 +301,7 @@ export default (props) => {
<div className="wiki-nav">
{/* 读sidebar转换成目录树 */}
<Sidebar fileList = {fileList} changeitem={changeitem} projectsId={projectsId} owner={owner} project={project} setReload={setReload} sidebar={sidebar} history={history} permission={permission} defaultSelectedKeys={defaultSelectedKeys} fileArrInit={fileArrInit}/>
<Sidebar fileList = {fileList} changeitem={changeitem} projectsId={projectsId} owner={owner} project={project} setReload={setReload} sidebar={sidebar} history={history} permission={permission} defaultSelectedKeys={defaultSelectedKeys} fileArrInit={fileArrInit} masterProtected={masterProtected}/>
</div>
</div>
@ -321,7 +330,7 @@ export default (props) => {
{permission && <Button type="primary" onClick={goEdit}>编辑</Button>}
</div>
{itemDetail&&itemDetail.md_content&&<RenderHtml className="wiki-content-detail editor-content-panel" value={ itemDetail && Base64.decode(itemDetail.md_content) } url={history.location}/>}
{itemDetail&&itemDetail.md_content&&<RenderHtml className="wiki-content-detail editor-content-panel imageLayerParent" value={ itemDetail && Base64.decode(itemDetail.md_content) } url={history.location}/>}
</div>
</div>
</div >
@ -330,7 +339,7 @@ export default (props) => {
}
<Modal title="新增目录" visible={visible} onCancel={()=>{setVisible(false);setAddMenuError(undefined);setMenuName(undefined);}} onOk={addMenu} className="wikiAddMenu myself-modal" width={450} centered>
<div className='mb10'>目录名称: </div>
<Input placeholder='请输入目录名称' value={menuName} onChange={(e)=>{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={50}></Input>
<Input placeholder='请输入目录名称' value={menuName} onChange={(e)=>{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={50} autoFocus></Input>
<div className='wikiAddMenuError mt5'>{addMenuError}</div>
</Modal>
</Spin>

View File

@ -115,10 +115,16 @@ export function markdownToTree(markdownText){
}
lines.map((item, index) =>{
const title = item.trim();
const isFile = title.startsWith('[[') && title.endsWith(']]');
const node = {
// 带空格+[[]]或者- 标识
title: item,
children: [],
key: undefined
key: undefined,
// 纯内容
titleStr: isFile ? title.substring(2, title.length - 2) : title.substring(2, title.length),
// 是否是wiki文件
isFile: isFile
}
// level空格的个数(层级)
const level = item.search(/\S/);
@ -200,4 +206,51 @@ function readList(list, readChildren){
list.push(item.title)
readList(list, item.children)
})
}
export function generateList(list) {
const dataList = [];
generate(list);
function generate(data){
for (let i = 0; i < data.length; i++) {
const node = data[i];
const { key, titleStr } = node;
dataList.push({ key, title: titleStr });
if (node.children) {
generate(node.children);
}
}
}
return dataList;
};
export const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
export function findFirstWiki(list){
for (let index = 0; index < list.length; index++) {
const element = list[index];
if (element.isFile) {
return element;
}else if (element.children.length) {
let result = findFirstWiki(element.children);
if (result) {
return result;
}
}
}
}

View File

@ -6,12 +6,13 @@ import '../../components/ModalFun/index.scss';
import { deleteWiki, findNodeByChildrenKey, findNodeByKey, getWiki, treeToMd, updateWiki } from '../../api';
import { useEffect } from 'react';
import { Base64 } from 'js-base64';
import { splicingTabs } from '../../utils';
const Search = Input.Search;
const {DirectoryTree, TreeNode} = Tree;
// wiki
export default function Sidebar(props) {
const {fileList, changeitem, owner, projectsId, project, setReload, sidebar, history, permission, defaultSelectedKeys, fileArrInit} = props;
const {fileList, changeitem, owner, projectsId, project, setReload, sidebar, history, permission, defaultSelectedKeys, fileArrInit, masterProtected} = props;
const {location:{pathname}} = history;
const [initMenuList, setInitMenuList] = useState(undefined);
const [menuList, setMenuList] = useState(undefined);
@ -65,9 +66,10 @@ export default function Sidebar(props) {
</a>
</Menu.Item>
<Menu.Item>
<a onClick={(e) => { deleteFileModal(e, title, isFile, item) }}>
删除
</a>
{
masterProtected && item.children.length ? <a onClick={() => { message.error("由于master分支设置了分支保护不允许删除wiki") }}>删除</a> :
<a onClick={(e) => { deleteFileModal(e, title, isFile, item) }}>删除</a>
}
</Menu.Item>
</Menu>
};
@ -80,9 +82,10 @@ export default function Sidebar(props) {
</a>
</Menu.Item>
<Menu.Item>
<a onClick={(e) => { deleteFileModal(e, title, isFile, item) }}>
删除
</a>
{
masterProtected ? <a onClick={() => { message.error("由于master分支设置了分支保护不允许删除wiki") }}>删除</a> :
<a onClick={(e) => { deleteFileModal(e, title, isFile, item) }}>删除</a>
}
</Menu.Item>
</Menu>
};
@ -281,8 +284,10 @@ export default function Sidebar(props) {
setVisible(false);
message.success('重命名成功');
}else{
console.log('修改文件目录顺序成功');
// message.success('');
}
}else{
message.error(res.message);
}
});
}
@ -447,10 +452,10 @@ export default function Sidebar(props) {
dragObj = item;
});
// \t
if(dragObj.title.indexOf('- ') !== -1){
if(!dragObj.isFile){
//
const title = info.node.props.dataRef.title;
const addBool = !info.dropToGap || ((info.node.props.children || []).length > 0 && dropPosition === 1)
const addBool = !info.dropToGap
upTitle(dragObj.children, addBool ? `\t${title}` : title);
}
@ -459,52 +464,56 @@ export default function Sidebar(props) {
// dropToGap: true false
if (!info.dropToGap) {
//
// ->
loop(data, dropKey, (item, index, arr) => {
const {title} = item;
const {title, key} = item;
if(title.indexOf('- ') === -1){
message.error('不能拖拽到页面上');
return;
}
const childrenName = item.children.map(item=>item.title.trim());
if(childrenName.includes(dragObj.title.trim())){
const childrenName = item.children.map(item=>item.titleStr);
if(childrenName.includes(dragObj.titleStr)){
message.error('不能与同级目录名称相同');
return;
}
dragObj.title = `\t${title.substring(0, title.indexOf('- '))}${dragObj.title.trim()}`;
dragObj.title = `${splicingTabs(key.split('-').length)}${dragObj.title.trim()}`;
item.children = item.children || [];
item.children.push(dragObj);
bool = true;
});
} else if (
(info.node.props.children || []).length > 0 && // Has children
dropPosition === 1 // On the bottom gap
) {
//
loop(data, dropKey, item => {
const childrenName = item.children.map(item=>item.title.trim())
if(childrenName.includes(dragObj.title.trim())){
message.error('不能与同级目录名称相同');
return;
}
const {title} = item;
dragObj.title = `\t${title.substring(0, title.indexOf('- '))}${dragObj.title.trim()}`;
item.children = item.children || [];
item.children.unshift(dragObj);
});
bool = true;
} else {
}
// else if (
// (info.node.props.children || []).length > 0 && // Has children
// dropPosition === 1 // On the bottom gap
// ) {
// //
// loop(data, dropKey, item => {
// const childrenName = item.children.map(item=>item.title.trim())
// if(childrenName.includes(dragObj.title.trim())){
// message.error('');
// return;
// }
// console.log('item', item, 'dragObj', dragObj);
// const {title} = item;
// dragObj.title = `\t${title.substring(0, title.indexOf('- '))}${dragObj.title.trim()}`;
// item.children = item.children || [];
// item.children.unshift(dragObj);
// });
// bool = true;
// }
else {
let ar;
let i;
loop(data, dropKey, (item, index, arr) => {
ar = arr;
i = index;
});
const childrenName = ar.map(item=>item.title.trim())
if(childrenName.includes(dragObj.title.trim())){
const childrenName = ar.map(item=>item.titleStr)
if(childrenName.includes(dragObj.titleStr)){
message.error('不能与同级目录名称相同');
return;
}
dragObj.title = `${ar[i].title.substring(0, ar[i].title.indexOf('- '))}${dragObj.title.trim()}`;
dragObj.title = `${splicingTabs(ar[i].key.split('-').length-1)}${dragObj.title.trim()}`;
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
@ -614,9 +623,9 @@ export default function Sidebar(props) {
</DirectoryTree> : ''}
{/* 新增子目录弹窗 */}
<Modal title={isEditName ? `编辑${isEditName === 1 ? '目录' : '页面'}` : "新增目录"} visible={Boolean(visible)} onCancel={onCancel} onOk={submit} className="wikiAddMenu myself-modal" width={450} centered>
<Modal title={isEditName ? `编辑${isEditName === 1 ? '目录' : '页面'}` : "新增目录"} visible={Boolean(visible)} onCancel={onCancel} onOk={submit} className="wikiAddMenu myself-modal" width={450} centered destroyOnClose>
<div className='mb10'>{isEditName === 2 ? '页面' : '目录'}名称: </div>
<Input placeholder={`请输入${isEditName === 2 ? '页面' : '目录'}名称`} value={menuName} onChange={(e)=>{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={50}></Input>
<Input placeholder={`请输入${isEditName === 2 ? '页面' : '目录'}名称`} value={menuName} onChange={(e)=>{setMenuName(e.target.value);setAddMenuError(undefined)}} maxLength={50} autoFocus></Input>
<div className='wikiAddMenuError mt5'>{addMenuError}</div>
</Modal>
</div>

24
src/forge/Wiki/utils.js Normal file
View File

@ -0,0 +1,24 @@
// 拼接\t
export function splicingTabs(count) {
var tabs = "";
for (var i = 0; i < count; i++) {
tabs += "\t";
}
return tabs;
}
// 输入:'2-2-2-1' 返回:['2', '2-2', '2-2-2', '2-2-2-1']
export function splitAndCombine(str) {
if(!str) return []
var parts = str.split('-');
var result = parts.reduce(function(acc, curr) {
if (acc.length === 0) {
acc.push(curr);
} else {
var lastItem = acc[acc.length - 1];
acc.push(lastItem + '-' + curr);
}
return acc;
}, []);
return result;
}

View File

@ -228,6 +228,12 @@ form{
.normal{
width: 100%;
}
#root{
width: 1200px;
}
.newContainers{
min-width: 1200px;
}
}
.ver-middle{
vertical-align: middle;

View File

@ -51,6 +51,10 @@
list-style-type: none;
}
.markdown-body video{
max-width: 100%;
}
ol,
ul,
li {

View File

@ -26,10 +26,6 @@ function Register(props){
const [setting, setSetting] = useState(undefined);
const seconds = useRef();
let interval = undefined;
//
// const inputEl = useRef(null);
useEffect(()=>{
//
@ -220,11 +216,6 @@ function Register(props){
}
}
useEffect(() => {
// inputEl.current.focus();
// clear;
}, [])
function changeRegisterType(type){
setGetCaptchaBut(false);
setRegisterType(type);
@ -277,8 +268,7 @@ function Register(props){
],
validateTrigger:"onBlur",
validateFirst: true,
// ref={inputEl}
})(<Input placeholder="请输入4-15位用户名以字母开头只能使用字母和数字" autoComplete="off"/>)}
})(<Input autoFocus placeholder="请输入4-15位用户名以字母开头只能使用字母和数字" autoComplete="off"/>)}
</Form.Item>
<Form.Item>
{getFieldDecorator('email',{

View File

@ -18,8 +18,6 @@ function ResetPassword(props) {
const [emailGo, setEmailGo] = useState(true);
const seconds = useRef();
let interval = undefined;
//
const inputEl = useRef(null);
//
useEffect(()=>{
@ -187,10 +185,6 @@ function ResetPassword(props) {
}
}
useEffect(() => {
inputEl.current.focus();
}, [])
return (
<div>
<div className="right_cont ResetPassword_content">
@ -213,7 +207,7 @@ function ResetPassword(props) {
],
validateTrigger: "onBlur",
validateFirst: true,
})(<Input ref={inputEl} className="account" placeholder="请输入已注册的手机号/邮箱" autoComplete="off"/>)}
})(<Input autoFocus className="account" placeholder="请输入已注册的手机号/邮箱"/>)}
</Form.Item>
<Form.Item>

View File

@ -16,20 +16,25 @@ export function ImageLayerOfCommentHOC(options = {}) {
onDelegateClick = (event) => {
const imageSrc = event.target.src || event.target.getAttribute('src') || event.target.getAttribute('href')
// 判断imageSrc是否是图片
const fileName = event.target.innerHTML.trim()
if (isImageExtension(imageSrc.trim()) || isImageExtension(fileName) || event.target.tagName == 'IMG') {
// 非回复里的头像图片; 非emoticons
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1) {
this.setState({
showImage: true,
imageSrc,
})
const fileName = event.target.innerHTML.trim();
const parentNodeUrl = event.target.parentNode && event.target.parentNode.getAttribute('href');
if(parentNodeUrl){
window.location.href = parentNodeUrl;
}else{
if (isImageExtension(imageSrc.trim()) || isImageExtension(fileName) || event.target.tagName == 'IMG') {
// 非回复里的头像图片; 非emoticons
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1) {
this.setState({
showImage: true,
imageSrc,
})
}
event.stopPropagation()
event.preventDefault && event.preventDefault()
event.originalEvent.preventDefault()
return false;
}
event.stopPropagation()
event.preventDefault && event.preventDefault()
event.originalEvent.preventDefault()
return false;
}
}

View File

@ -11,6 +11,7 @@ import SupplyPhoneModal from '../../forge/Component/ProfileModal/SupplyPhone';
import SystemNotice from '../../forge/Component/NoticeModal/SystemNotice';
import cookie from 'react-cookies';
import NpsModal from '../modals/npsModal';
import { IsPC } from 'educoder';
export function TPMIndexHOC(WrappedComponent) {
return class II extends React.Component {
@ -285,6 +286,8 @@ export function TPMIndexHOC(WrappedComponent) {
showCompeleteDialog:this.showCompeleteDialog,
showNpsModal: this.showNpsModal
};
let path =this.props.location.pathname;
let pathCheck = path.indexOf("/zone")>-1 && path.indexOf("/newdetail")>-1 && IsPC();
return (
<div className="indexHOC">
<SystemNotice
@ -307,7 +310,7 @@ export function TPMIndexHOC(WrappedComponent) {
{...this.state}
/> : ""}
{npsModalVisible && <NpsModal closeNpsModal={()=>{this.closeNpsModal()}} npsActionType={npsActionType} npsActionId={npsActionId}/>}
<Header {...this.state} {...this.props} {...common} publicNav={publicNav}></Header>
{ !pathCheck && <Header {...this.state} {...this.props} {...common} publicNav={publicNav}></Header> }
<Spin spinning={this.state.globalLoading} delay={0} className="globalSpin"
size="large" tip={this._gLoadingTip || "加载中..."}
>
@ -321,7 +324,7 @@ export function TPMIndexHOC(WrappedComponent) {
}
</div>
</Spin>
<NewFooter {...this.state} {...this.props} />
{!pathCheck && <NewFooter {...this.state} {...this.props} /> }
</div>
);
}