This commit is contained in:
ylj20011123 2025-09-30 14:42:08 +08:00
parent 5a7f174613
commit e876df2bde
40 changed files with 2664 additions and 2315 deletions

View File

@ -30,6 +30,11 @@ export default {
target: 'http://127.0.0.1:8900', // 'http://dev.eshangtech.com:8001',
changeOrigin: true,
pathRewrite: { '^/EShangApiDashboard': '/EShangApiDashboard' }
},
'/baidu-api/': {
target: 'https://api.map.baidu.com',
changeOrigin: true,
pathRewrite: { '^/baidu-api': '' },
}
},
test: {

View File

@ -1,6 +1,6 @@
{
"name": "ant-design-pro",
"version": "4.5.62",
"version": "4.5.64",
"private": true,
"description": "An out-of-box UI solution for enterprise applications",
"scripts": {

View File

@ -20,6 +20,7 @@ import { contractType } from "../contract/emun";
import ProjectDetail from './detail'
import PageTitleBox from '@/components/PageTitleBox';
import { CurrentUser } from 'umi';
import LeftSelectTree from '../reports/settlementAccount/component/leftSelectTree';
const { Text } = Typography;
@ -191,43 +192,16 @@ const ProjecetTable: React.FC<{ currentUser?: CurrentUser }> = (props) => {
];
return (
<PageContainer header={{
title: '',
breadcrumb: {},
}}>
<ProCard split="vertical" style={{ backgroundColor: '#fff' }}>
<ProCard
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20 }}
extra={<MenuFoldOutlined onClick={() => { setCollapsible(!collapsible) }} />}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "请选择服务区" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={!treeLoading ? [{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}] : []}
fieldNames={{
title: "label",
key: "key"
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
actionRef?.current?.reload()
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
<ProCard bodyStyle={{ paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<div >
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
{/* 项目页面 表格主体 */}
<ProTable<BusinessProjectModel>
headerTitle={<PageTitleBox props={props} />}
@ -302,25 +276,26 @@ const ProjecetTable: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// }}
pagination={{ defaultPageSize: 10 }} // 翻页默认10条分页
/>
{/* 查看项目详情 右侧弹出的抽屉 */}
<Drawer
width="80%"
className="project-drawer"
visible={showDetail} // 抽屉弹框是否显示状态
onClose={() => { // 关闭抽屉 则在清空选中行数据 并 设置抽屉状态为关闭
setCurrentRow(undefined);
setShowDetail(false);
}}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
closable={false}
>
{/* 抽屉打开时 加载项目详情组件 */}
{showDetail && <ProjectDetail id={currentRow?.BUSINESSPROJECT_ID} editable={false} showType={'search'}
tabActive={currentRow?.SETTLEMENT_MODES === 3000 || currentRow?.SETTLEMENT_MODES === 4000 ? '7' : ''}></ProjectDetail>}
</Drawer>
</ProCard>
</ProCard>
</PageContainer>
</div>
{/* 查看项目详情 右侧弹出的抽屉 */}
<Drawer
width="80%"
className="project-drawer"
visible={showDetail} // 抽屉弹框是否显示状态
onClose={() => { // 关闭抽屉 则在清空选中行数据 并 设置抽屉状态为关闭
setCurrentRow(undefined);
setShowDetail(false);
}}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
closable={false}
>
{/* 抽屉打开时 加载项目详情组件 */}
{showDetail && <ProjectDetail id={currentRow?.BUSINESSPROJECT_ID} editable={false} showType={'search'}
tabActive={currentRow?.SETTLEMENT_MODES === 3000 || currentRow?.SETTLEMENT_MODES === 4000 ? '7' : ''}></ProjectDetail>}
</Drawer>
</div>
</div>
);
}

View File

@ -7,7 +7,7 @@
* @Description:
*/
import { getSMSIdentityCode, modifyUserPassword } from "@/pages/account/setting/sevice";
import { getSMSIdentityCode, handleModifyPasswordByPassport, modifyUserPassword } from "@/pages/account/setting/sevice";
import ProForm, { ProFormCaptcha, ProFormText } from "@ant-design/pro-form";
import type { FormInstance } from "antd";
@ -70,21 +70,32 @@ const ForgetPasswordContent: React.FC = () => {
const newValue = { ...values, DataType: 2000 }
let success = null
delete newValue.ComfirmPassword
delete newValue.USER_COMFIRMPASSWORD
success = await handelResetPassWord({ ...newValue })
setSubmitting(false)
if (success) {
console.log('newValue', newValue);
success = await handleModifyPasswordByPassport({ ...newValue })
console.log('success', success);
if (success.Result_Code === 100) {
message.success(success.Result_Data)
setStep(2)
return true
} else {
message.error(success.Result_Desc)
return false
}
return false
// success = await handelResetPassWord({ ...newValue })
// setSubmitting(false)
// if (success) {
// setStep(2)
// return true
// }
// return false
}}
>
{/* -
<ProFormText
fieldProps={{
size: 'large',
@ -136,6 +147,40 @@ const ForgetPasswordContent: React.FC = () => {
]}
/>
*/}
{/* 新的账号+原密码验证方式 */}
<ProFormText
fieldProps={{
size: 'large',
prefix: <Typography.Text type="secondary" style={{ paddingRight: 16 }}></Typography.Text>,
}}
name="PassportName"
rules={[
{
required: true,
message: '请输入账号'
}
]}
validateTrigger="onBlur"
hasFeedback
placeholder="请输入账号"
/>
<ProFormText.Password
fieldProps={{
size: 'large',
prefix: <Typography.Text type="secondary" style={{ paddingRight: 16 }}></Typography.Text>,
}}
name="OriPassword"
rules={[
{
required: true,
message: '请输入原密码'
}
]}
placeholder="请输入原密码"
/>
<ProFormText.Password
fieldProps={{

View File

@ -23,6 +23,7 @@ import loginBg from '../../../assets/login-bg.png';
import styles from './index.less';
import { line } from '@antv/g2plot';
import session from '@/utils/session';
import { getLocationByIP, getUserIP } from '@/utils/format';
// 可接受的页面参数
export type LoginProps = {
@ -98,7 +99,7 @@ const Login: React.FC<LoginProps> = (props) => {
function successCallBack(req: any) {
}
useEffect(() => {
useEffect(async () => {
// 第三方 说是不安全
// fetch('https://api.ipify.org?format=json').then(response => response.json())
// .then(json => console.log(json.ip));
@ -118,16 +119,31 @@ const Login: React.FC<LoginProps> = (props) => {
// alert('您的浏览器不支持定位功能')
// }
// 可以一条龙拿到的
fetch('https://qifu-api.baidubce.com/ip/local/geo/v1/district').then(response => response.text()).then(data => {
const obj: any = JSON.parse(data).data
const res = {
...obj,
ip: JSON.parse(data).ip
}
session.set('basicInfo', res);
setBaseInfo(res)
});
// 先拿到ip
let IpInfo: any = await getUserIP()
console.log('IpInfoIpInfoIpInfoIpInfo', IpInfo);
// 用ip 去获取信息
let ipDetail: any = await getLocationByIP(IpInfo, 'XrQQuNQRGxap9YH2xmvx3dzuJVkXhTzT')
console.log('ipDetailipDetailipDetail', ipDetail);
const ipRes: any = {
country: ipDetail.country,
prov: ipDetail.province,
city: ipDetail.city,
district: ipDetail.district,
ip: IpInfo,
}
session.set('basicInfo', ipRes);
setBaseInfo(ipRes)
// // 可以一条龙拿到的
// fetch('https://qifu-api.baidubce.com/ip/local/geo/v1/district').then(response => response.text()).then(data => {
// const obj: any = JSON.parse(data).data
// const res = {
// ...obj,
// ip: JSON.parse(data).ip
// }
// session.set('basicInfo', res);
// setBaseInfo(res)
// });
const browserVersion = getBrowserVersion();
session.set('browserVersion', browserVersion);
@ -328,11 +344,12 @@ const Login: React.FC<LoginProps> = (props) => {
</LoginForm>
{/* <div style={{ textAlign: 'center', width: 328, margin: 'auto' }}>
<div style={{ textAlign: 'center', width: 328, margin: 'auto' }}>
<Space split>
<Link to="/user/register"></Link> | <Link to="/user/forgetPassword"><Typography.Text type="secondary" >?</Typography.Text></Link>
{/* <Link to="/user/register">商户注册</Link> | */}
<Link to="/user/forgetPassword"><Typography.Text type="secondary" >?</Typography.Text></Link>
</Space>
</div> */}
</div>
<div className={styles['form-bottom']}>
<Divider className={styles.divider}></Divider>
<p>

View File

@ -1,5 +1,6 @@
import request from "@/utils/request";
import type { CloudChangeUserModel, CloudChangePassword } from './data';
import requestEncryption from "@/utils/requestEncryption";
// 更新账户信息
export async function modifyUserInfo(data: CloudChangeUserModel) {
@ -48,3 +49,21 @@ export async function modifyUserMobilePhone(data: CloudChangeUserModel) {
// requestType: 'form',
});
}
// 根据用户账号修改密码
export async function handleModifyPasswordByPassport(params: any) {
const data = await requestEncryption(`/Logging/ModifyPasswordByPassport`, {
method: 'POST',
data: {
...params,
requestEncryption: true
},
})
if (data.Result_Code !== 100) {
return data
}
return data
}

View File

@ -39,6 +39,8 @@ import '@/pages/merchantManagement/style.less';
import session from "@/utils/session";
import { getDetail } from "@/pages/basicManage/Serverpart/service";
import PageTitleBox from '@/components/PageTitleBox';
import { formatTreeData } from '@/utils/format';
import { exportXlsxFromProColumnsExcelJS } from '@/utils/exportExcelFun';
const { Text } = Typography;
@ -82,6 +84,8 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
const [collapsible, setCollapsible] = useState<boolean>(false)
// 选中的服务区名称
const [serviceName, setSelectServiceName] = useState<string>()
// 导出excel数据
const [reqDetailList, setReqDetailList] = useState<any>();
// 加载服务区树
const { loading: treeLoading, data: treeView = [] } = useRequest(() => { return getServerpartTree(currentUser?.ProvinceCode) })
// 表格数据
@ -245,375 +249,391 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// 打印报表
setPrintOut(el);
}}>
<PageContainer header={{
title: '',
breadcrumb: {},
}}
style={{
width: '100%',
height: '100%'
}}>
<ProCard split="vertical" style={{ backgroundColor: '#fff', width: 'calc(100vw - 260px)', height: 'calc(100vh - 130px)' }}>
<ProCard
style={{ height: '100%' }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20 }}
extra={<MenuFoldOutlined onClick={() => { setCollapsible(!collapsible) }} />}
colSpan={!collapsible ? "300px" : "60px"}
title={!collapsible ? "请选择服务区" : ""}
headerBordered
collapsed={collapsible}
>
{!treeLoading && <Menu
mode="inline"
style={{ height: 'calc(100% - 100px)', overflowY: 'auto', overflowX: 'hidden' }}
selectedKeys={selectedId}
onSelect={(item) => {
// 拿到选择的服务区名称给导出的文件赋值
if (treeView && treeView.length > 0) {
treeView.forEach((i: any) => {
if (i.children && i.children.length > 0) {
i.children.forEach((subItem: any) => {
if (subItem.key === item.key) {
setSelectServiceName(subItem.label)
}
})
}
})
}
loadSelectedId(item)
}}
>
{getMenuDom(treeView, loadSelectedId)}
</Menu>}
</ProCard>
<ProCard bodyStyle={{ paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<ProTable<RevenueConfirmModel>
cardProps={{ // 去除表格内边距
bodyStyle: { padding: 24 }
}}
bordered={true}
rowKey="REVENUECONFIRM_ID"
headerTitle={<PageTitleBox props={props} />}
actionRef={actionRef}
search={{ span: 6, labelWidth: 'auto' }}
// manualRequest={true} // 是否需要手动触发首次请求, 配置为 true 时不可隐藏搜索表单
request={async (pramas, sorter) => {
const sortstr = Object.keys(sorter).map(n => {
const value = sorter[n]
return value ? `${n} ${value.replace('end', '')}` : ''
})
const data = await getRevenueConfirmList({
ServerpartId: selectedId && selectedId.length > 0 ? selectedId[0].split('-')[1] : currenMenu || '0',
StartDate: pramas.StartDate || '',
EndDate: pramas.EndDate || '',
sortstr: sortstr.toString()
} as RevenueConfirmParams
)
setTableData(data.data)
return {
...data, data: data.data.map((n: RevenueConfirmModel) => {
return { ...n, shopids: n.SERVERPARTSHOP_ID ? n.SERVERPARTSHOP_ID.split(',') : [] }
})
}
}}
options={false}
columns={revenuenColumns}
pagination={false}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
setSelectShops(selectedRows)
}
}}
toolbar={{
actions: [
// react打印插件
<ReactToPrint
// 打印内容的页面留白
pageStyle="@page { 15mm 15mm}"
// 显示的东西吧 button 在里面被点击触发content里面的事件
trigger={() => (
<Button key="printout" type="default"
>
</Button>
)}
// 点击触发的事件
content={() => {
// printOut是整个页面的dom 一般情况都是有的
if (printOut) {
// 标题 先找到标题的dom元素
const title = document.createElement('p')
// 设置标题dom元素的内容
title.innerHTML = `${currentServiceName}合作单位保底提成结算表`
// 给标题dom设置样式
title.setAttribute('style', 'font-size:20px;font-weight:600;display:flex;width:100%;justify-content: center;')
// 日期时间 timeUnit为父节点 time和date为子节点 显示打印内容标题下面 表格上面的那一块区域
const timeUnit = document.createElement('div')
const time = document.createElement('div')
const date = document.createElement('div')
// 时间显示的内容
time.innerHTML = `日期: ${moment().format('YYYY年MM月DD日')}`
date.innerHTML = `单位: 元`
// 加入到父节点中去
timeUnit.appendChild(time)
timeUnit.appendChild(date)
// 样式
timeUnit.setAttribute('style', 'width:100%;display:flex;justify-content: space-between;margin-bottom:15px;')
// 数据内容 打印的表格dom
// 表格的dom元素
const dataList = document.getElementsByClassName('ant-table-content')
// 克隆出来不影响原页面
const domNoChange = dataList[0].cloneNode(true)
// 拿到是不是有已经被选中的行
const length = selectShops ? selectShops.length : false
if (length) {
// 拿到表头的dom
const tableHeader = domNoChange.getElementsByClassName('ant-table-thead')
// 表头增加样式
tableHeader[0].setAttribute('style', 'width:100%;background: #fafafa;')
// 拿到每一列的标题
const th = tableHeader[0].getElementsByTagName("th");
// 由于页面的表头和效果图要的不一样 所以就自定义一个效果图上要的表头数组
// 由于这个页面莫名其妙在每行的后面都有一个空节点,所以最后给他赋值个空的
const titleText = ['合作单位', '结算起止时间', '营业额', '提成标准', '提成额', '保证租金', '备注说明', '']
const headList: { innerHTML: string; }[] = []
// th的第一个节点删除是因为要把选择框的节点去掉 打印不能有选择框出现
th.forEach((item: { innerHTML: string; }, index: string | number) => {
if (index === 0) {
item.remove()
} else if (index <= 7 && index !== 0) {
// 页面需要的节点 给他赋值上需要的标题 然后添加到一个数组里面
item.innerHTML = titleText[index]
headList.push(item)
}
})
// 不让标题内容换行 minWidth无法适配 只能不换行来满足需求
th.forEach((item: { innerHTML: string; }, index: string | number) => {
// 因为最后一个节点还是空节点所以不让最后一个不换行 其实问题也不大
if (index !== th.length - 1) {
item.style.whiteSpace = 'nowrap'
}
})
// 表单打印的数据内容
// 表单的数据节点
const tableBody = domNoChange.getElementsByClassName('ant-table-tbody')
// 每一行数据
const tr = tableBody[0].getElementsByTagName('tr')
// 哪几行是没被选中的索引列表
const numList: any[] = []
// 遍历每一行数据
tr.forEach((item: { getElementsByClassName: (arg0: string) => any; }, index: any) => {
// 拿到打钩的那个节点 如果这个节点下的checked节点为true那就是被选中了 false就是没选中
const isChecked = item.getElementsByClassName('ant-checkbox-input')
// 没被选中的行数的索引被添加到数组中
if (!isChecked[0].checked) {
numList.push(index)
}
})
// 倒序的for循环 正序的话当一个节点删除时 下一个节点会到刚刚删除的节点位置 无法参与判断
// 如果是没选中的节点就直接移除掉 留下来的节点都是选中的节点
for (let i = tr.length - 1; i >= 0; i -= 1) {
numList.forEach(item => {
if (i === item) {
tr[i].remove()
}
})
}
// 选中的节点继续遍历
tr.forEach((item: { getElementsByClassName: (arg0: string) => any; }, index: any) => {
// 因为页面的dom元素和要求图的dom元素不一样 所以用list先存页面中的数据
const list: any[] = []
// 获得每一行的 每一列对应的节点
const td = item.getElementsByTagName('td')
// 遍历一行的数据
td.forEach((subItem: { innerHTML: any; }, subIndex: number) => {
// 背景都变成白色
subItem.style.backgroundColor = 'white'
// 因为td的第一项是选择框 所以不放进数据列表中
if (subIndex >= 1) {
list.push(subItem.innerHTML)
}
})
// 把选择框的dom节点移除
td[0].remove()
// 拼接数据
td.forEach((subItem: { innerHTML: string; }, subIndex: number) => {
subItem.style.backgroundColor = 'white'
if (subIndex === 0) {
subItem.innerHTML = list[0]
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex === 1) {
// 时间数据的拼接
subItem.innerHTML = `${moment(list[1]).format('YYYY年MM月DD日')} - ${moment(list[2]).format('YYYY年MM月DD日')}`
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex > 1 && subIndex <= 6) {
// 因为上面拼接了一个 所以索引加1 小于6 是因为 要求的数据只有七行 但是会有一个空节点
subItem.innerHTML = list[subIndex + 1]
if (subIndex !== 6) {
// 备注就让它可以换行
subItem.style.whiteSpace = 'nowrap'
}
} else {
subItem.style.backgroundColor = 'white'
}
})
})
} else {
// 没有选中任何一行 就默认打印全部
// 表头dom节点 逻辑和上面差不多 就是没有了是否选中的判断
const tableHeader = domNoChange.getElementsByClassName('ant-table-thead')
const th = tableHeader[0].getElementsByTagName("th");
const titleText = ['合作单位', '结算起止时间', '营业额', '提成标准', '提成额', '保证租金', '备注说明', '']
const headList: { innerHTML: string; }[] = []
th[0].remove()
th.forEach((item: { innerHTML: string; }, index: string | number) => {
if (index !== th.length - 1) {
item.style.whiteSpace = 'nowrap'
}
if (index <= 7 && index >= 0) {
item.innerHTML = titleText[index]
headList.push(item)
} else {
item.style.maxWidth = '0px'
}
})
// 数据内容
const tableBody = domNoChange.getElementsByClassName('ant-table-tbody')
const tr = tableBody[0].getElementsByTagName('tr')
// 先遍历每一行的数据 拿到每一行中的数据
tr.forEach((item: { getElementsByTagName: (arg0: string) => any; }, index: any) => {
const list: any[] = []
const td = item.getElementsByTagName('td')
// 再对每一行的数据进行遍历 把原本的值先存一份
td.forEach((subItem: { innerHTML: any; }, subIndex: number) => {
if (subIndex >= 1) {
list.push(subItem.innerHTML)
}
})
td[0].remove()
td.forEach((subItem: { innerHTML: string; }, subIndex: number) => {
if (subIndex === 0) {
subItem.innerHTML = list[0]
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex === 1) {
subItem.innerHTML = `${moment(list[1]).format('YYYY年MM月DD日')} - ${moment(list[2]).format('YYYY年MM月DD日')}`
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex > 1 && subIndex <= 6) {
subItem.innerHTML = list[subIndex + 1]
if (subIndex !== 6) {
subItem.style.whiteSpace = 'nowrap'
}
} else {
item.setAttribute('style', 'width: 0%')
}
})
})
}
// 表单底部签字盖章数据
// 创建一个父节点 下面三个子节点 然后flex布局变掉 加一个当前用户的名称就可以
const currentUser = session.get('currentUser');
const signAndSeal = document.createElement('div')
signAndSeal.setAttribute('style', 'width:100%;display:flex;align-item:center;justify-content: space-between;margin-top:20px')
const serviceSeal = document.createElement('div')
const companySeal = document.createElement('div')
const makeExcel = document.createElement('div')
serviceSeal.innerHTML = '服务区 (签字盖章) :'
companySeal.innerHTML = '合作单位 (签字盖章) :'
makeExcel.innerHTML = `制表人 : ${currentUser.Name}`
makeExcel.setAttribute('style', 'text-align:right')
signAndSeal.appendChild(serviceSeal)
signAndSeal.appendChild(companySeal)
signAndSeal.appendChild(makeExcel)
// printContract方法也就是把第一个形参数组里面的每一项拼到一个父节点的里面 然后return出来
const ele = printContract([title || '', timeUnit || '', domNoChange || '', signAndSeal || ''], '');
// content方法中return出来的值 就会自动调起ReactToPrint依赖 然后根据ele来打印
return ele
}
// 拿不到整个页面dom就输出空 但是一般不会拿不到
return ''
}}
/>,
<Button
type="primary"
onClick={async () => {
const nowColumns = revenuenColumns.filter(n => !n.hideInTable)
const fat = nowColumns.map((n: any, index: number) => {
if (n?.children) {
return n?.children.map((m: { title: any; }) => {
const title = index === 0 ? m.title : n.title + m.title
return { ...m, title }
})
}
return n
})
console.log('tableData', tableData)
const dataList: any = JSON.parse(JSON.stringify(tableData))
dataList.forEach((item: any) => {
item.BUSINESS_ENDDATE = moment(item.BUSINESS_ENDDATE).format('YYYY-MM-DD')
item.BUSINESS_STARTDATE = moment(item.BUSINESS_STARTDATE).format('YYYY-MM-DD')
})
const success = await exportExcel(
// flat 就是数组维度降一层
fat.flat(),
dataList || [],
`${serviceName}合作单位保底提成结算表${moment().format('YYYY/MM/DD')}`,
);
if (success.message !== 'ok') {
message.info({ content: success.message });
}
}}
>
excel
</Button>
// <ReactToPrint
// pageStyle="@page { 15mm 15mm}"
// trigger={() => (
// <Button key="printout" type="default"
// style={{marginRight: '30px'}}
// >
// 导出
// </Button>
// )}
// content={() => {
// // printOut是整个页面的dom 一般情况都是有的
// if (printOut){
// const ele = handlePrint(printOut)
// return ele
// }
// return ''
// }}
// />
]
}}
/>
</ProCard>
</ProCard>
{/* 查看项目详情 右侧弹出的抽屉 */}
<Drawer
width="80%"
className="project-drawer"
visible={showDetail} // 抽屉弹框是否显示状态
onClose={() => { // 关闭抽屉 设置抽屉状态为关闭
setShowDetail(false);
setProject(undefined);
setCurrentRow(undefined);
}}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
closable={false}
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
extra={<MenuFoldOutlined onClick={() => { setCollapsible(!collapsible) }} />}
colSpan={!collapsible ? "300px" : "60px"}
title={!collapsible ? "请选择服务区" : ""}
headerBordered
collapsed={collapsible}
>
{/* 抽屉打开时 加载项目详情组件 */}
{showDetail && <RevenueList propsBP={curProject} propsRC={currentRow}
ShopRoyaltyId={currentRow?.SHOPROYALTY_ID ? currentRow?.SHOPROYALTY_ID : 0}
ShopIds={currentRow?.SERVERPARTSHOP_ID ? currentRow?.SERVERPARTSHOP_ID : ''}
StartDate={moment(currentRow?.BUSINESS_STARTDATE).format('YYYY-MM-DD')}
EndDate={moment(currentRow?.BUSINESS_ENDDATE).format('YYYY-MM-DD')} BusinessProjectId={currentRow?.BUSINESSPROJECT_ID}></RevenueList>}
</Drawer>
</PageContainer>
</div>
{!treeLoading && <Menu
mode="inline"
style={{ height: 'calc(100vh - 220px)', overflowY: 'auto', overflowX: 'hidden' }}
selectedKeys={selectedId}
onSelect={(item) => {
// 拿到选择的服务区名称给导出的文件赋值
if (treeView && treeView.length > 0) {
treeView.forEach((i: any) => {
if (i.children && i.children.length > 0) {
i.children.forEach((subItem: any) => {
if (subItem.key === item.key) {
setSelectServiceName(subItem.label)
}
})
}
})
}
loadSelectedId(item)
}}
>
{getMenuDom(treeView, loadSelectedId)}
</Menu>}
</ProCard>
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
bordered={true}
rowKey="REVENUECONFIRM_ID"
headerTitle={<PageTitleBox props={props} />}
actionRef={actionRef}
scroll={{ x: "100%", y: "calc(100vh - 400px)" }}
search={{ span: 6, labelWidth: 'auto' }}
// manualRequest={true} // 是否需要手动触发首次请求, 配置为 true 时不可隐藏搜索表单
request={async (pramas, sorter) => {
const sortstr = Object.keys(sorter).map(n => {
const value = sorter[n]
return value ? `${n} ${value.replace('end', '')}` : ''
})
const data = await getRevenueConfirmList({
ServerpartId: selectedId && selectedId.length > 0 ? selectedId[0].split('-')[1] : currenMenu || '0',
StartDate: pramas.StartDate || '',
EndDate: pramas.EndDate || '',
sortstr: sortstr.toString()
} as RevenueConfirmParams
)
let fieldData: any = [
"ACTUAL_REVENUE",
"PARTYA_SHAREPROFIT",
"GUARANTEE_AMOUNT",
]
let enumList: any = []
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data.data)), fieldData, enumList, [], ["GUARANTEERATIO"])
setReqDetailList(newPrintData)
setTableData(data.data)
return {
...data, data: data.data.map((n: RevenueConfirmModel) => {
return { ...n, shopids: n.SERVERPARTSHOP_ID ? n.SERVERPARTSHOP_ID.split(',') : [] }
})
}
}}
options={false}
columns={revenuenColumns}
pagination={false}
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
setSelectShops(selectedRows)
}
}}
toolbar={{
actions: [
// react打印插件
<ReactToPrint
// 打印内容的页面留白
pageStyle="@page { 15mm 15mm}"
// 显示的东西吧 button 在里面被点击触发content里面的事件
trigger={() => (
<Button key="printout" type="default"
>
</Button>
)}
// 点击触发的事件
content={() => {
// printOut是整个页面的dom 一般情况都是有的
if (printOut) {
// 标题 先找到标题的dom元素
const title = document.createElement('p')
// 设置标题dom元素的内容
title.innerHTML = `${currentServiceName}合作单位保底提成结算表`
// 给标题dom设置样式
title.setAttribute('style', 'font-size:20px;font-weight:600;display:flex;width:100%;justify-content: center;')
// 日期时间 timeUnit为父节点 time和date为子节点 显示打印内容标题下面 表格上面的那一块区域
const timeUnit = document.createElement('div')
const time = document.createElement('div')
const date = document.createElement('div')
// 时间显示的内容
time.innerHTML = `日期: ${moment().format('YYYY年MM月DD日')}`
date.innerHTML = `单位: 元`
// 加入到父节点中去
timeUnit.appendChild(time)
timeUnit.appendChild(date)
// 样式
timeUnit.setAttribute('style', 'width:100%;display:flex;justify-content: space-between;margin-bottom:15px;')
// 数据内容 打印的表格dom
// 表格的dom元素
const dataList = document.getElementsByClassName('ant-table-content')
// 克隆出来不影响原页面
const domNoChange = dataList[0].cloneNode(true)
// 拿到是不是有已经被选中的行
const length = selectShops ? selectShops.length : false
if (length) {
// 拿到表头的dom
const tableHeader = domNoChange.getElementsByClassName('ant-table-thead')
// 表头增加样式
tableHeader[0].setAttribute('style', 'width:100%;background: #fafafa;')
// 拿到每一列的标题
const th = tableHeader[0].getElementsByTagName("th");
// 由于页面的表头和效果图要的不一样 所以就自定义一个效果图上要的表头数组
// 由于这个页面莫名其妙在每行的后面都有一个空节点,所以最后给他赋值个空的
const titleText = ['合作单位', '结算起止时间', '营业额', '提成标准', '提成额', '保证租金', '备注说明', '']
const headList: { innerHTML: string; }[] = []
// th的第一个节点删除是因为要把选择框的节点去掉 打印不能有选择框出现
th.forEach((item: { innerHTML: string; }, index: string | number) => {
if (index === 0) {
item.remove()
} else if (index <= 7 && index !== 0) {
// 页面需要的节点 给他赋值上需要的标题 然后添加到一个数组里面
item.innerHTML = titleText[index]
headList.push(item)
}
})
// 不让标题内容换行 minWidth无法适配 只能不换行来满足需求
th.forEach((item: { innerHTML: string; }, index: string | number) => {
// 因为最后一个节点还是空节点所以不让最后一个不换行 其实问题也不大
if (index !== th.length - 1) {
item.style.whiteSpace = 'nowrap'
}
})
// 表单打印的数据内容
// 表单的数据节点
const tableBody = domNoChange.getElementsByClassName('ant-table-tbody')
// 每一行数据
const tr = tableBody[0].getElementsByTagName('tr')
// 哪几行是没被选中的索引列表
const numList: any[] = []
// 遍历每一行数据
tr.forEach((item: { getElementsByClassName: (arg0: string) => any; }, index: any) => {
// 拿到打钩的那个节点 如果这个节点下的checked节点为true那就是被选中了 false就是没选中
const isChecked = item.getElementsByClassName('ant-checkbox-input')
// 没被选中的行数的索引被添加到数组中
if (!isChecked[0].checked) {
numList.push(index)
}
})
// 倒序的for循环 正序的话当一个节点删除时 下一个节点会到刚刚删除的节点位置 无法参与判断
// 如果是没选中的节点就直接移除掉 留下来的节点都是选中的节点
for (let i = tr.length - 1; i >= 0; i -= 1) {
numList.forEach(item => {
if (i === item) {
tr[i].remove()
}
})
}
// 选中的节点继续遍历
tr.forEach((item: { getElementsByClassName: (arg0: string) => any; }, index: any) => {
// 因为页面的dom元素和要求图的dom元素不一样 所以用list先存页面中的数据
const list: any[] = []
// 获得每一行的 每一列对应的节点
const td = item.getElementsByTagName('td')
// 遍历一行的数据
td.forEach((subItem: { innerHTML: any; }, subIndex: number) => {
// 背景都变成白色
subItem.style.backgroundColor = 'white'
// 因为td的第一项是选择框 所以不放进数据列表中
if (subIndex >= 1) {
list.push(subItem.innerHTML)
}
})
// 把选择框的dom节点移除
td[0].remove()
// 拼接数据
td.forEach((subItem: { innerHTML: string; }, subIndex: number) => {
subItem.style.backgroundColor = 'white'
if (subIndex === 0) {
subItem.innerHTML = list[0]
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex === 1) {
// 时间数据的拼接
subItem.innerHTML = `${moment(list[1]).format('YYYY年MM月DD日')} - ${moment(list[2]).format('YYYY年MM月DD日')}`
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex > 1 && subIndex <= 6) {
// 因为上面拼接了一个 所以索引加1 小于6 是因为 要求的数据只有七行 但是会有一个空节点
subItem.innerHTML = list[subIndex + 1]
if (subIndex !== 6) {
// 备注就让它可以换行
subItem.style.whiteSpace = 'nowrap'
}
} else {
subItem.style.backgroundColor = 'white'
}
})
})
} else {
// 没有选中任何一行 就默认打印全部
// 表头dom节点 逻辑和上面差不多 就是没有了是否选中的判断
const tableHeader = domNoChange.getElementsByClassName('ant-table-thead')
const th = tableHeader[0].getElementsByTagName("th");
const titleText = ['合作单位', '结算起止时间', '营业额', '提成标准', '提成额', '保证租金', '备注说明', '']
const headList: { innerHTML: string; }[] = []
th[0].remove()
th.forEach((item: { innerHTML: string; }, index: string | number) => {
if (index !== th.length - 1) {
item.style.whiteSpace = 'nowrap'
}
if (index <= 7 && index >= 0) {
item.innerHTML = titleText[index]
headList.push(item)
} else {
item.style.maxWidth = '0px'
}
})
// 数据内容
const tableBody = domNoChange.getElementsByClassName('ant-table-tbody')
const tr = tableBody[0].getElementsByTagName('tr')
// 先遍历每一行的数据 拿到每一行中的数据
tr.forEach((item: { getElementsByTagName: (arg0: string) => any; }, index: any) => {
const list: any[] = []
const td = item.getElementsByTagName('td')
// 再对每一行的数据进行遍历 把原本的值先存一份
td.forEach((subItem: { innerHTML: any; }, subIndex: number) => {
if (subIndex >= 1) {
list.push(subItem.innerHTML)
}
})
td[0].remove()
td.forEach((subItem: { innerHTML: string; }, subIndex: number) => {
if (subIndex === 0) {
subItem.innerHTML = list[0]
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex === 1) {
subItem.innerHTML = `${moment(list[1]).format('YYYY年MM月DD日')} - ${moment(list[2]).format('YYYY年MM月DD日')}`
subItem.style.whiteSpace = 'nowrap'
} else if (subIndex > 1 && subIndex <= 6) {
subItem.innerHTML = list[subIndex + 1]
if (subIndex !== 6) {
subItem.style.whiteSpace = 'nowrap'
}
} else {
item.setAttribute('style', 'width: 0%')
}
})
})
}
// 表单底部签字盖章数据
// 创建一个父节点 下面三个子节点 然后flex布局变掉 加一个当前用户的名称就可以
const currentUser = session.get('currentUser');
const signAndSeal = document.createElement('div')
signAndSeal.setAttribute('style', 'width:100%;display:flex;align-item:center;justify-content: space-between;margin-top:20px')
const serviceSeal = document.createElement('div')
const companySeal = document.createElement('div')
const makeExcel = document.createElement('div')
serviceSeal.innerHTML = '服务区 (签字盖章) :'
companySeal.innerHTML = '合作单位 (签字盖章) :'
makeExcel.innerHTML = `制表人 : ${currentUser.Name}`
makeExcel.setAttribute('style', 'text-align:right')
signAndSeal.appendChild(serviceSeal)
signAndSeal.appendChild(companySeal)
signAndSeal.appendChild(makeExcel)
// printContract方法也就是把第一个形参数组里面的每一项拼到一个父节点的里面 然后return出来
const ele = printContract([title || '', timeUnit || '', domNoChange || '', signAndSeal || ''], '');
// content方法中return出来的值 就会自动调起ReactToPrint依赖 然后根据ele来打印
return ele
}
// 拿不到整个页面dom就输出空 但是一般不会拿不到
return ''
}}
/>,
<Button
type="primary"
onClick={async () => {
if (reqDetailList && reqDetailList.length > 0) {
// 尝试一下 导出新方法
exportXlsxFromProColumnsExcelJS(revenuenColumns,
reqDetailList,
`${serviceName}合作单位保底提成结算表${moment().format('YYYY/MM/DD')}`,
// {
// topTitle: `库存信息统计表`, // 顶部大标题
// }
)
} else {
message.error('暂无数据可导出!')
}
// const nowColumns = revenuenColumns.filter(n => !n.hideInTable)
// const fat = nowColumns.map((n: any, index: number) => {
// if (n?.children) {
// return n?.children.map((m: { title: any; }) => {
// const title = index === 0 ? m.title : n.title + m.title
// return { ...m, title }
// })
// }
// return n
// })
// console.log('tableData', tableData)
// const dataList: any = JSON.parse(JSON.stringify(tableData))
// dataList.forEach((item: any) => {
// item.BUSINESS_ENDDATE = moment(item.BUSINESS_ENDDATE).format('YYYY-MM-DD')
// item.BUSINESS_STARTDATE = moment(item.BUSINESS_STARTDATE).format('YYYY-MM-DD')
// })
// const success = await exportExcel(
// // flat 就是数组维度降一层
// fat.flat(),
// dataList || [],
// `${serviceName}合作单位保底提成结算表${moment().format('YYYY/MM/DD')}`,
// );
// if (success.message !== 'ok') {
// message.info({ content: success.message });
// }
}}
>
excel
</Button>
// <ReactToPrint
// pageStyle="@page { 15mm 15mm}"
// trigger={() => (
// <Button key="printout" type="default"
// style={{marginRight: '30px'}}
// >
// 导出
// </Button>
// )}
// content={() => {
// // printOut是整个页面的dom 一般情况都是有的
// if (printOut){
// const ele = handlePrint(printOut)
// return ele
// }
// return ''
// }}
// />
]
}}
/>
</div>
</div>
{/* 查看项目详情 右侧弹出的抽屉 */}
<Drawer
width="80%"
className="project-drawer"
visible={showDetail} // 抽屉弹框是否显示状态
onClose={() => { // 关闭抽屉 设置抽屉状态为关闭
setShowDetail(false);
setProject(undefined);
setCurrentRow(undefined);
}}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
closable={false}
>
{/* 抽屉打开时 加载项目详情组件 */}
{showDetail && <RevenueList propsBP={curProject} propsRC={currentRow}
ShopRoyaltyId={currentRow?.SHOPROYALTY_ID ? currentRow?.SHOPROYALTY_ID : 0}
ShopIds={currentRow?.SERVERPARTSHOP_ID ? currentRow?.SERVERPARTSHOP_ID : ''}
StartDate={moment(currentRow?.BUSINESS_STARTDATE).format('YYYY-MM-DD')}
EndDate={moment(currentRow?.BUSINESS_ENDDATE).format('YYYY-MM-DD')} BusinessProjectId={currentRow?.BUSINESSPROJECT_ID}></RevenueList>}
</Drawer>
</div >
);
}

View File

@ -31,6 +31,7 @@ import RevenueSecondList from "../revenueConfirmation/components/RevenueSecondLi
import { point } from "@antv/g2plot";
import CalibrationDifference from "./component/calibrationDifference";
import { handleHighPrecision } from "@/utils/utils";
import LeftSelectTree from "../settlementAccount/component/leftSelectTree";
const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -1239,7 +1240,14 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
const selectedAreaIds = info.checkedNodes.filter(n => n?.type === 0)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
console.log('selectedAreaIds', selectedAreaIds.map(n => n?.value)?.toString() || '');
setSelectAreaId(selectedAreaIds.map(n => n?.value)?.toString() || '')
}} />
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -1277,7 +1285,7 @@ const revenueConfirmationDifference: React.FC<{ currentUser: CurrentUser }> = (p
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -30,6 +30,7 @@ import session from '@/utils/session';
import { handleGetListObj } from '@/utils/utils';
import LeftSelectTree from '../../settlementAccount/component/leftSelectTree';
import BusinessanalysisDetail from "@/pages/reports/Finance/businessAnalysis/components/businessanalysisDetail";
import { formatTreeData } from '@/utils/format';
const handelDelete = async (investmentanalysisid: number) => {
@ -294,7 +295,7 @@ const INVESTMENTANALYSISTable: React.FC<{ currentUser: CurrentUser | undefined }
},
{
dataIndex: 'SERVERPART_NAME',
dataIndex: 'SERVERPARTSHOP_NAME|SERVERPART_NAME|SERVERPART_NAME',
title: '服务区名称',
align: 'center',
hideInSearch: true,
@ -970,7 +971,43 @@ const INVESTMENTANALYSISTable: React.FC<{ currentUser: CurrentUser | undefined }
}
})
setReqDetailList(data)
let fieldData: any = [
"ADJUST_RENT",
"MINTURNOVER",
"ADJUST_AMOUNT",
"GUARANTEE_MINPRICE",
"GUARANTEE_MAXPRICE",
"GUARANTEE_AVGPRICE",
"PROFIT_AMOUNT",
"REVENUE_LASTAMOUNT",
"PROFIT_TOTALAMOUNT",
]
let enumList: any = [
"SERVERPART_TYPE",
"BUSINESS_TRADE",
"BUSINESS_PTRADE",
]
let rateList: any = [
"RENT_RATIO",
"PERIOD_DEGREE",
"ADJUST_RATIO",
"GUARANTEERATIO",
"RATIOCHANGE",
"COMMISSION_RATIO",
"PROFIT_AVG",
"COMMISSION_MINRATIO",
"COMMISSION_MAXRATIO",
"COMMISSION_AVGRATIO",
]
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data)), fieldData, enumList, [ServerpartTypeObj, BusinessTradeIdsObj, BusinessTradeIdsObj], rateList)
setReqDetailList(newPrintData)
setUpdateTime(data[0].RECORD_DATE ? moment(data[0].RECORD_DATE).format('YYYY-MM-DD') : '')
console.log('datadatadata', data);

View File

@ -25,6 +25,7 @@ import ReactHTMLTableToExcel from "react-html-table-to-excel";
import Finance from "@/pages/reports/Finance/index";
import Merchant from '@/pages/reports/ShopExpenseDetail/detail'
import './RevenueSplit.less'
import LeftSelectTree from '../settlementAccount/component/leftSelectTree';
const { Text } = Typography;
@ -63,12 +64,12 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [expandRow, setExpandRow] = useState<string[]>([]); // 选择打开的服务区
const [reqDetailList, setReqDetailList] = useState<ProjectSplitSummaryModel[]>(); // 合计项数据源
const [fileName,setFileName] = useState<string>()// 文件名称
const [showDrawer,setShowDrawer] = useState<boolean>(false)// 抽屉是否打开
const [showAmount,setShowAmount] = useState<boolean>(false)// 商家缴款的抽屉
const [currentRow,setCurrentRow] = useState<any>()
const [searchTime,setSearchTime] = useState<any>()// 时间
const [serviceShopId,setServiceShopId] = useState<string>('')// 选中的门店id
const [fileName, setFileName] = useState<string>()// 文件名称
const [showDrawer, setShowDrawer] = useState<boolean>(false)// 抽屉是否打开
const [showAmount, setShowAmount] = useState<boolean>(false)// 商家缴款的抽屉
const [currentRow, setCurrentRow] = useState<any>()
const [searchTime, setSearchTime] = useState<any>()// 时间
const [serviceShopId, setServiceShopId] = useState<string>('')// 选中的门店id
// 请求服务区树列表
const { loading: treeLoading, data: treeView } = useRequest(async () => {
return getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, false, true)
@ -76,7 +77,7 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
const [collapsible, setCollapsible] = useState<boolean>(false)
const [selectedId, setSelectedId] = useState<string>()
// 是否显示打印的表格
const [showExportTable,setShowExportTable] = useState<boolean>(false)
const [showExportTable, setShowExportTable] = useState<boolean>(false)
const columns: ProColumns<ProjectSplitSummaryModel>[] = [
{
title: '序号',
@ -89,16 +90,16 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
dataIndex: 'MERCHANTS_NAME',
title: '经营单位',
align: 'left',
ellipsis:true,
ellipsis: true,
hideInSearch: true,
hideInDescriptions: true,
render: (_, record) => {
return <span onClick={()=>{
if (record.index && record.index.indexOf('.')!==-1){
return <span onClick={() => {
if (record.index && record.index.indexOf('.') !== -1) {
setCurrentRow(record.BUSINESSPROJECT_ID)
setShowDrawer(true)
}
}} style={{color:record.index && record.index.indexOf('.')!==-1?'#1890ff':'',cursor:record.index && record.index.indexOf('.')!==-1?'pointer':''}}>
}} style={{ color: record.index && record.index.indexOf('.') !== -1 ? '#1890ff' : '', cursor: record.index && record.index.indexOf('.') !== -1 ? 'pointer' : '' }}>
{record?.MERCHANTS_NAME || record?.SERVERPART_NAME || record?.SPREGIONTYPE_NAME}
</span>
},
@ -126,13 +127,13 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
hideInDescriptions: true,
valueType: 'digit',
render: (_, record) => {
return <span onClick={()=>{
if (record.index && record.index.indexOf('.')!==-1){
return <span onClick={() => {
if (record.index && record.index.indexOf('.') !== -1) {
setServiceShopId(record.SERVERPARTSHOP_ID.split(',')[0])
setShowAmount(true)
}
}}style={{color:record.index && record.index.indexOf('.')!==-1?'#1890ff':'',cursor:record.index && record.index.indexOf('.')!==-1?'pointer':''}}>
}} style={{ color: record.index && record.index.indexOf('.') !== -1 ? '#1890ff' : '', cursor: record.index && record.index.indexOf('.') !== -1 ? 'pointer' : '' }}>
{record?.ACCOUNT_AMOUNT}
</span>
},
@ -195,21 +196,21 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
},
},
]
useEffect(()=>{
useEffect(() => {
actionRef.current?.reload()
},[props.ServerpartId])
}, [props.ServerpartId])
// 把数据处理的更加细节
const handleGetDateDetail = (showIndexList: any,params: any,objList: any,item: any)=>{
showIndexList.forEach((smallItem: any,smallIndex: number)=>{
const res = params.filter((paramsItem: any)=>smallItem.dataIndex===paramsItem.name)
if (res && res.length>0){
if (res[0].type==='render'){
const handleGetDateDetail = (showIndexList: any, params: any, objList: any, item: any) => {
showIndexList.forEach((smallItem: any, smallIndex: number) => {
const res = params.filter((paramsItem: any) => smallItem.dataIndex === paramsItem.name)
if (res && res.length > 0) {
if (res[0].type === 'render') {
objList[smallIndex].innerText = res[0].fun(item)
}else if(res[0].type==='select'){
objList[smallIndex].innerText = res[0].fun[item[smallItem.dataIndex]] ? res[0].fun[item[smallItem.dataIndex]] :'-'
} else if (res[0].type === 'select') {
objList[smallIndex].innerText = res[0].fun[item[smallItem.dataIndex]] ? res[0].fun[item[smallItem.dataIndex]] : '-'
}
}else{
} else {
objList[smallIndex].innerText = item[smallItem.dataIndex]
}
})
@ -316,7 +317,7 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// const tableToXls = document.getElementById('RevenueSplit-to-xls')
// container.removeChild(tableToXls)
// }
const handleMERCHANTSNAME = (record: any)=>{
const handleMERCHANTSNAME = (record: any) => {
return record?.MERCHANTS_NAME || record?.SERVERPART_NAME || record?.SPREGIONTYPE_NAME
}
@ -345,7 +346,7 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// 打印报表
setPrintOut(el);
}}>
<div className={'revenueSplitHideBox'} style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}>
<div className={'revenueSplitHideBox'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
@ -358,68 +359,34 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
/> : ''
}
</div>
<div id='hiddenBox' style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}/>
<ProCard split="vertical"
style={{height: props.isComponents ? '' : 'calc(100vh - 130px)', backgroundColor: '#fff'}}>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ height: props.isComponents ? '' : 'calc(100vh - 130px)', backgroundColor: '#fff', display: 'flex' }}>
{
// 判断是不是组件 是组件的话 左边的选择列表就不会显示
props.isComponents ?
<>
</> :
<ProCard
className="pageTable-leftnav"
bodyStyle={{padding: 0, paddingTop: 20, paddingLeft: 20}}
extra={<MenuFoldOutlined onClick={() => {
setCollapsible(!collapsible)
}}/>}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "请选择服务区" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={!treeLoading ? [{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}] : []}
fieldNames={{
title: "label",
key: "key"
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
// actionRef?.current?.reload()
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
}
<ProCard bodyStyle={{
position: 'relative',
height: props.isComponents ? '' : "calc(100vh - 145px)",
width: props.isComponents ? '' : 'calc(100vw - 500px)',
<div style={{
width: props.isComponents ? '' : !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<div id='RevenueSplit' style={{position: 'absolute', zIndex: -1, top: 0, left: 0}}/>
<div id='RevenueSplit' style={{ position: 'absolute', zIndex: -1, top: 0, left: 0 }} />
<ProTable<ProjectSplitSummaryModel>
rowKey={(record) => {
return `${`${record?.SPREGIONTYPE_ID}|${record?.SERVERPART_ID}|${record?.SERVERPARTSHOP_ID}`}`
}}
className={props.isComponents && reqDetailList && reqDetailList.length === 0 ? 'RevenueSplitProTable hideBottom' : props.isComponents ? 'RevenueSplitProTable' : ''}
headerTitle={<span
style={{color: reqDetailList && reqDetailList.length > 0 ? '' : 'red'}}>{reqDetailList && reqDetailList.length > 0 ? "合作单位营业额分成到账汇总表" : "*服务区未有营收分润项目"}</span>} // 列表表头
style={{ color: reqDetailList && reqDetailList.length > 0 ? "#1890ff" : 'red', fontSize: 14, fontWeight: 600 }}>{reqDetailList && reqDetailList.length > 0 ? "合作单位营业额分成到账汇总表" : "*服务区未有营收分润项目"}</span>} // 列表表头
actionRef={actionRef}
formRef={formRef}
scroll={{y: 'calc(100vh - 560px)'}}
search={{span: 6, labelWidth: 'auto'}}
scroll={{ y: 'calc(100vh - 560px)' }}
search={{ span: 6, labelWidth: 'auto' }}
// 请求数据
request={async (params) => {
if (selectedId || props.ServerpartId) {
@ -462,15 +429,15 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
pagination={false}
toolbar={{
actions: [
<span style={{visibility: 'hidden'}}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-revenueSplit"
filename={`合作商户资金到账汇总报表_${moment().format('YYYY_MM_DD')}`}
sheet="sheet1"
/>
</span>,
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-revenueSplit"
filename={`合作商户资金到账汇总报表_${moment().format('YYYY_MM_DD')}`}
sheet="sheet1"
/>
</span>,
<Typography.Text type="secondary"></Typography.Text>,
<ReactToPrint
trigger={() => (
@ -494,12 +461,12 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
key="new"
type="primary"
onClick={async (e) => {
if(reqDetailList && reqDetailList.length>0){
if (reqDetailList && reqDetailList.length > 0) {
setShowExportTable(true)
setTimeout(()=>{
setTimeout(() => {
exportTable(e)
},100)
}else{
}, 100)
} else {
message.error('暂无数据可导出!')
}
// if (reqDetailList) {
@ -550,7 +517,7 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
CASHPAY_AMOUNT: number, MOBILEPAY_AMOUNT: number, REVENUE_AMOUNT: number,
SUBROYALTY_PRICE: number, ROYALTY_PRICE: number,
}, currentValue: ProjectSplitSummaryModel) => {
const previousValue = {...p}
const previousValue = { ...p }
previousValue.CASHPAY_AMOUNT = numeral(numeral(previousValue.CASHPAY_AMOUNT +
(currentValue.CASHPAY_AMOUNT || 0)).format('0.00')).value() || 0;
previousValue.MOBILEPAY_AMOUNT = numeral(numeral(previousValue.MOBILEPAY_AMOUNT +
@ -566,17 +533,17 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
CASHPAY_AMOUNT: 0, MOBILEPAY_AMOUNT: 0, REVENUE_AMOUNT: 0, SUBROYALTY_PRICE: 0, ROYALTY_PRICE: 0
});
// 显示在列表上方是的类型合计
return <div style={{paddingLeft: 30, paddingBottom: 0}}>
return <div style={{ paddingLeft: 30, paddingBottom: 0 }}>
<ProDescriptions column={3} className="commity-sale-description"
labelStyle={{color: "#00000073"}}
title={<Text type="success"
style={{color: "#1890ff", fontSize: 14}}></Text>}>
labelStyle={{ color: "#00000073" }}
title={<Text type="success"
style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="业主分润">¥{amountDom(reduceData.ROYALTY_PRICE)}</ProDescriptions.Item>
<ProDescriptions.Item
label="商家分润">¥{amountDom(reduceData.SUBROYALTY_PRICE)}</ProDescriptions.Item>
<ProDescriptions.Item label=""></ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={3} className="commity-sale-description" labelStyle={{color: "#00000073"}}>
<ProDescriptions column={3} className="commity-sale-description" labelStyle={{ color: "#00000073" }}>
<ProDescriptions.Item
label="营收金额">¥{amountDom(reduceData.REVENUE_AMOUNT)}</ProDescriptions.Item>
<ProDescriptions.Item
@ -590,8 +557,8 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
return <></>
}}
/>
</ProCard>
</ProCard>
</div>
</div>
{/* 经营门店 */}
<Drawer
width={'70%'}
@ -599,11 +566,11 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
onClose={() => {
setShowDrawer(false);
}}
// maskClosable={false}
// maskClosable={false}
>
{
showDrawer ?
<Finance isComponent={true} time={searchTime} currentRow={currentRow}/>
<Finance isComponent={true} time={searchTime} currentRow={currentRow} />
: ''
}
</Drawer>
@ -617,13 +584,13 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
>
{
showAmount ?
<Merchant isComponent={true} serviceShopId={serviceShopId} time={searchTime}/>
<Merchant isComponent={true} serviceShopId={serviceShopId} time={searchTime} />
: ''
}
</Drawer>
</div>
);
}
export default connect(({user}: ConnectState) => ({
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(ShareBenefit);

View File

@ -19,6 +19,7 @@ import session from "@/utils/session";
import PageTitleBox from "@/components/PageTitleBox";
import AiDrawer from "@/components/AiDrawer";
import { handleChangeKeyTo, handleSetPublicLog } from "@/utils/format";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const { Text } = Typography;
@ -886,41 +887,7 @@ const SpringFestival: React.FC<{ currentUser?: CurrentUser }> = (props) => {
}, [])
return (
<div className={'springFestivalBox'} style={{ background: '#fff', display: 'flex' }}>
<ProCard
className="pageTable-leftnav"
style={{ width: !collapsible ? "240px" : "60px" }}
headStyle={{ width: !collapsible ? "240px" : "60px" }}
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "240px" : "60px" }}
extra={<MenuFoldOutlined onClick={() => {
setCollapsible(!collapsible)
}} />}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "可筛选门店" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={!treeLoading ? [{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}] : []}
fieldNames={{
title: "label",
key: "key"
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
// actionRef?.current?.reload()
}}
/> : ''}
</ProCard>
<div className={'springFestivalBox'} >
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div className={'hideDiv'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
@ -936,131 +903,136 @@ const SpringFestival: React.FC<{ currentUser?: CurrentUser }> = (props) => {
</ProTable> : ''
}
</div>
<ProCard
style={{ width: !collapsible ? "calc(100% - 240px)" : "calc(100% - 60px)" }}
>
<ProTable
style={{ padding: 0 }}
formRef={formRef}
actionRef={actionRef}
search={{
span: 6,
labelWidth: 100,
defaultCollapsed: false,
optionRender: ({ searchText }, { form }) => {
return [
<Button
key="reset"
onClick={() => {
formRef.current?.resetFields();
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
loading={tableLoading}
onClick={() => {
clickTableBtnRef.current = true
formRef.current?.submit();
}}
>
</Button>
]
}
}}
loading={tableLoading}
headerTitle={<PageTitleBox props={props} showAI={true} AIFun={handleGetAIAnalysis} />}
id={'table-to-xls'}
columns={columns}
bordered={true}
scroll={{ x: "100%", y: 'calc(100vh - 450px)' }}
pagination={false}
dataSource={tableData}
request={async (params) => {
console.log('params', params)
if (!selectedId) {
setReqDetailList([])
return
}
if (clickTableBtnRef.current) {
if (params.STATISTICS_DATE) {
setSearchDate(params.STATISTICS_DATE)
} else {
setReqDetailList([])
setSearchDate(undefined)
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
style={{ padding: 0 }}
formRef={formRef}
actionRef={actionRef}
search={{
span: 6,
labelWidth: 100,
defaultCollapsed: false,
optionRender: ({ searchText }, { form }) => {
return [
<Button
key="reset"
onClick={() => {
formRef.current?.resetFields();
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
loading={tableLoading}
onClick={() => {
clickTableBtnRef.current = true
formRef.current?.submit();
}}
>
</Button>
]
}
}}
loading={tableLoading}
headerTitle={<PageTitleBox props={props} showAI={true} AIFun={handleGetAIAnalysis} />}
id={'table-to-xls'}
columns={columns}
bordered={true}
scroll={{ x: "100%", y: 'calc(100vh - 450px)' }}
pagination={false}
dataSource={tableData}
request={async (params) => {
console.log('params', params)
handleGetTableData(params)
}
// return {data: list || [], success: true,}
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
// table={activeKey === 1 ? 'table-to-xls0' : 'table-to-xls1'}
table="table-to-xls-SpringFestival"
filename={`${showCurrentFestivalObj?.label}营收分析_${moment(showCurrentFestivalObj?.startTime
).format('YYYY-MM-DD')}-${moment(showCurrentFestivalObj?.endTime).format('YYYY-MM-DD')}`}
sheet="sheet1"
/>
</span>,
<Button
key="new"
type="primary"
onClick={async (e) => {
if (reqDetailList && reqDetailList.length > 0) {
setTimeout(() => {
setShowExportTable(true)
if (!selectedId) {
setReqDetailList([])
return
}
if (clickTableBtnRef.current) {
if (params.STATISTICS_DATE) {
setSearchDate(params.STATISTICS_DATE)
} else {
setReqDetailList([])
setSearchDate(undefined)
}
handleGetTableData(params)
}
// return {data: list || [], success: true,}
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
// table={activeKey === 1 ? 'table-to-xls0' : 'table-to-xls1'}
table="table-to-xls-SpringFestival"
filename={`${showCurrentFestivalObj?.label}营收分析_${moment(showCurrentFestivalObj?.startTime
).format('YYYY-MM-DD')}-${moment(showCurrentFestivalObj?.endTime).format('YYYY-MM-DD')}`}
sheet="sheet1"
/>
</span>,
<Button
key="new"
type="primary"
onClick={async (e) => {
if (reqDetailList && reqDetailList.length > 0) {
setTimeout(() => {
exportTable(e)
setShowExportTable(true)
setTimeout(() => {
exportTable(e)
}, 100)
}, 100)
}, 100)
} else {
message.error('暂无数据可导出!')
}
// const nowColumns = columns.filter(n => !n.hideInTable)
// const fat = nowColumns.map((n: any, index: number) => {
// if (n?.children) {
// return n?.children.map((m: { title: any; }) => {
// const title = index === 0 ? m.title : n.title + m.title
// return { ...m, title }
// })
// }
// return n
// })
// if (reqDetailList && reqDetailList.length>0){
// const list: any = JSON.parse(JSON.stringify(reqDetailList))
// list.forEach((item: any,index: number)=>{
// item.index = index + 1
// })
// const curDate = moment(formRef.current?.getFieldValue('STATISTICS_DATE')).format('YYYYMMDD')
// const success = await exportExcelReceivedSum(
// fat.flat(),
// list || [],
// `春运营收分析_${curDate}`,
// );
// if (success.message !== 'ok') {
// message.info({ content: success.message });
// }
// }else{
// message.error('暂无数据可导出!')
// }
}}
>
excel
</Button>
],
}}
/>
</ProCard >
} else {
message.error('暂无数据可导出!')
}
// const nowColumns = columns.filter(n => !n.hideInTable)
// const fat = nowColumns.map((n: any, index: number) => {
// if (n?.children) {
// return n?.children.map((m: { title: any; }) => {
// const title = index === 0 ? m.title : n.title + m.title
// return { ...m, title }
// })
// }
// return n
// })
// if (reqDetailList && reqDetailList.length>0){
// const list: any = JSON.parse(JSON.stringify(reqDetailList))
// list.forEach((item: any,index: number)=>{
// item.index = index + 1
// })
// const curDate = moment(formRef.current?.getFieldValue('STATISTICS_DATE')).format('YYYYMMDD')
// const success = await exportExcelReceivedSum(
// fat.flat(),
// list || [],
// `春运营收分析_${curDate}`,
// );
// if (success.message !== 'ok') {
// message.info({ content: success.message });
// }
// }else{
// message.error('暂无数据可导出!')
// }
}}
>
excel
</Button>
],
}}
/>
</div>
</div>
<Drawer
width="80%"

View File

@ -20,6 +20,7 @@ import { contractType } from "@/pages/contract/emun";
import { exportExcelReceivedSum } from "@/utils/utils";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const { Text } = Typography;
@ -64,10 +65,10 @@ const StoreDetailRevenue: React.FC<{ currentUser?: CurrentUser }> = (props) => {
return getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, false, true)
})
const [reqDetailList, setReqDetailList] = useState<any[]>(); // 导出excel表格
const [fileName,setFileName] = useState<string>()
const [exportColumns,setExportColumns] = useState<any>()
const [fileName, setFileName] = useState<string>()
const [exportColumns, setExportColumns] = useState<any>()
// 是否显示打印的表格
const [showExportTable,setShowExportTable] = useState<boolean>(false)
const [showExportTable, setShowExportTable] = useState<boolean>(false)
const columns: any = [
{
title: '服务区',
@ -234,22 +235,22 @@ const StoreDetailRevenue: React.FC<{ currentUser?: CurrentUser }> = (props) => {
}, [])
const handleGetExportTime = (cYear: string,lYeaStr: string)=>{
if (columns && columns.length>0){
const handleGetExportTime = (cYear: string, lYeaStr: string) => {
if (columns && columns.length > 0) {
// 由于什么循环引用 导致不能深拷贝 所以重新搞个数组
const list: any = []
columns.forEach((item: any)=>{
columns.forEach((item: any) => {
list.push(item)
})
list.forEach((item: any)=>{
if (item.dataIndex==='lYear'){
list.forEach((item: any) => {
if (item.dataIndex === 'lYear') {
item.title = moment(lYeaStr).format('YYYY-MM-DD')
}else if(item.dataIndex==='curYear'){
} else if (item.dataIndex === 'curYear') {
item.title = moment(cYear).format('YYYY-MM-DD')
}
if (item.children && item.children.length>0){
item.children.forEach((subItem: any)=>{
if (subItem.dataIndex === 'CurGuaranteeRatio' || subItem.dataIndex === 'CyGuaranteeRatio'){
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.dataIndex === 'CurGuaranteeRatio' || subItem.dataIndex === 'CyGuaranteeRatio') {
subItem.title = '提成比例/固定租金'
}
})
@ -279,25 +280,25 @@ const StoreDetailRevenue: React.FC<{ currentUser?: CurrentUser }> = (props) => {
}
return (
<div style={{background: '#fff', display: 'flex'}}>
<div className={'storeHideDiv'} style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}>
<div style={{ background: '#fff', display: 'flex' }}>
<div className={'storeHideDiv'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length>0?
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
columns={exportColumns}
dataSource={reqDetailList}
expandable={{
defaultExpandAllRows:true
defaultExpandAllRows: true
}}
pagination={false}
>
</ProTable>:''
</ProTable> : ''
}
</div>
<div id='hiddenBox2' style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}>
<div id='hiddenBox2' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
</div>
<ProCard
{/* <ProCard
className="pageTable-leftnav"
style={{width: !collapsible ? "240px" : "60px"}}
headStyle={{width: !collapsible ? "240px" : "60px"}}
@ -330,144 +331,150 @@ const StoreDetailRevenue: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// actionRef?.current?.reload()
}}
/> : ''}
</ProCard>
<ProCard
style={{width: !collapsible ? "calc(100% - 240px)" : "calc(100% - 60px)"}}
>
<ProTable
formRef={formRef}
actionRef={actionRef}
rowKey={(record) => record?.Id + record?.Name}
search={{
span: 6,
labelWidth: 100,
}}
columns={columns}
bordered={true}
headerTitle={<PageTitleBox props={props} />}
scroll={{y: 'calc(100vh - 450px)'}}
pagination={false}
request={async (params: any) => {
if (curYear && curYear) {
if (!selectedId) {
return
}
const cyDate = params.lYear
</ProCard> */}
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
formRef={formRef}
actionRef={actionRef}
rowKey={(record) => record?.Id + record?.Name}
search={{
span: 6,
labelWidth: 100,
}}
columns={columns}
bordered={true}
headerTitle={<PageTitleBox props={props} />}
scroll={{ y: 'calc(100vh - 450px)' }}
pagination={false}
request={async (params: any) => {
if (curYear && curYear) {
if (!selectedId) {
return
}
const cyDate = params.lYear
const req = {
StatisticsDate: moment(curYear).format('YYYY-MM-DD'),
ContrastDate: moment(cyDate).format('YYYY-MM-DD'),
ServerpartIds: selectedId || ''
}
const data = await handleGetShopInCome(req)
const list = wrapTreeNode(data.List)
const req = {
StatisticsDate: moment(curYear).format('YYYY-MM-DD'),
ContrastDate: moment(cyDate).format('YYYY-MM-DD'),
ServerpartIds: selectedId || ''
}
const data = await handleGetShopInCome(req)
const list = wrapTreeNode(data.List)
let CurRevenueDailyAmountSum: number = 0
let CurRoyaltyDailyPriceSum: number = 0
let CurRoyaltyDailyTheorySum: number = 0
let CurRoyaltyDailyTheoryTaxSum: number = 0
let CyRevenueDailyAmountSum: number = 0
let CyRoyaltyDailyPriceSum: number = 0
let CyRoyaltyDailyTheorySum: number = 0
let CyRoyaltyDailyTheoryTaxSum: number = 0
if (list && list.length > 0) {
list.forEach((item: any) => {
CurRevenueDailyAmountSum += item.CurRevenueDailyAmount
CurRoyaltyDailyPriceSum += item.CurRoyaltyDailyPrice
CurRoyaltyDailyTheorySum += item.CurRoyaltyDailyTheory
CurRoyaltyDailyTheoryTaxSum += item.CurRoyaltyDailyTheoryTax
CyRevenueDailyAmountSum += item.CyRevenueDailyAmount
CyRoyaltyDailyPriceSum += item.CyRoyaltyDailyPrice
CyRoyaltyDailyTheorySum += item.CyRoyaltyDailyTheory
CyRoyaltyDailyTheoryTaxSum += item.CyRoyaltyDailyTheoryTax
let CurRevenueDailyAmountSum: number = 0
let CurRoyaltyDailyPriceSum: number = 0
let CurRoyaltyDailyTheorySum: number = 0
let CurRoyaltyDailyTheoryTaxSum: number = 0
let CyRevenueDailyAmountSum: number = 0
let CyRoyaltyDailyPriceSum: number = 0
let CyRoyaltyDailyTheorySum: number = 0
let CyRoyaltyDailyTheoryTaxSum: number = 0
if (list && list.length > 0) {
list.forEach((item: any) => {
CurRevenueDailyAmountSum += item.CurRevenueDailyAmount
CurRoyaltyDailyPriceSum += item.CurRoyaltyDailyPrice
CurRoyaltyDailyTheorySum += item.CurRoyaltyDailyTheory
CurRoyaltyDailyTheoryTaxSum += item.CurRoyaltyDailyTheoryTax
CyRevenueDailyAmountSum += item.CyRevenueDailyAmount
CyRoyaltyDailyPriceSum += item.CyRoyaltyDailyPrice
CyRoyaltyDailyTheorySum += item.CyRoyaltyDailyTheory
CyRoyaltyDailyTheoryTaxSum += item.CyRoyaltyDailyTheoryTax
})
}
list.unshift({
Name: '总计',
CurRevenueDailyAmount: CurRevenueDailyAmountSum.toFixed(2),
CurRoyaltyDailyPrice: CurRoyaltyDailyPriceSum.toFixed(2),
CurRoyaltyDailyTheory: CurRoyaltyDailyTheorySum.toFixed(2),
CurRoyaltyDailyTheoryTax: CurRoyaltyDailyTheoryTaxSum.toFixed(2),
CyRevenueDailyAmount: CyRevenueDailyAmountSum.toFixed(2),
CyRoyaltyDailyPrice: CyRoyaltyDailyPriceSum.toFixed(2),
CyRoyaltyDailyTheory: CyRoyaltyDailyTheorySum.toFixed(2),
CyRoyaltyDailyTheoryTax: CyRoyaltyDailyTheoryTaxSum.toFixed(2),
})
// const curResList = wrapTreeNode(data.List[0].Container.children)
// const lResList = wrapTreeNode(data.List[1].Container.children)
const curDate = moment(curYear).format('YYYYMMDD')
const cyDateStr = moment(cyDate).format('YYYYMMDD')
setShowlYear(cyDate)
setShowCurYear(curYear)
setFileName(`商户收入明细表_${curDate}_${cyDateStr}`)
handleGetExportTime(curDate, cyDateStr)
setReqDetailList(list);
return { data: list || [], success: true }
}
list.unshift({
Name: '总计',
CurRevenueDailyAmount: CurRevenueDailyAmountSum.toFixed(2),
CurRoyaltyDailyPrice: CurRoyaltyDailyPriceSum.toFixed(2),
CurRoyaltyDailyTheory: CurRoyaltyDailyTheorySum.toFixed(2),
CurRoyaltyDailyTheoryTax: CurRoyaltyDailyTheoryTaxSum.toFixed(2),
CyRevenueDailyAmount: CyRevenueDailyAmountSum.toFixed(2),
CyRoyaltyDailyPrice: CyRoyaltyDailyPriceSum.toFixed(2),
CyRoyaltyDailyTheory: CyRoyaltyDailyTheorySum.toFixed(2),
CyRoyaltyDailyTheoryTax: CyRoyaltyDailyTheoryTaxSum.toFixed(2),
})
// const curResList = wrapTreeNode(data.List[0].Container.children)
// const lResList = wrapTreeNode(data.List[1].Container.children)
const curDate = moment(curYear).format('YYYYMMDD')
const cyDateStr = moment(cyDate).format('YYYYMMDD')
setShowlYear(cyDate)
setShowCurYear(curYear)
setFileName(`商户收入明细表_${curDate}_${cyDateStr}`)
handleGetExportTime(curDate,cyDateStr)
setReqDetailList(list);
return {data: list || [], success: true}
}
}}
toolbar={{
actions: [
<span style={{visibility: 'hidden'}}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls2"
filename={fileName}
sheet="sheet1"
/>
</span>,
<Button
key="new"
type="primary"
onClick={async (e) => {
if (reqDetailList && reqDetailList.length > 0) {
setShowExportTable(true)
setTimeout(()=>{
exportTable(e)
},100)
} else {
message.error('暂无数据可导出!')
}
// const nowColumns = columns.filter(n => !n.hideInTable)
// const fat = nowColumns.map((n: any, index: number) => {
// if (n?.children) {
// return n?.children.map((m: { title: any; }) => {
// if (m.title.props) {
// const title = `${n.title.props.children}提成比例/固定租金`
// return { ...m, title }
// }
// const title = index === 0 ? m.title : n.title.props.children + m.title
// return { ...m, title }
// })
// }
// return n
// })
//
// const list: any = JSON.parse(JSON.stringify(reqDetailList))
// const curDate = moment(formRef.current?.getFieldValue('cYear')).format('YYYYMMDD')
// const cyDate = moment(formRef.current?.getFieldValue('lYear')).format('YYYYMMDD')
// const success = await exportExcelReceivedSum(
// fat.flat(),
// list || [],
// `商户收入明细表_${curDate}_${cyDate}`,
// );
// if (success.message !== 'ok') {
// message.info({ content: success.message });
// }
}}
>
excel
</Button>
],
}}
/>
</ProCard>
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls2"
filename={fileName}
sheet="sheet1"
/>
</span>,
<Button
key="new"
type="primary"
onClick={async (e) => {
if (reqDetailList && reqDetailList.length > 0) {
setShowExportTable(true)
setTimeout(() => {
exportTable(e)
}, 100)
} else {
message.error('暂无数据可导出!')
}
// const nowColumns = columns.filter(n => !n.hideInTable)
// const fat = nowColumns.map((n: any, index: number) => {
// if (n?.children) {
// return n?.children.map((m: { title: any; }) => {
// if (m.title.props) {
// const title = `${n.title.props.children}提成比例/固定租金`
// return { ...m, title }
// }
// const title = index === 0 ? m.title : n.title.props.children + m.title
// return { ...m, title }
// })
// }
// return n
// })
//
// const list: any = JSON.parse(JSON.stringify(reqDetailList))
// const curDate = moment(formRef.current?.getFieldValue('cYear')).format('YYYYMMDD')
// const cyDate = moment(formRef.current?.getFieldValue('lYear')).format('YYYYMMDD')
// const success = await exportExcelReceivedSum(
// fat.flat(),
// list || [],
// `商户收入明细表_${curDate}_${cyDate}`,
// );
// if (success.message !== 'ok') {
// message.info({ content: success.message });
// }
}}
>
excel
</Button>
],
}}
/>
</div>
</div>
</div>
)
}
export default connect(({user}: ConnectState) => ({
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(StoreDetailRevenue);

View File

@ -44,6 +44,7 @@ import './accountMonthly.less'
import { trimEnd } from 'lodash';
import DifferenceAmount from '../shareRoyalty/component/differenceAmount';
import PageTitleBox from '@/components/PageTitleBox';
import LeftSelectTree from '../settlementAccount/component/leftSelectTree';
const { Text } = Typography;
@ -986,8 +987,9 @@ const ReportTable: React.FC<{ currentUser?: CurrentUser }> = (props) => {
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
{/* height: 'calc(100vh - 66px)', */}
<div style={{ backgroundColor: '#fff', width: '100%', display: 'flex' }}>
<ProCard
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
{/* <ProCard
className="pageTable-leftnav"
style={{ width: !collapsible ? "240px" : "60px" }}
headStyle={{ width: !collapsible ? "240px" : "60px" }}
@ -1020,13 +1022,14 @@ const ReportTable: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// actionRef?.current?.reload()
}}
/> : ''}
</ProCard>
</ProCard> */}
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0,
width: `calc(100% - ${!collapsible ? 240 : 60}px)`
paddingRight: 0
}}>
{
showNotice ?
<div onClick={() => {

View File

@ -26,6 +26,7 @@ import Merchant from "@/pages/reports/ShopExpenseDetail/detail";
import './accountServerpart.less'
import AccountChildren from './components/accountChildren'
import PageTitleBox from '@/components/PageTitleBox';
import LeftSelectTree from '../settlementAccount/component/leftSelectTree';
const { Text } = Typography;
@ -736,359 +737,332 @@ const ShareBenefit: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// 打印报表
setPrintOut(el);
}}>
<ProCard split="vertical" style={{ backgroundColor: '#fff' }}>
<ProCard
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20 }}
extra={<MenuFoldOutlined onClick={() => { setCollapsible(!collapsible) }} />}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "请选择服务区" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={!treeLoading ? [{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}] : []}
fieldNames={{
title: "label",
key: "key"
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable<ProjectSplitSummaryModel>
rowKey={(record) => {
return `${`${record?.SPREGIONTYPE_ID}|${record?.index}`}`
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
// 取消掉选择点击左侧 右侧列表就直接调用接口拿到数据
// actionRef?.current?.reload()
loading={tableLoading}
headerTitle={<PageTitleBox props={props} />} // 列表表头
actionRef={actionRef}
formRef={formRef}
// scroll={{ y: 'calc(100vh - 500px)' }}
scroll={{ x: 'calc(100vw - 500px)', y: 700 }}
search={{
span: 6,
labelWidth: 'auto',
optionRender: (searchConfig, formProps, dom) => {
return [
<Button
key="reset"
onClick={() => {
formRef.current?.resetFields();
handleGetTableData()
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
onClick={() => {
// formRef.current?.submit();
canSearch.current = 1
const formData = formRef.current?.getFieldsValue()
console.log('formData', formData)
const params = {
...formData,
search_date: '',
StartDate: moment(formData?.search_date[0]._d).format('YYYY-MM-DD'),
EndDate: moment(formData.search_date[1]._d).format('YYYY-MM-DD')
}
handleGetTableData(params)
}}
>
</Button>
]
}
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
<div style={{ width: !collapsible ? 'calc(100% - 240px)' : 'calc(100% - 60px)', height: '100%' }}>
<ProCard className={'proCard'} id='bigAccountMonthly' bodyStyle={{ position: 'relative', paddingTop: 0, paddingBottom: 0, paddingRight: 0 }}>
<div id='accountMonthly' style={{ position: 'absolute', zIndex: -1, top: 0, left: 0 }} />
<ProTable<ProjectSplitSummaryModel>
rowKey={(record) => {
return `${`${record?.SPREGIONTYPE_ID}|${record?.index}`}`
}}
loading={tableLoading}
headerTitle={<PageTitleBox props={props} />} // 列表表头
actionRef={actionRef}
formRef={formRef}
// scroll={{ y: 'calc(100vh - 500px)' }}
scroll={{ x: 'calc(100vw - 500px)', y: 700 }}
search={{
span: 6,
labelWidth: 'auto',
optionRender: (searchConfig, formProps, dom) => {
return [
<Button
key="reset"
onClick={() => {
formRef.current?.resetFields();
handleGetTableData()
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
onClick={() => {
// formRef.current?.submit();
canSearch.current = 1
const formData = formRef.current?.getFieldsValue()
console.log('formData', formData)
const params = {
...formData,
search_date: '',
StartDate: moment(formData?.search_date[0]._d).format('YYYY-MM-DD'),
EndDate: moment(formData.search_date[1]._d).format('YYYY-MM-DD')
}
handleGetTableData(params)
}}
>
</Button>
]
}
}}
// 请求数据
request={(params, sort) => {
if (!sort || canSearch.current === 1) {
handleGetTableData(params)
}
}}
columns={columns}
dataSource={reqDetailList}
rowClassName={(record) => record?.SPREGIONTYPE_ID || record?.SERVERPART_ID ? 'expanded' : ''}
expandable={
{
rowExpandable: () => true,
// defaultExpandedRowKeys: ['0|0|0'],
indentSize: 0,
expandRowByClick: true,
defaultExpandAllRows: true,
onExpand: (expanded, record) => {
if (expanded) {
setExpandRow([...expandRow, `${record?.SPREGIONTYPE_ID}|${record?.SERVERPART_ID}|${record?.SERVERPARTSHOP_ID}`])
} else {
const nowData = expandRow?.reduce((p: string[], c) => {
if (c !== `${record?.SPREGIONTYPE_ID}|${record?.SERVERPART_ID}|${record?.SERVERPARTSHOP_ID}`) {
p.push(c)
}
return p
}, [])
setExpandRow(nowData || [])
}
// 请求数据
request={(params, sort) => {
if (!sort || canSearch.current === 1) {
handleGetTableData(params)
}
}}
columns={columns}
dataSource={reqDetailList}
rowClassName={(record) => record?.SPREGIONTYPE_ID || record?.SERVERPART_ID ? 'expanded' : ''}
expandable={
{
rowExpandable: () => true,
// defaultExpandedRowKeys: ['0|0|0'],
indentSize: 0,
expandRowByClick: true,
defaultExpandAllRows: true,
onExpand: (expanded, record) => {
if (expanded) {
setExpandRow([...expandRow, `${record?.SPREGIONTYPE_ID}|${record?.SERVERPART_ID}|${record?.SERVERPARTSHOP_ID}`])
} else {
const nowData = expandRow?.reduce((p: string[], c) => {
if (c !== `${record?.SPREGIONTYPE_ID}|${record?.SERVERPART_ID}|${record?.SERVERPARTSHOP_ID}`) {
p.push(c)
}
return p
}, [])
setExpandRow(nowData || [])
}
}
}
bordered
// options={false}
pagination={false}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
toolbar={{
actions: [
<Typography.Text type="secondary"></Typography.Text>,
<ReactToPrint
trigger={() => (
<Button key="printout" type="default">
</Button>
)}
content={() => {
if (printOut) {
const content: HTMLElement | Node | undefined = printOut?.getElementsByClassName('ant-card-body')[0]
// const extra: HTMLElement | Node | undefined = printOut?.getElementsByClassName('ant-pro-table-extra')[0]
const [start, end] = formRef.current?.getFieldValue('search_date') || [];
const innerText = start && end ? `统计时间:${moment(start).format('YYYY/MM/DD')}-${moment(end).format('YYYY/MM/DD')}` : '';
const ele = printOutInternal(content ? content.cloneNode(true) : [], innerText);
return ele
}
return ''
}}
/>,
<Button
key="new"
type="primary"
onClick={async () => {
if (reqDetailList) {
reqDetailList.forEach((c: any, i) => {
c.BUSINESS_TRADE = c.BUSINESS_TRADE ? businessType[c.BUSINESS_TRADE] : '-';
})
// 选择默认不显示的字段
const selectHideList: any = []
for (const key in columnsStateMap) {
if (!(columnsStateMap[key].show)) {
selectHideList.push(key)
}
}
bordered
// options={false}
pagination={false}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
toolbar={{
actions: [
<Typography.Text type="secondary"></Typography.Text>,
<ReactToPrint
trigger={() => (
<Button key="printout" type="default">
</Button>
)}
content={() => {
if (printOut) {
const content: HTMLElement | Node | undefined = printOut?.getElementsByClassName('ant-card-body')[0]
// const extra: HTMLElement | Node | undefined = printOut?.getElementsByClassName('ant-pro-table-extra')[0]
const [start, end] = formRef.current?.getFieldValue('search_date') || [];
const innerText = start && end ? `统计时间:${moment(start).format('YYYY/MM/DD')}-${moment(end).format('YYYY/MM/DD')}` : '';
const ele = printOutInternal(content ? content.cloneNode(true) : [], innerText);
return ele
}
return ''
}}
/>,
<Button
key="new"
type="primary"
onClick={async () => {
if (reqDetailList) {
reqDetailList.forEach((c: any, i) => {
c.BUSINESS_TRADE = c.BUSINESS_TRADE ? businessType[c.BUSINESS_TRADE] : '-';
})
// 选择默认不显示的字段
const selectHideList: any = []
for (const key in columnsStateMap) {
if (!(columnsStateMap[key].show)) {
selectHideList.push(key)
}
// 有hideInTable属性字段的数组 初筛
let filterList: any = columns.filter(n => !n.hideInTable)
filterList = filterList.filter(n => selectHideList.indexOf(n.dataIndex) === -1)
}
// 有hideInTable属性字段的数组 初筛
let filterList: any = columns.filter(n => !n.hideInTable)
filterList = filterList.filter(n => selectHideList.indexOf(n.dataIndex) === -1)
console.log('reqDetailList', reqDetailList)
console.log('SETTLEMENTMODESOBJ', SETTLEMENTMODESOBJ)
console.log('COMPACTTYPEOBJ', COMPACTTYPEOBJ)
const dataList: any = JSON.parse(JSON.stringify(reqDetailList))
dataList.forEach((item: any, index: number) => {
item.MERCHANTS_NAME = item.SPREGIONTYPE_NAME
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any, subIndex: number) => {
subItem.MERCHANTS_NAME = subItem.SERVERPART_NAME
if (index === 0) {
subItem.index = `${subIndex + 1}`
console.log('reqDetailList', reqDetailList)
console.log('SETTLEMENTMODESOBJ', SETTLEMENTMODESOBJ)
console.log('COMPACTTYPEOBJ', COMPACTTYPEOBJ)
const dataList: any = JSON.parse(JSON.stringify(reqDetailList))
dataList.forEach((item: any, index: number) => {
item.MERCHANTS_NAME = item.SPREGIONTYPE_NAME
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any, subIndex: number) => {
subItem.MERCHANTS_NAME = subItem.SERVERPART_NAME
if (index === 0) {
subItem.index = `${subIndex + 1}`
} else {
if (subIndex === 0) {
subItem.index = `${Number(dataList[index - 1].children[dataList[index - 1].children.length - 1].index) + 1}`
} else {
if (subIndex === 0) {
subItem.index = `${Number(dataList[index - 1].children[dataList[index - 1].children.length - 1].index) + 1}`
} else {
subItem.index = Number(item.children[subIndex - 1].index) + 1
}
subItem.index = Number(item.children[subIndex - 1].index) + 1
}
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any, thirdIndex: number) => {
thirdItem.index = `${subItem.index}.${thirdIndex + 1}`
thirdItem.BUSINESS_TYPE = contractType[thirdItem.BUSINESS_TYPE]
thirdItem.SETTLEMENT_MODES = SETTLEMENTMODESOBJ[thirdItem.SETTLEMENT_MODES]
thirdItem.COMPACT_TYPE = COMPACTTYPEOBJ[thirdItem.COMPACT_TYPE]
})
}
})
}
})
console.log('dataList', dataList)
const success = await exportExcelReceivedSum(
filterList,
dataList || [],
`合作商户资金到账汇总报表_${moment().format('YYYY/MM/DD')}`,
);
if (success.message !== 'ok') {
message.info({ content: success.message });
}
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any, thirdIndex: number) => {
thirdItem.index = `${subItem.index}.${thirdIndex + 1}`
thirdItem.BUSINESS_TYPE = contractType[thirdItem.BUSINESS_TYPE]
thirdItem.SETTLEMENT_MODES = SETTLEMENTMODESOBJ[thirdItem.SETTLEMENT_MODES]
thirdItem.COMPACT_TYPE = COMPACTTYPEOBJ[thirdItem.COMPACT_TYPE]
})
}
})
}
})
console.log('dataList', dataList)
const success = await exportExcelReceivedSum(
filterList,
dataList || [],
`合作商户资金到账汇总报表_${moment().format('YYYY/MM/DD')}`,
);
if (success.message !== 'ok') {
message.info({ content: success.message });
}
}}
>
excel
</Button>,
<span onClick={(e) => {
e.stopPropagation();
// 传入需要特别修改的字段及第二个参数 数组对象的格式 type是判断是render还是select的 fun是拿到值的方法
exportTable(e, [
{
name: 'MERCHANTS_NAME',
type: 'render',
fun: handleMERCHANTSNAME
},
{
name: 'BUSINESS_TRADE',
type: 'select',
fun: businessType
}
])
}}>
<ReactHTMLTableToExcel
ref={buttonRef}
id='accountMonthly-table-xls-button'
className="ant-btn"
filename={fileName}
table="accountMonthly-to-xls"
sheet="报表"
buttonText="下载报表"
/>
</span>
]
}}
tableExtraRender={() => {
if (reqDetailList && reqDetailList.length > 0) {
const reduceData = reqDetailList.reduce((p: {
REVENUE_AMOUNT: number, ROYALTY_PRICE: number, ACCOUNT_AMOUNT: number, SUBROYALTY_PRICE?: number, TICKET_FEE?: number, ROYALTY_THEORY?: number,
SUBROYALTY_THEORY?: number, DIFDAILY_REVENUE?: number
}, currentValue: ProjectSplitSummaryModel) => {
// 数据累加拿合计值
const previousValue = { ...p }
previousValue.REVENUE_AMOUNT = numeral(numeral(previousValue.REVENUE_AMOUNT +
(currentValue.REVENUE_AMOUNT || 0)).format('0.00')).value() || 0;
previousValue.ROYALTY_PRICE = numeral(numeral(previousValue.ROYALTY_PRICE +
(currentValue.ROYALTY_PRICE || 0)).format('0.00')).value() || 0;
previousValue.ACCOUNT_AMOUNT = numeral(numeral(previousValue.ACCOUNT_AMOUNT +
(currentValue.ACCOUNT_AMOUNT || 0)).format('0.00')).value() || 0;
previousValue.SUBROYALTY_PRICE = numeral(numeral((previousValue.SUBROYALTY_PRICE || 0) +
(currentValue.SUBROYALTY_PRICE || 0)).format('0.00')).value() || 0;
previousValue.TICKET_FEE = numeral(numeral((previousValue.TICKET_FEE || 0) +
(currentValue.TICKET_FEE || 0)).format('0.00')).value() || 0;
previousValue.ROYALTY_THEORY = numeral(numeral((previousValue.ROYALTY_THEORY || 0) +
(currentValue.ROYALTYDAILY_THEORY || 0)).format('0.00')).value() || 0;
previousValue.SUBROYALTY_THEORY = numeral(numeral((previousValue.SUBROYALTY_THEORY || 0) +
(currentValue.SUBROYALTYDAILY_THEORY || 0)).format('0.00')).value() || 0;
previousValue.DIFDAILY_REVENUE = numeral(numeral((previousValue.DIFDAILY_REVENUE || 0) +
(currentValue.DIFDAILY_REVENUE || 0)).format('0.00')).value() || 0;
return previousValue
}, {
REVENUE_AMOUNT: 0, ROYALTY_PRICE: 0, ACCOUNT_AMOUNT: 0
});
// 显示在列表上方是的类型合计
return <div style={{ paddingLeft: 25, paddingBottom: 0 }}>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="合作分成">¥{amountDom(otherData?.ProjectCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="固定租金">¥{amountDom(otherData?.ProjectRentRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="自营提成">¥{amountDom(otherData?.ProjectSelfCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="业主自营">¥{amountDom(otherData?.ProjectSelfRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="合计金额">¥{amountDom(reduceData?.REVENUE_AMOUNT)}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="合作分成">¥{amountDom(otherData?.PushCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="固定租金">¥{amountDom(otherData?.PushRentRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="自营提成">¥{amountDom(otherData?.PushSelfCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="业主自营">¥{amountDom(otherData?.PushSelfRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="合计金额">¥{amountDom(otherData?.PushRevenue)}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}>-</Text>}>
<ProDescriptions.Item label="合作分成">¥{amountDom(numeral(numeral((otherData?.ProjectCoopRevenue || 0) -
(otherData?.PushCoopRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="固定租金">¥{amountDom(numeral(numeral((otherData?.ProjectRentRevenue || 0) -
(otherData?.PushRentRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="自营提成">¥{amountDom(numeral(numeral((otherData?.ProjectSelfCoopRevenue || 0) -
(otherData?.PushSelfCoopRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="业主自营">¥{amountDom(numeral(numeral((otherData?.ProjectSelfRevenue || 0) -
(otherData?.PushSelfRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="合计金额">¥{amountDom(numeral(numeral((reduceData.REVENUE_AMOUNT || 0) -
(otherData?.PushRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="项目数量"><Text type="warning" style={{
fontSize: 30, lineHeight: 0.5,
fontFamily: "Bahnschrift Regular"
}}>{amountDom(numeral(otherData?.ProjectCount).format('0.00'))}</Text></ProDescriptions.Item>
<ProDescriptions.Item label="业主到账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.ROYALTY_PRICE)}</ProDescriptions.Item>
<ProDescriptions.Item label="商家到账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.SUBROYALTY_PRICE)}</ProDescriptions.Item>
<ProDescriptions.Item label="手续费">¥{amountDom(reduceData.TICKET_FEE)}</ProDescriptions.Item>
<ProDescriptions.Item label="差额">¥{amountDom(numeral(numeral((reduceData.ROYALTY_PRICE || 0) + (reduceData.SUBROYALTY_PRICE || 0) +
(reduceData.TICKET_FEE || 0) - (reduceData.REVENUE_AMOUNT || 0)).format('0.00')).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item></ProDescriptions.Item>
<ProDescriptions.Item label="业主入账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.ROYALTY_THEORY)}</ProDescriptions.Item>
<ProDescriptions.Item label="商家入账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.SUBROYALTY_THEORY)}</ProDescriptions.Item>
<ProDescriptions.Item></ProDescriptions.Item>
<ProDescriptions.Item label="自然日营业差额">¥{amountDom(numeral(reduceData.DIFDAILY_REVENUE).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}>(-)</Text>}>
<ProDescriptions.Item label=""></ProDescriptions.Item>
<ProDescriptions.Item label="业主应收" labelStyle={{ color: "red" }} className={'special'}>
<div style={{ cursor: 'pointer' }} onClick={() => {
setChildrenType(1)
setShowSmallDrawer(true)
}}>
¥{amountDom(numeral((reduceData.ROYALTY_PRICE || 0) -
(reduceData.ROYALTY_THEORY || 0)).format('0.00'))}
</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="商家欠款" labelStyle={{ color: "red" }} className={'special'}>
<div style={{ cursor: 'pointer' }} onClick={() => {
setChildrenType(2)
setShowSmallDrawer(true)
}}>
¥{amountDom(numeral((reduceData.SUBROYALTY_PRICE || 0) -
(reduceData.SUBROYALTY_THEORY || 0)).format('0.00'))}
</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="分润差额">¥{amountDom(numeral((reduceData.ROYALTY_PRICE || 0) -
(reduceData.ROYALTY_THEORY || 0) + (reduceData.SUBROYALTY_PRICE || 0) -
(reduceData.SUBROYALTY_THEORY || 0)).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="矫正差异">¥{amountDom(numeral((reduceData.REVENUE_AMOUNT || 0) -
(otherData?.PushRevenue || 0) - (reduceData.DIFDAILY_REVENUE || 0)).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
</div >
}
}
}}
>
excel
</Button>,
<span onClick={(e) => {
e.stopPropagation();
// 传入需要特别修改的字段及第二个参数 数组对象的格式 type是判断是render还是select的 fun是拿到值的方法
exportTable(e, [
{
name: 'MERCHANTS_NAME',
type: 'render',
fun: handleMERCHANTSNAME
},
{
name: 'BUSINESS_TRADE',
type: 'select',
fun: businessType
}
])
}}>
<ReactHTMLTableToExcel
ref={buttonRef}
id='accountMonthly-table-xls-button'
className="ant-btn"
filename={fileName}
table="accountMonthly-to-xls"
sheet="报表"
buttonText="下载报表"
/>
</span>
]
}}
tableExtraRender={() => {
if (reqDetailList && reqDetailList.length > 0) {
const reduceData = reqDetailList.reduce((p: {
REVENUE_AMOUNT: number, ROYALTY_PRICE: number, ACCOUNT_AMOUNT: number, SUBROYALTY_PRICE?: number, TICKET_FEE?: number, ROYALTY_THEORY?: number,
SUBROYALTY_THEORY?: number, DIFDAILY_REVENUE?: number
}, currentValue: ProjectSplitSummaryModel) => {
// 数据累加拿合计值
const previousValue = { ...p }
previousValue.REVENUE_AMOUNT = numeral(numeral(previousValue.REVENUE_AMOUNT +
(currentValue.REVENUE_AMOUNT || 0)).format('0.00')).value() || 0;
previousValue.ROYALTY_PRICE = numeral(numeral(previousValue.ROYALTY_PRICE +
(currentValue.ROYALTY_PRICE || 0)).format('0.00')).value() || 0;
previousValue.ACCOUNT_AMOUNT = numeral(numeral(previousValue.ACCOUNT_AMOUNT +
(currentValue.ACCOUNT_AMOUNT || 0)).format('0.00')).value() || 0;
previousValue.SUBROYALTY_PRICE = numeral(numeral((previousValue.SUBROYALTY_PRICE || 0) +
(currentValue.SUBROYALTY_PRICE || 0)).format('0.00')).value() || 0;
previousValue.TICKET_FEE = numeral(numeral((previousValue.TICKET_FEE || 0) +
(currentValue.TICKET_FEE || 0)).format('0.00')).value() || 0;
previousValue.ROYALTY_THEORY = numeral(numeral((previousValue.ROYALTY_THEORY || 0) +
(currentValue.ROYALTYDAILY_THEORY || 0)).format('0.00')).value() || 0;
previousValue.SUBROYALTY_THEORY = numeral(numeral((previousValue.SUBROYALTY_THEORY || 0) +
(currentValue.SUBROYALTYDAILY_THEORY || 0)).format('0.00')).value() || 0;
previousValue.DIFDAILY_REVENUE = numeral(numeral((previousValue.DIFDAILY_REVENUE || 0) +
(currentValue.DIFDAILY_REVENUE || 0)).format('0.00')).value() || 0;
return previousValue
}, {
REVENUE_AMOUNT: 0, ROYALTY_PRICE: 0, ACCOUNT_AMOUNT: 0
});
// 显示在列表上方是的类型合计
return <div style={{ paddingLeft: 25, paddingBottom: 0 }}>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="合作分成">¥{amountDom(otherData?.ProjectCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="固定租金">¥{amountDom(otherData?.ProjectRentRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="自营提成">¥{amountDom(otherData?.ProjectSelfCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="业主自营">¥{amountDom(otherData?.ProjectSelfRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="合计金额">¥{amountDom(reduceData?.REVENUE_AMOUNT)}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="合作分成">¥{amountDom(otherData?.PushCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="固定租金">¥{amountDom(otherData?.PushRentRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="自营提成">¥{amountDom(otherData?.PushSelfCoopRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="业主自营">¥{amountDom(otherData?.PushSelfRevenue)}</ProDescriptions.Item>
<ProDescriptions.Item label="合计金额">¥{amountDom(otherData?.PushRevenue)}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}>-</Text>}>
<ProDescriptions.Item label="合作分成">¥{amountDom(numeral(numeral((otherData?.ProjectCoopRevenue || 0) -
(otherData?.PushCoopRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="固定租金">¥{amountDom(numeral(numeral((otherData?.ProjectRentRevenue || 0) -
(otherData?.PushRentRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="自营提成">¥{amountDom(numeral(numeral((otherData?.ProjectSelfCoopRevenue || 0) -
(otherData?.PushSelfCoopRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="业主自营">¥{amountDom(numeral(numeral((otherData?.ProjectSelfRevenue || 0) -
(otherData?.PushSelfRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="合计金额">¥{amountDom(numeral(numeral((reduceData.REVENUE_AMOUNT || 0) -
(otherData?.PushRevenue || 0))).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item label="项目数量"><Text type="warning" style={{
fontSize: 30, lineHeight: 0.5,
fontFamily: "Bahnschrift Regular"
}}>{amountDom(numeral(otherData?.ProjectCount).format('0.00'))}</Text></ProDescriptions.Item>
<ProDescriptions.Item label="业主到账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.ROYALTY_PRICE)}</ProDescriptions.Item>
<ProDescriptions.Item label="商家到账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.SUBROYALTY_PRICE)}</ProDescriptions.Item>
<ProDescriptions.Item label="手续费">¥{amountDom(reduceData.TICKET_FEE)}</ProDescriptions.Item>
<ProDescriptions.Item label="差额">¥{amountDom(numeral(numeral((reduceData.ROYALTY_PRICE || 0) + (reduceData.SUBROYALTY_PRICE || 0) +
(reduceData.TICKET_FEE || 0) - (reduceData.REVENUE_AMOUNT || 0)).format('0.00')).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}></Text>}>
<ProDescriptions.Item></ProDescriptions.Item>
<ProDescriptions.Item label="业主入账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.ROYALTY_THEORY)}</ProDescriptions.Item>
<ProDescriptions.Item label="商家入账" labelStyle={{ color: "red" }} className={'special'}>¥{amountDom(reduceData.SUBROYALTY_THEORY)}</ProDescriptions.Item>
<ProDescriptions.Item></ProDescriptions.Item>
<ProDescriptions.Item label="自然日营业差额">¥{amountDom(numeral(reduceData.DIFDAILY_REVENUE).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
<ProDescriptions column={5} className="commity-sale-description"
labelStyle={{ color: "#00000073" }}
title={<Text type="success" style={{ color: "#1890ff", fontSize: 14 }}>(-)</Text>}>
<ProDescriptions.Item label=""></ProDescriptions.Item>
<ProDescriptions.Item label="业主应收" labelStyle={{ color: "red" }} className={'special'}>
<div style={{ cursor: 'pointer' }} onClick={() => {
setChildrenType(1)
setShowSmallDrawer(true)
}}>
¥{amountDom(numeral((reduceData.ROYALTY_PRICE || 0) -
(reduceData.ROYALTY_THEORY || 0)).format('0.00'))}
</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="商家欠款" labelStyle={{ color: "red" }} className={'special'}>
<div style={{ cursor: 'pointer' }} onClick={() => {
setChildrenType(2)
setShowSmallDrawer(true)
}}>
¥{amountDom(numeral((reduceData.SUBROYALTY_PRICE || 0) -
(reduceData.SUBROYALTY_THEORY || 0)).format('0.00'))}
</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="分润差额">¥{amountDom(numeral((reduceData.ROYALTY_PRICE || 0) -
(reduceData.ROYALTY_THEORY || 0) + (reduceData.SUBROYALTY_PRICE || 0) -
(reduceData.SUBROYALTY_THEORY || 0)).format('0.00'))}</ProDescriptions.Item>
<ProDescriptions.Item label="矫正差异">¥{amountDom(numeral((reduceData.REVENUE_AMOUNT || 0) -
(otherData?.PushRevenue || 0) - (reduceData.DIFDAILY_REVENUE || 0)).format('0.00'))}</ProDescriptions.Item>
</ProDescriptions>
</div >
}
return <></>
}}
/>
</ProCard>
return <></>
}}
/>
</div>
</ProCard>
</div>
{/* 经营单位 */}
<Drawer
width="80%"

View File

@ -44,6 +44,7 @@ import BusinessDetail from "@/pages/reports/Finance/businessAnalysis/components/
import RevenueTraffic from "@/pages/reports/Finance/businessWarning/components/revenueTraffic";
import { handleCorrectBayonetFlow, handleGetServerpartInfo } from "./service";
import session from "@/utils/session";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const { Text } = Typography;
@ -55,7 +56,7 @@ const businessWarning: React.FC<{ currentUser?: CurrentUser }> = (props) => {
const downloadBtnRef = useRef<any>()
const actionDetailRef = useRef<ActionType>();
const formDetailRef = useRef<ProFormInstance>();
const { currentUser,route } = props
const { currentUser, route } = props
// 左侧树展开还是收缩
const [collapsible, setCollapsible] = useState<boolean>(false)
const [selectedId, setSelectedId] = useState<string>()
@ -2064,7 +2065,6 @@ const businessWarning: React.FC<{ currentUser?: CurrentUser }> = (props) => {
clickTableBtnRef.current = false
}
// 把精算了的数据传给后端
const handleBeforeData = async (list: any, isReset?: boolean) => {
setActuaryTableLoading(true)
@ -2843,7 +2843,6 @@ const businessWarning: React.FC<{ currentUser?: CurrentUser }> = (props) => {
// handleBeforeData(sumList)
}
// 给精算算出具体的今年单车价值和去年单车价值
const handleGetVehicleAmount = (list: any) => {
console.log('list', list);
@ -2923,51 +2922,14 @@ const businessWarning: React.FC<{ currentUser?: CurrentUser }> = (props) => {
}
}
// 改变表格在加载过程中显示的字
const handleLoadingText = (str: string) => {
}
return (
<div className={'springFestivalBox'} style={{ background: '#fff', display: 'flex' }}>
<div className={'springFestivalBox'}>
<Spin style={{ display: 'none' }} className={'pageLoading'} />
<ProCard
className="pageTable-leftnav"
style={{ width: !collapsible ? "240px" : "60px" }}
headStyle={{ width: !collapsible ? "240px" : "60px" }}
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "240px" : "60px" }}
extra={<MenuFoldOutlined onClick={() => {
setCollapsible(!collapsible)
}} />}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "可筛选门店" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={!treeLoading ? [{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}] : []}
fieldNames={{
title: "label",
key: "key"
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
const selectedAreas = info.checkedNodes.filter(n => n?.type === 0)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
setSelectArea(selectedAreas.map(n => n?.value)?.toString() || '')
// actionRef?.current?.reload()
}}
/> : ''}
</ProCard>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div className={'businessWarningHideBox'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
@ -2987,280 +2949,293 @@ const businessWarning: React.FC<{ currentUser?: CurrentUser }> = (props) => {
</ProTable> : ''
}
</div>
<ProCard
style={{ width: !collapsible ? "calc(100% - 240px)" : "calc(100% - 60px)" }}
>
<ProTable
formRef={formRef}
actionRef={actionRef}
search={{
span: 6,
labelWidth: 100,
defaultCollapsed: false,
optionRender: ({ searchText }, { form }) => {
return [
<Button
key="reset"
onClick={() => {
setIsCompletion(false)
setBusinessTradeType(undefined)
formRef.current?.resetFields();
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
loading={showTableLoading}
onClick={() => {
setIsCompletion(false)
clickTableBtnRef.current = true
formRef.current?.submit();
}}
>
</Button>
]
}
}}
rowKey={(record) => {
return `${record?.SPRegionTypeId}-${record?.ServerpartId}-${record?.ServerpartShopId}-${record?.ServerpartShopName}-${record?.Name}-${record?.testIndex}-${record?.ServerpartName}`
}}
rowClassName={(record) => {
return `${record?.SPRegionTypeId}-${record?.ServerpartId}-${record?.ServerpartShopId}-${record?.ServerpartShopName}-${record?.Name}-${record?.testIndex}-${record?.ServerpartName}`
}}
headerTitle={
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>{tableHeaderTitle || ''}</span>
<div style={{ display: 'flex', alignItems: 'center', marginLeft: '4px' }}>
<span style={{ fontSize: '14px', color: 'gray', textIndent: '2rem' }}>{warnType.current ? '预警说明:' : ''}</span>
<span style={{ fontSize: '14px', color: 'red' }}>
{warnType.current === '1' ? '请重点关注入区车流增加自营商超营收同步增长,服务区整体营收呈现下降的情况!' :
warnType.current === '2' ? '请重点关注入区车流增加自营商超营收同步增长,服务区部分门店营收呈现下降的情况!' :
warnType.current === '3' ? '请重点关注营收与车流增幅产生较大差异的服务区!增幅差额=车流增幅-营收增幅,越大越不好,倒序排列' :
warnType.current === '4' ? '请重点关注营收与车流降幅产生较大差异的服务区!增幅差额=销售增幅-车流降幅,越大越不好,倒序排列' : ''}
</span>
</div>
<Tooltip title="分析入区车流与销售数据的趋势匹配情况,针对显著异常(如车流量增加但销售额未同步增长)提供预警,帮助发现可能的经营问题。">
<div style={{
display: 'flex', alignItems: 'center', justifyContent: 'center', width: '20px', height: '20px',
padding: '6px', border: '1px solid #ccc', color: '#ccc', borderRadius: '50%', cursor: 'pointer', marginLeft: '4px'
}}>?</div>
</Tooltip>
</div>}
id={'table-to-xls'}
columns={columns}
bordered={true}
scroll={{ y: 'calc(100vh - 450px)' }}
pagination={false}
loading={showTableLoading}
className={'revenueTable'}
dataSource={tableData}
request={async (params, sort, options) => {
console.log('params22', params)
// 没选服务区就return出去
if (!selectedId) {
setReqDetailList([])
return
}
setShowSort(false)
if (clickTableBtnRef.current) {
let paramsObj: any = {}
warnType.current = params.warningType
// setWarnType(params.warningType)
if (params?.solidType === '1') {
paramsObj = params
} else {
if (params.warningType === '1') {
paramsObj = {
...params,
showBayonet: '1',
showRevenue: '2',
showLevel: '1'
}
} else if (params.warningType === '2') {
paramsObj = {
...params,
showBayonet: '1',
showRevenue: '2',
showLevel: '2'
}
} else if (params.warningType === '3') {
paramsObj = {
...params,
showBayonet: '1',
showRevenue: '1'
}
setShowSort(true)
} else if (params.warningType === '4') {
paramsObj = {
...params,
showBayonet: '2',
showRevenue: '2',
}
setShowSort(true)
}
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
const selectedAreas = info.checkedNodes.filter(n => n?.type === 0)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
setSelectArea(selectedAreas.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
formRef={formRef}
actionRef={actionRef}
search={{
span: 6,
labelWidth: 100,
defaultCollapsed: false,
optionRender: ({ searchText }, { form }) => {
return [
<Button
key="reset"
onClick={() => {
setIsCompletion(false)
setBusinessTradeType(undefined)
formRef.current?.resetFields();
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
loading={showTableLoading}
onClick={() => {
setIsCompletion(false)
clickTableBtnRef.current = true
formRef.current?.submit();
}}
>
</Button>
]
}
}}
rowKey={(record) => {
return `${record?.SPRegionTypeId}-${record?.ServerpartId}-${record?.ServerpartShopId}-${record?.ServerpartShopName}-${record?.Name}-${record?.testIndex}-${record?.ServerpartName}`
}}
rowClassName={(record) => {
return `${record?.SPRegionTypeId}-${record?.ServerpartId}-${record?.ServerpartShopId}-${record?.ServerpartShopName}-${record?.Name}-${record?.testIndex}-${record?.ServerpartName}`
}}
headerTitle={
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>{tableHeaderTitle || ''}</span>
handleGetTableData(paramsObj)
}
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table={'table-to-xls-businessWarning'}
filename={`服务区经营预警_${searchParams?.StatisticsStartMonth}-${searchParams?.StatisticsEndMonth}`}
sheet="sheet1"
/>
</span>,
<Typography.Text type="secondary">{statisticalUnit === 1 ? "万元,万辆" : "元,辆"}</Typography.Text>,
<Button
key="new"
type="primary"
onClick={async (e) => {
setShowExportTable(true)
setTimeout(() => {
if (reqDetailList && reqDetailList.length > 0) {
exportTable(e)
} else {
setShowExportTable(false)
message.error('暂无数据可导出!')
}
}, 100)
}}
loading={showExportTable}
>
excel
</Button>
],
}}
columnsState={{
value: columnsStateMap,
onChange: (value: any) => {
setColumnsStateMap(value)
},
}}
options={{
manualRequest: true
}}
expandable={{
expandedRowKeys,
// defaultExpandedRowKeys: ['null-null-undefined-undefined-undefined-undefined-null'],
onExpand: async (record, event) => {
console.log('record', record)
console.log('event', event)
console.log('expandedRowKeys', expandedRowKeys)
if (record) {
if (expandedRowKeys && expandedRowKeys.length > 0) {
const list: any = JSON.parse(JSON.stringify(expandedRowKeys))
list.push(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
setExpandedRowKeys(list)
} else {
const list: any = []
list.push(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
setExpandedRowKeys(list)
}
} else {
const list: any = JSON.parse(JSON.stringify(expandedRowKeys))
const newList: any = list.filter((item) => item !== `${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
console.log('newList', newList)
setExpandedRowKeys(newList)
}
if (columnsLoading) {
<div style={{ display: 'flex', alignItems: 'center', marginLeft: '4px' }}>
<span style={{ fontSize: '14px', color: 'gray', textIndent: '2rem' }}>{warnType.current ? '预警说明:' : ''}</span>
<span style={{ fontSize: '14px', color: 'red' }}>
{warnType.current === '1' ? '请重点关注入区车流增加自营商超营收同步增长,服务区整体营收呈现下降的情况!' :
warnType.current === '2' ? '请重点关注入区车流增加自营商超营收同步增长,服务区部分门店营收呈现下降的情况!' :
warnType.current === '3' ? '请重点关注营收与车流增幅产生较大差异的服务区!增幅差额=车流增幅-营收增幅,越大越不好,倒序排列' :
warnType.current === '4' ? '请重点关注营收与车流降幅产生较大差异的服务区!增幅差额=销售增幅-车流降幅,越大越不好,倒序排列' : ''}
</span>
</div>
<Tooltip title="分析入区车流与销售数据的趋势匹配情况,针对显著异常(如车流量增加但销售额未同步增长)提供预警,帮助发现可能的经营问题。">
<div style={{
display: 'flex', alignItems: 'center', justifyContent: 'center', width: '20px', height: '20px',
padding: '6px', border: '1px solid #ccc', color: '#ccc', borderRadius: '50%', cursor: 'pointer', marginLeft: '4px'
}}>?</div>
</Tooltip>
</div>}
id={'table-to-xls'}
columns={columns}
bordered={true}
scroll={{ y: 'calc(100vh - 450px)' }}
pagination={false}
loading={showTableLoading}
className={'revenueTable'}
dataSource={tableData}
request={async (params, sort, options) => {
console.log('params22', params)
// 没选服务区就return出去
if (!selectedId) {
setReqDetailList([])
return
}
let isHave: boolean = true
if (event.children && event.children.length > 0) {
isHave = false
}
if (record && event.ServerpartId && isHave) {
setColumnsLoading(true)
addLoadingRow(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
const req: any = {
...searchParams,
pushProvinceCode: currentUser?.USER_PROVINCE || '340000',
ServerpartId: event.ServerpartId,
BusinessTradeType: BusinessTradeType || '',
calcYOY: isCalcYOYFlag,// 同比
calcQOQ: isCalcQOQFlag,// 环比
calcBayonet: isCalcBayonetFlag,// 最后一大列是否显示
}
const result = await handleGetMonthINCAnalysis(req)
const data = result.List && result.List.length > 0 ? wrapTreeNode(result.List) : []
console.log('data121', data)
let res: any = []
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any) => {
if (thirdItem.ServerpartId === event.ServerpartId) {
res = thirdItem.ShopINCList
}
})
}
})
setShowSort(false)
if (clickTableBtnRef.current) {
let paramsObj: any = {}
warnType.current = params.warningType
// setWarnType(params.warningType)
if (params?.solidType === '1') {
paramsObj = params
} else {
if (params.warningType === '1') {
paramsObj = {
...params,
showBayonet: '1',
showRevenue: '2',
showLevel: '1'
}
})
} else if (params.warningType === '2') {
paramsObj = {
...params,
showBayonet: '1',
showRevenue: '2',
showLevel: '2'
}
} else if (params.warningType === '3') {
paramsObj = {
...params,
showBayonet: '1',
showRevenue: '1'
}
setShowSort(true)
} else if (params.warningType === '4') {
paramsObj = {
...params,
showBayonet: '2',
showRevenue: '2',
}
setShowSort(true)
}
}
console.log('res', res)
if (res && res.length > 0) {
res.forEach((item: any, index: number) => {
item = handleChangeItem(item)
item.testIndex = index + 1
})
handleGetTableData(paramsObj)
}
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table={'table-to-xls-businessWarning'}
filename={`服务区经营预警_${searchParams?.StatisticsStartMonth}-${searchParams?.StatisticsEndMonth}`}
sheet="sheet1"
/>
</span>,
<Typography.Text type="secondary">{statisticalUnit === 1 ? "万元,万辆" : "元,辆"}</Typography.Text>,
<Button
key="new"
type="primary"
onClick={async (e) => {
setShowExportTable(true)
setTimeout(() => {
if (reqDetailList && reqDetailList.length > 0) {
exportTable(e)
} else {
setShowExportTable(false)
message.error('暂无数据可导出!')
}
}, 100)
}}
loading={showExportTable}
>
excel
</Button>
],
}}
columnsState={{
value: columnsStateMap,
onChange: (value: any) => {
setColumnsStateMap(value)
},
}}
options={{
manualRequest: true
}}
expandable={{
expandedRowKeys,
// defaultExpandedRowKeys: ['null-null-undefined-undefined-undefined-undefined-null'],
onExpand: async (record, event) => {
console.log('record', record)
console.log('event', event)
console.log('expandedRowKeys', expandedRowKeys)
if (record) {
if (expandedRowKeys && expandedRowKeys.length > 0) {
const list: any = JSON.parse(JSON.stringify(expandedRowKeys))
list.push(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
setExpandedRowKeys(list)
} else {
const list: any = []
list.push(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
setExpandedRowKeys(list)
}
} else {
const list: any = JSON.parse(JSON.stringify(expandedRowKeys))
const newList: any = list.filter((item) => item !== `${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
console.log('newList', newList)
setExpandedRowKeys(newList)
}
if (tableData && tableData.length > 0) {
const tableList: any = JSON.parse(JSON.stringify(tableData))
console.log('tableList', tableList)
if (haveIsOneService) {
tableList.forEach((item: any) => {
item.children = res
})
} else if (!haveIsOneArea) {
tableList.forEach((item: any) => {
if (columnsLoading) {
return
}
let isHave: boolean = true
if (event.children && event.children.length > 0) {
isHave = false
}
if (record && event.ServerpartId && isHave) {
setColumnsLoading(true)
addLoadingRow(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}-${event?.ServerpartName}`)
const req: any = {
...searchParams,
pushProvinceCode: currentUser?.USER_PROVINCE || '340000',
ServerpartId: event.ServerpartId,
BusinessTradeType: BusinessTradeType || '',
calcYOY: isCalcYOYFlag,// 同比
calcQOQ: isCalcQOQFlag,// 环比
calcBayonet: isCalcBayonetFlag,// 最后一大列是否显示
}
const result = await handleGetMonthINCAnalysis(req)
const data = result.List && result.List.length > 0 ? wrapTreeNode(result.List) : []
console.log('data121', data)
let res: any = []
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any) => {
if (thirdItem.ServerpartId === event.ServerpartId) {
thirdItem.children = res
res = thirdItem.ShopINCList
}
})
}
})
}
})
} else {
tableList.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.ServerpartId === event.ServerpartId) {
subItem.children = res
}
})
}
}
console.log('res', res)
if (res && res.length > 0) {
res.forEach((item: any, index: number) => {
item = handleChangeItem(item)
item.testIndex = index + 1
})
}
setTableData(tableList)
if (tableData && tableData.length > 0) {
const tableList: any = JSON.parse(JSON.stringify(tableData))
console.log('tableList', tableList)
if (haveIsOneService) {
tableList.forEach((item: any) => {
item.children = res
})
} else if (!haveIsOneArea) {
tableList.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
subItem.children.forEach((thirdItem: any) => {
if (thirdItem.ServerpartId === event.ServerpartId) {
thirdItem.children = res
}
})
}
})
}
})
} else {
tableList.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
if (subItem.ServerpartId === event.ServerpartId) {
subItem.children = res
}
})
}
})
}
setTableData(tableList)
}
removeLoadingRow(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}`)
setColumnsLoading(false)
}
removeLoadingRow(`${event?.SPRegionTypeId}-${event?.ServerpartId}-${event?.ServerpartShopId}-${event?.ServerpartShopName}-${event?.Name}-${event?.testIndex}`)
setColumnsLoading(false)
}
}
}}
/>
</ProCard>
}}
/>
</div>
</div>
<Drawer
width={'80%'}
visible={showCarDetailDrawer}

View File

@ -37,6 +37,7 @@ import LoadingBox from "../businessAnalysis/components/loading";
import AiDrawer from "@/components/AiDrawer";
import { request } from "http";
import data from "@/pages/newDataAnalysis/areaVehicle/data";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const { Text } = Typography;
@ -2380,7 +2381,7 @@ const revenueAnalysis: React.FC<{ currentUser?: CurrentUser, route?: string }> =
return (
<div className={'springFestivalBox'} style={{ background: '#fff', display: 'flex' }}>
<Spin style={{ display: 'none' }} className={'pageLoading'} />
<ProCard
{/* <ProCard
className="pageTable-leftnav"
style={{ width: !collapsible ? "240px" : "60px" }}
headStyle={{ width: !collapsible ? "240px" : "60px" }}
@ -2415,8 +2416,15 @@ const revenueAnalysis: React.FC<{ currentUser?: CurrentUser, route?: string }> =
// actionRef?.current?.reload()
}}
/> : ''}
</ProCard>
</ProCard> */}
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
const selectedAreas = info.checkedNodes.filter(n => n?.type === 0)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
setSelectArea(selectedAreas.map(n => n?.value)?.toString() || '')
}} />
<div className={'revenueAnalysisHideBox'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
@ -2435,9 +2443,12 @@ const revenueAnalysis: React.FC<{ currentUser?: CurrentUser, route?: string }> =
</ProTable> : ''
}
</div>
<ProCard
style={{ width: !collapsible ? "calc(100% - 240px)" : "calc(100% - 60px)" }}
>
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
formRef={formRef}
actionRef={actionRef}
@ -2662,21 +2673,7 @@ const revenueAnalysis: React.FC<{ currentUser?: CurrentUser, route?: string }> =
}
}}
/>
{/* <div>
{
showAiLoading ?
<div>
<LoadingBox />
</div> :
<div style={{ height: '400px' }}>
{aiRes || ''}
</div>
}
</div> */}
</ProCard>
</div>
{/* 月度信息抽屉 */}
<Drawer

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,28 @@
import React, {useRef, useState} from "react";
import type {CurrentUser} from "umi";
import { useRequest} from "umi";
import {connect} from "umi";
import type {ConnectState} from "@/models/connect";
import type {SHOPEXPENSEListModel} from "@/pages/reports/ShopExpenses/data";
import {MenuFoldOutlined} from "@ant-design/icons";
import type {FormInstance} from "antd";
import {Button, Drawer, message, Spin, Tree, Typography} from "antd";
import React, { useRef, useState } from "react";
import type { CurrentUser } from "umi";
import { useRequest } from "umi";
import { connect } from "umi";
import type { ConnectState } from "@/models/connect";
import type { SHOPEXPENSEListModel } from "@/pages/reports/ShopExpenses/data";
import { MenuFoldOutlined } from "@ant-design/icons";
import type { FormInstance } from "antd";
import { Button, Drawer, message, Spin, Tree, Typography } from "antd";
import ProCard from "@ant-design/pro-card";
import { getServerpartTree } from "@/services/options";
import type {ActionType} from "@ant-design/pro-table";
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/moment";
import {handleGetTableBasicData} from "@/pages/reports/ShopExpenseDetail/service";
import { handleGetTableBasicData } from "@/pages/reports/ShopExpenseDetail/service";
import session from "@/utils/session";
import {contractType} from "@/pages/contract/emun";
import { contractType } from "@/pages/contract/emun";
import ProjectDetail from "@/pages/BussinessProject/detail";
import type {BusinessProjectModel} from "@/pages/BussinessProject/data";
import {auto} from "@antv/s2"; // 枚举和树相关的引用,没有使用可以删除
import type { BusinessProjectModel } from "@/pages/BussinessProject/data";
import { auto } from "@antv/s2"; // 枚举和树相关的引用,没有使用可以删除
import LeftSelectTree from "../settlementAccount/component/leftSelectTree";
const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
const MerchantInformation: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
const actionRef = useRef<ActionType>();
const formRef = useRef<FormInstance>();
@ -35,13 +36,13 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
const [collapsible, setCollapsible] = useState<boolean>(false)
const [treeView,setTreeView] = useState<any>()
const [treeView, setTreeView] = useState<any>()
// 是否显示打印的表格
const [showExportTable,setShowExportTable] = useState<boolean>(false)
const [showExportTable, setShowExportTable] = useState<boolean>(false)
// 导出excel的时间
const [exportTime,setExportTime] = useState<string>()
const [exportTime, setExportTime] = useState<string>()
// 导出的加载效果
const [showLoading,setShowLoading] = useState<boolean>(false)
const [showLoading, setShowLoading] = useState<boolean>(false)
// 加载服务区树
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
const data = await getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, true, true)
@ -70,17 +71,17 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
// fixed:'left'
// },
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'Name',
hideInSearch: true,
width: 200,
ellipsis:true,
fixed:'left',
ellipsis: true,
fixed: 'left',
align: 'left',
render:(_,record)=>{
return <a style={{color:record.BUSINESSPROJECT_ID?'#1890ff':'#000000',cursor:record.BUSINESSPROJECT_ID?'pointer':''}} onClick={()=>{
if (record.BUSINESSPROJECT_ID){
console.log('record',record)
render: (_, record) => {
return <a style={{ color: record.BUSINESSPROJECT_ID ? '#1890ff' : '#000000', cursor: record.BUSINESSPROJECT_ID ? 'pointer' : '' }} onClick={() => {
if (record.BUSINESSPROJECT_ID) {
console.log('record', record)
setCurrentRow(record)
setShowDetail(true)
}
@ -107,7 +108,7 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
}
},
{
title:'结算模式',
title: '结算模式',
dataIndex: 'SETTLEMENT_MODES',
hideInTable: true,
hideInDescriptions: true,
@ -115,22 +116,22 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
fieldProps: {
mode: 'multiple'
},
request: ()=>{
request: () => {
return SETTLEMENT_MODESList
}
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
align: 'left',
dataIndex: 'MERCHANTS_NAME',
width: 200,
ellipsis:true,
render:(_,record)=>{
ellipsis: true,
render: (_, record) => {
return record?.MERCHANTS_NAME || record?.projectNumber || '-'
}
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
align: 'left',
dataIndex: 'BusinessType',
hideInSearch: true,
@ -139,97 +140,97 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
valueEnum: contractType
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
align: 'left',
dataIndex: 'COMPACT_STARTDATE',
width: 90,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
align: 'left',
dataIndex: 'COMPACT_ENDDATE',
width: 90,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'COMPACT_AMOUNT',
align:'right',
valueType:'digit',
align: 'right',
valueType: 'digit',
width: 90,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'SECURITYDEPOSIT',
align:'right',
valueType:'digit',
align: 'right',
valueType: 'digit',
width: 90,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'MINTURNOVER',
align:'right',
valueType:'digit',
align: 'right',
valueType: 'digit',
width: 100,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}></div>,
title: <div style={{ textAlign: 'center' }}></div>,
dataIndex: 'GUARANTEERATIO',
align:'right',
align: 'right',
width: 90,
hideInSearch: true,
render:(_,record)=>{
return <span>{record.GUARANTEERATIO?`${record.GUARANTEERATIO}%`:'-'}</span>
render: (_, record) => {
return <span>{record.GUARANTEERATIO ? `${record.GUARANTEERATIO}%` : '-'}</span>
}
},
{
title:'固定(保底)租金',
title: '固定(保底)租金',
dataIndex: '',
hideInSearch: true,
children: [
{
title:<div style={{textAlign:'center'}}>1</div>,
title: <div style={{ textAlign: 'center' }}>1</div>,
dataIndex: 'MINTURNOVERFirst',
align:'right',
valueType:'digit',
align: 'right',
valueType: 'digit',
width: 100,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}>2</div>,
title: <div style={{ textAlign: 'center' }}>2</div>,
dataIndex: 'MINTURNOVERSecond',
align:'right',
valueType:'digit',
align: 'right',
valueType: 'digit',
width: 100,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}>3</div>,
title: <div style={{ textAlign: 'center' }}>3</div>,
dataIndex: 'MINTURNOVERThird',
align:'right',
align: 'right',
width: 100,
valueType:'digit',
valueType: 'digit',
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}>4</div>,
title: <div style={{ textAlign: 'center' }}>4</div>,
dataIndex: 'MINTURNOVERFourth',
align:'right',
valueType:'digit',
align: 'right',
valueType: 'digit',
width: 100,
hideInSearch: true,
},
{
title:<div style={{textAlign:'center'}}>5</div>,
title: <div style={{ textAlign: 'center' }}>5</div>,
dataIndex: 'MINTURNOVERFifth',
align:'right',
align: 'right',
width: 100,
valueType:'digit',
valueType: 'digit',
hideInSearch: true,
},
]
@ -285,14 +286,14 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
borderRadius: '8px',
width: '200px'
}}>
<Spin/>
<span style={{marginLeft: '5px'}}>...</span>
<Spin />
<span style={{ marginLeft: '5px' }}>...</span>
</div>
</div>:''
</div> : ''
}
<div className={'merchantHideBox'} style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}>
<div className={'merchantHideBox'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
@ -305,9 +306,9 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
/> : ''
}
</div>
<div id='hiddenBox' style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}/>
<div style={{backgroundColor: '#fff',display:'flex'}}>
<ProCard
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
{/* <ProCard
style={{width:!collapsible ? "300px" : "60px"}}
className="pageTable-leftnav"
bodyStyle={{padding: 0, paddingTop: 20, paddingLeft: 20,width:!collapsible ? "300px" : "60px"}}
@ -341,9 +342,10 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width:!collapsible?'calc(100% - 300px)':'calc(100% - 60px)',
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
@ -354,81 +356,81 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
columns={columns}
bordered
rowKey={(record) => record?.Name + record?.Id + record?.BUSINESSPROJECT_ID}
search={{span: 6}}
scroll={{x: 1000,y: 'calc(100vh - 470px)'}}
pagination={{pageSize: 20}}
search={{ span: 6 }}
scroll={{ x: 1000, y: 'calc(100vh - 470px)' }}
pagination={{ pageSize: 20 }}
className={'overFlowYTable'}
request={async (params)=>{
if (!selectedId){
request={async (params) => {
if (!selectedId) {
setReqDetailList([])
return []
}
if (params.StartDate && params.EndDate){
if (params.StartDate && params.EndDate) {
setExportTime(`${moment(params.StartDate).format('YYYY-MM-DD')}_${moment(params.EndDate).format('YYYY-MM-DD')}`)
}else{
} else {
setExportTime('')
setReqDetailList([])
return []
}
console.log('selectedId',selectedId)
console.log('selectedId', selectedId)
let SETTLEMENT_MODESSTR: string = ''
if (params.SETTLEMENT_MODES && params.SETTLEMENT_MODES.length>0){
params.SETTLEMENT_MODES.forEach((item: any)=>{
if (SETTLEMENT_MODESSTR){
SETTLEMENT_MODESSTR+=`,${item}`
}else{
if (params.SETTLEMENT_MODES && params.SETTLEMENT_MODES.length > 0) {
params.SETTLEMENT_MODES.forEach((item: any) => {
if (SETTLEMENT_MODESSTR) {
SETTLEMENT_MODESSTR += `,${item}`
} else {
SETTLEMENT_MODESSTR = item
}
})
}
let isOneServer: boolean = false
if (selectedId.indexOf(',')===-1){
if (selectedId.indexOf(',') === -1) {
isOneServer = true
}
const req = {
ServerpartIds: selectedId,
SETTLEMENT_MODES:SETTLEMENT_MODESSTR || '',
startDate:params.StartDate || '',
endDate:params.EndDate || '',
keyword:params.MERCHANTS_NAME
SETTLEMENT_MODES: SETTLEMENT_MODESSTR || '',
startDate: params.StartDate || '',
endDate: params.EndDate || '',
keyword: params.MERCHANTS_NAME
}
const data = await handleGetTableBasicData(req)
if (data && data.length>0){
data.forEach((item: any)=>{
if (item.children && item.children.length>0){
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
let itemProjectNumber: number = 0
item.children.forEach((subItem: any)=>{
item.children.forEach((subItem: any) => {
subItem.projectNumber = subItem.children.length
itemProjectNumber+=subItem.projectNumber
itemProjectNumber += subItem.projectNumber
})
item.projectNumber = itemProjectNumber
}
})
}
console.log('data',data)
console.log('data', data)
let res: any = []
if (isOneServer){
if (data && data.length>0){
data.forEach((item: any)=>{
if (item.children && item.children.length>0){
item.children.forEach((subItem: any)=>{
if (isOneServer) {
if (data && data.length > 0) {
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
res.push(subItem)
})
}
})
}
}else{
} else {
res = data
}
setReqDetailList(data)
return {data: res, success: true}
return { data: res, success: true }
}}
headerTitle={"合同商户信息统计表(分账收银)"} // 列表表头
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}></span>} // 列表表头
toolbar={{
actions: [
<span style={{visibility: 'hidden'}}>
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
@ -483,6 +485,6 @@ const MerchantInformation: React.FC<{ currentUser: CurrentUser}> = (props) => {
)
}
export default connect(({user}: ConnectState) => ({
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(MerchantInformation);

View File

@ -25,6 +25,7 @@ import PageTitleBox from "@/components/PageTitleBox";
import { formatTreeData } from "@/utils/format";
import { handleGetListObj } from "@/utils/utils";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const abnormalAmount: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -279,7 +280,7 @@ const abnormalAmount: React.FC<{ currentUser: CurrentUser }> = (props) => {
: ''
}
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -318,7 +319,17 @@ const abnormalAmount: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
if (selectedIds.map(n => n?.value)?.toString().indexOf(',') === -1) {
handleGetShopList(selectedIds)
} else {
setServerpartShopObj({})
}
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -16,6 +16,7 @@ import SubMenu from "antd/lib/menu/SubMenu";
import moment from "moment";
import { handleGetABNORMALAUDITList } from "@/pages/reports/audit/abnormalAudit/service";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const abnormalAudit: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -253,7 +254,7 @@ const abnormalAudit: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -287,7 +288,9 @@ const abnormalAudit: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -25,6 +25,7 @@ import PageTitleBox from "@/components/PageTitleBox";
import { formatTreeData } from "@/utils/format";
import { handleGetListObj } from "@/utils/utils";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const abnormalExamine: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -289,7 +290,7 @@ const abnormalExamine: React.FC<{ currentUser: CurrentUser }> = (props) => {
: ''
}
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -328,7 +329,16 @@ const abnormalExamine: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
if (selectedIds.map(n => n?.value)?.toString().indexOf(',') === -1) {
handleGetShopList(selectedIds)
} else {
setServerpartShopObj({})
}
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -1,3 +1,4 @@
// 异常占比汇总
import { connect } from "umi";
import type { CurrentUser } from "umi";
import type { ConnectState } from "@/models/connect";
@ -14,6 +15,9 @@ import ReactHTMLTableToExcel from "react-html-table-to-excel";
import { handleGetAbnormalRateReport } from "@/pages/reports/audit/abnormalReport/service";
import moment from "moment/moment";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
const abnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -308,7 +312,7 @@ const abnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -342,7 +346,8 @@ const abnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
@ -359,7 +364,7 @@ const abnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
bordered
headerTitle={<PageTitleBox props={props} />}
search={{ span: 6 }}
scroll={{ x: 2000, y: 'calc(100vh - 470px)' }}
scroll={{ x: '100%', y: 'calc(100vh - 470px)' }}
request={async (params) => {
if (!selectedId) {
return
@ -373,37 +378,81 @@ const abnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
const data = await handleGetAbnormalRateReport(req)
console.log('data', data)
if (data && data.length > 0) {
setReqDetailList(data)
let fieldData: any = [
"TOTALCOUNT",
"TICKETCOUNT",
"EXCEPTIONCOUNT_1011",
"EXCEPTIONCOUNT_1050",
"EXCEPTIONCOUNT_1099",
"EXCEPTIONCOUNT_1060",
"EXCEPTIONCOUNT_2010",
"EXCEPTIONCOUNT_3030",
"EXCEPTIONCOUNT_3050",
"EXCEPTIONCOUNT_3010",
"EXCEPTIONCOUNT_3020",
"EXCEPTIONCOUNT_3990"
]
let enumList: any = []
let rateList: any = [
"EXCEPTIONCOUNT_1011Rate",
"EXCEPTIONCOUNT_1050Rate",
"EXCEPTIONCOUNT_1099Rate",
"EXCEPTIONCOUNT_1060Rate",
"EXCEPTIONCOUNT_2010Rate",
"EXCEPTIONCOUNT_3030Rate",
"EXCEPTIONCOUNT_3050Rate",
"EXCEPTIONCOUNT_3010Rate",
"EXCEPTIONCOUNT_3020Rate",
"EXCEPTIONCOUNT_3990Rate",
]
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data)), fieldData, enumList, [], rateList)
setReqDetailList(newPrintData)
return { data, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-abnormalReport"
filename={`单品统计报表${searchParams?.startDate}-${searchParams?.endDate}`}
sheet="sheet1"
/>
</span>,
// <span style={{ visibility: 'hidden' }}>
// <ReactHTMLTableToExcel
// buttonText={'导出excel'}
// ref={downloadBtnRef}
// table="table-to-xls-abnormalReport"
// filename={`单品统计报表${searchParams?.startDate}-${searchParams?.endDate}`}
// 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)
// 尝试一下 导出新方法
exportXlsxFromProColumnsExcelJS(columns,
reqDetailList,
`单品统计报表${searchParams?.startDate}-${searchParams?.endDate}`,
// {
// topTitle: `进销存类别报表`, // 顶部大标题
// }
)
} else {
message.error('暂无数据可导出!')
}
// if (reqDetailList && reqDetailList.length > 0) {
// setShowLoading(true)
// setTimeout(() => {
// setShowExportTable(true)
// setTimeout(() => {
// exportTable(e)
// }, 100)
// }, 100)
// } else {
// message.error('暂无数据可导出!')
// }
}}
>
excel

View File

@ -24,6 +24,7 @@ import PageTitleBox from "@/components/PageTitleBox";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
import { handleGetListObj } from "@/utils/utils";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const abnormalSale: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -279,7 +280,7 @@ const abnormalSale: React.FC<{ currentUser: CurrentUser }> = (props) => {
: ''
}
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -318,7 +319,17 @@ const abnormalSale: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
if (selectedIds.map(n => n?.value)?.toString().indexOf(',') === -1) {
handleGetShopList(selectedIds)
} else {
setServerpartShopObj({})
}
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -21,6 +21,7 @@ import { handleGetAuditTasksDetail } from './service'
import ProForm, { ProFormDatePicker, ProFormTextArea } from "@ant-design/pro-form";
import './style.less'
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const auditTasks: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -361,7 +362,7 @@ const auditTasks: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -395,7 +396,8 @@ const auditTasks: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -16,6 +16,9 @@ import { handleGetCheckAccountReport } from "./service";
import upload from "@/assets/upload.png";
import { handleGetCHECKACCOUNTList } from "@/pages/reports/audit/feedback/service";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
const checkAccountReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -451,7 +454,7 @@ const checkAccountReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -485,7 +488,10 @@ const checkAccountReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
@ -535,32 +541,50 @@ const checkAccountReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
})
}
console.log('list', list)
setReqDetailList(list)
let fieldData: any = [
"TypePoint",
"ExauditCount",
"TypeCount",
"PriceMore",
"PriceLess",
"TypeDays"
]
let enumList: any = []
let rateList: any = [
"ExauditRate",
"FeedbackRate",
"DaysCpercent",
]
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data)), fieldData, enumList, [], rateList)
setReqDetailList(newPrintData)
return { data: list, success: true }
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-checkAccountReport"
filename={`稽核情况汇总表${searchParams?.startDate}-${searchParams?.endDate}`}
sheet="sheet1"
/>
</span>,
// <span style={{ visibility: 'hidden' }}>
// <ReactHTMLTableToExcel
// buttonText={'导出excel'}
// ref={downloadBtnRef}
// table="table-to-xls-checkAccountReport"
// filename={`稽核情况汇总表${searchParams?.startDate}-${searchParams?.endDate}`}
// 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)
// 尝试一下 导出新方法
exportXlsxFromProColumnsExcelJS(columns,
reqDetailList,
`稽核情况汇总表${searchParams?.startDate}-${searchParams?.endDate}`,
// {
// topTitle: `进销存类别报表`, // 顶部大标题
// }
)
} else {
message.error('暂无数据可导出!')
}

View File

@ -1,15 +1,15 @@
import {connect} from "umi";
import type {CurrentUser} from "umi";
import type {ConnectState} from "@/models/connect";
import React, {useRef, useState} from "react";
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 { Popconfirm} from "antd";
import {Avatar, Button, Drawer, Menu, message, Space, Spin, Tree} from "antd";
import { MenuFoldOutlined } from "@ant-design/icons";
import type { FormInstance } from "antd";
import { Popconfirm } from "antd";
import { Avatar, Button, Drawer, Menu, message, Space, Spin, Tree } from "antd";
import useRequest from "@ahooksjs/use-request";
import {getServerpartTree, handleCallLogs} from "@/services/options";
import type {ActionType} from "@ant-design/pro-table";
import { getServerpartTree, handleCallLogs } 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 SubMenu from "antd/lib/menu/SubMenu";
@ -21,9 +21,12 @@ import {
} from "@/pages/reports/audit/feedback/service";
import AuditDetail from "@/pages/DataVerification/list/components/auditDetail";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
const checkAcount: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
@ -31,36 +34,36 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
const [collapsible, setCollapsible] = useState<boolean>(false)
const [treeView,setTreeView] = useState<any>()
const [treeView, setTreeView] = useState<any>()
// 加载服务区树
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
const data = await getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, true, true)
setTreeView(data)
return data
})
// 树相关的属性和方法
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 导出的加载效果
const [showLoading,setShowLoading] = useState<boolean>(false)
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
// 是否显示打印的表格
const [showExportTable,setShowExportTable] = useState<boolean>(false)
const [showExportTable, setShowExportTable] = useState<boolean>(false)
const [currenMenu, setCurrenMenu] = useState<any>(); // 当前选中左侧菜单的服务区节点
const [bigCurrenMenu,setBigCurrenMenu] = useState<any>() // 选中片区的节点
const [bigCurrenMenu, setBigCurrenMenu] = useState<any>() // 选中片区的节点
// 点击稽查反馈出现的弹框
const [inspectionModal,setInspectionModal] = useState<boolean>(false)
const [inspectionModal, setInspectionModal] = useState<boolean>(false)
const auditDetailRef = useRef<any>()
const [currentRow,setCurrentRow] = useState<any>()
const [currentRow, setCurrentRow] = useState<any>()
const columns: any = [
{
title:'处理状态',
dataIndex:'TREATMENT_MARKSTATE',
title: '处理状态',
dataIndex: 'TREATMENT_MARKSTATE',
hideInTable: true,
valueType: 'select',
valueEnum:{
0:"全部",
1:"未反馈",
2:"未冲正",
valueEnum: {
0: "全部",
1: "未反馈",
2: "未冲正",
},
initialValue: "0"
},
@ -71,7 +74,7 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
hideInTable: true,
hideInDescriptions: true,
colSize: 1,
initialValue: [moment().add(-1, 'month').format('YYYY-MM-DD'), moment().add(-1,"day").format('YYYY-MM-DD')],
initialValue: [moment().add(-1, 'month').format('YYYY-MM-DD'), moment().add(-1, "day").format('YYYY-MM-DD')],
search: {
transform: (value) => {
return {
@ -85,21 +88,21 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
}
},
{
title:'图片上传',
title: '图片上传',
hideInTable: true,
hideInSearch: true,
dataIndex: ''
},
{
title:'稽查类型',
title: '稽查类型',
hideInTable: true,
dataIndex:'CHECK_TYPE',
dataIndex: 'CHECK_TYPE',
valueType: 'select',
valueEnum:{
"":"全部",
"现场稽查":"现场稽查",
"区域稽查":"区域稽查",
"公司稽查":"公司稽查",
valueEnum: {
"": "全部",
"现场稽查": "现场稽查",
"区域稽查": "区域稽查",
"公司稽查": "公司稽查",
},
initialValue: ""
},
@ -120,44 +123,44 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
dataIndex: 'VALID',
valueType: 'select',
valueEnum: {
null:'全部',
null: '全部',
1: '有效',
0: '无效'
},
initialValue: '1'
},
{
title: <div style={{textAlign:'center'}}>{'序号'}</div>,
title: <div style={{ textAlign: 'center' }}>{'序号'}</div>,
dataIndex: '',
hideInSearch: true,
width: 70,
valueType: 'index'
},
{
title: <div style={{textAlign:'center'}}>{'服务区名称'}</div>,
title: <div style={{ textAlign: 'center' }}>{'服务区名称'}</div>,
width: 120,
dataIndex: 'SERVERPART_NAME',
hideInSearch: true,
},
{
title: <div style={{textAlign:'center'}}>{'门店名称'}</div>,
title: <div style={{ textAlign: 'center' }}>{'门店名称'}</div>,
width: 150,
dataIndex: 'SHOPNAME',
hideInSearch: true,
},
{
title: <div style={{textAlign:'center'}}>{'稽核反馈'}</div>,
title: <div style={{ textAlign: 'center' }}>{'稽核反馈'}</div>,
width: 200,
ellipsis: true,
dataIndex: 'CHECKACCOUNT_DESC',
hideInSearch: true,
render:(_,record)=>{
return <a onClick={()=>{
console.log('record',record)
render: (_, record) => {
return <a onClick={() => {
console.log('record', record)
setCurrentRow({
...record,
Audit_Id: record.CHECKACCOUNT_ID,
MachineCode:record.MACHINECODE
MachineCode: record.MACHINECODE
})
setInspectionModal(true)
}}>
@ -166,48 +169,48 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
}
},
{
title:<div style={{textAlign:'center'}}>{'稽核误差率'}</div>,
title: <div style={{ textAlign: 'center' }}>{'稽核误差率'}</div>,
width: 110,
hideInSearch: true,
align: 'right',
dataIndex: 'ERROR_RATE',
render:(_,record)=>{
return record?.ERROR_RATE?
<span style={{color: 'red',fontWeight:'bold'}}>{`${record?.ERROR_RATE}%`}</span>
:'-'
render: (_, record) => {
return record?.ERROR_RATE ?
<span style={{ color: 'red', fontWeight: 'bold' }}>{`${record?.ERROR_RATE}%`}</span>
: '-'
}
},
{
title:<div style={{textAlign:'center'}}>{'长短款/冲正流水'}</div>,
title: <div style={{ textAlign: 'center' }}>{'长短款/冲正流水'}</div>,
width: 130,
hideInSearch: true,
align: 'right',
dataIndex: 'DIFFERENT_PRICE',
render:(_,record)=>{
return <span style={{color:record.DIFFERENT_PRICE <0||record?.REPLENISH_AMOUNT<0?'red':record.DIFFERENT_PRICE >0||record?.REPLENISH_AMOUNT>0?'#008000':'',fontWeight:'bold' }}>
render: (_, record) => {
return <span style={{ color: record.DIFFERENT_PRICE < 0 || record?.REPLENISH_AMOUNT < 0 ? 'red' : record.DIFFERENT_PRICE > 0 || record?.REPLENISH_AMOUNT > 0 ? '#008000' : '', fontWeight: 'bold' }}>
{`${record.DIFFERENT_PRICE || '0'}/${record?.REPLENISH_AMOUNT || '0'}`}
</span>
}
},
{
title: <div style={{textAlign:'center'}}>{'稽核现金/对客现金'}</div>,
title: <div style={{ textAlign: 'center' }}>{'稽核现金/对客现金'}</div>,
width: 140,
hideInSearch: true,
dataIndex: 'CASH',
align: 'right',
render:(_,record)=>{
render: (_, record) => {
return `${record.CASHPAY || ''}/${record?.CASH || ''}`
}
},
{
title: <div style={{textAlign:'center'}}>{'对客营收'}</div>,
title: <div style={{ textAlign: 'center' }}>{'对客营收'}</div>,
width: 100,
hideInSearch: true,
align: 'right',
dataIndex: 'TOTALSELLAMOUNT'
},
{
title: <div style={{textAlign: 'center'}}>{'稽查时间'}</div>,
title: <div style={{ textAlign: 'center' }}>{'稽查时间'}</div>,
width: 160,
hideInSearch: true,
align: 'left',
@ -217,15 +220,15 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
}
},
{
title:'稽查类型',
title: '稽查类型',
width: 100,
dataIndex:'CHECK_TYPE',
dataIndex: 'CHECK_TYPE',
valueType: 'select',
valueEnum:{
"":"全部",
"现场稽查":"现场稽查",
"区域稽查":"区域稽查",
"公司稽查":"公司稽查",
valueEnum: {
"": "全部",
"现场稽查": "现场稽查",
"区域稽查": "区域稽查",
"公司稽查": "公司稽查",
},
hideInSearch: true
},
@ -253,7 +256,7 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
tempTable.remove() // 防止重复打印一个内容
}
// 查询的条件
const [searchParams,setSearchParams] = useState<any>()
const [searchParams, setSearchParams] = useState<any>()
return (
<div ref={(el) => {
@ -285,13 +288,13 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
borderRadius: '8px',
width: '200px'
}}>
<Spin/>
<span style={{marginLeft: '5px'}}>...</span>
<Spin />
<span style={{ marginLeft: '5px' }}>...</span>
</div>
</div> : ''
}
<div className={'saleReportHideBox'} style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}>
<div className={'saleReportHideBox'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
@ -304,10 +307,10 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
/> : ''
}
</div>
<div id='hiddenBox' style={{position: 'fixed', zIndex: -1, top: 0, left: 0}}/>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{backgroundColor: '#fff',display:'flex'}}>
<ProCard
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
{/* <ProCard
style={{width:!collapsible ? "300px" : "60px"}}
className="pageTable-leftnav"
bodyStyle={{padding: 0, paddingTop: 20, paddingLeft: 20,width:!collapsible ? "300px" : "60px"}}
@ -341,9 +344,11 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width:!collapsible?'calc(100% - 300px)':'calc(100% - 60px)',
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
@ -354,55 +359,63 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
columns={columns}
bordered
headerTitle={<PageTitleBox props={props} />}
search={{span: 6}}
request={async(params)=>{
console.log('bigCurrenMenu',bigCurrenMenu)
console.log('currenMenu',currenMenu)
if (!selectedId){
search={{ span: 6 }}
request={async (params) => {
console.log('bigCurrenMenu', bigCurrenMenu)
console.log('currenMenu', currenMenu)
if (!selectedId) {
return
}
const req = {
SearchParameter:{
SearchParameter: {
...params,
TREATMENT_MARKSTATE:params.TREATMENT_MARKSTATE==='0'?'':params.TREATMENT_MARKSTATE,
TREATMENT_MARKSTATE: params.TREATMENT_MARKSTATE === '0' ? '' : params.TREATMENT_MARKSTATE,
SERVERPART_IDS: selectedId,
},
PageIndex:1,
PageSize:99999
PageIndex: 1,
PageSize: 99999
}
handleCallLogs()
setSearchParams(params)
const data = await handleGetCHECKACCOUNTList(req)
console.log('data',data)
if (data && data.length>0){
setReqDetailList(data)
return {data,success: true}
console.log('data', data)
if (data && data.length > 0) {
let fieldData: any = [
"TOTALSELLAMOUNT"
]
let enumList: any = []
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data)), fieldData, enumList, [], [])
setReqDetailList(newPrintData)
return { data, success: true }
}
return {data: [],success: true}
return { data: [], success: true }
}}
toolbar={{
actions: [
<span style={{visibility: 'hidden'}}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-checkAcount"
filename={`现场稽核管理${searchParams?.Start_Date}-${searchParams?.End_Date}`}
sheet="sheet1"
/>
</span>,
// <span style={{ visibility: 'hidden' }}>
// <ReactHTMLTableToExcel
// buttonText={'导出excel'}
// ref={downloadBtnRef}
// table="table-to-xls-checkAcount"
// filename={`现场稽核管理${searchParams?.Start_Date}-${searchParams?.End_Date}`}
// 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)
// 尝试一下 导出新方法
exportXlsxFromProColumnsExcelJS(columns,
reqDetailList,
`现场稽核管理${searchParams?.Start_Date}-${searchParams?.End_Date}`,
// {
// topTitle: `进销存类别报表`, // 顶部大标题
// }
)
} else {
message.error('暂无数据可导出!')
}
@ -426,14 +439,14 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
setInspectionModal(false);
}}
destroyOnClose={true}
footer={<div style={{display: 'flex', width: '100%', justifyContent: 'space-between',alignItems:'center'}}>
footer={<div style={{ display: 'flex', width: '100%', justifyContent: 'space-between', alignItems: 'center' }}>
<div>
<Button danger onClick={() => {
auditDetailRef.current.setShowMoadl(!auditDetailRef.current.showModal)
}}></Button>
</div>
<div>
<Button style={{marginRight: '8px'}} onClick={()=>{
<Button style={{ marginRight: '8px' }} onClick={() => {
setCurrentRow(undefined)
setInspectionModal(false);
}}></Button>
@ -443,32 +456,32 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
const req: any = {
CHECKACCOUNTId: currentRow?.Audit_Id
}
console.log('req',req)
console.log('req', req)
const data = await handleDeleteCHECKACCOUNT(req)
if (data.Result_Code===100){
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
setCurrentRow(undefined)
setInspectionModal(false);
actionRef.current?.reload()
}else{
} else {
message.error(data.Result_Desc)
}
}}
>
<Button danger style={{marginRight: '8px'}}></Button>
<Button danger style={{ marginRight: '8px' }}></Button>
</Popconfirm>
<Button type='primary' onClick={async () => {
auditDetailRef.current?.auditFormRef.current.validateFields().then(async (res: any)=>{
if (res){
auditDetailRef.current?.auditFormRef.current.validateFields().then(async (res: any) => {
if (res) {
const res: any = auditDetailRef.current?.auditFormRef.current.getFieldsValue()
const detailObj: any = auditDetailRef.current?.detailRow
const imgList: any = auditDetailRef.current?.picList
let imgStr: string = ''
if (imgList && imgList.length>0){
imgList.forEach((item: any)=>{
if (imgStr){
imgStr+=`,${item.url}`
}else{
if (imgList && imgList.length > 0) {
imgList.forEach((item: any) => {
if (imgStr) {
imgStr += `,${item.url}`
} else {
imgStr = item.url
}
})
@ -476,19 +489,19 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
const req: any = {
CheckAccount_Id: currentRow.Audit_Id,
auditExplain: res?.CheckAccount_Desc,
isAddIn: !detailObj?.Add_Amount && detailObj?.Add_Amount!==0, // 有值false 没值true
imageInfo:imgStr,
isAddIn: !detailObj?.Add_Amount && detailObj?.Add_Amount !== 0, // 有值false 没值true
imageInfo: imgStr,
// memberShipId:'',
provinceCode: currentUser.ProvinceCode,
addAmout: res?.Add_Amount
}
const data = await handleUpLoadAuditExplain(req)
if (data.Result_Code===100){
if (data.Result_Code === 100) {
message.success(data.Result_Desc)
setCurrentRow(undefined)
setInspectionModal(false);
actionRef.current?.reload()
}else{
} else {
message.error(data.Result_Desc)
}
}
@ -497,12 +510,12 @@ const checkAcount: React.FC<{ currentUser: CurrentUser}> = (props) => {
</div>
</div>}
>
<AuditDetail onRef={auditDetailRef} isShow={inspectionModal} rowDetail={currentRow} currentDetail={currentRow}/>
<AuditDetail onRef={auditDetailRef} isShow={inspectionModal} rowDetail={currentRow} currentDetail={currentRow} />
</Drawer>
</div>
)
}
export default connect(({user}: ConnectState) => ({
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(checkAcount);

View File

@ -17,6 +17,7 @@ import moment from "moment";
import * as numeral from "numeral";
import ProDescriptions from "@ant-design/pro-descriptions";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const curDailyReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -353,48 +354,18 @@ const curDailyReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
extra={<MenuFoldOutlined onClick={() => {
setCollapsible(!collapsible)
}} />}
colSpan={!collapsible ? "300px" : "60px"}
title={!collapsible ? "请选择服务区" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={[{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}]}
fieldNames={{
title: "label",
key: "key"
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const all = info.checkedNodes.filter(n => n?.key === '0-0')
if (all && all.length > 0) {
// setIsAll(true)
setSelectedId(undefined)
} else {
// setIsAll(false)
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
}
// actionRef?.current?.reload()
// getData(selectedIds.map(n => n?.value)?.toString() || '')
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const all = info.checkedNodes.filter(n => n?.key === '0-0')
if (all && all.length > 0) {
// setIsAll(true)
setSelectedId(undefined)
} else {
// setIsAll(false)
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
}
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -17,6 +17,7 @@ import { handleGetCHECKACCOUNTList, handleUpLoadAuditExplain } from "@/pages/rep
import AuditDetail from "@/pages/DataVerification/list/components/auditDetail";
import upload from '@/assets/upload.png'
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const checkAcount: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -311,7 +312,7 @@ const checkAcount: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -345,7 +346,8 @@ const checkAcount: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -14,6 +14,9 @@ import ReactHTMLTableToExcel from "react-html-table-to-excel";
import { handleGetYsabnormalityReport } from "@/pages/reports/audit/spAbnormalReport/service";
import moment from "moment/moment";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
const spAbnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -305,7 +308,7 @@ const spAbnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -339,7 +342,9 @@ const spAbnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
@ -352,7 +357,7 @@ const spAbnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
columns={columns}
rowKey={(record) => record?.Id + record?.Name}
bordered
scroll={{ x: 2000 }}
scroll={{ x: '100%', y: 'calc(100vh - 470px)' }}
headerTitle={<PageTitleBox props={props} />}
search={{ span: 6 }}
request={async (params) => {
@ -370,7 +375,6 @@ const spAbnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
const data = await handleGetYsabnormalityReport(req)
console.log('data', data)
if (data && data.length > 0) {
setReqDetailList(data)
const list: any = JSON.parse(JSON.stringify(data))
list.forEach((item: any, index: number) => {
item.index = index + 1
@ -385,33 +389,62 @@ const spAbnormalReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
})
}
})
let fieldData: any = [
"EXCEPTIONTYPE",
"EXCEPTIONTYPE_B",
"EXCEPTIONTYPE_C",
"EXCEPTIONTYPE_Z",
"EXCEPTIONTYPE_F",
"EXCEPTIONTYPE_G",
"EXCEPTIONTYPE_L",
"EXCEPTIONTYPE_M",
"EXCEPTIONTYPE_R",
"TotalMust",
"EXCEPTIONTYPE_A",
"EXCEPTIONTYPE_H",
"EXCEPTIONTYPE_I",
"EXCEPTIONTYPE_J",
"EXCEPTIONTYPE_N",
"EXCEPTIONTYPE_O",
"EXCEPTIONTYPE_P",
"EXCEPTIONTYPE_Q",
"TotalMay",
]
let enumList: any = []
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(list)), fieldData, enumList, [], [])
setReqDetailList(newPrintData)
return { data: list, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-spAbnormalReport"
filename={`异常稽查报表${searchParams?.startDate}-${searchParams?.endDate}`}
sheet="sheet1"
/>
</span>,
// <span style={{ visibility: 'hidden' }}>
// <ReactHTMLTableToExcel
// buttonText={'导出excel'}
// ref={downloadBtnRef}
// table="table-to-xls-spAbnormalReport"
// filename={`异常稽查报表${searchParams?.startDate}-${searchParams?.endDate}`}
// 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)
// 尝试一下 导出新方法
exportXlsxFromProColumnsExcelJS(columns,
reqDetailList,
`异常稽查报表${searchParams?.startDate}-${searchParams?.endDate}`,
// {
// topTitle: `进销存类别报表`, // 顶部大标题
// }
)
} else {
message.error('暂无数据可导出!')
}

View File

@ -15,6 +15,9 @@ import ReactHTMLTableToExcel from "react-html-table-to-excel";
import moment from "moment";
import { handleGetSpecialBehaviorReport } from "@/pages/reports/audit/specialReport/service";
import PageTitleBox from "@/components/PageTitleBox";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
const specialReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -142,6 +145,7 @@ const specialReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
title: <div style={{ textAlign: 'center' }}></div>,
width: 150,
align: 'right',
valueType: 'digit',
hideInSearch: true,
dataIndex: 'EXCEPTIONCOUNT_2029'
},
@ -238,7 +242,7 @@ const specialReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -272,8 +276,8 @@ const specialReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
@ -308,37 +312,68 @@ const specialReport: React.FC<{ currentUser: CurrentUser }> = (props) => {
if (data && data.length > 0) {
const list: any = handleChangeIndexList(data)
console.log('list', list)
setReqDetailList(list)
let fieldData: any = [
"EXCEPTIONCOUNT_1019",
"TOTALCOUNT_1019",
"EXCEPTIONCOUNT_1029",
"TOTALCOUNT_1029",
"EXCEPTIONCOUNT_2029",
"TOTALCOUNT_2029",
]
let enumList: any = []
let rateList: any = [
"EXCEPTION_1019",
"EXCEPTION_1029",
"EXCEPTION_2029",
]
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(list)), fieldData, enumList, [], rateList)
setReqDetailList(newPrintData)
return { data: list, success: true }
}
return { data: [], success: true }
}}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-specialReport"
filename={`特殊行为占比${searchParams?.startDate}-${searchParams?.endDate}`}
sheet="sheet1"
/>
</span>,
// <span style={{ visibility: 'hidden' }}>
// <ReactHTMLTableToExcel
// buttonText={'导出excel'}
// ref={downloadBtnRef}
// table="table-to-xls-specialReport"
// filename={`特殊行为占比${searchParams?.startDate}-${searchParams?.endDate}`}
// 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)
// 尝试一下 导出新方法
exportXlsxFromProColumnsExcelJS(columns,
reqDetailList,
`特殊行为占比${searchParams?.startDate}-${searchParams?.endDate}`,
// {
// topTitle: `进销存类别报表`, // 顶部大标题
// }
)
} else {
message.error('暂无数据可导出!')
}
// if (reqDetailList && reqDetailList.length > 0) {
// setShowLoading(true)
// setTimeout(() => {
// setShowExportTable(true)
// setTimeout(() => {
// exportTable(e)
// }, 100)
// }, 100)
// } else {
// message.error('暂无数据可导出!')
// }
}}
>
excel

View File

@ -22,6 +22,7 @@ import type { BusinessProjectModel } from "@/pages/BussinessProject/data";
import ProjectDetail from "@/pages/BussinessProject/detail";
import SHOPEXPENSETable from "@/pages/reports/ShopExpenseDetail/detail";
import { handleHighPrecision } from "@/utils/utils";
import LeftSelectTree from "../settlementAccount/component/leftSelectTree";
const cashierDeduction: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -481,7 +482,7 @@ const cashierDeduction: React.FC<{ currentUser: CurrentUser }> = (props) => {
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -519,7 +520,15 @@ const cashierDeduction: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
const selectedAreaIds = info.checkedNodes.filter(n => n?.type === 0)
setSelectedAreaId(selectedAreaIds.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
@ -681,7 +690,7 @@ const cashierDeduction: React.FC<{ currentUser: CurrentUser }> = (props) => {
console.log('res', res)
return { data: res, success: true }
}}
headerTitle={`分账收银扣费明细表(${searchMonth || '-'}月)`} // 列表表头
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>{`分账收银扣费明细表(${searchMonth || '-'}月)`}</span>} // 列表表头
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>

View File

@ -960,6 +960,7 @@ const commodityInfo: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
closable={false}
destroyOnClose
bodyStyle={{ padding: '12px 24px' }}
>
<Detail currentRow={currentRow} currentUser={currentUser} treeView={treeView} />
</Drawer>

View File

@ -23,6 +23,7 @@ import session from "@/utils/session";
import PageTitleBox from "@/components/PageTitleBox";
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
import { formatTreeData } from "@/utils/format";
import LeftSelectTree from "../../settlementAccount/component/leftSelectTree";
const shopCommodity: React.FC<{ currentUser: CurrentUser }> = (props) => {
@ -251,7 +252,7 @@ const shopCommodity: React.FC<{ currentUser: CurrentUser }> = (props) => {
}
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -285,7 +286,8 @@ const shopCommodity: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -21,6 +21,7 @@ import ProjectDetail from "@/pages/BussinessProject/detail";
import DailyRevenue from "@/pages/reports/receivedAccounts/component/dailyRevenue";
import * as numeral from "numeral";
import { handleHighPrecision } from "@/utils/utils";
import LeftSelectTree from "../settlementAccount/component/leftSelectTree";
const receivedAccounts: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -438,7 +439,7 @@ const receivedAccounts: React.FC<{ currentUser: CurrentUser }> = (props) => {
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -479,7 +480,15 @@ const receivedAccounts: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
// 选中的片区
const selectedAreas = info.checkedNodes.filter(n => n?.type === 0)
setSelectedAreaId(selectedAreas.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
@ -626,7 +635,7 @@ const receivedAccounts: React.FC<{ currentUser: CurrentUser }> = (props) => {
console.log('res', res)
return { data: res, success: true }
}}
headerTitle={`分账收银到账统计表(${searchMonth || '-'}月)`} // 列表表头
headerTitle={<span style={{ color: "#1890ff", fontSize: 14, fontWeight: 600 }}>{`分账收银到账统计表(${searchMonth || '-'}月)`}</span>} // 列表表头
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>

View File

@ -29,6 +29,7 @@ import { handleGetProjectPeriodIncome, handleStorageMonthProjectAccount } from "
import { wrapTreeNode } from "@/utils/format";
import { handleGetSERVERPARTCRTList } from "@/pages/basicManage/costing/service";
import { handleHighPrecision } from "@/utils/utils";
import LeftSelectTree from "../settlementAccount/component/leftSelectTree";
const revenueConfirmation: React.FC<{ currentUser: CurrentUser }> = (props) => {
const { currentUser } = props
@ -1096,7 +1097,7 @@ const revenueConfirmation: React.FC<{ currentUser: CurrentUser }> = (props) => {
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<ProCard
{/* <ProCard
style={{ width: !collapsible ? "300px" : "60px" }}
className="pageTable-leftnav"
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
@ -1134,7 +1135,14 @@ const revenueConfirmation: React.FC<{ currentUser: CurrentUser }> = (props) => {
}}
// switcherIcon={<PlusOutlined />}
/> : ''}
</ProCard>
</ProCard> */}
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} otherFun={(info: any) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
const selectedAreaIds = info.checkedNodes.filter(n => n?.type === 0)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
setSelectAreaId(selectedAreaIds.map(n => n?.value)?.toString() || '')
}} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,

View File

@ -336,7 +336,9 @@ const YearExamineDetailTable = ({ parentRow, currentApprovalstate, onRef, setIsS
if (currentApprovalstate < 1) {
return
}
handleShowSettlementDetail()
if (handleShowSettlementDetail) {
handleShowSettlementDetail()
}
}}>
{record?.RevenueAmount ? `${handleFormatNumber(record?.RevenueAmount)}${record?.addRevenueMoney ? `${record?.addRevenueMoney > 0 ? '+' : record?.addRevenueMoney < 0 ? '' : ''}${record?.addRevenueMoney}` : ''}` : '0'}
</a> :

View File

@ -46,6 +46,7 @@ import ReactHTMLTableToExcel from "react-html-table-to-excel";
import ChangeRevenue from "@/pages/reports/shareRoyalty/component/changeRevenue";
import DifferenceAmount from './component/differenceAmount';
import PageTitleBox from '@/components/PageTitleBox';
import LeftSelectTree from '../settlementAccount/component/leftSelectTree';
const { Text } = Typography;
@ -303,6 +304,7 @@ const ReportTable: React.FC<{ currentUser?: CurrentUser, isComponents?: boolean,
title: '经营商家',
dataIndex: 'Business_Unit',
ellipsis: true,
width: 150,
key: 'Business_Unit',
hideInSearch: true,
render: (_, record) => {
@ -1256,40 +1258,42 @@ const ReportTable: React.FC<{ currentUser?: CurrentUser, isComponents?: boolean,
<div style={{ backgroundColor: '#fff', width: '100%', display: 'flex' }}>
{
isComponents ? '' :
<ProCard
className="pageTable-leftnav"
style={{ width: !collapsible ? "240px" : "60px" }}
headStyle={{ width: !collapsible ? "240px" : "60px" }}
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "240px" : "60px" }}
extra={<MenuFoldOutlined onClick={() => {
setCollapsible(!collapsible)
}} />}
colSpan={!collapsible ? "240px" : "60px"}
title={!collapsible ? "可筛选门店" : ""}
headerBordered
collapsed={collapsible}
>
{treeView && treeView.length > 0 ? <Tree
checkable
treeData={!treeLoading ? [{
label: '全部',
value: 0,
key: '0-0',
children: treeView
}] : []}
fieldNames={{
title: "label",
key: "key"
}}
blockNode
defaultExpandedKeys={['0-0']}
onCheck={(checkedKeys: React.Key[] | any, info) => {
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
// actionRef?.current?.reload()
}}
/> : ''}
</ProCard>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
// <ProCard
// className="pageTable-leftnav"
// style={{ width: !collapsible ? "240px" : "60px" }}
// headStyle={{ width: !collapsible ? "240px" : "60px" }}
// bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "240px" : "60px" }}
// extra={<MenuFoldOutlined onClick={() => {
// setCollapsible(!collapsible)
// }} />}
// colSpan={!collapsible ? "240px" : "60px"}
// title={!collapsible ? "可筛选门店" : ""}
// headerBordered
// collapsed={collapsible}
// >
// {treeView && treeView.length > 0 ? <Tree
// checkable
// treeData={!treeLoading ? [{
// label: '全部',
// value: 0,
// key: '0-0',
// children: treeView
// }] : []}
// fieldNames={{
// title: "label",
// key: "key"
// }}
// blockNode
// defaultExpandedKeys={['0-0']}
// onCheck={(checkedKeys: React.Key[] | any, info) => {
// const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
// setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
// // actionRef?.current?.reload()
// }}
// /> : ''}
// </ProCard>
}
<div style={{
paddingTop: isComponents ? '16px' : 0,
@ -1925,7 +1929,7 @@ const ReportTable: React.FC<{ currentUser?: CurrentUser, isComponents?: boolean,
],
}}
scroll={isComponents ? { y: 'calc(100vh - 300px)' } : false}
scroll={isComponents ? { y: 'calc(100vh - 300px)' } : { x: "100%" }}
pagination={false}
/>
</div>

View File

@ -48,6 +48,36 @@ const toPath = (di?: AnyCol['dataIndex']): (string | number)[] =>
const getByPath = (obj: any, path: (string | number)[]) =>
path.reduce((acc, k) => (acc == null ? acc : acc[k]), obj);
/** 支持 A|B 或逻辑的取值 */
const getValueWithOr = (obj: any, dataIndex?: AnyCol['dataIndex']): any => {
if (!dataIndex) return undefined;
// 如果是数组,直接使用原逻辑
if (Array.isArray(dataIndex)) {
return getByPath(obj, dataIndex);
}
// 如果是字符串,检查是否包含 | 符号
if (typeof dataIndex === 'string') {
if (dataIndex.includes('|')) {
// 分割并按优先级取值
const keys = dataIndex.split('|').map(key => key.trim());
for (const key of keys) {
const value = getByPath(obj, toPath(key));
if (value != null && value !== '') {
return value;
}
}
return null;
} else {
// 普通路径,使用原逻辑
return getByPath(obj, toPath(dataIndex));
}
}
return undefined;
};
/** 过滤 hideInTable父级联动 */
function pruneHiddenColumns(cols: AnyCol[]): AnyCol[] {
const walk = (arr: AnyCol[]): AnyCol[] =>
@ -129,7 +159,7 @@ function getCellValue(col: AnyCol, record: any, rowIndex: number) {
// << 新增:序号列
if (col.valueType === 'index') return rowIndex + 1;
const raw = getByPath(record, toPath(col.dataIndex));
const raw = getValueWithOr(record, col.dataIndex);
if (col.valueEnum) {
const ve = col.valueEnum[raw as any];
if (typeof ve === 'string') return ve;

View File

@ -1091,3 +1091,119 @@ export function formatTreeData(
return formatRecursive(data);
}
export async function getUserIP(): Promise<string> {
try {
// 尝试多个第三方API服务
const apis = [
'https://api.ipify.org?format=json',
'https://ipapi.co/json/',
'https://jsonip.com/',
'https://httpbin.org/ip'
];
for (const api of apis) {
try {
const response = await fetch(api, {
method: 'GET',
timeout: 5000, // 5秒超时
});
if (!response.ok) {
continue;
}
const data = await response.json();
// 根据不同API返回格式获取IP
if (data.ip) {
return data.ip;
} else if (data.origin) {
// httpbin返回格式
return data.origin;
}
} catch (error) {
console.warn(`IP API ${api} 请求失败:`, error);
continue;
}
}
throw new Error('所有IP服务都无法访问');
} catch (error) {
console.error('获取IP地址失败:', error);
return '获取失败';
}
}
/**
* IP地址获取地理位置信息
* @param ip IP地址
* @returns Promise<object>
*/
export async function getLocationByIP(ip: string, ak: string): Promise<{
country?: string;
province?: string;
city?: string;
district?: string;
isp?: string;
success: boolean;
message?: string;
}> {
if (!ip || ip === '获取失败') {
return {
success: false,
message: 'IP地址无效'
};
}
if (!ak) {
return {
success: false,
message: '百度地图API密钥(ak)不能为空'
};
}
try {
const response = await fetch(`/baidu-api/location/ip?ip=${ip}&ak=${ak}`, {
method: 'GET',
timeout: 8000,
headers: {
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP错误: ${response.status}`);
}
const data = await response.json();
// 检查百度API返回状态
if (data.status !== 0) {
return {
success: false,
message: `百度API错误: ${data.message || '未知错误'}`
};
}
// 解析百度地图返回的数据
const content = data.content;
const addressDetail = content.address_detail;
return {
country: '中国', // 百度地图IP定位默认中国
province: addressDetail.province || '',
city: addressDetail.city || '',
district: addressDetail.district || '',
isp: content.address || '',
success: true
};
} catch (error) {
console.error('获取地理位置失败:', error);
return {
success: false,
message: '获取地理位置失败'
};
}
}

View File

@ -1,4 +1,4 @@
// 由 scripts/writeVersion.js 自动生成
export const VERSION = "4.5.62";
export const GIT_HASH = "d0c4edd";
export const BUILD_TIME = "2025-09-23T05:40:18.538Z";
export const VERSION = "4.5.64";
export const GIT_HASH = "5a7f174";
export const BUILD_TIME = "2025-09-26T03:21:11.008Z";