forked from Gitlink/forgeplus-react
Merge pull request '区块链版本' (#501) from Nigel/forgeplus-react:master_zxh into dev_nanda
This commit is contained in:
commit
cd2b383b0d
|
@ -1,3 +1,4 @@
|
|||
.idea/
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
|
|
@ -32,7 +32,8 @@ export function initAxiosInterceptors(props) {
|
|||
// 判断网络是否连接
|
||||
initOnlineOfflineListener();
|
||||
|
||||
var proxy = "https://testforgeplus.trustie.net";
|
||||
// var proxy = "https://testforgeplus.trustie.net";
|
||||
var proxy = "http://localhost:3001";
|
||||
//响应前的设置
|
||||
axios.interceptors.request.use(
|
||||
config => {
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
import React , { useState , useEffect } from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import { Blueback } from '../Component/layout';
|
||||
import Editor from "react-monaco-editor";
|
||||
import Modals from './DisposeModal';
|
||||
import FileLanguage from '../Component/OpsFileLanguage';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
function Dispose(props){
|
||||
const [ spining , setSpining ] = useState(true);
|
||||
const [ info , setInfo ] = useState('.trustie-pipeline.yml');
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ ymlValue , setYmlValue ] = useState("");
|
||||
const [ sha , setSha ] = useState(undefined);
|
||||
const [ fileLanguage , setFileLanguage ] = useState(undefined);
|
||||
const [ first , setFirst ] = useState(false);
|
||||
|
||||
let projectsId = props.match.params.projectsId;
|
||||
let owner = props.match.params.owner;
|
||||
useEffect(()=>{
|
||||
if(projectsId){
|
||||
const url = `/${owner}/${projectsId}/get_trustie_pipeline.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id:projectsId
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data.content){
|
||||
setInfo(result.data.name);
|
||||
setYmlValue(result.data.content);
|
||||
setFirst(true);
|
||||
setSha(result.data.sha);
|
||||
}else{
|
||||
setFirst(false);
|
||||
}
|
||||
setSpining(false);
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
},[projectsId])
|
||||
|
||||
// 修改文件内容
|
||||
function changeEditor(value){
|
||||
setYmlValue(value);
|
||||
}
|
||||
|
||||
// 切换语言
|
||||
function select_language(value,array){
|
||||
setFileLanguage(value);
|
||||
setYmlValue( array && array.content);
|
||||
}
|
||||
|
||||
// 确定提交
|
||||
function submit(){
|
||||
let url = '';
|
||||
const { defaultBranch } = props;
|
||||
let params = {
|
||||
branch: defaultBranch,
|
||||
content:ymlValue,
|
||||
filepath:info,
|
||||
message:''
|
||||
}
|
||||
if(first){
|
||||
// 为true,则是编辑否则是新建
|
||||
url = `/${owner}/${projectsId}/update_trustie_pipeline.json`;
|
||||
axios.put(url,{
|
||||
...params,
|
||||
sha
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setVisible(true);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}else{
|
||||
url = `/${owner}/${projectsId}/create_file.json`;
|
||||
axios.post(url,params).then(result=>{
|
||||
if(result){
|
||||
setVisible(true);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
function suresubmit(){
|
||||
setVisible(false);
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}
|
||||
|
||||
return(
|
||||
<Spin spinning={spining}>
|
||||
<Modals visible={visible} closeFunc={(flag)=>setVisible(flag)} sureFunc={suresubmit}></Modals>
|
||||
<p>编程语言:</p>
|
||||
|
||||
<div className="mt20 mb20">
|
||||
<FileLanguage language={fileLanguage} select_language={select_language}/>
|
||||
</div>
|
||||
<p>配置脚本:</p>
|
||||
<div className="editorBody">
|
||||
<p className="editorHead">{info}</p>
|
||||
<Editor
|
||||
height="300px"
|
||||
language={"yml"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue="请输入内容"
|
||||
value={ymlValue}
|
||||
options={"editor_options"}
|
||||
onChange={changeEditor}
|
||||
></Editor>
|
||||
</div>
|
||||
<Blueback onClick={submit}>确定提交</Blueback>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
export default Dispose;
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Tabs } from 'antd';
|
||||
import { Tabs, Select } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import { getImageUrl , turnbar } from "educoder";
|
||||
|
@ -19,6 +19,7 @@ import RenderHtml from "../../components/render-html";
|
|||
import "../Order/order.scss";
|
||||
import MergeLinkFooter from "./MergeLinkFooter";
|
||||
|
||||
const Option = Select.Option;
|
||||
const TextArea = Input.TextArea;
|
||||
class MessageCount extends Component {
|
||||
constructor(props) {
|
||||
|
@ -40,6 +41,11 @@ class MessageCount extends Component {
|
|||
conflict_files:[],
|
||||
|
||||
copyVisible:false,
|
||||
|
||||
fix_issue_id: "",
|
||||
unclosed_issue_list: [],
|
||||
ownername: undefined,
|
||||
reponame: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -53,6 +59,7 @@ class MessageCount extends Component {
|
|||
SpinFlag: true,
|
||||
});
|
||||
this.getDetail();
|
||||
this.getUnclosedIssueList();
|
||||
|
||||
// this.clickBody();
|
||||
// 监听路由query传参,实现nps调研效果
|
||||
|
@ -89,6 +96,8 @@ class MessageCount extends Component {
|
|||
|
||||
getDetail = () => {
|
||||
const { projectsId, mergeId, owner } = this.props.match.params;
|
||||
this.state.ownername = owner;
|
||||
this.state.reponame = projectsId;
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}.json`;
|
||||
axios
|
||||
.get(url)
|
||||
|
@ -149,7 +158,7 @@ class MessageCount extends Component {
|
|||
SpinMerge: true,
|
||||
});
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { data, title, body, mergekey, pr_status } = this.state;
|
||||
const { data, title, body, mergekey, pr_status, fix_issue_id } = this.state;
|
||||
const url = `/${owner}/${projectsId}/pulls/${data.pull_request.id}/pr_merge.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
|
@ -158,6 +167,7 @@ class MessageCount extends Component {
|
|||
do: mergekey,
|
||||
body: body,
|
||||
title: title,
|
||||
fix_issue_id: fix_issue_id,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
|
@ -194,6 +204,47 @@ class MessageCount extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
changefixissue = (e) => {
|
||||
this.setState({
|
||||
fix_issue_id: parseInt(e.target.value),
|
||||
});
|
||||
};
|
||||
|
||||
renderIssueList = (list) => {
|
||||
if (list && list.length > 0) {
|
||||
return list.map((item, index) => {
|
||||
return (
|
||||
<Option
|
||||
key={item[0]}
|
||||
value={item[0]}
|
||||
>
|
||||
{item[0] + ":" + item[1]}
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
getUnclosedIssueList = () => {
|
||||
const url = `/projects/blockchain/get_unclosed_issue_list`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
"ownername": this.state.ownername,
|
||||
"reponame": this.state.reponame
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
this.state.unclosed_issue_list = result.data.unclosed_issues;
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
selectIssueChange = (selectedKeys, info) => {
|
||||
this.state.fix_issue_id = selectedKeys;
|
||||
};
|
||||
|
||||
submitmerge = () => {
|
||||
if (this.state.mergekey === "rebase") {
|
||||
this.setState({
|
||||
|
@ -593,6 +644,21 @@ class MessageCount extends Component {
|
|||
value={this.state.body}
|
||||
onChange={this.changbodypr}
|
||||
/>
|
||||
{/*<Input*/}
|
||||
{/* type="select"*/}
|
||||
{/* placeholder="请选择解决的issue"*/}
|
||||
{/* style={{ marginTop: 20 }}*/}
|
||||
{/* value={this.state.fix_issue_id}*/}
|
||||
{/* onChange={this.changefixissue}*/}
|
||||
{/*/>*/}
|
||||
<Select
|
||||
id = {'select_project'}
|
||||
style={{ marginTop: 20, width: "500px" }}
|
||||
placeholder={"请选择解决的易修"}
|
||||
onSelect={this.selectIssueChange}
|
||||
>
|
||||
{this.renderIssueList(this.state.unclosed_issue_list)}
|
||||
</Select>
|
||||
</div>
|
||||
<div
|
||||
className="clearfix mt15"
|
||||
|
|
|
@ -7,6 +7,8 @@ import { AlignCenter } from '../Component/layout';
|
|||
import '../css/index.scss';
|
||||
import './new.scss'
|
||||
|
||||
import { findDOMNode } from 'react-dom'
|
||||
|
||||
import axios from 'axios';
|
||||
const Option = Select.Option;
|
||||
class Index extends Component {
|
||||
|
@ -46,11 +48,11 @@ class Index extends Component {
|
|||
license_name: undefined,
|
||||
ignore_name: undefined,
|
||||
descNum:0,
|
||||
|
||||
categoreFlag:false,
|
||||
languageFlag:false,
|
||||
ignoreFlag:false,
|
||||
licenseFlag:false,
|
||||
show_div:"hidden",
|
||||
}
|
||||
}
|
||||
componentDidMount = () => {
|
||||
|
@ -77,7 +79,7 @@ class Index extends Component {
|
|||
getOwner=()=>{
|
||||
const { OIdentifier } = this.props.match.params;
|
||||
const { user_id } = this.props && this.props.current_user;
|
||||
|
||||
|
||||
const url = `/owners.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
|
@ -200,8 +202,8 @@ class Index extends Component {
|
|||
isSpin: true
|
||||
})
|
||||
const { projectsType } = this.props.match.params;
|
||||
const {
|
||||
project_language_id, project_category_id, license_id, ignore_id , owners_id ,
|
||||
const {
|
||||
project_language_id, project_category_id, license_id, ignore_id , owners_id ,
|
||||
ignoreFlag,licenseFlag,categoreFlag,languageFlag
|
||||
} = this.state;
|
||||
const decoderPass = Base64.encode(values.password);
|
||||
|
@ -299,6 +301,19 @@ class Index extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
// add by zxh: handleBlockchainChange
|
||||
handleBlockchainChange = (event) => {
|
||||
if (this.state.show_div == 'hidden') {
|
||||
this.setState({
|
||||
show_div: "visible"
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
show_div: "hidden"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
changeDesc=(e)=>{
|
||||
let value = e.target.value;
|
||||
this.setState({
|
||||
|
@ -444,7 +459,7 @@ class Index extends Component {
|
|||
validator:(rule, value, callback) => this.checkId(rule, value, callback, OwnerList, '拥有者')
|
||||
}],
|
||||
})(
|
||||
<AutoComplete
|
||||
<AutoComplete
|
||||
style={{width:"260px",height:"35px"}}
|
||||
placeholder="请选择拥有者"
|
||||
onChange={(value, e) => this.ChangePlatform(value, e, 'owners', OwnerList)}
|
||||
|
@ -483,7 +498,7 @@ class Index extends Component {
|
|||
)}
|
||||
</Form.Item>
|
||||
<div className="pr">
|
||||
<span className="toprightNum">{descNum}/200</span>
|
||||
{/*<span className="toprightNum">{descNum}/200</span>*/}
|
||||
<Form.Item
|
||||
label="项目简介"
|
||||
colon={false}
|
||||
|
@ -496,7 +511,7 @@ class Index extends Component {
|
|||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
|
||||
{
|
||||
(projectsType === "deposit" || !projectsType) &&
|
||||
<React.Fragment>
|
||||
|
@ -563,6 +578,41 @@ class Index extends Component {
|
|||
<Checkbox value="limit">将项目设为私有<span className="font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||
)}
|
||||
</Form.Item >
|
||||
{/*增加区块链选项,不要求必选,默认是选择的*/}
|
||||
<Form.Item
|
||||
label="确权"
|
||||
style={{ margin: "0px" }}
|
||||
className="privatePart"
|
||||
>
|
||||
{getFieldDecorator('blockchain')(
|
||||
<Checkbox value="limit" onClick={this.handleBlockchainChange}>项目加入确权机制<span className="ml15 font-13 color-grey-9">(贡献确权上链并使用token机制)</span></Checkbox>
|
||||
)}
|
||||
</Form.Item >
|
||||
|
||||
<Form.Item
|
||||
style={{ margin: "15px", display: "block" }}
|
||||
className="privatePart"
|
||||
ref={(blockchain_item => {this.blockchain_item = blockchain_item})}
|
||||
>
|
||||
<div class="div_flex_row" style={{visibility: this.state.show_div == "visible" ? "visible": "hidden"}}>
|
||||
{getFieldDecorator('blockchain_token_all', {
|
||||
rules: [{
|
||||
required: false, message: '请填写项目token总数(单位:枚)'
|
||||
}],
|
||||
})(
|
||||
<Input type={'number'} min={0} step={1} placeholder="请填写项目token总数(单位:枚)" />
|
||||
)}
|
||||
|
||||
{getFieldDecorator('blockchain_init_token', {
|
||||
rules: [{
|
||||
required: false, message: '请填写项目创始人获取token总数(单位:枚)'
|
||||
}],
|
||||
})(
|
||||
<Input type={'number'} min={0} max={100} step={1} placeholder="请填写项目创始人获去总token的百分比(%)" />
|
||||
)}
|
||||
</div>
|
||||
</Form.Item>
|
||||
|
||||
{
|
||||
projectsType && projectsType === "mirror" &&
|
||||
<Form.Item
|
||||
|
@ -610,7 +660,7 @@ class Index extends Component {
|
|||
<Checkbox checked={languageFlag} onChange={(e)=>this.showLanguageFunc(e)}>项目语言</Checkbox>
|
||||
)}
|
||||
</Form.Item>
|
||||
{languageFlag &&
|
||||
{languageFlag &&
|
||||
<Form.Item>
|
||||
{getFieldDecorator('project_language', {
|
||||
rules: [{
|
||||
|
|
|
@ -71,4 +71,9 @@
|
|||
.newContent_inline > .ant-form-item:nth-child(2){
|
||||
margin-left:0px
|
||||
}
|
||||
}
|
||||
|
||||
.div_flex_row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
|
@ -37,11 +37,13 @@ class Detail extends Component {
|
|||
visible: false,
|
||||
journal_spin: false,
|
||||
edit_spin: false,
|
||||
blockchain_token_num: 0,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getDetail();
|
||||
this.getBlockchainTokenNum();
|
||||
};
|
||||
|
||||
componentDidUpdate=()=>{
|
||||
|
@ -76,6 +78,20 @@ class Detail extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
getBlockchainTokenNum = () => {
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const url = `/blockchain/issue/get_token_num`;
|
||||
axios.post(url,{
|
||||
"issue_id": {orderId}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
this.state.blockchain_token_num = result.data.blockchain_token_num;
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
};
|
||||
|
||||
handleok = () => {
|
||||
this.setState({
|
||||
isShow: false,
|
||||
|
@ -346,6 +362,10 @@ class Detail extends Component {
|
|||
)}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">悬赏金额:</span>
|
||||
<span>{this.state.blockchain_token_num}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">里程碑:</span>
|
||||
<span className="title_overflow">
|
||||
|
|
|
@ -13,6 +13,7 @@ const Option = Select.Option;
|
|||
class order_form extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.getTokenProject(props.current_user.user_id, this.props.match.params.owner, this.props.match.params.projectsId);
|
||||
this.state = {
|
||||
branch_name: "",
|
||||
issue_tag_ids: "",
|
||||
|
@ -36,9 +37,27 @@ class order_form extends Component {
|
|||
show_token: false,
|
||||
cannot_edit: false,
|
||||
issue_current_user: true,
|
||||
issue_token_num: 0,
|
||||
blockchain_token_num: 0,
|
||||
atWhoLoginList:undefined
|
||||
};
|
||||
}
|
||||
|
||||
getTokenProject = (user_id, owner_login, project_name) => {
|
||||
const url = `/users/blockchain/balance_project`;
|
||||
axios.post(url,{
|
||||
user_id: user_id,
|
||||
owner_login: owner_login,
|
||||
project_name: project_name
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
this.state.issue_token_num = result.data.balance;
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
componentDidUpdate=(prevPros)=>{
|
||||
if(prevPros && this.props && this.props.checkIfLogin()===false){
|
||||
this.props.history.push("/403")
|
||||
|
@ -98,7 +117,7 @@ class order_form extends Component {
|
|||
if (result) {
|
||||
let data ={
|
||||
branch_name: result.data.branch_name,
|
||||
issue_tag_ids:
|
||||
issue_tag_ids:
|
||||
result.data.issue_tags && result.data.issue_tags[0].id ?
|
||||
String(result.data.issue_tags[0].id) : ""
|
||||
,
|
||||
|
@ -153,11 +172,11 @@ class order_form extends Component {
|
|||
description:"####问题描述\n\n\n####重现问题步骤\n\n\n####截图\n\n\n####建议解决办法\n",
|
||||
}
|
||||
this.setState({ ...data });
|
||||
this.props.form.setFieldsValue({
|
||||
this.props.form.setFieldsValue({
|
||||
...this.state,
|
||||
fixed_version_id: milepostId || ""
|
||||
fixed_version_id: milepostId || ""
|
||||
});
|
||||
|
||||
|
||||
}else if(this.props.form_type !== "new"){
|
||||
this.get_detail();
|
||||
}else{
|
||||
|
@ -186,7 +205,7 @@ class order_form extends Component {
|
|||
|
||||
// 创建
|
||||
handleSubmit = () => {
|
||||
|
||||
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
this.setState({
|
||||
|
@ -212,7 +231,7 @@ class order_form extends Component {
|
|||
if (values.issue_tag_ids.length > 0) {
|
||||
values.issue_tag_ids = [values.issue_tag_ids];
|
||||
}
|
||||
const { description, start_date, due_date, issue_type , atWhoLoginList } = this.state;
|
||||
const { description, start_date, due_date, issue_type , atWhoLoginList, blockchain_token_num } = this.state;
|
||||
if (form_type !== "edit") {
|
||||
const url = `/${owner}/${projectsId}/issues.json`;
|
||||
axios.post(url, {
|
||||
|
@ -223,6 +242,7 @@ class order_form extends Component {
|
|||
due_date: due_date,
|
||||
issue_type: issue_type,
|
||||
receivers_login:atWhoLoginList,
|
||||
blockchain_token_num: blockchain_token_num
|
||||
}).then((result) => {
|
||||
if (result && result.data.id) {
|
||||
this.props.showNotification("任务创建成功!");
|
||||
|
@ -370,6 +390,20 @@ class order_form extends Component {
|
|||
}
|
||||
};
|
||||
|
||||
adjustTokenNum = (e) => {
|
||||
var val = e.target.value;
|
||||
val = parseInt(val);
|
||||
if (val > this.state.issue_token_num) {
|
||||
val = this.state.issue_token_num;
|
||||
e.target.value = this.state.issue_token_num;
|
||||
} else {
|
||||
e.target.value = val;
|
||||
}
|
||||
this.setState({
|
||||
blockchain_token_num: val,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
@ -456,9 +490,21 @@ class order_form extends Component {
|
|||
</div>
|
||||
<div className="list-left list-left-padding issue-edit-form-right">
|
||||
<div className="pd20 background-f issue-form-right">
|
||||
<Form.Item label="悬赏金额">
|
||||
{getFieldDecorator("issue_token_num", {rules: []})(
|
||||
<Input
|
||||
ref={(input) => this.input_token=input}
|
||||
type={"number"}
|
||||
min={0}
|
||||
max={this.state.issue_token_num}
|
||||
onChange={this.adjustTokenNum.bind(this)}
|
||||
placeholder="定义悬赏token数量"
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="指派成员">
|
||||
{getFieldDecorator("assigned_to_id", {rules: []})(
|
||||
<Select
|
||||
<Select
|
||||
showSearch
|
||||
className="searchIcon"
|
||||
showArrow={true}
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { Select, Input, Button } from 'antd';
|
||||
const Option = Select.Option;
|
||||
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.async = true;
|
||||
script.src = 'https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js';
|
||||
document.head.appendChild(script);
|
||||
|
||||
const limit = 10;
|
||||
function BlockchainExCreate(props){
|
||||
const [ status , setStatus ] = useState(0);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ list , setList ] = useState([]);
|
||||
const [ authorityValBox , setAuthorityValBox] = useState(false);
|
||||
const [ selectKey , setSelectKey ] = useState("list");
|
||||
const { selectedOption, setSelectedOption } = useState("选择交易的项目");
|
||||
let user = props.current_user;
|
||||
|
||||
useEffect(()=>{
|
||||
if(user && user.login){
|
||||
getInfo();
|
||||
}
|
||||
}, [])
|
||||
|
||||
// read all the projects that the user has more than 0 tokens
|
||||
function getInfo(){
|
||||
const url = `/users/blockchain/balance`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
"user_id": user.user_id
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setStatus(result.data.status);
|
||||
if(status == 0) {
|
||||
setList(result.data.projects);
|
||||
setTotal(result.data.total_count);
|
||||
}
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
function createTrade(user_id) {
|
||||
const url = '/users/blockchain/create_trade';
|
||||
axios.post(url, {
|
||||
"user_id": user_id,
|
||||
"project_id": document.getElementById("input_project").value,
|
||||
"money": document.getElementById("money").value,
|
||||
"token_num": document.getElementById("token_num").value,
|
||||
// "description": document.getElementById("input_description").value
|
||||
}).then((result) => {
|
||||
if(result && result.data){
|
||||
if (result.data.status == 2) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function renderProjectList(list) {
|
||||
if (list && list.length > 0) {
|
||||
return list.map((item, index) => {
|
||||
return (
|
||||
<Option
|
||||
key={index+1}
|
||||
value={item[1].id+"/"+item[2]}
|
||||
>
|
||||
{item[0].login + "/" + item[1].name}
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function selectProjectChange(e) {
|
||||
document.getElementById("money").removeAttribute("hidden");
|
||||
document.getElementById("token_num").removeAttribute("hidden");
|
||||
document.getElementById("submit_btn").removeAttribute("hidden");
|
||||
// document.getElementById("input_description").removeAttribute("hidden");
|
||||
|
||||
document.getElementById("token_num").setAttribute("max", e.split('/')[1]);
|
||||
document.getElementById("input_project").value=e.split('/')[0];
|
||||
}
|
||||
|
||||
function adjustTokenNum() {
|
||||
var val = document.getElementById("token_num").value;
|
||||
val = parseInt(val);
|
||||
var max_val = document.getElementById("token_num").getAttribute("max");
|
||||
if (val > max_val) {
|
||||
document.getElementById("token_num").value = max_val;
|
||||
} else {
|
||||
document.getElementById("token_num").value = val;
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{minHeight:"400px"}}>
|
||||
<span className="blockchain_proj_select ml20">
|
||||
<Select
|
||||
id = {'select_project'}
|
||||
style={{width: "220px"}}
|
||||
placeholder={"选择交易的项目"}
|
||||
onSelect={(e) => {selectProjectChange(e)}}
|
||||
>
|
||||
{renderProjectList(list)}
|
||||
</Select>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<Input
|
||||
id={"input_project"}
|
||||
hidden={true}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<Input
|
||||
id={"input_project"}
|
||||
hidden={true}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="blockchain_input_num ml20">
|
||||
<Input
|
||||
type={'number'}
|
||||
id={"token_num"}
|
||||
placeholder={"输入售卖币数量"}
|
||||
hidden={true}
|
||||
min={1}
|
||||
onInput={() => {adjustTokenNum()}}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span className="blockchain_input_num ml20">
|
||||
<Input
|
||||
id={"money"}
|
||||
placeholder={"输入售卖金额"}
|
||||
hidden={true}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<Button hidden={true} id='submit_btn' className="primary ml20" onClick={() => {createTrade(user.user_id)}}>确认</Button>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BlockchainExCreate;
|
|
@ -0,0 +1,71 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import moment from "moment";
|
||||
import { Button ,Spin , Pagination , Popconfirm } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Nodata from '../Nodata';
|
||||
import axios from 'axios';
|
||||
|
||||
const limit = 10;
|
||||
function BlockchainExHistory(props){
|
||||
const [ list , setList ] = useState([]);
|
||||
let user = props.current_user;
|
||||
|
||||
useEffect(()=>{
|
||||
if(user && user.login){
|
||||
getInfo();
|
||||
}
|
||||
},[])
|
||||
|
||||
function getInfo(){
|
||||
const url = `/users/blockchain/get_history_trades`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
"user_id": user.user_id
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setList(result.data.results);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<ul className="CIList">
|
||||
<li>
|
||||
<span>
|
||||
<span hidden={true}></span>
|
||||
<span className="blockchain_username ml20">{"卖家名"}</span>
|
||||
<span className="blockchain_proj ml20">{"项目创建者/项目名"}</span>
|
||||
<span className="blockchain_proj ml20">{"token数量:价值"}</span>
|
||||
<span className="blockchain_username ml20">{"买家名"}</span>
|
||||
<span className="blockchain_time ml20">{"交易创建时间"}</span>
|
||||
<span className="blockchain_time ml20">{"交易截止时间"}</span>
|
||||
</span>
|
||||
</li>
|
||||
{list.map((item,key)=>{
|
||||
return(
|
||||
<li key={key}>
|
||||
<span>
|
||||
<span id={key} hidden={true}>{item[3].id}</span>
|
||||
<span className="blockchain_username ml20">{item[0].login}</span>
|
||||
<span className="blockchain_proj ml20">{item[1].login + "/" + item[2].name}</span>
|
||||
<span className="blockchain_proj ml20">{item[3].token_num + ":" + item[3].money}</span>
|
||||
<span className="blockchain_username ml20">{item[4].login}</span>
|
||||
<span className="blockchain_time ml20">{moment(item[3].created_at).format('YYYY-MM-DD HH:mm:ss')}</span>
|
||||
<span className="blockchain_time ml20">{moment(item[3].updated_at).format('YYYY-MM-DD HH:mm:ss')}</span>
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
:<Nodata _html="无历史交易"/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BlockchainExHistory;
|
|
@ -0,0 +1,93 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Button ,Spin , Pagination , Popconfirm } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Nodata from '../Nodata';
|
||||
import axios from 'axios';
|
||||
|
||||
const limit = 10;
|
||||
function BlockchainExList(props){
|
||||
const [ list , setList ] = useState([]);
|
||||
let user = props.current_user;
|
||||
|
||||
useEffect(()=>{
|
||||
if(user && user.login){
|
||||
getInfo();
|
||||
}
|
||||
},[])
|
||||
|
||||
function getInfo(){
|
||||
const url = `/users/blockchain/get_trades`;
|
||||
axios.get(url,{
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setList(result.data.results);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
function trade(index) {
|
||||
const url = `/users/blockchain/trade`;
|
||||
axios.post(url,{
|
||||
"user_id": user.user_id,
|
||||
"user_id2": user.user_id,
|
||||
"trade_id": document.getElementById(index).innerText
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
if (result.data.status == 2) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<ul className="CIList">
|
||||
<li>
|
||||
<span>
|
||||
<span hidden={true}></span>
|
||||
<span className="blockchain_username ml20">卖家名</span>
|
||||
<span className="blockchain_proj ml20">项目创建者/项目名</span>
|
||||
<span className="blockchain_balance ml20">token数</span>
|
||||
<span className="blockchain_balance ml20">售价</span>
|
||||
</span>
|
||||
{
|
||||
<Button hidden={true}>交易</Button>
|
||||
}
|
||||
</li>
|
||||
{list.map((item,key)=>{
|
||||
return(
|
||||
<li key={key}>
|
||||
<span>
|
||||
<span id={key} hidden={true}>{item[3].id}</span>
|
||||
<span className="blockchain_username ml20">{item[0].login}</span>
|
||||
<span className="blockchain_proj ml20">{item[1].login + "/" + item[2].name}</span>
|
||||
<span className="blockchain_balance ml20">{item[3].token_num}</span>
|
||||
<span className="blockchain_balance ml20">{item[3].money}</span>
|
||||
</span>
|
||||
{
|
||||
<Popconfirm
|
||||
title="确定交易?"
|
||||
onConfirm={() => {trade(key)}}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button>交易</Button>
|
||||
</Popconfirm>
|
||||
}
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
:<Nodata _html="暂无交易"/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BlockchainExList;
|
|
@ -0,0 +1,38 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Menu } from 'antd';
|
||||
import './Index.scss';
|
||||
import BlockchainExCreate from './BlockchainExCre';
|
||||
import BlockchainExList from './BlockchainExList';
|
||||
import BlockchainExVerify from './BlockchainExVerify';
|
||||
import BlockchainExHistory from './BlockchainExHistory';
|
||||
|
||||
|
||||
function BlockchainExMenu(props){
|
||||
const [ selectKey , setSelectKey ] = useState("list");
|
||||
|
||||
function changeKeys(e){
|
||||
setSelectKey(e.key);
|
||||
}
|
||||
|
||||
function renderMenu() {
|
||||
if (selectKey === "list") {return (<BlockchainExList {...props}/>)}
|
||||
else if (selectKey == 'create') {return (<BlockchainExCreate {...props}/>)}
|
||||
else if (selectKey == "verify") {return (<BlockchainExVerify {...props}/>)}
|
||||
else if (selectKey == "history") {return (<BlockchainExHistory {...props}/>)}
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<Menu mode="horizontal" className="menuStyle" onClick={changeKeys} selectedKeys={[selectKey]}>
|
||||
<Menu.Item key="list">交易列表</Menu.Item>
|
||||
<Menu.Item key="create">创建交易</Menu.Item>
|
||||
<Menu.Item key="verify">确认交易</Menu.Item>
|
||||
<Menu.Item key="history">历史交易</Menu.Item>
|
||||
</Menu>
|
||||
{
|
||||
renderMenu()
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BlockchainExMenu;
|
|
@ -0,0 +1,99 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Button ,Spin , Pagination , Popconfirm } from 'antd';
|
||||
import Nodata from '../Nodata';
|
||||
import moment from "moment";
|
||||
import axios from 'axios';
|
||||
|
||||
const limit = 10;
|
||||
function BlockchainExVerify(props){
|
||||
const [ list , setList ] = useState([]);
|
||||
let user = props.current_user;
|
||||
|
||||
useEffect(()=>{
|
||||
if(user && user.login){
|
||||
getInfo();
|
||||
}
|
||||
},[])
|
||||
|
||||
function getInfo(){
|
||||
const url = `/users/blockchain/get_verify_trades`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
"user_id": user.user_id
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setList(result.data.results);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
function verify_trade(index) {
|
||||
const url = `/users/blockchain/verify_trade`;
|
||||
axios.post(url,{
|
||||
"user_id": user.user_id,
|
||||
"trade_id": document.getElementById(index).innerText
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
if (result.data.status == 2) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<ul className="CIList">
|
||||
|
||||
<li>
|
||||
<span>
|
||||
<span hidden={true}></span>
|
||||
<span className="blockchain_username ml20">卖家名</span>
|
||||
<span className="blockchain_proj ml20">项目创建者/项目名</span>
|
||||
<span className="blockchain_proj ml20">token数量:价值</span>
|
||||
<span className="blockchain_username ml20">买家名</span>
|
||||
<span className="blockchain_time ml20">交易时间</span>
|
||||
</span>
|
||||
{
|
||||
<Button hidden={true}></Button>
|
||||
}
|
||||
</li>
|
||||
|
||||
{list.map((item,key)=>{
|
||||
return(
|
||||
<li key={key}>
|
||||
<span>
|
||||
<span id={key} hidden={true}>{item[3].id}</span>
|
||||
<span className="blockchain_username ml20">{item[0].login}</span>
|
||||
<span className="blockchain_proj ml20">{item[1].login + "/" + item[2].name}</span>
|
||||
<span className="blockchain_proj ml20">{item[3].token_num + ":" + item[3].money}</span>
|
||||
<span className="blockchain_username ml20">{item[4].login}</span>
|
||||
<span className="blockchain_time ml20">{moment(item[3].created_at).format('YYYY-MM-DD HH:mm:ss')}</span>
|
||||
</span>
|
||||
{
|
||||
<Popconfirm
|
||||
title="确认收货?"
|
||||
onConfirm={() => {verify_trade(key)}}
|
||||
okText="确认"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button>确认收货</Button>
|
||||
</Popconfirm>
|
||||
}
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
:<Nodata _html="暂无待处理交易"/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BlockchainExVerify;
|
|
@ -0,0 +1,115 @@
|
|||
import React , { useEffect , useState , forwardRef , useCallback } from 'react';
|
||||
import { Button , Modal , Form , Input } from 'antd';
|
||||
import { AlignCenter } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
import Modals from '../Component/Modal';
|
||||
import PasswordAuthority from '../Component/PasswordAuthority';
|
||||
import Nodata from "../Nodata";
|
||||
|
||||
function BlockchainTransfer(props){
|
||||
|
||||
const [ status , setStatus ] = useState(0);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ list , setList ] = useState([]);
|
||||
const [ authorityValBox , setAuthorityValBox] = useState(false);
|
||||
|
||||
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, isRequired) => (
|
||||
<React.Fragment>
|
||||
<span className={isRequired ? "required" : ""}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
let user = props.current_user;
|
||||
|
||||
useEffect(()=>{
|
||||
if(user && user.login){
|
||||
getInfo();
|
||||
}
|
||||
},[])
|
||||
|
||||
// read all the projects that the user has more than 0 tokens
|
||||
function getInfo(){
|
||||
const url = `/users/blockchain/balance`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
"user_id": user.user_id
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setStatus(result.data.status);
|
||||
if(status == 0) {
|
||||
setList(result.data.projects);
|
||||
setTotal(result.data.total_count);
|
||||
}
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
function okAuthority(){
|
||||
setAuthorityValBox(false);
|
||||
}
|
||||
|
||||
function cancelAuthority(){
|
||||
setAuthorityValBox(false);
|
||||
}
|
||||
|
||||
|
||||
function submit(owner, project, balance, id) {
|
||||
const url = '/users/blockchain/transfer';
|
||||
axios.post(url, {
|
||||
payer_id: user.user_id,
|
||||
project_id: project.id,
|
||||
transfer_amount: document.getElementById("amount_" + id).value,
|
||||
transfer_login: document.getElementById("login_" + id).value
|
||||
}).then((result) => {
|
||||
if (result && result.data) {
|
||||
if (result.data.status == 2) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<div style={{minHeight:"400px"}}>
|
||||
<PasswordAuthority authorityValBox={authorityValBox} successFunc={okAuthority} cancelFunc={cancelAuthority}></PasswordAuthority>
|
||||
{
|
||||
status == 0 && list && list.length > 0 ?
|
||||
<ul className="BalanceList">
|
||||
<li>
|
||||
<span className="blockchain_proj green ml20">项目创建者/项目名</span>
|
||||
<span className="blockchain_balance green ml20">token总量</span>
|
||||
<span className="blockchain_input_to ml20">目标转账用户</span>
|
||||
<span className="blockchain_input_num ml20">转账token数量</span>
|
||||
<Button hidden={true}></Button>
|
||||
</li>
|
||||
{list.map((item,index)=>{
|
||||
return(
|
||||
<li key={index}>
|
||||
<Form>
|
||||
<span className="blockchain_proj green ml20">{item[0].login + "/" + item[1].name}</span>
|
||||
<span className="blockchain_balance green ml20">{item[2]}</span>
|
||||
<span className="blockchain_input_to ml20"><Input type="text" placeholder={"请输入转给哪个用户(login)"} name={"transfer_login"} id={"login_"+index} /></span>
|
||||
<span className="blockchain_input_num ml20"><Input type="text" placeholder={"请输入转账token数量"} name={"transfer_amount"} id={"amount_"+index} /></span>
|
||||
<Button className="primary ml20" onClick={() => {submit(item[0], item[1], item[2], index)}}>确认</Button>
|
||||
</Form>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
:<Nodata _html="暂无数据"/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(forwardRef(BlockchainTransfer));;
|
|
@ -264,6 +264,48 @@ ul.ant-menu.menuStyle{
|
|||
color: #28BD6C;
|
||||
}
|
||||
}
|
||||
.blockchain_proj{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
width: 180px;
|
||||
}
|
||||
.blockchain_balance{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
width: 100px;
|
||||
}
|
||||
.blockchain_input_to{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 40px;
|
||||
width: 150px;
|
||||
}
|
||||
.blockchain_input_num{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 40px;
|
||||
width: 150px;
|
||||
}
|
||||
.blockchain_proj_select{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 40px;
|
||||
width: 220px;
|
||||
}
|
||||
.blockchain_username{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 40px;
|
||||
width: 60px;
|
||||
}
|
||||
.blockchain_time{
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 40px;
|
||||
width: 130px;
|
||||
}
|
||||
.CIList{
|
||||
padding:0px 30px;
|
||||
min-height: 400px;
|
||||
|
|
|
@ -23,6 +23,14 @@ const InfosDevOps = Loadable({
|
|||
loader: () => import("./devOpsCI"),
|
||||
loading: Loading,
|
||||
});
|
||||
const InfosBlockchainTransfer = Loadable({
|
||||
loader: () => import("./BlockchainTransfer"),
|
||||
loading: Loading,
|
||||
});
|
||||
const InfosBlockchainExMenu = Loadable({
|
||||
loader: () => import("./BlockchainExMenu"),
|
||||
loading: Loading,
|
||||
});
|
||||
const InfosDevOpsCD = Loadable({
|
||||
loader: () => import("./devOpsCD"),
|
||||
loading: Loading,
|
||||
|
@ -31,11 +39,11 @@ const InfosDevOpsCD = Loadable({
|
|||
const Statistics = Loadable({
|
||||
loader: () => import("./Statistics/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
});
|
||||
const GeneralView = Loadable({
|
||||
loader: () => import("./GeneralView/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
});
|
||||
const InfosUser = Loadable({
|
||||
loader: () => import("./InfosUser"),
|
||||
loading: Loading,
|
||||
|
@ -191,6 +199,16 @@ class Infos extends Component {
|
|||
this.props.history.push(`/${user && user.login}/devops/${type}`);
|
||||
}
|
||||
|
||||
change_blockchain_type=(type)=>{
|
||||
console.log(type)
|
||||
const {user} = this.state;
|
||||
this.setState({
|
||||
project_type: type ,
|
||||
route_type: undefined
|
||||
})
|
||||
this.props.history.push(`/users/${user && user.login}/blockchain/${type}`);
|
||||
}
|
||||
|
||||
undo_link = () => {
|
||||
const {user } = this.state;
|
||||
this.setState({
|
||||
|
|
Loading…
Reference in New Issue