Merge pull request '同步到测试分支' (#780) from pre_gitlink_ssr into gitlink_ssr_head
1
|
@ -2522,7 +2522,6 @@ _extend(KRange, {
|
|||
return self;
|
||||
},
|
||||
dump : function() {
|
||||
console.log('--------------------');
|
||||
console.log(this.startContainer.nodeType == 3 ? this.startContainer.nodeValue : this.startContainer, this.startOffset);
|
||||
console.log(this.endContainer.nodeType == 3 ? this.endContainer.nodeValue : this.endContainer, this.endOffset);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1715677391041') format('woff2'),
|
||||
url('iconfont.woff?t=1715677391041') format('woff'),
|
||||
url('iconfont.ttf?t=1715677391041') format('truetype');
|
||||
src: url('iconfont.woff2?t=1727340588188') format('woff2'),
|
||||
url('iconfont.woff?t=1727340588188') format('woff'),
|
||||
url('iconfont.ttf?t=1727340588188') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,42 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-gongxianquequan:before {
|
||||
content: "\e979";
|
||||
}
|
||||
|
||||
.icon-xuanzhong5:before {
|
||||
content: "\e97a";
|
||||
}
|
||||
|
||||
.icon-big-circle:before {
|
||||
content: "\e978";
|
||||
}
|
||||
|
||||
.icon-gitee:before {
|
||||
content: "\e974";
|
||||
}
|
||||
|
||||
.icon-gitea:before {
|
||||
content: "\e975";
|
||||
}
|
||||
|
||||
.icon-coding:before {
|
||||
content: "\e976";
|
||||
}
|
||||
|
||||
.icon-github1:before {
|
||||
content: "\e977";
|
||||
}
|
||||
|
||||
.icon-gitlab:before {
|
||||
content: "\e973";
|
||||
}
|
||||
|
||||
.icon-a-lianhe6:before {
|
||||
content: "\e972";
|
||||
}
|
||||
|
||||
.icon-a-22ziliaoshouce-xianxing:before {
|
||||
content: "\e971";
|
||||
}
|
||||
|
@ -413,6 +449,10 @@
|
|||
content: "\e90e";
|
||||
}
|
||||
|
||||
.icon-shanchu_important:before {
|
||||
content: "\f1d8";
|
||||
}
|
||||
|
||||
.icon-shanchu_tc_icon1:before {
|
||||
content: "\e90c";
|
||||
}
|
||||
|
|
|
@ -5,6 +5,69 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "41876673",
|
||||
"name": "贡献确权",
|
||||
"font_class": "gongxianquequan",
|
||||
"unicode": "e979",
|
||||
"unicode_decimal": 59769
|
||||
},
|
||||
{
|
||||
"icon_id": "657556",
|
||||
"name": "分期-选中",
|
||||
"font_class": "xuanzhong5",
|
||||
"unicode": "e97a",
|
||||
"unicode_decimal": 59770
|
||||
},
|
||||
{
|
||||
"icon_id": "157771",
|
||||
"name": "细圆",
|
||||
"font_class": "big-circle",
|
||||
"unicode": "e978",
|
||||
"unicode_decimal": 59768
|
||||
},
|
||||
{
|
||||
"icon_id": "41539674",
|
||||
"name": "gitee",
|
||||
"font_class": "gitee",
|
||||
"unicode": "e974",
|
||||
"unicode_decimal": 59764
|
||||
},
|
||||
{
|
||||
"icon_id": "41539676",
|
||||
"name": "gitea",
|
||||
"font_class": "gitea",
|
||||
"unicode": "e975",
|
||||
"unicode_decimal": 59765
|
||||
},
|
||||
{
|
||||
"icon_id": "41539677",
|
||||
"name": "coding",
|
||||
"font_class": "coding",
|
||||
"unicode": "e976",
|
||||
"unicode_decimal": 59766
|
||||
},
|
||||
{
|
||||
"icon_id": "41539675",
|
||||
"name": "github",
|
||||
"font_class": "github1",
|
||||
"unicode": "e977",
|
||||
"unicode_decimal": 59767
|
||||
},
|
||||
{
|
||||
"icon_id": "41539679",
|
||||
"name": "gitlab",
|
||||
"font_class": "gitlab",
|
||||
"unicode": "e973",
|
||||
"unicode_decimal": 59763
|
||||
},
|
||||
{
|
||||
"icon_id": "41195024",
|
||||
"name": "联合 6",
|
||||
"font_class": "a-lianhe6",
|
||||
"unicode": "e972",
|
||||
"unicode_decimal": 59762
|
||||
},
|
||||
{
|
||||
"icon_id": "40333433",
|
||||
"name": "使用手册",
|
||||
|
@ -705,6 +768,13 @@
|
|||
"unicode": "e90e",
|
||||
"unicode_decimal": 59662
|
||||
},
|
||||
{
|
||||
"icon_id": "41976790",
|
||||
"name": "shanchu_tc_icon-copy",
|
||||
"font_class": "shanchu_important",
|
||||
"unicode": "f1d8",
|
||||
"unicode_decimal": 61912
|
||||
},
|
||||
{
|
||||
"icon_id": "26470602",
|
||||
"name": "shanchu_tc_icon",
|
||||
|
|
29
src/App.js
|
@ -93,7 +93,7 @@ const Search = Loadable({
|
|||
})
|
||||
|
||||
const WikiPreview = Loadable({
|
||||
loader: () => import('./forge/Wiki/Preview'),
|
||||
loader: () => import('./forge/Wiki/page/preview'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
@ -340,9 +340,12 @@ class App extends Component {
|
|||
<MuiThemeProvider theme={theme}>
|
||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
{/* <GlccModal /> */}
|
||||
{!pathName || (pathName && pathName.toLowerCase() !== 'glcc') ? <SiderBar {...this.props}/> : <SiderBarHelp/>}
|
||||
{/* {!pathName || (pathName && pathName.toLowerCase() !== 'glcc') ? <SiderBar {...this.props}/> : <SiderBarHelp/>} */}
|
||||
{pathName && pathName.toLowerCase() === 'glcc' && <SiderBarHelp/>}
|
||||
{/* <Router> */}
|
||||
<Switch>
|
||||
{
|
||||
pathType ?
|
||||
<Switch>
|
||||
{/* iframe页面 */}
|
||||
<Route path="/hiagent"
|
||||
render={
|
||||
|
@ -350,7 +353,7 @@ class App extends Component {
|
|||
}
|
||||
></Route>
|
||||
{/* wiki预览 */}
|
||||
<Route path="/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={
|
||||
<Route path="/:owner/:proIdentity/:projectId/wiki/preview" render={
|
||||
(props) => {
|
||||
return (<WikiPreview {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
|
@ -528,14 +531,6 @@ class App extends Component {
|
|||
</Route> : pathType === '404' ? <Route component={Shixunnopage} />:
|
||||
""
|
||||
}
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => (
|
||||
<Home {...props} {...this.props} {...this.state}/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
{/* 个人主页 */}
|
||||
<Route path="/:username"
|
||||
render={
|
||||
|
@ -547,6 +542,16 @@ class App extends Component {
|
|||
|
||||
<Route component={Shixunnopage} />
|
||||
</Switch>
|
||||
:
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => (
|
||||
<Home {...props} {...this.props} {...this.state}/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
}
|
||||
|
||||
</MuiThemeProvider>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
|
|
@ -17,22 +17,23 @@ function locationurl(list) {
|
|||
}
|
||||
// TODO 开发期多个身份切换
|
||||
let debugType = ""
|
||||
if (isDev) {
|
||||
const _search = window.location.search;
|
||||
let parsed = {};
|
||||
if (_search) {
|
||||
parsed = queryString.parse(_search);
|
||||
}
|
||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
}
|
||||
// if (isDev) {
|
||||
// const _search = window.location.search;
|
||||
// let parsed = {};
|
||||
// if (_search) {
|
||||
// parsed = queryString.parse(_search);
|
||||
// }
|
||||
// debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
// window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
// window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'student'
|
||||
// }
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
// 判断网络是否连接
|
||||
initOnlineOfflineListener();
|
||||
|
||||
var proxy = "https://testforgeplus.trustie.net";
|
||||
// var proxy = "http://172.20.32.201:4000";
|
||||
// var proxy = "https://www.gitlink.org.cn";
|
||||
|
||||
//响应前的设置
|
||||
|
@ -44,19 +45,20 @@ export function initAxiosInterceptors(props) {
|
|||
requestProxy(config);
|
||||
let url = `/api${config.url}`;
|
||||
|
||||
if (`${config[0]}` !== `true`) {
|
||||
if (window.location.port === "3007") {
|
||||
config.url = `${proxy}${url}`;
|
||||
if (config.url.indexOf('?') === -1) {
|
||||
config.url = `${config.url}?debug=${debugType}`;
|
||||
} else {
|
||||
config.url = `${config.url}&debug=${debugType}`;
|
||||
}
|
||||
} else {
|
||||
config.url = url;
|
||||
}
|
||||
}
|
||||
// if (`${config[0]}` !== `true`) {
|
||||
// if (window.location.port === "3007") {
|
||||
// config.url = `${proxy}${url}`;
|
||||
// if (config.url.indexOf('?') === -1) {
|
||||
// config.url = `${config.url}?debug=${debugType}`;
|
||||
// } else {
|
||||
// config.url = `${config.url}&debug=${debugType}`;
|
||||
// }
|
||||
// } else {
|
||||
// config.url = url;
|
||||
// }
|
||||
// }
|
||||
config.withCredentials = false;
|
||||
config.url = url;
|
||||
return config;
|
||||
},
|
||||
err => {
|
||||
|
@ -95,11 +97,12 @@ export function initAxiosInterceptors(props) {
|
|||
}
|
||||
|
||||
if (response.data.status === 404) {
|
||||
console.log("response:",response);
|
||||
let responseURL = (response && response.request) ? response.request.responseURL:'';
|
||||
// 组织和个人的拥有情况,404不跳转
|
||||
if (responseURL.indexOf('/api/users/') === -1 && responseURL.indexOf('/api/organizations/') === -1 ) {
|
||||
// 邀请页面不进行404跳转
|
||||
if( window.location.pathname.includes('/invite') && (responseURL.includes('/simple.json')||responseURL.includes('/detail.json')||responseURL.includes('/menu_list.json'))){
|
||||
if( window.location.pathname.includes('/invite') && (responseURL.includes('/simple.json')||responseURL.includes('/detail.json')||responseURL.includes('/menu_list.json'))||responseURL.includes('/entries.json')){
|
||||
}else{
|
||||
locationurl('/nopage');
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ function requestForSignatrue (callback) {
|
|||
service.post(url, {
|
||||
url: currentUrl,
|
||||
}).then((response) => {
|
||||
console.log('got res')
|
||||
const data = response.data && response.data.data;
|
||||
|
||||
wx.config({
|
||||
|
@ -125,7 +124,6 @@ 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];
|
||||
|
|
|
@ -32,10 +32,18 @@ class ActivityItem extends Component {
|
|||
</p >
|
||||
}
|
||||
<p className="itemLine mt10">
|
||||
<Link to={`/${item && item.user_login}`} className="show-user-link">
|
||||
<img alt="" src={getImageUrl(`/${item.user_avatar}`)} className="createImage" />
|
||||
<span className="mr20">{item.user_name}</span>
|
||||
</Link>
|
||||
{
|
||||
item && item.user_login ?
|
||||
<Link to={`/${item.user_login}`} className="show-user-link">
|
||||
<img alt="" src={getImageUrl(`/${item.user_avatar}`)} className="createImage" />
|
||||
<span className="mr20">{item.user_name}</span>
|
||||
</Link>
|
||||
:
|
||||
<span className="show-user-link">
|
||||
<img alt="" src={getImageUrl(`/${item.user_avatar}`)} className="createImage" />
|
||||
<span className="mr20 color-grey-6">{item.user_name}</span>
|
||||
</span>
|
||||
}
|
||||
{item.created_at && <span className="color-grey-9">创建于<span className="ml2 color-grey-6">{item.created_at}</span></span>}
|
||||
</p >
|
||||
</div>
|
||||
|
|
|
@ -5,25 +5,21 @@ import axios from 'axios';
|
|||
|
||||
const Option = AutoComplete.Option;
|
||||
|
||||
export default ({ getUser , placeholder, width ,value })=>{
|
||||
export default ({ getUser , placeholder, width ,value, userList=[] })=>{
|
||||
const [ source , setSource ] = useState(undefined);
|
||||
const [ searchKey , setSearchKey ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(!value){
|
||||
setSearchKey(undefined);
|
||||
if(userList && userList.length){
|
||||
sourceOptions(userList);
|
||||
}else{
|
||||
getUserList();
|
||||
}
|
||||
},[value])
|
||||
|
||||
useEffect(()=>{
|
||||
getUserList();
|
||||
},[searchKey])
|
||||
},[])
|
||||
|
||||
function getUserList(e){
|
||||
function getUserList(value){
|
||||
const url = `/users/list.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
search: searchKey,
|
||||
search: value,
|
||||
},
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
|
@ -61,13 +57,9 @@ export default ({ getUser , placeholder, width ,value })=>{
|
|||
setSource(s);
|
||||
}
|
||||
|
||||
function changeInputUser(e){
|
||||
setSearchKey(e);
|
||||
};
|
||||
|
||||
// 选择用户
|
||||
function selectInputUser(e, option){
|
||||
setSearchKey(option.props.name);
|
||||
getUserList(option.props.name);
|
||||
getUser(option.props.login);
|
||||
};
|
||||
|
||||
|
@ -76,12 +68,12 @@ export default ({ getUser , placeholder, width ,value })=>{
|
|||
<AutoComplete
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
dataSource={source}
|
||||
value={searchKey}
|
||||
style={{ width: width || 300 }}
|
||||
onChange={changeInputUser}
|
||||
onSearch={(value)=>{getUserList(value)}}
|
||||
onSelect={selectInputUser}
|
||||
placeholder={placeholder || "搜索需要添加的用户..."}
|
||||
allowClear
|
||||
optionLabelProp="name"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -21,7 +21,7 @@ $(window).scroll(function () {
|
|||
});
|
||||
|
||||
function SiderBar(props) {
|
||||
const {location, history} = props;
|
||||
const {location, history,user} = props;
|
||||
const {search, pathname} = location;
|
||||
const [ data , setData ] = useState([]);
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
|
@ -30,9 +30,13 @@ function SiderBar(props) {
|
|||
const [ feedBackValue, setFeedBackValue] = useState(undefined);
|
||||
const [ failApply, setFailApply] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
user && setLogin(user.login);
|
||||
},[user])
|
||||
|
||||
useEffect(()=>{
|
||||
getFAQ();
|
||||
getCurrentUser();
|
||||
// getCurrentUser();
|
||||
//页面加载完成之后隐藏回到顶点
|
||||
$(".-task-sidebar .gotop").hide();
|
||||
// 意见反馈弹窗
|
||||
|
@ -51,15 +55,6 @@ function SiderBar(props) {
|
|||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
//获取当前登录账号信息->用于建议反馈
|
||||
function getCurrentUser(){
|
||||
let url = `/users/get_user_info.json`;
|
||||
axios.get(url).then((response) => {
|
||||
if (response && response.data && response.data.login) {
|
||||
setLogin(response.data.login);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function content(list){
|
||||
return <div>
|
||||
|
|
|
@ -20,8 +20,8 @@ export default ({ url , name , column , id , login })=>{
|
|||
}
|
||||
`;
|
||||
return(
|
||||
id?
|
||||
<Link to={`/${login}`}>
|
||||
(id && login)?
|
||||
<Link to={`/${login ||""}`}>
|
||||
<span className="User">
|
||||
{ url && <img src={url} alt=""/> }
|
||||
<span>{name}</span>
|
||||
|
|
|
@ -75,7 +75,7 @@ function Index(props){
|
|||
key:3,
|
||||
width:"10%",
|
||||
render:(value,item)=>{
|
||||
return <Link to={`/${value.login}`}><img src={getImageUrl(`/${value.image_url}`)} alt="" style={{borderRadius:"50%"}} width="32px" height="32px" /></Link>
|
||||
return <Link to={`/${value.login}`}><img src={`${value.image_url}`} alt="" style={{borderRadius:"50%"}} width="32px" height="32px" /></Link>
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -8,14 +8,9 @@ const { Option } = Select;
|
|||
function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const [ cate , setCate ] = useState(0);
|
||||
const [ value , setValue ] = useState(undefined);
|
||||
|
||||
const [ organizations , setOrganizations ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
setFieldsValue({goal:cate})
|
||||
},[])
|
||||
|
||||
useEffect(()=>{
|
||||
if(owner && repo && visible===true){
|
||||
getTeam();
|
||||
|
@ -25,7 +20,7 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
|||
owner_name:undefined,
|
||||
identifier:undefined
|
||||
})
|
||||
setValue(undefined)
|
||||
setCate(0);
|
||||
}
|
||||
},[repo,owner,visible])
|
||||
|
||||
|
@ -79,7 +74,6 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
|||
};
|
||||
|
||||
function getUser(id){
|
||||
setValue(id);
|
||||
setFieldsValue({
|
||||
owner_name:id
|
||||
})
|
||||
|
@ -94,6 +88,7 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
|||
okText="确认转移"
|
||||
cancelText={"取消"}
|
||||
centered
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<div className="diverModal">
|
||||
{
|
||||
|
@ -113,7 +108,8 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
|||
<Form {...layout} colon={false} layout={"horizontal"}>
|
||||
<Form.Item label="转移给:" style={{marginBottom:"0px"}}>
|
||||
{getFieldDecorator("goal",{
|
||||
rules:[]
|
||||
rules:[],
|
||||
initialValue: 0
|
||||
})(
|
||||
<Radio.Group onChange={changeType}>
|
||||
<Radio value={0}>个人</Radio>
|
||||
|
@ -128,7 +124,7 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
|||
rules:[{required:true,message:"请输入目标用户名"}]
|
||||
})(
|
||||
// <Input placeholder="请输入目标用户" autoComplete={"off"}/>
|
||||
<SearchUser getUser={getUser} width={"100%"} placeholder="请输入目标用户" value={value}/>
|
||||
<SearchUser getUser={getUser} width={"100%"} placeholder="请输入目标用户"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
}
|
||||
|
|
|
@ -125,14 +125,19 @@ function IssueCommentList(props){
|
|||
{journals && (journals.length > 0 && journals.map(item=>{return <div key={item.id} className='commentContentBox pb30'>
|
||||
{/* 评论 */}
|
||||
<div className='commentOperationBor'></div>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></Link>
|
||||
{
|
||||
item.user.login ?
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></Link>
|
||||
:
|
||||
<span><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></span>
|
||||
}
|
||||
<div className='commentContentRight'>
|
||||
{/* 判断是否是编辑状态 */}
|
||||
{(showEdit === 2 && updateId === item.id) ? <div className='mt15 mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={item.notes} defaultFileList={item.attachments} showUserImg={false}/></div> : <div>
|
||||
<div className='commentContent'>
|
||||
<div className='flexCenter font-14'>
|
||||
<div>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name}</Link>
|
||||
{item.user.login ? <Link to={`/${item.user.login}`}>{item.user.name}</Link>:<span>{item.user.name}</span>}
|
||||
<span className='ml15 timeAgo font-14'>{timeAgo(item.created_at)}</span>
|
||||
</div>
|
||||
{login && !isPhone() && <div>
|
||||
|
|
|
@ -62,7 +62,7 @@ function Index(props){
|
|||
key:3,
|
||||
width:"10%",
|
||||
render:(value,item)=>{
|
||||
return <Link to={`/${value.login}`}><img src={getImageUrl(`/${value.image_url}`)} alt="" style={{borderRadius:"50%"}} width="32px" height="32px" /></Link>
|
||||
return <Link to={`/${value.login}`}><img src={`${value.image_url}`} alt="" style={{borderRadius:"50%"}} width="32px" height="32px" /></Link>
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,30 +1,25 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Box, LongWidth, FlexAJ } from '../../Component/layout';
|
||||
import { Affix, Button, Input, message, Spin, Tree } from 'antd';
|
||||
import { Affix, Button, message, Spin } 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 { findNodeByFirstOrContrastName, getMenuListAndSidebarData, getWiki } 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;
|
||||
import TreeByWikiSidebar from '../../Wiki/components/treeByWikiSidebar';
|
||||
|
||||
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 [wikiPageInitDetail, setWikiPageInitDetail] = useState({})
|
||||
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;
|
||||
const { temp, history, data, adminUrl, match:{params:{deptId}}, location} = props;
|
||||
const {menuList=[], sidebar="", wikiPages=undefined} = wikiPageInitDetail;
|
||||
const search = new URLSearchParams(location.search);
|
||||
const wikiBySearch = search.get("wiki") || '';
|
||||
let scroller = undefined;
|
||||
|
||||
const { owner, identifier, projectId } = (data && data.gitlinkProject) || {};
|
||||
|
@ -38,26 +33,22 @@ function ProjectSource(props) {
|
|||
useEffect(() => {
|
||||
if(!owner) return
|
||||
// 获取wiki 列表
|
||||
wikiPages(wikiParams).then(async res => {
|
||||
if (res && res.message === "200") {
|
||||
setWikiList(res.data);
|
||||
// 解析sidebar获取目录list
|
||||
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([]);
|
||||
}
|
||||
getMenuListAndSidebarData(wikiParams).then(res=>{
|
||||
setWikiPageInitDetail(res);
|
||||
})
|
||||
}, [owner])
|
||||
|
||||
useEffect(()=>{
|
||||
if(!menuList.length) return
|
||||
// 通过路由直接访问
|
||||
let node = findNodeByFirstOrContrastName(menuList, wikiBySearch)
|
||||
// 有可能wikiBySearch是错误的值,导致右侧显示为空
|
||||
if(!node){
|
||||
history.push(`/zone/${deptId}/help`)
|
||||
return
|
||||
}
|
||||
setWiki(node);
|
||||
}, [menuList, wikiBySearch])
|
||||
|
||||
useEffect(() =>{
|
||||
if(!wiki){
|
||||
|
@ -70,7 +61,7 @@ function ProjectSource(props) {
|
|||
...wikiParams
|
||||
}).then(res=>{
|
||||
setLoading(false);
|
||||
if (res && res.message === "200") {
|
||||
if (res && res.code === 200) {
|
||||
setWikiDetail(res.data);
|
||||
const tocContent = getTocContent();
|
||||
setWikiContMenu(tocContent);
|
||||
|
@ -154,77 +145,28 @@ function ProjectSource(props) {
|
|||
};
|
||||
}, [])
|
||||
|
||||
function changeSearchValue(value) {
|
||||
if (value) {
|
||||
const va = value.trim();
|
||||
// 找到命中搜索的item的父元素
|
||||
const expandedKeys = flattenedMenuList.map(item => {
|
||||
if (item.title.match(new RegExp(va, 'i'))) {
|
||||
return getParentKey(item.key, initMenuList);
|
||||
}
|
||||
return null;
|
||||
}).filter((item, i, self) => item && self.indexOf(item) === i);
|
||||
setSearchValue(va);
|
||||
setExpandedKeys(splitAndCombine(expandedKeys[0]));
|
||||
} else {
|
||||
setSearchValue("");
|
||||
}
|
||||
}
|
||||
|
||||
// 收起展开
|
||||
function onExpand(expandedKeys) {
|
||||
setAutoExpandParent(false);
|
||||
setExpandedKeys(expandedKeys);
|
||||
}
|
||||
|
||||
// 选中节点
|
||||
function selectTree(keys,event){
|
||||
let {isFile} = event.node.props.dataRef;
|
||||
if(isFile){
|
||||
setWiki(event.node.props.dataRef);
|
||||
}
|
||||
}
|
||||
|
||||
function renderTreeNodes(data) {
|
||||
return data && data.length > 0 && data.map((item) => {
|
||||
const matchResult = item.titleStr.match(new RegExp(searchValue, 'i'));
|
||||
const title = matchResult ? (
|
||||
<span>
|
||||
{item.titleStr.substr(0, matchResult.index)}
|
||||
<span style={{ color: '#f50' }}>{item.titleStr.substring(matchResult.index, matchResult.index+searchValue.length)}</span>
|
||||
{item.titleStr.substr(matchResult.index+searchValue.length)}
|
||||
</span>
|
||||
) : (
|
||||
<span>{item.titleStr}</span>
|
||||
);
|
||||
return (
|
||||
<TreeNode title={title} key={item.key + ""} isLeaf={item.isFile} dataRef={item} className='menuHcNode font-15'>
|
||||
{renderTreeNodes(item.children)}
|
||||
</TreeNode>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const noDataText = adminUrl ? <a href={`${data && data.gitlinkProject.wiki_url}`} target="_blank" style={{color: '#466aff'}}>前往配置</a> : "正在建设中,敬请期待"
|
||||
const noDataText = adminUrl ? <a href={`${data && data.gitlinkProject.wiki_url}`} target="_blank" className='zone_apply_button'>前往配置</a> : "正在建设中,敬请期待"
|
||||
return (
|
||||
<div className="in_pro">
|
||||
<div className="boxmain" style={{ paddingTop: "56px" }}>
|
||||
<p className="in_title mb30">{data && data.sectionHelperTitle}</p>
|
||||
<Spin spinning={loading}>
|
||||
<Spin spinning={loading} wrapperClassName='themeSpin'>
|
||||
{
|
||||
wikiList && (wikiList.length > 0 ? <Box className='zoneHelpBox'>
|
||||
wikiPages && (wikiPages.length > 0 ? <Box className='zoneHelpBox'>
|
||||
{/* wiki目录导航 */}
|
||||
<div className='leftMenuBox mr20'>
|
||||
<div className='leftMenuHC'>
|
||||
<Search
|
||||
allowClear
|
||||
placeholder="输入关键字搜索文件"
|
||||
className="searchHC mb10"
|
||||
onSearch={changeSearchValue}
|
||||
/>
|
||||
<DirectoryTree onSelect={selectTree} expandedKeys={expandedKeys} onExpand={onExpand} autoExpandParent={autoExpandParent} showIcon={false}>
|
||||
{renderTreeNodes(initMenuList)}
|
||||
</DirectoryTree>
|
||||
<TreeByWikiSidebar
|
||||
wikiParams={wikiParams}
|
||||
hasPermission={false}
|
||||
wikiPageInitDetail={wikiPageInitDetail}
|
||||
clickNode={(node)=>{
|
||||
history.push(`/zone/${deptId}/help?wiki=${encodeURIComponent(node.titleStr)}`)
|
||||
}}
|
||||
history={history}
|
||||
hasOpen={false}
|
||||
searchClassName="searchHC mb10"
|
||||
treeNodeClassName="menuHcNode"/>
|
||||
</div>
|
||||
</div>
|
||||
{/* 内容区 */}
|
||||
|
@ -233,12 +175,12 @@ function ProjectSource(props) {
|
|||
<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 className='wikiTitleHC font-20 mb5'>{wikiDetail.title}</div>
|
||||
{wikiDetail.last_commit && <div className='wikiUpdateTimeHC font-15'>更新时间:{wikiDetail.last_commit.author.date || '刚刚'}</div>}
|
||||
</div>
|
||||
{adminUrl && <Button onClick={()=>{wiki && window.open(`${data && data.gitlinkProject.wiki_url}/${wiki.title_sub}/${wiki.key}`)}} className='zone_apply_button' style={{width: '90px', height: '34px'}}>配置内容</Button>}
|
||||
{adminUrl && <Button onClick={()=>{wiki && window.open(`${data && data.gitlinkProject.wiki_url}?wiki=${encodeURIComponent(wikiDetail.title)}`)}} 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}/>}
|
||||
{wikiDetail.content_base64 && <RenderHtml className="wikiContentHC editor-content-panel mt20 imageLayerParent" value={ Base64.decode(wikiDetail.content_base64) } url={history.location}/>}
|
||||
</LongWidth>
|
||||
{wikiContMenu && wikiContMenu !== "<ul></ul>" && <Affix offsetTop={80}>
|
||||
<div id="wikiContMenuBox" className='wikiContMenuBox font-15' dangerouslySetInnerHTML={{ __html: wikiContMenu }}></div>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { getZoneStatistics } from '../../../api';
|
||||
import '../index.scss';
|
||||
|
||||
// 专区简介,文字在左,图在右
|
||||
// statistics: 是否展示统计区域
|
||||
function Introduction({data, statistics=true}) {
|
||||
const {id, firstTitle, introductionContent, introductionImage} = data || {};
|
||||
const label = {
|
||||
communityUserCount: "社区用户",
|
||||
cmsDocVisits: "文章访问数",
|
||||
projectCount: "代码仓库",
|
||||
resourceCount: "社区资源",
|
||||
cmsDocCount: "社区新闻",
|
||||
specialProjectCount: "重大项目",
|
||||
}
|
||||
const [data1, setData1] = useState({});
|
||||
|
||||
useEffect(()=>{
|
||||
id && getZoneStatistics(id).then(res=>{
|
||||
setData1(res.data && res.data.data)
|
||||
})
|
||||
}, [id])
|
||||
|
||||
return <div className='introduction_1_bg'>
|
||||
<div className='introduction_1 width1200 pt50 pb60'>
|
||||
<div className='firstTitle font-bd font-30 mb50 align'>
|
||||
{firstTitle}
|
||||
<span className='firstTitle_back font-34'>ABOUT US</span>
|
||||
</div>
|
||||
<div>
|
||||
{introductionImage && <img src={introductionImage} alt="" width="526px" align="right" hspace="35" vspace="10"/>}
|
||||
{introductionContent && <span dangerouslySetInnerHTML={{ __html: introductionContent }} className='font-16' style={{lineHeight: '40px'}}></span>}
|
||||
</div>
|
||||
{statistics && <div className='df wrap mt50 between'>
|
||||
{Object.keys(label).map(item=>{
|
||||
return <div className='align font-16'>
|
||||
<span className='font-34 color-blue font-bd'>{data1[item]}</span><br/>
|
||||
{label[item]}
|
||||
</div>
|
||||
})}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default Introduction;
|
|
@ -0,0 +1,173 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getDirListById, getSubDocList } from '../../../api';
|
||||
import { Badge, Col, Icon, Row } from 'antd';
|
||||
import dirpng from '../image/new3.png'
|
||||
import new4 from '../image/new4.png';
|
||||
import new5 from '../image/new5.png';
|
||||
import new6 from '../image/new6.png';
|
||||
import new7 from '../image/new7.png';
|
||||
import new8 from '../image/new8.png';
|
||||
import new9 from '../image/new9.png';
|
||||
import new10 from '../image/new10.png';
|
||||
import new11 from '../image/new11.png';
|
||||
import new12 from '../image/new12.png';
|
||||
import new13 from '../image/new13.png';
|
||||
import '../index.scss';
|
||||
import Nodata from '../../../../Nodata';
|
||||
|
||||
function News({data, subTitle, firstDirIntro, secondDirIntro}) {
|
||||
const {firstTitle, key, homepageCmsTitle, id} = data || {};
|
||||
const logoByName = {
|
||||
"智慧城市OS": new4,
|
||||
"智慧交通OS": new5,
|
||||
"智慧建设OS": new6,
|
||||
"机器人OS": new7,
|
||||
"智能家居OS": new8,
|
||||
"桌面OS": new9,
|
||||
"服务器OS": new10,
|
||||
"移动智能终端OS": new11,
|
||||
"嵌入式及物联网OS": new12,
|
||||
"云OS": new13
|
||||
}
|
||||
const [dirList, setDirList] = useState([]);
|
||||
const firstDir = dirList[0];
|
||||
const secondDir = dirList[1];
|
||||
const dirs = dirList.slice(2)
|
||||
|
||||
// const rows = Math.ceil(dirs.length / 6);
|
||||
const [docListByFirstDir, setDocListByFirstDir] = useState([]);
|
||||
const [docListBySecondDir, setDocListBySecondDir] = useState([]);
|
||||
const [docListByDir, setDocListByDir] = useState([]);
|
||||
const [activeDirId, setActiveDirId] = useState(undefined);
|
||||
const [total, setTotal] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
id && getDirListById(id).then(res=>{
|
||||
if(res){
|
||||
const rows = res.data.rows
|
||||
setDirList(rows);
|
||||
// 获取第一个栏目的第一条文章
|
||||
rows[0] && getDocById(rows[0].id, 1, (data)=>{
|
||||
setDocListByFirstDir(data)
|
||||
})
|
||||
// 获取第2个栏目的第一条文章
|
||||
rows[1] && getDocById(rows[1].id, 8, (data)=>{
|
||||
setDocListBySecondDir(data)
|
||||
})
|
||||
rows[2] && setActiveDirId(rows[2].id)
|
||||
}
|
||||
})
|
||||
}, [id])
|
||||
|
||||
useEffect(()=>{
|
||||
activeDirId && getDocById(activeDirId, 4, (data)=>{
|
||||
setDocListByDir(data)
|
||||
}, (data)=>{setTotal(data)})
|
||||
}, [activeDirId])
|
||||
|
||||
// 根据招聘专栏的id获取其栏目下的招聘文章
|
||||
function getDocById(dirId, pageSize=10, setData, setTotal1){
|
||||
getSubDocList(dirId,{pageSize:pageSize,pageNum:1,auditStatus:1}).then(result=>{
|
||||
if(result && result.data.rows){
|
||||
let rows = result.data.rows;
|
||||
setData(rows);
|
||||
setTotal1 && setTotal1(result.data.total)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const renderItems = () => {
|
||||
const itemsPerRow = 6;
|
||||
let rendered = [];
|
||||
let currentRow = [];
|
||||
|
||||
dirs.forEach((item, index) => {
|
||||
|
||||
// 添加项目到当前行
|
||||
currentRow.push(
|
||||
<div key={item.id} className="center pointer mb20 n_1_dir" onClick={()=>{setActiveDirId(item.id)}}>
|
||||
<img src={logoByName[item.name] || new4} width={86}/>
|
||||
<p className={activeDirId === item.id && "activeDir pb3"}>{item.name}</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 如果达到每行项目数或是最后一个项目
|
||||
if ((index + 1) % itemsPerRow === 0 || index === dirs.length - 1) {
|
||||
// 将当前行添加到渲染列表
|
||||
rendered = rendered.concat(currentRow);
|
||||
|
||||
if (currentRow.some(item => item.key === activeDirId?.toString())) {
|
||||
rendered.push(
|
||||
<div className=' mt30 pl15 pr15' key="doc" style={{flex: "0 0 100%", overflow: 'hidden'}}>
|
||||
<div className='df wrap between'>
|
||||
{docListByDir.map(item=>{
|
||||
return <div className='docDetailByNews_1 mb20'>
|
||||
<Link to={`/zone/${key}/newdetail/${item.id}`} className="font-15">
|
||||
<Badge color="#466AFF"/>
|
||||
<span className='pl5'>{item.name}</span>
|
||||
</Link>
|
||||
<p className='task-hide color777'>{item.summary}</p>
|
||||
</div>
|
||||
})}
|
||||
{!docListByDir.length && <div className='mb20 pl40 font-15'>暂无数据~</div>}
|
||||
</div>
|
||||
{total > 4 && <div className='align'><Link to={`/zone/uos/news/${activeDirId}`} onClick={()=>{window.scrollTo(0,450)}} className="color-blue font-15">查看更多<i className='iconfont icon-jiantou1 ml10 font-12'></i></Link></div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// 重置当前行
|
||||
currentRow = [];
|
||||
}
|
||||
});
|
||||
return rendered;
|
||||
};
|
||||
|
||||
return <div className='news_1_bg'>
|
||||
<div className='news_1 width1200 pt50 pb60'>
|
||||
<p className='font-bd font-30 mb15 align task-hide'>{homepageCmsTitle}</p>
|
||||
<p className='font-16 align color212 mb50'>{subTitle}</p>
|
||||
<div className='df mb80'>
|
||||
{/* 第一个顺序栏目 */}
|
||||
{firstDir && <div className='firstDir clearfix'>
|
||||
<p className='font-16 task-hide'>
|
||||
{firstDir.name}
|
||||
<Link style={{color: 'white'}} className='fr font-15' to={`/zone/uos/news/${firstDir.id}`}>更多<Icon type="arrow-right" className="ml5"/></Link>
|
||||
</p>
|
||||
<div style={{fontFamily:"FangSong", height: 200}} className='font-24 ml85 mr80 flexCenter font-bd'>{firstDirIntro}</div>
|
||||
{docListByFirstDir[0] && <div className='pt10 pb10 pl20 docByFirstDir task-hide'>
|
||||
<Badge color="white" className='mr10'/>
|
||||
<Link to={`/zone/${key}/newdetail/${docListByFirstDir[0].id}`} className="font-15" style={{color: 'white'}}>{docListByFirstDir[0].name}</Link>
|
||||
</div>}
|
||||
</div>}
|
||||
{/* 第二个顺序栏目 */}
|
||||
{secondDir && <div className='secondDir flex1 ml30'>
|
||||
<div className='flexCenter pt15 pb15' style={{backgroundColor: '#F5F5F5'}}>
|
||||
<div className='img-box ml20 mr20'>
|
||||
<img src={dirpng}/>
|
||||
</div>
|
||||
<div>
|
||||
<p className='font-17 font-bd task-hide'>{secondDir.name}</p>
|
||||
<p className='color627'>{secondDirIntro}</p>
|
||||
</div>
|
||||
</div>
|
||||
<Row className='docBySecondDir pl25 pr30 pt10 pb30 mr0' type="flex" style={{alignContent: "flex-start", marginLeft: 0}} gutter={16}>
|
||||
{docListBySecondDir.map(item=>{
|
||||
return <Col span={12} className='mt15 task-hide pr15 font-15'>
|
||||
<Link to={`/zone/${key}/newdetail/${item.id}`}>
|
||||
<Badge color="#466AFF" className='mr10'/>
|
||||
{item.name}
|
||||
</Link>
|
||||
</Col>
|
||||
})}
|
||||
{docListBySecondDir && !docListBySecondDir.length && <div style={{margin: '0 auto', maxHeight: '230px'}}><Nodata small _html="暂无数据"/></div>}
|
||||
</Row>
|
||||
</div>}
|
||||
</div>
|
||||
<div className='df wrap backWhite pt15 pb15 pl10 pr10'>
|
||||
{renderItems()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default News;
|
|
@ -0,0 +1,52 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { getPartnerList } from '../../../api';
|
||||
import '../index.scss';
|
||||
|
||||
function Partner({data}) {
|
||||
const {id, key, homepagePartnersTitle} = data || {};
|
||||
const [ list , setList ] = useState([]);
|
||||
|
||||
useEffect(()=>{
|
||||
id && getPartnerList(id).then(response=>{
|
||||
if(response && response.data){
|
||||
const rows = response.data.rows;
|
||||
setList(rows[0] && rows[0].zonePartnersList);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
},[id])
|
||||
|
||||
const rows = Math.ceil(list.length / 11); // 每两行为一个周期,共11个格子
|
||||
|
||||
const gridItems = [];
|
||||
|
||||
const item = (item, index) => (
|
||||
<div key={index} className={`partner_1_logo flexCenter align ${item.link && 'pointer'}`} onClick={()=>{item.link && window.open(item.link)}}>
|
||||
<img src={item.logo} alt=''/>
|
||||
</div>
|
||||
)
|
||||
|
||||
// 将items数组分成每两行为一个周期的数组
|
||||
for (let i = 0; i < rows; i++) {
|
||||
const rowItems = list.slice(i * 11, i * 11 + 11);
|
||||
|
||||
gridItems.push(
|
||||
<div key={i} className='logoList'>
|
||||
{rowItems.slice(0, 6).map(item)}
|
||||
</div>
|
||||
);
|
||||
|
||||
gridItems.push(
|
||||
<div key={i + rows} className='logoList' style={{margin: '20px auto' }}>
|
||||
{rowItems.slice(6, 11).map(item)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className='partner_1_bg'>
|
||||
<div className='partner_1 width1200 pt50 pb60'>
|
||||
<p className='font-bd font-30 mb10 task-hide center mb50'>{homepagePartnersTitle}</p>
|
||||
<div>{gridItems}</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default Partner;
|
|
@ -0,0 +1,117 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import '../index.scss';
|
||||
import { getProjectListByScore, getProjectsTypeLists } from '../../../api';
|
||||
import { Carousel, Divider, Spin } from 'antd';
|
||||
import Nodata from '../../../../Nodata';
|
||||
|
||||
function Project({ data, subTitle }) {
|
||||
const { id, homepageProjectTitle } = data || {};
|
||||
const [typeList, setTypeList] = useState([]);
|
||||
const [typeId, setTypeId] = useState(undefined);
|
||||
const [lists, setLists] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const pages = [];
|
||||
|
||||
useEffect(() => {
|
||||
id && getProjectsTypeLists(id).then(result => {
|
||||
if (result) {
|
||||
const rows = result.data.rows;
|
||||
rows[0] && setTypeId(rows[0].id)
|
||||
setTypeList(rows);
|
||||
}
|
||||
}).catch(() => { })
|
||||
}, [id])
|
||||
|
||||
useEffect(() => {
|
||||
if (typeId) {
|
||||
setLoading(true);
|
||||
getProjectListByScore(id, {
|
||||
pageNum: page,
|
||||
pageSize: 6,
|
||||
projectTypeId: typeId
|
||||
}).then(result => {
|
||||
if (result) {
|
||||
setLists(result.data.rows);
|
||||
setTotal(result.data.total);
|
||||
setLoading(false);
|
||||
}
|
||||
}).catch(() => { })
|
||||
}
|
||||
}, [id, typeId, page])
|
||||
|
||||
const listPerPage = 6;
|
||||
for (let i = 0; i < Math.ceil(total / listPerPage); i++) {
|
||||
const start = i * listPerPage;
|
||||
const end = start + listPerPage;
|
||||
pages.push(lists.slice(start, end));
|
||||
}
|
||||
|
||||
return <div className='project_1_bg'>
|
||||
<div className='project_1 width1200 pt50 pb60'>
|
||||
<p className='font-bd font-30 mb15 align task-hide'>{homepageProjectTitle}</p>
|
||||
<p className='font-16 align color212 mb30'>{subTitle}</p>
|
||||
<div className='flexCenter align'>
|
||||
{typeList.slice(0, 3).map((item, index) => {
|
||||
return <div className={`proTypeBox flexCenter font-17 mr30 pointer ${typeId === item.id && "active"}`} onClick={() => { setTypeId(item.id); setPage(1) }}>
|
||||
<span className={`icon${index} mr5`}></span>
|
||||
{item.name}
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
<Spin spinning={loading}>
|
||||
<Carousel className='zone_1_carousel' afterChange={(current)=>{setLoading(true);setPage(current+1)}}>
|
||||
{pages.map((page1, index) => (
|
||||
<div key={index}>
|
||||
<div className='df wrap between mt60 pl10 pr10 mb25'>
|
||||
{lists.map((i, index) => {
|
||||
const { extra: { commitCount, contributorsCount, lastWeekScore, scoreChange } } = i || {}
|
||||
const order = page >= 2 ? (page-1)*6+index+1 : index+1;
|
||||
return <div key={`index${i.id}`} className={`proDetailByProject_1 padding20-30 backWhite mb30`}>
|
||||
<a onClick={() => window.open(i.projectURL)}>
|
||||
<span className={`mr10 font-22 p_1_order align p_1_order${order}`}>{order}</span>
|
||||
<span className='font-bd font-17'>{i.projectProperties && i.projectProperties.name}</span>
|
||||
</a>
|
||||
<div className="pd_desc task-hide-2 mt15">
|
||||
{i.projectProperties.description || "暂无描述"}
|
||||
</div>
|
||||
<div style={{ minHeight: 34 }}>
|
||||
{
|
||||
i.projectProperties && i.projectProperties.topics &&
|
||||
<ul className="pd_tag pb10">
|
||||
{
|
||||
i.projectProperties.topics.split(",").map(t => {
|
||||
return (
|
||||
<li>{t}</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
<p className='flexCenter between'>
|
||||
<div>
|
||||
<span className='color6B7 mr5'>开发者</span>{contributorsCount || 0}
|
||||
<Divider type="vertical" style={{ margin: '0 15px' }} />
|
||||
<span className='color6B7 mr5'>历史提交总量</span>{commitCount || 0}
|
||||
<Divider type="vertical" style={{ margin: '0 15px' }} />
|
||||
<span className='color6B7 mr5'>活跃度</span>{lastWeekScore || 0}
|
||||
</div>
|
||||
{!!scoreChange && <span className='font-18 font-bd fr'>
|
||||
<span className='mr10' style={{ fontFamily: "YouSheBiaoTiHei", color: '#495BA2' }}>较上周</span>
|
||||
<span className={scoreChange > 0 ? 'color-red' : "color-green"}>{scoreChange > 0 ? `+${scoreChange}` : scoreChange}</span>
|
||||
</span>}
|
||||
</p>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
{!loading && lists.length === 0 && <Nodata _html="暂无数据" />}
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default Project;
|
|
@ -0,0 +1,89 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { getSourceList, getSourceZoneList } from '../../../api';
|
||||
import png from '../image/source2.png'
|
||||
import { Spin } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Nodata from '../../../../Nodata';
|
||||
import '../index.scss';
|
||||
|
||||
function Source({data, subTitle}) {
|
||||
const {id, key, homepageResourceTitle="资源发布"} = data || {};
|
||||
const [ chooseZoneId , setChooseZoneId ] = useState(undefined);
|
||||
const [ zoneList , setZoneList ] = useState([]);
|
||||
const [ sourceList , setSourceList ] = useState([]);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
|
||||
useEffect(()=>{
|
||||
id && getSourceZoneList(id).then(response=>{
|
||||
if(response && response.data){
|
||||
const rows = response.data.rows;
|
||||
rows[0] && setChooseZoneId(rows[0].id)
|
||||
setZoneList(rows);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
},[id])
|
||||
|
||||
useEffect(()=>{
|
||||
if(chooseZoneId){
|
||||
setIsSpin(true);
|
||||
getSourceList({
|
||||
id,pageSize:4,pageNum:1,domainId:chooseZoneId
|
||||
}).then(response=>{
|
||||
if(response){
|
||||
setSourceList(response.data.rows);
|
||||
setTotal(response.data.total);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
},[chooseZoneId])
|
||||
|
||||
return <div className='source_1_bg'>
|
||||
<div className='source_1 width1200 pt50 pb60 flexCenter'>
|
||||
<div className='mr50' style={{width: '37%'}}>
|
||||
<p className='font-bd font-30 mb10 task-hide'>{homepageResourceTitle}</p>
|
||||
<p className='font-15 color212 mb20'>{subTitle}</p>
|
||||
<p className='mb30'><a href={`/zone/${key}/source`} className='color-blue'>前往资源中心 {'>'} </a></p>
|
||||
{zoneList.slice(0,2).map(item=>{
|
||||
return <div className={`pointer s_1_zone flexCenter between font-18 mt20 ${chooseZoneId === item.id && "active"}`} onClick={()=>{setChooseZoneId(item.id);}}>
|
||||
{item.name}
|
||||
<img src={png} width="74px" alt=''/>
|
||||
<img src={require('../image/source3.png')} width="53px" alt='' className='active_1'/>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
<div className='flex1'>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className='df wrap between'>
|
||||
{sourceList.map(i=>{
|
||||
const time = i.updateTime || i.createTime
|
||||
return <div className='s_1_souce mr25 mt30'>
|
||||
<div className='flexCenter between m15' style={{minHeight: 90}}>
|
||||
<div style={{width: '0'}} className='flex1'>
|
||||
<p className='task-hide'><Link to={`/zone/${key}/source/${i.id}`} className=" font-17 font-bd">{i.name}</Link></p>
|
||||
<p className="task-hide-2 color212">{i.summary}</p>
|
||||
</div>
|
||||
<img src={require("../image/new3.png")} width={48} className='ml10'/>
|
||||
</div>
|
||||
<div className='flexCenter between'>
|
||||
<span className='color848'>{time && time.split(" ")[0].replace(/-/g, '.')}</span>
|
||||
<Link className='color-blue' to={`/zone/${key}/source/${i.id}`}>
|
||||
<img src={require("../image/source4.png")} width={25} className='normalImg'/>
|
||||
<img src={require("../image/source5.png")} width={25} className='hoverImg'/>
|
||||
<span className='pl5'>下载</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
<div style={{marginLeft: 150}}>
|
||||
{!isSpin && !sourceList.length && <Nodata _html="暂无数据"/>}
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default Source;
|
|
@ -0,0 +1,193 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { getSpecialProjectDetail, getSpecialProjectList, getSpecialProjectTypeList } from '../../../api';
|
||||
import { Col, Divider, Row, Tag } from 'antd';
|
||||
import Nodata from '../../../../Nodata';
|
||||
import '../index.scss';
|
||||
|
||||
function SpecialProjects({data, subTitle}) {
|
||||
const {key, homepageSpecialProjectTitle, id} = data || {};
|
||||
const [typeList, setTypeList] = useState([]);
|
||||
const [typeId , setTypeId] = useState(undefined);
|
||||
const [projectList, setProjectList] = useState([]);
|
||||
const [selectedItem, setSelectedItem] = useState(null);
|
||||
const [projectDetail, setProjectDetail] = useState({});
|
||||
|
||||
useEffect(()=>{
|
||||
id && getSpecialProjectTypeList(id, {
|
||||
pageNum: 1,
|
||||
pageSize: 4,
|
||||
}).then(res=>{
|
||||
if(res){
|
||||
const rows = res.data.rows;
|
||||
rows[0] && setTypeId(rows[0].id)
|
||||
setTypeList(rows);
|
||||
}
|
||||
})
|
||||
}, [id])
|
||||
|
||||
useEffect(()=>{
|
||||
typeId && getSpecialProjectList(id, typeId).then(res=>{
|
||||
if(res){
|
||||
const rows = res.data.rows;
|
||||
// rows[0] && setTypeId(rows[0].id)
|
||||
setProjectList(rows);
|
||||
}
|
||||
})
|
||||
}, [typeId])
|
||||
|
||||
useEffect(()=>{
|
||||
selectedItem && getSpecialProjectDetail(selectedItem).then(res=>{
|
||||
if(res){
|
||||
const rows = res.data.rows;
|
||||
// 根据类型分类
|
||||
const rowsByType = rows.reduce((acc, item) => {
|
||||
// 如果acc中没有当前item.type的数组,则创建一个
|
||||
if (!acc[item.type]) {
|
||||
acc[item.type] = [];
|
||||
}
|
||||
// 将当前item添加到对应type的数组中
|
||||
acc[item.type].push(item);
|
||||
return acc;
|
||||
}, {});
|
||||
setProjectDetail({
|
||||
detail: projectList.find(item => item.id === selectedItem),
|
||||
...rowsByType
|
||||
});
|
||||
}
|
||||
})
|
||||
}, [selectedItem])
|
||||
|
||||
const itemsPerRow = 3;
|
||||
|
||||
const handleItemClick = (id) => {
|
||||
setSelectedItem(selectedItem === id ? null : id);
|
||||
};
|
||||
|
||||
const list = (title, table1, table2, list)=>{
|
||||
return !!list.length && <React.Fragment>
|
||||
<p className='leftBox font-16 font-bd'>{title}</p>
|
||||
<Divider dashed className="margin0-20"/>
|
||||
<Row className='s_p_rowList mb30 font-15'>
|
||||
<Col span={14} className='s_p_rowList_t font-bd'>{table1}</Col>
|
||||
<Col span={10} className='s_p_rowList_t font-bd'>{table2}</Col>
|
||||
{list.map(item=>{
|
||||
const {author} = item;
|
||||
const detail = item.relevancyObject;
|
||||
const {name, createUser, id} = detail
|
||||
return <React.Fragment>
|
||||
<Col span={14} className='task-hide'>
|
||||
<a href={`/zone/${key}/source/${id}`}>
|
||||
{title === "论文" ? <img src={require('../image/s_project1.png')} width={24} className='mr10'/> : title === "专利" ? <img src={require('../image/s_project2.png')} width={24} className='mr10'/> : <img src={createUser.avatar}/>}
|
||||
{name}
|
||||
</a>
|
||||
</Col>
|
||||
<Col span={10} className='task-hide'>{author}</Col>
|
||||
</React.Fragment>
|
||||
})}
|
||||
</Row>
|
||||
{!list.length && <Nodata _html="暂无数据" small/>}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
const list2 = (title, table1, table2, list)=>{
|
||||
return !!list.length && <React.Fragment>
|
||||
<p className='leftBox font-16 font-bd'>{title}</p>
|
||||
<Divider dashed className="margin0-20"/>
|
||||
<Row className='s_p_rowList mb30 font-15'>
|
||||
<Col span={24} className='s_p_rowList_t font-bd'>{table1}</Col>
|
||||
{list.map(item=>{
|
||||
const {relevancyObject:{projectURL, projectProperties:{name, authorImageUrl}}} = item;
|
||||
return <React.Fragment>
|
||||
<Col span={24}>
|
||||
<a href={projectURL}>
|
||||
<img src={authorImageUrl} width={24} className='mr10' style={{borderRadius: '50%'}}/>
|
||||
{name}
|
||||
</a>
|
||||
</Col>
|
||||
</React.Fragment>
|
||||
})}
|
||||
</Row>
|
||||
{!list.length && <Nodata _html="暂无数据" small/>}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
const renderItems = () => {
|
||||
let rendered = [];
|
||||
let currentRow = [];
|
||||
|
||||
projectList.forEach((item, index) => {
|
||||
// 添加项目到当前行
|
||||
currentRow.push(
|
||||
<div
|
||||
key={item.id}
|
||||
className={`s_p_detail ${selectedItem === item.id ? 'active' : ''}`}
|
||||
onClick={() => handleItemClick(item.id)}
|
||||
>
|
||||
<span className={`font-bd font-22 s_p_d_order align s_p_d_order${index+1}`}>{index+1}</span>
|
||||
<div className='font-bd font-17 task-hide-2 mb5'>{item.name}</div>
|
||||
<div className='task-hide-2 color6B7' style={{minHeight: '56px'}}>摘要:{item.description}</div>
|
||||
<p style={{color: '#75798A'}} className='mt3'><i className='iconfont icon-chengyuan2 font-15 mr5'></i>{item.projectLeader}</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
// 如果达到每行项目数或是最后一个项目
|
||||
if ((index + 1) % itemsPerRow === 0 || index === projectList.length - 1) {
|
||||
// 将当前行添加到渲染列表
|
||||
rendered = rendered.concat(currentRow);
|
||||
|
||||
// 如果当前行包含选中项,添加详情面板
|
||||
if (currentRow.some(item => item.key === selectedItem?.toString())) {
|
||||
|
||||
const {detail, PAPER=[], PATENT=[], PROJECT=[]} = projectDetail;
|
||||
const {name, projectLeader, awards, description} = detail || {};
|
||||
rendered.push(
|
||||
<div key={`details-${selectedItem}`} className="item-details">
|
||||
<div className="details-content">
|
||||
<div className='s_p_head'>
|
||||
<Tag color='#466AFF' style={{padding: '0 2px'}}>项目</Tag><span className='font-20 font-bd'>{name}</span>
|
||||
<p className='mt10 font-15 pb5'>项目负责人:<span className='color212'>{projectLeader}</span></p>
|
||||
<p className='font-15 pb5'>奖项:<span className='color-blue'>{awards}</span></p>
|
||||
<p className='font-15 pb5'>摘要:<span className='color212'>{description}</span></p>
|
||||
</div>
|
||||
<div style={{padding: '22px 33px'}}>
|
||||
{list("论文", "论文标题", "作者", PAPER)}
|
||||
{list("专利", "专利标题", "作者", PATENT)}
|
||||
{list2("开源项目", "项目名称", "参与者", PROJECT)}
|
||||
{!PAPER.length && !PATENT.length && !PROJECT.length && <Nodata _html="暂无数据" small/>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 重置当前行
|
||||
currentRow = [];
|
||||
}
|
||||
});
|
||||
return rendered;
|
||||
};
|
||||
|
||||
return <div className='specialProjects_1_bg'>
|
||||
<div className='specialProjects_1 width1200 pt50 pb60'>
|
||||
<p className='font-bd font-30 mb15 align task-hide'>{homepageSpecialProjectTitle}</p>
|
||||
<p className='font-16 align color212 mb50'>{subTitle}</p>
|
||||
<div className='flexCenter align mb50'>
|
||||
{typeList.map((item, index)=>{
|
||||
return <div className={`proTypeBox flexCenter mr30 color212 pointer pl5 pr5 ${typeId === item.id && "active"}`} onClick={()=>{setTypeId(item.id)}}>
|
||||
<span className={`s_p_order font-25 mr10 color-blue`}>
|
||||
<span className='s_p_order_1'>{index < 9 ? `0${index+1}` : index+1}</span>
|
||||
<span className={`s_p_order_icon s_p_order_icon${index}`}></span>
|
||||
<img src={require('../image/s_project3.png')} width="18"/>
|
||||
</span>
|
||||
<span className='font-17 font-bd task-hide'>{item.name}</span>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
<div className='df wrap between'>
|
||||
{renderItems()}
|
||||
<div style={{margin: '0 auto'}}>{!projectList.length && <Nodata _html="暂无数据"/>}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default SpecialProjects;
|
|
@ -0,0 +1,68 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { getVIPLists } from '../../../api';
|
||||
import { Carousel } from 'antd';
|
||||
import '../index.scss';
|
||||
import Nodata from '../../../../Nodata';
|
||||
|
||||
function Member({data, subTitle}) {
|
||||
const {id, key, homepageMemberTitle} = data || {};
|
||||
const [typeList, setTypeList] = useState([]);
|
||||
const [typeId, setTypeId] = useState(undefined);
|
||||
const [ vipsMap , setVipsMap ] = useState({});
|
||||
const list = vipsMap[typeId] || []
|
||||
const pages = [];
|
||||
|
||||
useEffect(()=>{
|
||||
id && getVIPLists(id).then(response=>{
|
||||
if(response && response.data){
|
||||
const rows = response.data.rows;
|
||||
const vips = {}
|
||||
const types = rows.map(item=>{
|
||||
const {id, typeName, zoneMemberList} = item
|
||||
vips[id] = zoneMemberList;
|
||||
return {id, typeName}
|
||||
})
|
||||
types[0] && setTypeId(types[0].id)
|
||||
setTypeList(types);
|
||||
setVipsMap(vips);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
},[id])
|
||||
|
||||
const listPerPage = 4;
|
||||
for (let i = 0; i < Math.ceil(list.length / listPerPage); i++) {
|
||||
const start = i * listPerPage;
|
||||
const end = start + listPerPage;
|
||||
pages.push(list.slice(start, end));
|
||||
}
|
||||
|
||||
return <div className='vip_1_bg backWhite'>
|
||||
<div className='vip_1 width1200 pt50 pb60'>
|
||||
<p className='font-bd font-30 mb15 task-hide center'>{homepageMemberTitle}</p>
|
||||
<div className='mb60 center'>
|
||||
{typeList.map(item=>{
|
||||
return <a className={`${typeId === item.id && "active"} v_type pb10 mr40 font-16`} onClick={()=>{setTypeId(item.id)}}>{item.typeName}</a>
|
||||
})}
|
||||
</div>
|
||||
<Carousel className='zone_1_carousel'>
|
||||
{pages.map((page, index) => (
|
||||
<div>
|
||||
<div key={index} className='df wrap between mb40'>
|
||||
{page.map((item) => (
|
||||
<div key={item.id} className="flexCenter mb30" style={{width: '46.6%'}}>
|
||||
<img src={item.imageUrl} className='image_v_1 mr50'/>
|
||||
<div className='flex1'>
|
||||
<p className="font-bd font-18 pb25 task-hide">{item.name}</p>
|
||||
<div className='intro_v_1 font-15'>{item.introduction || "暂无描述"}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
{list && !list.length && <Nodata _html="暂无数据" small/>}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default Member;
|
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 729 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 194 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 555 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 2.5 MiB |
After Width: | Height: | Size: 799 B |
After Width: | Height: | Size: 823 B |
After Width: | Height: | Size: 981 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 357 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 876 B |
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,462 @@
|
|||
.width1200{
|
||||
width: 1200px;
|
||||
margin:0px auto;
|
||||
}
|
||||
.align{
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.wrap{
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.between{
|
||||
justify-content: space-between
|
||||
}
|
||||
.color-theme{
|
||||
color: $primary-color;
|
||||
}
|
||||
.color212{
|
||||
color: #212F54;
|
||||
}
|
||||
.color627{
|
||||
color: #62729D;
|
||||
}
|
||||
.color6B7{
|
||||
color: #6B707C;
|
||||
}
|
||||
.color777{
|
||||
color: #777E99
|
||||
}
|
||||
.color848{
|
||||
color: #848992;
|
||||
}
|
||||
.backWhite{
|
||||
background-color: white;
|
||||
}
|
||||
.pointer{
|
||||
cursor: pointer;
|
||||
}
|
||||
.zone_1_carousel{
|
||||
.slick-dots li button:before{
|
||||
font-size: 12px;
|
||||
}
|
||||
.slick-dots li.slick-active button:before, .slick-dots li button:before{
|
||||
color: $primary-color;
|
||||
opacity: 1;
|
||||
}
|
||||
.slick-dots li button{
|
||||
background: none !important;
|
||||
}
|
||||
}
|
||||
.introduction_1_bg{
|
||||
background-image: url('./image/intro1.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.introduction_1{
|
||||
.firstTitle{
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
.firstTitle_back{
|
||||
position: absolute;
|
||||
top: 90%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: -1;
|
||||
color: #D9D9D9;
|
||||
}
|
||||
}
|
||||
}
|
||||
.news_1_bg{
|
||||
background-image: url('./image/new1.png');
|
||||
background-size: 100% 100%;
|
||||
.firstDir{
|
||||
background-image: url('./image/new2.png');
|
||||
background-size: 100% 100%;
|
||||
color: white;
|
||||
width: 476px;
|
||||
position: relative;
|
||||
&>p{
|
||||
padding: 10px 20px;
|
||||
background: linear-gradient( 101deg, rgba(255,255,255,0.21) 0%, rgba(255,255,255,0) 100%);
|
||||
}
|
||||
.docByFirstDir{
|
||||
background: linear-gradient( 180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.36) 49%, rgba(0,0,0,0.6) 100%);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.secondDir{
|
||||
border-top: 8px solid $primary-color;
|
||||
.img-box{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: #FFFFFF;
|
||||
img{
|
||||
width: 80%;
|
||||
margin: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.docBySecondDir{
|
||||
background: #FFFFFF;
|
||||
min-height: 230px;
|
||||
.none_panels{
|
||||
min-height: 205px;
|
||||
}
|
||||
}
|
||||
.docDetailByNews_1{
|
||||
width: 48%;
|
||||
background-color: #F8F8F8;
|
||||
padding: 20px 30px;
|
||||
&:hover{
|
||||
background-color: #F1F4FF;
|
||||
}
|
||||
}
|
||||
.n_1_dir{
|
||||
width: 195px;
|
||||
}
|
||||
}
|
||||
|
||||
.news_1_bg .activeDir, .vip_1_bg .v_type.active{
|
||||
position: relative;
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: $primary-color;
|
||||
width: 30%;
|
||||
height: 4px;
|
||||
bottom: -8px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
.project_1_bg{
|
||||
.proDetailByProject_1{
|
||||
flex: 0 0 48%;
|
||||
border-radius: 6px;
|
||||
&:hover{
|
||||
box-shadow: 0px 0px 10px 1px rgba(28,48,175,0.41);
|
||||
}
|
||||
&>a{
|
||||
color: #181818;
|
||||
&:hover{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
.pd_desc{
|
||||
min-height: 55px;
|
||||
color: #6B707C;
|
||||
}
|
||||
.pd_tag{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
li{
|
||||
height:24px;
|
||||
line-height:24px;
|
||||
background-color:var(--tag-back);
|
||||
border-radius:2px;
|
||||
margin-right: 12px;
|
||||
color: var(--primary-color);
|
||||
font-size:13px;
|
||||
padding:0px 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.p_1_order{
|
||||
display: inline-block;
|
||||
width: 36px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
border-radius: 5px;
|
||||
background-color: #485BA7;
|
||||
font-family: "YouSheBiaoTiHei";
|
||||
color: white;
|
||||
}
|
||||
.p_1_order1{
|
||||
background: linear-gradient( 94deg, #FF0000 0%, #FF6B00 100%);
|
||||
}
|
||||
.p_1_order2{
|
||||
background: linear-gradient( 94deg, #FF8000 0%, #FF9244 100%);
|
||||
}
|
||||
.p_1_order3{
|
||||
background: linear-gradient( 94deg, #FFB300 0%, #FFC400 100%);
|
||||
}
|
||||
}
|
||||
.project_1_bg .proTypeBox, .specialProjects_1_bg .proTypeBox{
|
||||
width: 280px;
|
||||
height: 63px;
|
||||
background: #F5F6F7;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #8DA8D7;
|
||||
color: #212F54;
|
||||
justify-content: center;
|
||||
&.active{
|
||||
background-image: url('./image/proTypeBack.png');
|
||||
background-size: 100% 100%;
|
||||
border: none;
|
||||
color: white;
|
||||
.icon0{
|
||||
background-image: url('./image/proType1_active.png');
|
||||
}
|
||||
.icon1{
|
||||
background-image: url('./image/proType2_active.png');
|
||||
}
|
||||
.icon2{
|
||||
background-image: url('./image/proType3_active.png');
|
||||
}
|
||||
.s_p_order_1, .s_p_order>img{
|
||||
display: none;
|
||||
}
|
||||
.s_p_order_icon{
|
||||
margin-top: 18px;
|
||||
display: inline-block;
|
||||
background-image: url('./image/s_project4.png');
|
||||
}
|
||||
.s_p_order_icon1{
|
||||
background-image: url('./image/s_project5.png');
|
||||
}
|
||||
.s_p_order_icon2{
|
||||
background-image: url('./image/s_project6.png');
|
||||
}
|
||||
.s_p_order_icon3{
|
||||
background-image: url('./image/s_project7.png');
|
||||
}
|
||||
}
|
||||
.icon1, .s_p_order_icon, .icon0, .icon2{
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.icon0{
|
||||
width: 19px;
|
||||
height: 18px;
|
||||
background-image: url('./image/proType1.png');
|
||||
}
|
||||
.icon1{
|
||||
background-image: url('./image/proType2.png');
|
||||
}
|
||||
.icon2{
|
||||
width: 25px;
|
||||
height: 19px;
|
||||
background-image: url('./image/proType3.png');
|
||||
}
|
||||
|
||||
}
|
||||
.source_1_bg{
|
||||
background-color: white;
|
||||
background-image: url('./image/source1.png');
|
||||
background-size: 100% 100%;
|
||||
.s_1_zone{
|
||||
width: 80%;
|
||||
padding: 5px 40px 5px 30px;
|
||||
background: #F4F5F8;
|
||||
box-shadow: 0px 0px 6px 1px #F0F0F0;
|
||||
border-radius: 6px;
|
||||
border: 2px solid #FFFFFF;
|
||||
position: relative;
|
||||
.active_1{
|
||||
display: none;
|
||||
}
|
||||
&.active{
|
||||
&::before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 6px;
|
||||
height: 32px;
|
||||
background-color: #0052D9;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.active_1{
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.s_1_souce{
|
||||
padding: 10px 25px 20px 25px;
|
||||
width: 325px;
|
||||
background: #FCFCFC;
|
||||
border-radius: 6px 6px 6px 6px;
|
||||
border: 1px solid #E9E9E9;
|
||||
&:hover{
|
||||
background: linear-gradient( 94deg, #2A4AD0 0%, #2B76D8 100%);
|
||||
box-shadow: 0px 0px 10px 1px rgba(28,48,175,0.08);
|
||||
a, p, div, span{
|
||||
color: white !important;
|
||||
}
|
||||
.hoverImg{
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.hoverImg, &:hover .normalImg{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.partner_1_bg{
|
||||
background: #F2F4F8;
|
||||
.partner_1_logo{
|
||||
width: 170px;
|
||||
height: 70px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 15px 1px rgba(28,48,175,0.08);
|
||||
border-radius: 8px 8px 8px 8px;
|
||||
&>img{
|
||||
max-width: 90%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
.logoList{
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
justify-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.vip_1_bg{
|
||||
.v_type{
|
||||
color: #212F54;
|
||||
&.active{
|
||||
color: $primary-color;
|
||||
}
|
||||
&.active::after{
|
||||
width: 75%;
|
||||
height: 2px;
|
||||
bottom: -4px;
|
||||
}
|
||||
}
|
||||
.intro_v_1{
|
||||
background-color: #F5F7FA;
|
||||
padding: 15px;
|
||||
min-height: 90px;
|
||||
}
|
||||
.image_v_1{
|
||||
width: 180px;
|
||||
height: 150px;
|
||||
object-fit: scale-down;
|
||||
}
|
||||
}
|
||||
.specialProjects_1_bg{
|
||||
background-image: url('./image/s_project.png');
|
||||
background-size: 100% 100%;
|
||||
.s_p_detail+div:not(.item-details){
|
||||
flex: 0 0 calc(33.333% - 20px);
|
||||
margin: 0 0 35px 0 !important;
|
||||
}
|
||||
.s_p_detail{
|
||||
flex: 0 0 calc(33.333% - 20px);
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 10px 1px rgba(28,48,175,0.08);
|
||||
border-radius: 7px 7px 7px 7px;
|
||||
position: relative;
|
||||
padding: 35px;
|
||||
margin-bottom: 35px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
.s_p_d_order{
|
||||
width: 36px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 6px 0px 6px 0px;
|
||||
background: linear-gradient( 159deg, #F0F3FF 0%, #E0E6FF 100%);
|
||||
font-family: YouSheBiaoTiHei;
|
||||
color: #354790;
|
||||
}
|
||||
.s_p_d_order1{
|
||||
color: #D97F07;
|
||||
background: linear-gradient( 159deg, #FFEDCA 0%, #FFD791 100%);
|
||||
}
|
||||
.s_p_d_order2{
|
||||
color: #566F90;
|
||||
background: linear-gradient( 159deg, #D9E1EB 0%, #B5C9DE 100%);
|
||||
}
|
||||
.s_p_d_order3{
|
||||
color: #C95E23;
|
||||
background: linear-gradient( 159deg, #F9D4B1 0%, #EAA562 100%);
|
||||
}
|
||||
&:focus-visible{
|
||||
outline: none;
|
||||
}
|
||||
&:hover{
|
||||
border: 1px solid $primary-color;
|
||||
}
|
||||
&.active{
|
||||
border: 1px solid $primary-color;
|
||||
position: relative;
|
||||
&::after,&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border-style: solid;
|
||||
border-width: 20px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-color: #fff transparent transparent transparent;
|
||||
z-index: 2;
|
||||
bottom: -39px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
border-color: $primary-color transparent transparent transparent;
|
||||
z-index: 1;
|
||||
bottom: -40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-details {
|
||||
flex: 0 0 100%;
|
||||
margin: 0 0 30px;
|
||||
overflow: hidden;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 10px 1px rgba(88,116,255,0.18);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leftBox{
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
&::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 8px;
|
||||
width: 5px;
|
||||
height: 16px;
|
||||
background: #4154F1;
|
||||
border-radius: 1px;
|
||||
}
|
||||
}
|
||||
.s_p_head{
|
||||
padding: 22px 33px;
|
||||
background-color: #F8FAFF;
|
||||
}
|
||||
.s_p_rowList{
|
||||
.s_p_rowList_t{
|
||||
padding: 15px 35px;
|
||||
background: rgba(65,84,241,0.04);
|
||||
}
|
||||
&>.ant-col{
|
||||
padding: 15px 35px;
|
||||
border-bottom: 1px solid #E2E4F3;
|
||||
}
|
||||
}
|
||||
.s_p_order{
|
||||
position: relative;
|
||||
font-family: YouSheBiaoTiHei;
|
||||
&>img{
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: -8px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import React,{ } from 'react';
|
||||
import Introduction from './component/introduction';
|
||||
import News from './component/news';
|
||||
import Project from './component/project';
|
||||
import Source from './component/source';
|
||||
import Member from './component/vip';
|
||||
import Partner from './component/partner';
|
||||
import SpecialProjects from './component/specialProjects';
|
||||
import '../../indexZone1.scss'
|
||||
import './index.scss'
|
||||
|
||||
function HeaderPageUos(props){
|
||||
const { data } = props;
|
||||
|
||||
return(
|
||||
<div className="uos_homepage_box">
|
||||
<Introduction data={data}/>
|
||||
<SpecialProjects data={data} subTitle="掌握领域动态,紧跟专项研究,洞察泛在操作系统最新进展"/>
|
||||
<News data={data} subTitle="掌握领域动态,紧跟专项研究,洞察泛在操作系统最新进展" firstDirIntro="CCF开源发展委员会“泛在操作系统开源生态”工作组" secondDirIntro="拥抱技术,与开发者携手预见未来!"/>
|
||||
<Project data={data} subTitle="探索前沿泛在项目,引领跨领域创新实践"/>
|
||||
<Source data={data} subTitle="集萃一站式文献与应用,助力构建高效、安全的泛在操作系统生态"/>
|
||||
<Member data={data}/>
|
||||
<Partner data={data}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default HeaderPageUos;
|
|
@ -85,7 +85,7 @@ function Main(props){
|
|||
setMainList(rows);
|
||||
// 隐藏判断原因:首页查看全部跳转过来后要默认选择指定的cateID而不是第一个
|
||||
// if (temp !== tempEnum.zone) {
|
||||
selectCate(cateId)
|
||||
selectCate(cateId || (rows[0] && rows[0].id))
|
||||
// }
|
||||
setIsSpin(false);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ function NewsList(props){
|
|||
const [ menuSpin , setMenuSpin ] = useState(true);
|
||||
const { id, temp } = props;
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if(id && cateId ){
|
||||
setMenuSpin(true);
|
||||
|
|
|
@ -61,7 +61,7 @@ export function getDocList(id){
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
// 获取文章列表
|
||||
export function getSubDocList(id,params){
|
||||
return fetch({
|
||||
url:`/cms/doc/open/dir/${id}/docList`,
|
||||
|
@ -69,6 +69,14 @@ export function getSubDocList(id,params){
|
|||
params
|
||||
})
|
||||
}
|
||||
// 获取文章列表(带内容)
|
||||
export function getDocAndContentList(id,params){
|
||||
return fetch({
|
||||
url:`/cms/doc/open/dir/${id}/docContentList`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
// 专区会员
|
||||
export function getVIPAllList(id){
|
||||
return fetch({
|
||||
|
@ -336,4 +344,86 @@ export function getDataSetdetail(datasetId,params) {
|
|||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function getSpecialProjectTypeList(id,params) {
|
||||
return fetch({
|
||||
url: `/zone/open/${id}/specialProjectType/list`,
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function getSpecialProjectList(id, specialProjectTypeId,params) {
|
||||
return fetch({
|
||||
url: `/zone/open/${id}/specialProjectType/${specialProjectTypeId}/specialProjectList`,
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function getSpecialProjectDetail(specialProjectId,params) {
|
||||
return fetch({
|
||||
url: `/zone/open/specialProject/${specialProjectId}/specialProjectRelevancyList`,
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 专区统计数据
|
||||
export function getZoneStatistics(id) {
|
||||
return fetch({
|
||||
url: `/zone/open/${id}/statistics`,
|
||||
method: 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
// 专区项目列表(带活跃度)
|
||||
export function getProjectListByScore(id,params) {
|
||||
return fetch({
|
||||
url: `/zone/open/${id}/projectByScore/list`,
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取已开通企业的组织列表
|
||||
export function getOrzCompanyList(){
|
||||
return fetch({
|
||||
url:`/pms/pmsEnterprise/myList`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
// 查询组织是否开通企业
|
||||
export function checkOpenedEnterprise(orgId){
|
||||
return fetch({
|
||||
url:`/pms/pmsEnterprise/${orgId}/workbenchUrl`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 组织升级为企业
|
||||
export function createEnterpriseByGitlinkOrgId(orgId, data) {
|
||||
return fetch({
|
||||
url: `/pms/pmsEnterprise/createByGitlinkOrgId/${orgId}`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 可选角色列表
|
||||
export function getRoleList(){
|
||||
return fetch({
|
||||
url:`/pms/pmsEnterprise/roleList`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 获取工作台初始用户列表
|
||||
export function getUserList(orgId){
|
||||
return fetch({
|
||||
url:`/pms/pmsEnterprise/gitlinkUserList/${orgId}`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ function beforeFetch(actionUrl){
|
|||
axios.defaults.withCredentials = true;
|
||||
}
|
||||
const config = {
|
||||
// headers:{Authorization:"Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjo0NCwidXNlcl9rZXkiOiI3NWY3MmJmYmE2NGU4N2U3NWVjNWMwZDk2OThkMDFiN2EyODE0YjYwIiwidXNlcm5hbWUiOiJpbm5vdiJ9.IviAyZQjPFc4rT3ejAKfJYx3_QgS78RCKHx1XS-A4uI_mrc7_l6wK76HVIoPCEvP0Qimzyc6dpeVW4cE2fILZw"},
|
||||
baseURL: actionUrl,
|
||||
timeout: 1800000, // 请求超时时间
|
||||
}
|
||||
|
@ -47,9 +48,9 @@ function beforeFetch(actionUrl){
|
|||
)
|
||||
return service;
|
||||
}
|
||||
let settings = localStorage.chromesetting&&JSON.parse(localStorage.chromesetting);
|
||||
let settings = localStorage.chromesetting&& localStorage.chromesetting !=="undefined"&& JSON.parse(localStorage.chromesetting);
|
||||
let actionUrl = settings && settings.common.zone +'/api';
|
||||
|
||||
const service = beforeFetch(actionUrl);
|
||||
export const httpUrl = actionUrl;
|
||||
export default service;
|
||||
export default service;
|
||||
|
|
|
@ -90,6 +90,11 @@ const HomePageByJCC = Loadable({
|
|||
loader : () => import("./Pages/JCC/homePage"),
|
||||
loading : Loading,
|
||||
});
|
||||
|
||||
const HomePageByUos = Loadable({
|
||||
loader : () => import("./Pages/homepage/uos"),
|
||||
loading : Loading,
|
||||
});
|
||||
const DatasetFileList = Loadable({
|
||||
loader : () => import("./Pages/dataset/fileList"),
|
||||
loading : Loading,
|
||||
|
@ -110,7 +115,13 @@ function Index(props){
|
|||
const sourcedetail = pathname.indexOf(`/zone/${deptId}/newdetail/`)>-1 && isPhone();
|
||||
const {current_user} = props;
|
||||
|
||||
console.log('deptId', deptId);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if(deptId && deptId === "KYDS7th"){
|
||||
window.location.href = 'https://gitlink.org.cn/competitions/2024';
|
||||
}
|
||||
if(deptId && deptId!=="apply"){
|
||||
getDetail();
|
||||
}
|
||||
|
@ -280,6 +291,7 @@ function Index(props){
|
|||
render={(p) => (
|
||||
deptId==="CCF-ODC" ? <HeaderPageCCF {...props} {...p} data={data} id={id} temp={ temp } />:
|
||||
deptId === "JCC" ? <HomePageByJCC {...props} {...p} data={data} id={id}/>:
|
||||
deptId === "uos" ? <HomePageByUos {...props} {...p} data={data} id={id}/>:
|
||||
temp === tempEnum.zone ? <HeaderPage {...props} {...p} data={data} id={id} temp={ temp }/>:
|
||||
<HeaderPageZone1 {...props} {...p} data={data} id={id} temp={ temp }/>
|
||||
)}
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.themeSpin .ant-spin-dot-item{
|
||||
background-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.information_main{
|
||||
background-color:#f3f5f8;
|
||||
min-height: 100vh;
|
||||
|
@ -81,7 +85,7 @@
|
|||
}
|
||||
.sub_t{
|
||||
margin-top: 35px;
|
||||
max-width:536px;
|
||||
max-width:600px;
|
||||
line-height:40px;
|
||||
color:rgba(225,225,225,0.9);
|
||||
font-size:16px;
|
||||
|
|
|
@ -129,8 +129,8 @@ function IssueCommentList(props){
|
|||
<div className='operationCommentBor'></div>
|
||||
<div className='flexCenter font-14' style={{width: '100%'}}>
|
||||
<div className='flexCenter opBox'>
|
||||
<span className='iconBackBox mr10'><i className={`iconfont font-12 ${journalsIcon[item.operate_category]}`}></i></span>
|
||||
<div className='task-hide' style={{maxWidth: item.closeAndSpan && item.id === item.start? '550px' : '700px'}}>
|
||||
<span className='iconBackBox mr10'><i className={`iconfont font-12 ${journalsIcon[item.operate_category] || "icon-xiugaibaobiaomoba"}`}></i></span>
|
||||
<div className='task-hide operationWords' style={{maxWidth: item.closeAndSpan && item.id === item.start? '550px' : '700px'}}>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr5'/></Link>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name} </Link>
|
||||
{(item.user.name.length + item.operate_content.length) > 62 ? <Tooltip title={<div><span>{item.user.name} </span><span dangerouslySetInnerHTML={{__html:item.operate_content}}></span></div>}><span dangerouslySetInnerHTML={{__html:item.operate_content}}></span></Tooltip> : <span dangerouslySetInnerHTML={{__html:item.operate_content}}></span>}
|
||||
|
@ -142,14 +142,19 @@ function IssueCommentList(props){
|
|||
</div> : '' : <div key={item.id} className='commentContentBox pb30'>
|
||||
{/* 评论 */}
|
||||
<div className='commentOperationBor'></div>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></Link>
|
||||
{
|
||||
item.user.login ?
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></Link>
|
||||
:
|
||||
<span><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></span>
|
||||
}
|
||||
<div className='commentContentRight'>
|
||||
{/* 判断是否是编辑状态 */}
|
||||
{(showEdit === 2 && updateId === item.id) ? <div className='mt15 mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={item.notes} defaultFileList={item.attachments} showUserImg={false}/></div> : <div>
|
||||
<div className='commentContent'>
|
||||
<div className='flexCenter font-14'>
|
||||
<div>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name}</Link>
|
||||
{item.user.login ? <Link to={`/${item.user.login}`}>{item.user.name}</Link>:<span>{item.user.name}</span>}
|
||||
<span className='ml15 timeAgo font-14'>{timeAgo(item.created_at)}</span>
|
||||
</div>
|
||||
{login && <div>
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
position: absolute;
|
||||
left: 12px;
|
||||
}
|
||||
.operationWords{
|
||||
a{
|
||||
color:#466aff;
|
||||
}
|
||||
}
|
||||
.operationLog+.commentContentBox{
|
||||
&>a, &>.commentContentRight{
|
||||
margin-top: 25px;
|
||||
|
|
|
@ -53,8 +53,13 @@ function Datas({checkbox ,item , projectsId,owner,chooseTagFunc}){
|
|||
<Copy value={`/${owner}/${projectsId}/issues/${item.project_issues_index}`}><span className="number">#{item.project_issues_index}</span></Copy>
|
||||
}
|
||||
</div>
|
||||
<Link to={`/${item.author && item.author.login}`}><i className="iconfont icon-chengyuan2 mr3 font-12" style={{color:'#898d9d'}}></i></Link>
|
||||
<span className="mr12"><Link style={{color:"#898d9d"}} to={`/${item.author && item.author.login}`}>{item.author && item.author.name}</Link></span>
|
||||
<span className="mr12">
|
||||
{item.author && item.author.login ?
|
||||
<Link style={{color:"#898d9d"}} to={`/${item.author.login}`}>
|
||||
<i className="iconfont icon-chengyuan2 mr3 font-12" style={{color:'#898d9d'}}></i>{item.author && item.author.name}</Link>
|
||||
:<span><i className="iconfont icon-chengyuan2 mr3 font-12" style={{color:'#898d9d'}}></i>{item.author && item.author.name}</span>
|
||||
}
|
||||
</span>
|
||||
<span className="mr12">{item.created_at} 发布</span>
|
||||
<span className="mr20">{item.updated_at}更新</span>
|
||||
{item.blockchain_token_num && <span className="mr30"><img src={gold} alt="" width="13px" className="mr3"/>{item.blockchain_token_num}</span>}
|
||||
|
|
|
@ -391,9 +391,13 @@ function Details(props){
|
|||
<Copy value={`/${owner}/${projectsId}/issues/${index}`}><span className="number">#{details.project_issues_index}</span></Copy>
|
||||
</div>
|
||||
{
|
||||
details.author &&
|
||||
details.author &&
|
||||
<div>
|
||||
<Link to={`/${details.author.login}`} className="author"><img src={getImageUrl(details.author.image_url)} alt="" />{details.author.name}</Link>
|
||||
{ details.author.login ?
|
||||
<Link to={`/${details.author.login}`} className="author"><img src={details.author.image_url} alt="" />{details.author.name}</Link>
|
||||
:
|
||||
<span className="author color-grey-6"><img src={details.author.image_url} alt="" />{details.author.name}</span>
|
||||
}
|
||||
<span className="ml10" style={{color:"#898d9d"}}>添加于{details.created_at}</span>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -185,6 +185,7 @@ function Sign(props){
|
|||
}
|
||||
|
||||
function createSign(){
|
||||
setEditId(undefined);
|
||||
const c = Math.random().toString(16).substr(-6);
|
||||
c && setDefaultColor(`#${c}`);
|
||||
setEdit(true);
|
||||
|
|
|
@ -207,7 +207,7 @@ function CoderDepot(props){
|
|||
axios.get(url, {
|
||||
params: { ref:branch}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
if (result && result.data.status !== 404) {
|
||||
setCommitCount(result.data.commits_count);
|
||||
setDirInfo(result.data.entries);
|
||||
setFileInfo(undefined);
|
||||
|
@ -222,6 +222,9 @@ function CoderDepot(props){
|
|||
setEditReadme(false);
|
||||
setHide(true);
|
||||
getReadmeInfo('', branchName || defaultBranch);
|
||||
}else{
|
||||
// entries接口返回404:分支不存在或被删除
|
||||
props.history.push(`/${owner}/${projectsId}`)
|
||||
}
|
||||
setTimeout(function(){setIsSpin(false);},500);
|
||||
}).catch(error=>{setIsSpin(false);})
|
||||
|
|
|
@ -132,11 +132,11 @@ const DevIndex = Loadable({
|
|||
loading: Loading,
|
||||
});
|
||||
const Wiki = Loadable({
|
||||
loader: () => import('../Wiki/Index'),
|
||||
loader: () => import('../Wiki/page/index'),
|
||||
loading: Loading,
|
||||
});
|
||||
const WikiEdit = Loadable({
|
||||
loader: () => import('../Wiki/EditWiki'),
|
||||
loader: () => import('../Wiki/page/edit'),
|
||||
loading: Loading,
|
||||
});
|
||||
const Invite = Loadable({
|
||||
|
@ -209,15 +209,14 @@ class Detail extends Component {
|
|||
defaultBranch: undefined,
|
||||
|
||||
// 非本平台项目
|
||||
platform: false,
|
||||
platform: true,
|
||||
mirror_status:0,
|
||||
bannerList: props.projectMenu || []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
componentDidMount = () => {
|
||||
// this.getProject();
|
||||
componentDidMount=()=>{
|
||||
let history = this.props.location;
|
||||
this.clearIssueCookies(history);
|
||||
if (this.props.clearProject) {
|
||||
|
@ -228,7 +227,8 @@ class Detail extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate = async (prevState) => {
|
||||
|
||||
componentDidUpdate = async (prevState) => {
|
||||
let prevParam = prevState.match.params;
|
||||
let propsParam = this.props.match.params;
|
||||
if (prevState && this.props && (prevParam.projectsId !== propsParam.projectsId || prevParam.owner !== propsParam.owner)) {
|
||||
|
@ -243,7 +243,7 @@ class Detail extends Component {
|
|||
// 非issue链接地址清除cookie states,具体保存和操作在order.js页面
|
||||
this.clearIssueCookies(history);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
clearIssueCookies = (history) => {
|
||||
const { pathname } = history;
|
||||
|
@ -255,9 +255,7 @@ class Detail extends Component {
|
|||
}
|
||||
}
|
||||
async componentWillMount() {
|
||||
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
|
||||
if (!this.props.projectBase) {
|
||||
const data = await getProjectFunc(owner, projectsId);
|
||||
if (data && data.data) {
|
||||
|
@ -451,19 +449,28 @@ class Detail extends Component {
|
|||
// 获取动态导航栏菜单
|
||||
async getBanner(data) {
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
if (!data) {
|
||||
const url = `/${owner}/${projectsId}/menu_list.json`;
|
||||
const res = await axios.get(url)
|
||||
if (res.data) {
|
||||
data = res.data
|
||||
const url = `/${owner}/${projectsId}/menu_list.json`;
|
||||
axios.get(url).then(res=>{
|
||||
if(res && res.data){
|
||||
this.setState({
|
||||
bannerList: res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
this.setState({
|
||||
bannerList: data
|
||||
})
|
||||
}
|
||||
})
|
||||
// if (!data) {
|
||||
// const url = `/${owner}/${projectsId}/menu_list.json`;
|
||||
// axios.get(url).then(res=>{
|
||||
// if(res && res.data){
|
||||
// this.setState({
|
||||
// bannerList: res.data
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }else{
|
||||
// this.setState({
|
||||
// bannerList: data
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
// 关注和取消关注
|
||||
|
@ -535,12 +542,14 @@ class Detail extends Component {
|
|||
const url = `/${owner}/${projectsId}/forks.json`;
|
||||
axios.post(url).then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
if (result.data.message === "fork失败,你已拥有了这个项目") {
|
||||
this.props.showNotification(result.data.message);
|
||||
if (result.data.message && result.data.message.indexOf("fork失败")>-1) {
|
||||
// fork失败,已经fork过,跳转到fork的仓库
|
||||
this.props.history.push(`/${current_user && current_user.login}/${projectsId}`);
|
||||
return;
|
||||
}
|
||||
this.props.history.push(`/${current_user && current_user.login}/${result.data.identifier}`);
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
this.props.showNpsModal("indexProject", 3);
|
||||
}
|
||||
this.setState({
|
||||
|
@ -758,7 +767,8 @@ class Detail extends Component {
|
|||
</Content>
|
||||
}
|
||||
<Spin spinning={secondSync && !firstSync} className="spinstyle" tip="正在同步镜像" size="large">
|
||||
<Switch {...this.props}>
|
||||
{/* mirror_status = 1的情况不显示项目详情子模块 */}
|
||||
{!firstSync && <Switch {...this.props}>
|
||||
{/* 服务 */}
|
||||
<Route path="/:owner/:projectsId/service"
|
||||
render={
|
||||
|
@ -796,15 +806,15 @@ class Detail extends Component {
|
|||
}
|
||||
></Route>
|
||||
{/* wiki编辑文件 */}
|
||||
<Route path="/:owner/:projectsId/wiki/:wikiName/:key/edit"
|
||||
<Route path="/:owner/:projectsId/wiki/edit"
|
||||
render={
|
||||
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* wiki具体某一个地址 */}
|
||||
<Route path="/:owner/:projectsId/wiki/:wikiName/:key"
|
||||
{/* wiki复制文件 */}
|
||||
<Route path="/:owner/:projectsId/wiki/copy"
|
||||
render={
|
||||
(props) => (<Wiki {...this.props} {...props} {...this.state} {...common} />)
|
||||
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* wiki */}
|
||||
|
@ -960,7 +970,7 @@ class Detail extends Component {
|
|||
(props) => <CoderDepot {...this.props} {...props} {...this.state} {...common} mirror_status={mirror_status}/>
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
</Switch>}
|
||||
</Spin>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -79,25 +79,34 @@ class MergeItem extends Component {
|
|||
</Tag>
|
||||
</p>
|
||||
<p className="grid-item font-13">
|
||||
<Link
|
||||
to={`/${item && item.author_login}`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
className="radius"
|
||||
src={getImageUrl(`/${item && item.avatar_url}`)}
|
||||
alt=""
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
</Link>
|
||||
<AlignCenter>
|
||||
<Link
|
||||
to={`/${item && item.author_login}`}
|
||||
className="show-user-link color-grey-8 ml5"
|
||||
>
|
||||
{item && item.author_name}
|
||||
</Link>
|
||||
{
|
||||
item && item.author_login ?
|
||||
<Link
|
||||
to={`/${item.author_login}`}
|
||||
className="show-user-link color-grey-8"
|
||||
>
|
||||
<img
|
||||
className="radius mr5"
|
||||
src={getImageUrl(`/${item && item.avatar_url}`)}
|
||||
alt=""
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
{item && item.author_name}
|
||||
</Link>
|
||||
:
|
||||
<span className="color-grey-6">
|
||||
<img
|
||||
className="radius mr5"
|
||||
src={getImageUrl(`/${item && item.avatar_url}`)}
|
||||
alt=""
|
||||
width="24"
|
||||
height="24"
|
||||
/>{item && item.author_name}
|
||||
</span>
|
||||
}
|
||||
|
||||
<span className="ml15 color-grey-8">
|
||||
{item.pull_request_staus === "open"
|
||||
? "创建于"
|
||||
|
@ -114,10 +123,8 @@ class MergeItem extends Component {
|
|||
item.is_original ?
|
||||
(
|
||||
(item.fork_project_user && item.fork_project_identifier) ?
|
||||
<Link
|
||||
to={`/${ item.fork_project_user }/${ item.fork_project_identifier }/tree/${turnbar(item.pull_request_head)}`}
|
||||
className="maxW200px task-hide ver-middle" style={{maxWidth:"300px"}}
|
||||
>
|
||||
<Link to={`/${ item.fork_project_user }/${ item.fork_project_identifier }/tree/${turnbar(item.pull_request_head)}`}
|
||||
className="maxW200px task-hide ver-middle" style={{maxWidth:"300px"}} >
|
||||
{item.fork_project_user_name || "仓库已删除"} : {item.pull_request_head || "分支已删除"}
|
||||
</Link>
|
||||
:
|
||||
|
|
|
@ -342,7 +342,7 @@ class MessageCount extends Component {
|
|||
const {
|
||||
data,
|
||||
SpinMerge,
|
||||
pr_status,
|
||||
pr_status,
|
||||
isSpin,
|
||||
ismesrge,
|
||||
SpinFlag,
|
||||
|
@ -404,42 +404,56 @@ class MessageCount extends Component {
|
|||
{
|
||||
<div className="mt15">
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/${data.pull_request.is_original ? data.pull_request.fork_project_user : data.issue.project_author}/${data.pull_request.is_original?data.project_identifier:projectsId}/tree/${turnbar(data.pull_request && data.pull_request.head)}`}
|
||||
className="ver-middle task-hide" style={{maxWidth:"300px"}} title={`${data.pull_request.fork_project_user}: ${data.pull_request && data.pull_request.head}`}
|
||||
>
|
||||
{data.pull_request && data.pull_request.fork_project_user}: {data.pull_request && data.pull_request.head}
|
||||
</Link>
|
||||
{
|
||||
(data.pull_request.fork_project_user || data.issue.author_name!=="已注销") ?
|
||||
<Link
|
||||
to={`/${data.pull_request.is_original ? data.pull_request.fork_project_user : data.issue.author_name}/${data.pull_request.is_original?data.project_identifier:projectsId}/tree/${turnbar(data.pull_request && data.pull_request.head)}`}
|
||||
className="ver-middle task-hide" style={{maxWidth:"300px"}} title={`${data.pull_request.fork_project_user}: ${data.pull_request && data.pull_request.head}`}
|
||||
>
|
||||
{data.pull_request && (data.pull_request.is_original ? data.pull_request.fork_project_user:data.issue.author_name)}: {data.pull_request && data.pull_request.head}
|
||||
</Link>
|
||||
:
|
||||
<span className="ver-middle task-hide" style={{maxWidth:"300px"}} title={`${data.pull_request.fork_project_user}: ${data.pull_request && data.pull_request.head}`}>
|
||||
{data.pull_request && (data.pull_request.is_original ? data.pull_request.fork_project_user:data.issue.author_name)}: {data.pull_request && data.pull_request.head}
|
||||
</span>
|
||||
|
||||
}
|
||||
</Tag>
|
||||
<span className="mr8 ver-middle">
|
||||
<i
|
||||
className={
|
||||
"iconfont icon-youjiang color-grey-c font-16"
|
||||
}
|
||||
></i>
|
||||
<i className={"iconfont icon-youjiang color-grey-c font-16"} />
|
||||
</span>
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/${owner}/${projectsId}/tree/${data.pull_request.base}`}
|
||||
className="ver-middle task-hide" style={{maxWidth:"300px"}} title={`${data.issue.project_author_name}:${data.pull_request.base}`}
|
||||
>
|
||||
{data.issue.project_author}: {data.pull_request.base}
|
||||
{data.issue.project_author_name}: {data.pull_request.base}
|
||||
</Link>
|
||||
</Tag>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="mt15">
|
||||
<Link to={`/${data.issue.author_login}`} className="show-user-link">
|
||||
<img className="mr5" src={getImageUrl(`/${data.issue.author_picture}`)}
|
||||
alt="" width="24" height="24" style={{borderRadius:"50%"}}
|
||||
/>
|
||||
</Link>
|
||||
{
|
||||
data.issue.author_login?
|
||||
<Link to={`/${data.issue.author_login}`} className="show-user-link">
|
||||
<img className="mr5" src={getImageUrl(`/${data.issue.author_picture}`)}
|
||||
alt="" width="24" height="24" style={{borderRadius:"50%"}}
|
||||
/>
|
||||
</Link>
|
||||
:
|
||||
<span><img className="mr5" src={getImageUrl(`/${data.issue.author_picture}`)} alt="" width="24" height="24" style={{borderRadius:"50%"}}/></span>
|
||||
}
|
||||
<span className="ver-middle">
|
||||
<span className="color-grey-8 mr5">由</span>
|
||||
<Link to={`/${data.issue.author_login}`} className="show-user-link color-blue">
|
||||
{data.issue.author_name}
|
||||
</Link>
|
||||
{
|
||||
data.issue.author_login ?
|
||||
<Link to={`/${data.issue.author_login}`} className="show-user-link color-blue">
|
||||
{data.issue.author_name}
|
||||
</Link>
|
||||
:
|
||||
<span className="show-user-link color-grey-6">{data.issue.author_name}</span>
|
||||
}
|
||||
<span className="ml5 color-grey-8">
|
||||
{pr_status === 0
|
||||
? "创建于"
|
||||
|
|
|
@ -146,18 +146,14 @@ const ReplyItem = memo(({ note, isChild }) => {
|
|||
<div className="reply-item-head">
|
||||
<Link
|
||||
to={`/${note.user && note.user.login}`}
|
||||
className="show-user-link"
|
||||
className="show-user-link color-black fwb"
|
||||
>
|
||||
<Avatar src={note.user && note.user.imageUrl
|
||||
? getImageUrl(`/${note.user.imageUrl}`)
|
||||
: "images/avatars/User/b"} size={24} />
|
||||
</Link>
|
||||
<Link
|
||||
to={`/${note.user && note.user.login}`}
|
||||
className="show-user-link color-black ml10 fwb"
|
||||
>
|
||||
: "images/avatars/User/b"} size={24} className="mr10"/>
|
||||
{note.user && note.user.username}
|
||||
</Link> 于 <span className="show-user-link color-black">{timeAgo(note.createdAt)}</span> 发表评论:
|
||||
</Link>
|
||||
于 <span className="show-user-link color-black">{timeAgo(note.createdAt)}</span> 发表评论:
|
||||
<span className="btn-right">
|
||||
{user &&
|
||||
(user.admin ||
|
||||
|
|
|
@ -19,11 +19,15 @@ function Apply(props) {
|
|||
setIsSpin(true);
|
||||
getList();
|
||||
}
|
||||
},[username])
|
||||
},[username, page])
|
||||
|
||||
function getList() {
|
||||
const url = `/users/${username}/applied_projects.json`;
|
||||
Axios.get(url).then(result=>{
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
page,per_page:limit
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setList(result.data.applied_projects);
|
||||
setTotal(result.data.total_count);
|
||||
|
|
|
@ -6,6 +6,7 @@ import nullBot from '../../../../softbot/image/notBot.png';
|
|||
import { getAllInstallBots, deleteInstallBot } from "../../../../softbot/api";
|
||||
import './index.scss';
|
||||
import axios from "axios";
|
||||
import LogoBot from '../../../Settings/image/logoBot.png';
|
||||
|
||||
// 配置已安装的bot
|
||||
function DispositionBot(props){
|
||||
|
@ -85,7 +86,7 @@ function DispositionBot(props){
|
|||
{botList && (botList.length > 0 ? <div className="setBotListBox">
|
||||
{botList.map((item, index)=>{return <div className="disBotItem" key={index}>
|
||||
<div className="botNameLeft">
|
||||
<img src={getImageUrl(item.logo)} alt="" className="imgBox mr20"/>
|
||||
<img src={(item.logo && !(item.logo.indexOf("347246")>-1 || item.logo.indexOf("412603")>-1)) ? getImageUrl(item.logo) : LogoBot} alt="" className="imgBox mr20"/>
|
||||
<Link className="font-15 botName" to={`/settings/installbot/${item.bot_id}`}>{item.bot_name}</Link>
|
||||
<span className={`statusBox font-12 ml10 ${item.state === 0 ? '' : 'active'}`}>{item.state === 0 ? '挂起' : '启用'}</span>
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,7 @@ import { getImageUrl } from 'educoder';
|
|||
import { getMyBot, getTransferToBot, receiveTransferBot, refuseTransferBot } from "../../../../softbot/api";
|
||||
import nullBot from '../../../../softbot/image/notBot1.png';
|
||||
import moment from "moment";
|
||||
import LogoBot from '../../../Settings/image/logoBot.png';
|
||||
|
||||
function ExploitBot(props){
|
||||
const {current_user} = props;
|
||||
|
@ -96,7 +97,7 @@ function ExploitBot(props){
|
|||
{botList && (botList.length > 0 ? <div className="softBotListBox">
|
||||
{botList.map((item, index)=>{return <div className="softBotItem" key={index}>
|
||||
<div className="botOneLine botNameWarpBox">
|
||||
<img src={getImageUrl(item.logo)} alt="" className="imgBox mr20" object-fit="fill"/>
|
||||
<img src={(item.logo && !(item.logo.indexOf("347246")>-1 || item.logo.indexOf("412603")>-1)) ? getImageUrl(item.logo) : LogoBot} alt="" className="imgBox mr20" object-fit="fill"/>
|
||||
<Link className="font-15 botOneLine botNameBox" to={`/settings/mybot/configuration/${item.bot_id}`}>{item.bot_name}</Link>
|
||||
<span className={`font-12 ml10 statusBot ${item.is_public ? item.is_market ? 'market' : 'public' : 'private'}`}>{item.is_public ? item.is_market ? '上架' : '公开' : '私有'}</span>
|
||||
</div>
|
||||
|
|
|
@ -83,7 +83,7 @@ function Disposition(props){
|
|||
bot_name, bot_des, webhook, is_public,
|
||||
login: current_user && current_user.login,
|
||||
user_id: current_user && current_user.user_id,
|
||||
logo: `/api/attachments/${window.location.host !== 'www.gitlink.org.cn' ? 347246 : 412603}`,
|
||||
// logo: `/api/attachments/${window.location.host !== 'www.gitlink.org.cn' ? 347246 : 412603}`,
|
||||
limit_and_events: {
|
||||
event_code: event_code ? event_code.toString() : '',
|
||||
event_pr: event_pr ? event_pr.toString() : '',
|
||||
|
|
|
@ -19,7 +19,8 @@ function Main(props){
|
|||
|
||||
useEffect(()=>{
|
||||
if(current_user && !current_user.login){
|
||||
props.history.push(`/login?go_page=/${owner}/${projectsId}/service`);
|
||||
// 未登录用户访问会跳转到代码库主页,此处不用处理
|
||||
// props.history.push(`/login?go_page=/${owner}/${projectsId}/service`);
|
||||
}else{
|
||||
setHas_trace_user(current_user.has_trace_user);
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 4.0 KiB |
|
@ -6,6 +6,7 @@ import './setting.scss';
|
|||
import { useEffect } from "react";
|
||||
import { getStoreAllInstallBots } from "../../softbot/api";
|
||||
import { getImageUrl } from 'educoder';
|
||||
import LogoBot from './image/logoBot.png';
|
||||
|
||||
function SoftBot(props){
|
||||
const {projectDetail} = props;
|
||||
|
@ -34,7 +35,7 @@ function SoftBot(props){
|
|||
{botList && (botList.length > 0 ? <div className="botListBox">
|
||||
{botList.map((item, index)=>{return <div className="disBotItem" key={index}>
|
||||
<div className="flexCenter">
|
||||
<img src={getImageUrl(item.logo)} alt="" className="imgBox mr20"/>
|
||||
<img src={(item.logo && !(item.logo.indexOf("347246")>-1 || item.logo.indexOf("412603")>-1)) ? getImageUrl(item.logo) : LogoBot} alt="" className="imgBox mr20"/>
|
||||
<span className="font-15 botName">{item.bot_name}</span>
|
||||
<span className={`statusBox font-12 ml10 ${item.state === 0 ? '' : 'active'}`}>{item.state === 0 ? '挂起' : '启用'}</span>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import Loadable from "react-loadable";
|
||||
|
@ -7,9 +7,10 @@ import { withRouter } from "react-router";
|
|||
import { SnackbarHOC } from "educoder";
|
||||
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
|
||||
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
|
||||
import ProjectDetail from '../Main/Detail'
|
||||
import '../css/index.scss';
|
||||
import './Index.scss';
|
||||
import { checkOpenedEnterprise } from '../Information/api';
|
||||
import axios from 'axios';
|
||||
|
||||
const GroupNew = Loadable({
|
||||
loader: () => import("./Group/GroupNew"),
|
||||
|
@ -36,12 +37,39 @@ const SubDetailIndex = Loadable({
|
|||
loading: Loading,
|
||||
});
|
||||
// forge项目详情
|
||||
// const ProjectDetail = Loadable({
|
||||
// loader: () => import("../Main/Detail"),
|
||||
// loading: Loading,
|
||||
// });
|
||||
const team = CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
||||
const ProjectDetail = Loadable({
|
||||
loader: () => import("../Main/Detail"),
|
||||
loading: Loading,
|
||||
});
|
||||
export default withRouter(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
||||
((props)=>{
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const [ organizeDetail , setOrganizeDetail ] = useState(undefined);
|
||||
const [ enterpriseOpenInfo, setEnterpriseOpenInfo] = useState(false);
|
||||
useEffect(()=>{
|
||||
if(OIdentifier){
|
||||
getDetail(OIdentifier);
|
||||
}
|
||||
},[OIdentifier]);
|
||||
|
||||
function getDetail(identifier) {
|
||||
const url = `/organizations/${identifier}.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setOrganizeDetail(result.data);
|
||||
const {id} = result.data;
|
||||
checkOrgOpenEnterprise(id)
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function checkOrgOpenEnterprise(orgId){
|
||||
checkOpenedEnterprise(orgId).then(res=>{
|
||||
if(res && res.data.code === 200){
|
||||
setEnterpriseOpenInfo(res.data.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div className="newMain">
|
||||
<Switch>
|
||||
|
@ -84,7 +112,7 @@ const team = CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
|||
<Route
|
||||
path="/:OIdentifier/members"
|
||||
render={(p) => {
|
||||
return <TeamDetailIndex {...props} {...p}/>
|
||||
return <TeamDetailIndex {...props} {...p} enterpriseOpened = {enterpriseOpenInfo && enterpriseOpenInfo.isOpen}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
|
@ -92,10 +120,18 @@ const team = CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
|||
<Route
|
||||
path="/:OIdentifier/setting"
|
||||
render={(p) => (
|
||||
<TeamDetailIndex {...props} {...p}/>
|
||||
<TeamDetailIndex {...props} {...p} enterpriseOpened = {enterpriseOpenInfo && enterpriseOpenInfo.isOpen}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 开通企业工作台 */}
|
||||
<Route
|
||||
path="/:OIdentifier/enterprise"
|
||||
render={(p) => {
|
||||
return <TeamDetailIndex {...props} {...p}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
{/* 组织下的项目详情 */}
|
||||
<Route
|
||||
path="/:owner/:projectsId"
|
||||
|
@ -108,15 +144,11 @@ const team = CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
|||
<Route
|
||||
path="/:OIdentifier"
|
||||
render={(p) => (
|
||||
<DetailIndex {...props} {...p}/>
|
||||
<DetailIndex {...props} {...p} organizeDetail={organizeDetail} enterpriseOpenInfo={enterpriseOpenInfo}/>
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)))
|
||||
|
||||
team.preFetch = ProjectDetail.preFetch
|
||||
|
||||
export default withRouter(team)
|
||||
))))
|
|
@ -576,4 +576,13 @@
|
|||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.settingBtn{
|
||||
color: #466AFF;
|
||||
border-color: #466AFF!important;
|
||||
line-height: 30px;
|
||||
&.ant-btn.ant-btn-background-ghost.ant-btn-primary{
|
||||
background-color: #fff!important;
|
||||
color: #466AFF!important;
|
||||
}
|
||||
}
|
|
@ -7,12 +7,13 @@ import Item from './ListItem';
|
|||
import Right from './RightBox';
|
||||
import NoData from '../Nodata';
|
||||
import CheckProfile from '../Component/ProfileModal/Profile';
|
||||
import { Menu , Pagination , Dropdown , Spin , Tooltip , Radio } from 'antd';
|
||||
import { Menu , Pagination , Dropdown , Spin , Tooltip , Radio, Button } from 'antd';
|
||||
import ConcentrateProject from '../users/GeneralView/ConcentrateProject';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import RenderHtml from "../../components/render-html";
|
||||
import EmptyImg from '../Images/nodata.png';
|
||||
import axios from 'axios';
|
||||
import { checkOpenedEnterprise } from '../Information/api';
|
||||
|
||||
const limit = 15;
|
||||
function List(props){
|
||||
|
@ -22,27 +23,11 @@ function List(props){
|
|||
const [ search , setSearch ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ sortBy , setSortBy ] = useState("updated_on");
|
||||
const [ organizeDetail , setOrganizeDetail ] = useState(undefined);
|
||||
const [ mode , setMode ] = useState("overview");
|
||||
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const { current_user } = props;
|
||||
console.log(props);
|
||||
const { current_user, organizeDetail, enterpriseOpenInfo } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(OIdentifier){
|
||||
getDetail(OIdentifier);
|
||||
}
|
||||
},[OIdentifier]);
|
||||
|
||||
function getDetail(id) {
|
||||
const url = `/organizations/${id}.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setOrganizeDetail(result.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(organizeDetail){
|
||||
|
@ -109,17 +94,44 @@ function List(props){
|
|||
<div className="content-orz">
|
||||
<div className="top-orz">
|
||||
<div className="box">
|
||||
<img src={getImageUrl(organizeDetail && organizeDetail.avatar_url)} alt=""/>
|
||||
<img src={getImageUrl(organizeDetail && organizeDetail.avatar_url)} alt="" />
|
||||
<div className="info-orz">
|
||||
<p className="orz-main">
|
||||
<span className="orz-name">{organizeDetail && organizeDetail.nickname}</span>
|
||||
{organizeDetail && organizeDetail.is_admin ?
|
||||
<Link to={`/${OIdentifier}/setting`} className="color-blue ml10 font-14 df"><i className="iconfont icon-shezhi2"></i>设置</Link>
|
||||
:""}
|
||||
<span className="orz-name task-hide">{organizeDetail && organizeDetail.nickname}</span>
|
||||
{organizeDetail && (
|
||||
<div>
|
||||
{organizeDetail.pms_enable && organizeDetail.is_admin && !enterpriseOpenInfo.isOpen &&
|
||||
<Link to={`/${OIdentifier}/enterprise`}>
|
||||
<Button type='primary'>开通工作台</Button>
|
||||
</Link>
|
||||
}
|
||||
{
|
||||
organizeDetail.pms_enable && enterpriseOpenInfo.isOpen && organizeDetail.is_member && (enterpriseOpenInfo.url ?
|
||||
<Button type='primary' onClick={() => { window.open(enterpriseOpenInfo.url) }}>前往工作台</Button>
|
||||
:
|
||||
<Button type='primary'>正在开通工作台</Button>)
|
||||
}
|
||||
{/* {
|
||||
organizeDetail.pms_enable && organizeDetail.is_admin &&(
|
||||
!enterpriseOpenInfo.isOpen ? (
|
||||
<Link to={`/${OIdentifier}/enterprise`}>
|
||||
<Button type='primary'>开通工作台</Button>
|
||||
</Link>
|
||||
) :
|
||||
enterpriseOpenInfo.url ? (
|
||||
<Button type='primary' onClick={() => { window.open(enterpriseOpenInfo.url) }}>前往工作台</Button>
|
||||
) : (
|
||||
<Button type='primary'>正在开通工作台</Button>
|
||||
)
|
||||
)
|
||||
} */}
|
||||
{organizeDetail.is_admin && <Link to={`/${OIdentifier}/setting`} className="color-blue ml20 font-14"><Button type='primary' ghost>设置</Button></Link>}
|
||||
</div>
|
||||
)}
|
||||
</p>
|
||||
<div className="orz-desc task-hide-2">
|
||||
<Tooltip title={organizeDetail && organizeDetail.description} placement={"bottomLeft"}>
|
||||
<span style={{display:"block"}}>{organizeDetail && organizeDetail.description}</span>
|
||||
<span style={{ display: "block" }}>{organizeDetail && organizeDetail.description}</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -129,7 +141,7 @@ function List(props){
|
|||
<div className="list-l">
|
||||
{
|
||||
organizeDetail.news_title &&
|
||||
<div className="teamnewstatus">
|
||||
<div className="teamnewstatus mb30">
|
||||
<p className="teamname"><i className="iconfont icon-dongtaiicon1" /><span>新闻动态</span></p>
|
||||
<p className="teamtitle">
|
||||
{organizeDetail.news_title}
|
||||
|
@ -228,6 +240,7 @@ function List(props){
|
|||
showCompeleteDialog={props.showCompeleteDialog}
|
||||
completeProfile={props.completeProfile}
|
||||
history={props.history}
|
||||
enterpriseOpened = {enterpriseOpenInfo.isOpen}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -49,7 +49,7 @@ const Img = styled.img`{
|
|||
height:45px;
|
||||
margin-right:12px;
|
||||
}`
|
||||
function RightBox({ OIdentifier , history , admin , showCompeleteDialog ,completeProfile }) {
|
||||
function RightBox({ OIdentifier , history , admin , showCompeleteDialog ,completeProfile , enterpriseOpened }) {
|
||||
const [ languageData, setLanguageData ] = useState(undefined);
|
||||
const [ memberData, setMemberData ] = useState(undefined);
|
||||
const [ groupData, setGroupData ] = useState(undefined);
|
||||
|
@ -148,7 +148,7 @@ function RightBox({ OIdentifier , history , admin , showCompeleteDialog ,complet
|
|||
</Box>
|
||||
:""
|
||||
}
|
||||
<Box
|
||||
{!enterpriseOpened && <Box
|
||||
name="组织团队"
|
||||
count={groupData && groupData.total_count}
|
||||
icon={<i className="iconfont icon-zuzhituandui font-17 mr8"></i>}
|
||||
|
@ -188,6 +188,7 @@ function RightBox({ OIdentifier , history , admin , showCompeleteDialog ,complet
|
|||
</React.Fragment>:<Nodata _html="暂无团队" small/>
|
||||
}
|
||||
</Box>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ const CLANew = Loadable({
|
|||
export default (( props )=>{
|
||||
const pathname = props.location.pathname;
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const {organizeDetail} = props;
|
||||
const { organizeDetail , enterpriseOpened } = props;
|
||||
useEffect(()=>{
|
||||
if(organizeDetail){
|
||||
const {nickname} = organizeDetail;
|
||||
|
@ -68,8 +68,9 @@ export default (( props )=>{
|
|||
const array = {list:[
|
||||
{name:'基本设置',icon:"icon-base",href:`/${OIdentifier}/setting`},
|
||||
{name:'组织首页管理',icon:"icon-huabanfuben",href:`/${OIdentifier}/setting/index`},
|
||||
{name:'组织成员管理',icon:"icon-zuzhichengyuan",href:`/${OIdentifier}/setting/member`},
|
||||
{name:'组织团队管理',icon:"icon-zuzhixiangmu",href:`/${OIdentifier}/setting/group`},
|
||||
// ,href: enterpriseOpened ? `${ mygetHelmetapi && mygetHelmetapi.common.zone }/${OIdentifier}/members` : `/${OIdentifier}/setting/member`
|
||||
{name:'组织成员管理',icon:"icon-zuzhichengyuan",href:`/${OIdentifier}/setting/member`, hide: enterpriseOpened},
|
||||
{name:'组织团队管理',icon:"icon-zuzhixiangmu",href:`/${OIdentifier}/setting/group`, hide: enterpriseOpened},
|
||||
// {name:'管理web钩子',icon:"icon-zhongqingdianxinicon10",href:`/${OIdentifier}/setting/hooks`}
|
||||
{name:'CLA管理',img:claIcon,href:`/${OIdentifier}/setting/agreement`,hide:organizeDetail && !organizeDetail.enabling_cla}
|
||||
],
|
||||
|
|
|
@ -23,11 +23,7 @@ function CLAinfos(props){
|
|||
}
|
||||
},[current_user,details])
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user &&!current_user.login){
|
||||
props.history.push(`/login?go_page=/${OIdentifier}/cla/${claid}`);
|
||||
}
|
||||
},[current_user])
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if(claid){
|
||||
|
|
|
@ -9,6 +9,7 @@ function TeamSettingCLA(props){
|
|||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const [ list , setList ] = useState(undefined);
|
||||
const [ isSpin , setisSpin ] = useState(false);
|
||||
const { current_user } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(OIdentifier){
|
||||
|
@ -28,6 +29,14 @@ function TeamSettingCLA(props){
|
|||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function toDetail(){
|
||||
if(current_user && current_user.login){
|
||||
window.open(`/${OIdentifier}/cla/${list.key}`, '_blank');
|
||||
}else{
|
||||
window.open(`/login?go_page=/${OIdentifier}/cla/${claid}`, '_blank');
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{border:list && list.id ? "none":"1px solid #eee"}}>
|
||||
<Title>CLA管理</Title>
|
||||
|
@ -40,7 +49,7 @@ function TeamSettingCLA(props){
|
|||
<p className="task-hide cla_name">{list.name}</p>
|
||||
<span className="cla_personCount">签署人数<span>{list.count || 0}</span></span>
|
||||
<div className="cla_btn">
|
||||
<Button href={`/${OIdentifier}/cla/${list.key}`} target="_blank" style={{color:"#466aff",borderColor:"#466aff"}}>查看协议</Button>
|
||||
<Button onClick={toDetail} style={{color:"#466aff",borderColor:"#466aff"}}>查看协议</Button>
|
||||
<Button onClick={()=>{props.history.push(`/${OIdentifier}/setting/agreement/${list.key}`)}} style={{color:"#466aff",borderColor:"#466aff"}} className="ml22">编辑</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { WhiteBack , FlexAJ } from '../../Component/layout';
|
||||
import { Table , Pagination , Popconfirm, Button, message, Select, Spin } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
import './teamSetting.scss';
|
||||
import { createEnterpriseByGitlinkOrgId, getRoleList, getUserList, checkOpenedEnterprise } from '../../Information/api';
|
||||
|
||||
const Img = styled.img`{
|
||||
width:30px;
|
||||
height:30px;
|
||||
border-radius:50%;
|
||||
}`
|
||||
const limit = 15;
|
||||
export default (({organizeDetail,history,match, current_user})=>{
|
||||
const OIdentifier = match.params.OIdentifier;
|
||||
const {login} = current_user
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ data , setData ] = useState(undefined);
|
||||
const [ roleList, setRoleList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
// 定时器
|
||||
let intervalId = null;
|
||||
|
||||
useEffect(()=>{
|
||||
getRoleList().then(res=>{
|
||||
const {code, rows} = res && res.data
|
||||
if(code === 200){
|
||||
setRoleList(rows);
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(()=>{
|
||||
if(organizeDetail){
|
||||
const {nickname} = organizeDetail;
|
||||
document.title = `开通组织工作台-${nickname}`;
|
||||
pollData()
|
||||
}
|
||||
}, [organizeDetail])
|
||||
|
||||
useEffect(()=>{
|
||||
if(organizeDetail && organizeDetail.id){
|
||||
getData(organizeDetail.id);
|
||||
}
|
||||
},[organizeDetail,page])
|
||||
|
||||
// 轮询函数
|
||||
const pollData = () => {
|
||||
checkOpenedEnterprise(organizeDetail.id).then(res=>{
|
||||
if(res && res.data.code === 200){
|
||||
const {data} = res.data;
|
||||
if(data.isOpen && !data.url){
|
||||
setLoading(true)
|
||||
}else if(data.isOpen){
|
||||
clearInterval(intervalId);
|
||||
window.location = data.url
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
function getData(id){
|
||||
getUserList(id).then(res=>{
|
||||
const {code, rows, total} = res && res.data
|
||||
if(code === 200){
|
||||
setData(rows);
|
||||
setTotal(total);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 切换分页
|
||||
function ChangePage(page){
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '头像',
|
||||
dataIndex: 'imageUrl',
|
||||
render:(value)=>{
|
||||
return(
|
||||
<Img src={value}></Img>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'nickname',
|
||||
},
|
||||
{
|
||||
title: '邮箱',
|
||||
dataIndex: 'email',
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['role', 'roleKey'],
|
||||
width:"20%",
|
||||
render:(value,record)=>{
|
||||
return <Select value={value} onChange={(value)=>{
|
||||
const users = [...data];
|
||||
users.map(item=>item.username === record.username && (item.role.roleKey = value))
|
||||
setData(users);
|
||||
}}>
|
||||
{roleList && roleList.map(item=>{return <Select.Option key={item.roleKey}>{item.roleName}</Select.Option>})}
|
||||
</Select>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'username',
|
||||
key: "action",
|
||||
render:(value)=>{
|
||||
return (
|
||||
<Button type='danger' size='small' disabled={value === login} onClick={()=>{
|
||||
const users = data.filter(item=>{return item.username !== value});
|
||||
setData(users);
|
||||
}}><i className='iconfont icon-fuzhi-shanchu font-14'></i></Button>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function createEnterprise(){
|
||||
const users = data.map(item=>{return {userId: item.userId, roleKey: item.role.roleKey}})
|
||||
createEnterpriseByGitlinkOrgId(organizeDetail.id, users).then(res=>{
|
||||
if(res && res.data.code === 200){
|
||||
message.success('开通成功');
|
||||
intervalId = setInterval(pollData, 1000);
|
||||
}else{
|
||||
message.error(res && res.data.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
return(
|
||||
<Spin spinning={loading}>
|
||||
<WhiteBack style={{border:"1px solid #eee"}} className='exterpriseBox'>
|
||||
<div className='padding30'>
|
||||
首次创建组织工作台时,系统将根据组织团队用户在组织工作台中根据不同团队初始化成不同角色。请您知悉以下角色权限,再次确认组织成员的角色分配。<br/>
|
||||
<span className='font-bd'>组织管理员:</span>原owner团队成员,对组织内所有代码库均具有管理员权限,在组织工作台中拥有最高管理权限<br/>
|
||||
<span className='font-bd'>项目管理员:</span>原管理员团队成员,对组织内所有代码库均具有管理员权限,在组织工作台中拥有项目管理权限<br/>
|
||||
<span className='font-bd'>普通成员:</span>原开发者及报告者团队成员,对组织内所有代码库均具有开发者权限,在组织工作台中拥有项目基础使用权限及查看权限
|
||||
</div>
|
||||
<FlexAJ className="padding20-30">
|
||||
<div style={{width:"580px"}}>
|
||||
{/* <Search placeholder="输入用户名或邮箱、团队名搜索" onSearch={(value)=>{setSearch(value)}}/> */}
|
||||
</div>
|
||||
{/* <Sort menu={menu}>
|
||||
<a className="color-blue">角色筛选<i className="iconfont icon-sanjiaoxing-down ml3 font-14"></i></a>
|
||||
</Sort> */}
|
||||
</FlexAJ>
|
||||
<div className="pl30 pr30 pb30" style={{minHeight:"400px"}}>
|
||||
<Table
|
||||
size="small"
|
||||
columns={columns}
|
||||
dataSource={data}
|
||||
pagination={false}
|
||||
className="teamMemberTable"
|
||||
></Table>
|
||||
{/* {
|
||||
total > limit ?
|
||||
<div className="edu-txt-center mt30 mb20">
|
||||
<Pagination simple current={page} total={total} pageSize={limit} onChange={ChangePage}></Pagination>
|
||||
</div>
|
||||
:""
|
||||
} */}
|
||||
</div>
|
||||
<div className='edu-txt-right pl30 pr30 pb30'>
|
||||
<Button type='primary' ghost className='mr20' onClick={()=>{history.push(`/${OIdentifier}`)}}>暂不开通</Button>
|
||||
<Button type='primary' onClick={createEnterprise}>确认并开通工作台</Button>
|
||||
</div>
|
||||
</WhiteBack>
|
||||
</Spin>
|
||||
)
|
||||
})
|
|
@ -129,4 +129,14 @@
|
|||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.exterpriseBox{
|
||||
.padding30{
|
||||
color: #4C5876;
|
||||
line-height: 30px;
|
||||
border-bottom: 1px dashed #eee;
|
||||
}
|
||||
.font-bd{
|
||||
color: #0D0F12;
|
||||
}
|
||||
}
|
|
@ -26,9 +26,15 @@ const Setting = Loadable({
|
|||
loader: () => import("../Setting/TeamSettingIndex"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Enterprise = Loadable({
|
||||
loader: () => import("../Setting/enterprise"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
function Detail(props){
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const pathname = props.location.pathname;
|
||||
const {enterpriseOpened} = props;
|
||||
|
||||
const [ detail , setDetail ] = useState(undefined);
|
||||
const [ flag , setFlag ] = useState(true);
|
||||
|
@ -55,30 +61,30 @@ function Detail(props){
|
|||
|
||||
useEffect(()=>{
|
||||
if(OIdentifier){
|
||||
getDetail();
|
||||
getDetail(OIdentifier);
|
||||
}
|
||||
},[OIdentifier]);
|
||||
|
||||
function getDetail() {
|
||||
const url = `/organizations/${OIdentifier}.json`;
|
||||
function getDetail(id) {
|
||||
const url = `/organizations/${id}.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setDetail(result.data);
|
||||
let keyWords=`${result.data.nickname},${OIdentifier},`;
|
||||
let title= result.data.nickname+'('+ OIdentifier +') ' +result.data.description;
|
||||
setSeoMeta(keyWords,title,title,`/${OIdentifier}`,OIdentifier);
|
||||
let keyWords=`${result.data.nickname},${id},`;
|
||||
let title= result.data.nickname+'('+ id +') ' +result.data.description;
|
||||
setSeoMeta(keyWords,title,title,`/${id}`,id);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// function updateDetail(name,desc){
|
||||
// let d = detail;
|
||||
// d.name = name;
|
||||
// d.description = desc;
|
||||
// setDetail(d);
|
||||
// }
|
||||
function updateDetail(name,desc){
|
||||
let d = detail;
|
||||
d.name = name;
|
||||
d.description = desc;
|
||||
setDetail(d);
|
||||
}
|
||||
return(
|
||||
<div className="teamDetail">
|
||||
<div className="teamDetail mb50">
|
||||
{
|
||||
detail &&
|
||||
<Cards
|
||||
|
@ -86,18 +92,11 @@ function Detail(props){
|
|||
title={detail.nickname}
|
||||
desc={!buttonflag && detail.description}
|
||||
img={detail.avatar_url}
|
||||
rightBtn={
|
||||
<React.Fragment>
|
||||
{flag && !buttonflag && detail.is_admin ?
|
||||
<Link to={`/${OIdentifier}/setting`} className="color-blue ml10 font-14">设置<i className="iconfont icon-shezhi2 ml3 fr"></i></Link>
|
||||
:""}
|
||||
{buttonflag &&
|
||||
<span className="subNavs">
|
||||
<Link to={`/${OIdentifier}/members`} className={pathname ===`/${OIdentifier}/members` ? "active":""}><span>组织成员</span>{detail.num_users && <lable>{detail.num_users}</lable>}</Link>
|
||||
<Link to={`/${OIdentifier}/teams`} className={pathname ===`/${OIdentifier}/teams` ? "active":""}><span>组织团队</span>{detail.num_teams &&<lable>{detail.num_teams}</lable>}</Link>
|
||||
</span>
|
||||
}
|
||||
</React.Fragment>
|
||||
rightBtn={buttonflag && !enterpriseOpened &&
|
||||
<span className="subNavs">
|
||||
<Link to={`/${OIdentifier}/members`} className={pathname ===`/${OIdentifier}/members` ? "active":""}><span>组织成员</span>{detail.num_users && <lable>{detail.num_users}</lable>}</Link>
|
||||
<Link to={`/${OIdentifier}/teams`} className={pathname ===`/${OIdentifier}/teams` ? "active":""}><span>组织团队</span>{detail.num_teams &&<lable>{detail.num_teams}</lable>}</Link>
|
||||
</span>
|
||||
}
|
||||
bottomInfos={
|
||||
!buttonflag && <div>
|
||||
|
@ -137,19 +136,20 @@ function Detail(props){
|
|||
}}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/:OIdentifier/setting"
|
||||
render={(p) => {
|
||||
return <Setting {...props} {...p} organizeDetail={detail} updateFunc={getDetail}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/:OIdentifier"
|
||||
path="/:OIdentifier/setting"
|
||||
render={(p) => {
|
||||
return <DetailIndex {...props} {...p} organizeDetail={detail}/>
|
||||
return <Setting {...props} {...p} organizeDetail={detail} updateFunc={updateDetail} enterpriseOpened={enterpriseOpened}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/:OIdentifier/enterprise"
|
||||
render={(p) => {
|
||||
return <Enterprise {...props} {...p} organizeDetail={detail}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Pagination , Spin } from 'antd';
|
|||
import AddMemberBox from './Component/AddMemberBox';
|
||||
|
||||
const limit = 16;
|
||||
function TeamMember({organizeDetail,current_user,history,match}){
|
||||
function TeamMember({organizeDetail,current_user,history,match,enterpriseOpened}){
|
||||
const OIdentifier = match.params.OIdentifier;
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
|
@ -46,7 +46,7 @@ function TeamMember({organizeDetail,current_user,history,match}){
|
|||
<WhiteBack style={{marginBottom:"30px",border:'1px solid #eee'}}>
|
||||
<Banner>组织成员
|
||||
{
|
||||
organizeDetail && organizeDetail.is_admin &&
|
||||
!enterpriseOpened && organizeDetail && organizeDetail.is_admin &&
|
||||
<AddMemberBox
|
||||
className="addMemberBtn"
|
||||
orzId={organizeDetail && organizeDetail.id}
|
||||
|
|
|
@ -136,8 +136,8 @@ class Attachment extends Component {
|
|||
<span className="ml20">{item.filesize}</span>
|
||||
</a>
|
||||
) : (
|
||||
<Link
|
||||
to={`${item.url}`}
|
||||
<a
|
||||
href={`${item.url}`}
|
||||
target="_blank"
|
||||
className="attachment-list-a"
|
||||
download
|
||||
|
@ -145,7 +145,7 @@ class Attachment extends Component {
|
|||
<i className="iconfont icon-fujian mr8 paper-clip-color font-12"></i>
|
||||
<span>{item.title}</span>
|
||||
<span className="ml20">{item.filesize}</span>
|
||||
</Link>
|
||||
</a>
|
||||
)}
|
||||
|
||||
{canDelete ? (
|
||||
|
|
|
@ -84,7 +84,7 @@ class Read extends Component {
|
|||
暂仅支持文本格式,不支持图片,excel等不可以txt读取的文件
|
||||
</p> */}
|
||||
<p className="mt10">
|
||||
文件名请使用英文且不得超过{size}MB
|
||||
文件名请使用英文且不得超过{size}MB<span style={{color:"#f07622"}}>(超过{size}MB文件请用git工具上传)</span>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
|