From 2ecdd73c7f635dd34a4b65393dd8d69af46defa2 Mon Sep 17 00:00:00 2001 From: caishi <1149225589@qq.com> Date: Mon, 28 Dec 2020 20:42:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=96=E5=9B=B4=E8=B4=A1=E7=8C=AE=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AppConfig.js | 2 +- src/common/TextUtil.js | 2 +- src/forge/Main/Detail.js | 40 +++++++++------ src/forge/Main/Index.js | 37 +++++++------- src/forge/Main/Index.scss | 12 +++++ src/forge/Main/IndexItem.js | 42 ++++++++++++++-- src/forge/Main/SpecialModal.jsx | 45 +++++++++++++++++ src/forge/Main/list.css | 1 + src/forge/New/Index.js | 25 ++++++++-- src/forge/Settings/Collaborator.js | 10 +++- src/forge/Settings/Setting.js | 7 ++- src/forge/Settings/setting.scss | 3 ++ src/forge/Upload/Index.js | 5 +- src/forge/Upload/single.jsx | 78 ++++++++++++++++++++++++++++++ src/forge/Upload/untitled | 21 -------- src/forge/UsersList/list.css | 3 ++ src/forge/css/index.scss | 2 +- 17 files changed, 263 insertions(+), 72 deletions(-) create mode 100644 src/forge/Main/SpecialModal.jsx create mode 100644 src/forge/Upload/single.jsx delete mode 100644 src/forge/Upload/untitled diff --git a/src/AppConfig.js b/src/AppConfig.js index ca941733..a369d843 100644 --- a/src/AppConfig.js +++ b/src/AppConfig.js @@ -58,7 +58,7 @@ export function initAxiosInterceptors(props) { // TODO 避免重复的请求 https://github.com/axios/axios#cancellation var proxy = "http://localhost:3000"; - proxy = "http://39.105.176.215:49999"; + proxy = "https://testforgeplus.trustie.net"; const requestMap = {}; window.setfalseInRequestMap = function (keyName) { diff --git a/src/common/TextUtil.js b/src/common/TextUtil.js index 94e73631..4a1441fc 100644 --- a/src/common/TextUtil.js +++ b/src/common/TextUtil.js @@ -68,7 +68,7 @@ export function appendFileSizeToUploadFile(item) { return `${item.title}${uploadNameSizeSeperator}${item.filesize}` } export function appendFileSizeToUploadFileAll(fileList) { - return fileList.map(item => { + return fileList && fileList.map(item => { if (item.name.indexOf(uploadNameSizeSeperator) == -1) { return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` }) } diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js index cccab05b..d4354a40 100644 --- a/src/forge/Main/Detail.js +++ b/src/forge/Main/Detail.js @@ -4,23 +4,13 @@ import { Link, Route, Switch } from 'react-router-dom'; import { Content } from '../Component/layout'; import '../css/index.scss' import './list.css'; +import SpecialModal from './SpecialModal'; import Loadable from 'react-loadable'; import Loading from '../../Loading'; import axios from 'axios'; -import img_1 from '../Images/1.png'; -import img_2 from '../Images/2.png'; -import img_3 from '../Images/3.png'; -import img_6 from '../Images/6.png'; -import img_7 from '../Images/7.png'; -import img_parise from '../Images/parise.png'; -import img_focus from '../Images/focus.png'; -import img_parised from '../Images/parised.png'; -import img_focused from '../Images/focused.png'; -import img_fork from '../Images/fork.png'; -import img_milepost from '../Images/milepost.png'; const Setting = Loadable({ loader: () => import('../Settings/Index'), loading: Loading, @@ -172,7 +162,9 @@ class Detail extends Component { defaultBranch:undefined, // 非本平台项目 - platform:false + platform:false, + visible:false, + user_apply_signatures:[] } } @@ -198,6 +190,14 @@ class Detail extends Component { open_devops:result.data.open_devops, platform:result.data.platform && result.data.platform !== 'educoder' }) + let signa = result.data.user_apply_signatures && result.data.user_apply_signatures[0]; + if(result.data.is_secret && (signa && signa.status !== "passed")){ + this.setState({ + visible:true, + is_secret:result.data.is_secret, + user_apply_signatures:signa + }) + } // 工作流:两种状态进入的链接不同 const pathname = this.props.history.location.pathname; @@ -378,13 +378,24 @@ class Detail extends Component { }) } + hideModal=()=>{ + this.setState({ + visible:false + }) + } + + sureModal=()=>{ + this.hideModal(); + this.props.history.push('/projects'); + } + render() { const { projectDetail, watchers_count, praises_count, forked_count, firstSync , secondSync , isManager, watched, praised, - project , open_devops , platform , defaultBranch } = this.state; + project , open_devops , platform , defaultBranch , project_id , user_apply_signatures , visible } = this.state; const url = this.props.history.location.pathname; const urlArr = url.split("/"); const urlFlag = (urlArr.length === 3); @@ -411,6 +422,7 @@ class Detail extends Component { } return (
+
@@ -503,7 +515,7 @@ class Detail extends Component {
  • - + 主页
  • diff --git a/src/forge/Main/Index.js b/src/forge/Main/Index.js index 9f4cfb8a..9cba30fe 100644 --- a/src/forge/Main/Index.js +++ b/src/forge/Main/Index.js @@ -1,7 +1,6 @@ import React, { Component } from 'react'; import { Link } from 'react-router-dom'; -import { Menu, Input , Spin, Pagination , Popover , Select } from 'antd'; -import { getUrl } from 'educoder'; +import { Menu, Input , Spin, Pagination , Popover } from 'antd'; import '../css/index.scss' import './list.css'; import './Index.scss'; @@ -37,8 +36,8 @@ class Index extends Component { } componentDidMount = () => { - const { page, limit, search, sort, project_type, category_id , languageId } = this.state; - this.getListData(page, limit, search, sort, project_type, category_id , languageId); + const { page,search, sort, project_type, category_id , languageId } = this.state; + this.getListData(page,search, sort, project_type, category_id , languageId); this.getType(); @@ -73,14 +72,14 @@ class Index extends Component { } // 获取列表 - getListData = (page, limit, search, sort, project_type, category_id,languageId) => { + getListData = (page,search, sort, project_type, category_id,languageId) => { const { current_user } = this.props; const url = `/projects.json`; axios.get(url, { params: { user_id: current_user && current_user.user_id, page, - limit, + limit:15, search, sort_by: sort, project_type, @@ -131,8 +130,8 @@ class Index extends Component { search: undefined }) this.setTypeList(list, type) - const { page, limit, sort, category_id , languageId } = this.state; - this.getListData(page, limit, undefined, sort, type, category_id , languageId); + const { page,sort, category_id , languageId } = this.state; + this.getListData(page,undefined, sort, type, category_id , languageId); } // 获取类型 @@ -167,8 +166,8 @@ class Index extends Component { page: 1 }); this.setCategoryList(list, id) - const { limit, sort, project_type , languageId } = this.state; - this.getListData(1, limit, undefined, sort, project_type, id , languageId); + const { sort, project_type , languageId } = this.state; + this.getListData(1,undefined, sort, project_type, id , languageId); } // 排序 @@ -179,8 +178,8 @@ class Index extends Component { search: undefined, isSpin: true }) - const { limit, project_type, category_id , languageId } = this.state; - this.getListData(1, limit, undefined, e.key, project_type, category_id , languageId); + const {project_type, category_id , languageId } = this.state; + this.getListData(1,undefined, e.key, project_type, category_id , languageId); } // 搜索 @@ -192,8 +191,8 @@ class Index extends Component { project_type: undefined, sort: "updated_on" }) - const { limit, sort, category_id , languageId } = this.state; - this.getListData(1, limit, value, sort, undefined, category_id , languageId); + const {sort, category_id , languageId } = this.state; + this.getListData(1,value, sort, undefined, category_id , languageId); } changeSearchValue = (e) => { this.setState({ @@ -205,8 +204,8 @@ class Index extends Component { this.setState({ page }) - const { limit, search, sort, project_type, category_id , languageId } = this.state; - this.getListData(page, limit, search, sort, project_type, category_id , languageId); + const {search, sort, project_type, category_id , languageId } = this.state; + this.getListData(page,search, sort, project_type, category_id , languageId); } getoDetail=(login,identifier)=>{ @@ -219,8 +218,8 @@ class Index extends Component { isSpin:true, languageId:e === 0 ?undefined:e }) - const { page, limit, sort , project_type , category_id } = this.state; - this.getListData(page, limit, undefined, sort, project_type, category_id ,e === 0 ?undefined:e); + const { page,sort , project_type , category_id } = this.state; + this.getListData(page, undefined, sort, project_type, category_id ,e === 0 ?undefined:e); } menu =()=> { @@ -329,7 +328,7 @@ class Index extends Component {
- + {this.pagination(total,limit,page)}
diff --git a/src/forge/Main/Index.scss b/src/forge/Main/Index.scss index cb006f67..381572f6 100644 --- a/src/forge/Main/Index.scss +++ b/src/forge/Main/Index.scss @@ -71,4 +71,16 @@ text-align: right; } } +} +.singleBtn{ + display: inline-block; + .ant-upload-list-item{ + position: absolute; + bottom: 0px; + width: 100%; + left: 0px; + .ant-upload-list-item-name{ + text-align: left; + } + } } \ No newline at end of file diff --git a/src/forge/Main/IndexItem.js b/src/forge/Main/IndexItem.js index f0658f38..fa783767 100644 --- a/src/forge/Main/IndexItem.js +++ b/src/forge/Main/IndexItem.js @@ -6,23 +6,58 @@ import '../css/index.scss'; import Nodata from '../Nodata'; import './list.css'; import img_parise from '../Images/parise.png'; +import SpecialModal from './SpecialModal'; class IndexItem extends Component { + constructor(props){ + super(props); + this.state={ + visible:false, + user_apply_signatures:[], + project_id:undefined + } + } TurnToDetail = (login, url) => { this.props.history.push({ pathname: url, state: login }) } + + projectHref=(link , user_apply_signatures,project_id,is_secret)=>{ + let signa = user_apply_signatures && user_apply_signatures[0]; + if(is_secret && (signa && signa.status !== "passed")){ + this.setState({ + visible:true, + user_apply_signatures:user_apply_signatures.length>0 ? user_apply_signatures[0] : undefined, + project_id + }) + }else{ + this.props.history.push(link); + } + } + hideModal=()=>{ + this.setState({ + visible:false + }) + } + + sureModal=()=>{ + this.hideModal(); + const { getListData } = this.props; + getListData && getListData(1); + } + render() { const { projects } = this.props; + const { visible , user_apply_signatures , project_id } = this.state; const renderList = ( projects && projects.length > 0 ? projects.map((item, key) => { return (
{ item.platform === "educoder" ? - + : @@ -32,7 +67,7 @@ class IndexItem extends Component { }
- + this.projectHref(`/projects/${item.author.login}/${item.identifier}`,item.user_apply_signatures, item.id,item.is_secret)} className="hide-1 color-grey-3 font-18 task-hide fwt-500 " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}> {item.author.name}/{item.name} { item.forked_from_project_id ? @@ -51,7 +86,7 @@ class IndexItem extends Component { :"" } - + 赞 {item.praises_count} fork {item.forked_count} @@ -74,6 +109,7 @@ class IndexItem extends Component { ) return (
+ {renderList}
) diff --git a/src/forge/Main/SpecialModal.jsx b/src/forge/Main/SpecialModal.jsx new file mode 100644 index 00000000..afd021f2 --- /dev/null +++ b/src/forge/Main/SpecialModal.jsx @@ -0,0 +1,45 @@ +import React , { useEffect , useState } from 'react'; +import { Modal } from 'antd'; +import UploadSingle from '../Upload/single'; +import './Index.scss'; +import axios from 'axios'; +import { getUrl } from 'educoder'; + +function SpecialModal({ visible , hideModal , sureModal , showNotification , user_apply_signatures , project_id }){ + const [ id ,setId ] = useState(undefined); + + + function loadFunc(id){ + setId(id); + } + + function sure(){ + if(!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting")){ + const url = `/apply_signatures.json`; + axios.post(url,{ + attachment_id:id, + project_id:project_id + }).then(result=>{ + if(result && result.data.id){ + showNotification("已提交文件,正在等待审核!"); + sureModal(); + } + }) + }else{ + sureModal(); + } + } + return( + + { + !user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting") ? +
+
该项目为私有项目,请先下载开源协议,阅读并填写
相关信息后,将协议上传,平台审核通过后即可进入当前项目
+
+ : +

您上传的文件正在审核中,通过后才能访问当前项目

+ } +
+ ) +} +export default SpecialModal; \ No newline at end of file diff --git a/src/forge/Main/list.css b/src/forge/Main/list.css index 522cd516..dd40d404 100644 --- a/src/forge/Main/list.css +++ b/src/forge/Main/list.css @@ -220,6 +220,7 @@ text-align: center; height: 40px; line-height: 28px; + border:1px solid transparent; } .headerMenu-wrapper{ font-size: 16px; diff --git a/src/forge/New/Index.js b/src/forge/New/Index.js index 7d7a5ee0..3d6b4ec3 100644 --- a/src/forge/New/Index.js +++ b/src/forge/New/Index.js @@ -38,7 +38,9 @@ class Index extends Component { project_language_name: undefined, project_category_name: undefined, license_name: undefined, - ignore_name: undefined + ignore_name: undefined, + + licenseForDisabled:undefined } } componentDidMount = () => { @@ -114,7 +116,7 @@ class Index extends Component { _data = data.filter(item => item.name.toLowerCase().indexOf(name.toLowerCase()) > -1); } let list = _data && _data.map((item) => ( - )); @@ -124,6 +126,17 @@ class Index extends Component { } } + selectSerect=(flag)=>{ + if(flag){ + this.props.form.setFieldsValue({ + private:true + }) + } + this.setState({ + licenseForDisabled:flag + }) + } + subMitFrom = () => { this.props.form.validateFieldsAndScroll((err, values) => { if (!err) { @@ -168,7 +181,8 @@ class Index extends Component { } ChangePlatform = (value, e, name, list) => { - this.setOptionsList(list, name, value) + this.setOptionsList(list, name, value); + this.setState({ [name + "_id"]: e.key, [name + "_name"]: value, @@ -249,6 +263,7 @@ class Index extends Component { project_category_list, license_list, ignore_list, + licenseForDisabled, mirrorCheck } = this.state; @@ -434,8 +449,8 @@ class Index extends Component { style={{ margin: "0px" }} className="privatePart" > - {getFieldDecorator('private')( - 将项目设为私有(只有项目所有人或拥有权限的项目成员才能看到) + {getFieldDecorator('private',{valuePropName:"checked"})( + 将项目设为私有(只有项目所有人或拥有权限的项目成员才能看到) )} { diff --git a/src/forge/Settings/Collaborator.js b/src/forge/Settings/Collaborator.js index d1e6d7d1..cda25a5c 100644 --- a/src/forge/Settings/Collaborator.js +++ b/src/forge/Settings/Collaborator.js @@ -290,8 +290,10 @@ class Collaborator extends Component { return "text-green"; } else if (role === "Developer") { return "text-primary"; - } else { + } else if(role === "Reporter"){ return "text-yellow"; + }else{ + return "text-gray"; } }; const member_roles = (item) => { @@ -302,7 +304,11 @@ class Collaborator extends Component { - ) : ( + ) : + item.is_apply_signature ? + + : + ( {operation && operation[0].name} diff --git a/src/forge/Settings/Setting.js b/src/forge/Settings/Setting.js index 729ea2a5..2c1989af 100644 --- a/src/forge/Settings/Setting.js +++ b/src/forge/Settings/Setting.js @@ -15,6 +15,7 @@ class Setting extends Component { CategoryList: undefined, LanguageList: undefined, private_check: undefined, + is_secret:false }; } @@ -52,10 +53,11 @@ class Setting extends Component { .then((result) => { if (result) { this.props.form.setFieldsValue({ - ...result.data, + ...result.data }); this.setState({ private_check: result.data.private, + is_secret:result.data.is_secret }); } }) @@ -152,7 +154,7 @@ class Setting extends Component { render() { const { getFieldDecorator } = this.props.form; - const { CategoryList, LanguageList, private_check } = this.state; + const { CategoryList, LanguageList, private_check , is_secret } = this.state; return (
@@ -177,6 +179,7 @@ class Setting extends Component { 将仓库设为私有 diff --git a/src/forge/Settings/setting.scss b/src/forge/Settings/setting.scss index 35726cba..3d1d6aeb 100644 --- a/src/forge/Settings/setting.scss +++ b/src/forge/Settings/setting.scss @@ -151,6 +151,9 @@ .text-yellow{color: #FF6E21 !important;} .text-delete{color: #BBBBBB; } .text-delete:hover{color: #db2828; } +.text-grey{ + color: #999; +} .new-tag-div{ padding: 15px; height: 75px; diff --git a/src/forge/Upload/Index.js b/src/forge/Upload/Index.js index 2c751b16..d2113f6f 100644 --- a/src/forge/Upload/Index.js +++ b/src/forge/Upload/Index.js @@ -1,5 +1,5 @@ import React, { Component } from "react"; -import { Upload, Button, Icon } from 'antd'; +import { Upload , Icon } from 'antd'; import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder'; import axios from 'axios'; @@ -45,8 +45,7 @@ class Index extends Component { deleteAttachment = (file) => { const url = `/attachments/${file.response ? file.response.id : file.uid}.json` - axios.delete(url, { - }).then((response) => { + axios.delete(url).then((response) => { if (response.data) { if (response.data.status === 0) { this.setState((state) => { diff --git a/src/forge/Upload/single.jsx b/src/forge/Upload/single.jsx new file mode 100644 index 00000000..45e3f1a5 --- /dev/null +++ b/src/forge/Upload/single.jsx @@ -0,0 +1,78 @@ +import React, { useEffect , useState } from "react"; +import { Upload } from 'antd'; +import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder'; + +import axios from 'axios'; + +function Single({ children , showNotification , className , load , size }) { + const [ fileList , setFileList ] = useState(undefined); + // 移除 + function onAttachmentRemove(file){ + if (!file.percent || file.percent === 100) { + deleteAttachment(file); + return false; + } + } + + function deleteAttachment(file){ + let uid = file.response ? file.response.id : file.uid; + const url = `/attachments/${uid}.json` + axios.delete(url).then((response) => { + if (response.data && response.data.status === 0) { + let list = fileList.filter(item=> item.response && item.response.id !== uid); + setFileList(list); + fileIdList(list); + } + }).catch(error=>{}); + } + + + function handleChange(info){ + if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') { + let fileList = [info.file]; + + let list = appendFileSizeToUploadFileAll(fileList); + setFileList(list); + if ( info.file.status === 'done') { + let f = info.fileList && info.fileList.length>0 && info.fileList[info.fileList.length-1]; + if(f && f.response && f.response.status === -1){ + showNotification(f.response.message) + setFileList(f); + } + fileIdList(fileList); + } + } + } + + function fileIdList(fileList){ + let l = fileList && fileList.length > 0 && fileList[0]; + let array = [l && l.response && l.response.id]; + load && load(array); + } + + function beforeUpload(file){ + if(!size) return; + const isLt100M = file.size / 1024 / 1024 < size; + if (!isLt100M) { + this.props.showNotification(`文件大小必须小于${size}MB!`); + } + return isLt100M; + } + + //判断是否已经提交,如已提交评论则上一条评论数据清除 + const upload = { + name: 'file', + fileList: fileList, + action: `${getUploadActionUrl()}`, + onChange: handleChange, + onRemove: onAttachmentRemove, + beforeUpload: beforeUpload + }; + + return ( + + {children} + + ) +} +export default Single; \ No newline at end of file diff --git a/src/forge/Upload/untitled b/src/forge/Upload/untitled deleted file mode 100644 index 2796e4d7..00000000 --- a/src/forge/Upload/untitled +++ /dev/null @@ -1,21 +0,0 @@ - -1.请求URL: https://code.ihub.org.cn/api/v1/mirrors/create.json - -2.请求方式: POST - -3.参数: - -{ - "image_url": "xxx.git", #必填,且后缀必为.git, - "language": "Ruby", #必填,如数据库不存在,则会创建新的记录 -} - - -4. 返回值: { - "status": 1, - "message": "同步成功,项目ID===1806" -} - -5. 返回值说明: 仅有当有返回值,且返回值的status 的值为1, 才是创建成功,其余均为创建失败 - - diff --git a/src/forge/UsersList/list.css b/src/forge/UsersList/list.css index 2de17ea1..2a8e63b6 100644 --- a/src/forge/UsersList/list.css +++ b/src/forge/UsersList/list.css @@ -62,6 +62,9 @@ .text-yellow{ color: #FFA802 !important } +.text-grey{ + color: #999; +} .text-gray { color: #888888; } diff --git a/src/forge/css/index.scss b/src/forge/css/index.scss index 82844d4e..55f8ba03 100644 --- a/src/forge/css/index.scss +++ b/src/forge/css/index.scss @@ -159,7 +159,7 @@ form{ background-color: #fff; .list-affix{ min-height: 20px; - max-height: 60vh; + max-height: 180px; overflow-y: auto; } & li{