update
This commit is contained in:
parent
018ce67a4d
commit
4e6fe8ef95
1
.vercel/project.json
Normal file
1
.vercel/project.json
Normal file
@ -0,0 +1 @@
|
||||
{"projectName":"trae_cloud-platform_lsb2"}
|
||||
@ -247,6 +247,11 @@ export default [
|
||||
name: 'reports/serverpartOfComparison',
|
||||
component: './reports/comparisonOfServerpart/index',
|
||||
},
|
||||
{
|
||||
path: 'reports/warningQueryContract',
|
||||
name: 'reports/warningQueryContract',
|
||||
component: './reports/contractWarningQuery/index',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
999
src/pages/reports/contractWarningQuery/index.tsx
Normal file
999
src/pages/reports/contractWarningQuery/index.tsx
Normal file
@ -0,0 +1,999 @@
|
||||
// 合同预警查询
|
||||
import moment from "moment";
|
||||
import numeral from 'numeral';
|
||||
import { connect } from "umi";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { PageContainer } from "@ant-design/pro-layout";
|
||||
import ProTable from "@ant-design/pro-table";
|
||||
import { FormInstance, Spin, Tooltip } from "antd";
|
||||
import { Col, Row } from "antd";
|
||||
import { Button, DatePicker, Drawer, message, Modal, Popconfirm, Select, Typography } from "antd";
|
||||
import { ExclamationCircleOutlined, FileSearchOutlined, PlusOutlined } from "@ant-design/icons";
|
||||
|
||||
import type { CurrentUser } from '@/models/user';
|
||||
import type { ConnectState } from "@/models/connect";
|
||||
import type { ActionType, ProColumns } from "@ant-design/pro-table";
|
||||
import { exportExcel, getBase64 } from '@/utils/utils';
|
||||
import ProForm, { ProFormDatePicker, ProFormSelect, ProFormTextArea, ProFormUploadButton } from "@ant-design/pro-form";
|
||||
import { getProjectList } from "@/pages/BussinessProject/service";
|
||||
import useRequest from "@ahooksjs/use-request";
|
||||
import { deletePicture, uploadPicture } from "@/services/picture";
|
||||
import type { UploadFile } from "antd/es/upload/interface";
|
||||
import fileIcon from '@/assets/detail/fileIcon.svg'
|
||||
import session from "@/utils/session";
|
||||
import PageTitleBox from "@/components/PageTitleBox";
|
||||
import { delCompact, getList, handleContractSupple } from "@/pages/contract/service";
|
||||
import { ContractListModel } from "@/pages/contract/data";
|
||||
import { contractType } from "@/pages/contract/emun";
|
||||
import ContractDetail from "@/pages/contract/components/detail";
|
||||
import ContractEdit from "@/pages/contract/components/editor";
|
||||
import ReactHTMLTableToExcel from "react-html-table-to-excel";
|
||||
|
||||
// 删除数据
|
||||
const handelDelete = async (registerCompactId: number) => {
|
||||
const hide = message.loading('正在删除...');
|
||||
try {
|
||||
const result = await delCompact(registerCompactId);
|
||||
|
||||
hide();
|
||||
if (result.Result_Code !== 100) {
|
||||
message.error(`${result.Result_Desc}`);
|
||||
return false;
|
||||
}
|
||||
message.success('删除成功!');
|
||||
return true;
|
||||
} catch (error) {
|
||||
hide();
|
||||
message.error('删除失败');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 上传附件
|
||||
const customUploadRequest = async (fileList: UploadFile[], tableId: string) => {
|
||||
if (!fileList.length) {
|
||||
message.error("您上传的附件不存在.")
|
||||
return false
|
||||
}
|
||||
const formData = new FormData();
|
||||
fileList.forEach(file => {
|
||||
formData.append('files[]', file);
|
||||
});
|
||||
formData.append('TableType', '1115');
|
||||
formData.append('TableId', tableId);
|
||||
const success = await uploadPicture(formData)
|
||||
if (success) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// const contractWarningQuery: React.FC<{ currentUser?: CurrentUser }> = ({ currentUser }) => {
|
||||
const contractWarningQuery: React.FC<{ currentUser: CurrentUser }> = (props) => {
|
||||
const { currentUser } = props
|
||||
const downloadBtnRef = useRef<any>()
|
||||
// props
|
||||
|
||||
const [currentRow, setCurrentRow] = useState<ContractListModel | undefined>(undefined)
|
||||
const [showDetail, setShowDetail] = useState<number>(0)
|
||||
const actionRef = useRef<ActionType>()
|
||||
const [searchParams, setSearchParams] = useState<any>();
|
||||
const [showBtn, setShowBtn] = useState<boolean>(false)
|
||||
const editorRef = useRef<ActionType>()
|
||||
const modalRef = useRef<FormInstance>()
|
||||
// 显示附属合同的悬浮框
|
||||
const [showModal, setShowModal] = useState<boolean>(false)
|
||||
// 悬浮弹出框选中的内容
|
||||
const [contract, setContract] = useState<any>()
|
||||
// 悬浮框表格数据
|
||||
const [modalTableData, setModalTableData] = useState<any>()
|
||||
// 结算模式枚举对象
|
||||
const [modesObj, setModesObj] = useState<any>()
|
||||
// 切換日期的时间
|
||||
const [changeDayDate, setChangeDayDate] = useState<any>()
|
||||
// modal的loading
|
||||
const [modalLoading, setModalLoading] = useState<any>(false)
|
||||
// 拿到结算模式列表
|
||||
const SETTLEMENT_MODESList = session.get("SETTLEMENT_MODESList")
|
||||
const SETTLEMENT_MODESObj = session.get("SETTLEMENT_MODESObj")
|
||||
// 合同类型对象
|
||||
const compactType = session.get("COMPACT_CHARACTERObj")
|
||||
// 合同类型子项
|
||||
const COMPACT_DETAILS = session.get("COMPACT_DETAILSObj")
|
||||
// 右上角选择的类型
|
||||
const [BIGCOMPACT_DETAILS, SETBIGCOMPACT_DETAILS] = useState<any>()
|
||||
// 退场时间
|
||||
const [exitTime, setExitTime] = useState<any>()
|
||||
// 子组件详情数据
|
||||
const [childrenData, setChildrenData] = useState<any>()
|
||||
// 是否显示新增附属合同
|
||||
const [addSubsidiary, setAddSubsidiary] = useState<boolean>(false)
|
||||
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
|
||||
// 查询的条件
|
||||
// 拿到子组件详情
|
||||
const handleGetChildrenData = (obj: any) => {
|
||||
if (obj.COMPACT_DETAILS === 1000) {
|
||||
setAddSubsidiary(true)
|
||||
} else {
|
||||
setAddSubsidiary(false)
|
||||
}
|
||||
setChildrenData(obj)
|
||||
}
|
||||
// 拿到改变的合同类型子项
|
||||
const handleGetContractChild = (obj: any) => {
|
||||
if (obj === 1000) {
|
||||
setAddSubsidiary(true)
|
||||
} else {
|
||||
setAddSubsidiary(false)
|
||||
}
|
||||
}
|
||||
// 附件文件
|
||||
const [fileList, setFileList] = useState<UploadFile[]>([]) // 需要上传的附件图片列表
|
||||
const [priviewImage, setPriviewImage] = useState<string>(); // 预览的文件地址
|
||||
const [COMPACTLIST, setCOMPACTLIST] = useState<any>()
|
||||
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
|
||||
const { loading: COMPACTLoading, data: COMPACTLISTS } = useRequest(async () => {
|
||||
const options = session.get("COMPACT_DETAILSList")
|
||||
if (options && options.length > 0) {
|
||||
options.forEach((item: any) => {
|
||||
if (item.value !== 2002 && item.value !== 3000) {
|
||||
item.disabled = true
|
||||
item.label = <Tooltip title={'请跳转到关联合同内添加!'}>
|
||||
<span style={{ color: 'rgba(0,0,0,0.25)' }}>{item.label}</span>
|
||||
</Tooltip>
|
||||
}
|
||||
})
|
||||
}
|
||||
setCOMPACTLIST(options)
|
||||
})
|
||||
// 导出的加载效果
|
||||
const [showLoading, setShowLoading] = useState<boolean>(false)
|
||||
// 是否显示打印的表格
|
||||
const [showExportTable, setShowExportTable] = useState<boolean>(false)
|
||||
const [columnsStateMap, setColumnsStateMap] = useState<any>({
|
||||
THREEPART_LINKMAN: {
|
||||
show: false,
|
||||
}
|
||||
});
|
||||
const columns: ProColumns<ContractListModel>[] = [
|
||||
// {
|
||||
// title: '所属服务区',
|
||||
// dataIndex: 'SERVERPART_ID',
|
||||
// valueType: 'select',
|
||||
// request: async () => {
|
||||
// return await getServerpartOption();
|
||||
// }
|
||||
// },
|
||||
{
|
||||
title: '查询合同',
|
||||
dataIndex: 'searchKey',
|
||||
hideInTable: true,
|
||||
hideInDescriptions: true,
|
||||
fieldProps: {
|
||||
placeholder: "请输入合同编号/名称/乙方"
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
title: '合同编号',
|
||||
dataIndex: 'COMPACT_CODE',
|
||||
hideInSearch: true,
|
||||
hideInTable: true,
|
||||
},
|
||||
{
|
||||
title: '合同名称',
|
||||
dataIndex: 'COMPACT_NAME',
|
||||
// ellipsis: true,
|
||||
hideInSearch: true,
|
||||
hideInDescriptions: true,
|
||||
// width:'25%',
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
return <a onClick={() => {
|
||||
setCurrentRow(record)
|
||||
setShowDetail(1)
|
||||
}}>{record.COMPACT_NAME}</a>
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '经营模式',
|
||||
dataIndex: 'BUSINESS_TYPE',
|
||||
valueType: 'select',
|
||||
valueEnum: contractType,
|
||||
width: 110,
|
||||
align: "center",
|
||||
// hideInSearch: true,
|
||||
},
|
||||
|
||||
{
|
||||
title: '合同金额(万元)',
|
||||
dataIndex: 'COMPACT_AMOUNT',
|
||||
hideInSearch: true,
|
||||
align: 'right',
|
||||
width: 130,
|
||||
sorter: true,
|
||||
render: (_) => {
|
||||
return <span style={{ paddingRight: 16 }}>{numeral(_).format('0,0.00')}</span>
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '乙方',
|
||||
dataIndex: 'SECONDPART_NAME',
|
||||
hideInDescriptions: true,
|
||||
hideInSearch: true,
|
||||
sorter: true,
|
||||
width: 130,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '丙方联系人',
|
||||
dataIndex: 'THREEPART_LINKMAN',
|
||||
hideInDescriptions: true,
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
width: 130,
|
||||
sorter: true,
|
||||
},
|
||||
{
|
||||
title: '合同主体',
|
||||
dataIndex: 'SERVERPART_NAME',
|
||||
ellipsis: true,
|
||||
hideInDescriptions: true,
|
||||
hideInSearch: true,
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '关联合同',
|
||||
dataIndex: 'RELATE_COMPACT',
|
||||
hideInDescriptions: true,
|
||||
hideInSearch: true,
|
||||
width: 100,
|
||||
align: 'center',
|
||||
render: (_, record) => {
|
||||
return <span>{record?.RELATE_COMPACT > 0 ? '是' : ''}</span>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '附件',
|
||||
dataIndex: 'ATTACHMENT_STATE',
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
width: 60,
|
||||
render: (_, record) => {
|
||||
return <div style={{ width: '100%', display: 'flex', justifyContent: 'center' }}>
|
||||
{
|
||||
record?.ATTACHMENT_STATE === 1000 ?
|
||||
<img style={{ width: '15px', height: '15px' }} src={fileIcon} /> : ''
|
||||
}
|
||||
</div>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '到期日期',
|
||||
dataIndex: 'dateRange',
|
||||
valueType: "dateRange",
|
||||
hideInTable: true,
|
||||
hideInDescriptions: true,
|
||||
fieldProps: {
|
||||
ranges: Number(moment().format('MM')) > 6 ? {
|
||||
"一月内": [moment(), moment().add(1, 'months')],
|
||||
"三月内": [moment(), moment().add(3, 'months')],
|
||||
"六月内": [moment(), moment().add(6, 'months')],
|
||||
"截止年底": [moment(), moment().endOf('y')],
|
||||
"明年上半年": [moment(), moment(`${moment(moment().add(1, 'y')).format('YYYY')}-06-30`)],
|
||||
|
||||
|
||||
} : {
|
||||
"一月内": [moment(), moment().add(1, 'months')],
|
||||
"三月内": [moment(), moment().add(3, 'months')],
|
||||
"六月内": [moment(), moment().add(6, 'months')],
|
||||
"截止上半年": [moment(), moment(`${moment().format('YYYY')}-06-30`)],
|
||||
"下半年": [moment(), moment(moment().endOf('y'))],
|
||||
}
|
||||
},
|
||||
initialValue: [moment(), moment().add(1, 'months')],
|
||||
},
|
||||
{
|
||||
title: '合同状态',
|
||||
dataIndex: 'COMPACT_STATE',
|
||||
valueType: 'select',
|
||||
initialValue: '1000',
|
||||
// hideInSearch: true,
|
||||
hideInTable: true,
|
||||
valueEnum: { 0: { text: '无效', status: 'error' }, 1: { text: '待补充', status: 'process' }, 1000: { text: '有效', status: 'success' } },
|
||||
},
|
||||
{
|
||||
title: '合同类型',
|
||||
dataIndex: 'COMPACT_TYPE',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
width: 130,
|
||||
valueEnum: compactType,
|
||||
ellipsis: true,
|
||||
initialValue: "340001"
|
||||
},
|
||||
{
|
||||
title: '类型子项',
|
||||
dataIndex: 'COMPACT_DETAILS',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
width: 130,
|
||||
valueEnum: COMPACT_DETAILS,
|
||||
ellipsis: true,
|
||||
initialValue: "1000"
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'COMPACT_STARTDATE',
|
||||
valueType: 'date',
|
||||
sorter: true,
|
||||
width: 110
|
||||
},
|
||||
{
|
||||
title: '结束日期',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'COMPACT_ENDDATE',
|
||||
valueType: 'date',
|
||||
sorter: true,
|
||||
width: 110
|
||||
},
|
||||
{
|
||||
title: '撤场时间',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'CLOSED_DATE',
|
||||
valueType: 'date',
|
||||
sorter: true,
|
||||
width: 110
|
||||
},
|
||||
{
|
||||
title: '操作人',
|
||||
dataIndex: 'STAFF_NAME',
|
||||
hideInSearch: true,
|
||||
hideInTable: true
|
||||
},
|
||||
{
|
||||
dataIndex: 'OPERATE_DATE',
|
||||
title: '更新时间',
|
||||
valueType: 'fromNow',
|
||||
hideInTable: true,
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
// 如果是商户账号,则只能查看合同信息,不能做编辑、删除操作
|
||||
title: '操作',
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
hideInDescriptions: true,
|
||||
hideInSearch: true,
|
||||
hideInTable: currentUser?.UserPattern === 2000,
|
||||
width: 120,
|
||||
render: (_, record) => {
|
||||
return [
|
||||
// <a onClick={() => { history.push(`/contract/detail/${record.REGISTERCOMPACT_ID}`) }}>查看</a>,
|
||||
<a onClick={() => {
|
||||
setCurrentRow(record)
|
||||
setShowDetail(2)
|
||||
// history.push(`contract/edit/${record.REGISTERCOMPACT_ID}`)
|
||||
}}>编辑</a>,
|
||||
<Popconfirm
|
||||
title="确认删除该合同记录吗?"
|
||||
onConfirm={async () => {
|
||||
const sucesse = await handelDelete(record.REGISTERCOMPACT_ID);
|
||||
if (sucesse && actionRef.current) {
|
||||
actionRef.current.reload();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<a>删除</a>
|
||||
</Popconfirm>
|
||||
]
|
||||
}
|
||||
}
|
||||
];
|
||||
// 附属合同的表格字段
|
||||
const modalColumns: any = [
|
||||
{
|
||||
dataIndex: 'BUSINESSPROJECT_NAME',
|
||||
title: '项目名称',
|
||||
align: 'center',
|
||||
ellipsis: true,
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
dataIndex: 'SERVERPARTSHOP_NAME',
|
||||
title: '门店名称',
|
||||
align: 'center',
|
||||
hideInSearch: true,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '合同金额',
|
||||
dataIndex: 'GUARANTEE_PRICE',
|
||||
hideInSearch: true,
|
||||
width: 130,
|
||||
align: "center",
|
||||
render: (_) => {
|
||||
return <div style={{ width: 100, textAlign: "right" }}>{_}</div>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'PROJECT_STARTDATE',
|
||||
valueType: 'date',
|
||||
align: 'center',
|
||||
sorter: true,
|
||||
width: 110
|
||||
},
|
||||
{
|
||||
title: '结束日期',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'PROJECT_ENDDATE',
|
||||
valueType: 'date',
|
||||
align: 'center',
|
||||
sorter: true,
|
||||
width: 110
|
||||
},
|
||||
{
|
||||
title: '结算模式',
|
||||
width: 110,
|
||||
dataIndex: 'SETTLEMENT_MODES',
|
||||
align: 'center',
|
||||
valueEnum: SETTLEMENT_MODESObj
|
||||
},
|
||||
{
|
||||
title: '切换结算模式',
|
||||
width: 140,
|
||||
dataIndex: 'SWITCH_MODES',
|
||||
align: 'center',
|
||||
render: (_, record) => {
|
||||
return <Select
|
||||
style={{ width: '135px' }}
|
||||
options={(SETTLEMENT_MODESList?.filter(d => d.value !== record.SETTLEMENT_MODES) || []).map((item) => ({
|
||||
value: item.value,
|
||||
label: item.label,
|
||||
}))}
|
||||
value={record.SWITCH_MODES}
|
||||
onChange={(e: any) => {
|
||||
const list = JSON.parse(JSON.stringify(modalTableData))
|
||||
list.forEach((item: any) => {
|
||||
if (item.BUSINESSPROJECT_ID === record.BUSINESSPROJECT_ID) {
|
||||
item.SWITCH_MODES = e
|
||||
}
|
||||
})
|
||||
setModalTableData(list)
|
||||
}}
|
||||
></Select>
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '切换日期',
|
||||
width: 130,
|
||||
dataIndex: 'SwitchDate',
|
||||
align: 'center',
|
||||
render: (_, record) => {
|
||||
return <DatePicker value={record.SwitchDate} onChange={(e: any) => {
|
||||
const list = JSON.parse(JSON.stringify(modalTableData))
|
||||
list.forEach((item: any) => {
|
||||
if (item.BUSINESSPROJECT_ID === record.BUSINESSPROJECT_ID) {
|
||||
item.SwitchDate = moment(e._d)
|
||||
}
|
||||
})
|
||||
setModalTableData(list)
|
||||
}} />
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '退场日期',
|
||||
hideInSearch: true,
|
||||
dataIndex: 'exitTime',
|
||||
valueType: 'date',
|
||||
sorter: true,
|
||||
width: 140,
|
||||
render: (_, record) => {
|
||||
return <DatePicker value={record.exitTime} onChange={(e: any) => {
|
||||
|
||||
const list = JSON.parse(JSON.stringify(modalTableData))
|
||||
|
||||
list.forEach((item: any) => {
|
||||
if (item.BUSINESSPROJECT_ID === record.BUSINESSPROJECT_ID) {
|
||||
if (e) {
|
||||
item.exitTime = moment(e._d)
|
||||
} else {
|
||||
item.exitTime = undefined
|
||||
}
|
||||
}
|
||||
})
|
||||
setModalTableData(list)
|
||||
}} />
|
||||
}
|
||||
},
|
||||
]
|
||||
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() // 防止重复打印一个内容
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<PageContainer header={{
|
||||
title: '',
|
||||
breadcrumb: {},
|
||||
}}>
|
||||
|
||||
{
|
||||
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.slice(0, columns.length - 1)}
|
||||
dataSource={reqDetailList}
|
||||
pagination={false}
|
||||
expandable={{
|
||||
defaultExpandAllRows: true
|
||||
}}
|
||||
/> : ''
|
||||
}
|
||||
</div>
|
||||
|
||||
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
|
||||
|
||||
|
||||
<ProTable<ContractListModel>
|
||||
headerTitle={<PageTitleBox props={props} />}
|
||||
rowKey="REGISTERCOMPACT_ID"
|
||||
request={async (params, sorter) => {
|
||||
const sortstr = Object.keys(sorter).map(n => {
|
||||
const value = sorter[n]
|
||||
return value ? `${n} ${value.replace('end', '')}` : ''
|
||||
})
|
||||
const [start, end] = params?.dateRange || ['', '']
|
||||
const searchWholeParams = {
|
||||
searchParameter: {
|
||||
...params,
|
||||
COMPACT_STARTDATE: start,
|
||||
COMPACT_ENDDATE: end,
|
||||
Due_StartDate: start,
|
||||
Due_EndDate: end,
|
||||
// COMPACT_TYPE: "340001",
|
||||
// COMPACT_DETAILS: "1000"
|
||||
},
|
||||
sortstr: sortstr.length ? sortstr.toString() : "",
|
||||
keyWord: params.searchKey ? { key: "COMPACT_CODE,SECONDPART_NAME,COMPACT_NAME", value: params.searchKey } : null, // 关键词查询
|
||||
pagesize: 999999
|
||||
}
|
||||
const list = await getList(searchWholeParams)
|
||||
console.log('listlistlist', list);
|
||||
setReqDetailList(list.data)
|
||||
setSearchParams(searchWholeParams);
|
||||
return list
|
||||
}}
|
||||
actionRef={actionRef}
|
||||
search={{ span: 6 }}
|
||||
columns={columns}
|
||||
toolbar={{
|
||||
// 如果是商户账号,则只能查看合同信息,不能做新增操作
|
||||
actions: currentUser?.UserPattern !== 2000 ? [
|
||||
<span style={{ visibility: 'hidden' }}>
|
||||
<ReactHTMLTableToExcel
|
||||
buttonText={'导出excel'}
|
||||
ref={downloadBtnRef}
|
||||
table="table-to-xls-saleRankReport"
|
||||
filename={`合同预警${searchParams?.searchParameter?.Due_StartDate} - ${searchParams?.searchParameter?.Due_EndDate}`}
|
||||
sheet="sheet1"
|
||||
/>
|
||||
</span>,
|
||||
<Typography.Text type="secondary">单位:万元</Typography.Text>,
|
||||
<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
|
||||
key="new"
|
||||
icon={<PlusOutlined />}
|
||||
type="primary"
|
||||
|
||||
onClick={() => {
|
||||
setShowDetail(2)
|
||||
// history.push('contract/create')
|
||||
}}
|
||||
>
|
||||
合同
|
||||
</Button>,
|
||||
] : [],
|
||||
}}
|
||||
columnsState={{
|
||||
value: columnsStateMap,
|
||||
onChange: setColumnsStateMap,
|
||||
}}
|
||||
pagination={{ defaultPageSize: 10 }}
|
||||
/>
|
||||
<Drawer
|
||||
className={showDetail === 1 ? "contract-drawer" : "contract-detail-drawer"}
|
||||
width="73%"
|
||||
visible={showDetail !== 0}
|
||||
onClose={() => {
|
||||
setCurrentRow(undefined);
|
||||
setShowDetail(0);
|
||||
SETBIGCOMPACT_DETAILS(undefined)
|
||||
}}
|
||||
destroyOnClose
|
||||
title={showDetail === 2 ?
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div className="card-title" style={{ fontWeight: 700 }}>{!currentRow ? "新增合同" : currentRow?.COMPACT_NAME}</div>
|
||||
{
|
||||
currentRow && addSubsidiary ?
|
||||
<ProForm
|
||||
style={{ width: '350px' }}
|
||||
className={'subsidiaryBox'}
|
||||
layout={'horizontal'}
|
||||
submitter={{
|
||||
render: (_, record) => {
|
||||
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ProFormSelect
|
||||
name="BIGCOMPACT_DETAILS"
|
||||
label="新增附属合同"
|
||||
placeholder="请选择合同类型"
|
||||
// rules={[
|
||||
// {
|
||||
// required: true,
|
||||
// message: '请选择合同类型',
|
||||
// },
|
||||
// ]}
|
||||
// request={async () => {
|
||||
// const options = session.get("COMPACT_DETAILSList")
|
||||
// return options;
|
||||
// }}
|
||||
options={COMPACTLIST}
|
||||
addonAfter={showBtn ?
|
||||
<Button type="primary" icon={<FileSearchOutlined />}
|
||||
onClick={() => {
|
||||
setShowModal(true)
|
||||
}}>选择</Button> :
|
||||
false
|
||||
}
|
||||
fieldProps={{
|
||||
onChange: (e: any) => {
|
||||
SETBIGCOMPACT_DETAILS(e)
|
||||
if (e === 3000 || e === 2002) {
|
||||
setShowBtn(true)
|
||||
} else {
|
||||
setShowBtn(false)
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ProForm> : ''
|
||||
}
|
||||
</div>
|
||||
: ""}
|
||||
closable={false}
|
||||
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
|
||||
>
|
||||
{/* 编辑/查看合同 */}
|
||||
{showDetail !== 0 && currentRow !== undefined && (showDetail === 1 ?
|
||||
<ContractDetail contractId={currentRow?.REGISTERCOMPACT_ID} currentRow={currentRow} clickedId={[currentRow?.REGISTERCOMPACT_ID]}></ContractDetail> :
|
||||
<ContractEdit handleGetChildrenData={handleGetChildrenData} handleGetContractChild={handleGetContractChild} currentUser={currentUser} onRef={editorRef} contractId={currentRow?.REGISTERCOMPACT_ID} actionRef={actionRef} setShowDetail={setShowDetail}></ContractEdit>)
|
||||
}
|
||||
{/* 新增合同 */}
|
||||
{
|
||||
!currentRow && showDetail !== 0 && <ContractEdit actionRef={actionRef} setShowDetail={setShowDetail} showType={'add'} />
|
||||
}
|
||||
</Drawer>
|
||||
|
||||
<Modal
|
||||
title="附属合同"
|
||||
width={1400}
|
||||
style={{ height: '500px' }}
|
||||
destroyOnClose
|
||||
open={showModal}
|
||||
confirmLoading={modalLoading}
|
||||
onOk={() => {
|
||||
modalRef.current?.validateFields().then(async (res) => {
|
||||
if (res) {
|
||||
setModalLoading(true)
|
||||
if (contract && contract.length > 0) {
|
||||
|
||||
} else {
|
||||
message.error('请先选择附属合同')
|
||||
setModalLoading(false)
|
||||
return
|
||||
}
|
||||
const list: any = []
|
||||
const completeList: any = []
|
||||
modalTableData.forEach((item: any) => {
|
||||
if (contract.indexOf(item.BUSINESSPROJECT_ID) !== -1) {
|
||||
list.push({ label: item.BUSINESSPROJECT_ID, value: item.SWITCH_MODES })
|
||||
completeList.push(item)
|
||||
}
|
||||
})
|
||||
const descValue: string = modalRef.current?.getFieldsValue()
|
||||
let req
|
||||
if (BIGCOMPACT_DETAILS === 2002) {
|
||||
if (!completeList[0].exitTime) {
|
||||
message.error('请选择退场日期')
|
||||
return
|
||||
}
|
||||
req = {
|
||||
CompactDetails: BIGCOMPACT_DETAILS,// 补充协议类型
|
||||
ContractId: childrenData?.REGISTERCOMPACT_ID,// 主合同内码
|
||||
// ClosedDate:moment(exitTime).format('YYYY-MM-DD'),// 撤场日期
|
||||
ClosedDate: moment(completeList[0].exitTime).format('YYYY-MM-DD'),// 撤场日期
|
||||
SettlementModes: list[0].value,// 切换后的结算模式
|
||||
SwitchDate: completeList[0].SwitchDate ? moment(completeList[0].SwitchDate).format('YYYY-MM-DD') : '',// 切换日期
|
||||
ProjectList: list,// 变更经营项目列表
|
||||
StaffId: currentUser?.ID,// 操作人内码
|
||||
StaffName: currentUser?.Name,// 操作人员
|
||||
CompactDPDesc: descValue && descValue.COMPACT_DPDESC ? descValue.COMPACT_DPDESC : '',// 注意事项
|
||||
}
|
||||
} else {
|
||||
if (list[0].value) {
|
||||
req = {
|
||||
CompactDetails: BIGCOMPACT_DETAILS,// 补充协议类型
|
||||
ContractId: childrenData?.REGISTERCOMPACT_ID,// 主合同内码
|
||||
SettlementModes: list[0].value,// 切换后的结算模式
|
||||
SwitchDate: completeList[0].SwitchDate ? moment(completeList[0].SwitchDate).format('YYYY-MM-DD') : '',// 切换日期
|
||||
ProjectList: list,// 变更经营项目列表
|
||||
StaffId: currentUser?.ID,// 操作人内码
|
||||
StaffName: currentUser?.Name,// 操作人员
|
||||
CompactDPDesc: descValue && descValue.COMPACT_DPDESC ? descValue.COMPACT_DPDESC : '',// 注意事项
|
||||
}
|
||||
} else {
|
||||
message.error('请选择结算模式')
|
||||
setModalLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
const data = await handleContractSupple(req)
|
||||
|
||||
if (data) {
|
||||
const waitUpload = fileList.filter(n => n.status !== 'done')
|
||||
if (waitUpload.length > 0) {
|
||||
await customUploadRequest(waitUpload, data.Result_Data?.REGISTERCOMPACT_ID)
|
||||
}
|
||||
// actionRef.current.reload();
|
||||
}
|
||||
|
||||
if (data.Result_Code === 100) {
|
||||
message.success(data.Result_Desc)
|
||||
setShowModal(false)
|
||||
setFileList([])
|
||||
actionRef.current?.reload()
|
||||
} else {
|
||||
message.error(data.Result_Desc)
|
||||
}
|
||||
setModalLoading(false)
|
||||
}
|
||||
})
|
||||
}}
|
||||
onCancel={() => {
|
||||
setModalTableData([])
|
||||
setShowModal(false)
|
||||
setContract([])
|
||||
setFileList([])
|
||||
setExitTime(undefined)
|
||||
setModalLoading(false)
|
||||
}}>
|
||||
<ProForm
|
||||
layout={'horizontal'}
|
||||
formRef={modalRef}
|
||||
submitter={{
|
||||
render: (_, record) => {
|
||||
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ProFormUploadButton
|
||||
name="ImgList"
|
||||
title="上传附件"
|
||||
label="合同附件"
|
||||
wrapperCol={{ span: 20 }}
|
||||
labelCol={{ span: 3 }}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '请上传合同文件',
|
||||
}
|
||||
]}
|
||||
fieldProps={{
|
||||
name: 'files',
|
||||
listType: 'text',
|
||||
className: 'is-dragging',
|
||||
// defaultFileList: priviewFileList,
|
||||
fileList,
|
||||
multiple: true,
|
||||
onPreview: async (file) => {
|
||||
if (file.type && file.type?.indexOf('image/') > -1) { // 未上传的文件 如果是图片类型的
|
||||
if (!file.url && !file.preview) {
|
||||
setPriviewImage(await getBase64(file.lastModifiedDate))
|
||||
} else {
|
||||
setPriviewImage(file?.url)
|
||||
}
|
||||
} else {
|
||||
const filenameSplitPointArr = file.fileName?.split('.') || []
|
||||
if (['png', 'jpg', 'jpeg'].indexOf(filenameSplitPointArr[filenameSplitPointArr?.length - 1]) > -1) {
|
||||
setPriviewImage(file?.url)
|
||||
}
|
||||
else if (file?.url) {
|
||||
window.open(file?.url)
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeUpload: (file, files) => {
|
||||
setFileList([...fileList, ...files])
|
||||
return false
|
||||
},
|
||||
onChange: async (info: any) => {
|
||||
if (info.file.status === 'removed') {
|
||||
// 如果在待上传列表中找到,则说明当前图片没有上传服务器,可直接删除
|
||||
const index = fileList.findIndex(n => n.uid === info.file.uid);
|
||||
if (!info.file?.deletepath) {
|
||||
const newFileList = fileList.slice();
|
||||
newFileList.splice(index, 1);
|
||||
setFileList(newFileList)
|
||||
return
|
||||
}
|
||||
confirm({
|
||||
title: '确认删除该文件吗?',
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
async onOk() {
|
||||
const deleteLoading = message.loading('正在删除...')
|
||||
const success = await deletePicture(info.file?.deletepath, info.file?.uid, '', '3000')
|
||||
deleteLoading()
|
||||
if (success) {
|
||||
const files = [...fileList]
|
||||
files.splice(index, 1)
|
||||
setFileList(files)
|
||||
}
|
||||
else {
|
||||
message.error("删除失败")
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
label="合同注意事项"
|
||||
width={800}
|
||||
name="COMPACT_DPDESC"
|
||||
fieldProps={{
|
||||
autoSize: { minRows: 1, maxRows: 6 },
|
||||
}}
|
||||
placeholder="请输入合同注意事项"
|
||||
wrapperCol={{ span: 20 }}
|
||||
labelCol={{ span: 3 }}
|
||||
/>
|
||||
{/* { */}
|
||||
{/* BIGCOMPACT_DETAILS===2002? */}
|
||||
{/* <ProFormDatePicker */}
|
||||
{/* name="exitTime" */}
|
||||
{/* label="退场日期" */}
|
||||
{/* wrapperCol={{ span: 20 }} */}
|
||||
{/* labelCol={{ span: 3 }} */}
|
||||
{/* rules={[ */}
|
||||
{/* { */}
|
||||
{/* required: true, */}
|
||||
{/* message: '请选择退场日期', */}
|
||||
{/* } */}
|
||||
{/* ]} */}
|
||||
{/* fieldProps={{ */}
|
||||
{/* onChange:(e: any)=>{ */}
|
||||
{/* if (e){ */}
|
||||
{/* setExitTime(e._d) */}
|
||||
{/* } */}
|
||||
{/* } */}
|
||||
{/* }} */}
|
||||
{/* />:'' */}
|
||||
{/* } */}
|
||||
</ProForm>
|
||||
{/* <div style={{display:'flex',alignItems:'center'}}> */}
|
||||
{/* <p>退场时间</p> */}
|
||||
{/* <DatePicker onChange={(e: any)=>{ */}
|
||||
{/* }} /> */}
|
||||
{/* </div> */}
|
||||
<ProTable
|
||||
search={false}
|
||||
pagination={false}
|
||||
options={false}
|
||||
rowKey={'BUSINESSPROJECT_ID'}
|
||||
style={{ minHeight: 480 }}
|
||||
columns={BIGCOMPACT_DETAILS === 2002 ? [...modalColumns.slice(0, 5), modalColumns[modalColumns.length - 1]] : modalColumns.slice(0, modalColumns.length - 2)}
|
||||
request={async () => {
|
||||
const req = {
|
||||
PROJECT_VALID: 1,
|
||||
REGISTERCOMPACT_ID: currentRow?.REGISTERCOMPACT_ID,
|
||||
PageIndex: 1,
|
||||
pagesize: 9999,
|
||||
keyWord: null
|
||||
}
|
||||
const data = await getProjectList(req)
|
||||
setModalTableData(data.data)
|
||||
// return data
|
||||
}}
|
||||
dataSource={modalTableData}
|
||||
rowSelection={{ // 可选择的表格配置
|
||||
type: "checkbox", // 该表格为单选
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
// 选中行发生改变时,存储选中行的数据
|
||||
setContract(selectedRowKeys)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Modal>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(({ user }: ConnectState) => ({
|
||||
currentUser: user?.currentUser
|
||||
}))(contractWarningQuery);
|
||||
@ -905,6 +905,12 @@ const YearExamineProcess = ({ currentUser, onShow, setOnShow, parentRow, setPare
|
||||
list = list.filter((item: any) => item.value !== 827);
|
||||
}
|
||||
|
||||
// 剔除 结算时间在2025年4月1日 之前的数据 不给陶杰
|
||||
if (parentRow?.PROJECT_ENDDATE && new Date(parentRow?.PROJECT_ENDDATE).getTime() < new Date('2025-04-01 00:00:00').getTime()) {
|
||||
list = list.filter((item: any) => item.value !== 1802);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (currentUser?.ID === 2785) {
|
||||
list.push({ label: '严琅杰', value: 2785 })
|
||||
|
||||
@ -141,6 +141,22 @@ const BookingMealOrder: React.FC<{ currentUser: CurrentUser | undefined }> = (pr
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "获得积分",
|
||||
dataIndex: "MEMBERSHIP_POINT",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "获得成长值",
|
||||
dataIndex: "MEMBERGROWTH_VALUE",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
// {
|
||||
// dataIndex: 'COUPON_SEND_ID',
|
||||
// title: '优惠券名',
|
||||
|
||||
@ -193,6 +193,22 @@ const ConsumptionRecordSearch: React.FC<{ currentUser: CurrentUser, isComponent?
|
||||
align: 'center',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "获得积分",
|
||||
width: 120,
|
||||
dataIndex: "MEMBERSHIP_POINT",
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "获得成长值",
|
||||
width: 120,
|
||||
dataIndex: "MEMBERGROWTH_VALUE",
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "消费时间 ",
|
||||
width: 150,
|
||||
@ -238,6 +254,11 @@ const ConsumptionRecordSearch: React.FC<{ currentUser: CurrentUser, isComponent?
|
||||
headerTitle={<PageTitleBox props={props} />}
|
||||
scroll={{ x: '100%', y: isComponent ? '300px' : 'calc(100vh - 430px)' }}
|
||||
search={isComponent ? false : { span: 6 }}
|
||||
options={isComponent ? false : {
|
||||
density: true,
|
||||
reload: true,
|
||||
setting: true
|
||||
}}
|
||||
request={async (params) => {
|
||||
let req: any = {}
|
||||
|
||||
|
||||
@ -102,6 +102,15 @@ const GrowthValueRecordSearch: React.FC<{ currentUser: CurrentUser, isComponent?
|
||||
ellipsis: true,
|
||||
valueType: 'digit'
|
||||
},
|
||||
{
|
||||
title: "实付金额",
|
||||
width: 120,
|
||||
dataIndex: "PAY_AMOUNT",
|
||||
hideInSearch: true,
|
||||
align: 'center',
|
||||
ellipsis: true,
|
||||
valueType: 'digit'
|
||||
},
|
||||
{
|
||||
title: "成长来源",
|
||||
width: 120,
|
||||
@ -180,6 +189,11 @@ const GrowthValueRecordSearch: React.FC<{ currentUser: CurrentUser, isComponent?
|
||||
headerTitle={<PageTitleBox props={props} />}
|
||||
scroll={{ x: '100%', y: isComponent ? '300px' : 'calc(100vh - 430px)' }}
|
||||
search={isComponent ? false : { span: 6 }}
|
||||
options={isComponent ? false : {
|
||||
density: true,
|
||||
reload: true,
|
||||
setting: true
|
||||
}}
|
||||
request={async (params) => {
|
||||
const req: any = isComponent ? {
|
||||
searchParameter: {
|
||||
|
||||
@ -252,7 +252,7 @@ const MallEvaluationManage: React.FC<{ currentUser: CurrentUser | undefined, isC
|
||||
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
||||
{
|
||||
isComponent ? '' :
|
||||
<LeftSelectMallType setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} setData={setLeftTreeData} />
|
||||
<LeftSelectMallType setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} setData={setLeftTreeData} isShowAllInTree={true} />
|
||||
|
||||
}
|
||||
<div style={{
|
||||
@ -269,6 +269,7 @@ const MallEvaluationManage: React.FC<{ currentUser: CurrentUser | undefined, isC
|
||||
}}
|
||||
formRef={formRef}
|
||||
bordered
|
||||
options={false}
|
||||
headerTitle={<PageTitleBox props={props} />} // 列表表头
|
||||
actionRef={actionRef}
|
||||
search={isComponent ? false : { span: 6, labelWidth: 'auto' }}
|
||||
|
||||
@ -226,6 +226,22 @@ const MallOrderManage: React.FC<{ currentUser: CurrentUser }> = (props) => {
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "获得积分",
|
||||
dataIndex: "MEMBERSHIP_POINT",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "获得成长值",
|
||||
dataIndex: "MEMBERGROWTH_VALUE",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "订单时间",
|
||||
dataIndex: "ORDER_DATE",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// 订单汇总统计
|
||||
// 订单汇总统计 商城的
|
||||
import { ConnectState } from "@/models/connect";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { connect, CurrentUser } from "umi";
|
||||
@ -129,6 +129,22 @@ const MallSummaryStatistics: React.FC<{ currentUser: CurrentUser | undefined }>
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "获得积分",
|
||||
dataIndex: "MEMBERSHIP_POINT",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "获得成长值",
|
||||
dataIndex: "MEMBERGROWTH_VALUE",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
dataIndex: 'ORDER_DATE',
|
||||
title: '订单时间',
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
.proformList {
|
||||
.ant-form-item-control-input-content>div:first-of-type {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
|
||||
.ant-pro-form-list-item {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,18 +4,20 @@ import type { CurrentUser } from "umi";
|
||||
import type { ConnectState } from "@/models/connect";
|
||||
import React, { useRef, useState } from "react";
|
||||
import type { FormInstance } from "antd";
|
||||
import { Button, Col, message, Modal, Row, Space, Spin, Tree } from "antd";
|
||||
import { Button, Col, message, Modal, Row, Space, Spin, Tree, Image } from "antd";
|
||||
import useRequest from "@ahooksjs/use-request";
|
||||
import type { ActionType } from "@ant-design/pro-table";
|
||||
import ProTable from "@ant-design/pro-table";
|
||||
import LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
|
||||
import PageTitleBox from "@/components/PageTitleBox";
|
||||
import { handeGetCOMMENTList, handeSynchroCOMMENT } from "../service";
|
||||
import { handeDeleteCOMMENT, handeDeleteREPLY, handeGetCOMMENTDetail, handeGetCOMMENTList, handeGetREPLYDetail, handeSynchroCOMMENT, handeSynchroREPLY, handeSynchroReplyList } from "../service";
|
||||
import moment from 'moment'
|
||||
import session from "@/utils/session";
|
||||
import { handleSetlogSave } from "@/utils/format";
|
||||
import Draggable from "react-draggable";
|
||||
import ProForm, { ProFormText, ProFormTextArea } from "@ant-design/pro-form";
|
||||
import ProForm, { ProFormList, ProFormText, ProFormTextArea, ProFormUploadButton } from "@ant-design/pro-form";
|
||||
import { getBase64 } from "@/utils/utils";
|
||||
import './MerchantEvaluationManage.less'
|
||||
|
||||
|
||||
|
||||
@ -33,6 +35,13 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
const [showDetailDrawer, setShowDetailDrawer] = useState<boolean>(false)
|
||||
// 点击的当前数据
|
||||
const [currentRow, setCurrentRow] = useState<any>()
|
||||
// 评论的附件
|
||||
const [fileList, setFileList] = useState<any>()
|
||||
const [imagePreviewVisible, setImagePreviewVisible] = useState<boolean>(false) // 预览图片
|
||||
const [priviewImage, setPriviewImage] = useState<string>(); // 预览的图片地址
|
||||
// 删除回复的加载效果
|
||||
const [deleteREPLYLoading, setDeleteREPLYLoading] = useState<boolean>(false)
|
||||
|
||||
|
||||
const MEMBERSHIPLEVELYNObj = session.get('MEMBERSHIPLEVELYNObj')
|
||||
// 树相关的属性和方法
|
||||
@ -152,7 +161,23 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
align: "center",
|
||||
render: (_, record) => {
|
||||
return record?.COMMENT_CONTENT ? <a onClick={() => {
|
||||
setCurrentRow(record)
|
||||
console.log('recordrecord', record);
|
||||
|
||||
if (record?.ImageList && record?.ImageList.length > 0) {
|
||||
let list: any = []
|
||||
record?.ImageList.forEach((item: any) => {
|
||||
list.push({
|
||||
name: "",
|
||||
url: item?.ImageUrl
|
||||
})
|
||||
})
|
||||
setFileList(list)
|
||||
}
|
||||
|
||||
setCurrentRow({
|
||||
...record,
|
||||
ReplyList: record?.ReplyList || []
|
||||
})
|
||||
setShowDetailDrawer(true)
|
||||
}}>{record?.COMMENT_CONTENT}</a> : "-"
|
||||
}
|
||||
@ -169,7 +194,48 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
|
||||
// 删除评论
|
||||
const handleDeleteEvaluation = async () => {
|
||||
|
||||
const req: any = {
|
||||
COMMENTId: currentRow?.COMMENT_ID
|
||||
}
|
||||
const data = await handeDeleteCOMMENT(req)
|
||||
if (data.Result_Code === 100) {
|
||||
message.success(data.Result_Desc)
|
||||
setShowDetailDrawer(false)
|
||||
setCurrentRow(undefined);
|
||||
setFileList([])
|
||||
actionRef.current?.reload()
|
||||
} else {
|
||||
message.error(data.Result_Desc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 删除回复
|
||||
const handleDeleteEvaluationREPLY = async (REPLY_ID: string) => {
|
||||
const req: any = {
|
||||
REPLYId: REPLY_ID
|
||||
}
|
||||
setDeleteREPLYLoading(true)
|
||||
const data = await handeDeleteREPLY(req)
|
||||
setDeleteREPLYLoading(false)
|
||||
if (data.Result_Code === 100) {
|
||||
message.success(data.Result_Desc)
|
||||
actionRef?.current?.reload()
|
||||
return true
|
||||
} else {
|
||||
message.error(data.Result_Desc)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 预览上传后的图片
|
||||
const handlePreview = async () => {
|
||||
setFileList(fileList)
|
||||
setImagePreviewVisible(true)
|
||||
};
|
||||
const handleChangePreview = (val: any) => {
|
||||
setImagePreviewVisible(val)
|
||||
}
|
||||
|
||||
return (
|
||||
@ -194,6 +260,7 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
expandable={{
|
||||
expandRowByClick: true
|
||||
}}
|
||||
options={false}
|
||||
scroll={{ x: "100%", y: isComponent ? '300px' : "calc(100vh - 410px)" }}
|
||||
headerTitle={<PageTitleBox props={props} />} // 列表表头
|
||||
search={isComponent ? false : { span: 6 }}
|
||||
@ -250,7 +317,20 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 图片预览组件 */}
|
||||
{fileList && fileList.length > 0 && <div style={{ display: 'none' }}>
|
||||
<Image.PreviewGroup
|
||||
preview={{
|
||||
visible: imagePreviewVisible,
|
||||
onVisibleChange: vis => {
|
||||
handleChangePreview(vis)
|
||||
}
|
||||
}}>
|
||||
{
|
||||
fileList.map((n) => <Image src={n.url} key={n.url} />)
|
||||
}
|
||||
</Image.PreviewGroup>
|
||||
</div>}
|
||||
|
||||
|
||||
<Modal
|
||||
@ -267,14 +347,15 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
afterClose={() => {
|
||||
}}
|
||||
bodyStyle={{
|
||||
maxHeight: '850px', // 你可以根据需要调整高度
|
||||
height: '700px', // 你可以根据需要调整高度
|
||||
overflowY: 'auto',
|
||||
}}
|
||||
onCancel={() => {
|
||||
setShowDetailDrawer(false)
|
||||
setCurrentRow(undefined);
|
||||
setFileList([])
|
||||
}}
|
||||
footer={<div style={{ width: '100%', boxSizing: 'border-box', padding: '0 16px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
footer={<div style={{ width: '100%', boxSizing: 'border-box', padding: '0 8px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<Button danger onClick={() => {
|
||||
handleDeleteEvaluation()
|
||||
@ -284,6 +365,7 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
<Button style={{ marginRight: '8px' }} onClick={() => {
|
||||
setShowDetailDrawer(false)
|
||||
setCurrentRow(undefined);
|
||||
setFileList([])
|
||||
}}>
|
||||
取消
|
||||
</Button>
|
||||
@ -310,15 +392,64 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
<ProForm
|
||||
formRef={modalFormRef}
|
||||
submitter={false}
|
||||
labelCol={{ style: { width: 80 } }}
|
||||
initialValues={currentRow}
|
||||
onFinish={async (res: any) => {
|
||||
const req: any = {
|
||||
console.log('currentRowcurrentRowcurrentRow', currentRow);
|
||||
console.log('resresresresres', res);
|
||||
|
||||
if (res.ReplyList && res.ReplyList.length > 0) {
|
||||
let list: any = []
|
||||
res.ReplyList.forEach((item: any) => {
|
||||
list.push({
|
||||
COMMENT_ID: currentRow?.COMMENT_ID || "",
|
||||
COMMENT_CONTENT: currentRow?.COMMENT_CONTENT || "",
|
||||
// COMMENT_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
|
||||
STAFF_ID: currentUser?.ID,
|
||||
STAFF_NAME: currentUser?.Name,
|
||||
REPLY_DATE: moment().format('YYYY-MM-DD HH:mm:ss'),
|
||||
REPLY_CONTENT: item.REPLY_CONTENT,
|
||||
REPLY_STATE: 1
|
||||
})
|
||||
})
|
||||
console.log('list', list);
|
||||
|
||||
const data = await handeSynchroReplyList({
|
||||
list: list
|
||||
})
|
||||
console.log('datadatadatadata', data);
|
||||
if (data.Result_Code === 100) {
|
||||
message.success(data.Result_Desc)
|
||||
setFileList([])
|
||||
setShowDetailDrawer(false)
|
||||
setCurrentRow(undefined);
|
||||
actionRef.current?.reload()
|
||||
} else {
|
||||
message.error(data.Result_Desc)
|
||||
}
|
||||
} else {
|
||||
setFileList([])
|
||||
setShowDetailDrawer(false)
|
||||
setCurrentRow(undefined);
|
||||
actionRef.current?.reload()
|
||||
}
|
||||
// const data = await handeSynchroCOMMENT(req)
|
||||
|
||||
|
||||
}}
|
||||
// request={async () => {
|
||||
// if (currentRow?.ReplyList && currentRow?.ReplyList.length > 0) {
|
||||
// const req: any = {
|
||||
// REPLYId: currentRow?.ReplyList[0].REPLY_ID
|
||||
// }
|
||||
// const data = await handeGetREPLYDetail(req)
|
||||
// console.log('datadatadata', data);
|
||||
// return {
|
||||
// ...data,
|
||||
// ReplyToEvaluation: data.REPLY_CONTENT
|
||||
// }
|
||||
// } else {
|
||||
// return {}
|
||||
// }
|
||||
|
||||
// }}
|
||||
>
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
@ -328,22 +459,118 @@ const MerchantEvaluationManage: React.FC<{ currentUser: CurrentUser, isComponent
|
||||
readonly
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={24}>
|
||||
<ProFormUploadButton
|
||||
label={""}
|
||||
name={"ImageList"}
|
||||
disabled
|
||||
readonly
|
||||
max={0}
|
||||
fileList={fileList || []}
|
||||
listType="picture-card"
|
||||
accept="image/*"
|
||||
fieldProps={{
|
||||
onPreview: handlePreview
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col span={24} className="proformList">
|
||||
<ProFormList
|
||||
name="ReplyList"
|
||||
label="回复评价"
|
||||
copyIconProps={false}
|
||||
deleteIconProps={false}
|
||||
creatorButtonProps={{
|
||||
position: 'bottom',
|
||||
creatorButtonText: '新增一条回复',
|
||||
}}
|
||||
style={{ width: '100%' }}
|
||||
itemContainerStyle={{ width: '100%' }}
|
||||
>
|
||||
{(field, index, action) => {
|
||||
const isInitialItem = index < (currentRow?.ReplyList?.length || 0);
|
||||
return (
|
||||
<div
|
||||
key={field.key}
|
||||
style={{
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
marginBottom: '10px',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: 1 }}>
|
||||
<ProFormTextArea
|
||||
name={"REPLY_CONTENT"} // 确保使用 field.name
|
||||
placeholder="请输入回复内容"
|
||||
readonly={isInitialItem} // 直接使用 isInitialItem
|
||||
fieldProps={{
|
||||
style: { width: '100%' },
|
||||
autoSize: { minRows: 3, maxRows: 6 },
|
||||
}}
|
||||
rules={[{ required: true, message: '请输入回复内容' }]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{
|
||||
width: '50px',
|
||||
marginLeft: '8px',
|
||||
gap: '8px'
|
||||
}}>
|
||||
{isInitialItem ? (
|
||||
<Button
|
||||
danger
|
||||
loading={deleteREPLYLoading}
|
||||
onClick={async () => {
|
||||
const replyId = currentRow?.ReplyList?.[index]?.REPLY_ID;
|
||||
if (replyId) {
|
||||
const success = await handleDeleteEvaluationREPLY(replyId);
|
||||
if (success) {
|
||||
action?.remove(index);
|
||||
}
|
||||
} else {
|
||||
action?.remove(index);
|
||||
}
|
||||
}}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
danger
|
||||
onClick={() => action?.remove(index)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</ProFormList>
|
||||
</Col>
|
||||
|
||||
{/* <Col span={24}>
|
||||
<ProFormTextArea
|
||||
label={"回复评价"}
|
||||
name={"COMMENT_CONTENT"}
|
||||
name={"ReplyToEvaluation"}
|
||||
rules={[{
|
||||
required: true,
|
||||
message: '请输入回复内容'
|
||||
}]}
|
||||
readonly={currentRow?.ReplyList && currentRow?.ReplyList.length > 0 ? true : false}
|
||||
/>
|
||||
</Col>
|
||||
</Col> */}
|
||||
</Row>
|
||||
|
||||
</ProForm>
|
||||
|
||||
</Modal>
|
||||
</div>
|
||||
</Modal >
|
||||
</div >
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -175,6 +175,11 @@ const PointsRecordSearch: React.FC<{ currentUser: CurrentUser, isComponent?: Boo
|
||||
headerTitle={<PageTitleBox props={props} />}
|
||||
search={isComponent ? false : { span: 6 }}
|
||||
scroll={{ x: '100%', y: isComponent ? '300px' : 'calc(100vh - 430px)' }}
|
||||
options={isComponent ? false : {
|
||||
density: true,
|
||||
reload: true,
|
||||
setting: true
|
||||
}}
|
||||
request={async (params) => {
|
||||
const req: any = isComponent ? {
|
||||
SearchParameter: {
|
||||
|
||||
@ -29,13 +29,14 @@ type DetailProps = {
|
||||
noWj?: any // 把万佳商贸隐藏
|
||||
selectOnly?: boolean// 传入的时候 仅支持单选
|
||||
setData?: any // 把树形的数据 传出去
|
||||
isShowAllInTree?: boolean
|
||||
}
|
||||
const LeftSelectMallType = ({ setSelectedId, reload, actionRef, currentUser, width, otherFun, setCollapsible, collapsible, haveTest, handleGetLeftTreeData, noWj, selectOnly, setData }: DetailProps) => {
|
||||
const LeftSelectMallType = ({ setSelectedId, reload, actionRef, currentUser, width, otherFun, setCollapsible, collapsible, haveTest, handleGetLeftTreeData, noWj, selectOnly, setData, isShowAllInTree }: DetailProps) => {
|
||||
const searchTreeRef = useRef<FormInstance>();
|
||||
// 默认的服务区树
|
||||
const [allTreeViews, setAllTreeViews] = useState<any>()
|
||||
// 是否要显示全部
|
||||
const [isShowAllInTree, setIsShowAllInTree] = useState<boolean>(false)
|
||||
// const [isShowAllInTree, setIsShowAllInTree] = useState<boolean>(false)
|
||||
// 加载服务区树
|
||||
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
|
||||
|
||||
@ -205,19 +206,18 @@ const LeftSelectMallType = ({ setSelectedId, reload, actionRef, currentUser, wid
|
||||
: convertTreeForSelectOnly(treeView))
|
||||
: (isShowAllInTree
|
||||
? [{
|
||||
label: '全部',
|
||||
USERDEFINEDTYPE_NAME: '全部',
|
||||
value: 0,
|
||||
key: '0-0',
|
||||
USERDEFINEDTYPE_ID: '0-0',
|
||||
children: treeView
|
||||
}]
|
||||
: treeView)}
|
||||
blockNode
|
||||
// defaultExpandAll={isShowAllInTree ? false : true}
|
||||
// defaultExpandedKeys={isShowAllInTree ? treeShowRow && treeShowRow.length > 0 ? treeShowRow : ['0-0'] : []}
|
||||
defaultExpandedKeys={isShowAllInTree ? treeShowRow && treeShowRow.length > 0 ? treeShowRow : ['0-0'] : []}
|
||||
onCheck={(checkedKeys: React.Key[] | any, info) => {
|
||||
console.log('checkedKeyscheckedKeyscheckedKeys', checkedKeys);
|
||||
console.log('infoinfoinfoinfoinfoinfo', info);
|
||||
|
||||
// 多选逻辑
|
||||
// const selectedIds = info.checkedNodes.filter((n: any) => n?.USERDEFINEDTYPE_PID !== -1)
|
||||
const selectedIds = info.checkedNodes.filter((n: any) => n?.USERDEFINEDTYPE_ID)
|
||||
|
||||
@ -397,6 +397,11 @@ const RegistrationRetentionAnalysis: React.FC<{ currentUser: CurrentUser, isComp
|
||||
pagination={{ pageSize: 100 }}
|
||||
dataSource={tableData}
|
||||
loading={tableLoading}
|
||||
options={isComponent ? false : {
|
||||
density: true,
|
||||
reload: true,
|
||||
setting: true
|
||||
}}
|
||||
request={async (params) => {
|
||||
handleGetTableData()
|
||||
// if (!isFirst) {
|
||||
|
||||
@ -129,6 +129,22 @@ const SummaryOfReservation: React.FC<{ currentUser: CurrentUser | undefined }> =
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "获得积分",
|
||||
dataIndex: "MEMBERSHIP_POINT",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "获得成长值",
|
||||
dataIndex: "MEMBERGROWTH_VALUE",
|
||||
width: 120,
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
dataIndex: 'ORDER_DATE',
|
||||
title: '订单时间',
|
||||
|
||||
@ -103,6 +103,7 @@ const CollectProducts = ({ parentDetail, currentUser }: DetailProps) => {
|
||||
expandable={{
|
||||
expandRowByClick: true
|
||||
}}
|
||||
options={false}
|
||||
search={false}
|
||||
scroll={{ x: "100%", y: '300px' }}
|
||||
// headerTitle={<PageTitleBox props={props} />} // 列表表头
|
||||
|
||||
@ -68,6 +68,7 @@ const LicensePlateManage = ({ parentDetail }: DetailProps) => {
|
||||
expandRowByClick: true
|
||||
}}
|
||||
search={false}
|
||||
options={false}
|
||||
scroll={{ x: "100%", y: '300px' }}
|
||||
// headerTitle={<PageTitleBox props={props} />} // 列表表头
|
||||
request={async (params) => {
|
||||
|
||||
@ -93,6 +93,7 @@ const MemberDiscounts = ({ parentDetail }: DetailProps) => {
|
||||
expandRowByClick: true
|
||||
}}
|
||||
search={false}
|
||||
options={false}
|
||||
scroll={{ x: "100%", y: '300px' }}
|
||||
// headerTitle={<PageTitleBox props={props} />} // 列表表头
|
||||
request={async (params) => {
|
||||
|
||||
@ -245,6 +245,15 @@ const memberInfor: React.FC<{ currentUser: CurrentUser }> = (props) => {
|
||||
sorter: true,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: "会员成长值",
|
||||
width: 120,
|
||||
dataIndex: "MEMBERGROWTH_VALUE",
|
||||
hideInSearch: true,
|
||||
ellipsis: true,
|
||||
sorter: true,
|
||||
align: 'center',
|
||||
},
|
||||
// {
|
||||
// title: "付费会员",
|
||||
// width: 120,
|
||||
|
||||
@ -884,3 +884,77 @@ export async function handeGetGetOnlineOrderSummary(params: any) {
|
||||
}
|
||||
return data.Result_Data.List
|
||||
}
|
||||
|
||||
|
||||
// 同步回复表
|
||||
export async function handeSynchroREPLY(params: any) {
|
||||
const data = await requestEncryption(`/Comment/SynchroREPLY`, {
|
||||
method: 'POST',
|
||||
data: { ...params, requestEncryption: true }
|
||||
})
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 拿到回复详情
|
||||
export async function handeGetREPLYDetail(params: any) {
|
||||
const data = await requestEncryption(`/Comment/GetREPLYDetail`, {
|
||||
method: 'POST',
|
||||
data: { ...params, requestEncryption: true }
|
||||
})
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data.Result_Data
|
||||
}
|
||||
|
||||
// 拿到评价表明细
|
||||
export async function handeGetCOMMENTDetail(params: any) {
|
||||
const data = await requestEncryption(`/Comment/GetCOMMENTDetail`, {
|
||||
method: 'POST',
|
||||
data: { ...params, requestEncryption: true }
|
||||
})
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data.Result_Data
|
||||
}
|
||||
|
||||
// 删除评价
|
||||
export async function handeDeleteCOMMENT(params: any) {
|
||||
const data = await requestEncryption(`/Comment/DeleteCOMMENT`, {
|
||||
method: 'POST',
|
||||
data: { ...params, requestEncryption: true }
|
||||
})
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
// 删除回复
|
||||
export async function handeDeleteREPLY(params: any) {
|
||||
const data = await requestEncryption(`/Comment/DeleteREPLY`, {
|
||||
method: 'POST',
|
||||
data: { ...params, requestEncryption: true }
|
||||
})
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 批量添加回复
|
||||
export async function handeSynchroReplyList(params: any) {
|
||||
const data = await requestEncryption(`/Comment/SynchroReplyList`, {
|
||||
method: 'POST',
|
||||
data: { ...params, requestEncryption: true }
|
||||
})
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user