1) 营销系统增加导出
This commit is contained in:
parent
343a5a9763
commit
fd178f3b64
|
@ -894,7 +894,7 @@ export const batchSend = (data) => {
|
||||||
|
|
||||||
// 批量导出
|
// 批量导出
|
||||||
export const exportKey = (data) => {
|
export const exportKey = (data) => {
|
||||||
return req("get", baseurl + "/key/export", data);
|
return derive("get", baseurl + "/key/export", data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { req };
|
export { req };
|
||||||
|
|
|
@ -1,154 +1,154 @@
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from "react";
|
||||||
import { Button, Icon, BlockLoading, Notify, Grid } from 'zent'
|
import { Button, Icon, BlockLoading, Notify, Grid } from "zent";
|
||||||
import { bachUploadAll, handelResponse } from '../../assets/api.js'
|
import { bachUploadAll, handelResponse } from "../../assets/api.js";
|
||||||
import './style.less'
|
import "./style.less";
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '行号',
|
title: "行号",
|
||||||
name: 'id'
|
name: "id",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'key',
|
title: "key",
|
||||||
name: 'key'
|
name: "key",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '错误原因',
|
title: "错误原因",
|
||||||
name: 'msg'
|
name: "msg",
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
const UseUploadExcel = (props) => {
|
const UseUploadExcel = (props) => {
|
||||||
const { title = '提示', onClose, onImport, visible = false, url } = props
|
const { title = "提示", onClose, onImport, visible = false, url } = props;
|
||||||
|
|
||||||
const [fileState, setFilesState] = useState(null) // 文件
|
const [fileState, setFilesState] = useState(null); // 文件
|
||||||
const [filesName, setFilesName] = useState('') // 文件名
|
const [filesName, setFilesName] = useState(""); // 文件名
|
||||||
const [filesTip, setFilesTip] = useState(2) // 解析 tip 0失败 1部分成功 200全部成功
|
const [filesTip, setFilesTip] = useState(2); // 解析 tip 0失败 1部分成功 200全部成功
|
||||||
const [loading, setLoading] = useState(false) // 解析 loading
|
const [loading, setLoading] = useState(false); // 解析 loading
|
||||||
const [hash, setHash] = useState('') // 后端值
|
const [hash, setHash] = useState(""); // 后端值
|
||||||
const [disabledSureBtn, setDisabledSureBtn] = useState(true) // 导入 按钮
|
const [disabledSureBtn, setDisabledSureBtn] = useState(true); // 导入 按钮
|
||||||
const [partSuccessTag, setPartSuccessTag] = useState(false) // 部分成功
|
const [partSuccessTag, setPartSuccessTag] = useState(false); // 部分成功
|
||||||
const [showUpType, setShowUpType] = useState(false) // false无文件上传 true文件上传
|
const [showUpType, setShowUpType] = useState(false); // false无文件上传 true文件上传
|
||||||
const [totalData, setTotalData] = useState(0)
|
const [totalData, setTotalData] = useState(0);
|
||||||
const [errCoun, setErrCoun] = useState(0)
|
const [errCoun, setErrCoun] = useState(0);
|
||||||
const [tableData, setTableData] = useState([])
|
const [tableData, setTableData] = useState([]);
|
||||||
|
|
||||||
const bachUploadState_200 = (res) => {
|
const bachUploadState_200 = (res) => {
|
||||||
setFilesTip(200)
|
setFilesTip(200);
|
||||||
setHash(res.data.hash)
|
setHash(res.data.hash);
|
||||||
setDisabledSureBtn(false)
|
setDisabledSureBtn(false);
|
||||||
console.log('res => 成功', res)
|
console.log("res => 成功", res);
|
||||||
}
|
};
|
||||||
|
|
||||||
const bachUploadState_0 = (res) => {
|
const bachUploadState_0 = (res) => {
|
||||||
setFilesTip(0)
|
setFilesTip(0);
|
||||||
}
|
};
|
||||||
|
|
||||||
const erObj = (data) => {
|
const erObj = (data) => {
|
||||||
let msgObj = ''
|
let msgObj = "";
|
||||||
for (let key in data) {
|
for (let key in data) {
|
||||||
msgObj += data[key] + ' '
|
msgObj += data[key] + " ";
|
||||||
}
|
}
|
||||||
return msgObj
|
return msgObj;
|
||||||
}
|
};
|
||||||
|
|
||||||
const bachUploadState_1 = (res) => {
|
const bachUploadState_1 = (res) => {
|
||||||
setPartSuccessTag(true)
|
setPartSuccessTag(true);
|
||||||
let rowError = res.data.rowError
|
let rowError = res.data.rowError;
|
||||||
setTotalData(rowError.total)
|
setTotalData(rowError.total);
|
||||||
setErrCoun(rowError.error_count)
|
setErrCoun(rowError.error_count);
|
||||||
setHash(rowError.hash)
|
setHash(rowError.hash);
|
||||||
let errArr = []
|
let errArr = [];
|
||||||
for (let key in rowError.error) {
|
for (let key in rowError.error) {
|
||||||
errArr.push(rowError.error[key])
|
errArr.push(rowError.error[key]);
|
||||||
}
|
}
|
||||||
errArr = errArr.map((item, index) => {
|
errArr = errArr.map((item, index) => {
|
||||||
return {
|
return {
|
||||||
key: item.key,
|
key: item.key,
|
||||||
id: index + 1,
|
id: index + 1,
|
||||||
msg: erObj(item.msg)
|
msg: erObj(item.msg),
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
setTableData(errArr)
|
setTableData(errArr);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件后端解析
|
* 文件后端解析
|
||||||
*/
|
*/
|
||||||
const excelParseFun = async (file) => {
|
const excelParseFun = async (file) => {
|
||||||
setLoading(true)
|
setLoading(true);
|
||||||
let formdata = new FormData()
|
let formdata = new FormData();
|
||||||
formdata.append('file', file)
|
formdata.append("file", file);
|
||||||
|
|
||||||
bachUploadAll(url, formdata).then((res) => {
|
bachUploadAll(url, formdata).then((res) => {
|
||||||
setLoading(false)
|
setLoading(false);
|
||||||
if (res.code === 200 || res.code === 0 || res.code === 1) {
|
if (res.code === 200 || res.code === 0 || res.code === 1) {
|
||||||
switch (res.code) {
|
switch (res.code) {
|
||||||
case 200:
|
case 200:
|
||||||
bachUploadState_200(res)
|
bachUploadState_200(res);
|
||||||
return
|
return;
|
||||||
case 0:
|
case 0:
|
||||||
bachUploadState_0(res)
|
bachUploadState_0(res);
|
||||||
return
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
bachUploadState_1(res)
|
bachUploadState_1(res);
|
||||||
return
|
return;
|
||||||
default:
|
default:
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('res =>', res)
|
console.log("res =>", res);
|
||||||
Notify.error(res.message)
|
Notify.error(res.message);
|
||||||
setFilesTip(0)
|
setFilesTip(0);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* input 文件改变
|
* input 文件改变
|
||||||
* @param {file} e
|
* @param {file} e
|
||||||
*/
|
*/
|
||||||
const fileChange = (e) => {
|
const fileChange = (e) => {
|
||||||
let my_file = e.target.files[0]
|
let my_file = e.target.files[0];
|
||||||
setFilesState(my_file)
|
setFilesState(my_file);
|
||||||
setFilesName(my_file.name)
|
setFilesName(my_file.name);
|
||||||
setShowUpType(true)
|
setShowUpType(true);
|
||||||
excelParseFun(my_file) // 文件解析
|
excelParseFun(my_file); // 文件解析
|
||||||
console.log('file =>', my_file)
|
console.log("file =>", my_file);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格文件模版下载
|
* 表格文件模版下载
|
||||||
*/
|
*/
|
||||||
const downloadMBExcel = () => {
|
const downloadMBExcel = () => {
|
||||||
window.location.href =
|
window.location.href =
|
||||||
'http://lsxdemall.oss-cn-beijing.aliyuncs.com/MarketingSystem/key%E6%A8%A1%E7%89%88.xlsx'
|
"http://lsxdemall.oss-cn-beijing.aliyuncs.com/MarketingSystem/key%E6%A8%A1%E7%89%88.xlsx";
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确定导入
|
* 确定导入
|
||||||
*/
|
*/
|
||||||
const importBtn = () => {
|
const importBtn = () => {
|
||||||
if (hash !== '') {
|
if (hash !== "") {
|
||||||
bachOnClose()
|
bachOnClose();
|
||||||
onImport(hash)
|
onImport(hash);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新上传
|
* 重新上传
|
||||||
*/
|
*/
|
||||||
const resetUpload = () => {
|
const resetUpload = () => {
|
||||||
setPartSuccessTag(false)
|
setPartSuccessTag(false);
|
||||||
setFilesTip(0)
|
setFilesTip(0);
|
||||||
}
|
};
|
||||||
|
|
||||||
const bachOnClose = () => {
|
const bachOnClose = () => {
|
||||||
setFilesTip(2)
|
setFilesTip(2);
|
||||||
setPartSuccessTag(false)
|
setPartSuccessTag(false);
|
||||||
setShowUpType(false)
|
setShowUpType(false);
|
||||||
onClose()
|
onClose();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 弹窗 顶部信息
|
* 弹窗 顶部信息
|
||||||
|
@ -157,23 +157,23 @@ const UseUploadExcel = (props) => {
|
||||||
const uploadTop = () => {
|
const uploadTop = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='step-bar'>
|
<div className="step-bar">
|
||||||
<div className='step-group'>
|
<div className="step-group">
|
||||||
<div className='step-code active'>1</div>
|
<div className="step-code active">1</div>
|
||||||
<span className='step-label active'>上传文件</span>
|
<span className="step-label active">上传文件</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='step-center'>
|
<div className="step-center">
|
||||||
<div className='step-line'></div>
|
<div className="step-line"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className='step-group'>
|
<div className="step-group">
|
||||||
<div className='step-code'>2</div>
|
<div className="step-code">2</div>
|
||||||
<span className='step-label'>导入完成</span>
|
<span className="step-label">导入完成</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='upload-panel1'>
|
<div className="upload-panel1">
|
||||||
<div className='upload-label'>直接上传</div>
|
<div className="upload-label">直接上传</div>
|
||||||
<div className='upload-info'>
|
<div className="upload-info">
|
||||||
<div> - 支持文件类型:xls,xlsx,csv</div>
|
<div> - 支持文件类型:xls,xlsx,csv</div>
|
||||||
<div>
|
<div>
|
||||||
- 支持所有基础字段的导入,一次至多导入 10000
|
- 支持所有基础字段的导入,一次至多导入 10000
|
||||||
|
@ -182,8 +182,8 @@ const UseUploadExcel = (props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 无,文件上传
|
* 无,文件上传
|
||||||
|
@ -191,24 +191,25 @@ const UseUploadExcel = (props) => {
|
||||||
*/
|
*/
|
||||||
const uploadExcel = () => {
|
const uploadExcel = () => {
|
||||||
return (
|
return (
|
||||||
<div className='upload-excel-01'>
|
<div className="upload-excel-01">
|
||||||
<input
|
<input
|
||||||
type='file'
|
type="file"
|
||||||
accept='.xls,.xlsx,.csv'
|
accept=".xls,.xlsx,.csv"
|
||||||
className='upload-input'
|
className="upload-input"
|
||||||
onChange={(e) => fileChange(e)}
|
onChange={(e) => fileChange(e)}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
style={{
|
style={{
|
||||||
background: '#1890ff',
|
background: "#1890ff",
|
||||||
color: '#FFFFFF',
|
color: "#FFFFFF",
|
||||||
border: 'none'
|
border: "none",
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
上传文件
|
上传文件
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析 tip
|
* 解析 tip
|
||||||
|
@ -216,20 +217,20 @@ const UseUploadExcel = (props) => {
|
||||||
*/
|
*/
|
||||||
const tipSuccess = () => {
|
const tipSuccess = () => {
|
||||||
return (
|
return (
|
||||||
<div className='upload-success'>
|
<div className="upload-success">
|
||||||
<Icon type='check-circle' className='success-icon' />
|
<Icon type="check-circle" className="success-icon" />
|
||||||
<span>文件解析成功, 点击 "确定导入" 即可导入</span>
|
<span>文件解析成功, 点击 "确定导入" 即可导入</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
const tipErr = () => {
|
const tipErr = () => {
|
||||||
return (
|
return (
|
||||||
<div className='upload-error'>
|
<div className="upload-error">
|
||||||
<Icon type='error-circle' className='error-icon' />
|
<Icon type="error-circle" className="error-icon" />
|
||||||
<span>文件解析失败, 请查看导入规则并更新文件</span>
|
<span>文件解析失败, 请查看导入规则并更新文件</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传
|
* 文件上传
|
||||||
|
@ -237,20 +238,20 @@ const UseUploadExcel = (props) => {
|
||||||
*/
|
*/
|
||||||
const upFilesExcel = () => {
|
const upFilesExcel = () => {
|
||||||
return (
|
return (
|
||||||
<div className='up-files-excel'>
|
<div className="up-files-excel">
|
||||||
<div className='user-file-box'>
|
<div className="user-file-box">
|
||||||
<p className='user-file-name'>
|
<p className="user-file-name">
|
||||||
<Icon type='text-guide-o' />
|
<Icon type="text-guide-o" />
|
||||||
{filesName}
|
{filesName}
|
||||||
</p>
|
</p>
|
||||||
<div className='file-update-box'>
|
<div className="file-update-box">
|
||||||
<input
|
<input
|
||||||
type='file'
|
type="file"
|
||||||
accept='.xls,.xlsx,.csv'
|
accept=".xls,.xlsx,.csv"
|
||||||
className='upload-input1'
|
className="upload-input1"
|
||||||
onChange={(e) => fileChange(e)}
|
onChange={(e) => fileChange(e)}
|
||||||
/>
|
/>
|
||||||
<Icon type='up-circle-o' />
|
<Icon type="up-circle-o" />
|
||||||
<span>更新文件</span>
|
<span>更新文件</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -258,16 +259,16 @@ const UseUploadExcel = (props) => {
|
||||||
{(() => {
|
{(() => {
|
||||||
switch (filesTip) {
|
switch (filesTip) {
|
||||||
case 0:
|
case 0:
|
||||||
return tipErr()
|
return tipErr();
|
||||||
case 200:
|
case 200:
|
||||||
return tipSuccess()
|
return tipSuccess();
|
||||||
default:
|
default:
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 底部
|
* 底部
|
||||||
|
@ -275,41 +276,43 @@ const UseUploadExcel = (props) => {
|
||||||
*/
|
*/
|
||||||
const uploadFooter = () => {
|
const uploadFooter = () => {
|
||||||
return (
|
return (
|
||||||
<div className='upload-panel1'>
|
<div className="upload-panel1">
|
||||||
<div className='upload-label'>下载模板并填写后上传</div>
|
<div className="upload-label">下载模板并填写后上传</div>
|
||||||
<div className='upload-info'>
|
<div className="upload-info">
|
||||||
<div>
|
<div>
|
||||||
请先下载「数字世界营销管理系统_keys_模板」并按照模板填写后再上传。
|
请先下载「数字世界营销管理系统_keys_模板」并按照模板填写后再上传。
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
type='default'
|
type="default"
|
||||||
className='btn-upload1'
|
className="btn-upload1"
|
||||||
onClick={() => downloadMBExcel()}>
|
onClick={() => downloadMBExcel()}
|
||||||
|
>
|
||||||
下载模板
|
下载模板
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className='btn-group'>
|
<div className="btn-group">
|
||||||
<Button type='default' onClick={() => bachOnClose()}>
|
<Button type="default" onClick={() => bachOnClose()}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type='primary'
|
type="primary"
|
||||||
disabled={disabledSureBtn}
|
disabled={disabledSureBtn}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
importBtn(e)
|
importBtn(e);
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
background: '#1890ff',
|
background: "#1890ff",
|
||||||
color: '#FFFFFF',
|
color: "#FFFFFF",
|
||||||
border: 'none'
|
border: "none",
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
确定导入
|
确定导入
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全部错误和全部正确
|
* 全部错误和全部正确
|
||||||
|
@ -321,8 +324,8 @@ const UseUploadExcel = (props) => {
|
||||||
{showUpType ? upFilesExcel() : uploadExcel()}
|
{showUpType ? upFilesExcel() : uploadExcel()}
|
||||||
{uploadFooter()}
|
{uploadFooter()}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部分正确
|
* 部分正确
|
||||||
|
@ -330,62 +333,64 @@ const UseUploadExcel = (props) => {
|
||||||
const partSuccess = () => {
|
const partSuccess = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='file-upload-tip'>
|
<div className="file-upload-tip">
|
||||||
文件上传成功.共 {totalData} 条手机号,其中 {totalData - errCoun}
|
文件上传成功.共 {totalData} 条手机号,其中 {totalData - errCoun}
|
||||||
条可成功导入
|
条可成功导入
|
||||||
</div>
|
</div>
|
||||||
<div className='file-errmsg1'>
|
<div className="file-errmsg1">
|
||||||
发现以下 {errCoun} 条不符合要求,将不会被导入
|
发现以下 {errCoun} 条不符合要求,将不会被导入
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='gridpanel1'>
|
<div className="gridpanel1">
|
||||||
<Grid
|
<Grid
|
||||||
columns={columns}
|
columns={columns}
|
||||||
datasets={tableData}
|
datasets={tableData}
|
||||||
scroll={{ y: 250 }}
|
scroll={{ y: 250 }}
|
||||||
size='large'
|
size="large"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='foot-bar'>
|
<div className="foot-bar">
|
||||||
<div className='btn-group'>
|
<div className="btn-group">
|
||||||
<Button
|
<Button
|
||||||
type='default'
|
type="default"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
resetUpload()
|
resetUpload();
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
重新上传
|
重新上传
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type='primary'
|
type="primary"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
importBtn(e)
|
importBtn(e);
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
background: '#1890ff',
|
background: "#1890ff",
|
||||||
color: '#FFFFFF',
|
color: "#FFFFFF",
|
||||||
border: 'none'
|
border: "none",
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
确定导入
|
确定导入
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{visible ? (
|
{visible ? (
|
||||||
<div>
|
<div>
|
||||||
<div className='modal'></div>
|
<div className="modal"></div>
|
||||||
<div className='import-excel' style={{ height: 'auto' }}>
|
<div className="import-excel" style={{ height: "auto" }}>
|
||||||
<BlockLoading loading={loading} iconText='解析中...' icon='circle'>
|
<BlockLoading loading={loading} iconText="解析中..." icon="circle">
|
||||||
<div className='import-header'>
|
<div className="import-header">
|
||||||
<div className='import-title'>{title}</div>
|
<div className="import-title">{title}</div>
|
||||||
<Icon
|
<Icon
|
||||||
type='close'
|
type="close"
|
||||||
className='import-close'
|
className="import-close"
|
||||||
onClick={() => bachOnClose()}
|
onClick={() => bachOnClose()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -395,7 +400,7 @@ const UseUploadExcel = (props) => {
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default UseUploadExcel
|
export default UseUploadExcel;
|
||||||
|
|
|
@ -6,41 +6,46 @@
|
||||||
* @Description:key列表查询组件
|
* @Description:key列表查询组件
|
||||||
* @FilePath: \frontend\src\components\keysFind\index.jsx
|
* @FilePath: \frontend\src\components\keysFind\index.jsx
|
||||||
*/
|
*/
|
||||||
import './index.less'
|
import "./index.less";
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from "react";
|
||||||
import { Button, Select, DateRangePicker, Notify } from 'zent'
|
import { Button, Select, DateRangePicker, Notify } from "zent";
|
||||||
import Ipt from '@/components/input/main'
|
import Ipt from "@/components/input/main";
|
||||||
import Form from '@/components/form/main'
|
import Form from "@/components/form/main";
|
||||||
import FormItem from '@/components/form-item/main'
|
import FormItem from "@/components/form-item/main";
|
||||||
import _ from 'lodash'
|
import _ from "lodash";
|
||||||
import {
|
import {
|
||||||
getReSellerOption,
|
getReSellerOption,
|
||||||
handelResponse,
|
handelResponse,
|
||||||
getPlanChoseOption
|
getPlanChoseOption,
|
||||||
} from '../../assets/api'
|
} from "../../assets/api";
|
||||||
import { FixedSizeList } from 'react-window'
|
import { FixedSizeList } from "react-window";
|
||||||
|
|
||||||
const stateList = [
|
const stateList = [
|
||||||
{ key: 0, text: '全部' },
|
{ key: 0, text: "全部" },
|
||||||
{ key: 1, text: '可使用' },
|
{ key: 1, text: "可使用" },
|
||||||
{ key: 2, text: '已使用' },
|
{ key: 2, text: "已使用" },
|
||||||
{ key: 3, text: '已完结' },
|
{ key: 3, text: "已完结" },
|
||||||
{ key: 4, text: '已作废' }
|
{ key: 4, text: "已作废" },
|
||||||
]
|
];
|
||||||
function init() {
|
function init() {
|
||||||
return {
|
return {
|
||||||
date: [],
|
date: [],
|
||||||
reseller: '',
|
reseller: "",
|
||||||
plan: '',
|
plan: "",
|
||||||
state: { key: 0, text: '全部' },
|
state: { key: 0, text: "全部" },
|
||||||
key: ''
|
key: "",
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ({ onQuery }) => {
|
export default ({ onQuery, query }) => {
|
||||||
const [models, setModels] = useState(init())
|
const [models, setModels] = useState(init());
|
||||||
const [resellerOption, setResellerOption] = useState([]) /* 分销商 */
|
const [resellerOption, setResellerOption] = useState([]); /* 分销商 */
|
||||||
const [planChoseOption, setPlanChoseOption] = useState([]) /* 营销计划 */
|
const [planChoseOption, setPlanChoseOption] = useState([]); /* 营销计划 */
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let param = onChange(models);
|
||||||
|
query(param);
|
||||||
|
}, [models]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
/* 获取分销商 */
|
/* 获取分销商 */
|
||||||
|
@ -50,13 +55,13 @@ export default ({ onQuery }) => {
|
||||||
(req, msg) => {
|
(req, msg) => {
|
||||||
const data = req.map((item) => ({
|
const data = req.map((item) => ({
|
||||||
key: item.id,
|
key: item.id,
|
||||||
text: item.name
|
text: item.name,
|
||||||
}))
|
}));
|
||||||
setResellerOption(data)
|
setResellerOption(data);
|
||||||
},
|
},
|
||||||
(err) => {}
|
(err) => {}
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
/* 获取营销计划 */
|
/* 获取营销计划 */
|
||||||
getPlanChoseOption().then((res) =>
|
getPlanChoseOption().then((res) =>
|
||||||
handelResponse(
|
handelResponse(
|
||||||
|
@ -64,14 +69,14 @@ export default ({ onQuery }) => {
|
||||||
(req, msg) => {
|
(req, msg) => {
|
||||||
const data = req.map((item) => ({
|
const data = req.map((item) => ({
|
||||||
key: item.id,
|
key: item.id,
|
||||||
text: item.title
|
text: item.title,
|
||||||
}))
|
}));
|
||||||
setPlanChoseOption(data)
|
setPlanChoseOption(data);
|
||||||
},
|
},
|
||||||
(err) => {}
|
(err) => {}
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
function renderOptionList(options, renderOption) {
|
function renderOptionList(options, renderOption) {
|
||||||
return (
|
return (
|
||||||
|
@ -79,12 +84,13 @@ export default ({ onQuery }) => {
|
||||||
height={256}
|
height={256}
|
||||||
itemCount={options.length}
|
itemCount={options.length}
|
||||||
itemSize={32}
|
itemSize={32}
|
||||||
width={200}>
|
width={200}
|
||||||
|
>
|
||||||
{({ index, style }) => (
|
{({ index, style }) => (
|
||||||
<div style={style}>{renderOption(options[index], index)}</div>
|
<div style={style}>{renderOption(options[index], index)}</div>
|
||||||
)}
|
)}
|
||||||
</FixedSizeList>
|
</FixedSizeList>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange(data) {
|
function onChange(data) {
|
||||||
|
@ -94,38 +100,38 @@ export default ({ onQuery }) => {
|
||||||
reseller_id: data.reseller?.key || null,
|
reseller_id: data.reseller?.key || null,
|
||||||
plan_id: data.plan?.key || null,
|
plan_id: data.plan?.key || null,
|
||||||
status: data.state?.key || null,
|
status: data.state?.key || null,
|
||||||
key: data.key || null
|
key: data.key || null,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='keysFind'>
|
<div className="keysFind">
|
||||||
<Form>
|
<Form>
|
||||||
<FormItem labelname='请选择日期:' required='' labelwidth='95px'>
|
<FormItem labelname="请选择日期:" required="" labelwidth="95px">
|
||||||
<DateRangePicker
|
<DateRangePicker
|
||||||
dateFormat='YYYY-MM-DD'
|
dateFormat="YYYY-MM-DD"
|
||||||
value={models.date}
|
value={models.date}
|
||||||
className='zent-datepicker-plan'
|
className="zent-datepicker-plan"
|
||||||
width={204}
|
width={204}
|
||||||
onChange={(va) => setModels({ ...models, date: va })}
|
onChange={(va) => setModels({ ...models, date: va })}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem labelname='状态:' required='' labelwidth='50px'>
|
<FormItem labelname="状态:" required="" labelwidth="50px">
|
||||||
<Select
|
<Select
|
||||||
name='state'
|
name="state"
|
||||||
value={models.state}
|
value={models.state}
|
||||||
options={stateList}
|
options={stateList}
|
||||||
placeholder='请选择'
|
placeholder="请选择"
|
||||||
width={204}
|
width={204}
|
||||||
clearable
|
clearable
|
||||||
onChange={(va) => setModels({ ...models, state: va })}
|
onChange={(va) => setModels({ ...models, state: va })}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem labelname='分销商:' required='' labelwidth='70px'>
|
<FormItem labelname="分销商:" required="" labelwidth="70px">
|
||||||
<Select
|
<Select
|
||||||
value={models.reseller}
|
value={models.reseller}
|
||||||
options={resellerOption}
|
options={resellerOption}
|
||||||
placeholder='请选择'
|
placeholder="请选择"
|
||||||
renderOptionList={renderOptionList}
|
renderOptionList={renderOptionList}
|
||||||
width={204}
|
width={204}
|
||||||
clearable
|
clearable
|
||||||
|
@ -133,54 +139,56 @@ export default ({ onQuery }) => {
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem labelname='计划名称:' required='' labelwidth='90px'>
|
<FormItem labelname="计划名称:" required="" labelwidth="90px">
|
||||||
<Select
|
<Select
|
||||||
value={models.plan}
|
value={models.plan}
|
||||||
options={planChoseOption}
|
options={planChoseOption}
|
||||||
placeholder='请选择'
|
placeholder="请选择"
|
||||||
renderOptionList={renderOptionList}
|
renderOptionList={renderOptionList}
|
||||||
width={204}
|
width={204}
|
||||||
clearable
|
clearable
|
||||||
onChange={(va) => setModels({ ...models, plan: va })}
|
onChange={(va) => setModels({ ...models, plan: va })}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem labelname='KEY:' required='' labelwidth='50px'>
|
<FormItem labelname="KEY:" required="" labelwidth="50px">
|
||||||
<Ipt
|
<Ipt
|
||||||
value={models.key}
|
value={models.key}
|
||||||
countShow={false}
|
countShow={false}
|
||||||
labelWidth='0px'
|
labelWidth="0px"
|
||||||
placeholder='请输入'
|
placeholder="请输入"
|
||||||
width={204}
|
width={204}
|
||||||
onChange={(va) => setModels({ ...models, key: va })}
|
onChange={(va) => setModels({ ...models, key: va })}
|
||||||
onClearItem={() => setModels({ ...models, key: '' })}
|
onClearItem={() => setModels({ ...models, key: "" })}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<div className='button_box'>
|
<div className="button_box">
|
||||||
<Button
|
<Button
|
||||||
type='primary'
|
type="primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (
|
||||||
onChange(models).plan_id ||
|
onChange(models).plan_id ||
|
||||||
onChange(models).reseller_id ||
|
onChange(models).reseller_id ||
|
||||||
onChange(models).key
|
onChange(models).key
|
||||||
) {
|
) {
|
||||||
onQuery(onChange(models))
|
onQuery(onChange(models));
|
||||||
} else {
|
} else {
|
||||||
Notify.warn('请输入【分销商】或【计划名称】或【key】进行查询')
|
Notify.warn("请输入【分销商】或【计划名称】或【key】进行查询");
|
||||||
}
|
}
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
查询
|
查询
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setModels(init())
|
setModels(init());
|
||||||
onQuery(onChange(init()))
|
onQuery(onChange(init()));
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
重置
|
重置
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
71
src/utils.js
71
src/utils.js
|
@ -1,69 +1,82 @@
|
||||||
/* 去重 */
|
/* 去重 */
|
||||||
export function deWeightThree(data, key) {
|
export function deWeightThree(data, key) {
|
||||||
let map = new Map()
|
let map = new Map();
|
||||||
for (let item of data) {
|
for (let item of data) {
|
||||||
if (!map.has(item[key])) {
|
if (!map.has(item[key])) {
|
||||||
map.set(item[key], item)
|
map.set(item[key], item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [...map.values()]
|
return [...map.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* uuid生成器 */
|
/* uuid生成器 */
|
||||||
export function uuid(len, radix) {
|
export function uuid(len, radix) {
|
||||||
var chars =
|
var chars =
|
||||||
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
|
||||||
var uuid = [],
|
var uuid = [],
|
||||||
i
|
i;
|
||||||
radix = radix || chars.length
|
radix = radix || chars.length;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
// Compact form
|
// Compact form
|
||||||
for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
|
for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
|
||||||
} else {
|
} else {
|
||||||
// rfc4122, version 4 form
|
// rfc4122, version 4 form
|
||||||
var r
|
var r;
|
||||||
|
|
||||||
// rfc4122 requires these characters
|
// rfc4122 requires these characters
|
||||||
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
|
uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
|
||||||
uuid[14] = '4'
|
uuid[14] = "4";
|
||||||
|
|
||||||
// Fill in random data. At i==19 set the high bits of clock sequence as
|
// Fill in random data. At i==19 set the high bits of clock sequence as
|
||||||
// per rfc4122, sec. 4.1.5
|
// per rfc4122, sec. 4.1.5
|
||||||
for (i = 0; i < 36; i++) {
|
for (i = 0; i < 36; i++) {
|
||||||
if (!uuid[i]) {
|
if (!uuid[i]) {
|
||||||
r = 0 | (Math.random() * 16)
|
r = 0 | (Math.random() * 16);
|
||||||
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
|
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uuid.join('')
|
return uuid.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
//计算两个时间差 返回天
|
//计算两个时间差 返回天
|
||||||
export function timeDiff(begin_time, end_time) {
|
export function timeDiff(begin_time, end_time) {
|
||||||
//年月日时分秒转换为时间戳
|
//年月日时分秒转换为时间戳
|
||||||
let beginTime = new Date(begin_time).getTime() / 1000
|
let beginTime = new Date(begin_time).getTime() / 1000;
|
||||||
let endTime = new Date(end_time).getTime() / 1000
|
let endTime = new Date(end_time).getTime() / 1000;
|
||||||
var starttime = ''
|
var starttime = "";
|
||||||
var endtime = ''
|
var endtime = "";
|
||||||
if (beginTime < endTime) {
|
if (beginTime < endTime) {
|
||||||
starttime = beginTime
|
starttime = beginTime;
|
||||||
endtime = endTime
|
endtime = endTime;
|
||||||
} else {
|
} else {
|
||||||
starttime = endTime
|
starttime = endTime;
|
||||||
endtime = beginTime
|
endtime = beginTime;
|
||||||
}
|
}
|
||||||
//计算天数
|
//计算天数
|
||||||
var timediff = endtime - starttime
|
var timediff = endtime - starttime;
|
||||||
var days = parseInt(timediff / 86400)
|
var days = parseInt(timediff / 86400);
|
||||||
//计算小时数
|
//计算小时数
|
||||||
var remain = timediff % 86400
|
var remain = timediff % 86400;
|
||||||
var hours = parseInt(remain / 3600)
|
var hours = parseInt(remain / 3600);
|
||||||
//计算分钟数
|
//计算分钟数
|
||||||
var remain = remain % 3600
|
var remain = remain % 3600;
|
||||||
var mins = parseInt(remain / 60)
|
var mins = parseInt(remain / 60);
|
||||||
var res = Number(days + 1)
|
var res = Number(days + 1);
|
||||||
return res
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNowTime() {
|
||||||
|
var now = new Date();
|
||||||
|
var year = now.getFullYear();
|
||||||
|
var month =
|
||||||
|
now.getMonth() + 1 <= 9 ? "0" + (now.getMonth() + 1) : now.getMonth() + 1;
|
||||||
|
var day = now.getDate() <= 9 ? "0" + now.getDate() : now.getDate();
|
||||||
|
var tt = now.getHours() <= 9 ? "0" + now.getHours() : now.getHours();
|
||||||
|
var mm = now.getMinutes() <= 9 ? "0" + now.getMinutes() : now.getMinutes();
|
||||||
|
var ss = now.getSeconds() <= 9 ? "0" + now.getSeconds() : now.getSeconds();
|
||||||
|
let datelist = [year, month, day, tt, mm, ss];
|
||||||
|
return datelist.join("");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue