|
|
import React from 'react'
|
|
|
import { Table, Divider, Modal, Button, Input, Cascader, Upload, Icon, message } from 'antd'
|
|
|
|
|
|
function HotKeywords() {
|
|
|
return <div>
|
|
|
HotKeywords
|
|
|
</div>
|
|
|
import HotApi from '../../services/seo/hot-keywords'
|
|
|
|
|
|
const { TextArea } = Input;
|
|
|
|
|
|
const titleObj = {
|
|
|
id: '序号',
|
|
|
keyword: '关键词',
|
|
|
msortName: '大品类',
|
|
|
sortName: '小品类',
|
|
|
yoho_goods_num: '商品数',
|
|
|
is_push: '是否推送',
|
|
|
add_time: '添加时间'
|
|
|
};
|
|
|
|
|
|
const columns = [];
|
|
|
|
|
|
Object.keys(titleObj).forEach(key => {
|
|
|
columns.push({
|
|
|
title: titleObj[key],
|
|
|
dataIndex: key,
|
|
|
key: key,
|
|
|
});
|
|
|
});
|
|
|
|
|
|
let globalSort = [];
|
|
|
|
|
|
function ActionButton(props) {
|
|
|
function editClick() {
|
|
|
props.keyword.callbackFn('edit', props.keyword);
|
|
|
}
|
|
|
function deleteClick() {
|
|
|
props.keyword.callbackFn('delete', props.keyword);
|
|
|
}
|
|
|
return (
|
|
|
<span>
|
|
|
<a href="javascript:;" onClick={editClick}>编辑</a>
|
|
|
<Divider type="vertical" />
|
|
|
<a href="javascript:;" onClick={deleteClick}>删除</a>
|
|
|
</span>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
class OptionModal extends React.Component {
|
|
|
constructor(props) {
|
|
|
super(props);
|
|
|
|
|
|
this.props = props;
|
|
|
this.state = {
|
|
|
sorts: globalSort || []
|
|
|
};
|
|
|
|
|
|
this.renderData = Object.assign({}, props.record || {});
|
|
|
|
|
|
this.hotApi = new HotApi();
|
|
|
|
|
|
this.loadHotList = props.loadHotList;
|
|
|
this.hideOptionModal = props.hideOptionModal;
|
|
|
this.handleKeywordChange = this.handleKeywordChange.bind(this);
|
|
|
this.handleDescChange = this.handleDescChange.bind(this);
|
|
|
this.handleSortChange = this.handleSortChange.bind(this);
|
|
|
this.handleImageChange = this.handleImageChange.bind(this);
|
|
|
this.loadSortData = this.loadSortData.bind(this);
|
|
|
|
|
|
|
|
|
switch (this.renderData.type) {
|
|
|
case 'edit':
|
|
|
this.modalTitle = '编辑关键词';
|
|
|
this.handleOk = this.handleSave.bind(this);
|
|
|
break;
|
|
|
case 'delete':
|
|
|
this.modalTitle = '删除关键词';
|
|
|
this.handleOk = this.handleDelete.bind(this);
|
|
|
break;
|
|
|
default:
|
|
|
this.modalTitle = '新建关键词';
|
|
|
this.handleOk = this.handleSave.bind(this);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if (!globalSort.length) {
|
|
|
this.loadSortDataAsync().then(result => {
|
|
|
this.setState({sorts: result});
|
|
|
globalSort = result;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
handleDelete() {
|
|
|
return this.hotApi.delHotKeywords([this.renderData.id]).then(result => {
|
|
|
if (result.code === 200) {
|
|
|
this.loadHotList && this.loadHotList();
|
|
|
this.hideOptionModal && this.hideOptionModal();
|
|
|
} else {
|
|
|
message.error(result.message);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
handleSave() {
|
|
|
return this.hotApi.saveHotKeywords(this.renderData).then(result => {
|
|
|
if (result.code === 200) {
|
|
|
this.loadHotList && this.loadHotList();
|
|
|
this.hideOptionModal && this.hideOptionModal();
|
|
|
} else {
|
|
|
message.error(result.message);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
handleKeywordChange(e) {
|
|
|
this.renderData.keyword = e.target.value;
|
|
|
}
|
|
|
handleDescChange(e) {
|
|
|
this.renderData.describe = e.target.value;
|
|
|
}
|
|
|
handleSortChange(select) {
|
|
|
this.renderData.msort = select[0];
|
|
|
this.renderData.misort = select[1];
|
|
|
this.renderData.sort_id = select[2];
|
|
|
}
|
|
|
handleImageChange(info) {
|
|
|
const status = info.file.status;
|
|
|
|
|
|
if (status === 'uploading') {
|
|
|
this.setState({ loading: true });
|
|
|
return;
|
|
|
} else if (status === 'done') {
|
|
|
const result = info.file.response;
|
|
|
let state = { loading: false };
|
|
|
|
|
|
if (result.code === 200) {
|
|
|
this.renderData.goods_img = result.data.images[0];
|
|
|
}
|
|
|
|
|
|
this.setState(state);
|
|
|
}
|
|
|
}
|
|
|
beforeUpload(file) {
|
|
|
const isImage = file.type.indexOf('image') > -1;
|
|
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
|
|
|
|
if (!isImage) {
|
|
|
message.error('请上传图片!');
|
|
|
} else if (!isLt2M) {
|
|
|
message.error('图片大小需小于 2MB!');
|
|
|
}
|
|
|
|
|
|
return isImage && isLt2M;
|
|
|
}
|
|
|
loadSortData(selectedOptions) {
|
|
|
const targetOption = selectedOptions[selectedOptions.length - 1];
|
|
|
|
|
|
targetOption.loading = true;
|
|
|
|
|
|
this.loadSortDataAsync(targetOption.value).then(result => {
|
|
|
targetOption.loading = false;
|
|
|
targetOption.children = result;
|
|
|
globalSort = this.state.sorts;
|
|
|
this.setState({sorts: this.state.sorts});
|
|
|
});
|
|
|
}
|
|
|
loadSortDataAsync(id) {
|
|
|
return this.hotApi.getSubSorts(id || 0).then(result => {
|
|
|
result.map(val => {
|
|
|
if (id) {
|
|
|
val.value = val.sort_id;
|
|
|
val.label = val.sort_name;
|
|
|
val.isLeaf = false;
|
|
|
val.children = (val.sub || []).map(sval => {
|
|
|
sval.value = sval.sort_id;
|
|
|
sval.label = sval.sort_name;
|
|
|
sval.isLeaf = true;
|
|
|
|
|
|
return sval;
|
|
|
})
|
|
|
} else {
|
|
|
val.value = val.id;
|
|
|
val.label = val.sortName;
|
|
|
val.isLeaf = false;
|
|
|
}
|
|
|
|
|
|
return val;
|
|
|
});
|
|
|
|
|
|
return result;
|
|
|
});
|
|
|
}
|
|
|
uploadButton(loading) {
|
|
|
return (
|
|
|
<div>
|
|
|
<Icon type={loading ? 'loading' : 'plus'} />
|
|
|
<div className="ant-upload-text">Upload</div>
|
|
|
</div>);
|
|
|
}
|
|
|
render() {
|
|
|
const record = this.renderData;
|
|
|
|
|
|
let title = '';
|
|
|
|
|
|
if (record.sort_id || record.msort || record.misort) {
|
|
|
let arr = [];
|
|
|
|
|
|
record.msortName && arr.push(record.msortName);
|
|
|
record.misortName && arr.push(record.misortName);
|
|
|
record.sortName && arr.push(record.sortName);
|
|
|
record.sortShowName = arr.join('/');
|
|
|
}
|
|
|
|
|
|
if (record && record.type === 'delete') {
|
|
|
return (
|
|
|
<Modal title={this.modalTitle} visible={true} onOk={this.handleOk} onCancel={this.hideOptionModal}>
|
|
|
<p>确认删除该关键词?</p>
|
|
|
</Modal>
|
|
|
)
|
|
|
} else {
|
|
|
const imageUrl = '';
|
|
|
|
|
|
return (
|
|
|
<Modal title={this.modalTitle} visible={true} onOk={this.handleOk} onCancel={this.hideOptionModal}>
|
|
|
<div style={{ paddingBottom: 10 }}>
|
|
|
<span>关键词:</span>
|
|
|
<Input onChange={this.handleKeywordChange} defaultValue={record.keyword} readOnly={record.id > 0}/>
|
|
|
</div>
|
|
|
<div style={{ paddingBottom: 10 }}>
|
|
|
<span>描述:</span>
|
|
|
<TextArea rows={4} onChange={this.handleDescChange} defaultValue={record.describe}/>
|
|
|
</div>
|
|
|
<div style={{ paddingBottom: 10 }}>
|
|
|
<span>封面图:</span>
|
|
|
<Upload
|
|
|
name="avatar"
|
|
|
listType="picture-card"
|
|
|
className="avatar-uploader"
|
|
|
showUploadList={false}
|
|
|
action="/upload/image"
|
|
|
name="file"
|
|
|
beforeUpload={this.beforeUpload}
|
|
|
onChange={this.handleImageChange}>
|
|
|
{record.goods_img ? <img src={record.goods_img} style={{maxWidth: 200}} /> : this.uploadButton(this.state.loading)}
|
|
|
</Upload>
|
|
|
</div>
|
|
|
<div style={{ paddingBottom: 10 }}>
|
|
|
<span>品类:</span>
|
|
|
{record.sortShowName ? <Input defaultValue={record.sortShowName} readOnly={record.id > 0}/> : <Cascader
|
|
|
options={this.state.sorts}
|
|
|
loadData={this.loadSortData}
|
|
|
onChange={this.handleSortChange}
|
|
|
style={{ width: '100%' }}
|
|
|
placeholder="" />}
|
|
|
|
|
|
</div>
|
|
|
</Modal>
|
|
|
)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
columns.push({
|
|
|
title: '操作',
|
|
|
key: 'action',
|
|
|
render(keyword) {
|
|
|
return <ActionButton keyword={keyword}/>
|
|
|
}
|
|
|
});
|
|
|
|
|
|
class HotKeywords extends React.Component {
|
|
|
constructor(props) {
|
|
|
super(props);
|
|
|
|
|
|
this.state = {
|
|
|
showModal: false,
|
|
|
dataSource: [],
|
|
|
columns: columns,
|
|
|
selectedRowKeys: [],
|
|
|
pagination: {
|
|
|
current: 1,
|
|
|
total: 1,
|
|
|
pageSize: 10
|
|
|
}
|
|
|
};
|
|
|
|
|
|
this.hotApi = new HotApi();
|
|
|
|
|
|
this.loadHotList = this.loadHotList.bind(this);
|
|
|
this.handleTableChange = this.handleTableChange.bind(this);
|
|
|
this.deleteTableRow = this.deleteTableRow.bind(this);
|
|
|
this.hideOptionModal = this.hideOptionModal.bind(this);
|
|
|
this.addTableRow = this.addTableRow.bind(this);
|
|
|
|
|
|
this.loadHotList();
|
|
|
}
|
|
|
loadHotList(params = {}) {
|
|
|
const { current, pageSize } = this.state.pagination;
|
|
|
|
|
|
params.page = params.page || current || 1;
|
|
|
params.limit = params.limit || pageSize || 10;
|
|
|
|
|
|
this.hotApi.getHotList(params).then(result => {
|
|
|
if (result.code === 200 && result.data) {
|
|
|
const pagination = this.state.pagination;
|
|
|
const { keywords, total } = result.data;
|
|
|
|
|
|
pagination.total = total;
|
|
|
|
|
|
this.setState({
|
|
|
dataSource: keywords,
|
|
|
pagination: pagination
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
onSelectChange(selectedRowKeys) {
|
|
|
this.setState({selectedRowKeys});
|
|
|
}
|
|
|
handleTableChange(pagination) {
|
|
|
this.setState({pagination});
|
|
|
this.loadHotList({page: pagination.current});
|
|
|
}
|
|
|
deleteTableRow() {
|
|
|
this.deleteKeywordsAsync(this.state.selectedRowKeys);
|
|
|
}
|
|
|
addTableRow() {
|
|
|
this.showOptionModal('add');
|
|
|
}
|
|
|
sendToBaidu() {
|
|
|
|
|
|
}
|
|
|
deleteKeywordsAsync(ids) {
|
|
|
this.hotApi.delHotKeywords(ids).then(result => {
|
|
|
result.code === 200 && this.loadHotList();
|
|
|
});
|
|
|
}
|
|
|
showOptionModal(type, record) {
|
|
|
// const modelRecord = {...record};
|
|
|
const modelRecord = record || {};
|
|
|
|
|
|
modelRecord.type = type;
|
|
|
this.modelRecord = modelRecord;
|
|
|
this.setState({showModal: true});
|
|
|
}
|
|
|
hideOptionModal() {
|
|
|
this.modelRecord = null;
|
|
|
this.setState({showModal: false});
|
|
|
}
|
|
|
optionModal(showModal) {
|
|
|
if (showModal) {
|
|
|
return <OptionModal hideOptionModal={this.hideOptionModal} record={this.modelRecord} loadHotList={this.loadHotList}/>
|
|
|
} else {
|
|
|
return <div></div>;
|
|
|
}
|
|
|
}
|
|
|
render() {
|
|
|
const { showModal, dataSource, columns, selectedRowKeys, pagination, loading } = this.state;
|
|
|
const hasSelected = selectedRowKeys.length > 0;
|
|
|
|
|
|
const rowSelection = {
|
|
|
selectedRowKeys,
|
|
|
onChange: this.onSelectChange.bind(this)
|
|
|
};
|
|
|
const rowKey = record => {
|
|
|
record.callbackFn = this.showOptionModal.bind(this);
|
|
|
|
|
|
return record.id;
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
<div>
|
|
|
<div style={{ paddingBottom: 10 }}>
|
|
|
<Button type="primary" onClick={this.deleteTableRow} disabled={!hasSelected} loading={loading}>删除</Button>
|
|
|
<Button type="primary" style={{ marginLeft: 10 }} onClick={this.addTableRow}>添加</Button>
|
|
|
{this.optionModal(showModal)}
|
|
|
</div>
|
|
|
|
|
|
<Table rowSelection={rowSelection} dataSource={dataSource} columns={columns}
|
|
|
rowKey={rowKey} pagination={pagination} onChange={this.handleTableChange}/>
|
|
|
</div>
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
export default HotKeywords |
...
|
...
|
|