Merge pull request 'nanda版本' (#500) from qyzh1996/forgeplus-react:sponsor into dev_nanda

This commit is contained in:
xxq250 2023-01-12 21:07:16 +08:00
commit a9cfa2b56f
26 changed files with 4194 additions and 579 deletions

1
.gitignore vendored
View File

@ -87,4 +87,5 @@ typings/
.DS_Store
.idea/*
.forgeplus-react.sublime-workspace

BIN
build.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,317 @@
{
"auto_complete":
{
"selected_items":
[
[
"samp",
"samp2_method"
],
[
"modu",
"module_method"
],
[
"cu",
"currentTerm"
],
[
"req",
"requestVote"
],
[
"reque",
"RequestVote"
],
[
"App",
"AppendEntries"
],
[
"hea",
"heartBeatInterval"
],
[
"time",
"timeOut"
],
[
"ele",
"electionTimeout"
],
[
"R",
"Raft"
],
[
"vote",
"votedFor"
],
[
"Ra",
"RaftState"
],
[
"is",
"isleader"
]
]
},
"buffers":
[
{
"file": "src/redux/actions/actionTypes.js",
"settings":
{
"buffer_size": 5688,
"encoding": "UTF-8",
"line_ending": "Unix"
}
}
],
"build_system": "",
"build_system_choices":
[
],
"build_varint": "",
"command_palette":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"console":
{
"height": 171.0,
"history":
[
"ls"
]
},
"distraction_free":
{
"menu_visible": true,
"show_minimap": false,
"show_open_files": false,
"show_tabs": false,
"side_bar_visible": false,
"status_bar_visible": false
},
"expanded_folders":
[
"/home/qyzh/new_trustie/forgeplus-react"
],
"file_history":
[
"/home/qyzh/OSS/forgeplus/app/models/user.rb",
"/home/qyzh/OSS/forgeplus/db/structure.sql",
"/home/qyzh/OSS/forgeplus/app/controllers/settings_controller.rb",
"/home/qyzh/OSS/forgeplus/app/controllers/application_controller.rb",
"/home/qyzh/OSS/Trustie/app/controllers/projects_controller.rb",
"/home/qyzh/temp.sh",
"/home/qyzh/OSS/Trustie/Gemfile",
"/home/qyzh/.npm/_logs/2020-06-07T02_42_06_886Z-debug.log",
"/home/qyzh/OSS/forgeplus/app/controllers/users_controller.rb",
"/home/qyzh/OSS/forgeplus/app/controllers/accounts_controller.rb",
"/home/qyzh/custom/conf/app.ini",
"/home/qyzh/OSS/Trustie_old/Gemfile.lock",
"/home/qyzh/OSS/Trustie/Gemfile.lock",
"/home/qyzh/ruby_study/test.rb",
"/home/qyzh/RubymineProjects/myblog/app/controller/users_controller.rb",
"/home/qyzh/OSS/forgeplus/app/libs/limit_forbid_control.rb",
"/home/qyzh/OSS/forgeplus/log/development.log",
"/home/qyzh/NJU-DisSys-2017/src/raft/raft.go",
"/home/qyzh/OSS/forgeplus/config/application.rb",
"/home/qyzh/RubymineProjects/demo/app/helpers/welcome_helper.rb",
"/home/qyzh/RubymineProjects/demo/app/controllers/welcome_controller.rb",
"/home/qyzh/RubymineProjects/demo/config/routes.rb",
"/home/qyzh/RubymineProjects/demo/app/views/welcome/index.html.erb",
"/home/qyzh/trustie/Gemfile",
"/home/qyzh/trustie/Gemfile.lock",
"/home/qyzh/ruby_study/test",
"/home/qyzh/NJU-DisSys-2017/src/labrpc/test_test.go",
"/home/qyzh/NJU-DisSys-2017/src/labrpc/labrpc.go",
"/home/qyzh/NJU-DisSys-2017/src/raft/test_test.go",
"/home/qyzh/NJU-DisSys-2017/src/raft/persister.go",
"/home/qyzh/NJU-DisSys-2017/src/raft/util.go",
"/home/qyzh/NJU-DisSys-2017/src/raft/config.go"
],
"find":
{
"height": 29.0
},
"find_in_files":
{
"height": 0.0,
"where_history":
[
]
},
"find_state":
{
"case_sensitive": true,
"find_history":
[
"current_user",
"user_set",
"login",
"platform",
"Platform不包含于列表中",
"find_by_",
"find_by",
"3.2.22",
"bug",
"persister",
"currentTerm",
"currentTern",
"term",
"your",
"electionInterval",
"your",
"if",
"your",
"Persister",
"make",
"Your code here",
"Call",
"labrpc",
"main"
],
"highlight": true,
"in_selection": false,
"preserve_case": false,
"regex": false,
"replace_history":
[
],
"reverse": false,
"show_context": true,
"use_buffer2": true,
"whole_word": false,
"wrap": true
},
"groups":
[
{
"selected": 0,
"sheets":
[
{
"buffer": 0,
"file": "src/redux/actions/actionTypes.js",
"semi_transient": false,
"settings":
{
"buffer_size": 5688,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/JavaScript/JavaScript.sublime-syntax",
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 0,
"type": "text"
}
]
}
],
"incremental_find":
{
"height": 29.0
},
"input":
{
"height": 0.0
},
"layout":
{
"cells":
[
[
0,
0,
1,
1
]
],
"cols":
[
0.0,
1.0
],
"rows":
[
0.0,
1.0
]
},
"menu_visible": true,
"output.find_results":
{
"height": 0.0
},
"pinned_build_system": "",
"project": "forgeplus-react.sublime-project",
"replace":
{
"height": 54.0
},
"save_all_on_build": true,
"select_file":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"select_project":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"select_symbol":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"selected_group": 0,
"settings":
{
},
"show_minimap": true,
"show_open_files": false,
"show_tabs": true,
"side_bar_visible": true,
"side_bar_width": 288.0,
"status_bar_visible": true,
"template_settings":
{
}
}

932
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -63,6 +63,7 @@
"rc-upload": "^2.9.4",
"react": "^16.13.1",
"react-beautiful-dnd": "^10.0.4",
"react-charts": "^2.0.0-beta.7",
"react-codemirror": "^1.0.0",
"react-codemirror2": "^6.0.1",
"react-color": "^2.18.0",
@ -85,6 +86,7 @@
"react-slick": "^0.28.1",
"react-split-pane": "^0.1.91",
"react-url-query": "^1.5.0",
"react-vis": "^1.11.7",
"react-zmage": "^0.8.5-beta.31",
"redux": "^4.0.5",
"redux-thunk": "2.3.0",
@ -96,6 +98,11 @@
"slick-carousel": "^1.8.1",
"store": "^2.0.12",
"styled-components": "^4.4.1",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.6.2",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.11.0",
"webpack-manifest-plugin": "^2.2.0",
"whatwg-fetch": "2.0.3",
"wrap-md-editor": "^0.2.20",
"xterm": "4.8.1",

View File

@ -82,6 +82,20 @@ const OrganizeIndex = Loadable({
loader: () => import('./forge/Team/Index'),
loading: Loading,
})
// Sponsor
const Sponsor = Loadable({
loader: () => import('./forge/sponsor/Sponsor'),
loading: Loading,
})
// Sponsor Confirmation
const SponsorConfirmation = Loadable({
loader: () => import('./forge/sponsor/SponsorConfirmation'),
loading: Loading,
})
const EducoderLogin = Loadable({
loader: () => import('./modules/login/EducoderLogin'),
loading: Loading,
})
const Search = Loadable({
loader: () => import('./modules/search/'),
@ -350,7 +364,7 @@ class App extends Component {
}
}>
</Route>
{/*403*/}
<Route path="/403" component={Shixunauthority} />
@ -387,7 +401,7 @@ class App extends Component {
path="/login"
render={(props) =><LoginRegisterPage {...this.props} {...props} mygetHelmetapi={mygetHelmetapi}/>}
></Route>
{/* 注册 */}
<Route
path="/register"
@ -426,7 +440,7 @@ class App extends Component {
}
}>
</Route>
{/*新建项目等*/}
<Route
path={"/projects"}
@ -470,7 +484,16 @@ class App extends Component {
return (<InfosIndex {...this.props} {...this.state} />)
}
}></Route>
<Route exact path="/sponsor_confirmation/:username/:tier_id"
render={
(props) => (<SponsorConfirmation {...this.props}{...this.state}></SponsorConfirmation>)
}>
</Route>
<Route exact path="/sponsor/:username"
render={
(props) => (<Sponsor {...this.props}{...this.state}></Sponsor>)
}>
</Route>
<Route component={Shixunnopage} />
</Switch>

View File

@ -33,7 +33,6 @@ export function initAxiosInterceptors(props) {
initOnlineOfflineListener();
var proxy = "https://testforgeplus.trustie.net";
//响应前的设置
axios.interceptors.request.use(
config => {

View File

@ -99,7 +99,7 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
{/* <Link to={{ pathname: `/${owner}/${projectsId}/devops${open_devops ? `/dispose`:""}`, state }}> */}
<Link className='newTab' to={{ pathname: `/${owner}/${projectsId}/devops`, state:{...state,open_devops} }}>
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>引擎(Engine)<div className='newBtnImg'></div>
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
</Link>
</li>
:""
@ -117,7 +117,7 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
{
item.menu_name === "versions" &&
<li className={pathname==="milestones" ? "active" : ""}>
<Link to={{ pathname: `/${owner}/${projectsId}/milestones`, state }}>
<Link to={{ pathname: `/${owner}/${projectsId}/milestones`, state }}>
<i className={pathname==="milestones" ? "iconfont icon-lichengbeiicon color-grey-3 mr5 font-14":"iconfont icon-lichengbeiicon color-grey-6 font-14 mr5"}></i>
<span>里程碑</span>
{projectDetail && projectDetail.versions_count ? <span className="num">{numFormat(projectDetail.versions_count)}</span> :""}

View File

@ -0,0 +1,191 @@
import React , { Component } from "react";
import { Form , Input , Select,Divider,Button,Checkbox,Dropdown,Menu} from 'antd';
import {Link} from 'react-router-dom';
import UploadComponent from '../Upload/Index';
import '../Order/order.css';
import './version.css';
import axios from 'axios';
const Option = Select.Option;
const TextArea = Input.TextArea;
class NewVersion extends Component{
constructor(props){
super(props);
this.state={
branch_name:"",
issue_tag_ids:"",
fixed_version_id:"",
issue_chosen:undefined,
fileList:undefined,
ischeck:undefined,
pull:undefined,
tag_name:'',
data:undefined
}
}
componentDidMount=()=>{
this.getSelectList();
}
getSelectList=()=>{
const { projectsId,versionId} = this.props.match.params;
const url = `/projects/${projectsId}/version_releases/${versionId}/edit.json`;
axios.get(url).then((result)=>{
if(result){
this.setState({
data:result.data,
pull:result.data.target_commitish
})
}
}).catch((error)=>{
console.log(error);
})
}
//delete
deleteversion=()=>{
const { projectsId , versionId} = this.props.match.params;
const url = `/projects/${projectsId}/version_releases/${versionId}.json`;
axios.delete(url,{ data: {
project_id: projectsId,
id:versionId
}
}).then((result)=>{
if(result){
this.props.history.push(`/projects/${projectsId}/version`);
}
}).catch((error)=>{
console.log(error);
})
}
// 创建
handleSubmit=()=>{
this.props.form.validateFieldsAndScroll((err, values) => {
if(!err){
const { projectsId,versionId} = this.props.match.params;
const { pull,ischeck } = this.state;
const url = `/projects/${projectsId}/version_releases/${versionId}.json`;
// if(values.issue_type==="普通"){
// values.issue_type="1"
// }
axios.put(url,{
...values,
tag_name:this.state.data&&this.state.data.tag_name,
draft:false,
prerelease:ischeck,
target_commitish:pull
}).then(result=>{
if(result){
this.props.history.push(`/projects/${projectsId}/version`);
}
}).catch(error=>{
console.log(error);
})
}
})
}
RedieonChange=(e)=>{
this.setState({
ischeck:e.target.checked
})
}
Preservation=()=>{
alert(this.state.data.tag_name)
}
renderMenu =(array,id)=>{
return(
<Menu>
{
array && array.length > 0 && array.map((item,key)=>{
return(
<Menu.Item key={item} onClick={()=>this.getOption(item)}>{item}</Menu.Item>
)
})
}
</Menu>
)
}
getOption=(name)=>{
this.setState({
pull:name
})
}
changmodelname=(e)=>{
this.setState({
tag_name:e.target.value
})
}
render(){
const { getFieldDecorator } = this.props.form;
const { projectsId } = this.props.match.params;
return(
<div className="main">
<Form>
<h1 style={{marginLeft:15,marginTop:20}}>发布新版</h1>
<h5 style={{marginLeft:15}}>版本发布组织项目的版本</h5>
<Divider/>
<div style={{display:'flex',marginLeft:15}}>
{this.state.data&&this.state.data.tag_name}@{this.state.data&&this.state.data.target_commitish}
</div>
<div style={{display:'flex'}}>
<div className="versionmilepostleft">
<h1>标题</h1>
<div>
<Form.Item>
{getFieldDecorator('name', {
rules: [{
required: true, message: '请输入标题'
}],
initialValue:this.state.data&&this.state.data.name
})(
<Input placeholder="标题"/>
)}
</Form.Item>
</div>
<h1>内容</h1>
<Form.Item>
{getFieldDecorator('body', {
rules: [{
required: true, message: '请输入描述内容'
}],
initialValue:this.state.data&&this.state.data.body
})(
<TextArea placeholder="添加一个可选的扩展描述。。。" style={{height:"300px"}}/>
)}
</Form.Item>
{/* <UploadComponent load={this.UploadFunc} style={{width:80,marginLeft:15}}></UploadComponent> */}
</div>
</div>
<Divider/>
<div className="fr">
<Checkbox onChange={this.RedieonChange}>标记为预行版</Checkbox>
<p>标记此版本不适合生产使用</p>
</div>
<div className="clearfix mt15" style={{marginTop:5}} >
<a className='topWrapper_btn_delete fr' onClick={()=>this.deleteversion()} style={{marginLeft:15}}>删除发布</a>
<a className='topWrapper_btn fr' onClick={()=>this.handleSubmit()} style={{marginRight:15}}>编辑发布信息</a>
<Link to={`/projects/${projectsId}/version`} style={{marginRight:30}} className='topWrapper_btn fr'>取消</Link>
</div>
</Form>
</div>
)
}
}
const WrappedNewVersionForm = Form.create({ name: 'NewVersionForm' })(NewVersion);
export default WrappedNewVersionForm;

View File

@ -0,0 +1,350 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Avatar, Tag, Button, Spin, Input, Form, message, Divider} from "antd";
import { Route, Switch } from "react-router-dom";
import { withRouter } from "react-router";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import axios from "axios";
import { getImageUrl } from "educoder";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
import SponsorTierItem from "./sponsor_tier_item";
import "../users/new_user.css";
import "../css/index.scss";
import '../users/Index.scss';
import "./sponsor.css";
const tempData = [
{id:1, tier: 5, description: "这能让我感到很开心"},
{id:2, tier: 10, description: "如果您更加慷慨的话就选择这个"},
{id:3, tier: 150, description: "这能为我带来相当多的额外收入"},
{id:4, tier: 250, description: "这能为我带来相当多的额外收入"},
{id:5, tier: 500, description: "这能为我带来相当多的额外收入"},
{id:6, tier: 1000, description: "这能为我带来相当多的额外收入"},
{id:7, tier: 5000, description: "这能为我带来相当多的额外收入"},
];
const tempDesc = "我长期从事开源社区相关工作...目前已经开发了多个项目如xxx, xxxx, ...\n我希望通过资助机制成为全职开源开发者如果您对我的项目感兴趣请资助我"
const tempSponsors = [
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
{image_url: "avatars/User/b", username: "万山川", user_id: 1369, login:"alpc104"},
];
const FormItem = Form.Item;
const TextArea = Input.TextArea;
const DescriptionForm = Form.create()(
class extends Component{
getItemsValue = ()=>{
const val= this.props.form.getFieldsValue(); // 获取from表单的值
return val;
}
render(){
const { form, initValue} = this.props;
const { getFieldDecorator } = form; // 校验控件
return(
<Form >
<FormItem>
{getFieldDecorator(`sponsor_description`,{
rules: [],
initialValue: initValue ? initValue : undefined
})(
// <Input placeholder="请输入"/>
<TextArea rows={4} placeholder="请输入"></TextArea>
)}
</FormItem>
</Form>
)
}
}
);
class Sponsor extends Component {
constructor(props) {
super(props);
this.state = {
isSpin: false,
user: undefined,
sponsor_description: undefined,
sponsors: undefined,
edit: false,
tiers: [],
};
}
componentDidMount = () => {
this.fetchUser();
this.fetchData();
};
fetchUser = () => {
this.setState({
isSpin: true,
});
const { current_user } = this.props;
const { username } = this.props.match.params;
let url = `/users/${username || (current_user && current_user.login)}.json`;
axios
.get(url)
.then((result) => {
// TODO: 在这里添加了对用户自我介绍的处理,前后端交互实现后需要删掉
// result.data.sponsor_description = tempDesc;
this.setState({
user: result.data,
sponsor_description: result.data.sponsor_description,
isSpin: false,
}, () => {this.fetchSponsors()});
// console.log(result.data);
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
};
fetchSponsors = () => {
// console.log("fetch sponsors");
const user_id = this.state.user.user_id;
let url = `/sponsorships/sponsored.json`;
axios.get(url, {params: {id: user_id}})
.then((result) => {
// console.log(result);
this.setState({
sponsors: result.data.sponsorships,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
// this.setState({
// sponsors: tempData,
// displayList: tempData,
// })
// this.setState({
// sponsors: tempSponsors,
// });
}
fetchData = () => {
let url = `/sponsor_tiers.json`;
const user_login = this.props.match.params.username;
axios
.get(url, {params:{login: user_login}})
.then((result) => {
// console.log(result.data);
// console.log(tempData)
this.setState({
tiers: result.data
});
})
.catch((error) => {
console.log(error);
})
}
editDescription = () => {
this.setState({
edit: true,
});
}
cancelEdit = () => {
this.setState({
edit: false,
})
}
confirmEdit = () => {
//TODO: 增加和后端交互
let value = this.formRef.getItemsValue().sponsor_description;
// console.log(value);
let user = this.state.user;
let url = `/users/${user.user_id}/update_sponsor_description.json`
axios.put(url, {sponsor_description: value})
.then((result) => {
user.sponsor_description = value;
this.setState({
user: user,
edit: false
})
this.props.showNotification("修改成功")
})
.catch(error => {
console.log(error);
this.props.showNotification("修改失败")
})
// if (user){
// user.sponsor_description = value;
// }
// this.setState({
// user: user,
// edit: false,
// });
}
visitorTemplate = () => {
const user = this.state.user;
return (
<div>
{user && user.sponsor_description?
(<p>{user.sponsor_description}</p>):(<p></p>)}
</div>
);
}
manageTemplate = () => {
const user = this.state.user;
return (
<div>
<div>
<i className="iconfont icon-bianji3 font-15" onClick={() => this.editDescription()}></i>
</div>
{user && user.sponsor_description? (<div>{user.sponsor_description}</div>):(<div></div>)}
</div>
);
}
editTemplate = () => {
const user = this.state.user;
return (
<div>
<DescriptionForm
initValue={user && user.sponsor_description}
wrappedComponentRef={(form) => this.formRef = form}
/>
<Button onClick={() => this.confirmEdit()}>确认</Button>
<Button onClick={() => this.cancelEdit()}>取消</Button>
</div>
);
}
sponsorList(){
const {sponsors} = this.state;
const sponsorList = (sponsors && sponsors.length>0 ? sponsors.map((item, key)=>{
return (
<Link to={`/users/${item.login}`} className="show-user-link">
<img className="sponsor-page-sponsors" alt="" src={getImageUrl(`images/${item && item.image_url}`)} title={item.username}></img>
</Link>);
})
:"")
return (<p>{sponsorList}</p>);
}
render(){
const { current_user} = this.props;
const { user, isSpin, tiers} = this.state;
const sponsorList = this.sponsorList();
// console.log(tiers);
var content = "";
if (current_user && user && user.login !== current_user.login){
content = this.visitorTemplate();
}
else if(current_user && user && user.login === current_user.login && this.state.edit){
content = this.editTemplate();
}
else if(current_user && user && user.login === current_user.login && !this.state.edit){
content = this.manageTemplate();
}
return (
<div className="newMain clearfix">
<Spin spinning={isSpin}>
<div className="new-content-flex">
<div className="sponsor-page-left">
<div className="list-l-Menu pd20 ">
<div className="text-center mt15 font-16 fwb"> 成为{user && user.username}的赞助者吧</div>
<div className="text-center"><Avatar
size={110}
src={getImageUrl(`images/${user && user.image_url}`)}
/>
{user && user.user_identity && (
<div className="mt-n15 position-relative">
<Tag color="#FF6E21" style={{marginRight:"0px"}}>{user && user.user_identity}</Tag>
</div>
)}
</div>
<Divider />
{content}
<Divider />
<div>
赞助者:
{sponsorList}
</div>
</div>
<div className="bgcF">
{/* <div className="list-l-Menu pd20 ">
{content}
</div>
<div className="list-l-Menu pd20 ">
赞助者:
{sponsorList}
</div> */}
</div>
</div>
<div className="sponsor-page-right">
<SponsorTierItem
{...this.props}
{...this.state}
tiers={tiers}>
</SponsorTierItem>
</div>
</div>
</Spin>
</div>
);
}
}
export default withRouter(
ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newMain",
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Sponsor))))
);

View File

@ -0,0 +1,325 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Avatar, Tag, Button, Spin, Input, Divider, Form, Radio, Alert, message, Modal} from "antd";
import { Route, Switch } from "react-router-dom";
import { withRouter } from "react-router";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import axios from "axios";
import { getImageUrl } from "educoder";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
import "../users/new_user.css";
import "../css/index.scss";
import '../users/Index.scss';
import "./sponsor.css";
import { submitUserCode } from "../../redux/actions/ojForUser";
const tempData = {amount:100, description: "如果您更加慷慨的话就选择这个"};
const tempBalance = 999;
const FormItem = Form.Item;
const { confirm } = Modal;
const SponsorConfirmation = Form.create()(
class extends Component{
constructor(props) {
super(props);
this.state = {
isSpin: false,
user: undefined,
tier: undefined,
single: false,
balance: undefined,
is_sponsoring: false,
visible: false,
sponsorship_id: undefined,
};
}
componentDidMount = () => {
this.fetchUser();
this.fetchTierInformation();
this.fetchBalance();
// this.fetchData();
};
//组件刚刚挂载时TPMINDEXHOC还没从后端获取current_user需要在获取后再使用current_user的内容
componentWillReceiveProps = () => {
if (this.props.current_user)
this.fetchBalance();
}
fetchUser = () => {
this.setState({
isSpin: true,
});
const { current_user } = this.props;
const { username } = this.props.match.params;
let url = `/users/${username || (current_user && current_user.login)}.json`;
axios
.get(url)
.then((result) => {
this.setState({
user: result.data,
isSpin: false,
});
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
};
fetchTierInformation = () => {
const { current_user } = this.props;
const { username, tier_id } = this.props.match.params;
let url = `/sponsor_tiers/${tier_id}.json`;
axios
.get(url)
.then((result) => {
this.setState({
tier: result.data.tier,
is_sponsoring: result.data.is_sponsoring,
sponsorship_id: result.data.sponsorship_id,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
}
fetchBalance = () => {
const { current_user } = this.props;
let url = `/wallets/balance.json`;
if (current_user){
axios
.get(url, {params: {id: current_user.user_id}})
.then((result) => {
this.setState({
balance: result.data.balance,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
}
}
reSelect = () => {
const {user} = this.state;
this.setState({
route_type: undefined
})
this.props.history.push(`/sponsor/${user && user.login}`)
}
changeSingle = (e) => {
this.setState({
single: e.target.value
})
}
updateSponsorship = () => {
const value = this.props.form.getFieldsValue();
const {tier, user, sponsorship_id} = this.state;
const {current_user} = this.props;
let url = `/sponsorships/${sponsorship_id}.json`;
axios.put(url, {
amount: tier.tier,
visible: value.visible
})
.then((result) => {
if (result && result.data.status == 1)
this.props.showNotification(result.data.message);
})
.catch((error) => {
console.log(error);
})
}
submit = () => {
const value = this.props.form.getFieldsValue();
const {tier, user} = this.state;
const {current_user} = this.props;
// console.log(value);
let url = `/sponsorships.json`;
axios.post(url, {
amount: tier.tier,
visible: value.visible,
single: value.single,
developer_id: user.user_id,
})
.then((result) => {
// console.log(result);
if (result && result.data.status == 1)
this.props.showNotification(result.data.message);
})
.catch((error) => {
console.log(error);
})
}
handleCancel = e => {
this.setState({
visible: false,
});
};
showModal = () => {
this.setState({
visible: true,
});
};
showConfirm = () => {
const {user} = this.state;
const fun = this.state.is_sponsoring?this.updateSponsorship:this.submit;
let text = this.state.is_sponsoring?`确认要修改对 ${user && user.username} 的赞助吗?若修改金额,将在下次自动扣款生效。`
:`确认要赞助 ${user && user.username} 吗?`;
confirm({
// title: '确认赞助',
// icon: <ExclamationCircleOutlined />,
content: text,
onOk() {
fun()
},
onCancel() {
},
});
}
render(){
const {tier_id, username} = this.props.match.params;
const {current_user, form} = this.props;
const {user, isSpin, tier, balance, is_sponsoring, single} = this.state;
const {getFieldDecorator} = form;
const current_username = current_user && current_user.username;
const alert_text = this.state.single? `您选择了单次付费,本次扣除${tier && tier.tier}硬币`
:`您选择了按月付费每月20日将扣除${tier && tier.tier}硬币`;
// console.log("sponsoring", is_sponsoring);
// console.log("tier: ", tier);
// console.log("current user", current_user);
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
return (
<div className="newMain clearfix">
<Spin spinning={isSpin}>
<div className="new-content-flex">
<div className="sponsor-confirmation-left">
<div className="list-l-Menu pd20 ">
<p>
<Avatar
size={50}
src={getImageUrl(`images/${user && user.image_url}`)}
/>
<a href={`/sponsor/${user && user.login}`}>赞助{user && user.username}</a>/
</p>
<p>
赞助者为
<Avatar
size={50}
src={getImageUrl(`images/${current_user && current_user.image_url}`)}
/>
{current_user && current_user.username}
</p>
<Divider></Divider>
<p>所选赞助等级</p>
<p>{tier && tier.tier}硬币</p>
<p>{tier && tier.description}</p>
<Button onClick={() => this.reSelect()}>重新选择</Button>
</div>
</div>
<div className="sponsor-confirmation-right">
<div className="list-l-Menu pd20 ">
<Form>
<FormItem >
{getFieldDecorator(`single`,{
rules: [{
required: true
}],
initialValue: single
})(
<Radio.Group onChange={(e) => this.changeSingle(e)} disabled={is_sponsoring}>
<Radio style={radioStyle} value={true}>单次付费</Radio>
<Radio style={radioStyle} value={false}>按月支付</Radio>
</Radio.Group>
)}
</FormItem>
<p>本次支付金额{tier && tier.tier}硬币</p>
<p>{this.state.single? "单次付费": "即日起-次月20日"}</p>
<Divider></Divider>
<div>支付信息</div>
<div>
<div>
<Avatar
size={50}
src={getImageUrl(`images/${current_user && current_user.image_url}`)}
/>
</div>
<div>
<div>{current_user && current_user.username}</div>
<div>硬币余额{balance}</div>
</div>
</div>
<Alert message={alert_text} type="warning"/>
<Divider></Divider>
<span>赞助关系可见性</span>
<FormItem >
{getFieldDecorator(`visible`,{
rules: [{
required: true
}],
initialValue: 1
})(
<Radio.Group >
<Radio style={radioStyle} value={1}>所有人可见</Radio>
<Radio style={radioStyle} value={0}>私密</Radio>
</Radio.Group>
)}
</FormItem>
<Button type='primary' className="confirm-btn" onClick={() => this.showConfirm()}>赞助 {user && user.username}</Button>
</Form>
</div>
</div>
</div>
</Spin>
</div>
);
}
});
export default withRouter(
ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newMain",
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(SponsorConfirmation))))
);

View File

@ -0,0 +1,80 @@
.sponsor-page-left{
width: 65%;
padding-right: 20px;
box-sizing: border-box;
margin-bottom: 20px;
}
.sponsor-page-right{
width: 35%;
padding-right: 20px;
box-sizing: border-box;
margin-bottom: 20px;
}
.sponsor-page-sponsors{
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 11px;
}
.sponsor-confirmation-left{
width: 35%;
padding-right: 20px;
box-sizing: border-box;
margin-bottom: 20px;
}
.sponsor-confirmation-right{
width: 65%;
padding-right: 20px;
box-sizing: border-box;
margin-bottom: 20px;
}
.sponsor-inline{
display: inline-block;
}
.tier-Item:last-child{
border-bottom: none !important;
}
.tier-Item{
border-bottom:1px solid rgba(238,238,238,1);
padding:9px 12px;
}
.right{
float: right
}
.btn-border-5{
border-radius: 5px;
}
.description-edit{
min-height:28px;
border:true;
}
.tier-title{
font-size: 16px;
font-weight: 600;
}
.mr10{
margin-right: 10px;
}
.confirm-btn{
width: 100%;
border-radius: 5px;
}
.sponsor-item-btn{
display: flex;
flex-direction: column;
}

View File

@ -0,0 +1,422 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Avatar, Tag, Button, Spin, Icon, Modal, Input, Form, message, Popconfirm, Divider, InputNumber} from "antd";
import { Route, Switch } from "react-router-dom";
import { withRouter } from "react-router";
// import { EditOutlined } from "@ant-design/icons";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import axios from "axios";
import { getImageUrl } from "educoder";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
import "../users/new_user.css";
import "../css/index.scss";
import '../users/Index.scss';
import "./sponsor.css";
import "../Main/list.scss";
import Item from "antd/lib/list/Item";
const FormItem = Form.Item;
const EditTierForm = Form.create()(
class extends Component{
getItemsValue = ()=>{
const val= this.props.form.getFieldsValue(); // 获取from表单的值
return val;
}
render(){
const { form, initValue1, initValue2, initValueList } = this.props;
const { getFieldDecorator } = form; // 校验控件
return(
<Form >
<FormItem label={`金额`} >
{getFieldDecorator(`tier`,{
rules: [{
message: '请输入数字!',
pattern: /^[0-9]+$/,
required: true
}],
initialValue: initValue1 ? initValue1 : undefined
})(
<InputNumber placeholder="请输入数字"/>
)}
</FormItem>
<FormItem label={`描述`} >
{getFieldDecorator(`description`,{
rules: [{
message: '必填字段!',
required: true,
}, {
max: 255,
message: "长度不能超过255个字符"
}],
initialValue: initValue2 ? initValue2 : undefined
})(
<Input placeholder="请输入"/>
)}
</FormItem>
</Form>
)
}
});
class SponsorTierItem extends Component{
constructor(props) {
super(props)
var edit = new Array();
if (props.tiers){
for(var i=0; i<props.tiers.length; i++) edit.push(false);
}
this.state = {
tiers: props.tiers,
new_tier: undefined,
edit: edit,
isSpin: false,
}
// this.state = {
// tiers: undefined,
// new_tier: undefined,
// edit: undefined,
// isSpin: false,
// }
}
componentDidMount = () => {
}
// 如果服务器较慢组件会先被挂载此时父组件传来的props数据是空的但是获得数据后,有新的props需要更新。
// 如果用户点击了修改自我描述等父组件的方法,父组件会重新渲染,这个方法又会被调用,有可能原有的编辑框会丢失。
// 因此先判断一下父组件传过来的数据是否有变化。没有变化则不需要修改state
componentWillReceiveProps = () => {
if (this.props.tiers !== this.state.tiers){
var edit = new Array();
for(var i=0; i<this.props.tiers.length; i++) edit.push(false);
this.setState({
tiers: this.props.tiers,
edit: edit,
})
}
}
fetchData = () => {
let url = `/sponsor_tiers.json`;
axios
.get(url)
.then((result) => {
console.log(result.data);
// console.log(tempData);
var edit = new Array();
for(var i=0; i<result.data.length; i++) edit.push(false);
this.setState({
tiers: result.data,
edit: edit,
})
})
.catch((error) => {
console.log(error);
})
}
fetchUser = () => {
this.setState({
isSpin: true,
});
const { current_user } = this.props;
const { username } = this.props.match.params;
let url = `/users/${username || (current_user && current_user.login)}.json`;
axios
.get(url)
.then((result) => {
this.setState({
user: result.data,
isSpin: false,
});
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
};
editTier = (item, key, e) => {
var edit = this.state.edit;
var editing = false;
for(var i=0; i<edit.length; i++)
editing = editing || edit[i];
if(editing){
this.props.showNotification("请先完成当前编辑");
return;
}
else{
edit[key] = true;
this.setState({
edit:edit
})
}
}
confirmEdit = async (item, key, e) => {
let url;
try {
const values = await this.formRef.props.form.validateFields();
// console.log('Success:', values);
} catch (errorInfo) {
this.props.showNotification('提交失败,数据不合法');
return false;
}
let values = this.formRef.getItemsValue();
// console.log(this.formRef);
const {current_user} = this.props;
if (this.state.new_tier == key){
console.log("new tier");
url = `/sponsor_tiers.json`;
axios
.post(url, {
...values,
user_id: current_user.user_id
})
.then((result) => {
var {tiers, edit} = this.state;
tiers[key] = result.data.tier;
edit[key] = false;
this.setState({
tiers: tiers,
edit: edit,
new_tier: undefined
})
// message.success("新增成功");
this.props.showNotification(`新增成功!`);
})
.catch((error) => {
console.log(error);
this.props.showNotification("新增失败");
})
}
else{
url = `/sponsor_tiers/${item.id}.json`
axios
.put(url, {
...values,
})
.then((result) => {
var {tiers, edit} = this.state;
tiers[key] = result.data.tier;
edit[key] = false;
this.setState({
tiers: tiers,
edit: edit,
new_tier: undefined
})
// message.success("修改成功");
this.props.showNotification(`修改成功!`);
})
.catch((error) => {
console.log(error);
this.props.showNotification("修改失败");
})
}
// TODO: 在此处加入对后端的修改请求
// TODO: 修改的请求实现
}
cancelEdit = (item, key, e) => {
let {tiers, edit, new_tier} = this.state;
if (new_tier){
tiers.pop();
edit.pop();
}
else {
edit[key] = false;
}
this.setState({
tiers: tiers,
edit: edit,
new_tier: undefined
})
}
newTier = () => {
if (this.state.new_tier !== undefined){
this.props.showNotification("请先完成当前编辑")
return;
}
let {tiers, edit} = this.state;
tiers.push({tier: 1, description: ""})
edit.push(true);
this.setState({
tiers: tiers,
edit: edit,
new_tier: tiers.length - 1,
})
}
deleteTier = (item, key, e) => {
// TODO: 此处向后端发送请求删除
let {tiers, edit} = this.state;
let url = `/sponsor_tiers/${item.id}.json`;
axios
.delete(url)
.then((result) => {
tiers.splice(key, 1)
edit.splice(key, 1)
this.setState({
tiers: tiers,
edit: edit,
})
this.props.showNotification("删除成功");
})
.catch((error) => {
console.log(error);
this.props.showNotification("删除失败");
})
}
toConformation = (item, key, e) => {
const {user} = this.props;
this.setState({
route_type: undefined
})
this.props.history.push(`/sponsor_confirmation/${user && user.login}/${item.id}`)
}
visitorTemplate = (item, key) => {
return (
<ul className="tier-Item">
<div className="tier-title">
{item.tier}&nbsp;&nbsp;硬币
<Button className="right btn-border-5" onClick={(e) => this.toConformation(item, key, e)}>选择</Button>
</div>
<div>
{item.description}
</div>
</ul>
);
}
manageTemplate = (item, key) => {
return (
<div className="tier-Item">
<div>
<span className="tier-title">{item.tier}&nbsp;&nbsp;硬币</span>
<Popconfirm
title="确认删除?"
onConfirm={e => this.deleteTier(item, key, e)}
// onCancel={cancel}
okText="是"
cancelText="否"
>
<i className="iconfont icon-shanchu font-15 right"></i>
</Popconfirm>
<i className="iconfont icon-bianji3 font-15 mr10 right" onClick={e => this.editTier(item, key, e)}></i>
</div>
<div>
{item.description}
</div>
</div>
);
}
editTemplate = (item, key) => {
return (
<div className="tier-Item">
<EditTierForm
initValue1={item.tier}
initValue2={item.description}
wrappedComponentRef={(form) => this.formRef = form}
/>
<Button onClick={e => this.confirmEdit(item, key, e)}>确定</Button>
<Button onClick={e => this.cancelEdit(item, key, e)}>取消</Button>
</div>
);
}
render() {
const {tiers} = this.state;
const { current_user} = this.props;
const {user} = this.props;
// console.log("item state tiers:", tiers);
// console.log("item props tiers:", this.props.tiers);
const renderList = (
tiers && tiers.length > 0 ? tiers.map((item, key) => {
const tier = this.state.edit[key]? (<Input></Input>):item.tier;
const description = this.state.edit[key]? (<Input></Input>):item.description;
var content = "";
if (current_user && user && user.login !== current_user.login){
content = this.visitorTemplate(item, key);
}
else if(current_user && user && user.login === current_user.login && this.state.edit[key]){
content = this.editTemplate(item, key);
}
else if(current_user && user && user.login === current_user.login && !this.state.edit[key]){
content = this.manageTemplate(item, key);
}
// return (
// <ul className="list-l-Menu">
// <div className="font-15 mr5">
// 金额:{amount}
// {current_user && user && user.login === current_user.login ?
// // (<Icon type="edit" onClick={item => this.editTier(item)}/>
// (<i className="iconfont icon-bianji3 font-15 mr5" onClick={e => this.editTier(item, key, e)}></i>):
// <Button >选择</Button>}
// </div>
// <div className="font-15 mr5">
// 描述:{description}
// {current_user && user && user.login === current_user.login ?
// (<i className="iconfont icon-shanchu font-15"></i>):""}
// </div>
// </ul>
// )
return content;
}) : ""
);
return (
<div>
<div className="list-l-Menu">
<p className="tier-Item tier-title">选择您的赞助等级</p>
{/* <Divider/> */}
{renderList}
</div>
{current_user && user && user.login === current_user.login ?
( <Button type="primary" onClick={() => this.newTier()}>新增赞助等级</Button>):
""
}
</div>
)
}
}
export default SponsorTierItem;

View File

@ -1,6 +1,6 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Spin , Menu } from "antd";
import { Spin , Menu, Button } from "antd";
import FocusButton from "../UsersList/focus_button";
import axios from "axios";
@ -64,6 +64,19 @@ const Personal = Loadable({
})
const Wallet = Loadable({
loader: () => import("./sponsor/wallet"),
loading: Loading,
});
const SponsorManagement = Loadable({
loader: () => import("./sponsor/SponsorManagement"),
loading: Loading,
});
const SponsorDataCharts = Loadable({
loader: () => import("./sponsor/communityData"),
loading: Loading,
});
class Infos extends Component {
constructor(props) {
super(props);
@ -72,6 +85,9 @@ class Infos extends Component {
user: undefined,
project_type: undefined,
route_type: undefined,
c: undefined,
sponsor_management: undefined,
choose_chart: undefined,
undo_events:0,
menuKey:"6",
avatarVisible:false
@ -108,6 +124,10 @@ class Infos extends Component {
this.setState({menuKey:undefined,route_type:"following"});
}else if(pathname === `/${username}/followers`){
this.setState({menuKey:undefined,route_type:"followers"});
}else if(pathname === `/${username}/wallet`){
this.setState({menuKey:"6",route_type:undefined});
}else if(pathname === `/${username}/sponsor_management`){
this.setState({menuKey:"7",route_type:undefined});
}else{
this.setState({menuKey:"6",route_type:undefined});
}
@ -197,6 +217,58 @@ class Infos extends Component {
this.props.history.push(`/${user && user.login}/organizes`)
}
sponsor_link = () => {
const {user} = this.state
this.setState({
route_type: undefined
})
this.props.history.push(`/sponsor/${user && user.login}`)
}
sponsor_management_link = () => {
const {user} = this.state
this.setState({
route_type: undefined,
sponsor_management: true,
project_type: undefined,
choose_wallet: undefined,
choose_chart: undefined,
})
this.props.history.push(`/users/${user && user.login}/sponsor_management`)
}
wallet_link = () => {
const {user} = this.state
this.setState({
project_type: undefined,
choose_wallet: true,
route_type: undefined,
sponsor_management: undefined,
choose_chart: undefined,
})
this.props.history.push(`/users/${user && user.login}/wallet`)
}
sponsor_setting_link = () => {
const {user} = this.state
this.setState({
route_type: undefined
})
this.props.history.push(`/users/${user && user.login}/sponsor_setting`)
}
sponsor_statistic = () => {
const {user} = this.state
this.setState({
project_type: undefined,
choose_wallet: undefined,
route_type: undefined,
sponsor_management: undefined,
choose_chart: true
})
this.props.history.push(`/users/${user && user.login}/sponsor_community_data`)
}
resetUser=()=>{
const { resetUserInfo } = this.props;
@ -253,14 +325,17 @@ class Infos extends Component {
}
render() {
// sponsor相关代码
const { choose_wallet, choose_chart, sponsor_management } = this.state;
const { current_user } = this.props;
const { username } = this.props.match.params;
const { user, isSpin, route_type , undo_events , menuKey , avatarVisible } = this.state;
return (
<div className="newMain clearfix">
{
avatarVisible &&
<Avatar
avatarVisible &&
<Avatar
onCancel={this.onCancelAvatar}
avatarImg={getImageUrl(`/${user && user.image_url}`)}
login={current_user && current_user.login}
@ -295,42 +370,51 @@ class Infos extends Component {
<div className="userDescription">
{user && user.description}
</div>
<div>
{user && current_user && user.login === current_user.login && (
<div className="user-info-star-button">
{/*<Button
block
className="text-button-grey"
onClick={()=>this.props.history.push(`/users/${user.login}/info`)}
type="primary"
>
{" "}
<i className="iconfont icon-shezhi4 font-15"></i>
修改资料
</Button>*/}
<Button
block
className="text-button-grey ml-5"
href={`/sponsor/${user && user.login}`}
type="primary"
>
修改赞助信息
</Button>
{/* {user && current_user && user.login === current_user.login && (
<div className="user-info-star-button ">
<Button
block
className="text-button-grey"
onClick={()=>this.props.history.push(`/${user.login}/info`)}
type="primary"
>
{" "}
<i className="iconfont icon-shezhi4 font-15 mr5"></i>
修改资料
</Button>
</div>
)} */}
{current_user && user && user.login !== current_user.login && (
<div className="user-info-star-button ">
<FocusButton
is_block={true}
is_watch={user.is_watch}
id={user.login}
fontClass={"font-14 ml5"}
starText={"关注TA"}
notReset={true}
/>
</div>
)}
{
current_user && user && user.login === current_user.login &&
<div className="usersDesc">
<p>想全方位展示自己试试点击下方按钮定制化您的专属个人简介吧</p>
{
user.show_super_description ? <a className="emptyBtn" onClick={()=>this.aboutDescFunc(false)}>隐藏个人简介</a> : <a className="fullBtn" onClick={()=>this.aboutDescFunc(true)}></a>
}
</div>
}
</div>
)}
{current_user && user && user.login !== current_user.login && (
<div className="user-info-star-button ">
<FocusButton
is_block={true}
is_watch={user.is_watch}
id={user.login}
fontClass={"font-14 ml5"}
starText={"关注TA"}
/>
<Button
block
className="text-button-grey ml-5"
href={`/sponsor/${user && user.login}`}
type="primary"
>
赞助
</Button>
</div>
)}
</div>
<div className="focusBox">
<Link
to={`/${user && user.login}/following`}
@ -391,6 +475,33 @@ class Infos extends Component {
{ user && user.user_org_count && user.user_org_count > 0 ? <span className="menuNum">({user.user_org_count})</span>:""}
</Link>
</Menu.Item>
{
current_user && current_user.login && current_user.login === username ?
<Menu.Item key="6">
<Link to={`/users/${user && user.login}/wallet`}>
<i className="iconfont icon-bianzu1"></i>
</Link>
</Menu.Item>
:""
}
{
current_user && current_user.login && current_user.login === username ?
<Menu.Item key="7">
<Link to={`/users/${user && user.login}/sponsor_management`}>
<i className="iconfont icon-dashujucunchu"></i>
</Link>
</Menu.Item>
:""
}
{/* {
current_user && current_user.login && current_user.login === username ?
<Menu.Item key="6">
<Link to={`/users/${user && user.login}/sponsor_community_data`}>
<i className="iconfont icon-gongzuoliu1"></i>
</Link>
</Menu.Item>
:""
} */}
</Menu>
}
{user && (
@ -407,6 +518,24 @@ class Infos extends Component {
return <Notice {...this.props} {...this.state} deleteUndoEvent={this.deleteUndoEvent}/>;
}}
></Route>
<Route
path="/:username/wallet"
render={() => {
return <Wallet {...this.props} {...this.state} />;
}}
></Route>
<Route
path="/:username/sponsor_management"
render={() => {
return <SponsorManagement {...this.props} {...this.state} />;
}}
></Route>
<Route
path="/:username/sponsor_community_data"
render={() => {
return <SponsorDataCharts {...this.props} {...this.state} is_sponsor={true}/>;
}}
></Route>
<Route
path="/:username/followers"
render={() => {

View File

@ -29,10 +29,15 @@
.mt-n15{margin-top: -15px;}
.position-relative{position: relative;}
.mr-5{margin-right: 5px;}
.mt-5{margin-top: 5px;}
.ml-5{margin-left: 5px;}
a.text-button-grey{
color: #fff;
}
.user-info-star-button{margin: 20px 50px 0 50px}
.user-info-star-button{
display: flex;
margin: 20px 20px 0 20px
}
.list-l-p{
width: 100%;
display: -ms-flexbox;

View File

@ -0,0 +1,45 @@
import React, { Component } from 'react';
import { Tooltip } from 'antd';
import '../../css/index.scss'
import '../../Main/list.scss';
class CoinChangeItem extends Component {
TurnToDetail = (login, url) => {
this.props.history.push({
pathname: url,
state: login
})
}
render() {
const { coinChanges, current_user } = this.props;
const renderList = (
coinChanges && coinChanges.length > 0 ? coinChanges.map((item, key) => {
let url = current_user && item.to_user_login == current_user.login? `/users/${item.from_user_login}`:`/users/${item.to_user_login}`;
return (
<div className="p-r-Item" key={key}>
<div className="p-r-Infos">
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>金额{current_user && item.to_user_login == current_user.login? "收入":"支出"}{item.amount}硬币</p>
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>变动原因{item.reason}</p>
{/* <p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>备注:{item.description}</p> */}
<div className="p-r-about">
<span className="p-r-detail">
<span><label>时间</label>{item.date}</span>
{current_user && item.to_user_login == current_user.login?
(<span><label>金额来源</label><a href={url}>{item.from_user}</a></span>):
(<span><label>金额去向</label><a href={url}>{item.to_user}</a></span>)}
</span>
</div>
</div>
</div>
)
}) : ""
)
return (
<div className="project-list minH-670">
{renderList}
</div>
)
}
}
export default CoinChangeItem;

View File

@ -0,0 +1,309 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Menu, Input, Spin, Pagination, Popover, Button, Divider } from "antd";
import SponsorBarCharts from "./charts/sponsorBarChart";
import SponsorPieCharts from "./charts/sponsorPieChart";
import axios from "axios";
import CoinChangeItem from "./CoinChangeItem";
import Nodata from "../../Nodata";
import img_array from "../../Images/array.png";
import SponsorList from "./sponsor_list";
import "../../sponsor/sponsor.css";
// import "../new_user.css";
// const Search = Input.Search;
// const tempData = [
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: true, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "-", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: true, sponsor: true, login:"alpc104", start_time: "2020-08-01", stop_time: "-", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "-", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: true, login:"alpc104", start_time: "2020-08-01", stop_time: "-", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "-", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "2020-09-05", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: true, login:"alpc104", start_time: "2020-08-01", stop_time: "2020-09-05", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "2020-09-05", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "2020-09-05", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "2020-09-05", amount: 100},
// {image_url: "avatars/User/b", username: "万山川", user_id: 1369, visible: false, sponsor: false, login:"alpc104", start_time: "2020-08-01", stop_time: "2020-09-05", amount: 100},
// ];
class SponsorManagement extends Component{
constructor(props) {
super(props);
this.state = {
page: 1,
limit: 15,
sort_by: undefined,
totalCount: undefined,
isSpin: false,
total: undefined,
category: "sponsoring",
is_sponsor: false,
sponsors: undefined,
displayList: undefined,
chartsData: {income:[], outcome:[]},
};
}
changeCategory = (cate) => {
this.setState({
category: cate.target.value,
page: 1,
}, ()=>{
if(this.state.category === "chart")
this.get_chart_data();
else
this.get_sponsors();
});
// if(cate.target.value === "chart"){
// this.setState({
// category: cate.target.value,
// page: 1,
// });
// }
// else{
// this.setState({
// category: cate.target.value,
// page: 1,
// }, ()=>{this.get_sponsors();});
// }
};
componentDidMount = () => {
this.get_sponsors();
}
get_chart_data = () => {
this.setState({
isSpin: true
})
let url = `/wallets/balance_chart.json`;
const {current_user} = this.props;
let user_id = current_user && current_user.user_id;
if (current_user){
axios.get(url, {
params: {
id: user_id,
sponsor: true,
}})
.then((result) => {
this.setState({
chartsData: result.data,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
}
};
get_sponsors = ()=>{
const user_id = this.props.current_user.user_id;
let url = this.state.is_sponsor? `sponsoring`:`sponsored`;
url = this.state.category === "stopped"? `stopped_` + url: url;
url = `/sponsorships/` + url + `.json`;
const {page, limit} = this.state;
this.setState({
isSpin: true
})
axios.get(url, {
params: {
id: user_id,
page: page,
limit: limit,
}})
.then((result) => {
// console.log(result);
this.setState({
displayList: result.data.sponsorships,
total: result.data.count,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
// this.setState({
// sponsors: tempData,
// displayList: tempData,
// })
}
//切换页数
changePage = (page) => {
this.setState({
page: page
}, ()=>{this.get_sponsors()})
};
// 排序
ChangeSoryBy = (e) => {
console.log(e.key)
};
changeSearchValue = (e) => {
this.setState({
search: e.target.value,
});
};
menu =()=> (
<Menu onClick={this.ChangeSoryBy}>
<Menu.Item key="time_order">时间从近到远排序</Menu.Item>
<Menu.Item key="reverse_time_order">时间从远到近排序</Menu.Item>
</Menu>
);
category_button=(category)=>{
const { current_user, user } = this.props;
const button_lists =
user && current_user && user.login === current_user.login
? [
{ type: "sponsoring", name: "赞助中" },
{ type: "stopped", name: "已终止" },
{ type: "chart", name: "统计图表" },
]
:
[];
let list = button_lists.map((item, key) => {
return (
<span key={key} className="pr15">
<Button
type={
(category && category === item.type) || (!category && !item.type)
? "primary"
: "default"
}
ghost={
(category && category === item.type) || (!category && !item.type)
}
value={item.type}
onClick={this.changeCategory}
>
{item.name}
</Button>
</span>
);
})
return list;
}
changeStatus=(check_is_sponsor, e)=>{
// const {is_sponsor} = this.state
// const new_is_sponsor = is_sponsor === check_is_sponsor ? undefined : check_is_sponsor
// this.state.is_sponsor = check_is_sponsor;
this.setState({
is_sponsor: check_is_sponsor,
page: 1,
}, ()=>{
if(this.state.category === "chart")
this.get_chart_data();
else
this.get_sponsors();
});
}
render() {
const { current_user, user } = this.props;
const { category , is_sponsor, sponsors, displayList, chartsData} = this.state;
const {isSpin, total, search, limit, page }= this.state;
// console.log(displayList);
const sponsorList = displayList && displayList.length > 0 ?
<SponsorList
{...this.props}
userClass={"w-33"}
current_user={current_user}
users={displayList}
rerender={this.get_sponsors}
history={this.props.history}
></SponsorList>
:
<Nodata _html={`暂时没有数据`} />
const chartComponent = <div>
<p>七天内赞助{this.state.is_sponsor?"支出":"收入"}</p>
<SponsorBarCharts is_sponsor={this.state.is_sponsor} data={chartsData}></SponsorBarCharts>
{/* <p>{this.state.is_sponsor?"":""}</p>
<SponsorPieCharts is_sponsor={this.state.is_sponsor}></SponsorPieCharts> */}
</div>
const displayComponent = category==="chart"?chartComponent
:
sponsorList;
return (
// <div className="list-right boxShandow radius-2" style={{padding:0}}>
<Spin spinning={isSpin}>
{/* <div className="list-r-operation"> */}
{/* <Search
placeholder="输入关键字进行搜索"
enterButton="搜索"
size="large"
onSearch={this.get_sponsors}
className="list-r-Search"
value={search}
onChange={this.changeSearchValue}
/> */}
{/* <div>
<Popover content={this.menu()} trigger={["click"]} placement="bottom">
<a className="ant-dropdown-link">
<span className="color-blue font-16">
排序 <img src={img_array} alt="" width="10px" />
</span>
</a>
</Popover>
</div> */}
{/* </div> */}
<div className="infosType">
<div>{this.category_button(category)}</div>
{
user && current_user && user.login === current_user.login ?
<div className="infoStatus">
<span className={is_sponsor === true ? "active" : "" } onClick={(e)=>this.changeStatus(true, e)}>我赞助的</span>
{
!is_sponsor ? (<Divider type={"vertical"} className="statusDivider" ></Divider>):""
}
<span className={is_sponsor === false ? "active" : "" } onClick={(e)=>this.changeStatus(false, e)}>赞助我的</span>
</div>
:""
}
</div>
{user && current_user && user.login === current_user.login?
displayComponent:<Nodata _html={`暂时没有项目`} />
}
{
total && total > limit && category!="chart"?
<div className="edu-txt-center pt30 mb30 border-top-grey">
<Pagination
simple
defaultCurrent={page}
total={total}
pageSize={limit}
onChange={this.changePage}
></Pagination>
</div>
:
""
}
</Spin>
// </div>
);
}
};
export default SponsorManagement;

View File

@ -0,0 +1,77 @@
import React, { Component } from 'react';
import {XYPlot, VerticalBarSeries, VerticalGridLines, HorizontalGridLines, XAxis, YAxis, Crosshair, DiscreteColorLegend} from 'react-vis';
// import DiscreteColorLegend from 'legends/discrete-color-legend';
import "./style.scss";
// const ONE_DAY = 86400000;
// const d = new Date().getTime()-ONE_DAY*7;
// const data = [
// {x: new Date(d+ONE_DAY).toLocaleDateString(), y: 8},
// {x: new Date(d+ONE_DAY*2).toLocaleDateString(), y: 5},
// {x: new Date(d+ONE_DAY*3).toLocaleDateString(), y: 4},
// {x: new Date(d+ONE_DAY*4).toLocaleDateString(), y: 9},
// {x: new Date(d+ONE_DAY*5).toLocaleDateString(), y: 2},
// {x: new Date(d+ONE_DAY*6).toLocaleDateString(), y: 7},
// {x: new Date(d+ONE_DAY*7).toLocaleDateString(), y: 2},
// ];
// const data2 = [
// {x: new Date(d+ONE_DAY).toLocaleDateString(), y: 2},
// {x: new Date(d+ONE_DAY*2).toLocaleDateString(), y: 3},
// {x: new Date(d+ONE_DAY*3).toLocaleDateString(), y: 1},
// {x: new Date(d+ONE_DAY*4).toLocaleDateString(), y: 5},
// {x: new Date(d+ONE_DAY*5).toLocaleDateString(), y: 4},
// {x: new Date(d+ONE_DAY*6).toLocaleDateString(), y: 0},
// {x: new Date(d+ONE_DAY*7).toLocaleDateString(), y: 2},
// ];
const ITEMS = [
{title: '收入', strokeWidth: 13},
{title: '支出', strokeWidth: 13}
];
class CoinChangeCharts extends Component {
constructor(props) {
super(props);
this.state = {
crosshairValues: []
};
// console.log(this.props);
}
render() {
const {chartsData} = this.props;
if(chartsData == undefined){
return (<div className="App"></div>);
}
var max = 0;
for(var i=0; i<chartsData.income.length; i++){
max = Math.max(max, chartsData.income[i].y, chartsData.outcome[i].y);
}
return (
<div className="App">
<DiscreteColorLegend height={80} width={1300} items={ITEMS} />
<XYPlot xType="ordinal" height={400} width= {700} yDomain={[-0.5, max]}>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<YAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<VerticalBarSeries data={chartsData.income} />
<VerticalBarSeries data={chartsData.outcome} />
</XYPlot>
</div>
);
}
}
export default CoinChangeCharts;

View File

@ -0,0 +1,79 @@
import React, { Component } from 'react';
import {XYPlot, VerticalBarSeries, VerticalGridLines, HorizontalGridLines, XAxis, YAxis, Crosshair, DiscreteColorLegend} from 'react-vis';
// import DiscreteColorLegend from 'legends/discrete-color-legend';
import "./style.scss";
const ONE_DAY = 86400000;
const d = new Date().getTime()-ONE_DAY*7;
const data = [
{x: new Date(d+ONE_DAY).toLocaleDateString(), y: 6},
{x: new Date(d+ONE_DAY*2).toLocaleDateString(), y: 3},
{x: new Date(d+ONE_DAY*3).toLocaleDateString(), y: 2},
{x: new Date(d+ONE_DAY*4).toLocaleDateString(), y: 7},
{x: new Date(d+ONE_DAY*5).toLocaleDateString(), y: 0},
{x: new Date(d+ONE_DAY*6).toLocaleDateString(), y: 5},
{x: new Date(d+ONE_DAY*7).toLocaleDateString(), y: 0},
];
const data2 = [
{x: new Date(d+ONE_DAY).toLocaleDateString(), y: 3},
{x: new Date(d+ONE_DAY*2).toLocaleDateString(), y: 4},
{x: new Date(d+ONE_DAY*3).toLocaleDateString(), y: 2},
{x: new Date(d+ONE_DAY*4).toLocaleDateString(), y: 6},
{x: new Date(d+ONE_DAY*5).toLocaleDateString(), y: 5},
{x: new Date(d+ONE_DAY*6).toLocaleDateString(), y: 1},
{x: new Date(d+ONE_DAY*7).toLocaleDateString(), y: 3},
];
const ITEMS = [
{title: '收入', strokeWidth: 13},
{title: '支出', strokeWidth: 13}
];
class SponsorBarCharts extends Component {
constructor(props) {
super(props);
this.state = {
crosshairValues: []
};
console.log(this.props)
}
componentWillReceiveProps = () => {
this.setState({
crosshairValues: []
})
}
render() {
const chartsData = this.props.is_sponsor?this.props.data.outcome:this.props.data.income;
var max = 0;
for(var i=0; i<chartsData.length; i++){
max = Math.max(max, chartsData[i].y);
}
return (
<div className="App">
{/* <DiscreteColorLegend height={20} width={1300} items={ITEMS} /> */}
<XYPlot animation={true} xType="ordinal" height={400} width= {700} yDomain={[-0.5, max]}>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<YAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
} }/>
<VerticalBarSeries data={chartsData} />
</XYPlot>
</div>
);
}
}
export default SponsorBarCharts;

View File

@ -0,0 +1,70 @@
import React, { Component } from 'react';
import {FlexibleXYPlot, RadialChart, VerticalGridLines, HorizontalGridLines, XAxis, YAxis, Crosshair, DiscreteColorLegend} from 'react-vis';
// import DiscreteColorLegend from 'legends/discrete-color-legend';
import "./style.scss";
const data = [
{label: "张三", angle: 1},
{label: "李四", angle: 2},
{label: "王五", angle: 5},
{label: "赵六", angle: 3},
];
const data2 = [
{label: "张三", angle: 2},
{label: "林磊", angle: 1},
{label: "赵辉", angle: 4},
];
const ITEMS = [
{title: '收入', color: 'powderblue', strokeWidth: 13},
{title: '支出', color: 'powderblue', strokeWidth: 13}
];
class SponsorPieCharts extends Component {
constructor(props) {
super(props);
this.state = {
crosshairValues: []
};
}
componentWillReceiveProps = () => {
this.setState({
crosshairValues: []
})
}
render() {
const DATA = this.props.is_sponsor?data2:data;
// const DATA = [{angle: 1}, {angle: 5}, {angle: 2}]
return (
<div>
{/* <DiscreteColorLegend height={20} width={1300} items={ITEMS} /> */}
{/* <FlexibleXYPlot height={400} width= {700}> */}
{/* <VerticalGridLines />
<HorizontalGridLines />
<XAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<YAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
} }/> */}
<RadialChart
innerRadius={70}
radius={140}
showLabels={true}
data={DATA} height={400} width= {400}/>
{/* </FlexibleXYPlot> */}
</div>
);
}
}
export default SponsorPieCharts;

View File

@ -0,0 +1,5 @@
@import "react-vis/dist/styles/plot.scss";
@import "react-vis/dist/styles/examples.scss";
@import "react-vis/dist/styles/legends.scss";
@import "react-vis/dist/styles/radial-chart.scss";
@import "react-vis/dist/styles/treemap.scss";

View File

@ -0,0 +1,133 @@
import React, { Component } from 'react';
import {XYPlot, VerticalBarSeries, LineSeries, VerticalGridLines, HorizontalGridLines, XAxis, YAxis, Crosshair, DiscreteColorLegend} from 'react-vis';
// import DiscreteColorLegend from 'legends/discrete-color-legend';
import "./charts/style.scss";
import '../../Main/list.scss';
import "../../UsersList/list.css";
import "../../sponsor/sponsor.css";
import "../new_user.css"
import axios from "axios";
import { isSupported } from 'clipboard';
const ITEMS = [
{title: '资助者数量', strokeWidth: 13},
{title: '受资助人数', strokeWidth: 13},
];
class SponsorDataCharts extends Component {
constructor(props) {
super(props);
this.state = {
crosshairValues: [],
sponsor: [],
sponsored: [],
nums: [],
};
}
componentDidMount = () => {
this.get_chart_data();
}
get_chart_data = () => {
this.setState({
isSpin: true
})
let url = `/sponsorships/community_data.json`;
axios.get(url)
.then((result) => {
this.setState({
sponsor: result.data.sponsor,
sponsored: result.data.sponsored,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
url = `/wallets/community_data.json`;
axios.get(url)
.then((result) => {
this.setState({
nums: result.data,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
};
componentWillReceiveProps = () => {
this.setState({
crosshairValues: []
})
}
render() {
// const DATA = this.props.is_sponsor?data2:data;
const {sponsor, sponsored, nums} = this.state;
var max1 = 0;
for(var i=0; i<sponsor.length; i++){
max1 = Math.max(max1, sponsor[i].y, sponsored[i].y);
}
var max2 = 0;
for(var i=0; i<nums.length; i++){
max2 = Math.max(max2, nums[i].y);
}
return (
<div className="App">
<p className="color-grey-3 font-18 task-hide ">平台资助者/受资助人数</p>
<DiscreteColorLegend height={80} width={1300} items={ITEMS} />
<XYPlot
animation={true} xType="ordinal" height={400} width= {700}
yDomain={[-0.5, max1]}
>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<YAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<LineSeries data={sponsor} />
<LineSeries data={sponsored} />
</XYPlot>
<p className="color-grey-3 font-18 task-hide ">平台资助交易数量</p>
<XYPlot
animation={true} xType="ordinal" height={400} width= {700}
yDomain={[-0.5, max2]}
>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<YAxis style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}/>
<VerticalBarSeries data={nums} />
</XYPlot>
</div>
);
}
}
export default SponsorDataCharts;

View File

@ -0,0 +1,781 @@
.lineH2{line-height:2}
.t_project_banner {
/* height: 260px;
background: url(../Images/banner_list.jpg) no-repeat center; */
background-color: #050d34;
}
.ProjectListIndex{
width: 1200px;
margin:20px auto;
display: flex;
align-items: flex-start;
flex-wrap:wrap;
}
.list-left{
width: 26%;
padding-right: 20px;
box-sizing: border-box;
margin-bottom: 20px;
}
.list-left > div{
border:1px solid #eee;
}
.list-left > div.bgcF{
border:none;
}
.list-right{
width:74%;
background: #fff;
padding:10px;
border:1px solid #eee;
}
/* 首页列表的新建和排序的下拉列表 */
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left{
border-right: none!important;
}
.ant-menu-vertical > .ant-menu-item{
margin:0px!important;
height: 35px;
line-height: 35px;
border-bottom: 1px solid #eee;
font-size: 14px!important;
}
.ant-menu-vertical > .ant-menu-item:last-child{
border-bottom: none;
}
.list-r-operation{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
padding:25px 30px;
border-bottom: 1px solid #E0E0E0;
}
.list-r-Search{
width: 400px;
}
.padding0-25{
padding:0px 25px;
}
.list-r-Search .ant-btn-lg{
height: 38px;
}
.list-r-Search .ant-input-group-addon{border: none !important;}
.list-r-Search .ant-input-search-button{height: 40px !important;}
.createBtn{
border-radius: 4px;
margin-left: 20px;
display: inline-block;
padding:3px 15px;
background-color: #4CACFF;
color: #fff!important;
}
/* 列表 */
.project-list{
padding:0px 30px;
}
.border-top-grey{
border-top: 1px solid rgba(238,238,238,1);
}
.p-r-Item:last-child{
border-bottom: none !important;
}
.p-r-Item{
display: flex;
border-bottom:1px solid rgba(238,238,238,1);
padding:22px 0px;
justify-content: flex-start;
}
.boxShandow{
box-shadow:0px 2px 20px 10px rgba(0,0,0,0.03);
}
.p-r-photo{
width: 60px;
height: 60px;
border-radius: 50%;
margin-right: 22px;
margin-top: 8px;
}
.p-r-Infos{
flex: 1;
width: 0;
}
.p-r-name{
display: flex;
justify-content: space-between;
align-items: center;
}
.p-r-name > p{
flex: 1;
width: 0;
}
.p-r-btn{
display: flex;
align-items: center;
}
.p-r-btn > span{
height: 35px;
line-height: 35px;
border:1px solid #f4f4f4;
border-radius: 5px;
display: block;
margin-left: 20px;
background-color: #fff;
display: flex;
}
.p-r-btn > span > a{
display: flex;
align-items: center;
padding:0px 12px;
background:#ececec;
}
.p-r-btn > span > a:active{
background: #f4f4f4;
}
.p-r-btn > span > span{
padding:0px 8px;
}
.p-r-tags{
display: flex;
opacity: 1;
}
.p-r-tags.large > span{
height: 30px;
line-height: 30px;
font-size: 14px;
}
.p-r-tags > span{
margin-left: 15px;
padding:0px 10px;
border-radius:15px;
background: #EBF4FE;
color: #333;
height: 24px;
line-height: 24px;
display: block;
font-size: 12px;
display: flex;
}
.p-r-tags > span.pariseTag{
background: #FFF3DC;
}
.p-r-tags.large > span >label{
padding:0px 12px;
}
.p-r-tags > span >label{
padding:0px 8px;
}
.p-r-tags.large > span >span{
padding:0px 6px;
}
.pariseImg{
width: 14px;
height: 12px;
margin-top: 6px;
margin-right: 3px;
}
.p-r-tags > span >span{
display: block;
background: #fff;
border-left: #efefef;
padding:0px 4px;
border-radius: 0px 4px 4px 0px;
color: #999;
}
.p-r-content{
margin-top:10px;
color: #666;
display: flex;
}
.p-r-detail > span{
margin-right: 22px;
color: #888;
}
.p-r-detail > span > label{
color: #999;
}
.p-r-about{
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
margin-top: 8px;
color: #666;
}
.spincontent{
height:400px;
}
.spinstyle .ant-spin-text{
margin-top:30px;
color: #888;
}
/* -----------详情------------ */
.detailHeader-wrapper{
background-color:#FBFCFF;
border-bottom:1px solid #e2e2e2;
}
.headerMenu-wrapper{
display: flex;
flex-direction: row;
cursor: pointer;
li{
font-size: 14px;
position: relative;
text-align: center;
height: 40px;
line-height: 28px;
padding:0px 20px;
& > a{
color: #666;
&> img{
margin-right: 8px;
}
&> span.num{
line-height: 24px;
margin-left: 5px;
margin-top: 2px;
font-size: 12px;
float: right;
color: #666!important;
background-color: rgba(153, 153, 153, 0.13);;
border-radius: 50%;
width: 24px;
height: 24px;
}
}
&.active a,&.active a i{
color: #2A61FF!important;
}
&.active::after,&:hover::after{
position: absolute;
bottom:0px;
height:2px;
background-color: #2A61FF;
content:'';
left: 0px;
width:100%;
}
&:hover::after{
background-color: rgba(153, 153, 153, 0.2);;
}
}
}
.detail_tag_btn{
height:34px;
line-height: 32px;
border-radius:5px;
border:1px solid #D0D0D0;
display: flex;
align-items: center;
margin-left: 10px;
padding:0px;
background-color:#FAFBFC;
box-shadow: none;
&:hover{
background-color: #F3F4F6;
}
.detail_tag_btn_name{
padding:0px 18px;
min-width: 82px;
text-align: center;
&:hover>span{
color: #333!important;
}
img{
margin-right: 10px;
}
}
.detail_tag_btn_count{
width: 42px;
text-align: center;
background: #fff;
border-radius: 0px 4px 4px 0px;
height:100%;
border-left: 1px solid #D0D0D0;
}
}
.ant-tooltip {
max-width: fit-content!important;
}
.files-md{
padding:20px;
}
/* 详情-代码 */
.branch-wrapper{
border:1px solid #eee;
border-radius: 4px;
display: flex;
align-items: center;
height: 60px;
padding:0px 30px;
width: 1200px;
margin:0px auto;
background-color: #fff;
margin-top: 20px;
justify-content: space-between;
}
.branch-wrapper > a >i{
color: #5091FF;
margin-right: 5px;
cursor: default;
}
.branch-wrapper a{
display: flex;
align-items: center;
justify-content: center;
text-align: center;
height: 30px;
line-height: 30px;
cursor: pointer;
font-size: 16px;
color: #333333;
}
.branch-wrapper a > span{
position: relative;
min-height: 20px;
display: block;
}
.branch-wrapper a.active > span::after{
position: absolute;
content: '';
bottom: -5px;
width: 30px;
height: 3px;
left: 0px;
background-color:#5091FF;
}
.gitAddressClone{
margin:0px 20px 14px 20px!important;
display: flex;
height: 40px;
align-items: center;
border-radius: 4px;
border:1px solid #eee;
background: #fff;
margin-left: 20px;
position: relative;
}
.gitAddressClone > span{
display: flex;
line-height: 40px;
height: 40px;
padding:0px 12px;
cursor: pointer;
align-items: center;
}
.addressTips{
position: absolute;
font-size: 12px;
color: #FF6E21;
top:-34px;
left: 30px;
background-color: #fff;
border:1px solid #FE881D;
padding:0px 5px;
height: 28px;
line-height: 28px;
}
.addressTips>span{position: relative;display: block;}
.addressTips>span::before{
box-sizing: content-box;
width: 0px;
height: 0px;
position: absolute;
top: 25px;
left:50%;
margin-left: -4px;
padding:0;
border-top:8px solid #FFFFFF;
border-bottom:8px solid transparent;
border-left:8px solid transparent;
border-right:8px solid transparent;
display: block;
content:'';
z-index: 12;
}
.addressTips>span::after{
box-sizing: content-box;
width: 0px;
height: 0px;
position: absolute;
top: 26px;
left:50%;
margin-left: -4px;
padding:0;
border-top:8px solid #FE881D;
border-bottom:8px solid transparent;
border-left:8px solid transparent;
border-right:8px solid transparent;
display: block;
content:'';
z-index: 11;
}
.gitAddressClone > span.addressType{
color: #4CACFF;
}
.gitAddressClone > span:last-child{
border-right: none;
}
.gitAddressClone > input{
border:none;
outline: none;
padding:0px 8px;
height: 40px;
line-height: 40px;
border-radius: 0px;
border: 1px solid #eee;
flex:1;
}
.wrap-commit-table .ant-table-small > .ant-table-content > .ant-table-body{
margin:0px;
}
.wrap-commit-table .ant-table-title{
background-color: rgba(241,248,255,1);
padding: 13px 16px!important;
}
.commitKey{
cursor: pointer;
border:1px solid #FD7700;
background-color:#FFF3DC;
color: #FD7700!important;
padding:0px 12px;
height: 20px;
line-height: 20px;
margin-left:15px;
border-radius: 18px;
max-width: 100%;
}
/* 分支 */
.branchTitle{
padding:8px 10px;
color: #333;
font-size: 16px;
border-bottom: 1px solid #d9d9d9;
}
.branchUl li{
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: space-between;
padding:20px 0px;
border-bottom: 1px solid #eee;
}
.branchUl li:last-child{
border-bottom: none;
}
.operationBtn{
border:1px solid #f4f4f4;
border-radius: 3px;
padding:0px 6px;
background-color:#fff;
color:#666!important;
display: inline-block;
}
.messages{
max-width: 700px;
}
.leftPoint{
margin-left: 20px;
position: relative;
}
.leftPoint::before{
position: absolute;
left: -10px;
top:8px;
border-radius: 50%;
width: 4px;
height: 4px;
background-color: #dadada;
content: '';
}
/* 文件目录、文件内容 */
.subFileName{
position: relative;
margin-left: 15px;
height: 22px;
}
.subFileName::before{
position: absolute;
content: '/';
left: -10px;
top: 0px;
color: #999;
height: 22px;
line-height: 22px;
}
.addFile{
display: flex;
}
.addFile a{
display: block;
background-color: rgba(76, 172, 255,0.8);
color: #fff;
cursor: pointer;
height: 32px;
line-height: 32px;
padding: 0px 10px;
}
.addFile a:first-child{
border-radius: 4px;
}
.addFile a:last-child{
/* border-radius: 0px 4px 4px 0px; */
border-left: 1px solid rgba(247, 247, 247, 0.3);
}
.addFile a:active{
background-color: rgba(76, 172, 255,1);
}
@media screen and (max-width: 750px){
.list-r-Search{
flex: 1;
}
.list-left,.list-right{
width: 100%;
padding: 0px;
}
}
@media screen and (max-width: 400px){
.list-r-Search{
width: 100%;
}
.headerMenu-wrapper{
flex-direction: column;
width: 100%;
}
.headerMenu-wrapper li{
width: 100%;
}
.gitAddressClone{
width:100%;
margin-left: 0px;
}
.gitAddressClone > span{
padding:0px;
}
.messages{
max-width: 100%;
}
}
.commonBox{
border:1px solid #ddd;
margin-top: 30px;
border-radius: 4px;
}
.commonBox .commonBox-title{
padding:0px 20px;
box-sizing: border-box;
font-size: 16px;
background: #FAFBFC;/* F1F8FF */
font-weight: bold;
height: 45px;
line-height: 45px;
border-bottom: 1px solid #d9d9d9;
border-radius: 4px 4px 0px 0px;
}
.readBox{
border:none;
&.commonBox .commonBox-info{
border:1px solid #D0D0D0;
border-top: none;
border-radius: 0px 0px 4px 4px;
padding:20px 38px;
}
}
.commonBox .commonBox-title.boxTitle{
display: flex;
justify-content: space-between;
height: 65px;
line-height: 65px;
background: #FAFCFF;
border-radius: 4px 4px 0px 0px;
border: 1px solid rgba(42, 97, 255, 0.23);
}
.synchronism{
display: block;
height: 34px;
line-height: 34px;
padding:0px 15px;
color: #fff!important;
background-color: #28BD6C;
border-radius: 4px;
}
.files_info{
cursor: pointer;
}
.commonBox {
.commonBox-info{
padding:20px 15px;
}
}
.commonBox-title-read{
vertical-align: middle;
color: #666;
font-size: 14px;
}
@media screen and (max-width: 370px){
.p-r-tags,.p-r-btn{
opacity: 0;
display: none;
}
.p-r-about{
flex-wrap: wrap;
}
.commitKey{
margin-right: 0px;
}
.list-r-Search{
width: 100%;
}
}
.null_data_box{
width: 100%;
border: 1px solid #d4d4d5;
border-radius:3px ;
}
.title{
font-weight: bold;
background: #f4f4f4;
padding: 10px 15px;
box-sizing: border-box;
border-bottom: 1px solid #d4d4d5;
}
.item_title{
font-size:18px;
font-weight: bold;
margin-bottom: 15px;
}
.item{
padding: 15px;
border-bottom: 1px solid #dededf;
}
.item:last-child{
border-bottom:none;
}
.item_title small{
font-weight: 400;
margin-left: 10px;
}
.item_title small a{
color: #4183c6;
}
.Markdown{
background: #f7f7f7;
padding: 10px 20px;
}
.item .gitAddressClone input:focus{
border: 1px solid #2185d0;
}
.content-file{margin-top: 8px;}
.content-file .CodeMirror{
background-color: #f7f7f7;
border: 1px solid #e4e4e4;
border-radius: 4px;
height: auto;
}
.content-file.edit .CodeMirror{
background-color: #fff;
}
.content-file .CodeMirror .CodeMirror-scroll{
min-height: 450px;
}
.text-center{text-align: center;}
.fork-css{
position: absolute;
left: 0;
top: 50px;
width: 100%;
}
.color-grey-ccc{
color: #ccc !important;
}
a.color-grey-ccc:hover{
color: #4cacff !important;
}
.pull-right{float: right;}
.commitList{
padding:0px 30px;
min-height: 400px;
}
.commitList > div{
border-bottom: 1px solid #EEEEEE;
padding:16px 0px;
}
.commitList > div:last-child{
border-bottom: none;
}
/* 标签列表 */
.div_table{
border:1px solid #eee;
border-radius: 2px;
}
.ul_thead{
padding:0px 30px;
box-sizing: border-box;
background: #FAFAFA;
border-bottom: 1px solid #eee;
height: 50px;
line-height: 50px;
}
.ul_tbody{
padding:0px 30px;
}
.ul_thead li, .ul_tbody li{
display: flex;
align-items: center;
text-align: left
}
.ul_tbody li{
padding:18px 0px;
border-bottom: 1px solid #eee;
}
.ul_tbody li:last-child{
border-bottom: none;
}
.ul_thead li > span , .ul_tbody li > span{
width: 20%;
padding-right: 20px;
}
.ul_thead li > span:nth-child(2), .ul_tbody li > span:nth-child(2){
flex:1;
}
.ul_tbody_third{
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: left;
}
.ul_tbody_forth{
text-align: center;
display: flex;
justify-content: center;
}
.depotNum{
color: #666!important;
span:last-child{
color: #333;
}
&:hover span:last-child{
color: #2A61FF;
}
}

View File

@ -0,0 +1,103 @@
import React, { Component } from "react";
import { getImageUrl } from "educoder";
import FocusButton from "../../UsersList/focus_button";
import { Button, message, Popconfirm } from "antd";
import '../../Main/list.scss';
import "../../UsersList/list.css";
import "../../sponsor/sponsor.css";
import "../new_user.css"
import axios from "axios";
import { Link } from "react-router-dom";
class SponsorList extends Component {
stop_sponsorship = (item, key, e)=>{
// console.log("before: ", this.state.users);
let url = `/sponsorships/${item.id}.json`;
axios.delete(url)
.then((result) => {
console.log(result);
// this.props.showNotification("终止成功")
if(result && result.data.status == 1){
this.props.showNotification(result.data.message);
this.props.rerender();
}
})
.catch((error) => {
console.log(error);
this.props.showNotification("失败");
})
}
to_sponsor_page = (item, key, e) => {
this.props.history.push(`/sponsor/${item.login}`);
}
renderList = (users, userClass, current_user) => {
if (users && users.length > 0) {
return users.map((item, key) => {
// console.log(item);
return (
<div className="p-r-Item" key={key}>
{/* <div className="mr10">
<a
href={`/users/${item.login}`}
className="show-user-link"
>
<img className="p-r-photo"
src={getImageUrl(`images/${item.image_url}`)}
alt=""
/>
</a>
</div> */}
<Link to={`/users/${item.login}`} className="show-user-link">
<img className="p-r-photo" src={getImageUrl(`images/${item.image_url}`)} alt="" />
</Link>
<div className="p-r-Infos">
<a className="p-r-name hide-1 color-grey-3 font-18 task-hide " href={`/users/${item.login}`}>{item && item.username}</a>
<div className="mr10">
<span className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>金额{item.amount}硬币</span>
<span className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>累计金额{item.accumulate}硬币</span>
</div>
<div className="p-r-about">
<span className="p-r-detail">
<span><label>赞助时间</label>{item.start_time}&nbsp;-&nbsp;{item.stop_time? item.stop_time:""}</span>
<span><label>{item.visible? "公开":"私有"}</label></span>
</span>
</div>
</div>
<div className="sponsor-item-btn">
{item.stop_time? "":(
<Popconfirm
title="确认终止?"
onConfirm={e => this.stop_sponsorship(item, key, e)}
// onCancel={cancel}
okText="是"
cancelText="否"
>
<Button >终止赞助关系</Button>
</Popconfirm>
)}
{!item.stop_time && item.sponsor_id==current_user.user_id? (
<Button className="mt5" onClick={e => this.to_sponsor_page(item, key, e)}>修改赞助</Button>
):""}
</div>
</div>
);
});
} else{
return null;
}
}
render() {
const { users, userClass, current_user } = this.props;
return (
<div className="project-list minH-670">{this.renderList(users, userClass, current_user)}</div>
);
}
}
export default SponsorList;

View File

@ -0,0 +1,272 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Menu, Input, Spin, Pagination, Popover, Button, Divider } from "antd";
import axios from "axios";
import CoinChangeItem from "./CoinChangeItem";
import Nodata from "../../Nodata";
import img_array from "../../Images/array.png";
import CoinChangeCharts from "./charts/coinChangeCharts";
const Search = Input.Search;
const tempData = [
{amount: -3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: 3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: -3, description: "des", reasons: "no reason", to_user: "串", date: "2016年1月5日"},
{amount: 3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: -3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: 3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: -3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: 3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"},
{amount: -3, description: "des", reasons: "no reason", to_user: "串串", date: "2016年1月5日"}
];
class Wallet extends Component {
constructor(props) {
super(props);
this.state = {
page: 1,
limit: 10,
sort_by: "desc",
isSpin: false,
coinChangeList: undefined,
displayList: undefined,
total: undefined,
category: "all",
balance: 50,
saerch: undefined,
chartsData: {income:[], outcome:[]},
};
}
componentDidMount = () => {
this.get_coin_changes();
};
componentDidUpdate = () => {
// this.get_coin_changes()
};
componentWillReceiveProps = () => {
if (this.props.current_user)
this.get_coin_changes();
}
get_chart_data = () => {
this.setState({
isSpin: true
})
let url = `/wallets/balance_chart.json`;
const {current_user} = this.props;
let user_id = current_user && current_user.user_id;
if (current_user){
axios.get(url, {
params: {
id: user_id,
}})
.then((result) => {
this.setState({
chartsData: result.data,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
}
};
get_coin_changes = () => {
this.setState({
isSpin: true
})
let url = `/wallets/coin_changes.json`;
const {category, sort_by, page, limit} = this.state;
const {current_user} = this.props;
let user_id = current_user && current_user.user_id;
if (current_user){
axios.get(url, {
params: {
id: user_id,
category: category,
sort_direction: sort_by,
page: page,
limit: limit,
}})
.then((result) => {
// console.log(result);
this.setState({
coinChangeList: result.data.coin_changes,
displayList: result.data.coin_changes,
total: result.data.count,
balance: result.data.balance,
isSpin: false,
})
})
.catch((error) => {
console.log(error);
this.setState({
isSpin: false,
});
});
}
};
changeCategory = (cate) => {
if(cate.target.value == "charts"){
// console.log("charts");
this.setState({
category: cate.target.value,
page: 1,
}, ()=> {this.get_chart_data();});
return ;
}
else{
this.setState({
category: cate.target.value,
page: 1,
}, ()=> {this.get_coin_changes();});
}
};
//切换页数
changePage = (page) => {
this.setState({
page: page
}, ()=>{this.get_coin_changes();})
};
// 排序
ChangeSoryBy = (e) => {
this.setState({
sort_by: e.key,
page: 1,
}, ()=>{this.get_coin_changes();})
// this.get_coin_changes();
console.log(e.key);
};
changeSearchValue = (e) => {
this.setState({
search: e.target.value,
});
};
menu =()=> (
<Menu onClick={this.ChangeSoryBy}>
<Menu.Item key="desc">时间从近到远排序</Menu.Item>
<Menu.Item key="asc">时间从远到近排序</Menu.Item>
</Menu>
);
category_button=(category)=>{
const { current_user, user } = this.props;
const button_lists =
user && current_user && user.login === current_user.login
? [
{ type: "all", name: "所有" },
{ type: "income", name: "收入" },
{ type: "outcome", name: "支出" },
{ type: "charts", name: "查看统计" },
]
:
[];
let list = button_lists.map((item, key) => {
return (
<span key={key} className="pr15">
<Button
type={
(category && category === item.type) || (!category && !item.type)
? "primary"
: "default"
}
ghost={
(category && category === item.type) || (!category && !item.type)
}
value={item.type}
onClick={this.changeCategory}
>
{item.name}
</Button>
</span>
);
})
return list;
}
render() {
const { current_user, user } = this.props;
const { category , sort_by, chartsData } = this.state;
const { displayList, coinChangeList, isSpin, total, search, limit, page, balance} = this.state;
const coinChangeItem = displayList && displayList.length > 0 ?
<CoinChangeItem
{...this.props}
{...this.state}
coinChanges={displayList}
></CoinChangeItem>:
<Nodata _html={`暂时没有项目`} />;
const displayComponent =
category === "charts"? <CoinChangeCharts chartsData={chartsData}></CoinChangeCharts>
:
coinChangeItem;
return (
<Spin spinning={isSpin}>
<div className="list-r-operation">
{/* <Search
placeholder="输入关键字进行搜索"
enterButton="搜索"
size="large"
onSearch={this.get_coin_changes}
className="list-r-Search"
value={search}
onChange={this.changeSearchValue}
/> */}
<div>
<Popover content={this.menu()} trigger={["click"]} placement="bottom">
<a className="ant-dropdown-link">
<span className="color-blue font-16">
排序 <img src={img_array} alt="" width="10px" />
</span>
</a>
</Popover>
</div>
</div>
<div className="infosType">余额{balance}</div>
<div className="infosType">
<div>{this.category_button(category)}</div>
</div>
{user && current_user && user.login === current_user.login?
displayComponent
:
<Nodata _html={`暂时没有项目`} />
}
{
total && total > limit && category != "charts"?
<div className="edu-txt-center pt30 mb30 border-top-grey">
<Pagination
simple
defaultCurrent={page}
total={total}
pageSize={limit}
onChange={this.changePage}
></Pagination>
</div>
:
""
}
</Spin>
);
}
}
export default Wallet;

View File

@ -476,10 +476,12 @@ class LoginRegisterComponent extends Component {
if (this.state.codes === undefined || this.state.codes == ""||this.state.codes.length===0) {
// this.openNotification(`请输入验证码`,2);
this.setState({
Phonenumberisnotcosyzm:"验证码不能为空",
})
return
/*****
// this.setState({
// Phonenumberisnotcosyzm:"验证码不能为空",
// })
// return
******/
} else if (this.state.passwords === undefined || this.state.passwords == "" ||this.state.passwords.length===0) {
this.setState({
Phonenumberisnotcosymmm:"密码不能为空",
@ -504,16 +506,18 @@ class LoginRegisterComponent extends Component {
if(this.props.weixinlogin){
url= '/weapps/register.json';
}else{
url = "/accounts/register.json";
url = "/accounts/remote_register.json";
}
axios.post(url, {
login: this.state.logins,
// login: this.state.logins,
email: this.state.logins,
password: this.state.passwords,
code: this.state.codes,
username: this.state.codes,
platform: "forge"
}).then((result) => {
if(result){
if(result.data.status===-2){
if(result.data.status!=0){
if(result.data.message==="验证码不正确"){
this.setState({
Phonenumberisnotcosyzm:"验证码不正确",
@ -1168,12 +1172,12 @@ class LoginRegisterComponent extends Component {
onfocus="this.removeAttribute('readonly')" style={{
width:'210px',
height:'38px',
}} placeholder="请输入验证码"
}} placeholder="请输入用户名"
onChange={this.codesonChange}
value={codes}
>
</Input>
{
{/* {
getverificationcodes === undefined ?
<Button className=" ml5 font-14" disabled style={{"width": "120px","text-align":"center", "height": "45px",}}
size={"large"}>重新发送{seconds}s</Button>
@ -1183,7 +1187,7 @@ class LoginRegisterComponent extends Component {
:
<Button className=" ml5 font-14 " type="primary" style={{"width": "120px","text-align":"center", "height": "45px",}}
onClick={() => this.getverificationcode()} size={"large"}>重新发送</Button>
}
} */}
</div>
<div>