nili
3 months ago
18 changed files with 563 additions and 65 deletions
@ -0,0 +1 @@ |
|||||
|
!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["51.a2ea1b3b.async.js",51],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["p__MoneyManagement.7ad34f8d.async.js",190],["247.3fe8fb10.async.js",247],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.4594a64b.async.js",301],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.c61abcd9.async.js",371],["390.41467286.async.js",390],["393.38316f72.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.92290426.async.js",455],["p__Proxy__ProxyUserManagement.7f03f17a.async.js",526],["531.4c68f902.async.js",531],["539.49b7b156.async.js",539],["p__AdvRecordListV2.77bc346f.async.js",542],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.20e45f05.async.js",635],["p__App__AppManagement.7b88d7c4.async.js",731],["p__AdminManagement.16f4328b.async.js",816],["822.4ba8fa04.async.js",822],["841.614ef4c0.async.js",841],["p__AdvRecordList.fc092f59.async.js",857],["p__UserManagement.5e827801.async.js",903],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930],["942.561ac28f.async.js",942],["p__Proxy__ProxyAdvRecordListV2.d373f52a.async.js",990]],"r":{"/*":[20,28],"/":[1,6,7,19,21,28],"/welcome":[1,2,3,11,19,29,6,7,21,28],"/super":[0,1,2,5,13,15,16,24,28,29,6,7,19,21],"/adminList":[0,1,2,23,24,30,6,7,19,21,28],"/bind":[1,2,11,12,18,19,29,6,7,21,28],"/appList":[0,1,2,5,12,15,16,22,24,28,29,6,7,19,21],"/advList/:code":[0,1,2,15,16,19,24,25,26,28,29,6,7,21],"/advListV2/:code":[0,1,2,15,16,17,19,24,25,28,29,6,7,21],"/user/:code":[0,1,2,15,16,24,27,28,29,6,7,19,21],"/money/:code":[0,1,2,4,15,16,24,28,29,6,7,19,21],"/app/:code":[0,1,2,9,15,16,19,24,25,28,29,6,7,21],"/user/login":[1,2,8,15,24],"/proxy/advListV2/:code":[0,1,2,15,16,19,24,25,28,29,31,6,7,21],"/proxy/user/:code":[0,1,2,14,15,16,24,28,29,6,7,19,21]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}(); |
@ -1 +0,0 @@ |
|||||
!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["51.a2ea1b3b.async.js",51],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["p__MoneyManagement.7ad34f8d.async.js",190],["247.3fe8fb10.async.js",247],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.4594a64b.async.js",301],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.ec53e5c4.async.js",371],["390.41467286.async.js",390],["393.38316f72.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.92290426.async.js",455],["531.4c68f902.async.js",531],["539.49b7b156.async.js",539],["p__AdvRecordListV2.516b9678.async.js",542],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.20e45f05.async.js",635],["p__App__AppManagement.7b88d7c4.async.js",731],["p__AdminManagement.16f4328b.async.js",816],["822.4ba8fa04.async.js",822],["841.614ef4c0.async.js",841],["p__AdvRecordList.fc092f59.async.js",857],["p__UserManagement.5e827801.async.js",903],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930],["942.561ac28f.async.js",942]],"r":{"/*":[19,27],"/":[1,6,7,18,20,27],"/welcome":[1,2,3,11,18,28,6,7,20,27],"/super":[0,1,2,5,13,14,15,23,27,28,6,7,18,20],"/adminList":[0,1,2,22,23,29,6,7,18,20,27],"/bind":[1,2,11,12,17,18,28,6,7,20,27],"/appList":[0,1,2,5,12,14,15,21,23,27,28,6,7,18,20],"/advList/:code":[0,1,2,14,15,18,23,24,25,27,28,6,7,20],"/advListV2/:code":[0,1,2,14,15,16,18,23,24,27,28,6,7,20],"/user/:code":[0,1,2,14,15,23,26,27,28,6,7,18,20],"/money/:code":[0,1,2,4,14,15,23,27,28,6,7,18,20],"/app/:code":[0,1,2,9,14,15,18,23,24,27,28,6,7,20],"/user/login":[1,2,8,14,23]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}(); |
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,336 @@ |
|||||
|
import { advList } from '@/services/matrix/admin'; |
||||
|
import { incomeDaily1, incomeOverview1 } from '@/services/matrix/device'; |
||||
|
import { Column } from '@ant-design/charts'; |
||||
|
import { |
||||
|
ColumnsState, |
||||
|
PageContainer, |
||||
|
ProColumns, |
||||
|
ProFormDateRangePicker, |
||||
|
ProFormSelect, |
||||
|
ProTable, |
||||
|
QueryFilter, |
||||
|
StatisticCard, |
||||
|
} from '@ant-design/pro-components'; |
||||
|
import { useIntl } from '@umijs/max'; |
||||
|
import { Divider, Tabs } from 'antd'; |
||||
|
import TabPane from 'antd/es/tabs/TabPane'; |
||||
|
import moment from 'moment'; |
||||
|
import RcResizeObserver from 'rc-resize-observer'; |
||||
|
import React, { useEffect, useRef, useState } from 'react'; |
||||
|
import { useParams } from 'react-router-dom'; |
||||
|
|
||||
|
import UserInfo from '../User/UserInfo'; |
||||
|
|
||||
|
// import { RequestOptionsType, ProFieldRequestData } from "@ant-design/pro-utils";
|
||||
|
|
||||
|
import type { ActionType } from '@ant-design/pro-components'; |
||||
|
const ProxyAdvRecordListV2: React.FC = () => { |
||||
|
const actionRef = useRef<ActionType>(); |
||||
|
const deviceRef = useRef<ActionType>(); |
||||
|
|
||||
|
const [responsive, setResponsive] = useState(false); |
||||
|
/** |
||||
|
* @en-US International configuration |
||||
|
* @zh-CN 国际化配置 |
||||
|
* */ |
||||
|
const intl = useIntl(); |
||||
|
const { code } = useParams(); |
||||
|
|
||||
|
const [overview, setOverview] = useState<API.OverviewBo>(); |
||||
|
const [daily, setDaily] = useState<API.DateIncome[]>([]); |
||||
|
|
||||
|
const isMobile = () => { |
||||
|
return window.innerWidth <= 768; |
||||
|
}; |
||||
|
|
||||
|
const [columnsState, setColumnsState] = useState<Record<string, ColumnsState>>({ |
||||
|
deviceId: { show: !isMobile() }, |
||||
|
appName: { show: !isMobile() }, |
||||
|
platform: { show: !isMobile() }, |
||||
|
deviceBrand: { show: !isMobile() }, |
||||
|
deviceName: { show: !isMobile() }, |
||||
|
ip: { show: !isMobile() }, |
||||
|
}); |
||||
|
|
||||
|
const columns: ProColumns<API.MatrixAdvRecordBo>[] = [ |
||||
|
{ |
||||
|
title: '用户id', |
||||
|
dataIndex: 'userId', |
||||
|
valueType: 'textarea', |
||||
|
hideInTable: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '设备id', |
||||
|
dataIndex: 'deviceId', |
||||
|
valueType: 'textarea', |
||||
|
ellipsis: true, |
||||
|
copyable: true, |
||||
|
hideInSearch: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '用户', |
||||
|
dataIndex: 'user', |
||||
|
hideInSearch: true, |
||||
|
width: 150, |
||||
|
renderText: (_, record) => { |
||||
|
if (!record.user) { |
||||
|
return; |
||||
|
} |
||||
|
return <UserInfo data={record.user} />; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '平台', |
||||
|
dataIndex: 'platform', |
||||
|
valueEnum: { |
||||
|
1: { |
||||
|
text: '穿山甲', |
||||
|
}, |
||||
|
2: { |
||||
|
text: '腾讯', |
||||
|
}, |
||||
|
3: { |
||||
|
text: '百度联盟', |
||||
|
}, |
||||
|
4: { |
||||
|
text: 'Mintegral', |
||||
|
}, |
||||
|
5: { |
||||
|
text: '快手', |
||||
|
}, |
||||
|
6: { |
||||
|
text: '游可赢', |
||||
|
}, |
||||
|
7: { |
||||
|
text: 'Sigmob', |
||||
|
}, |
||||
|
8: { |
||||
|
text: 'Admob', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ecpm(元)', |
||||
|
dataIndex: 'ecpm', |
||||
|
hideInSearch: true, |
||||
|
renderText: (x) => { |
||||
|
return x / 100; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ecpm-代理归属(元)', |
||||
|
dataIndex: 'ecpmAdmin', |
||||
|
hideInSearch: true, |
||||
|
renderText: (x) => { |
||||
|
return x / 100; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '设备', |
||||
|
dataIndex: 'device', |
||||
|
hideInSearch: true, |
||||
|
renderText: (_, record) => { |
||||
|
return ( |
||||
|
<> |
||||
|
<p>{record.deviceBrand}</p> |
||||
|
<p>{record.deviceName}</p> |
||||
|
</> |
||||
|
); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ip', |
||||
|
dataIndex: 'ip', |
||||
|
hideInSearch: true, |
||||
|
valueType: 'textarea', |
||||
|
}, |
||||
|
{ |
||||
|
title: '时间', |
||||
|
hideInSearch: true, |
||||
|
dataIndex: 'createdAt', |
||||
|
valueType: 'dateTime', |
||||
|
}, |
||||
|
{ |
||||
|
title: '时间', |
||||
|
hideInTable: true, |
||||
|
dataIndex: 'createdAt', |
||||
|
valueType: 'dateRange', |
||||
|
}, |
||||
|
// {
|
||||
|
// title: "应用名称",
|
||||
|
// hideInTable: true,
|
||||
|
// dataIndex: 'appId',
|
||||
|
// valueType: "select",
|
||||
|
// request: appNameMap
|
||||
|
// }
|
||||
|
]; |
||||
|
|
||||
|
const fetchData = async (params: any) => { |
||||
|
const res = await advList({ ...params, code: code }); |
||||
|
return { |
||||
|
data: res.data?.data, |
||||
|
total: res.data?.total, |
||||
|
success: true, |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
const fetchOverview = async () => { |
||||
|
const res = await incomeOverview1({ appCode: code }); |
||||
|
if (res.data) { |
||||
|
setOverview(res.data); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const fetchDaily = async (params: API.IncomeQuery | undefined) => { |
||||
|
const res = await incomeDaily1({ ...params, code: code }); |
||||
|
if (res.data) { |
||||
|
setDaily(res.data); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
actionRef.current?.reload(); |
||||
|
deviceRef.current?.reload(); |
||||
|
fetchOverview(); |
||||
|
fetchDaily(undefined); |
||||
|
}, [code]); |
||||
|
|
||||
|
const formatIncome = (v: number | undefined) => { |
||||
|
if (!v) { |
||||
|
return 0; |
||||
|
} |
||||
|
return parseFloat((v / 1000_00).toFixed(2)); |
||||
|
}; |
||||
|
|
||||
|
const processedChartData: { date: string | number; income: number }[] = daily.map((item) => ({ |
||||
|
date: (() => { |
||||
|
const inputDateStr = item.date + ''; |
||||
|
const year: string = inputDateStr.slice(0, 4); |
||||
|
const month: string = inputDateStr.slice(4, 6); |
||||
|
const day: string = inputDateStr.slice(6, 8); |
||||
|
|
||||
|
return `${year}-${month}-${day}`; |
||||
|
})(), |
||||
|
income: formatIncome(item.income), |
||||
|
})); |
||||
|
|
||||
|
const config = { |
||||
|
data: processedChartData, |
||||
|
xField: 'date', |
||||
|
yField: 'income', |
||||
|
tooltip: { |
||||
|
name: '收入', |
||||
|
field: 'income', |
||||
|
}, |
||||
|
axis: { |
||||
|
date: { |
||||
|
title: '日期', |
||||
|
}, |
||||
|
}, |
||||
|
title: |
||||
|
'累计' + |
||||
|
formatIncome(daily.reduce((acc, data) => acc + (data.income ? data.income : 0), 0)) + |
||||
|
'元', |
||||
|
height: 400, |
||||
|
label: { |
||||
|
text: (d: any) => (d.income > 0 ? d.income : ''), |
||||
|
textBaseline: 'bottom', |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
return ( |
||||
|
<PageContainer> |
||||
|
<Tabs defaultActiveKey="2" centered style={{ backgroundColor: 'white', padding: '20px' }}> |
||||
|
<TabPane tab="广告详情" key="2"> |
||||
|
<ProTable<API.MatrixAdvRecordBo, API.AdvRecordQuery> |
||||
|
headerTitle={intl.formatMessage({ |
||||
|
id: 'pages.searchTable.title', |
||||
|
defaultMessage: 'Enquiry form', |
||||
|
})} |
||||
|
actionRef={actionRef} |
||||
|
rowKey="id" |
||||
|
search={{ |
||||
|
labelWidth: 120, |
||||
|
}} |
||||
|
request={fetchData} |
||||
|
columns={columns} |
||||
|
columnsState={{ |
||||
|
value: columnsState, |
||||
|
onChange: (newState) => { |
||||
|
setColumnsState(newState); |
||||
|
}, |
||||
|
}} |
||||
|
/> |
||||
|
</TabPane> |
||||
|
<TabPane tab="数据总览" key="3"> |
||||
|
<RcResizeObserver |
||||
|
key="resize-observer" |
||||
|
onResize={(offset) => { |
||||
|
setResponsive(offset.width < 596); |
||||
|
}} |
||||
|
> |
||||
|
<StatisticCard> |
||||
|
<StatisticCard.Group direction={responsive ? 'column' : 'row'}> |
||||
|
<StatisticCard |
||||
|
statistic={{ |
||||
|
title: '上月收入(元)', |
||||
|
value: formatIncome(overview?.lastMonthIncome), |
||||
|
}} |
||||
|
/> |
||||
|
<Divider type={responsive ? 'horizontal' : 'vertical'} /> |
||||
|
<StatisticCard |
||||
|
statistic={{ |
||||
|
title: '本月收入(元)', |
||||
|
value: formatIncome(overview?.thisMonthIncome), |
||||
|
}} |
||||
|
/> |
||||
|
<Divider type={responsive ? 'horizontal' : 'vertical'} /> |
||||
|
<StatisticCard |
||||
|
statistic={{ |
||||
|
title: '今日收入(元)', |
||||
|
value: formatIncome(overview?.todayIncome), |
||||
|
}} |
||||
|
/> |
||||
|
<Divider type={responsive ? 'horizontal' : 'vertical'} /> |
||||
|
<StatisticCard |
||||
|
statistic={{ |
||||
|
title: '昨日收入(元)', |
||||
|
value: formatIncome(overview?.yesterdayIncome), |
||||
|
}} |
||||
|
/> |
||||
|
</StatisticCard.Group> |
||||
|
</StatisticCard> |
||||
|
</RcResizeObserver> |
||||
|
|
||||
|
<QueryFilter defaultCollapsed split onFinish={fetchDaily}> |
||||
|
<ProFormSelect |
||||
|
label="平台" |
||||
|
name="platform" |
||||
|
valueEnum={{ |
||||
|
1: '穿山甲', |
||||
|
2: '腾讯', |
||||
|
3: '百度联盟', |
||||
|
4: 'Mintegral', |
||||
|
5: '快手', |
||||
|
6: '游可赢', |
||||
|
7: 'Sigmob', |
||||
|
8: 'Admob', |
||||
|
}} |
||||
|
/> |
||||
|
<ProFormDateRangePicker |
||||
|
fieldProps={{ |
||||
|
disabledDate: (current: any) => current && current >= moment().startOf('day'), |
||||
|
}} |
||||
|
name="date" |
||||
|
label="时间" |
||||
|
/> |
||||
|
</QueryFilter> |
||||
|
{/* <Line {...config} /> */} |
||||
|
<Column {...config} /> |
||||
|
</TabPane> |
||||
|
</Tabs> |
||||
|
</PageContainer> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default ProxyAdvRecordListV2; |
@ -0,0 +1,112 @@ |
|||||
|
import { list } from '@/services/matrix/matrixUserController'; |
||||
|
import { cent2Yuan, formatIncome } from '@/utils/numberUtils'; |
||||
|
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; |
||||
|
import { useParams } from '@umijs/max'; |
||||
|
import { Tag } from 'antd'; |
||||
|
import { useEffect, useRef } from 'react'; |
||||
|
|
||||
|
import UserInfo from '../User/UserInfo'; |
||||
|
|
||||
|
const ProxyUserManagement: React.FC = () => { |
||||
|
const { code } = useParams(); |
||||
|
const actionRef = useRef<ActionType>(); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
actionRef.current?.reload(); |
||||
|
}, [code]); |
||||
|
|
||||
|
const columns: ProColumns<API.UserBo>[] = [ |
||||
|
{ |
||||
|
title: '用户id', |
||||
|
dataIndex: 'userId', |
||||
|
valueType: 'textarea', |
||||
|
hideInTable: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'id', |
||||
|
dataIndex: 'id', |
||||
|
valueType: 'textarea', |
||||
|
ellipsis: true, |
||||
|
copyable: true, |
||||
|
hideInSearch: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '用户', |
||||
|
hideInSearch: true, |
||||
|
dataIndex: 'nickname', |
||||
|
valueType: 'textarea', |
||||
|
renderText: (nickname: string, r: API.UserBo) => { |
||||
|
return <UserInfo data={r} />; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '支付宝名称', |
||||
|
dataIndex: 'name', |
||||
|
hideInSearch: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '支付宝账号', |
||||
|
dataIndex: 'aliPayAccount', |
||||
|
hideInSearch: true, |
||||
|
}, |
||||
|
{ |
||||
|
title: '微信', |
||||
|
dataIndex: 'wxOpenId', |
||||
|
hideInSearch: true, |
||||
|
renderText: (s: string | undefined) => { |
||||
|
if (s) { |
||||
|
return <Tag color="green">已绑定</Tag>; |
||||
|
} |
||||
|
return <Tag color="red">未绑定</Tag>; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '总收益(元)', |
||||
|
hideInSearch: true, |
||||
|
dataIndex: 'income', |
||||
|
renderText: (r: number) => { |
||||
|
return formatIncome(r); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '已提现(元)', |
||||
|
hideInSearch: true, |
||||
|
dataIndex: 'realMoney', |
||||
|
renderText: (r: number) => { |
||||
|
return cent2Yuan(r); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '注册时间', |
||||
|
hideInSearch: true, |
||||
|
dataIndex: 'createdAt', |
||||
|
valueType: 'dateTime', |
||||
|
}, |
||||
|
{ |
||||
|
title: '时间', |
||||
|
hideInTable: true, |
||||
|
dataIndex: 'createdAt', |
||||
|
valueType: 'dateRange', |
||||
|
hideInSearch: true, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
return ( |
||||
|
<PageContainer> |
||||
|
<ProTable<API.UserBo, API.UserQuery> |
||||
|
actionRef={actionRef} |
||||
|
request={async (params: API.UserQuery) => { |
||||
|
const res = await list({ ...params, appCode: code }); |
||||
|
return { |
||||
|
data: res.data?.data, |
||||
|
total: res.data?.total, |
||||
|
success: true, |
||||
|
}; |
||||
|
}} |
||||
|
columns={columns} |
||||
|
/> |
||||
|
</PageContainer> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default ProxyUserManagement; |
Loading…
Reference in new issue