cjd-parkball
Version:
> 中后台业务组件库,中后台就像公园,进入需要买门票(登录),所以以 Parkball(公园球) 命名,公园内必定捕获!作为一个组件库,提供使用方法文档,方便开发者的调用
227 lines (214 loc) • 7.19 kB
JavaScript
import React from 'react';
import { Input } from 'antd';
import request from '@terminus/utils/request';
import './index.scss';
const DElEAR_API = '/api/bifrost/dealer/realations/dealerSearch';
const SEARCH_WIDTH = 650;
export default class selectTable extends React.Component {
state = {
dataSource: [],
curSelectedDelear: null,
placeholderValue: '',
generalName: '',
pageSize: 50,
pageNo: 1,
showPanel: false,
timerId: null,
pageCount: 0,
calcFlag: true,
calsPosition: { left: 0 },
}
componentDidMount() {
const { placeholder = '请输入', initialDelearId } = this.props;
// 默认经销商
if (initialDelearId) {
request(`/api/bifrost/dealer/${initialDelearId}`).then((res) => {
this.setState({
curSelectedDelear: res,
generalName: `(${res.legalRepresentative})${res.companyName}`
})
this.props.onResult(res);
});
}
this.setState({
placeholderValue: placeholder
})
this.searchDealer('');
if (this.contentNode) {
this.contentNode.addEventListener('scroll', this.handleScroll.bind(this));
}
}
componentWillReceiveProps(nextProps) {
const { delearType } = nextProps;
if (delearType) {
this.searchDealer('', delearType);
}
}
debounce = (fn, delay = 3000) => {
//期间间隔执行 节流
return (...rest) => { //箭头函数是没有arguments的 所以用...rest 来代替
let args = rest;
if (this.state.timerId) {
clearTimeout(this.state.timerId);//要用this.timerId 而不能直接定义var timerId=null;
}
this.state.timerId = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
onClickMenuItem = (item) => {
this.setState({
curSelectedDelear: item,
generalName: `(${item.legalRepresentative})${item.companyName}`
})
this.props.onResult(item);
}
//选择某个经销商(加入防抖动后 在频繁输入时 不会发送请求)
onChange = (e) => {
this.setState({
generalName: e.currentTarget.value
})
let debounceAjax = this.debounce(this.searchDealer, 500)
debounceAjax(e.currentTarget.value)
}
// 初始化经销商
searchDealer = (value, agencyType) => {
const { api = DElEAR_API, delearType } = this.props;
const { pageSize } = this.state;
const type = (agencyType || delearType) ? `&delearType=${Number(agencyType || delearType)}` : '';
request(`${api}?generalName=${value}&pageSize=${pageSize}&pageNo=1${type}`).then((res) => {
this.setState({
dataSource: this.selectedHighlight(res.dealerVos),
pageNo: 2,
pageCount: Math.ceil(res.total/res.pageSize)
})
});
}
// 获取经销商数据
getAgencyData() {
const { api = DElEAR_API, delearType } = this.props;
const { generalName, pageSize, pageNo, dataSource } = this.state;
const type = delearType ? `&delearType=${Number(delearType)}` : '';
request(`${api}?generalName=${generalName}&pageSize=${pageSize}&pageNo=${pageNo}${type}`).then((res) => {
this.setState({
dataSource: this.selectedHighlight(dataSource.concat(res.dealerVos)),
pageNo: pageNo + 1,
})
});
}
// 滚动到底部加载数据
handleScroll=(e)=>{
const clientHeight = e.target.clientHeight
const scrollHeight = e.target.scrollHeight
const scrollTop = e.target.scrollTop
const isBottom = (clientHeight + scrollTop === scrollHeight)
const { pageCount, pageNo } = this.state;
if (isBottom && (pageNo <= pageCount)) {
this.getAgencyData();
}
}
// 选中高亮
selectedHighlight(arr) {
const { curSelectedDelear } = this.state;
if (arr && arr.length && curSelectedDelear && curSelectedDelear.id) {
return arr.map(item => {
if (item.id === curSelectedDelear.id) {
return Object.assign(item, {highlightClass: 'highlight'})
}
return item;
})
}
return arr;
}
// 输入框聚焦
onFocus = () => {
const { curSelectedDelear, calcFlag } = this.state
this.setState({
showPanel: true,
generalName: '',
placeholderValue: curSelectedDelear ? `(${curSelectedDelear.legalRepresentative})${curSelectedDelear.companyName}` : '请输入'
})
this.searchDealer('')
if (this.contentBox) { // 首次聚焦定位
let domRect = this.contentBox.getBoundingClientRect();
if (calcFlag && (window.screen.width - domRect.left) < SEARCH_WIDTH) {
this.setState({
calsPosition: { right: 0 }
})
}
this.setState({
calcFlag: false
})
}
}
// 失去焦点
onBlur = () => {
const { curSelectedDelear } = this.state
this.setState({
showPanel: false,
generalName: curSelectedDelear ? `(${curSelectedDelear.legalRepresentative})${curSelectedDelear.companyName}` : ''
})
}
render() {
const {
dataSource = [],
showPanel,
generalName,
placeholderValue,
calsPosition
} = this.state;
const {
disabled,
initialDelearId
} = this.props;
return (
<div className="s__box" ref={ node => this.contentBox = node }>
<Input
{...this.props}
placeholder={placeholderValue}
value={generalName}
initialValue={initialDelearId}
onChange={this.onChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
disabled={disabled}
autocomplete="off"
/>
{/* 这里必须用display控制元素显隐 */}
<div className="m_u" style={{display: showPanel ? 'block' : 'none', ...calsPosition}}>
<div className="li_w li_title">
<span style={{flex: 2}}>经销商名称</span>
<span>经销商编码</span>
<span>经营者</span>
<span>省份</span>
<span>法人</span>
<span>联系方式</span>
</div >
{/* 下面用mousedown不用click 是因为前者优先于blur事件发生 */}
<div ref={ node => this.contentNode = node } className="m_con">
{
dataSource.length > 0 ? dataSource.map(item => {
return (
<div
key={item.id}
className={`li_w ${item.highlightClass}`}
onMouseDown={this.onClickMenuItem.bind(this, item)}
>
<span title={item.companyName} style={{flex: 2}}>{item.companyName}</span>
<span title={item.outId}>{item.outId}</span>
<span title={item.parentCompanyName}>{item.parentCompanyName}</span>
<span title={item.province}>{item.province}</span>
<span title={item.legalRepresentative}>{item.legalRepresentative}</span>
<span title={item.dailyContactMobile}>{item.dailyContactMobile}</span>
</div>
)
}) : (
<div className="tip">暂无数据</div>
)
}
</div>
</div>
</div>
)
}
}