ylj20011123 4e6fe8ef95 update
2025-07-21 19:52:53 +08:00

841 lines
30 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 } from "umi";
import type { CurrentUser } from "umi";
import type { ConnectState } from "@/models/connect";
import React, { useRef, useState } from "react";
import ProCard from "@ant-design/pro-card";
import { MenuFoldOutlined } from "@ant-design/icons";
import type { FormInstance } from "antd";
import { Button, Col, Drawer, message, Modal, Row, 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 LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
import PageTitleBox from "@/components/PageTitleBox";
import { handeGetMemberShipLicenseList, handleGetCONSUMPTIONRECORDList, handleGetMEMBERGROWTHList, handleGetMEMBERSHIPList, handleGetPOINTRECORDList } from "../service";
import session from "@/utils/session";
import moment from 'moment'
import Draggable from "react-draggable";
import ProForm, { ProFormSelect, ProFormText, ProFormTextArea } from "@ant-design/pro-form";
import memberInfoIcon from '@/assets/detail/memberInfoIcon.png'
import closeIcon from '@/assets/detail/closeIcon.png'
import memberDetailIcon from '@/assets/detail/memberDetailIcon.png'
import AddressDetail from "../MemberAddress/components/addressDetail";
import { handleSetlogSave } from "@/utils/format";
import MemberDetail from "./component/memberDetail";
const memberInfor: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
const downloadBtnRef = useRef<any>()
const draggleRef = React.createRef<any>()
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
const modalRef = useRef<FormInstance>();
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [collapsible, setCollapsible] = useState<boolean>(false)
const [treeView, setTreeView] = useState<any>()
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
let MEMBERSHIPTYPEYNObj = session.get('MEMBERSHIPTYPEYNObj');
let MEMBERSHIP_LEVELList = session.get('MEMBERSHIP_LEVELList');
let COMPANY_STATEObj = session.get('COMPANY_STATEObj');
let COMPANY_STATEList = session.get('COMPANY_STATEList');
let CONSUMPTIONRECORDTYPEObj = session.get('CONSUMPTIONRECORDTYPEObj')
// 树相关的属性和方法
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 [showDetailDrawer, setShowDetailDrawer] = useState<boolean>(false)
// 当前行数据
const [currentRow, setCurrentRow] = useState<any>()
// 弹出框拖动效果
const [bounds, setBounds] = useState<{ left: number, right: number, top: number, bottom: number }>() // 移动的位置
const [disabled, setDraggleDisabled] = useState<boolean>() // 是否拖动
// 当前选中在详情里面要查看的内容
const [selectTab, setSelectTab] = useState<number>(1)
let MEMBERSHIPLEVELYNObj = session.get('MEMBERSHIPLEVELYNObj')
let SCORETYPETree = session.get('SCORETYPETree')
const [columnsStateMap, setColumnsStateMap] = useState<any>({
MEMBERSHIP_CODE: { show: false },
MEMBERSHIP_CARD: { show: false },
MEMBERSHIP_ADDRESS: { show: false },
PLUS_EXPIRYDATE: { show: false },
RECOMMEND_NAME: { show: false },
MEMBERSHIP_DESC: { show: false },
});
const onDraggaleStart = (event, uiData) => {
const { clientWidth, clientHeight } = window.document.documentElement;
const targetRect = draggleRef.current?.getBoundingClientRect();
if (!targetRect) {
return;
}
setBounds({
left: -targetRect.left + uiData.x,
right: clientWidth - (targetRect.right - uiData.x),
top: -targetRect.top + uiData.y,
bottom: clientHeight - (targetRect.bottom - uiData.y),
});
};
const columns: any = [
{
title: "用户昵称",
width: 200,
dataIndex: "MEMBERSHIP_NAME",
ellipsis: true,
align: 'center',
fixed: 'left',
render: (_, record) => {
return <a onClick={() => {
setCurrentRow(record)
setShowDetailDrawer(true)
handleSetlogSave(`查看${record?.MEMBERSHIP_NAME}${record?.MEMBERSHIP_ID}】会员信息`)
}}>
{record?.MEMBERSHIP_NAME || ""}
</a>
},
fieldProps: {
placeholder: "请输入要查询的内容"
}
},
{
title: "会员类型",
width: 120,
dataIndex: "MEMBERSHIP_TYPE",
ellipsis: true,
hideInTable: true,
align: 'center',
valueType: 'select',
valueEnum: {
...MEMBERSHIPTYPEYNObj,
},
// initialValue: "0"
},
{
title: "会员类型",
width: 120,
dataIndex: "MEMBERSHIP_TYPE",
ellipsis: true,
hideInSearch: true,
align: 'center',
valueType: 'select',
valueEnum: {
...MEMBERSHIPTYPEYNObj,
},
},
{
title: "会员编码",
width: 120,
dataIndex: "MEMBERSHIP_CODE",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
{
title: "会员性别",
width: 120,
dataIndex: "MEMBERSHIP_SEX",
hideInSearch: true,
ellipsis: true,
align: 'center',
valueType: 'select',
valueEnum: {
0: '男',
1: '女',
}
},
{
title: "会员生日",
width: 150,
dataIndex: "MEMBERSHIP_BIRTHDAY",
hideInSearch: true,
ellipsis: true,
align: 'center',
render: (_, record) => {
return record?.MEMBERSHIP_BIRTHDAY ? moment(record?.MEMBERSHIP_BIRTHDAY).format('YYYY-MM-DD') : '-'
}
},
{
title: "联系电话",
width: 120,
dataIndex: "MEMBERSHIP_MOBILEPHONE",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
{
title: "证件号码",
width: 150,
dataIndex: "CERTIFICATE_NUMBER",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
{
title: "会员卡号",
width: 120,
dataIndex: "MEMBERSHIP_CARD",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
// {
// title: "会员头像",
// width: 120,
// dataIndex: "MEMBERSHIP_HEADIMAGEURL",
// hideInSearch: true,
// ellipsis: true,
// align: 'center',
// render: (_, record) => {
// return record?.MEMBERSHIP_HEADIMAGEURL ? <a onClick={() => {
// window.open(record?.MEMBERSHIP_HEADIMAGEURL)
// }}>点击查看</a> : ""
// }
// },
{
title: "联系地址",
width: 180,
dataIndex: "MEMBERSHIP_ADDRESS",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
{
title: "车牌号",
width: 150,
dataIndex: "PLATE_NUMBER",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
{
title: "会员等级",
width: 120,
dataIndex: "MEMBERSHIP_LEVEL",
ellipsis: true,
align: 'center',
valueType: 'select',
valueEnum: MEMBERSHIPLEVELYNObj,
// initialValue: "0"
},
{
title: "会员积分",
width: 120,
dataIndex: "MEMBERSHIP_POINT",
hideInSearch: true,
ellipsis: true,
sorter: true,
align: 'center',
},
{
title: "会员成长值",
width: 120,
dataIndex: "MEMBERGROWTH_VALUE",
hideInSearch: true,
ellipsis: true,
sorter: true,
align: 'center',
},
// {
// title: "付费会员",
// width: 120,
// dataIndex: "ISPLUS",
// hideInSearch: true,
// ellipsis: true,
// align: 'center',
// valueType: 'select',
// valueEnum: {
// 0: "否",
// 1: "是"
// }
// },
{
title: "付费有效期",
width: 120,
dataIndex: "PLUS_EXPIRYDATE",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
{
title: "账户余额",
width: 120,
dataIndex: "ACCOUNT_BALANCE",
hideInSearch: true,
ellipsis: true,
sorter: true,
align: 'center',
},
{
title: "推荐人",
width: 120,
dataIndex: "RECOMMEND_NAME",
hideInSearch: true,
ellipsis: true,
align: 'center',
},
// {
// title: "会员状态",
// width: 120,
// dataIndex: "MEMBERSHIP_STATE",
// ellipsis: true,
// align: 'center',
// valueType: 'select',
// valueEnum: COMPANY_STATEObj,
// initialValue: "1000"
// },
{
title: "注册时间",
width: 150,
dataIndex: "ADDTIME",
align: 'center',
hideInSearch: true,
ellipsis: true,
sorter: true,
// sorter: (a, b) => {
// const timeA = new Date(a.ADDTIME).getTime();
// const timeB = new Date(b.ADDTIME).getTime();
// return timeB - timeA; // 倒序排序
// },
// 默认排序配置
defaultSortOrder: 'descend',
render: (_, record) => {
return record?.ADDTIME ? moment(record?.ADDTIME).format('YYYY-MM-DD') : '-'
}
},
{
title: "备注",
width: 120,
dataIndex: "MEMBERSHIP_DESC",
hideInSearch: true,
ellipsis: true,
},
// {
// title: "操作",
// width: 120,
// dataIndex: "options",
// hideInSearch: true,
// align: 'center',
// ellipsis: true,
// fixed: "right",
// render: (_, record) => {
// return <Space>
// <a onClick={() => {
// setCurrentRow(record)
// setShowDetailDrawer(true)
// }}>详情</a>
// </Space>
// }
// }
]
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-memberInfor'); // 给table添加id值与按钮上的table字段对应
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
setShowLoading(false)
downloadBtnRef.current.handleDownload();
setShowExportTable(false)
tempTable.remove() // 防止重复打印一个内容
}
// 消费的列表
let consumptionColumns: any = [
{
title: "服务区名称",
width: 150,
dataIndex: "SERVERPART_NAME",
hideInSearch: true,
ellipsis: true,
align: 'center'
},
{
title: "门店名称",
width: 150,
dataIndex: "SHOPNAME",
hideInSearch: true,
ellipsis: true,
align: 'center'
},
{
title: "消费类型",
width: 120,
dataIndex: "CONSUMPTIONRECORD_TYPE",
hideInSearch: true,
ellipsis: true,
valueType: 'select',
valueEnum: CONSUMPTIONRECORDTYPEObj,
align: 'center'
},
{
title: "订单金额",
width: 120,
dataIndex: "CONSUME_AMOUNT",
hideInSearch: true,
valueType: 'digit',
ellipsis: true,
align: 'center'
},
{
title: "消费金额",
width: 120,
dataIndex: "CONSUME_PRICE",
hideInSearch: true,
valueType: 'digit',
ellipsis: true,
align: 'center'
},
{
title: "消费积分",
width: 120,
dataIndex: "CONSUME_SCORE",
hideInSearch: true,
valueType: 'digit',
ellipsis: true,
align: 'center'
},
{
title: "实付金额",
width: 120,
dataIndex: "PAY_AMOUNT",
hideInSearch: true,
valueType: 'digit',
ellipsis: true,
align: 'center'
},
{
title: "优惠金额",
width: 150,
dataIndex: "COUPON_AMOUNT",
hideInSearch: true,
ellipsis: true,
align: 'center'
},
{
title: "消费时间 ",
width: 150,
dataIndex: "CONSUMPTIONRECORD_DATE",
hideInSearch: true,
align: 'center',
render: (_, record) => {
return record?.CONSUMPTIONRECORD_DATE ? moment(record?.CONSUMPTIONRECORD_DATE).format('YYYY-MM-DD HH:mm:ss') : '-'
}
},
]
// 积分的列表
let PointColumns: any = [
{
title: "服务区名称",
width: 150,
dataIndex: "SERVERPART_NAME",
hideInSearch: true,
ellipsis: true,
align: 'center'
},
{
title: "门店名称",
width: 150,
dataIndex: "SHOPNAME",
hideInSearch: true,
ellipsis: true,
align: 'center'
},
{
title: "积分方式",
width: 120,
dataIndex: "POINT_TYPE",
hideInSearch: true,
ellipsis: true,
align: 'center',
valueType: 'select',
valueEnum: {
"1": "累计",
"-1": "消耗"
},
},
{
title: "积分来源",
width: 120,
dataIndex: "POINT_SOURCE",
hideInSearch: true,
ellipsis: true,
valueType: 'treeSelect',
align: 'center',
request: () => {
return SCORETYPETree
}
},
{
title: "本次积分",
width: 120,
dataIndex: "CURRENT_POINT",
hideInSearch: true,
ellipsis: true,
align: 'center',
valueType: "digit"
},
{
title: "累计积分",
width: 120,
dataIndex: "MEMBERSHIP_POINT",
hideInSearch: true,
ellipsis: true,
align: 'center',
valueType: "digit"
},
{
title: "获取时间",
width: 120,
dataIndex: "CREATE_DATE",
hideInSearch: true,
align: 'center',
ellipsis: true,
},
]
// 成长值的列表
let GrowthValueColumns: any = [
{
title: "服务区名称",
width: 150,
dataIndex: "SERVERPART_NAME",
hideInSearch: true,
align: 'center',
ellipsis: true,
},
{
title: "门店名称",
width: 150,
dataIndex: "SHOPNAME",
hideInSearch: true,
align: 'center',
ellipsis: true,
},
{
title: "累计成长值",
width: 120,
dataIndex: "MEMBERSHIP_GROWTH",
hideInSearch: true,
ellipsis: true,
align: 'center',
valueType: 'digit'
},
{
title: "本次成长值",
width: 120,
dataIndex: "CURRENT_GROWTH",
hideInSearch: true,
ellipsis: true,
align: 'center',
valueType: 'digit'
},
{
title: "成长来源",
width: 120,
dataIndex: "GROWTH_SOURCE",
hideInSearch: true,
ellipsis: true,
valueType: 'treeSelect',
align: 'center',
request: () => {
return SCORETYPETree
}
},
{
title: "成长方式",
width: 120,
dataIndex: "GROWTH_TYPE",
hideInSearch: true,
align: 'center',
ellipsis: true,
valueType: 'select',
valueEnum: {
"1": "积累",
"-1": "消耗",
}
},
{
title: "操作时间",
width: 120,
dataIndex: "OPERATE_DATE",
align: 'center',
hideInSearch: true,
render: (_, record) => {
return record?.OPERATE_DATE ? moment(record?.OPERATE_DATE).format('YYYY-MM-DD') : "-"
}
},
]
// 悬浮框的关闭方法
const handleCloseModal = () => {
setShowDetailDrawer(false)
setCurrentRow(undefined);
}
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: 'calc(100vh - 450px)' }}
headerTitle={<PageTitleBox props={props} />}
search={{ span: 6 }}
request={async (params, sorter) => {
console.log('paramsparamsparams', params);
const sortstr = Object.keys(sorter).map(n => {
const value = sorter[n]
return value ? `${n} ${value.replace('end', '')}` : ''
})
const req: any = {
SearchParameter: {
PROVINCE_CODE: currentUser?.ProvinceCode || "",
OWNERUNIT_ID: 911,
MEMBERSHIP_TYPE: params?.MEMBERSHIP_TYPE === "0" ? "0" : params?.MEMBERSHIP_TYPE,
MEMBERSHIP_LEVEL: params?.MEMBERSHIP_LEVEL === "0" ? "" : params?.MEMBERSHIP_LEVEL,
MEMBERSHIP_STATE: params?.MEMBERSHIP_STATE
},
keyWord: {
// PLATE_NUMBER
Key: "MEMBERSHIP_NAME,MEMBERSHIP_MOBILEPHONE,CERTIFICATE_NUMBER,MEMBERSHIP_CARD,MEMBERSHIP_ADDRESS",
value: params?.MEMBERSHIP_NAME || ""
},
PageIndex: params.current || 1,
PageSize: params?.pageSize,
sortstr: sortstr.length ? sortstr.toString() : "",
}
setSearchParams(params)
handleSetlogSave(`查看了会员账户管理列表`)
const data = await handleGetMEMBERSHIPList(req)
// 可以拿到车牌号的用户信息列表
// const data = await handeGetMemberShipLicenseList(req)
console.log('datadatadatadatadata', data);
if (data.List && data.List.length > 0) {
return { data: data.List, success: true, total: data.TotalCount }
}
return { data: [], success: true }
// const allReq: any = {
// SearchParameter: {
// PROVINCE_CODE: currentUser?.ProvinceCode || ""
// },
// PageIndex: 1,
// PageSize: 99999
// }
// const allData = await handleGetMEMBERSHIPList(allReq)
// setTableData(allData)
}}
toolbar={{
actions: []
}}
pagination={{
defaultPageSize: 20,
showTotal: (total) => `${total} 条记录`
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
/>
</div>
</div>
{/* 会员详情 */}
<MemberDetail showDetailDrawer={showDetailDrawer}
currentRow={currentRow}
handleCloseModal={handleCloseModal}
currentUser={currentUser} />
{/* <Drawer
width={'80%'}
open={showDetailDrawer}
closable={false}
onClose={() => {
setShowDetailDrawer(false);
setCurrentRow(null)
}}
title={`${MEMBERSHIP_LEVELObj ? MEMBERSHIP_LEVELObj[currentRow?.MEMBERSHIP_LEVEL] ? MEMBERSHIP_LEVELObj[currentRow?.MEMBERSHIP_LEVEL] : "" : ''}${currentRow?.MEMBERSHIP_NAME}`}
bodyStyle={{ padding: 0 }}
footer={
<div style={{ width: '100%', display: 'flex', justifyContent: 'flex-end' }}>
</div>
}
>
<ProTable
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>消费记录</span>}
search={false}
options={false}
bordered
columns={consumptionColumns}
scroll={{ x: '100%', y: '450px' }}
request={async () => {
const req: any = {
SearchParameter: {
MEMBERSHIP_IDS: currentRow?.MEMBERSHIP_ID,
PROVINCE_CODE: currentUser?.ProvinceCode || "",
OWNERUNIT_ID: 911
},
PageIndex: 1,
PageSize: 20
}
const data = await handleGetCONSUMPTIONRECORDList(req)
console.log('11111', data);
if (data.List && data.List.length > 0) {
return { data: data.List, success: true, total: data.TotalCount }
}
return { data: [], success: true }
}}
/>
<ProTable
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>积分记录</span>}
search={false}
options={false}
bordered
scroll={{ x: '100%', y: '450px' }}
columns={PointColumns}
request={async () => {
const req: any = {
SearchParameter: {
MEMBERSHIP_IDS: currentRow?.MEMBERSHIP_ID,
PROVINCE_CODE: currentUser?.ProvinceCode || "",
OWNERUNIT_ID: 911
},
PageIndex: 1,
PageSize: 20
}
const data = await handleGetPOINTRECORDList(req)
console.log('22222', data);
if (data.List && data.List.length > 0) {
return { data: data.List, success: true, total: data.TotalCount }
}
return { data: [], success: true }
}}
/>
<ProTable
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>成长值记录</span>}
search={false}
options={false}
bordered
scroll={{ x: '100%', y: '450px' }}
columns={GrowthValueColumns}
request={async () => {
const req: any = {
SearchParameter: {
MEMBERSHIP_IDS: currentRow?.MEMBERSHIP_ID,
PROVINCE_CODE: currentUser?.ProvinceCode || "",
OWNERUNIT_ID: 911
},
PageIndex: 1,
PageSize: 20
}
const data = await handleGetMEMBERGROWTHList(req)
console.log('33333', data);
if (data.List && data.List.length > 0) {
return { data: data.List, success: true, total: data.TotalCount }
}
return { data: [], success: true }
}}
/>
</Drawer> */}
</div>
)
}
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(memberInfor);