💥 feat(模块): 添加了个很棒的功能

This commit is contained in:
ylj20011123 2025-07-30 16:16:41 +08:00
parent 7c7f6abdac
commit ac37e35e94

View File

@ -1,6 +1,6 @@
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 { connect } from "umi";
import { handleAddQuestion, handleDeleteQuestion, handleEditQuestion, handleGetQuestionList } from "./service";
@ -8,12 +8,16 @@ import { handleGetAddExamineType, handleGetAllTypeQuestion, handleGetExamineType
import moment from "moment";
import AddQuestion from "./components/addQuestion";
import { request } from "express";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
const { currentUser } = props
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
const addQuestionRef = useRef<any>()
// 显示新增问题的悬浮框
@ -30,7 +34,11 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
// 拿到protable的问题分类
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 = [
{
@ -273,8 +281,252 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
// 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 (
<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={{
width: '100%',
paddingTop: 0,
@ -316,8 +568,13 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
console.log('data', data);
if (data && data.length > 0) {
let list: any = getLeafNodes(data)
console.log('listlistlistlistlist321', list);
setReqDetailList(list)
return { data: data, success: true }
}
setReqDetailList([])
return { data: [], success: true }
@ -348,10 +605,40 @@ const examineQuestion: React.FC<{ currentUser: any }> = (props) => {
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-saleRankReport"
filename={`考核问题列表`}
sheet="sheet1"
/>
</span>,
<Button type="primary" onClick={(e) => {
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>
]
}}