You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/public/react/src/modules/developer/DeveloperHome.js

510 lines
13 KiB

/*
* @Description: undefined
* @Author: tangjiang
* @Date: 2019-11-15 11:02:49
* @Last Modified by: tangjiang
* @Last Modified time: 2019-11-18 16:52:38
*/
import './index.scss';
import React from 'react';
import { Table, Button, Dropdown, Icon, Menu, Card, Input, Select, Tag } from 'antd';
import { connect } from 'react-redux';
import actions from '../../redux/actions';
import MultipTags from './components/multiptags';
import { Link } from 'react-router-dom';
import CONST from '../../constants';
import { withRouter } from 'react-router';
const {tagBackground, diffText} = CONST;
const { Search } = Input;
const { Option } = Select;
// import reqwest from 'reqwest';
/**
* 下拉菜单
*/
const maps = {
'categoryMenu': [
{
'key': '0',
'name': '全部',
'value': '0'
},
{
'key': '1',
'name': '程序设计基础',
'value': '1'
},
{
'key': '2',
'name': '数据结构与计算',
'value': '2'
}
],
'difficultMenu': [
{
'key': '1',
'name': '简单',
'value': '1'
},
{
'key': '2',
'name': '中等',
'value': '2'
},
{
'key': '3',
'name': '困难',
'value': '3'
}
],
'statusMenu': [
{
'key': '-1',
'name': '未做',
'value': '-1'
},
{
'key': '0',
'name': '未通过',
'value': '0'
},
{
'key': '1',
'name': '已通过',
'value': '1'
}
],
'come_fromMenu': [
{
'key': 'all',
'name': '全部',
'value': 'all'
},
{
'key': 'mine',
'name': '我创建的',
'value': 'mine'
}
]
};
const testMaps = {
category: {
1: '程序设计基础',
2: '数据结构与算法'
}
}
class DeveloperHome extends React.PureComponent {
/**
* 表格列
*/
options = {
title: '操作',
key: 'action',
fixed: 'right',
width: 100,
render: (text, record) => (
<span>
<Button type="primary" onClick={() => this.handleClickEditor(record.identifier)}>编辑
{/* <Link to={`/problems/${record.identifier}/edit`}></Link> */}
</Button>
</span>
),
}
columns = [
{
title: '标题',
dataIndex: 'name',
render: (name, record) => <Button type="link" onClick={() => this.handleNameClick(record)} className={'oj_item_name'}>{name}</Button>
},
{
title: '分类',
dataIndex: 'category',
width: '20%',
align: 'center',
render: (category) => <span>{category ? testMaps['category'][+category] : '-'}</span>
},
{
title: '难度',
dataIndex: 'difficult',
align: 'center',
width: '15%',
render: (difficult) => {
if (difficult) {
return <Tag color={tagBackground[+difficult]}>{diffText[+difficult]}</Tag>
} else {
return '-';
}
}
},
{
title: '热度',
dataIndex: 'hack_user_lastest_codes_count',
sorter: true,
align: 'center',
width: '10%'
},
{
title: '通过率',
dataIndex: 'passed_rate',
sorter: true,
align:'right',
width: '10%',
render: val => <span>{`${val}%`}</span>
},
];
state = {
data: [],
loading: false,
searchParams: {
search: '', // 查询关键字
'come_from': '', // 来源
difficult: '', // 难易度
status: '', // 未做
category: '', // 分类
'sort_by': '', // 排序
'sort_direction': '', // 排序方向
page: 1, // 当前页数
limit: 10 // 每页显示条件
},
columns: this.columns,
searchInfo: []
};
componentDidMount() {
// 是否是我的,如果是我的 显示编辑按钮
const { isMySource } = this.props;
console.log(this.props);
if (isMySource) {
this.handleFilterSearch({come_from: 'mine'});
let _columns = this.columns.concat([this.options]);
this.setState({
columns: _columns
});
} else {
this.fetchData();
}
const {hacks_count} = this.props.ojListReducer;
this.setState({
pagination: {
total: hacks_count
}
});
}
// 是否登录
isLogin = (url) => {
if(this.props.checkIfLogin()===false){
this.props.showLoginDialog()
return false;
}
return true;
}
// 新建
handleClickNew = () => {
if (this.isLogin()) {
// this.props.history.push('/problems/new');
window.location.href = '/problems/new'
}
// window.location.href = '/problems/new';
}
// 编辑
handleClickEditor = (identifier) => {
if (this.isLogin()) {
this.props.history.push(`/problems/${identifier}/edit`)
}
}
// table条件变化时
handleTableChange = (pagination, filters, sorter) => {
const {field, order} = sorter;
const {current, pageSize} = pagination;
this.handleFilterSearch({
sort_by: field,
sort_direction: order === 'descend' ? 'desc' : 'asc',
page: current,
limit: pageSize
});
this.props.changePaginationInfo(pagination);
};
// 获取接口数据
fetchData = () => {
this.props.fetchOJList(this.state.searchParams);
};
/**
* 根据类型获取下拉菜单
* @param type 类型
* @param handleClick 处理函数
*/
getMenuItems = (type, handleClick) => {
return (
<Menu onClick={handleClick}>
{
maps[type].map((item) => {
return (
<Menu.Item key={item.key}>
{item.name}
</Menu.Item>
)
})
}
</Menu>
)
};
getOptionsItem = (type) => {
return maps[type].map(item => {
return <Option key={item.key} value={item.value}>{item.name}</Option>
});
}
// 点击条件时加载数据
handleFilterSearch = (obj) => {
const searchParams = Object.assign({}, this.state.searchParams, obj);
this.setState({
searchParams: searchParams
}, () => {
if (this.isLogin()) {
this.fetchData();
}
});
}
// 添加显示搜索条件
addShowFilterCtx = (obj) => {
const {searchInfo} = this.state
const index = searchInfo.findIndex(item => item.type === obj.type);
let tempArr = [...searchInfo];
if (index > -1) {
tempArr[index] = obj;
} else {
tempArr.push(obj);
}
this.setState({
searchInfo: tempArr
});
}
/**
* 搜索输入框
* @param value 输入框值
*/
handleInputSearch = (value) => {
value = value.trim();
// if (value.length === 0) return;
this.handleFilterSearch({search: value});
}
// handleSearchChange = (e) => {
// console.log(e.target.value);
// const value = e.target.value.trim();
// }
// 下拉类别菜单
handleCategoryMenuClick = (item) => {
this.addShowFilterCtx({
type: 'category',
key: item.key
});
this.handleFilterSearch({category: +item.key === 0 ? '' : +item.key});
}
// 难度下拉
handleHardMenuClick = (item) => {
this.addShowFilterCtx({
type: 'difficult',
key: item.key
});
this.handleFilterSearch({difficult: +item.key});
}
// 状态下拉
handleSatusMenuClick = (item) => {
this.addShowFilterCtx({
type: 'status',
key: item.key
});
this.handleFilterSearch({status: +item.key});
}
// 来源下拉
handleOriginMenuClick = (item) => {
this.addShowFilterCtx({
type: 'come_from',
key: item.key
});
this.handleFilterSearch({come_from: item.key === 'all' ? '' : item.key});
if (item.key !== 'all') {
let _columns = this.columns.concat([this.options]);
this.setState({
columns: _columns
});
} else {
this.setState({
columns: this.columns
})
}
}
handleTagClose = (info) => {
this.handleFilterSearch({[info.type]: ''});
// 移除 searcInfo 中的数据
const { type } = info;
let tempArr = [...this.state.searchInfo];
const index = tempArr.findIndex(item => item.type === type);
if (index > -1) tempArr.splice(index, 1);
this.setState({
searchInfo: tempArr
});
if (info.type === 'come_from' && info.key === 'mine') {
this.setState({
columns: this.columns
});
}
}
// 点击name
handleNameClick = (record) => {
// console.log('name has click', record);
// 先调用start接口获取返回的 identifier, 再跳转到开启编辑
if (this.isLogin()) {
// console.log(record);
this.props.startProgramQuestion(record.identifier, this.props);
}
}
// if(this.props.checkIfLogin()===false){
// this.props.showLoginDialog()
// return
// }
render () {
// const { testReducer, handleClick } = this.props;
const {
ojListReducer: {hacks_list, top_data, hacks_count},
pagination
} = this.props;
const {passed_count = 0, simple_count = 0, medium_count = 0, diff_count = 0} = top_data;
const { columns } = this.state;
// 渲染条件内容
const renderSearch = () => {
return this.state.searchInfo.map(info => {
let ctx = '';
const arrs = maps[`${info.type}Menu`];
arrs.forEach(item => {
if (item.key === info.key) ctx = item.name;
});
return (
<Tag
closable
className={'search_tag_style'}
key={info.type}
onClose={() => this.handleTagClose(info)}
>{ctx}</Tag>
)});
};
return (
<div className="developer-list">
<div className="ant-spin-container">
<div className={'banner-wrap'}></div>
<div className="educontent">
<div className={'card-top'}>
<div className="search-params">
<p className={'save-question'}>已解决 <span className={''}>{passed_count}</span> / {hacks_count} </p>
<div className={'question-level'}>
<MultipTags type="success" text="简单" numb={simple_count} style={{ marginRight: '20px' }}/>
<MultipTags type="warning" text="中等" numb={medium_count} style={{ marginRight: '20px' }}/>
<MultipTags type="error" text="困难" numb={diff_count}/>
</div>
<Button type="primary" onClick={this.handleClickNew}>新建
{/* <Link to="/problems/new">新建</Link> */}
</Button>
</div>
</div>
<div className={'card-table'}>
<div bordered={false} className={'filter_ctx_area'}>
<div>
<Dropdown className={'dropdonw-style'} placement="bottomLeft" overlay={this.getMenuItems('categoryMenu', this.handleCategoryMenuClick)}>
<span className={'dropdown-span'}>分类 <Icon type="down"/></span>
</Dropdown>
<Dropdown className={'dropdonw-style'} placement="bottomLeft" overlay={this.getMenuItems('difficultMenu', this.handleHardMenuClick)}>
<span className={'dropdown-span'}>难度 <Icon type="down"/></span>
</Dropdown>
<Dropdown className={'dropdonw-style'} placement="bottomLeft" overlay={this.getMenuItems('statusMenu', this.handleSatusMenuClick)}>
<span className={'dropdown-span'}>状态 <Icon type="down"/></span>
</Dropdown>
<Dropdown className={'dropdonw-style'} placement="bottomLeft" overlay={this.getMenuItems('come_fromMenu', this.handleOriginMenuClick)}>
<span className={'dropdown-span'}>来源 <Icon type="down"/></span>
</Dropdown>
</div>
<div className={'choice_ctx'}>
{renderSearch()}
</div>
<Search
placeholder="输入标题进行搜索"
onChange={this.handleSearchChange}
onSearch={value => this.handleInputSearch(value)}
style={{ width: 320, float: 'right' }}
/>
</div>
<Card bordered={false} style={{ marginTop: '2px'}}>
<Table
columns={columns}
rowKey={record => Math.random()}
dataSource={hacks_list}
pagination={pagination}
onChange={this.handleTableChange}
/>
</Card>
</div>
</div>
</div>
</div>
);
}
}
/**
* @param {*} state store
* @param {*} ownProps DeveloperHome 中的 props
*/
const mapStateToProps = (state, ownProps) => {
const {
testReducer,
ojListReducer,
commonReducer
} = state;
const { pagination } = ojListReducer;
return {
testReducer,
ojListReducer,
isMySource: commonReducer.isMySource,
pagination
}
};
const mapDispatchToProps = (dispatch) => ({
handleClick: () => dispatch(actions.toggleTodo()),
fetchOJList: (params) => dispatch(actions.getOJList(params)),
changePaginationInfo: (obj) => dispatch(actions.changePaginationInfo(obj)),
startProgramQuestion: (id, props) => dispatch(actions.startProgramQuestion(id, props))
});
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(DeveloperHome));
// export default DeveloperHome;