Merge pull request 'issue' (#516) from durian/forgeplus-react:gitlink_server_issue into gitlink_server_issue

This commit is contained in:
caishi 2023-03-10 15:22:32 +08:00
commit 2ec69c4322
6 changed files with 78 additions and 37 deletions

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Button, Popconfirm, Radio, Input, message, Tooltip, Spin } from 'antd';
import { Button, Popconfirm, Radio, Input, message, Tooltip, Spin, Pagination } from 'antd';
import axios from 'axios';
import { getImageUrl, timeAgo } from 'educoder';
import RenderHtml from '../../../../components/render-html';
@ -27,6 +27,10 @@ function IssueCommentList(props){
const [spin, setSpin] = useState(false);
// issue
const [journalsCount, setJournalsCount] = useState(undefined);
//
const limit = 50;
const [page, setPage] = useState(1);
const [totalCount, setTotalCount] = useState(undefined);
// icon
const journalsIcon ={
'issue': 'icon-chuangjianqianbao',
@ -46,10 +50,12 @@ function IssueCommentList(props){
useEffect(()=>{
setSpin(true);
axios.get(`/v1/${owner}/${projectsId}/issues/${index}/journals`,{params:{
category
category,
page,
limit
}}).then(res=>{
if(res && res.data){
const {journals, total_comment_journals_count} = res.data;
const {journals, total_comment_journals_count, total_count} = res.data;
if(category === 'all'){
const array = [];
let start = undefined;
@ -74,12 +80,13 @@ function IssueCommentList(props){
}
})
}
setTotalCount(total_count);
setJournalsCount(total_comment_journals_count);
setJournals(journals);
setSpin(false)
}
})
}, [reload, category])
}, [reload, category, page])
function commentCtx(v){
return <RenderHtml className="break_word_comments imageLayerParent commentRenderHtml" value={v} url={location}/>;
@ -104,7 +111,7 @@ function IssueCommentList(props){
<div className="commentListBox">
{/* 全部 / 评论 / 操作日志 */}
<div className='typeActionBox mt30 mb20'>
<Radio.Group onChange={(e)=>{setSpin(true);setCategory(e.target.value)}} value={category}>
<Radio.Group onChange={(e)=>{setSpin(true);setPage(1);setCategory(e.target.value)}} value={category}>
<Radio value={'comment'} className='typeActionRadio font-14'>评论<span className='journalsCount font-13 ml5'>{journalsCount}</span></Radio>
<Radio value={'operate'} className='typeActionRadio font-14'>操作日志</Radio>
<Radio value={'all'} className='typeActionRadio font-14'>全部</Radio>
@ -130,15 +137,15 @@ function IssueCommentList(props){
{journals && (journals.length > 0 && journals.map(item=>{return item.is_journal_detail ? (!item.closeAndSpan || item.id === item.start || open === item.start) ? <div key={item.id} className='operationLog'>
{/* 操作日志 */}
<div className='operationCommentBor'></div>
<div className='flexCenter font-13' style={{flex: 1}}>
<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={{flex: '1'}}>
<div className='task-hide' 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}&nbsp;</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>}
</div>
<span className='ml15 timeAgo font-12'>{timeAgo(item.created_at)}</span>
<span className='ml15 timeAgo font-14'>{timeAgo(item.created_at)}</span>
</div>
{(item.closeAndSpan && item.id === item.start) && <a className='primaryColor' onClick={()=>{setOpen(open === item.id ? undefined : item.id)}}>{open === item.id ? `点击收起操作日志` : `已折叠${item.numCount}条, 点击查看`}<i className={`iconfont ${open === item.id ? `icon-sanjiaoxing-up` : 'icon-sanjiaoxing-down'} font-15`}></i></a>}
</div>
@ -153,7 +160,7 @@ function IssueCommentList(props){
<div className='flexCenter font-14'>
<div>
<Link to={`/${item.user.login}`}>{item.user.name}</Link>
<span className='ml15 timeAgo font-15'>{timeAgo(item.created_at)}</span>
<span className='ml15 timeAgo font-14'>{timeAgo(item.created_at)}</span>
</div>
{login && <div>
{/* 平台管理员/仓库管理员/发布评论者/issue创建者 */}
@ -167,8 +174,8 @@ function IssueCommentList(props){
<Button type='link' className='color-grey-89'><i className='iconfont icon-fuzhi-shanchu font-14 mr8'></i>删除</Button>
</Popconfirm>}
{/* 仅评论者可修改 */}
{login === item.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(item.id); setShowEdit(2)}}><i className='iconfont icon-a-bianji12 font-13 mr8'></i>修改</Button>}
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id); setReplyId(item.id); setShowEdit(3)}}><Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-13 mr8'></i>回复</Button></CheckProfile>
{login === item.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(item.id); setShowEdit(2)}}><i className='iconfont icon-a-bianji12 font-14 mr8'></i>修改</Button>}
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id); setReplyId(item.id); setShowEdit(3)}}><Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-14 mr8'></i>回复</Button></CheckProfile>
</div>}
</div>
<div className='contentHtml mb5'>{commentCtx(item.notes)}</div>
@ -189,7 +196,7 @@ function IssueCommentList(props){
<Link to={`/${i.user.login}`}>{i.user.name}</Link>
{i.reply_user && <span className='ml5 timeAgo mr3'>回复</span>}
<span>{i.reply_user && i.reply_user.name}</span>
<span className='ml15 timeAgo font-15'>{timeAgo(i.created_at)}</span>
<span className='ml15 timeAgo font-14'>{timeAgo(i.created_at)}</span>
</div>
{login && <div>
{/* 平台管理员/仓库管理员/发布评论者/回复评论者/issue创建者 */}
@ -203,9 +210,9 @@ function IssueCommentList(props){
<Button type='link' className='color-grey-89'><i className='iconfont icon-fuzhi-shanchu font-14 mr8'></i>删除</Button>
</Popconfirm>}
{/* 仅回复评论者可修改 */}
{login === i.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(i.id); setShowEdit(4)}}><i className='iconfont icon-a-bianji12 font-13 mr8'></i>修改</Button>}
{login === i.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(i.id); setShowEdit(4)}}><i className='iconfont icon-a-bianji12 font-14 mr8'></i>修改</Button>}
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id);setReplyId(i.id); setShowEdit(5)}}>
<Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-13 mr8'></i>回复</Button>
<Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-14 mr8'></i>回复</Button>
</CheckProfile>
</div>}
</div>
@ -222,6 +229,9 @@ function IssueCommentList(props){
</div>}))}
</div>
</Spin>
{totalCount>limit && <div className='mt20 paginationIssueComment mb20'>
<Pagination simple current={page} pageSize={limit} total={totalCount} onChange={(page)=>setPage(page)}/>
</div>}
{/* 无数据 */}
{journals && !journals.length && <Nodata _html="暂无数据"/>}
</div>

View File

@ -189,4 +189,7 @@
width: 100%;
height: 30px;
border: none;
}
.paginationIssueComment{
text-align: center;
}

View File

@ -220,7 +220,7 @@ class Index extends Component {
user_id:owners_id,
blockchain: tokenConTri,
blockchain_token_all: 10000,
blockchain_init_token: blockchain_init && blockchain_init/100
blockchain_init_token: parseInt(blockchain_init)
}).then((result) => {
if (result && result.data.id) {
projectsType && projectsType !== "mirror" && this.props.showNotification(`项目创建成功!`);
@ -651,7 +651,9 @@ class Index extends Component {
required: tokenConTri, message: '初始token值为一个不超过10000的正整数'
},
{ validator: (rule,val,callback) =>{
if(val>10000){
if(!/^[1-9]+[0-9]*]*$/.test(val)){
callback('初始token值为正整数');
}if(val>10000){
callback('初始token值最大值10000');
}else{
callback();

View File

@ -20,7 +20,7 @@ export default Form.create()(
function checkPsd(rule, value, callback){
const map = passMap;
if(value){
current_user && value.length > 8 && Axios.post(`/v1/${current_user.login}/check_password.json`,{
current_user && value.length > 7 && Axios.post(`/v1/${current_user.login}/check_password.json`,{
password: value
}).then(res=>{
if(res && !res.data.status){

View File

@ -12,8 +12,7 @@ import { FlexAJ } from '../../Component/layout';
// -
function Contribution(props){
//
const limit = 15;
const limit = 10;
const [page, setPage] = useState(1);
const [total, setTotal] = useState(undefined);
//
@ -29,19 +28,42 @@ function Contribution(props){
const [error2, setError2] = useState(undefined);
// id
const [proId, setProId] = useState(undefined);
const { checkIfLogin , showLoginDialog , current_user:{user_id, login}, current_user } = props;
console.log('current_user', current_user);
const {current_user:{user_id, login, open_blockchain}, current_user} = props;
const {user} = props;
const username = props.match.params.username;
useEffect(()=>{
if((username && current_user && (current_user.login !== username)) || !open_blockchain){
props.history.push(`/${username}`);
}
},[current_user,username])
useEffect(()=>{
// token
axios.get(`/users/blockchain/balance.json`,{params: {user_id}}).then(res=>{
axios.get(`/users/blockchain/balance.json`,{params: {
user_id,
limit,
page
}}).then(res=>{
if(res && res.data){
setList(res.data.projects);
const {projects} = res.data;
const newProjects = [];
let deleteProjectCount = 0;
projects.map(item=>{
if(item.id){
newProjects.unshift(item);
}else{
deleteProjectCount++;
}
})
deleteProjectCount && newProjects.push({
'balance': deleteProjectCount
})
setList(newProjects);
setTotal(res.data.total_count);
}
})
}, [reload])
}, [reload, page])
useEffect(()=>{
if(user){
@ -53,14 +75,15 @@ function Contribution(props){
//
function getUser(id, login){
const userLoginObject = Object.assign(userLogin);
// 使JSON
const userLoginObject = JSON.parse(JSON.stringify(userLogin));
userLoginObject[id] = login;
setUserLogin(userLoginObject);
}
// token
function setToken(id, token){
const tokenCountObject = Object.assign(tokenCount);
const tokenCountObject = JSON.parse(JSON.stringify(tokenCount));
tokenCountObject[id] = token;
setTokenCount(tokenCountObject);
}
@ -80,7 +103,6 @@ function Contribution(props){
}else if(!/^[1-9]+[0-9]*]*$/.test(tokenCountById) || tokenCountById>max){
setError2('转账token数额必须为不超过token总数的正整数');
}else{
console.log('userLogin', userLoginById, 'tokenCount', tokenCountById);
axios.post(`/users/blockchain/transfer`, {
owner_login: login,
project_identifier: identifier,
@ -90,8 +112,9 @@ function Contribution(props){
payer_id: user_id,
project_id: id
}).then(res=>{
console.log('res', res);
if(res && res.data && res.data.status === 2){
getUser(id, undefined);
setToken(id, undefined);
setReload(Math.random());
message.success('转账成功');
}
@ -115,19 +138,19 @@ function Contribution(props){
<div className='tableColumn5'>操作</div>
</div>}
{list && !list.length && <Nodata _html="暂无数据"/>}
{list && list.map(item=>{return <div key={item.id} className='flexCenterCont transferAccount'>
{list && list.map(item=>{return item.id ? <div key={item.id} className='flexCenterCont transferAccount'>
<div className='tableColumn1'>{item.name}</div>
<div className='tableColumn2'>{item.balance}</div>
<div className='tableColumn3'>
<SearchUser getUser={(login)=>{getUser(item.id, login)}} width={"100%"} placeholder="搜索转账目标用户"/>
<SearchUser getUser={(login)=>{getUser(item.id, login)}} width={"100%"} placeholder="搜索转账目标用户" value={userLogin[item.id]}/>
{proId === item.id && error1 && <div className='errorTipTri'>{error1}</div>}
</div>
<div className='tableColumn4'>
<Input onChange={(e)=>{setToken(item.id, e.target.value)}} placeholder='请输入token数额'/>
<Input value={tokenCount[item.id]} onChange={(e)=>{setToken(item.id, e.target.value)}} placeholder='请输入token数额'/>
{proId === item.id && error2 && <div className='errorTipTri'>{error2}</div>}
</div>
<div className='tableColumn5'><Button className='confirmTransfer' onClick={()=>{confirmTransfer(item.id, item.identifier, item.balance)}}>确认</Button></div>
</div>})}
</div>: <div className='flexCenterCont transferAccount deleteRepo'>{item.balance}个项目被删除</div>})}
</div> : <div className='contributionTable mt20 record'>
<FlexAJ className='contributionRecordItem font-15'>
<span><span className='themeSpan'>蒋宇航</span><span className='themeSpan'>GilLink/确实开源</span>给你转账了1000个tiken</span>
@ -138,9 +161,9 @@ function Contribution(props){
<span className='tableHeadTri'>6小时前</span>
</FlexAJ>
</div>}
{/* {total > limit && <div className='mt20 paginationTri'>
{total > limit && <div className='mt20 paginationTri mb50'>
<Pagination simple current={page} pageSize={limit} total={total} onChange={(page)=>setPage(page)}/>
</div>} */}
</div>}
</div>
)
}

View File

@ -40,14 +40,17 @@
padding: 15px 0;
border-bottom: 1px solid #eee;
}
.deleteRepo{
color: slategrey;
}
.tableColumn3, .tableColumn4{
width: 200px;
width: 150px;
}
.tableColumn1{
width: 130px;
width: 200px;
}
.tableColumn5{
width: 120px;
width: 100px;
text-align: center;
}
.tableColumn2{