ylj20011123 f1ba03ab73 update
2025-12-09 09:50:12 +08:00

616 lines
24 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 注册留存分析 用户行为记录分析
import { connect, Link } from "umi";
import type { CurrentUser } from "umi";
import type { ConnectState } from "@/models/connect";
import React, { useEffect, useRef, useState } from "react";
import ProCard from "@ant-design/pro-card";
import { MenuFoldOutlined } from "@ant-design/icons";
import { FormInstance, Tooltip } from "antd";
import { Button, message, Space, Spin, Tree } from "antd";
import useRequest from "@ahooksjs/use-request";
import { getServerpartTree } from "@/services/options";
import type { ActionType } from "@ant-design/pro-table";
import ProTable from "@ant-design/pro-table";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
import moment from 'moment'
import PageTitleBox from "@/components/PageTitleBox";
import { handleGetBEHAVIORRECORDList, handleGetBEHAVIORRECORDListCloud } from "@/pages/Setting/OperationLog/service";
import MemberDetail from "../memberInfor/component/memberDetail";
import { handleSetlogSave } from "@/utils/format";
import { handeGetNestingFIELDENUMListNoEncryption } from "../service";
import { highlightText } from "@/utils/highlightText";
const RegistrationRetentionAnalysis: React.FC<{ currentUser: CurrentUser, isComponent?: Boolean, parentDetail?: any }> = (props) => {
const { dispatch, children, currentUser, isComponent, parentDetail } = props
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
// 是否显示打印的表格
const [showExportTable, setShowExportTable] = useState<boolean>(false)
// 查询的条件
const [searchParams, setSearchParams] = useState<any>()
// 表格数据
const [tableData, setTableData] = useState<any>()
// 表格加载效果
const [tableLoading, setTableLoading] = useState<boolean>(false)
// 判断是否是第一次
const [isFirst, setIsFirst] = useState<boolean>(true)
// 当前查询的文字
const [currentSearchText, setCurrentSearchText] = useState<string>('')
const [columnsStateMap, setColumnsStateMap] = useState<any>({
BEHAVIORRECORD_ID: { show: false },
OPERATING_SYSTEM: { show: false },
BROWSER_VERSION: { show: false },
});
// 改变panes
const handleTabsPanes = (payload: any): void => {
if (dispatch) {
dispatch({
type: 'global/changeTabsRoutes',
payload: { data: payload, action: 'add' },
});
}
};
// 显示详情抽屉
const [showDetailDrawer, setShowDetailDrawer] = useState<boolean>(false)
// 当前行数据
const [currentRow, setCurrentRow] = useState<any>()
const columns: any = [
{
title: '查询内容',
hideInTable: true,
dataIndex: 'searchValue',
fieldProps: {
placeholder: '请输入操作人员/访问页面'
}
},
{
title: '查询时间',
dataIndex: 'search_date',
valueType: 'dateRange',
hideInTable: true,
hideInDescriptions: true,
search: {
transform: (value) => {
return {
BEHAVIORRECORD_TIME_Start: value[0],
BEHAVIORRECORD_TIME_End: value[1],
};
},
},
fieldProps: {
ranges: {
"当日": [moment(), moment()],
"本月": [moment().startOf('M'), moment()],
}
},
initialValue: [moment(), moment()],
// initialValue: [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
},
{
title: '日志编号',
width: 120,
hideInSearch: true,
dataIndex: 'BEHAVIORRECORD_ID'
},
{
title: '访问页面',
width: 150,
hideInSearch: true,
ellipsis: true,
dataIndex: 'BEHAVIORRECORD_ROUTNAME',
render: (_, record) => {
return highlightText(record?.BEHAVIORRECORD_ROUTNAME, currentSearchText)
}
// render: (_, record) => {
// return record?.BEHAVIORRECORD_ROUTNAME ? <a onClick={() => {
// console.log('record', record);
// const req: any = {
// key: record.BEHAVIORRECORD_ROUT,
// path: record.BEHAVIORRECORD_ROUT,
// title: record.BEHAVIORRECORD_ROUTNAME,
// children: children
// }
// console.log('req', req);
// handleTabsPanes(req)
// }}>
// {record?.BEHAVIORRECORD_ROUTNAME || ""}
// </a> : "-"
// return record?.BEHAVIORRECORD_ROUTNAME ? <Link to={record.BEHAVIORRECORD_ROUT}>
// {record?.BEHAVIORRECORD_ROUTNAME}
// </Link> : ""
// }
},
{
title: '操作类型',
dataIndex: 'BEHAVIORRECORD_TYPE',
// hideInSearch: true,
width: 100,
valueType: 'treeSelect',
align: 'center',
request: async () => {
const req = {
FIELDEXPLAIN_FIELD: 'BEHAVIORRECORD_TYPE',
FIELDEXPLAIN_ID: "",
FIELDENUM_PID: "",
FIELDENUM_STATUS: 1,
SearchKey: ""
}
const data = await handeGetNestingFIELDENUMListNoEncryption(req);
console.log('djskadjsaivbsjavbcv', data);
return data
},
// valueEnum: {
// "1000": '操作',
// "1001": '编辑',
// "1002": '删除',
// "2000": '查询'
// },
// initialValue: 1000,
fieldProps: {
fieldNames: {
label: 'FIELDENUM_NAME',
value: 'FIELDENUM_VALUE',
children: 'children'
},
treeDefaultExpandAll: true,
}
},
{
title: '操作人员',
hideInSearch: true,
align: 'center',
dataIndex: 'USER_NAME',
ellipsis: true,
width: 120,
render: (_, record) => {
return isComponent ? record?.USER_NAME : <a onClick={() => {
setCurrentRow(record)
setShowDetailDrawer(true)
handleSetlogSave(`查看${record?.MEMBERSHIP_NAME}${record?.MEMBERSHIP_ID}】会员信息`)
}}>
{/* {record?.USER_NAME || '-'} */}
{highlightText(record?.USER_NAME, currentSearchText)}
</a>
}
},
{
title: '操作地址',
hideInSearch: true,
// hideInTable: isComponent,
hideInTable: true,
dataIndex: 'USER_LOGINIP',
align: 'center',
width: 150,
},
{
title: '操作地点',
hideInSearch: true,
dataIndex: 'USER_LOGINPLACE',
align: 'center',
width: 160,
ellipsis: true,
},
// {
// title: '响应时间(s)',
// hideInSearch: true,
// dataIndex: 'BEHAVIORRECORD_DURATION',
// width: 120,
// align: 'center',
// sorter: (a, b) => a.BEHAVIORRECORD_DURATION - b.BEHAVIORRECORD_DURATION,
// render: (_, record) => {
// return `${record?.BEHAVIORRECORD_DURATION ? record?.BEHAVIORRECORD_DURATION : ""}`
// }
// },
{
title: <div style={{ textAlign: 'center' }}></div>,
hideInSearch: true,
dataIndex: 'BEHAVIORRECORD_EXPLAIN',
width: 250,
align: 'left',
ellipsis: true,
},
// {
// title: '操作状态',
// dataIndex: 'status',
// hideInSearch: true,
// width: 100,
// render: (_, record) => {
// return '成功'
// }
// },
{
title: '操作日期',
width: 160,
valueType: 'date',
align: 'center',
dataIndex: 'BEHAVIORRECORD_TIME',
hideInSearch: true,
sorter: true,
render: (_, record) => {
return record?.BEHAVIORRECORD_TIME
}
},
{
title: '操作平台',
width: 160,
dataIndex: 'SOURCE_PLATFORM',
valueType: 'select',
align: 'center',
valueEnum: {
"出行平台": "出行平台",
// "数智化看板": "数智化看板",
// "驿行畅旅": "驿行畅旅",
// "驿付商家版": "驿付商家版",
// "微信公众号": "微信公众号",
// "驿商云客户端": "驿商云客户端",
"彩云驿出行": "彩云驿出行",
},
initialValue: '彩云驿出行'
},
{
title: '操作系统',
width: 150,
hideInSearch: true,
dataIndex: 'OPERATING_SYSTEM',
},
{
title: '浏览器版本',
width: 150,
hideInSearch: true,
dataIndex: 'BROWSER_VERSION',
},
// {
// title: '接口信息',
// width: 150,
// hideInSearch: true,
// dataIndex: 'REQUEST_INFO',
// ellipsis: true,
// },
// {
// title: '调用入参',
// width: 150,
// hideInSearch: true,
// dataIndex: 'BEHAVIORRECORD_DESC',
// ellipsis: true,
// },
// {
// title: '操作',
// width: 120,
// dataIndex: 'options'
// }
]
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 tempTable = document.createElement('table');
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 handleGetTableData = async (paramsObj?: any) => {
let result: any = {}
const res: any = formRef ? formRef?.current?.getFieldsValue() : {}
console.log('resresres', res);
let [start, end] = ['', '']
// let [start, end] = res?.search_date
let params: any = {}
if (res) {
[start, end] = res?.search_date
params = {
BEHAVIORRECORD_TIME: res && res.BEHAVIORRECORD_TIME ? moment(res.BEHAVIORRECORD_TIME._d).format('YYYY-MM-DD') : "",
SOURCE_PLATFORM: res && res.SOURCE_PLATFORM ? res.SOURCE_PLATFORM : "",
BEHAVIORRECORD_TYPE: res && res.BEHAVIORRECORD_TYPE ? res.BEHAVIORRECORD_TYPE : "",
start: start,
end: end,
...res
}
}
setTableLoading(true)
console.log('isComponentisComponent', isComponent);
console.log('paramsparamsparamsparamsparams', params);
const req: any = isComponent ? {
SearchParameter: {
SOURCE_PLATFORMS: '彩云驿出行',
USER_MOBILEPHONE: parentDetail?.MEMBERSHIP_MOBILEPHONE
},
SortStr: 'BEHAVIORRECORD_TIME desc',
PageIndex: paramsObj.current || 1,
PageSize: paramsObj?.pageSize || 999999
} : {
SearchParameter: {
BEHAVIORRECORD_TIME_Start: moment(params?.start).format('YYYY-MM-DD'),
BEHAVIORRECORD_TIME_End: moment(params?.end).format('YYYY-MM-DD'),
SOURCE_PLATFORMS: params?.SOURCE_PLATFORM,
// BEHAVIORRECORD_TYPE: params?.BEHAVIORRECORD_TYPE
},
SortStr: 'BEHAVIORRECORD_TIME desc',
KeyWord: {
Key: 'BEHAVIORRECORD_ROUTNAME,USER_NAME,VISIT_CHANNELS,BEHAVIORRECORD_PREROUT',
Value: params?.searchValue || ''
},
PageIndex: paramsObj.current || 1,
PageSize: paramsObj?.pageSize || 999999
}
console.log('reqreqreqreq', req);
setSearchParams(params)
const data = await handleGetBEHAVIORRECORDList(req)
console.log('dhsjdhasjdhs', data);
setReqDetailList(data.List)
setTableData(data.List)
setTableLoading(false)
result = { data: data.List, success: true, total: data.TotalCount }
// if (isComponent) {
// } else {
// const allReq: any = {
// SearchParameter: {
// BEHAVIORRECORD_TIME_Start: moment(params?.start).format('YYYY-MM-DD'),
// BEHAVIORRECORD_TIME_End: moment(params?.end).format('YYYY-MM-DD'),
// SOURCE_PLATFORMS: params?.SOURCE_PLATFORM,
// // BEHAVIORRECORD_TYPE: params?.BEHAVIORRECORD_TYPE
// },
// SortStr: 'BEHAVIORRECORD_TIME desc',
// KeyWord: {
// Key: 'BEHAVIORRECORD_ROUTNAME,USER_NAME,VISIT_CHANNELS,BEHAVIORRECORD_PREROUT',
// Value: params?.searchValue || ''
// },
// PageIndex: 1,
// PageSize: 999999
// }
// const allData = await handleGetBEHAVIORRECORDList(allReq)
// setReqDetailList(data)
// setTableData(allData)
// setIsFirst(false)
// }
}
// 悬浮框的关闭方法
const handleCloseModal = () => {
setShowDetailDrawer(false)
setCurrentRow(undefined);
}
// useEffect(async () => {
// handleGetTableData()
// }, [])
return (
<div ref={(el) => {
// 打印报表
if (!reqDetailList || reqDetailList.length === 0) return;
setPrintOut(el);
}} >
{
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={columns}
dataSource={reqDetailList}
pagination={false}
expandable={{
defaultExpandAllRows: true
}}
/> : ''
}
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<div style={{
width: '100%',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
actionRef={actionRef}
formRef={formRef}
columns={columns}
bordered
expandable={{
expandRowByClick: true
}}
scroll={{ x: '100%', y: isComponent ? '300px' : 'calc(100vh - 470px)' }}
search={isComponent ? false : { span: 6, defaultCollapsed: false }}
// dataSource={tableData}
// loading={tableLoading}
options={isComponent ? false : {
density: true,
reload: true,
setting: true
}}
request={async (params) => {
console.log('paramsparamsparamsparams', params);
const req: any = isComponent ? {
SearchParameter: {
SOURCE_PLATFORMS: '彩云驿出行',
USER_MOBILEPHONE: parentDetail?.MEMBERSHIP_MOBILEPHONE,
USER_ID: parentDetail?.MEMBERSHIP_ID
},
SortStr: 'BEHAVIORRECORD_TIME desc',
PageIndex: params?.current || 1,
PageSize: params?.pageSize || 999999
} : {
SearchParameter: {
BEHAVIORRECORD_TIME_Start: moment(params?.BEHAVIORRECORD_TIME_Start).format('YYYY-MM-DD'),
BEHAVIORRECORD_TIME_End: moment(params?.BEHAVIORRECORD_TIME_End).format('YYYY-MM-DD'),
SOURCE_PLATFORMS: params?.SOURCE_PLATFORM,
BEHAVIORRECORD_TYPE: params?.BEHAVIORRECORD_TYPE
},
SortStr: 'BEHAVIORRECORD_TIME desc',
KeyWord: {
Key: 'BEHAVIORRECORD_ROUTNAME,USER_NAME,VISIT_CHANNELS,BEHAVIORRECORD_PREROUT',
Value: params?.searchValue || ''
},
PageIndex: 1,
PageSize: 999999
}
setSearchParams(params)
let data = []
if (isComponent) {
data = await handleGetBEHAVIORRECORDList(req)
} else {
if (params?.SOURCE_PLATFORM === '出行平台') {
data = await handleGetBEHAVIORRECORDList(req)
} else if (params?.SOURCE_PLATFORM === '彩云驿出行') {
data = await handleGetBEHAVIORRECORDListCloud(req)
}
}
setCurrentSearchText(params?.searchValue || "")
setReqDetailList(data.List)
setTableData(data.List)
setTableLoading(false)
if (data.List && data.List.length > 0) {
return { data: data.List, success: true, total: data.TotalCount }
}
return { data: [], success: true }
// const data = await handleGetTableData(params)
// return data
// if (!isFirst) {
// handleGetTableData()
// }
// console.log('data', data);
// if (data && data.length > 0) {
// setReqDetailList(data)
// return { data, success: true }
// }
// return { data: [], success: true }
}}
toolbar={{
actions: isComponent ? [] : [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-saleRankReport"
filename={`操作日志列表`}
sheet="sheet1"
/>
</span>,
<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>
]
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
onChange={(pagination, filters, sorter, extra) => {
if (extra.action === 'sort') {
return;
}
}}
/>
</div>
</div>
{/* 会员详情 */}
<MemberDetail showDetailDrawer={showDetailDrawer}
currentRow={currentRow}
handleCloseModal={handleCloseModal}
currentUser={currentUser} />
</div>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(RegistrationRetentionAnalysis);