Commit d34f48c4 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫
parents 8245682b 35bccae9
......@@ -24,6 +24,7 @@ import balancedRoute from './balancedRoute'; // 平台结算管理
import capitalAccount from './capitalAccountRoute'; // 会员资金账户
import messageRoute from './messgeRoute'; // 消息管理
import systemManageRoute from './systemManageRoute'; // 系统管理
import orderSystemRoutes from './orderSystemRoutes'; // 订单管理
const routeList = [
pageCustomized,
calssPropertyRoute,
......@@ -43,6 +44,7 @@ const routeList = [
capitalAccount,
messageRoute,
systemManageRoute,
orderSystemRoutes
]
const router = [
......
......@@ -50,7 +50,7 @@ export interface ShopInfo {
type: number;
environment: number;
logoUrl: string;
describe: string;
describe?: any;
state: number;
url: string;
}
......
import React from 'react'
import React, { useState, useEffect, useRef, useCallback, useLayoutEffect } from 'react'
import { Link, history } from 'umi'
import { Menu, Dropdown, List, Typography, Badge, Button, Avatar } from 'antd'
import { Menu, Dropdown, List, Avatar, Skeleton} from 'antd'
import { BellOutlined, CaretDownOutlined } from '@ant-design/icons'
import styles from './index.less'
import { removeAuth, getAuth } from '@/utils/auth'
import messageIcon1 from '@/asserts/home-icon-1.png'
import { PublicApi } from '@/services/api';
import moment from 'moment';
import msg_system from '@/asserts/msg_system.png'
import msg_platform from '@/asserts/msg_platform.png'
const RightContent: React.FC<{}> = (props) => {
const [visible, setVisible] = useState(false);
const [messageData, setMessageData] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const ws = useRef<WebSocket | null>(null);
const toLogin = () => {
removeAuth()
......@@ -24,40 +32,70 @@ const RightContent: React.FC<{}> = (props) => {
);
const userInfo = getAuth()
useEffect(() => {
if(visible) {
setLoading(true)
PublicApi.getReportMessagePlatformPage({current: '1', pageSize: '4'})
.then((data) => {
if(data.code === 1000) {
setLoading(false)
setMessageData(data.data.data);
}
})
}
}, [visible])
const webSocketInit = useCallback(() => {
console.log(ws.current)
if (!ws.current || ws.current.readyState === 3) {
ws.current = new WebSocket(`ws://10.0.0.25:8100/report/websocket?memberId=${userInfo.memberId}&roleId=${userInfo.memberRoleId}`);
ws.current.onopen = (e) => {
console.log(e)
}
ws.current.onmessage = (e) => {
console.log(e)
};
ws.current.onclose = (e) => {
console.log("关闭连接")
}
ws.current.onerror = (e) => {
console.log("socket 出错")
}
}
}, [ws]);
const data = [
'Racing car sprays burning fuel into crowd.',
'Japanese princess to wed commoner.',
'Australian walks 100km afterrafter outback crash.',
'Man charged over missing wedding girl.',
'Los Angeles battles huge wildfires.',
];
useLayoutEffect(() => {
// webSocketInit();
return () => {
ws.current?.close();
};
}, [ws, webSocketInit]);
const menuMessage = (
<div className={styles.noticeBox}>
<div className={styles.header}>消息列表</div>
<List
itemLayout="horizontal"
dataSource={data}
dataSource={messageData}
footer={
<a className={styles.messageFooter}>
<a className={styles.messageFooter} href="/message/messageList">
{"查看更多 ->"}
</a>
}
renderItem={item => {
console.log(item);
renderItem={(item:any) => {
return (
<List.Item>
<div className={styles.msgContainer}>
<div className={styles.msgItemIcon}>
<Avatar src={messageIcon1} />
</div>
<div>
<div className={styles.msgTitle}>订单支付</div>
<div className={styles.msgTime}>2020-08-25 12:58</div>
<Skeleton paragraph={{ rows: 1 }} loading={loading} active avatar>
<div className={styles.msgContainer}>
<div className={styles.msgItemIcon}>
<Avatar src={item.type == 1 ? msg_system : msg_platform} />
</div>
<div>
<div className={styles.msgTitle}>{item.title}</div>
<div className={styles.msgTime}>{moment(item.sendTime).format('YYYY-MM-DD HH:mm:ss')}</div>
</div>
</div>
</div>
</Skeleton>
</List.Item>
)
}}
......@@ -67,13 +105,13 @@ const RightContent: React.FC<{}> = (props) => {
return <div className={styles.lxLayoutRight}>
<Link to="/home" className={styles.lxLink}>返回首页</Link>
<Dropdown overlay={menuMessage} trigger={['click']}>
<Dropdown overlay={menuMessage} trigger={['click']} visible={visible}>
<a
href=""
rel="noopener noreferrer"
className={styles.topMessage}
>
<BellOutlined />
<BellOutlined onClick={() => setVisible(!visible)}/>
<span className="pulse"></span>
</a>
</Dropdown>
......
......@@ -90,18 +90,20 @@
border-radius: 4px;
box-shadow: 0 6px 16px -8px rgba(0,0,0,.08), 0 9px 28px 0 rgba(0,0,0,.05), 0 12px 48px 16px rgba(0,0,0,.03);
:global{
.ant-list {
width: 320px;
}
.ant-list-footer{
padding: 0;
}
.ant-list-item{
padding: 0;
}
.ant-skeleton {
width: 320px;
padding: 12px 18px;
}
}
h4{
padding-left: 24px;
border-bottom: 1px solid #f0f0f0;
}
.header {
padding: 17px 24px;
font-size: 14px;
......
......@@ -20,6 +20,14 @@ interface CssExports {
'lxLink': string;
'avatar': string;
'avatarWrap': string;
'topMessage': string,
'noticeBox': string,
'header': string,
'messageFooter': string,
'msgContainer': string,
'msgItemIcon': string,
'msgTitle': string,
'msgTime': string
}
export const cssExports: CssExports;
export default cssExports;
......@@ -52,12 +52,12 @@ const AccountLists: React.FC<{}> = () => {
dataIndex: 'memberRoleName',
key: 'memberRoleName',
},
{
title: '会员等级',
dataIndex: 'memberLevel',
key: 'memberLevel',
render: (t, r) => <LevelBrand level={r.level} />
},
// {
// title: '会员等级',
// dataIndex: 'memberLevel',
// key: 'memberLevel',
// render: (t, r) => <LevelBrand level={r.level} />
// },
{
title: '账户余额',
dataIndex: 'accountBalance',
......
......@@ -58,16 +58,16 @@ export const searchSchema: ISchema = {
}
}
},
memberLevel: {
type: 'string',
enum: [],
"x-component-props": {
placeholder: '请选择会员等级',
style: {
width: 174
}
}
},
// memberLevel: {
// type: 'string',
// enum: [],
// "x-component-props": {
// placeholder: '请选择会员等级',
// style: {
// width: 174
// }
// }
// },
memberStatus: {
type: 'string',
'x-component-props': {
......
export interface Ilist {
dateTime: any,
roleName: string,
count: number
}
export enum TimeEnum {
WEEK = 1,
MONTH = 2,
YEAR = 3
}
export interface ImemberData {
/**
* 今日注册数
*/
todayCount: number,
/**
* 七日注册数
*/
weekCount: number,
/**
* 三十日注册数
*/
monthCount: number,
/**
* 三十日注册数
*/
totalCount: number,
/**
* 周统计数据
*/
weekList: Ilist[],
/**
* 月统计数据
*/
monthList: Ilist[],
/**
* 年统计数据
*/
yearList: Ilist[]
}
export interface IorderData {
/**
* 今日订单数
*/
todayCount: number,
/**
* 今日营业额
*/
todayAmount: number,
/**
* 七日订单数
*/
weekCount: number,
/**
* 七日营业额
*/
weekAmount: number,
/**
* 三十日订单数
*/
monthCount: number,
/**
* 三十日营业额
*/
monthAmount: number
,
/**
* 累鸡订单数
*/
totalCount: number,
/**
* 累计营业额
*/
totalAmount: number,
/**
* 周统计数据
*/
weekList: Ilist[],
/**
* 月统计数
*/
monthList: Ilist[],
/**
* 年统计数
*/
yearList: Ilist[]
}
export interface ItodayAdd {
orderAmount: string,
orderGrowthRate: number,
memberCount: string,
memberGrowthRate: number,
commodityCount: number,
commodityGrowthRate: number,
shopCount: number,
shopGrowthRate: number
}
\ No newline at end of file
import React from 'react';
import {
Chart,
Geom,
Axis,
Tooltip,
Legend,
Annotation,
Guide
} from 'bizcharts';
const { Line } = Guide;
interface IProps {
currentIndex: number,
}
const LineChart: React.FC<IProps> = (props) => {
const { currentIndex } = props
const data1 = [
{
"month": "2020-07-13",
"city": "供应链",
"revenue": 1
},
{
"month": "2020-07-13",
"city": "采购商",
"revenue": 1.56
},
{
"month": "2020-07-13",
"city": "加工企业",
"revenue": 1.66
},
{
"month": "2020-07-14",
"city": "供应链",
"revenue": 0.35
},
{
"month": "2020-07-14",
"city": "采购商",
"revenue": 0.89
},
{
"month": "2020-07-14",
"city": "加工企业",
"revenue": 0.89
},
{
"month": "2020-07-15",
"city": "供应链",
"revenue": 0.19
},
{
"month": "2020-07-15",
"city": "采购商",
"revenue": 0.18
},
{
"month": "2020-07-15",
"city": "加工企业",
"revenue": 0.28
},
{
"month": "2020-07-16",
"city": "供应链",
"revenue": 1.2
},
{
"month": "2020-07-16",
"city": "采购商",
"revenue": 0.59
},
{
"month": "2020-07-16",
"city": "加工企业",
"revenue": 0.28
},
{
"month": "2020-07-17",
"city": "供应链",
"revenue": 1.52
},
{
"month": "2020-07-17",
"city": "采购商",
"revenue": 0.3583
},
{
"month": "2020-07-17",
"city": "加工企业",
"revenue": 0.35
},
{
"month": "2020-07-18",
"city": "供应链",
"revenue": 1.15
},
{
"month": "2020-07-18",
"city": "采购商",
"revenue": 1.025
},
{
"month": "2020-07-18",
"city": "加工企业",
"revenue": 1.28
},
{
"month": "2020-07-19",
"city": "供应链",
"revenue": 1.132
},
{
"month": "2020-07-19",
"city": "采购商",
"revenue": 1.15
},
{
"month": "2020-07-19",
"city": "加工企业",
"revenue": 0.26
},
];
const data2 = [
{
"month": "2020-07-13",
"city": "供应链",
"revenue": 1
},
{
"month": "2020-07-13",
"city": "采购商",
"revenue": 1.56
},
{
"month": "2020-07-13",
"city": "加工企业",
"revenue": 1.66
},
{
"month": "2020-07-14",
"city": "供应链",
"revenue": 0.35
},
{
"month": "2020-07-14",
"city": "采购商",
"revenue": 0.89
},
{
"month": "2020-07-14",
"city": "加工企业",
"revenue": 0.89
},
{
"month": "2020-07-15",
"city": "供应链",
"revenue": 0.19
},
{
"month": "2020-07-15",
"city": "采购商",
"revenue": 0.18
},
{
"month": "2020-07-15",
"city": "加工企业",
"revenue": 0.28
},
{
"month": "2020-07-16",
"city": "供应链",
"revenue": 1.2
},
{
"month": "2020-07-16",
"city": "采购商",
"revenue": 0.59
},
{
"month": "2020-07-16",
"city": "加工企业",
"revenue": 0.28
},
{
"month": "2020-07-17",
"city": "供应链",
"revenue": 1.52
},
{
"month": "2020-07-17",
"city": "采购商",
"revenue": 0.3583
},
{
"month": "2020-07-17",
"city": "加工企业",
"revenue": 0.35
},
{
"month": "2020-07-18",
"city": "供应链",
"revenue": 1.15
},
{
"month": "2020-07-18",
"city": "采购商",
"revenue": 1.025
},
{
"month": "2020-07-18",
"city": "加工企业",
"revenue": 1.28
},
{
"month": "2020-07-19",
"city": "供应链",
"revenue": 1.132
},
{
"month": "2020-07-19",
"city": "采购商",
"revenue": 1.15
},
{
"month": "2020-07-19",
"city": "加工企业",
"revenue": 0.26
},
];
const scale = {
"revenue": {
"range": [
0,
1
],
"ticks": [
0,
1,
2,
3,
4
]
},
"month": {
"range":[0.05, 0.95]
}
};
return (
<Chart height={360} data={currentIndex === 2 ? data2 : data1} scale={scale} forceFit>
<Legend position="top-left" />
<Axis name="month" />
<Axis
name="revenue"
label={{
formatter: val => `${val}%`,
}}
/>
<Tooltip
showCrosshairs
shared
/>
<Geom type="line" tooltip={['revenue*city', (value, name) => {
return {
value: `${value.toFixed(3)} %`,
name
}
}]} position="month*revenue" size={2} color={'city'} />
<Geom
type="point"
tooltip={false}
position="month*revenue"
size={4}
shape={'circle'}
color={'city'}
style={{
stroke: '#fff',
lineWidth: 1,
}}
/>
<Annotation.Text
position={['50%', '50%']}
alignX="middle"
alignY="middle"
html={`<div style="color:#8c8c8c;font-size:1.16em;text-align: center;width: 10em;">项目总数<br><span style="color:red;font-size:2.5em;">${200}</span></div>`}
/>
</Chart>
);
}
export default LineChart;
\ No newline at end of file
import React from 'react';
import { Chart, Interval } from 'bizcharts';
interface IProps {
currentIndex: number,
}
const ColumnChart: React.FC<IProps> = (props) => {
const { currentIndex } = props
const data1 = [
{ day: '08-01', sales: 38 },
{ day: '08-02', sales: 52 },
{ day: '08-03', sales: 61 },
{ day: '08-04', sales: 45 },
{ day: '08-05', sales: 48 },
{ day: '08-06', sales: 38 },
{ day: '08-07', sales: 38 },
];
const data2 = [
{ day: '08-01', sales: 38 },
{ day: '08-02', sales: 52 },
{ day: '08-03', sales: 61 },
{ day: '08-04', sales: 45 },
{ day: '08-05', sales: 48 },
{ day: '08-06', sales: 38 },
{ day: '08-07', sales: 38 },
{ day: '08-08', sales: 38 },
{ day: '08-09', sales: 48 },
{ day: '08-10', sales: 23 },
{ day: '08-11', sales: 35 },
{ day: '08-12', sales: 54 },
{ day: '08-13', sales: 32 },
{ day: '08-14', sales: 45 },
{ day: '08-15', sales: 32 },
];
return (
<Chart height={302} autoFit data={currentIndex === 2 ? data2 : data1} >
<Interval position="day*sales" />
</Chart>
)
}
export default ColumnChart;
\ No newline at end of file
.dataRiskTip{
font-size: 12px;
font-weight: 400;
color: #909399;
}
.dataRiskAction{
display: flex;
> div{
width: 240px;
height: 48px;
background: #FAFBFC;
line-height: 48px;
margin-right: 24px;
> img{
margin: 8px 16px;
}
}
}
\ No newline at end of file
import React from 'react';
import styles from './index.less';
import { Row, Col, Card } from 'antd';
// 数据风控图标
import dataRiskIcon3 from '@/asserts/home-icon-3.png'
import dataRiskIcon4 from '@/asserts/home-icon-4.png'
import dataRiskIcon5 from '@/asserts/home-icon-5.png'
import dataRiskIcon6 from '@/asserts/home-icon-6.png'
import dataRiskIcon7 from '@/asserts/home-icon-7.png'
import dataRiskIcon8 from '@/asserts/home-icon-8.png'
const DataCenter: React.FC = () => {
return (
<Row gutter={[24, 12]}>
<Col span={24}>
<Card
headStyle={{borderBottom:'none'}}
title={
<>
<p>数据中心</p>
<p className={styles.dataRiskTip}>实时展示会员数据、交易数据等综合指标的动态趋势,满足数据化运营的需要</p>
</>
}
bordered={false}
extra={<a href="#">进入数据中心</a>}
>
<div className={styles.dataRiskAction}>
<div>
<img src={dataRiskIcon3} alt=""/>
<span>网站运营数据</span>
</div>
<div>
<img src={dataRiskIcon4} alt=""/>
<span>APP运营数据</span>
</div>
<div>
<img src={dataRiskIcon5} alt=""/>
<span>用户分析</span>
</div>
<div>
<img src={dataRiskIcon6} alt=""/>
<span>商品分析</span>
</div>
<div>
<img src={dataRiskIcon7} alt=""/>
<span>交易分析</span>
</div>
<div>
<img src={dataRiskIcon8} alt=""/>
<span>售后分析</span>
</div>
</div>
</Card>
</Col>
</Row>
)
}
export default DataCenter
\ No newline at end of file
......@@ -7,7 +7,7 @@ import todayIcon from '@/asserts/home-icon-24.png'
import weekIcon from '@/asserts/home-icon-25.png'
import monthIcon from '@/asserts/home-icon-26.png'
import totalIcon from '@/asserts/home-icon-27.png'
import { ImemberData, Ilist } from '../../common/interface';
export enum TimeEnum {
WEEK = 1,
......@@ -15,30 +15,49 @@ export enum TimeEnum {
YEAR = 3
}
const MemberStatistics: React.FC = () => {
const [timeRadio, setTimeRadio] = useState<TimeEnum>(TimeEnum.WEEK)
interface Iprops {
memberData: ImemberData
}
const MemberStatistics: React.FC<Iprops> = (props) => {
const { memberData } = props;
const [timeRadio, setTimeRadio] = useState<TimeEnum>(TimeEnum.WEEK);
// 设置折线图的data
const [currentLineChartData, setCurrentLineChartData] = useState<Ilist[]>([]);
const handleChangeTime = (e) => {
setTimeRadio(e.target.value)
const dataMap = {
[TimeEnum.WEEK]: props.memberData.weekList,
[TimeEnum.MONTH]: props.memberData.monthList,
[TimeEnum.YEAR]: props.memberData.yearList
}
setCurrentLineChartData(dataMap[e.target.value]);
}
useEffect(() => {
setCurrentLineChartData(props.memberData.weekList);
}, [props.memberData])
const data = [
{
icon: todayIcon,
value: 86,
value: memberData.todayCount,
tips: '今日注册'
},
{
icon: weekIcon,
value: 867,
value: memberData.weekCount,
tips: '最近7日注册'
},
{
icon: monthIcon,
value: 1280,
value: memberData.monthCount,
tips: '最近30日注册'
},
{
icon: totalIcon,
value: 5686,
value: memberData.totalCount,
tips: '累计注册'
}
]
......@@ -51,21 +70,21 @@ const MemberStatistics: React.FC = () => {
<Radio.Group value={timeRadio} buttonStyle="solid" size="small" onChange={handleChangeTime}>
<Radio.Button value={TimeEnum.WEEK}></Radio.Button>
<Radio.Button value={TimeEnum.MONTH}></Radio.Button>
<Radio.Button value={TimeEnum.YEAR}></Radio.Button>
<Radio.Button value={TimeEnum.YEAR}></Radio.Button>
</Radio.Group>
}
>
<Row>
<Col span={24}>
{/* 折线图 */}
<LineChart currentIndex={1} />
<LineChart data={currentLineChartData} />
</Col>
<Col span={24}>
<Row>
{
data.map((item) => {
return (
<Col span={6} key={item.value}>
<Col span={6} key={item.tips}>
<div className={styles.lineDesc}>
<img src={item.icon} className={styles.icon} alt=""/>
<div className={styles.lineDescText}>
......
import React from 'react';
import { Chart, Legend, LineAdvance} from 'bizcharts';
import { Ilist } from '../../common/interface';
interface IProps {
data: Ilist[]
}
const LineChart: React.FC<IProps> = (props) => {
return (
<Chart height={360} data={props.data} forceFit>
<Legend position="top-left" />
{/* <Axis name="dateTime" />
<Axis name="count"/> */}
<LineAdvance
position="dateTime*count"
color={'roleName'}
point
area
shape="smooth"
></LineAdvance>
</Chart>
);
}
export default LineChart;
\ No newline at end of file
import React from 'react';
// import { Chart, Interval } from 'bizcharts';
import { Chart, Tooltip, Point, Line, Interval } from "bizcharts";
interface IProps {
currentIndex: number,
}
const ColumnChart: React.FC<IProps> = (props) => {
const colors = ["#6394f9", "#62daaa"];
return (
<Chart height={302} autoFit data={props.data} >
<Tooltip shared />
<Interval
tooltip={['dateTime*count', (text, num) => {
return {
name: '订单数',
value: num
};
}]}
position="dateTime*count"
color={colors[0]}
/>
<Line
tooltip={['dateTime*amount', (text, num) => {
return {
name: '营业额',
value: num
};
}]}
position="dateTime*amount"
color={colors[1]}
size={3}
shape="smooth"
/>
<Point
position="dateTime*amount"
tooltip={['dateTime*amount', (text, num) => {
return {
name: '营业额',
value: num
};
}]}
color={colors[1]}
size={3}
shape="circle"
/>
</Chart>
)
}
export default ColumnChart;
\ No newline at end of file
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { Card, Radio, Row, Col } from 'antd';
import styles from './index.less'
import ColumnChart from './columnChart';
......@@ -8,38 +8,49 @@ import todayIcon from '@/asserts/home-icon-24.png'
import weekIcon from '@/asserts/home-icon-25.png'
import monthIcon from '@/asserts/home-icon-26.png'
import totalIcon from '@/asserts/home-icon-27.png'
import { TimeEnum, IorderData, Ilist } from '../../common/interface'
export enum TimeEnum {
WEEK = 1,
MONTH = 2,
YEAR = 3
interface Iprops {
orderData: IorderData
}
const OrderStatistics = () => {
const OrderStatistics: React.FC<Iprops> = (props) => {
const { orderData } = props
const [timeRadio, setTimeRadio] = useState<TimeEnum>(TimeEnum.WEEK)
const [currentChartData, setCurrentChartData] = useState<Ilist[]>([]);
const handleChangeTime = (e) => {
setTimeRadio(e.target.value)
const dataMap = {
[TimeEnum.WEEK]: orderData.weekList,
[TimeEnum.MONTH]: orderData.monthList,
[TimeEnum.YEAR]: orderData.yearList
}
setCurrentChartData(dataMap[e.target.value]);
}
useEffect(() => {
setCurrentChartData(props.orderData.weekList);
}, [props.orderData])
const data = [
{
icon: todayIcon,
value: 86,
tips: '今日注册'
value: orderData.todayCount,
tips: `今日营业额(${orderData.todayCount}单)`
},
{
icon: weekIcon,
value: 867,
tips: '最近7日注册'
value: orderData.weekCount,
tips: `最近7日营业额(${orderData.weekAmount}单)`
},
{
icon: monthIcon,
value: 1280,
tips: '最近30日注册'
value: orderData.monthCount,
tips: `最近30日营业额(${orderData.monthAmount}单)`
},
{
icon: totalIcon,
value: 5686,
tips: '累计注册'
value: orderData.totalCount,
tips: `累计营业额(${orderData.totalCount}单)`
}
]
return (
......@@ -52,21 +63,21 @@ const OrderStatistics = () => {
<Radio.Group value={timeRadio} buttonStyle="solid" size="small" onChange={handleChangeTime}>
<Radio.Button value={TimeEnum.WEEK}></Radio.Button>
<Radio.Button value={TimeEnum.MONTH}></Radio.Button>
<Radio.Button value={TimeEnum.YEAR}></Radio.Button>
<Radio.Button value={TimeEnum.YEAR}></Radio.Button>
</Radio.Group>
}
>
<Row style={{margin: '36px 0 0 0'}}>
<Col span={24}>
{/* 折线图 */}
<ColumnChart currentIndex={1} />
<ColumnChart data={currentChartData} />
</Col>
<Col span={24}>
<Row>
{
data.map((item) => {
data.map((item,key) => {
return (
<Col span={6} key={item.value}>
<Col span={6} key={key}>
<div className={styles.lineDesc}>
<img src={item.icon} className={styles.icon} alt=""/>
<div className={styles.lineDescText}>
......
.dataRiskTip{
font-size: 12px;
font-weight: 400;
color: #909399;
}
.dataRiskAction{
display: flex;
> div{
width: 240px;
height: 48px;
background: #FAFBFC;
line-height: 48px;
margin-right: 24px;
> img{
margin: 8px 16px;
}
}
}
\ No newline at end of file
import React from 'react';
import { Row, Col, Card, Badge } from 'antd';
import styles from './index.less'
// 数据风控图标
import dataRiskIcon1 from '@/asserts/home-icon-1.png'
import dataRiskIcon2 from '@/asserts/home-icon-2.png'
interface Iprops {}
const RiskCenter: React.FC<Iprops> = () => {
return (
<Row gutter={[24, 12]}>
<Col span={24}>
<Card
headStyle={{borderBottom:'none'}}
title={<><p>风控中心</p><p className={styles.dataRiskTip}>全面的风控体系,监控交易异常、资金异常、行为异常,并实时预警</p></>}
bordered={false}
extra={<a href="#">进入风控中心</a>}
>
<div className={styles.dataRiskAction}>
<div>
<img src={dataRiskIcon1} alt=""/>
<span>预警规则</span>
</div>
<div>
<img src={dataRiskIcon2} alt=""/>
<span>预警控制台<Badge count={4} size="small" /></span>
</div>
<div>
<img src={dataRiskIcon1} alt=""/>
<span>预警处理</span>
</div>
</div>
</Card>
</Col>
</Row>
)
}
export default RiskCenter
\ No newline at end of file
// 便签样式
.notePaperBox{
width: 100%;
height: 248px;
background: #6C9CEB;
border-radius: 3px;
.notePaperContainer{
width: calc(100% - 2px);
height: 50%;
border-top: 0;
.noteHeader {
padding: 21px 16px;
display: flex;
align-items: center;
color: #fff;
.text {
margin-left: 16px;
font-size: 14px;
}
}
.noteGap{
width: 96%;
height: calc(30% - 1px);
text-align: center;
border-top: 1px dashed #c5c5c5;
margin: 0 auto;
position: relative;
&::before{
content: '';
width: 10px;
height: 10px;
position: absolute;
border-radius: 50%;
border-left: 1px solid #F4F5F7;
background-color: #F4F5F7;
position:absolute;
left: -11px;
top: -5px;
}
&::after{
content: '';
width: 10px;
height: 10px;
position: absolute;
border-radius: 50%;
border-left: 1px solid #F4F5F7;
background-color: #F4F5F7;
position:absolute;
right: -11px;
top: -5px;
}
}
.noteBody{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
.value {
font-size: 24px;
margin-bottom: 24px;
}
a {
color: #fff;
}
}
}
}
.notePaperBoxGreen{
background-color: #41CC9E;
}
.feeCustomCard{
background-color: #fff;
border-radius: 3px;
padding: 32px 24px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.info {
display: flex;
flex-direction: row;
align-items: center;
img {
width: 48px;
height: 48px;
margin-right: 16px;
}
.lineDescTitle {
font-size: 24px;
font-weight: 500;
color: #303133;
margin-bottom: 0;
}
.lineDescTip {
font-size: 12px;
color: #909399;
margin-bottom: 0;
}
}
}
\ No newline at end of file
import React from 'react';
import { Row, Col } from 'antd';
import styles from './index.less';
import cx from 'classnames';
import { RightOutlined } from '@ant-design/icons';
// 收付款图标
import feeIcon1 from '@/asserts/home-icon-15.png'
import feeIcon2 from '@/asserts/home-icon-16.png'
import feeIcon3 from '@/asserts/home-icon-17.png'
import feeIcon4 from '@/asserts/home-icon-18.png'
import feeIcon5 from '@/asserts/home-icon-19.png'
import feeIcon6 from '@/asserts/home-icon-20.png'
const Settlement: React.FC = () => {
return (
<Row gutter={[24, 12]} style={{marginTop: 9, marginBottom: 0}}>
<Col span={5} style={{paddingBottom:0}}>
<div className={styles.notePaperBox}>
<div className={styles.notePaperContainer}>
<div className={styles.noteHeader}>
<img src={feeIcon1} alt=""/>
<span className={styles.text}>待付款代收账款结算</span>
</div>
<div className={styles.noteGap}></div>
<div className={styles.noteBody}>
<span className={styles.value}>15</span>
<a>查看 <RightOutlined /></a>
</div>
</div>
</div>
</Col>
<Col span={5} style={{paddingBottom:0}}>
<div className={cx(styles.notePaperBox, styles.notePaperBoxGreen)}>
<div className={styles.notePaperContainer}>
<div className={styles.noteHeader}>
<img src={feeIcon2} alt=""/>
<span className={styles.text}>已完成代收账款结算</span>
</div>
<div className={styles.noteGap}></div>
<div className={styles.noteBody}>
<span className={styles.value}>15</span>
<a>查看 <RightOutlined /></a>
</div>
</div>
</div>
</Col>
<Col span={7} style={{paddingBottom:0}}>
<Row gutter={[0, 24]}>
<Col span={24} style={{padding:0}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon3} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTip}>待提现申请</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</Col>
<Col span={24} style={{paddingBottom:0}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon4} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTip}>待支付提现申请</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</Col>
</Row>
</Col>
<Col span={7} style={{paddingBottom:0}}>
<Row gutter={[0, 24]}>
<Col span={24} style={{padding:0}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon5} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTip}>待付款积分结算</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</Col>
<Col span={24} style={{paddingBottom:0}}>
<div className={cx(styles.lineDesc, styles.feeCustomCard)}>
<div className={styles.info}>
<img src={feeIcon6} alt=""/>
<div className={styles.lineDescText}>
<p className={styles.lineDescTitle}>86</p>
<p className={styles.lineDescTip}>已完成积分结算</p>
</div>
</div>
<a key="list-loadmore-more">查看&nbsp;<RightOutlined /></a>
</div>
</Col>
</Row>
</Col>
</Row>
)
}
export default Settlement
\ No newline at end of file
......@@ -24,14 +24,14 @@
flex: 1;
&:first-child {
margin-right: 15px;
margin-right: 50px;
}
.left {
display: flex;
flex-direction: row;
align-items: center;
.lineDescText {
margin-left: 15px;
margin-left: 24px;
.lineDescTitle {
font-size: 24px;
......
import React from 'react';
import { Row, Col, Card } from 'antd';
import { CaretUpOutlined } from '@ant-design/icons';
import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons';
import StatusTag from '@/components/StatusTag'
import styles from './index.less';
// 图标图片集
......@@ -8,38 +8,44 @@ import orderIcon from '@/asserts/home-icon-23.png'
import memberIcon from '@/asserts/home-icon-12.png'
import productIcon from '@/asserts/home-icon-10.png'
import brandIcon from '@/asserts/home-icon-11.png'
import { ItodayAdd } from '../../common/interface'
const TodayAdd: React.FC = () => {
const data = [
interface Iprops {
data: ItodayAdd
}
const TodayAdd: React.FC<Iprops> = (props) => {
const { data } = props;
const list = [
{
title: '今日新增订单(元)',
number: '102,086.00',
number: data.orderAmount,
icon: orderIcon,
percent: '3.4%'
percent: data.orderGrowthRate
},
{
title: '今日新增会员',
number: '45.00',
number: data.memberCount,
icon: memberIcon,
percent: '3.4%'
percent: data.memberGrowthRate
},
{
title: '今日新增商品',
number: '88.00',
number: data.commodityCount,
icon: productIcon,
percent: '3.4%'
percent: data.commodityGrowthRate
},
{
title: '今日新增品牌',
number: '20',
number: data.shopCount,
icon: brandIcon,
percent: '3.4%'
percent: data.shopGrowthRate
}
]
return (
<Row gutter={[24, 12]}>
{
data.map((item, key) => {
list.map((item, key) => {
return (
<Col span={6} key={key}>
<div className={styles.homeCard}>
......@@ -53,7 +59,20 @@ const TodayAdd: React.FC = () => {
</div>
</div>
<div className={styles.footer}>
<StatusTag title={<><CaretUpOutlined />{item.percent}</>} type="success" />
<StatusTag
title={
<>
{
item.percent >= 0
? <CaretUpOutlined />
: <CaretDownOutlined />
}
{item.percent} %
</>
}
type={item.percent >= 0 ? "success" : "danger"}
/>
<span>&nbsp;&nbsp;相比昨日</span>
</div>
</div>
......
// home页面样式
.homeCard{
border-radius: 3px;
position: relative;
:global {
.ant-card-head-title{
font-size: 12px;
color: #909399;
}
}
.numberDesc{
font-size: 32px;
font-weight: 500;
color: #303133;
}
.numberIcon{
text-align: right;
position: absolute;
top: -10px;
right: 0px;
}
}
.lineDesc{
display: flex;
align-items: center;
margin-top: 14px;
position: relative;
img{
display: block;
width: 48px;
height: 48px;
margin: 24px 16px 24px 24px;
}
.lineDescText{
p{
margin-bottom: 8px;
line-height: 1;
}
.lineDescTitle{
font-size: 24px;
font-weight: 500;
color: #303133;
}
.lineDescTip{
font-size: 12px;
font-weight: 400;
color: #909399;
}
}
a{
position: absolute;
right: 30px;
}
}
.chartBox{
margin-top: 24px;
......@@ -89,131 +33,6 @@
}
}
// .commodityTotalTitle{
// text-align: center;
// span{
// font-size: 12px;
// font-weight: 400;
// color: #909399;
// }
// p{
// height: 72px;
// font-size: 24px;
// font-weight: 500;
// color: #303133;
// line-height: 72px;
// }
// }
// .commodityTotalDesc{
// display: flex;
// flex: 1;
// .aHalfOfWidth {
// width: 50%;
// }
// }
// 便签样式
.notePaperBox{
width: 100%;
height: 248px;
background: #6C9CEB;
border-radius: 3px;
.notePaperContainer{
width: calc(100% - 2px);
height: 50%;
border-top: 0;
.noteGap{
width: 96%;
height: calc(30% - 1px);
text-align: center;
border-top: 1px dashed #c5c5c5;
margin: 0 auto;
position: relative;
&::before{
content: '';
width: 10px;
height: 10px;
position: absolute;
border-radius: 50%;
border-left: 1px solid #F4F5F7;
background-color: #F4F5F7;
position:absolute;
left: -11px;
top: -5px;
}
&::after{
content: '';
width: 10px;
height: 10px;
position: absolute;
border-radius: 50%;
border-left: 1px solid #F4F5F7;
background-color: #F4F5F7;
position:absolute;
right: -11px;
top: -5px;
}
}
.noteHeader{
p{
display: flex;
align-items: center;
padding: 20px 0 8px;
color: #FFFFFF;
font-size: 14px;
font-weight: 500;
img{
padding: 0 16px 0 20px;
}
}
}
.noteBody{
width: 100%;
height: 70%;
text-align: center;
p{
color: #fff;
font-size: 24px;
font-weight: 500;
a{
color: #fff;
font-size: 14px;
font-weight: 400;
}
}
}
}
}
.notePaperBoxGreen{
background-color: #41CC9E;
}
.feeCustomCard{
background-color: #fff;
border-radius: 3px;
height: 110px;
}
.dataRiskTip{
font-size: 12px;
font-weight: 400;
color: #909399;
}
.dataRiskAction{
display: flex;
> p{
width: 240px;
height: 48px;
background: #FAFBFC;
line-height: 48px;
margin-right: 24px;
> img{
margin: 8px 16px;
}
}
}
// 适配
@media screen and (max-width: 1441px) {
......
This diff is collapsed.
import React, { useState, useEffect } from 'react'
import React, { useState } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Button, Card, Space, Radio, Row, Col, Table, Tabs, Tag, Avatar, Image, List, Badge } from 'antd'
import cx from 'classnames'
import { Button, Card } from 'antd'
import {history} from 'umi'
import NiceForm from '@/components/NiceForm'
import { createFormActions, FormButtonGroup, Reset, Submit } from '@formily/antd'
import styles from './index.less'
import { createFormActions, FormButtonGroup, Reset, Submit, FormEffectHooks } from '@formily/antd'
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus'
import ReutrnEle from '@/components/ReturnEle'
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect'
import { PublicApi } from '@/services/api'
const addSchemaAction = createFormActions()
const AddMessage: React.FC<{}> = () => {
interface Irole {
label: string,
value: number
}
const {
pageStatus,
id
} = usePageStatus()
const AddMessage: React.FC<{}> = () => {
const [roles, setRoles] = useState<Irole[]>([])
const { pageStatus } = usePageStatus()
const handleSubmit = (val) => {
console.log(val, 'vvv')
const data = {
...val,
roleIds: val.roleIds === 0 ? roles.map((item) => item.value) : [val.roleIds],
}
PublicApi.postReportMessagePlatformSend(data)
.then((data) => {
if(data.code === 1000) {
history.push('/message/messageList');
}
})
}
const getSendTargets = async () => {
const res = await PublicApi.getMemberManageRoleAll();
if(res.code === 1000) {
return [{label: '所有', value: 0}].concat(
res.data.map((item) => ({label: item.roleName, value: item.roleId}))
);
}
return []
}
const creatEffect = () => ($) => {
useAsyncSelect('roleIds', getSendTargets);
$('requestAsyncSelect', 'roleIds').subscribe((state) => {
setRoles(state.payload);
})
}
return (
......@@ -38,7 +64,7 @@ const AddMessage: React.FC<{}> = () => {
schema={{
type: 'object',
properties: {
roleName: {
roleIds: {
type: 'string',
title: '发送对象',
required: true,
......@@ -49,7 +75,7 @@ const AddMessage: React.FC<{}> = () => {
{ label: 'Four', value: '4' }
],
},
remark: {
title: {
type: 'textarea',
title: '发送标题',
"x-rules": [
......@@ -65,11 +91,11 @@ const AddMessage: React.FC<{}> = () => {
rows: 4
}
},
role123: {
url: {
type: 'string',
title: '消息跳转链接',
},
remark123: {
content: {
type: 'textarea',
title: '消息内容',
required: true,
......@@ -89,6 +115,8 @@ const AddMessage: React.FC<{}> = () => {
}
}}
onSubmit={handleSubmit}
effects={creatEffect()}
>
<FormButtonGroup offset={4}>
<Submit>发送</Submit>
......
import React, { useState, useEffect } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Button, Card, Space, Radio, Row, Col, Table, Tabs, Tag, Avatar, Image, List, Badge } from 'antd'
import cx from 'classnames'
import { Button, Card, Avatar, List } from 'antd'
import {history} from 'umi'
import styles from './index.less'
import StatusTag from '@/components/StatusTag'
import { PlusOutlined } from '@ant-design/icons'
//图标
import messageIcon1 from '../../asserts/home-icon-1.png'
import messageIcon2 from '../../asserts/home-icon-2.png'
import messageIcon3 from '../../asserts/home-icon-8.png'
import msg_system from '@/asserts/msg_system.png'
import msg_platform from '@/asserts/msg_platform.png'
import moment from 'moment';
import { PublicApi } from '@/services/api'
const Message: React.FC<{}> = () => {
const [dataSource, setDataSource] = useState<any>()
const [dataSource, setDataSource] = useState<any>([])
const [pagation, setPagation] = useState({
current: 1,
pageSize: 10,
})
const data = [
{
id: 1,
icon: messageIcon1,
status: 'success',
type: '系统消息',
title: '订单发货',
message: '订单发货,请注意查收,清单发货,请注意查收!',
time: '2015-15-05',
},
{
id: 2,
icon: messageIcon2,
status: 'success',
type: '系统消息',
title: '订单收货',
message: '订单发货,请注意查收,清单发货,请注意查收!',
time: '2015-15-05',
},
{
id: 3,
icon: messageIcon1,
status: 'primary',
type: '系统消息',
title: '系统消息',
message: '账户异常,请注意账户资金安全!',
time: '2015-15-05',
},
{
id: 4,
icon: messageIcon3,
status: 'primary',
type: '系统消息',
title: '系统消息',
message: '账户支出300元,请注意账户资金安全!',
time: '2015-15-05',
},
];
useEffect(() => {
// @ts-ignore
PublicApi.getManageMessagePlatformPage(pagation).then(res => {
console.log(res)
if(res.code===1000){
setDataSource(res.data)
}
})
async function init() {
const data = await getList(pagation);
setDataSource(data);
}
init()
}, [])
const renderMessage = (data) => {
const getList = async (params) => {
const res = await PublicApi.getReportMessagePlatformPage(params);
if(res.code === 1000) {
return res.data
}
return {
totalCount: 0,
data: []
}
}
const handlePaginationChange = (page, pageSize) => {
getList({page, pageSize})
.then((data) => {
setDataSource(data);
})
}
const renderMessage = (data) => {
return (
<>
<StatusTag type={data.status} title={data.type} />
<span className={styles.messageTitle}>{data.title}</span>
<span className={styles.messageText}>{data.message}</span>
<StatusTag type={data.type == 1 ? 'primary' : 'success'} title={data.type === 1 ? '系统消息' : '平台消息'} />
<span className={styles.messageTitle}>{data.title || ''}</span>
<span className={styles.messageText}>{data.content || ''}</span>
</>
)
}
......@@ -84,7 +57,6 @@ const Message: React.FC<{}> = () => {
const showTotal = (total) => {
return `共 ${total} 条`;
}
return (
<PageHeaderWrapper>
<Card>
......@@ -93,12 +65,10 @@ const Message: React.FC<{}> = () => {
</p>
<List
itemLayout="horizontal"
dataSource={data}
dataSource={dataSource.data}
className={styles.customList}
pagination={{
onChange: page => {
console.log(page);
},
onChange: handlePaginationChange,
current: pagation.current,
pageSize: pagation.pageSize,
size: "small",
......@@ -106,13 +76,13 @@ const Message: React.FC<{}> = () => {
total: dataSource?.totalCount || 0,
showTotal: showTotal
}}
renderItem={item => (
renderItem={(item: any) => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src={item.icon} />}
avatar={<Avatar src={item.type == 1 ? msg_system : msg_platform} />}
title={renderMessage(item)}
/>
<div>{item.time}</div>
<div>{moment(item.sendTime).format('YYYY-MM-DD HH:mm:ss')}</div>
</List.Item>
)}
/>
......
......@@ -8,6 +8,7 @@ import * as PayApi from './PayApi'
import * as SearchApi from './SearchApi'
import * as OrderApi from './OrderApi';
import * as SettleApi from './SettleApi';
import * as ReportApi from './reportApi';
/**
* 可在这里写入自定义的接口
......@@ -27,5 +28,6 @@ export const PublicApi = {
...PayApi,
...SearchApi,
...OrderApi,
...SettleApi
...SettleApi,
...ReportApi
}
......@@ -9,6 +9,7 @@ const tokenList = [
{ name: 'Search', token: 'ca19f532efba91f7773cbfbd526b798c6ac83df670071e97d72c50dca1d53a48' }, // 搜索服务
{ name: 'Order', token: '5de0aaeaac12c8d911d86dada6cd128993e34cd6e13135fa79246aa5979a2bcd' }, //订单服务,
{ name: 'Settle', token: 'fffbeeaaa198c285955997c606bc279fc6950fea118580c786f2c73eecccaa6a' }, //结算服务
{ name: 'report', token: 'e709e5bd31eb2b84de468944b153a62a05afcc13f0ea880be7333b928c7c0620'}, //报表服务
]
const getConfigMap = (tokens) => tokens.map(v => ({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment