Commit ff6064b7 authored by XieZhiXiong's avatar XieZhiXiong

对接完评论相关已有接口

parent 28439d0a
......@@ -2,33 +2,37 @@
* @Author: XieZhiXiong
* @Date: 2020-09-23 09:55:40
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-09-23 11:12:37
* @Description:
* @LastEditTime: 2020-10-21 14:58:09
* @Description: 评价管理相关路由
*/
const commentRoutes = {
path: '/comment',
name: 'comment',
icon: 'SmileOutlined',
routes: [
// 会员评价查询
{
path: '/comment/query',
name: 'query',
component: '@/pages/comment/query/index',
},
// 会员评价详情
{
path: '/comment/query/detailed',
name: 'queryDetailed',
path: '/comment/query/detail',
name: 'queryDetail',
component: '@/pages/comment/query/detailed/index',
hideInMenu: true,
},
// 评价管理
{
path: '/comment/manage',
name: 'manage',
component: '@/pages/comment/manage/index',
},
// 评价管理-详情
{
path: '/comment/manage/detailed',
name: 'manageDetailed',
path: '/comment/manage/detail',
name: 'manageDetail',
component: '@/pages/comment/manage/detailed/index',
hideInMenu: true,
hidePageHeader: true,
......
/*
* @Author: LeeJiancong
* @Date: 2020-08-04 15:47:40
* @LastEditors: Please set LastEditors
* @LastEditTime: 2020-10-20 18:19:02
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-10-21 14:48:29
*/
/**
......@@ -19,8 +19,21 @@ import memberAbility from './memberAbility'
import ruleSettingRoutes from './ruleSettingRoutes'
import authConfig from './authConfig'
import rfqRoute from './rfqRoute' // 询价单路由
import commentRoutes from './commentRoutes';
import contentRoute from './contentRoute';
const routeList = [pageCustomized, calssPropertyRoute, trademarkRoute, commodity, rfqRoute, logisticsRoutes, memberAbility, ruleSettingRoutes, authConfig, contentRoute]
const routeList = [
pageCustomized,
calssPropertyRoute,
trademarkRoute,
commodity,
rfqRoute,
logisticsRoutes,
memberAbility,
ruleSettingRoutes,
authConfig,
commentRoutes,
contentRoute,
]
const router = [
{
path: '/login',
......
......@@ -2,13 +2,13 @@
* @Author: XieZhiXiong
* @Date: 2020-08-21 11:13:55
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-08-25 10:05:19
* @LastEditTime: 2020-10-21 16:39:54
* @Description:
*/
import { TableProps, TablePaginationConfig, ColumnType } from 'antd/lib/table';
export interface StandardTableProps extends TableProps<any> {
pagination?: TablePaginationConfig;
pagination?: TablePaginationConfig | false;
onPaginationChange?: (page: number, size: number) => void;
}
......
......@@ -159,9 +159,9 @@ export default {
// 评论管理
'menu.comment': '评论管理',
'menu.comment.query': '会员评价查询',
'menu.comment.queryDetailed': '评价统计',
'menu.comment.queryDetail': '评价统计',
'menu.comment.manage': '评价管理',
'menu.comment.manageDetailed': '评价管理',
'menu.comment.manageDetail': '评价管理',
// 订单管理
'menu.orderSystem': '订单管理',
......
......@@ -2,7 +2,7 @@
* @Author: XieZhiXiong
* @Date: 2020-09-23 11:02:03
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-10-20 14:26:49
* @LastEditTime: 2020-10-21 15:19:00
* @Description:
*/
import React, { useState, useEffect } from 'react';
......@@ -16,6 +16,7 @@ import {
} from 'antd';
import { history } from 'umi';
import { PublicApi } from '@/services/api';
import { GetOrderPlatformOrderDetailsResponse } from '@/services/OrderApi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { createFormActions } from '@formily/antd';
import { usePageStatus } from '@/hooks/usePageStatus';
......@@ -31,27 +32,48 @@ import styles from './evaluate.less';
const formActions = createFormActions();
const CommentManageDetailed: React.FC = () => {
const { id } = usePageStatus();
const [commentInfo, seCommentInfo] = useState<Unevaluated[]>([]);
const [infoLoading, setInfoLoading] = useState(false);
const { id, orderId } = usePageStatus();
const [orderInfo, setOrderInfo] = useState<GetOrderPlatformOrderDetailsResponse>();
const [orderInfoLoading, setOrderInfoLoading] = useState(false);
const [commentInfo, setCommentInfo] = useState<Unevaluated[]>([]);
const [commentInfoLoading, setCommentInfoLoading] = useState(false);
// 获取订单详情
const getOrderInfo = () => {
if (!orderId || orderId === 'undefined') {
return;
}
setOrderInfoLoading(true);
PublicApi.getOrderPlatformOrderDetails({
id: orderId,
}).then(res => {
if (res.code === 1000) {
setOrderInfo(res.data);
}
}).finally(() => {
setOrderInfoLoading(false);
});
};
// 获取评论详情
const getCommentInfo = () => {
if (!id) {
return;
}
setInfoLoading(true);
setCommentInfoLoading(true);
PublicApi.getMemberPlatformCommentOrderTradeHistoryGet({
id,
}).then(res => {
if (res.code === 1000) {
seCommentInfo(normalizeUnevaluatedList(res.data));
setCommentInfo(normalizeUnevaluatedList([res.data]));
}
}).finally(() => {
setInfoLoading(false);
setCommentInfoLoading(false);
});
};
useEffect(() => {
getOrderInfo();
getCommentInfo();
}, []);
......@@ -78,7 +100,7 @@ const CommentManageDetailed: React.FC = () => {
);
return (
<Spin spinning={infoLoading}>
<Spin spinning={commentInfoLoading || orderInfoLoading}>
<PageHeaderWrapper
title={
<>
......@@ -89,7 +111,7 @@ const CommentManageDetailed: React.FC = () => {
<AvatarWrap
info={{
aloneTxt: '单',
name: '订单号:DPTY12'
name: orderInfo? orderInfo.orderNo : '',
}}
/>
}
......@@ -101,8 +123,7 @@ const CommentManageDetailed: React.FC = () => {
padding: '0 32px',
}}
>
<Descriptions.Item label="采购会员">BPTY12</Descriptions.Item>
<Descriptions.Item label="下单时间" span={2}>2020-08-25 08:49</Descriptions.Item>
<Descriptions.Item label="下单时间" span={2}>{orderInfo?.createTime}</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
......@@ -113,6 +134,7 @@ const CommentManageDetailed: React.FC = () => {
initialValues={{
comments: commentInfo,
}}
editable={false}
expressionScope={{
UploadTip,
beforeUpload,
......
......@@ -5,10 +5,12 @@ import { Link } from 'umi';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { createFormActions } from '@formily/antd';
import moment from 'moment';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { PublicApi } from '@/services/api';
import { isJSONStr } from '@/utils';
import EyePreview from '@/components/EyePreview';
import NiceForm from '@/components/NiceForm';
import { listSearchSchema } from './schema';
......@@ -28,7 +30,7 @@ const CommentManage: React.FC = () => {
align: 'center',
render: (text, record) => (
<EyePreview
url={`/comment/manage/detailed`}
url={`/comment/manage/detail?orderId=${record.orderId}&id=${record.id}`}
>
{text}
</EyePreview>
......@@ -38,15 +40,22 @@ const CommentManage: React.FC = () => {
title: '交易商品/交易时间',
dataIndex: 'product',
align: 'center',
render: (text, record) => (
render: (text, record) => {
const product = isJSONStr(text) || {};
return (
<>
<div>{text}</div>
<div>
<div>{product.productName}</div>
<div
style={{
marginTop: 4,
}}
>
<ClockCircleOutlined />
{record.dealTime}
{` ${record.dealTime}`}
</div>
</>
),
)
},
},
{
title: '被评价方',
......@@ -89,8 +98,15 @@ const CommentManage: React.FC = () => {
];
const fetchListData = (params: any) => {
const { createTimeStart, createTimeEnd, dealTimeStart, dealTimeEnd, ...rest } = params;
return new Promise((resolve, reject) => {
PublicApi.getMemberPlatformCommentOrderTradeHistoryPage(params)
PublicApi.getMemberPlatformCommentOrderTradeHistoryPage({
...rest,
createTimeStart: createTimeStart ? moment(+createTimeStart).format('YYYY-MM-DD HH:mm:ss') : null,
createTimeEnd: createTimeEnd ? moment(+createTimeEnd).format('YYYY-MM-DD HH:mm:ss') : null,
dealTimeStart: dealTimeStart ? moment(+dealTimeStart).format('YYYY-MM-DD HH:mm:ss') : null,
dealTimeEnd: dealTimeEnd ? moment(+dealTimeEnd).format('YYYY-MM-DD HH:mm:ss') : null,
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
......@@ -125,7 +141,7 @@ const CommentManage: React.FC = () => {
<Card>
<StandardTable
tableProps={{
rowKey: 'orderNo',
rowKey: 'id',
}}
columns={columns}
currentRef={ref}
......
......@@ -44,25 +44,44 @@ export const listSearchSchema: ISchema = {
subMemberName: {
type: 'string',
default: undefined,
enum: [],
'x-component-props': {
placeholder: '被评价方(全部)',
placeholder: '被评价方',
allowClear: true,
},
},
memberName: {
type: 'string',
default: undefined,
enum: [],
'x-component-props': {
placeholder: '评价方(全部)',
placeholder: '评价方',
allowClear: true,
},
},
star: {
type: 'string',
default: undefined,
enum: [],
enum: [
{
label: '一星',
value: 1,
},
{
label: '二星',
value: 2,
},
{
label: '三星',
value: 3,
},
{
label: '四星',
value: 4,
},
{
label: '五星',
value: 5,
},
],
'x-component-props': {
placeholder: '评价星级(全部)',
allowClear: true,
......
......@@ -135,28 +135,23 @@ const EvaluationList = props => {
return (
<RowStyleLayout {...componentProps} key={index}>
<Row align="middle">
<Col span={10}>
<Col span={8}>
<div className="goodInfo">
<div className="goodInfo-left">
<img src={item.good ? item.good.pic : ''} />
</div>
<div className="goodInfo-right">
<div className="goodInfo-title">进口头层黄牛皮荔枝纹/红色/XL</div>
<div className="goodInfo-desc">20 平方英尺</div>
<div className="goodInfo-price">¥ 400.00</div>
<div className="goodInfo-title">{item.good.productName}</div>
<div className="goodInfo-desc">X {item.good.purchaseCount || ''}</div>
<div className="goodInfo-price">{`¥ ${item.good.price}`}</div>
</div>
</div>
</Col>
<Col span={10}>
<Col span={16}>
<div className="main">
<SchemaField path={FormPath.parse(path).concat(index)} />
</div>
</Col>
<Col span={4}>
<div style={{ textAlign: 'right' }}>
<SmilingFace value={2} />
</div>
</Col>
</Row>
</RowStyleLayout>
)
......
/*
* @Author: XieZhiXiong
* @Date: 2020-09-22 20:34:49
* @Date: 2020-10-19 18:08:51
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-09-22 20:52:53
* @LastEditTime: 2020-10-21 13:58:50
* @Description:
*/
import { ISchema } from '@formily/antd';
......@@ -19,7 +19,28 @@ export const searchSchema: ISchema = {
properties: {
star: {
type: 'string',
enum: [],
enum: [
{
label: '一星',
value: 1,
},
{
label: '二星',
value: 2,
},
{
label: '三星',
value: 3,
},
{
label: '四星',
value: 4,
},
{
label: '五星',
value: 5,
},
],
'x-component-props': {
placeholder: '评论星级',
allowClear: true,
......@@ -28,7 +49,7 @@ export const searchSchema: ISchema = {
},
},
},
'[startDate, endDate]': {
'[dealTimeStart, dealTimeEnd]': {
type: 'string',
default: '',
'x-component': 'dateSelect',
......@@ -40,7 +61,7 @@ export const searchSchema: ISchema = {
},
},
},
name: {
memberName: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
......
import React from 'react';
import React, { useState, useEffect } from 'react';
import { Tabs, Row, Col, Button } from 'antd';
import { createFormActions } from '@formily/antd';
import { history } from 'umi';
import { PublicApi } from '@/services/api';
import { isJSONStr } from '@/utils';
import MellowCard from '@/components/MellowCard';
import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import { Pie } from '@/components/Charts';
import Mood from '@/components/Mood';
import NiceForm from '@/components/NiceForm';
import { searchSchema } from './schema';
import Shelves from './components/Shelves';
import RecordList from './components/RecordList';
import RecordList, { ListParams, RecordRes } from './components/RecordList';
import styles from './index.less';
const { TabPane } = Tabs;
const receivedFormActions = createFormActions();
interface EstimateSumItems {
id?: number,
title?: JSX.Element,
star?: number,
last7days?: number,
last30days?: number,
last180days?: number,
before180days?: number,
sum?: number,
};
const CommentDetailed: React.FC = () => {
const [evaluateSum, setEvaluateSum] = useState<EstimateSumItems[]>([]);
const [evaluatePie, setEvaluatePie] = useState<{ x: string, y: number }[]>([]);
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 = {};
switch (item.star) {
case 1:
case 2: {
target = ret[0];
break;
}
case 3: {
target = ret[1];
break;
}
case 4:
case 5: {
target = ret[2];
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: any) => 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 getTradeSummary = () => {
PublicApi.getMemberPlatformCommentCountSupplyTradeSummary().then(res => {
if (res.code === 1000) {
const evaluate = summaryEvaluate(res.data.rows);
const evaluatePieData = getSummaryEvaluatePie(evaluate);
setEvaluateSum(evaluate);
setEvaluatePie(evaluatePieData);
}
});
};
// 获取评价记录
const getTradeHistory = (params: ListParams): Promise<RecordRes> => {
const { star, ...rest } = params;
return new Promise((resolve, reject) => {
PublicApi.getMemberPlatformCommentCountSupplyTradeHistoryPage({
...rest,
starLevel: params.star,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
const product = isJSONStr(item.product) || {};
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: product.productName || '',
price: product.price,
quantity: product.purchaseCount,
created: item.createTime,
target: item.byMemberName,
orderId: product.orderId,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
const evaluateColumns: EditableColumns[] = [
{
title: ' ',
......@@ -45,47 +199,9 @@ const CommentDetailed: React.FC = () => {
},
];
const evaluatePie = [
{
x: `好评 30%`,
y: 100,
},
{
x: `中评 20%`,
y: 50,
},
{
x: `差评 10%`,
y: 10,
},
];
const evaluate = [
{
id: 1,
title: (<Mood type="smile" />),
last7days: 10,
last30days: 20,
last180days: 30,
before180days: 30,
},
{
id: 2,
title: (<Mood type="notBad" />),
last7days: 10,
last30days: 20,
last180days: 30,
before180days: 30,
},
{
id: 3,
title: (<Mood type="sad" />),
last7days: 10,
last30days: 20,
last180days: 30,
before180days: 30,
},
];
useEffect(() => {
getTradeSummary();
}, []);
return (
<MellowCard
......@@ -113,10 +229,10 @@ const CommentDetailed: React.FC = () => {
<Col flex="auto">
<PolymericTable
dataSource={evaluate}
dataSource={evaluateSum}
columns={evaluateColumns}
loading={false}
pagination={null}
pagination={false}
rowClassName={() => styles['record-row']}
/>
</Col>
......@@ -124,29 +240,12 @@ const CommentDetailed: React.FC = () => {
</Shelves>
<Shelves title="评价记录">
<RecordList list={[]} />
<div
style={{
padding: '24px 0',
textAlign: 'center',
}}
>
<Button>查看更多评论</Button>
</div>
</Shelves>
</TabPane>
<TabPane tab="收到的评价" key="2">
<NiceForm
actions={receivedFormActions}
onSubmit={values => {}}
effects={($, actions) => {
}}
schema={searchSchema}
<RecordList
fetchList={getTradeHistory}
paginationType="button"
searchable={false}
/>
<RecordList list={[]} />
</Shelves>
</TabPane>
</Tabs>
</MellowCard>
......
......@@ -7,6 +7,7 @@ import { createFormActions } from '@formily/antd';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { useAsyncInitSelect } from '@/formSchema/effects/useAsyncInitSelect';
import { PublicApi } from '@/services/api';
import { Link } from 'umi';
import EyePreview from '@/components/EyePreview';
import NiceForm from '@/components/NiceForm';
......@@ -55,7 +56,7 @@ const CommentQuery = () => {
align: 'center',
render: (text, record) => (
<EyePreview
url={`/comment/query/detailed`}
url={`/comment/query/detail`}
>
{text}
</EyePreview>
......@@ -102,9 +103,23 @@ const CommentQuery = () => {
];
const fetchListData = (params: any) => {
return Promise.resolve({
total: 2,
// return new Promise((resolve, reject) => {
// PublicApi.getMemberPlatformCommentOrderTradeHistoryPage(params)
// .then(res => {
// if (res.code === 1000) {
// resolve(res.data);
// }
// reject();
// })
// .catch(() => {
// reject();
// });
// });
return new Promise((resolve, reject) => {
resolve({
data: mock,
totalCount: 2,
});
});
};
......
......@@ -76,61 +76,3 @@ export const listSearchSchema: ISchema = {
},
},
};
\ No newline at end of file
export const evaluateSchema: ISchema = {
type: 'object',
properties: {
comments: {
type: 'array',
'x-component': 'EvaluationList',
default: [
{
name: '杰尼',
age: 24,
small: 1,
},
],
items: {
type: 'object',
properties: {
MEGA_LADYOUT: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 6,
labelAlign: 'left',
},
properties: {
star: {
title: '满意程度',
required: true,
'x-component': 'Rating',
'x-component-props': {
allowHalf: false,
},
},
comment: {
type: 'string',
title: '评价',
required: true,
'x-component': 'TextArea',
'x-component-props': {
rows: 4,
},
},
picture: {
type: 'string',
title: '图片',
required: true,
'x-component': 'CustomUpload',
'x-component-props': {
},
},
},
},
},
},
},
},
};
\ No newline at end of file
......@@ -304,6 +304,38 @@ export function normalizeFiledata(url: any): any {
};
};
/**
* 检查是否还有更多
* @param {Number} curPage 当前页码
* @param {Number} curSize 当前页数
* @param {Number} dataLen 当前数据长度
* @param {Number} dataTotal 数据总长度
*/
export const checkMore = (curPage: number, curSize: number, dataLen: number, dataTotal: number) => {
let hasMore = true;
if (!dataLen || dataLen + (curPage - 1) * curSize >= +dataTotal) {
hasMore = false;
}
return hasMore;
};
/**
*
* @param {string} str 需要判断是否是 JSON字符串的 字符串
*/
export const isJSONStr = str => {
if (typeof str === 'string') {
try {
const complete = JSON.parse(str);
return complete;
} catch(e) {
return null;
}
}
return str;
}
export default {
isArray,
isObject,
......
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