Commit 58fbf765 authored by XieZhiXiong's avatar XieZhiXiong

chore: 删除无用文件

parent e056b620
......@@ -13,7 +13,7 @@ import {
MEMBER_INNER_STATUS_BADGE_COLOR,
MEMBER_OUTER_STATUS_TYPE,
} from '../../constant';
import StatusTag from '../../components/StatusTag';
import StatusTag from '@/components/StatusTag';
/**
*
......
......@@ -13,7 +13,7 @@ import {
MEMBER_INNER_STATUS_BADGE_COLOR,
MEMBER_OUTER_STATUS_TYPE,
} from '../../constant';
import StatusTag from '../../components/StatusTag';
import StatusTag from '@/components/StatusTag';
import styles from '../styles.less';
/**
......
import React from 'react';
import {
Steps,
Tabs,
} from 'antd';
import MellowCard from '@/components/MellowCard';
import styles from './index.less';
interface AuditProcessProp {
outerVerifyCurrent?: number;
innerVerifyCurrent?: number;
outerVerifySteps?: { step: number, stepName: string, roleName: string }[];
innerVerifySteps?: { step: number, stepName: string, roleName: string }[];
};
const AuditProcess: React.FC<AuditProcessProp> = ({
outerVerifyCurrent = 0,
innerVerifyCurrent = 0,
outerVerifySteps = [],
innerVerifySteps = [],
}) => (
<MellowCard>
<Tabs onChange={() => {}}>
<Tabs.TabPane tab="外部审核流程" key="1">
<Steps style={{ marginTop: 30 }} progressDot current={outerVerifyCurrent}>
{outerVerifySteps.map(item => (
<Steps.Step
key={item.step}
title={item.stepName}
description={item.roleName}
/>
))}
</Steps>
</Tabs.TabPane>
<Tabs.TabPane tab="内部审核流程" key="2">
<Steps style={{ marginTop: 30 }} progressDot current={innerVerifyCurrent}>
{innerVerifySteps.map(item => (
<Steps.Step
key={item.step}
title={item.roleName}
description={item.stepName}
/>
))}
</Steps>
</Tabs.TabPane>
</Tabs>
</MellowCard>
);
export default AuditProcess;
\ No newline at end of file
.basicInfo {
.descriptions {
:global {
.ant-descriptions-item-label {
flex: 0 0 128px;
color: rgba(107, 119, 140, 1);
}
}
}
}
\ No newline at end of file
import React, { useState } from 'react';
import {
Row,
Col,
Descriptions,
} from 'antd';
import MellowCard from '@/components/MellowCard';
import {
MEMBER_TYPE_CHANNEL_CORPORATE,
MEMBER_TYPE_CHANNEL_INDIVIDUAL,
} from '@/constants/member';
import PicWrap from '../PicWrap';
import FlowRecords, { InnerHistoryItem, OuterHistoryItem } from '../FlowRecords';
import styles from './index.less';
interface BasicInfoProps {
basic?: {
account?: string,
phone?: string,
email?: string,
created?: string,
};
channel?: {
memberType?: number,
level?: string,
type?: string,
areas?: string[],
desc?: string,
};
extra?: {
groupName: string,
elements: {
fieldCNName?: string,
fieldType?: string,
fieldValue?: any,
}[],
}[];
outerHistory?: OuterHistoryItem[];
innerHistory?: InnerHistoryItem[];
channelRender?: React.ReactNode; // 自定义渲染渠道信息
}
const BasicInfo: React.FC<BasicInfoProps> = ({
basic = {},
channel = {},
extra = [],
outerHistory = [],
innerHistory,
channelRender,
}) => {
return (
<div className={styles.basicInfo}>
<Row gutter={[0, 24]}>
<Col span={24}>
<MellowCard
title="基本信息"
>
<Descriptions column={2} className={styles.descriptions}>
<Descriptions.Item label="登录账户">{basic.account}</Descriptions.Item>
<Descriptions.Item label="注册手机号">{basic.phone}</Descriptions.Item>
<Descriptions.Item label="注册邮箱">{basic.email}</Descriptions.Item>
<Descriptions.Item label="申请时间">{basic.created}</Descriptions.Item>
</Descriptions>
</MellowCard>
</Col>
{
(
channel.memberType === MEMBER_TYPE_CHANNEL_CORPORATE ||
channel.memberType === MEMBER_TYPE_CHANNEL_INDIVIDUAL
) && (
<Col span={24}>
<MellowCard
title="渠道信息"
>
{!channelRender ? (
<Descriptions column={2} className={styles.descriptions}>
<Descriptions.Item label="渠道级别">{channel.level}</Descriptions.Item>
<Descriptions.Item label="渠道类型">{channel.type}</Descriptions.Item>
<Descriptions.Item label="代理地市">
<Row gutter={[16, 16]}>
{
channel.areas ?
channel.areas.map(item => (
<Col key={item} span={12}>{item}</Col>
)) :
null
}
</Row>
</Descriptions.Item>
<Descriptions.Item label="渠道描述">{channel.desc}</Descriptions.Item>
</Descriptions>
) : channelRender}
</MellowCard>
</Col>
)
}
{extra.map((item, index) => (
<Col key={index} span={24}>
<MellowCard
title={item.groupName}
>
<Row gutter={20}>
<Col span={12}>
<Descriptions column={1} className={styles.descriptions}>
{item.elements.map((ele, index) => (index + 1) % 2 !== 0 ? (
<Descriptions.Item key={index} label={ele.fieldCNName}>
{
ele.fieldType !== 'upload' ?
ele.fieldValue :
(
<PicWrap
pics={[ele.fieldValue]}
/>
)
}
</Descriptions.Item>
) : null)}
</Descriptions>
</Col>
<Col span={12}>
<Descriptions column={1} className={styles.descriptions}>
{item.elements.map((ele, index) => (index + 1) % 2 === 0 ? (
<Descriptions.Item key={index} label={ele.fieldCNName}>
{
ele.fieldType !== 'upload' ?
ele.fieldValue :
(
<PicWrap
pics={[ele.fieldValue]}
/>
)
}
</Descriptions.Item>
) : null)}
</Descriptions>
</Col>
</Row>
</MellowCard>
</Col>
))}
<Col span={24}>
<FlowRecords
outerHistory={outerHistory}
innerHistory={innerHistory}
/>
</Col>
</Row>
</div>
);
};
export default BasicInfo;
@import '../../../../global/styles/utils.less';
.equityInfo {
.container {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 24px;
height: 192px;
background: #ffffff;
border-radius: 8px;
&-title {
margin-bottom: 20px;
line-height: 24px;
font-size: 14px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
}
&-content {
}
}
.tofo {
display: flex;
padding: 0 0 4px;
margin: 0;
min-height: 101px;
overflow-x: auto;
.silkyScrollbar();
&-item {
flex: 0 0 33.333%;
list-style: none;
&-logo {
width: 40px;
height: 40px;
margin: 0 auto 4px;
text-align: center;
> img {
width: 100%;
height: 100%;
}
}
&-title {
margin-bottom: 9px;
line-height: 22px;
font-size: 12px;
font-weight: 400;
color: rgba(23, 43, 77, 1);
text-align: center;
:global {
.anticon {
margin-left: 4px;
}
}
}
&-extra {
text-align: center;
}
&-tag {
line-height: 22px;
padding: 0 6px;
font-size: 12px;
font-weight: 400;
text-align: center;
border-radius: 4px;
&-price {
color: rgba(101, 84, 192, 1);
background: rgba(234, 230, 255, 1);
}
&-recurrence {
color: rgba(230, 63, 59, 1);
background: rgba(255, 235, 230, 1);
}
&-integral {
color: rgba(255, 153, 31, 1);
background: rgba(255, 250, 230, 1);
}
}
}
}
.exhibition {
display: flex;
align-items: center;
&-left {
flex: 1;
}
&-right {
flex-shrink: 0;
}
&-title {
line-height: 20px;
margin-bottom: 24px;
font-size: 12px;
font-weight: 400;
color: rgba(107, 119, 140, 1);
}
&-amount {
font-size: 24px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
line-height: 24px;
> span {
margin-left: 8px;
line-height: 12px;
font-size: 12px;
font-weight: 400;
color: rgba(107, 119, 140, 1);
}
}
&-logo {
width: 72px;
height: 72px;
> img {
width: 100%;
height: 100%;
}
}
}
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import {
Row,
Col,
Tabs,
Tooltip,
} from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import MellowCard from '@/components/MellowCard';
import equity1 from '@/assets/imgs/equity-1.png';
import equity2 from '@/assets/imgs/equity-2.png';
import equity3 from '@/assets/imgs/equity-3.png';
import equity4 from '@/assets/imgs/equity-4.png';
import equity5 from '@/assets/imgs/equity-5.png';
import styles from './index.less';
const { TabPane } = Tabs;
const PAGE_SIZE = 8;
export interface ReceivedData {
id?: number;
createTime?: string;
ruleName?: string;
score?: number;
remark?: string;
};
export interface UsageData {
id?: number;
createTime?: string;
rightTypeName?: string;
spendTypeName?: string;
point?: number;
remark?: string;
};
export interface FetchParams {
current: number;
pageSize: number;
};
export interface EquityInfoProps {
equityInfo?: {
sumReturnMoney?: number, // 累计返现金额
sumUsedPoint?: number, // 已用积分
sumPoint?: number, // 累计积分
rights?: {
acquireWay: string,
id: number,
name: string,
paramWay: string,
parameter: string,
remark: string,
rightTypeEnum: number,
status: number,
}[];
};
fetchReceivedList?: (params: FetchParams) => Promise<{ data: ReceivedData[] , totalCount: number }>;
fetchUsageList?: (params: FetchParams) => Promise<{ data: UsageData[] , totalCount: number }>;
}
const equityTxtMap = {
1: '折扣',
2: '返现',
3: '积分',
};
const clsMap = {
1: 'tofo-item-tag-price',
2: 'tofo-item-tag-recurrence',
3: 'tofo-item-tag-integral',
};
const EquityInfo: React.FC<EquityInfoProps> = ({
equityInfo = {},
fetchReceivedList,
fetchUsageList,
}) => {
const [receivedPage, setReceivedPage] = useState(1);
const [receivedSize, setReceivedSize] = useState(PAGE_SIZE);
const [receivedTotal, setReceivedTotal] = useState(0);
const [receivedList, setReceivedList] = useState<ReceivedData[]>([]);
const [receivedListLoading, setReceivedListLoading] = useState(false);
const [usagePage, setUsagePage] = useState(1);
const [usageSize, setUsageSize] = useState(PAGE_SIZE);
const [usageTotal, setUsageTotal] = useState(0);
const [usageList, setUsageList] = useState<UsageData[]>([]);
const [usageListLoading, setUsageListLoading] = useState(false);
const receivedColumns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'rightTypeName',
align: 'center',
},
{
title: '获取数量',
dataIndex: 'point',
align: 'center',
},
{
title: '获取时间',
dataIndex: 'createTime',
align: 'center',
},
{
title: '备注',
dataIndex: 'remark',
align: 'center',
ellipsis: true,
},
];
const usageColumns: EditableColumns[] = [
{
title: 'ID',
dataIndex: 'id',
align: 'center',
},
{
title: '会员权益名称',
dataIndex: 'rightTypeName',
align: 'center',
},
{
title: '会员权益使用名称',
dataIndex: 'spendTypeName',
align: 'center',
},
{
title: '使用数量',
dataIndex: 'point',
align: 'center',
},
{
title: '使用时间',
dataIndex: 'createTime',
align: 'center',
},
{
title: '备注',
dataIndex: 'remark',
align: 'center',
ellipsis: true,
},
];
const getReceivedList = (params?) => {
if (fetchReceivedList) {
setReceivedListLoading(true);
fetchReceivedList({
current: receivedPage,
pageSize: receivedSize,
...params,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setReceivedList(data);
setReceivedTotal(totalCount);
}).finally(() => {
setReceivedListLoading(false);
});
}
};
const getUsageList = (params?) => {
if (fetchUsageList) {
setUsageListLoading(true);
fetchUsageList({
current: usagePage,
pageSize: usageSize,
...params,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setUsageList(data);
setUsageTotal(totalCount);
}).finally(() => {
setUsageListLoading(false);
});
}
};
useEffect(() => {
getReceivedList();
}, []);
const handleTabChange = key => {
switch (key) {
case '1':
getReceivedList();
break;
case '2':
getUsageList();
break;
default:
break;
}
};
const handleReceivedPaginationChange = (page: number, size: number) => {
setReceivedPage(page);
setReceivedSize(size);
getReceivedList({
current: page,
pageSize: size,
});
};
const handleUsagePaginationChange = (page: number, size: number) => {
setUsagePage(page);
setUsageSize(size);
getUsageList({
current: page,
pageSize: size,
});
};
return (
<div className={styles.equityInfo}>
<Row gutter={[0, 24]}>
<Col span={24}>
<Row gutter={24}>
<Col span={8}>
<div className={styles.container}>
<div className={styles['container-title']}>
当前权益
</div>
<div className={styles['container-content']}>
<ul className={styles.tofo}>
{equityInfo.rights ? equityInfo.rights.map(item => (
<li key={item.id} className={styles['tofo-item']}>
<div className={styles['tofo-item-logo']}>
<img src={require(`@/assets/imgs/equity-${item.rightTypeEnum}.png`)} />
</div>
<div className={styles['tofo-item-title']}>
{item.name}
<Tooltip title={item.remark}>
<QuestionCircleOutlined />
</Tooltip>
</div>
<div className={styles['tofo-item-extra']}>
<span
className={classNames(styles['tofo-item-tag'], styles[clsMap[item.rightTypeEnum]])}
>
{item.parameter}% {equityTxtMap[item.rightTypeEnum] || ''}
</span>
</div>
</li>
)) : null}
</ul>
</div>
</div>
</Col>
<Col span={8}>
<div className={styles.container}>
<div className={styles['container-content']}>
<div className={styles.exhibition}>
<div className={styles['exhibition-left']}>
<div className={styles['exhibition-title']}>
累计返现金额
</div>
<div className={styles['exhibition-amount']}>
{equityInfo?.sumReturnMoney}
<span>CNY</span>
</div>
</div>
<div className={styles['exhibition-right']}>
<div className={styles['exhibition-logo']}>
<img src={equity4} />
</div>
</div>
</div>
</div>
</div>
</Col>
<Col span={8}>
<div className={styles.container}>
<div className={styles['container-content']}>
<div className={styles.exhibition}>
<div className={styles['exhibition-left']}>
<div className={styles['exhibition-title']}>
已用积分/总积分
</div>
<div className={styles['exhibition-amount']}>
{equityInfo?.sumUsedPoint}/{equityInfo?.sumPoint}
</div>
</div>
<div className={styles['exhibition-right']}>
<div className={styles['exhibition-logo']}>
<img src={equity5} />
</div>
</div>
</div>
</div>
</div>
</Col>
</Row>
</Col>
<Col span={24}>
<MellowCard
title="活跃分获取记录"
>
<Tabs onChange={handleTabChange}>
<TabPane tab="权益获取记录" key="1">
<PolymericTable
dataSource={receivedList}
columns={receivedColumns}
loading={receivedListLoading}
pagination={{
pageSize: receivedSize,
total: receivedTotal,
}}
onPaginationChange={handleReceivedPaginationChange}
/>
</TabPane>
<TabPane tab="权益使用记录" key="2">
<PolymericTable
dataSource={usageList}
columns={usageColumns}
loading={usageListLoading}
pagination={{
pageSize: usageSize,
total: usageTotal,
}}
onPaginationChange={handleUsagePaginationChange}
/>
</TabPane>
</Tabs>
</MellowCard>
</Col>
</Row>
</div>
);
};
export default EquityInfo;
import React from 'react';
import {
Tabs,
Badge,
} from 'antd';
import { STATUS_COLOR_MAP, STATUS_COLOR_TXT } from '../../constant';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import MellowCard from '@/components/MellowCard';
import {
MEMBER_STATUS_TAG_MAP,
MEMBER_INNER_STATUS_BADGE_COLOR,
MEMBER_OUTER_STATUS_BADGE_COLOR,
MEMBER_OUTER_STATUS_TYPE,
} from '../../constant';
import styles from './index.less';
export interface InnerHistoryItem {
createTime?: string,
id?: number;
operatorName?: string;
operatorOrgName?: string;
operatorJobTitle?: string;
operation?: string;
innerStatusName?: string;
remark?: string;
innerStatus?: number;
};
export interface OuterHistoryItem {
createTime?: string,
id?: number;
operation?: string;
operatorRoleName?: string;
remark?: string;
statusDescription?: string;
status?: number,
};
interface FlowRecordsProps {
outerHistory?: OuterHistoryItem[];
innerHistory?: InnerHistoryItem[];
};
const FlowRecords: React.FC<FlowRecordsProps> = ({ outerHistory = [], innerHistory }) => {
const outerColumns: EditableColumns[] = [
{
title: '序号',
dataIndex: 'index',
align: 'center',
render: (text, record, index) => index + 1,
},
{
title: '操作角色',
dataIndex: 'operatorRoleName',
align: 'center',
},
{
title: '状态',
dataIndex: 'statusDescription',
align: 'center',
render: (text, record) => (
<Badge color={MEMBER_OUTER_STATUS_BADGE_COLOR[record.status]} text={text} />
),
},
{
title: '操作',
dataIndex: 'operation',
align: 'center',
},
{
title: '操作时间',
dataIndex: 'createTime',
align: 'center',
ellipsis: true,
},
{
title: '审核意见',
dataIndex: 'remark',
align: 'center',
ellipsis: true,
},
];
const innerColumns: EditableColumns[] = [
{
title: '序号',
dataIndex: 'index',
align: 'center',
render: (text, record, index) => index + 1,
},
{
title: '操作人',
dataIndex: 'operatorName',
align: 'center',
},
{
title: '部门',
dataIndex: 'operatorOrgName',
align: 'center',
},
{
title: '职位',
dataIndex: 'operatorJobTitle',
align: 'center',
},
{
title: '状态',
dataIndex: 'innerStatusName',
align: 'center',
render: (text, record) => (
<Badge color={MEMBER_INNER_STATUS_BADGE_COLOR[record.innerStatus]} text={text} />
),
},
{
title: '操作',
dataIndex: 'operation',
align: 'center',
},
{
title: '操作时间',
dataIndex: 'createTime',
align: 'center',
ellipsis: true,
},
{
title: '审核意见',
dataIndex: 'remark',
align: 'center',
ellipsis: true,
},
];
return (
<MellowCard>
<Tabs onChange={() => {}}>
<Tabs.TabPane tab="流转记录" key="1">
<PolymericTable
dataSource={outerHistory}
columns={outerColumns}
loading={false}
pagination={null}
/>
</Tabs.TabPane>
{innerHistory && (
<Tabs.TabPane tab="内部单据流转记录" key="2">
<PolymericTable
dataSource={innerHistory}
columns={innerColumns}
loading={false}
pagination={null}
/>
</Tabs.TabPane>
)}
</Tabs>
</MellowCard>
);
};
export default FlowRecords;
\ No newline at end of file
......@@ -2,7 +2,7 @@
* @Author: XieZhiXiong
* @Date: 2021-05-20 17:40:29
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-05-20 18:00:40
* @LastEditTime: 2021-06-29 15:25:01
* @Description: 会员诚信信息统计信息
*/
import React, { HTMLAttributes } from 'react';
......
.sincerityInfo {
.tofo {
height: 100%;
:global {
.antd-card {
height: 100%;
}
}
&-item {
width: 50%;
padding: 55px 24px;
&-logo {
width: 72px;
height: 72px;
}
}
}
}
.contentBox {
position: relative;
padding-right: 72px;
background: #ffffff;
&-main {
}
&-extra {
position: absolute;
top: 0;
right: 0;
bottom: 0;
}
.title {
margin-bottom: 20px;
line-height: 20px;
font-size: 12px;
font-weight: 400;
color: rgba(107, 119, 140, 1);
:global {
.anticon {
margin-left: 6px;
}
}
}
.txt {
line-height: 32px;
font-size: 24px;
font-weight: 500;
color: rgba(23, 43, 77, 1);
}
}
.record {
&-tabs {
:global {
.ant-tabs-nav::before {
border-bottom: none;
}
}
}
&-btns {
margin-bottom: 16px;
}
&-row {
:global {
.ant-table-cell:first-child {
background-color: rgba(250, 251, 252, 1);
}
}
}
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import {
Row,
Col,
Tabs,
Card,
Tooltip,
Button,
Spin,
} from 'antd';
import {
QuestionCircleOutlined,
} from '@ant-design/icons';
import { isJSONStr } from '@/utils';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import { Pie } from '@/components/Charts';
import MellowCard from '@/components/MellowCard';
import Mood from '@/components/Mood';
import styles from './index.less';
import request from '@/utils/request';
const { TabPane } = Tabs;
interface ContentBoxProps {
title?: string;
desc?: string;
content?: React.ReactNode;
extra?: React.ReactNode;
};
const ContentBox: React.FC<ContentBoxProps> = ({
title = '我是标题',
content,
extra,
desc,
}) => (
<div className={styles.contentBox}>
<div className={styles['contentBox-main']}>
<div className={styles.title}>
{title}
<Tooltip title={desc}>
<QuestionCircleOutlined />
</Tooltip>
</div>
<div className={styles.txt}>
{content}
</div>
</div>
<div className={styles['contentBox-extra']}>
{extra}
</div>
</div>
);
const PAGE_SIZE = 5;
export interface BasicInfo {
pieData: {
x: string,
y: number,
}[],
items: {
id: number,
creditTypeName: string,
remark: string,
creditPoint: number,
currentPoint: number,
}[],
loading?: boolean,
};
export interface EstimateSumItems {
id?: number,
title?: JSX.Element,
star?: number,
last7days?: number,
last30days?: number,
last180days?: number,
before180days?: number,
sum?: number,
};
export interface EstimateSum {
dataSource: EstimateSumItems[],
loading?: boolean,
};
export interface ComplaintSum {
dataSource: EstimateSumItems,
loading?: boolean,
};
export interface FetchParams {
current: number;
pageSize: number;
};
export interface SalesProps {
id?: number;
createTime?: string;
star?: number;
comment?: string;
product?: string;
byMemberName?: string;
remark?: string;
};
export interface ComplaintProps {
id?: number;
createTime?: string;
content?: string;
reason?: string;
byMemberName?: string;
remark?: string;
};
interface SincerityInfoProps {
basicInfo?: BasicInfo;
salesEstimateSum?: EstimateSum;
/**
交易评论历史记录
*/
fetchSalesList?: (params: FetchParams) => Promise<{ data: SalesProps[] , totalCount: number }>;
afterEstimateSum?: EstimateSum;
/**
售后评论历史记录
*/
fetchAfterList?: (params: FetchParams) => Promise<{ data: SalesProps[] , totalCount: number }>;
complaintSum?: ComplaintSum;
/**
投诉历史记录
*/
fetchComplaintList?: (params: FetchParams) => Promise<{ data: ComplaintProps[] , totalCount: number }>;
};
const SincerityInfo: React.FC<SincerityInfoProps> = ({
basicInfo = {},
salesEstimateSum = {},
fetchSalesList,
afterEstimateSum = {},
fetchAfterList,
complaintSum = {},
fetchComplaintList,
}) => {
const creditData = basicInfo.pieData || [];
const integralItems = basicInfo.items || [];
const { dataSource: complaintSumData } = complaintSum;
const [salesEvaluate, setSalesEvaluate] = useState([]);
const [salesEvaluatePie, setSalesEvaluatePie] = useState([]);
const [afterEvaluate, setAfterEvaluate] = useState([]);
const [afterEvaluatePie, setAfterEvaluatePie] = useState([]);
const [salesTabKey, setSalesTabKey] = useState('evaluateSum');
const [afterTabKey, setAfterTabKey] = useState('evaluateSum');
const [salesPage, setSalesPage] = useState(1);
const [salesSize, setSalesSize] = useState(PAGE_SIZE);
const [salesTotal, setSalesTotal] = useState(0);
const [salesList, setSalesList] = useState([]);
const [salesListLoading, setSalesListLoading] = useState(false);
const [afterPage, setAfterPage] = useState(1);
const [afterSize, setAfterSize] = useState(PAGE_SIZE);
const [afterTotal, setAfterTotal] = useState(0);
const [afterList, setAfterList] = useState([]);
const [afterListLoading, setAfterListLoading] = useState(false);
const [complainPage, setComplainPage] = useState(1);
const [complainSize, setComplainSize] = useState(PAGE_SIZE);
const [complainTotal, setComplainTotal] = useState(0);
const [complainList, setComplainList] = useState([]);
const [complainListLoading, setComplainListLoading] = useState(false);
const exchangeMood = (star: number): React.ReactNode => {
let node = null;
switch (star) {
case 1:
case 2: {
node = (
<>
<Mood type="sad" />
<span>差评</span>
</>
);
break;
}
case 3: {
node = (
<>
<Mood type="notBad" />
<span>中评</span>
</>
);
break;
}
case 4:
case 5: {
node = (
<>
<Mood type="smile" />
<span>好评</span>
</>
);
break;
}
default:
break;
}
return node;
};
const recordColumns: EditableColumns[] = [
{
title: '投诉单号',
dataIndex: 'remark',
},
{
title: '摘要',
dataIndex: 'content',
ellipsis: true,
},
{
title: '投诉方',
dataIndex: 'byMemberName',
},
{
title: '投诉原因',
dataIndex: 'reason',
ellipsis: true,
},
{
title: '交易单据时间',
dataIndex: 'createTime',
align: 'center',
ellipsis: true,
},
];
const evaluateColumns: EditableColumns[] = [
{
title: ' ',
dataIndex: 'title',
align: 'center',
},
{
title: '最近7天',
dataIndex: 'last7days',
align: 'center',
},
{
title: '最近30天',
dataIndex: 'last30days',
align: 'center',
},
{
title: '最近180天',
dataIndex: 'last180days',
align: 'center',
},
{
title: '180天前',
dataIndex: 'before180days',
align: 'center',
},
];
const evaluateRecordColumns: EditableColumns[] = [
{
title: '评论',
dataIndex: 'star',
align: 'center',
render: (text) => exchangeMood(text),
},
{
title: '评价内容',
dataIndex: 'comment',
align: 'center',
ellipsis: true,
},
{
title: '交易商品',
dataIndex: 'product',
align: 'center',
ellipsis: true,
},
{
title: '评价方',
dataIndex: 'byMemberName',
align: 'center',
},
{
title: '交易时间',
dataIndex: 'createTime',
align: 'center',
},
{
title: '订单号',
dataIndex: 'orderNo',
align: 'center',
},
];
const summaryEvaluate = (items: EstimateSumItems[]): EstimateSumItems[] => {
// 顺序写死的 1:表示好评,2:表示中评,3:表示差评
// 根据 1、2星级为差评,3星级为中评,4、5星级为好评往里边塞数据
const source = items || [];
const ret = [
{
id: 1,
title: (<Mood type="smile" />),
},
{
id: 2,
title: (<Mood type="notBad" />),
},
{
id: 3,
title: (<Mood type="sad" />),
},
];
for (let i = 0; i < source.length; i++) {
const item = source[i];
const { star, ...rest } = item;
let target = null;
switch (item.star) {
case 1:
case 2: {
target = ret[2];
break;
}
case 3: {
target = ret[1];
break;
}
case 4:
case 5: {
target = ret[0];
break;
}
default:
break;
}
if (!target) {
continue;
}
// 大于 2 表示已经添加过一次数据,之后就累加上去,否则直接赋值
if (Object.keys(target).length <= 2) {
target = Object.assign(target, rest);
} else {
for (const key in target) {
if (!Object.prototype.hasOwnProperty.call(target, key)) {
continue;
}
// 排除 id、title 固定的 key
if (key !== 'id' && key !== 'title') {
target[key] += item[key];
}
}
}
}
return ret;
};
// 取得评价统计 Pie 饼图数据
const getSummaryEvaluatePie = (data: EstimateSumItems[]) => {
const source = data || [];
const count = source.reduce((pre, now) => now.sum + pre, 0);
const good = source[0] && source[0].sum ? source[0].sum : 0;
const notBad = source[1] && source[1].sum ? source[1].sum : 0;
const bad = source[2] && source[2].sum ? source[2].sum : 0;
const ret = [
{
x: `好评 ${count > 0 ? (good / count * 100).toFixed(2) : '0'}%`,
y: good,
},
{
x: `中评 ${count > 0 ? (notBad / count * 100).toFixed(2) : 0}%`,
y: notBad,
},
{
x: `差评 ${count > 0 ? (bad / count * 100).toFixed(2) : 0}%`,
y: bad,
},
];
return ret;
};
// 获取交易评价记录列表
const getSalesRecordList = (extraParams: {[key: string]: any} = {}) => {
if (fetchSalesList) {
setSalesListLoading(true);
fetchSalesList({
current: salesPage,
pageSize: salesSize,
...extraParams,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setSalesList(data);
setSalesTotal(totalCount);
}).finally(() => {
setSalesListLoading(false);
});
}
};
// 获取售后评价记录列表
const getAfterRecordList = (extraParams: {[key: string]: any} = {}) => {
if (fetchAfterList) {
setAfterListLoading(true);
fetchAfterList({
current: afterPage,
pageSize: afterSize,
...extraParams,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setAfterList(data);
setAfterTotal(totalCount);
}).finally(() => {
setAfterListLoading(false);
});
}
};
// 获取投诉评价记录列表
const getComplaintList = () => {
if (fetchComplaintList) {
setComplainListLoading(true);
fetchComplaintList({
current: complainPage,
pageSize: complainSize,
}).then(res => {
const { data = [], totalCount = 0 } = (res || {});
setComplainList(data);
setComplainTotal(totalCount);
}).finally(() => {
setComplainListLoading(false);
});
}
};
useEffect(() => {
getComplaintList();
}, []);
// 监听交易评价数据改变,组合所需数据
useEffect(() => {
const evaluate = summaryEvaluate(salesEstimateSum.dataSource);
const evaluatePie = getSummaryEvaluatePie(evaluate);
setSalesEvaluate(evaluate);
setSalesEvaluatePie(evaluatePie);
}, [salesEstimateSum.dataSource]);
// 监听售后评价数据改变,组合所需数据
useEffect(() => {
const evaluate = summaryEvaluate(afterEstimateSum.dataSource);
const evaluatePie = getSummaryEvaluatePie(evaluate);
setAfterEvaluate(evaluate);
setAfterEvaluatePie(evaluatePie);
}, [afterEstimateSum.dataSource]);
const handleSalesTabChange = key => {
if (key === 'evaluateRecord') {
getSalesRecordList();
}
setSalesTabKey(key);
};
const handleAfterTabChange = key => {
if (key === 'evaluateRecord') {
getAfterRecordList();
}
setAfterTabKey(key);
};
const handleSalesPaginationChange = (page: number, size: number) => {
setSalesPage(page);
setSalesSize(size);
getSalesRecordList();
};
const handleAfterPaginationChange = (page: number, size: number) => {
setAfterPage(page);
setAfterSize(size);
getAfterRecordList();
};
const handleComplainPaginationChange = (page: number, size: number) => {
setComplainPage(page);
setComplainSize(size);
getComplaintList();
};
const handleSalesRadioChange = value => {
setSalesPage(1);
getSalesRecordList({
starLevel: value,
});
};
const handleAfterRadioChange = value => {
setAfterPage(1);
getAfterRecordList({
starLevel: value,
});
};
return (
<div className={styles.sincerityInfo}>
<Row gutter={[0, 24]}>
<Col span={24}>
<Spin spinning={Boolean(basicInfo.loading)}>
<Row gutter={24}>
<Col flex="386px">
<MellowCard
title="信用积分"
fullHeight
>
<Pie
hasLegend
subTitle="信用积分"
total={() => creditData.reduce((pre, now) => now.y + pre, 0)}
data={creditData}
height={178}
colors={['#6C9CEB', '#8777D9', '#FFC400', '#41CC9E']}
/>
</MellowCard>
</Col>
{basicInfo.loading === false && (
<Col flex="1">
<div className={styles.tofo}>
<MellowCard fullHeight>
{integralItems.map((item, index) => (
<Card.Grid key={item.id} className={styles['tofo-item']}>
<ContentBox
title={item.creditTypeName}
desc={`${item.remark}(${item.creditPoint})`}
content={item.currentPoint}
extra={
<img
className={styles['tofo-item-logo']}
src={require(`@/assets/imgs/integral-${index + 1}.png`)}
/>
}
/>
</Card.Grid>
))}
</MellowCard>
</div>
</Col>
)}
</Row>
</Spin>
</Col>
<Col span={24}>
<MellowCard>
<Tabs
className={styles['record-tabs']}
activeKey={salesTabKey}
onChange={handleSalesTabChange}
tabBarExtraContent={
salesTabKey === 'evaluateRecord' ? (
<>
<Button type="text" onClick={() => handleSalesRadioChange(3)}>好评</Button>
<Button type="text" onClick={() => handleSalesRadioChange(2)}>中评</Button>
<Button type="text" onClick={() => handleSalesRadioChange(1)}>差评</Button>
<Button type="text" onClick={() => handleSalesRadioChange(0)}>全部</Button>
</>
) : null
}
>
<TabPane tab="交易评价统计" key="evaluateSum">
<Spin spinning={Boolean(salesEstimateSum.loading)}>
<Row gutter={24}>
<Col flex="386px">
<Pie
hasLegend
subTitle="累计评价"
total={() => salesEvaluatePie.reduce((pre, now) => now.y + pre, 0)}
data={salesEvaluatePie}
height={178}
colProps={{
span: 8,
}}
colors={['#41CC9E', '#FFC400', '#EF6260']}
/>
</Col>
<Col flex="1">
<PolymericTable
dataSource={salesEvaluate}
columns={evaluateColumns}
loading={false}
pagination={null}
rowClassName={() => styles['record-row']}
/>
</Col>
</Row>
</Spin>
</TabPane>
<TabPane tab="交易评价记录" key="evaluateRecord">
<PolymericTable
rowKey="remark"
dataSource={salesList}
columns={evaluateRecordColumns}
loading={salesListLoading}
pagination={{
pageSize: salesSize,
total: salesTotal,
}}
onPaginationChange={handleSalesPaginationChange}
/>
</TabPane>
</Tabs>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard>
<Tabs
className={styles['record-tabs']}
activeKey={afterTabKey}
onChange={handleAfterTabChange}
tabBarExtraContent={
afterTabKey === 'evaluateRecord' ? (
<>
<Button type="text" onClick={() => handleAfterRadioChange(3)}>好评</Button>
<Button type="text" onClick={() => handleAfterRadioChange(2)}>中评</Button>
<Button type="text" onClick={() => handleAfterRadioChange(1)}>差评</Button>
<Button type="text" onClick={() => handleAfterRadioChange(0)}>全部</Button>
</>
) : null
}
>
<TabPane tab="售后评价统计" key="evaluateSum">
<Spin spinning={Boolean(afterEstimateSum.loading)}>
<Row gutter={24}>
<Col flex="386px">
<Pie
hasLegend
subTitle="累计评价"
total={() => afterEvaluatePie.reduce((pre, now) => now.y + pre, 0)}
data={afterEvaluatePie}
height={178}
colProps={{
span: 8,
}}
colors={['#41CC9E', '#FFC400', '#EF6260']}
/>
</Col>
<Col flex="1">
<PolymericTable
dataSource={afterEvaluate}
columns={evaluateColumns}
loading={false}
pagination={null}
rowClassName={() => styles['record-row']}
/>
</Col>
</Row>
</Spin>
</TabPane>
<TabPane tab="售后评价记录" key="evaluateRecord">
<PolymericTable
rowKey="remark"
dataSource={afterList}
columns={evaluateRecordColumns}
loading={afterListLoading}
pagination={{
pageSize: afterSize,
total: afterTotal,
}}
onPaginationChange={handleAfterPaginationChange}
/>
</TabPane>
</Tabs>
</MellowCard>
</Col>
<Col span={24}>
<MellowCard title="投诉记录">
<div className={styles['record-btns']}>
<Button type="text">全部({complaintSumData?.sum})</Button>
<Button type="text">最近7天({complaintSumData?.last7days})</Button>
<Button type="text">最近30天({complaintSumData?.last30days})</Button>
<Button type="text">最近180天({complaintSumData?.last180days})</Button>
<Button type="text">180天前({complaintSumData?.before180days})</Button>
</div>
<PolymericTable
rowKey="remark"
dataSource={complainList}
columns={recordColumns}
loading={complainListLoading}
pagination={{
pageSize: complainSize,
total: complainTotal,
}}
onPaginationChange={handleComplainPaginationChange}
/>
</MellowCard>
</Col>
</Row>
</div>
);
};
export default SincerityInfo;
.tag {
line-height: 22px;
padding: 0 8px;
font-size: 12px;
font-weight: 400;
color: #00B37A;
background: #EBF7F2;
border-radius: 4px;
&__success {
color: #00B37A;
background: #EBF7F2;
}
&__warnning {
color: #FF991F;
background: #FFFAE6;
}
&__default {
color: #606266;
background: #F4F5F7;
}
&__danger {
color: #E63F3B;
background: #FFEBE6;
}
&__primary {
color: #3F7ED2;
background: #F0F8FF;
}
}
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2020-08-31 17:52:14
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-08-31 18:59:18
* @Description: 状态 tag
*/
import React from 'react';
import classNames from 'classnames';
import styles from './index.less';
interface StatusTagProps {
type: 'success' | 'warning' | 'default' | 'danger' | 'primary';
title: string;
};
const StatusTag: React.FC<StatusTagProps> = ({ type, title }) => {
const cls = classNames(styles.tag, styles[`tag__${type}`]);
return (
<span className={cls}>{title}</span>
);
};
export default StatusTag;
\ No newline at end of file
......@@ -28,7 +28,7 @@ import {
MEMBER_OUTER_STATUS_UNCOMMITTED,
MEMBER_OUTER_STATUS_FAILED,
} from '@/constants/member';
import StatusTag from '../components/StatusTag';
import StatusTag from '@/components/StatusTag';
import { importSchema, auditModalSchema } from './schema';
import { coverColFiltersItem } from '../utils';
import { MEMBER_OUTER_STATUS_TYPE, MEMBER_STATUS_TAG_MAP } from '../constant';
......
......@@ -15,7 +15,7 @@ import { FORM_FILTER_PATH } from '@/formSchema/const';
import EyePreview from '@/components/EyePreview';
import NiceForm from '@/components/NiceForm';
import LevelBrand from '@/components/LevelBrand';
import StatusTag from '../components/StatusTag';
import StatusTag from '@/components/StatusTag';
import { PublicApi } from '@/services/api';
import useSpliceArray from '@/hooks/useSpliceArray';
import { querySchema } from './schema';
......
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