💥 feat(模块): 添加了个很棒的功能
This commit is contained in:
parent
7c7f6abdac
commit
ac37e35e94
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { ActionType, FormInstance, ProForm, ProFormDigit, ProFormList, ProFormRadio, ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea, ProFormTreeSelect, ProTable } from "@ant-design/pro-components";
|
import { ActionType, FormInstance, ProForm, ProFormDigit, ProFormList, ProFormRadio, ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea, ProFormTreeSelect, ProTable } from "@ant-design/pro-components";
|
||||||
import { Button, Col, message, Modal, Popconfirm, Row, Space } from "antd";
|
import { Button, Col, message, Modal, Popconfirm, Row, Space, Spin } from "antd";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import { connect } from "umi";
|
import { connect } from "umi";
|
||||||
import { handleAddQuestion, handleDeleteQuestion, handleEditQuestion, handleGetQuestionList } from "./service";
|
import { handleAddQuestion, handleDeleteQuestion, handleEditQuestion, handleGetQuestionList } from "./service";
|
||||||
@ -8,12 +8,16 @@ import { handleGetAddExamineType, handleGetAllTypeQuestion, handleGetExamineType
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import AddQuestion from "./components/addQuestion";
|
import AddQuestion from "./components/addQuestion";
|
||||||
import { request } from "express";
|
import { request } from "express";
|
||||||
|
import ReactHTMLTableToExcel from "react-html-table-to-excel";
|
||||||
|
|
||||||
const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
||||||
const { currentUser } = props
|
const { currentUser } = props
|
||||||
|
const downloadBtnRef = useRef<any>()
|
||||||
|
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
const formRef = useRef<FormInstance>();
|
const formRef = useRef<FormInstance>();
|
||||||
|
// 导出的加载效果
|
||||||
|
const [showLoading, setShowLoading] = useState<boolean>(false)
|
||||||
|
|
||||||
const addQuestionRef = useRef<any>()
|
const addQuestionRef = useRef<any>()
|
||||||
// 显示新增问题的悬浮框
|
// 显示新增问题的悬浮框
|
||||||
@ -30,7 +34,11 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
// 拿到protable的问题分类
|
// 拿到protable的问题分类
|
||||||
const [bigTypeList, setBigTypeList] = useState<any>()
|
const [bigTypeList, setBigTypeList] = useState<any>()
|
||||||
|
|
||||||
|
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
|
||||||
|
|
||||||
|
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
|
||||||
|
// 是否显示打印的表格
|
||||||
|
const [showExportTable, setShowExportTable] = useState<boolean>(false)
|
||||||
|
|
||||||
const columns: any = [
|
const columns: any = [
|
||||||
{
|
{
|
||||||
@ -273,8 +281,252 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
// return res
|
// return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const exportColumns: any = [
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>问题分类</div>,
|
||||||
|
dataIndex: "bigName",
|
||||||
|
width: 150,
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "问题分类",
|
||||||
|
dataIndex: "id",
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: 'treeSelect',
|
||||||
|
request: async () => {
|
||||||
|
const typeReq = {
|
||||||
|
// any: [{
|
||||||
|
// "key": ""
|
||||||
|
// }]
|
||||||
|
}
|
||||||
|
let typeData = await handleGetExamineTypeTreeList(typeReq)
|
||||||
|
console.log('typeData', typeData);
|
||||||
|
return typeData
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
multiple: false,
|
||||||
|
treeDefaultExpandAll: true,
|
||||||
|
showSearch: true,
|
||||||
|
treeNodeFilterProp: 'title',
|
||||||
|
placeholder: '请选择问题分类',
|
||||||
|
fieldNames: {
|
||||||
|
label: "name",
|
||||||
|
value: "id"
|
||||||
|
},
|
||||||
|
// options: bigTypeList || []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>问题分类</div>,
|
||||||
|
dataIndex: "description",
|
||||||
|
width: 150,
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>问题内容</div>,
|
||||||
|
dataIndex: "title",
|
||||||
|
width: 200,
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>问题类型</div>,
|
||||||
|
dataIndex: "type",
|
||||||
|
width: 100,
|
||||||
|
hideInSearch: true,
|
||||||
|
align: 'center',
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
let questionType: string = record?.type && record?.type.split('_') && record?.type.split('_').length > 0 ? record?.type.split('_')[0] : ''
|
||||||
|
return questionType === 'radio' ? '单选' : questionType === 'checked' ? "多选" : ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: <div style={{ textAlign: 'center' }}>有效状态</div>,
|
||||||
|
// dataIndex: "status",
|
||||||
|
// width: 100,
|
||||||
|
// // hideInSearch: true,
|
||||||
|
// align: 'center',
|
||||||
|
// valueType: "select",
|
||||||
|
// ellipsis: true,
|
||||||
|
// valueEnum: {
|
||||||
|
// "1": "有效",
|
||||||
|
// "0": "无效"
|
||||||
|
// },
|
||||||
|
// initialValue: "1",
|
||||||
|
// render: (_, record) => {
|
||||||
|
// return record?.type ? record?.status ? '有效' : '无效' : ""
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: <div style={{ textAlign: 'center' }}>必填</div>,
|
||||||
|
// dataIndex: "required",
|
||||||
|
// width: 100,
|
||||||
|
// hideInSearch: true,
|
||||||
|
// align: 'center',
|
||||||
|
// ellipsis: true,
|
||||||
|
// render: (_, record) => {
|
||||||
|
// return record?.isNoChildren ? record?.required ? '是' : "否" : ''
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>选项内容</div>,
|
||||||
|
dataIndex: "options",
|
||||||
|
width: 300,
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
let str: string = ''
|
||||||
|
if (record.options && record?.options.length > 0) {
|
||||||
|
record.options.forEach((item: any, index: number) => {
|
||||||
|
str += `${item.text};`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return str || ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>更新时间</div>,
|
||||||
|
dataIndex: "updatedAt",
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.updatedAt ? moment(record?.updatedAt).format('YYYY-MM-DD HH:mm:ss') : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>创建时间</div>,
|
||||||
|
dataIndex: "createdAt",
|
||||||
|
width: 150,
|
||||||
|
align: 'center',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (_, record) => {
|
||||||
|
return record?.createdAt ? moment(record?.createdAt).format('YYYY-MM-DD HH:mm:ss') : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: <div style={{ textAlign: 'center' }}>操作人</div>,
|
||||||
|
dataIndex: "operator",
|
||||||
|
width: 100,
|
||||||
|
align: 'center',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const exportTable = (e) => {
|
||||||
|
e.stopPropagation(); // 防止Collapse组件收起
|
||||||
|
const main = document.getElementsByClassName(`saleReportHideBox${printIndex}`)[0]
|
||||||
|
const thead = main.querySelector('thead').cloneNode(true); // 深克隆DOM节点
|
||||||
|
const tbody = main.querySelector('tbody').cloneNode(true); // 深克隆DOM节点
|
||||||
|
const container = document.querySelector('#hiddenBox');
|
||||||
|
|
||||||
|
|
||||||
|
// 加个标题
|
||||||
|
const tableTop = document.createElement('div')
|
||||||
|
tableTop.innerText = `考核问题表`
|
||||||
|
tableTop.setAttribute('style', 'font-size:20px;font-weight:600;display:flex;width:100%;justify-content: center;text-align: center;');
|
||||||
|
|
||||||
|
// // 加个时间
|
||||||
|
// const tableTime = document.createElement('div')
|
||||||
|
// tableTime.innerText = `${moment().format('YYYY-MM-DD')}`
|
||||||
|
// tableTop.setAttribute('style', 'font-size:14px;display:flex;width:100%;justify-content: flex-start;text-align: center;');
|
||||||
|
|
||||||
|
const tempTable = document.createElement('table');
|
||||||
|
tempTable.appendChild(tableTop)
|
||||||
|
// tempTable.appendChild(tableTime)
|
||||||
|
|
||||||
|
tempTable.appendChild(thead);
|
||||||
|
tempTable.appendChild(tbody);
|
||||||
|
|
||||||
|
tempTable.setAttribute('id', 'table-to-xls-saleRankReport'); // 给table添加id,值与按钮上的table字段对应
|
||||||
|
|
||||||
|
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
|
||||||
|
|
||||||
|
setShowLoading(false)
|
||||||
|
|
||||||
|
downloadBtnRef.current.handleDownload();
|
||||||
|
setShowExportTable(false)
|
||||||
|
tempTable.remove() // 防止重复打印一个内容
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把无限嵌套的树形 变为 单层的
|
||||||
|
const getLeafNodes = (treeList: any) => {
|
||||||
|
const result: any = [];
|
||||||
|
|
||||||
|
function traverse(list: any, bigName: any) {
|
||||||
|
for (const node of list) {
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
traverse(node.children, bigName);
|
||||||
|
} else {
|
||||||
|
result.push({
|
||||||
|
...node,
|
||||||
|
bigName // 新增字段
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of treeList) {
|
||||||
|
traverse([item], item.name); // 第一层的 name 作为 bigName 传入
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
{
|
||||||
|
showLoading ?
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
background: 'rgba(0,0,0,0.1)',
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 5,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: '15px 20px 10px',
|
||||||
|
background: '#fff',
|
||||||
|
borderRadius: '8px',
|
||||||
|
width: '200px'
|
||||||
|
}}>
|
||||||
|
<Spin />
|
||||||
|
<span style={{ marginLeft: '5px' }}>数据导出中...</span>
|
||||||
|
</div>
|
||||||
|
</div> : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className={`saleReportHideBox${printIndex}`} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
|
||||||
|
{
|
||||||
|
showExportTable && reqDetailList && reqDetailList.length > 0 ?
|
||||||
|
<ProTable
|
||||||
|
columns={exportColumns}
|
||||||
|
dataSource={reqDetailList}
|
||||||
|
pagination={false}
|
||||||
|
expandable={{
|
||||||
|
defaultExpandAllRows: true
|
||||||
|
}}
|
||||||
|
/> : ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
|
||||||
|
|
||||||
|
|
||||||
<div style={{
|
<div style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
paddingTop: 0,
|
paddingTop: 0,
|
||||||
@ -316,8 +568,13 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
|
|
||||||
console.log('data', data);
|
console.log('data', data);
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
|
|
||||||
|
let list: any = getLeafNodes(data)
|
||||||
|
console.log('listlistlistlistlist321', list);
|
||||||
|
setReqDetailList(list)
|
||||||
return { data: data, success: true }
|
return { data: data, success: true }
|
||||||
}
|
}
|
||||||
|
setReqDetailList([])
|
||||||
return { data: [], success: true }
|
return { data: [], success: true }
|
||||||
|
|
||||||
|
|
||||||
@ -348,10 +605,40 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
|
|||||||
}}
|
}}
|
||||||
toolbar={{
|
toolbar={{
|
||||||
actions: [
|
actions: [
|
||||||
|
<span style={{ visibility: 'hidden' }}>
|
||||||
|
<ReactHTMLTableToExcel
|
||||||
|
buttonText={'导出excel'}
|
||||||
|
ref={downloadBtnRef}
|
||||||
|
table="table-to-xls-saleRankReport"
|
||||||
|
filename={`考核问题列表`}
|
||||||
|
sheet="sheet1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
</span>,
|
||||||
<Button type="primary" onClick={(e) => {
|
<Button type="primary" onClick={(e) => {
|
||||||
setShowQuestionModal(true)
|
setShowQuestionModal(true)
|
||||||
}}>
|
}}>
|
||||||
新增问题
|
新增问题
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="new"
|
||||||
|
type="primary"
|
||||||
|
onClick={(e) => {
|
||||||
|
if (reqDetailList && reqDetailList.length > 0) {
|
||||||
|
setShowLoading(true)
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowExportTable(true)
|
||||||
|
setTimeout(() => {
|
||||||
|
exportTable(e)
|
||||||
|
}, 100)
|
||||||
|
}, 100)
|
||||||
|
} else {
|
||||||
|
message.error('暂无数据可导出!')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
导出excel
|
||||||
</Button>
|
</Button>
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user