Commit 58cd5ee7 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat: 交易能力 -> 供应会员评价管理国际化

parent 78925a60
......@@ -19,6 +19,7 @@ import logistics from './zh-CN/logistics'
import dealAbility from './zh-CN/dealAbility'
import purchaserEvaluation from './zh-CN/purchaserEvaluation'
import stockSellStorage from './zh-CN/stockSellStorage'
import supplierEvaluation from './zh-CN/supplierEvaluation'
import content from './zh-CN/content'
import commodity from './zh-CN/commodity'
import trademark from './zh-CN/trademark'
......@@ -53,6 +54,7 @@ export default {
...dealAbility,
...purchaserEvaluation,
...stockSellStorage,
...supplierEvaluation,
...content,
...processRuleSetting,
}
export default {
'supplierEvaluation.sousuo': '搜索',
'supplierEvaluation.shurudingdanhao': '输入 订单号 进行搜索',
'supplierEvaluation.dingdanzhaiyao': '订单摘要',
'supplierEvaluation.caigouhuiyuan': '采购会员',
'supplierEvaluation.xiadanshijian': '下单时间',
'supplierEvaluation.dingdanleixing': '订单类型',
'supplierEvaluation.chaxun': '查询',
'supplierEvaluation.tupiandaxiaochaoguo10M': '图片大小超过10M',
'supplierEvaluation.xiugai': '修改',
'supplierEvaluation.zhichiJPGPNGJPEG': '支持JPG/PNG/JPEG',
'supplierEvaluation.meizhangzuidabuchaoguo': '每张最大不超过 10M,尺寸不限',
'supplierEvaluation.zuidashuliangxianzhi4': '最大数量限制 4张',
'supplierEvaluation.ninhaiyouweibaocunde': '"您还有未保存的内容,是否确定要离开?"',
'supplierEvaluation.fabu': '发布',
'supplierEvaluation.dingdanhao': '订单号',
'supplierEvaluation.waibuzhuangtai': '外部状态',
'supplierEvaluation.neibuzhuangtai': '内部状态',
'supplierEvaluation.caozuo': '操作',
'supplierEvaluation.pingjia': '评价',
'supplierEvaluation.yiwancheng': '已完成',
'supplierEvaluation.zaicishurunideneirong': '在此输入你的内容',
'supplierEvaluation.qingshuruneirong': '请输入内容',
'supplierEvaluation.shangjiajieshi': '商家解释',
'supplierEvaluation.shangjiaduiyupingjiadejie': '商家对于评价的解释,显示在商品交易评价中',
'supplierEvaluation.beipingjiafang': '被评价方',
'supplierEvaluation.fachudepingjia': '发出的评价',
'supplierEvaluation.shoudaodepingjia': '收到的评价',
'supplierEvaluation.pingjiajilu': '评价记录',
'supplierEvaluation.leijipingjia': '累计评价',
'supplierEvaluation.pingjiatongji': '评价统计',
'supplierEvaluation.gailan': '概览',
'supplierEvaluation.180tianqian': '180天前',
'supplierEvaluation.zuijin180tian': '最近180天',
'supplierEvaluation.zuijin30tian': '最近30天',
'supplierEvaluation.zuijin7tian': '最近7天',
'supplierEvaluation.chaping': '差评',
'supplierEvaluation.zhongping': '中评',
'supplierEvaluation.haoping': '好评',
'supplierEvaluation.dingdanzonge': '订单总额',
}
/*
* @Author: XieZhiXiong
* @Date: 2021-08-11 14:20:42
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-18 10:44:56
* @Description: 解释 Modal
*/
import React from 'react';
import { Modal, Tooltip } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { createAsyncFormActions } from '@formily/antd';
import NiceForm from '@/components/NiceForm';
import schema from './schema';
const modalFormActions = createAsyncFormActions();
export type ValuesType = {
/**
* 解释内容
*/
content: string,
}
interface ExplainModalProps {
visible: boolean;
confirmLoading: boolean;
onSubmit: (values: ValuesType) => void;
/**
* 关闭触发事件
*/
onClose: () => void;
/**
* 是否只可以选择 不接受申请
*/
rejected?: boolean;
}
const ExplainModal: React.FC<ExplainModalProps> = (props) => {
const {
visible,
confirmLoading,
onSubmit,
onClose,
} = props;
const handleClose = () => {
onClose?.();
};
const handleSubmit = values => {
if (onSubmit) {
onSubmit(values);
}
};
return (
<Modal
title={(
<>
商家解释
<Tooltip title="商家对于评价的解释,显示在商品交易评价中">
<QuestionCircleOutlined style={{ marginLeft: 3 }} />
</Tooltip>
</>
)}
visible={visible}
confirmLoading={confirmLoading}
onOk={() => modalFormActions.submit()}
onCancel={handleClose}
destroyOnClose
>
<NiceForm
effects={() => {
}}
actions={modalFormActions}
schema={schema}
onSubmit={handleSubmit}
/>
</Modal>
);
};
export default ExplainModal;
/*
* @Author: XieZhiXiong
* @Date: 2021-08-11 14:20:42
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-18 10:44:56
* @Description: 解释 Modal
*/
import React from 'react';
import { Modal, Tooltip } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { createAsyncFormActions } from '@formily/antd';
import NiceForm from '@/components/NiceForm';
import schema from './schema';
import { getIntl } from 'umi';
const intl = getIntl();
const modalFormActions = createAsyncFormActions();
export type ValuesType = {
/**
* 解释内容
*/
content: string,
}
interface ExplainModalProps {
visible: boolean;
confirmLoading: boolean;
onSubmit: (values: ValuesType) => void;
/**
* 关闭触发事件
*/
onClose: () => void;
/**
* 是否只可以选择 不接受申请
*/
rejected?: boolean;
}
const ExplainModal: React.FC<ExplainModalProps> = (props) => {
const {
visible,
confirmLoading,
onSubmit,
onClose,
} = props;
const handleClose = () => {
onClose?.();
};
const handleSubmit = values => {
if (onSubmit) {
onSubmit(values);
}
};
return (
<Modal
title={(
<>
{intl.formatMessage({id: 'supplierEvaluation.shangjiajieshi'})}
<Tooltip title={intl.formatMessage({id: 'supplierEvaluation.shangjiaduiyupingjiadejie'})}>
<QuestionCircleOutlined style={{ marginLeft: 3 }} />
</Tooltip>
</>
)}
visible={visible}
confirmLoading={confirmLoading}
onOk={() => modalFormActions.submit()}
onCancel={handleClose}
destroyOnClose
>
<NiceForm
effects={() => {
}}
actions={modalFormActions}
schema={schema}
onSubmit={handleSubmit}
/>
</Modal>
);
};
export default ExplainModal;
/*
* @Author: XieZhiXiong
* @Date: 2021-08-11 14:23:08
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-11 14:58:47
* @Description:
*/
import { ISchema } from '@formily/antd';
const schema: ISchema = {
type: 'object',
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelAlign: 'top',
},
properties: {
content: {
type: 'string',
'x-component': 'textarea',
'x-component-props': {
placeholder: '在此输入你的内容',
rows: 5,
},
'x-rules': [
{
required: true,
message: '请输入内容',
},
],
},
},
},
},
};
export default schema;
/*
* @Author: XieZhiXiong
* @Date: 2021-08-11 14:23:08
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-11 14:58:47
* @Description:
*/
import { ISchema } from '@formily/antd';
import { getIntl } from 'umi';
const intl = getIntl();
const schema: ISchema = {
type: 'object',
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelAlign: 'top',
},
properties: {
content: {
type: 'string',
'x-component': 'textarea',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.zaicishurunideneirong'}),
rows: 5,
},
'x-rules': [
{
required: true,
message: intl.formatMessage({id: 'supplierEvaluation.qingshuruneirong'}),
},
],
},
},
},
},
};
export default schema;
import React, { useEffect, useState, useRef } from 'react';
import { Tabs, Row, Col } from 'antd';
import { history } from 'umi';
import { observer, inject } from 'mobx-react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { getMemberCommentSupplyCountTradeSummary, getMemberCommentSupplyCountTradeHistoryPage, getMemberCommentSupplyReceiveTradeHistoryPage, getMemberCommentSupplySendTradeHistoryPage, postMemberCommentSupplyReceiveTradeHistoryReply } from '@/services/MemberV2Api';
import { IEvaluationModule } from '@/module/evaluationModule';
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 ExplainModal, { ValuesType } from './components/ExplainModal';
import Shelves from '../../purchaserEvaluation/components/Shelves';
import RecordList, { ListParams, RecordRes, RecordItem } from '../../purchaserEvaluation/components/RecordList';
import styles from './index.less';
const { TabPane } = Tabs;
interface ReceivedSearch {
/**
* 评价星级(1-5)
*/
star: string
/**
* 交易时间开始
*/
dealTimeStart: string
/**
* 交易时间结束
*/
dealTimeEnd: string
/**
* 评价方名称
*/
memberName: string
};
interface EstimateSumItems {
id?: number,
title?: JSX.Element,
star?: number,
last7days?: number,
last30days?: number,
last180days?: number,
before180days?: number,
sum?: number,
};
interface AnalysisProps {
EvaluationStore?: IEvaluationModule;
};
const Analysis: React.FC<AnalysisProps> = ({
EvaluationStore,
}) => {
const [evaluateSum, setEvaluateSum] = useState([]);
const [evaluatePie, setEvaluatePie] = useState([]);
const [visibleExplainModal, setVisibleExplainModal] = useState(false);
const [explainConfirmLoading, setExplainConfirmLoading] = useState(false);
const { supplier, setSupplierActiveKey } = EvaluationStore;
const recordListRef = useRef<RecordList | null>(null);
const currentRecordRef = useRef<RecordItem | null>(null);
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 getTradeSummary = () => {
getMemberCommentSupplyCountTradeSummary().then(res => {
if (res.code === 1000) {
const evaluate = summaryEvaluate(res.data.rows);
const evaluatePieData = getSummaryEvaluatePie(evaluate);
setEvaluateSum(evaluate);
setEvaluatePie(evaluatePieData);
}
}).catch((err) => {
console.warn(err);
});
};
// 获取评价记录
const getTradeHistory = (params: ListParams): Promise<RecordRes> => {
const { star, ...rest } = params;
return new Promise((resolve, reject) => {
getMemberCommentSupplyCountTradeHistoryPage({
...rest,
starLevel: params.star,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
target: item.byMemberName,
orderId: item.orderId,
dealTime: item.dealTime as string,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
// 获取收到的评价列表
const getReceivedList = (params: ListParams): Promise<RecordRes> => {
return new Promise((resolve, reject) => {
getMemberCommentSupplyReceiveTradeHistoryPage({
...params,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
target: item.memberName,
orderId: item.orderId,
replyStatus: item.replyStatus,
dealTime: item.dealTime as string,
status: item.status,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
// 获取发出的评价列表
const getSentList = (params: ListParams): Promise<RecordRes> => {
const { memberName, ...rest } = params;
return new Promise((resolve, reject) => {
getMemberCommentSupplySendTradeHistoryPage({
...rest,
subMemberName: memberName,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
target: item.subMemberName,
orderId: item.orderId,
dealTime: item.dealTime as string,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
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',
},
];
useEffect(() => {
getTradeSummary();
}, []);
const handleJumpReceived = record => {
history.push(`/memberCenter/tranactionAbility/supplierEvaluation/received/detail?id=${record.id}`);
};
const handleEditSent = record => {
history.push(`/memberCenter/tranactionAbility/supplierEvaluation/sent/edit?id=${record.id}`);
};
const handleJumpSent = record => {
history.push(`/memberCenter/tranactionAbility/supplierEvaluation/sent/detail?id=${record.id}`);
};
const handleVisibleExplainModal = (flag?: boolean) => {
setVisibleExplainModal(!!flag);
};
const handleExplain = (record: RecordItem) => {
currentRecordRef.current = record;
handleVisibleExplainModal(true);
};
const handleExplainSubmit = (values: ValuesType) => {
setExplainConfirmLoading(true);
postMemberCommentSupplyReceiveTradeHistoryReply({
id: currentRecordRef.current.id,
content: values.content,
}).then((res) => {
if (res.code === 1000) {
recordListRef.current?.refresh();
handleVisibleExplainModal(false);
}
}).finally(() => {
setExplainConfirmLoading(false);
});
};
return (
<PageHeaderWrapper>
<MellowCard
bodyStyle={{
padding: '0 24px 24px',
}}
>
<Tabs
className={styles.tabs}
activeKey={supplier.activeKey}
onChange={setSupplierActiveKey}
>
<TabPane tab="概览" key="1">
<Shelves title="评价统计">
<Row gutter={24}>
<Col flex="399px">
<Pie
hasLegend
subTitle="累计评价"
total={() => evaluatePie.reduce((pre, now) => now.y + pre, 0)}
data={evaluatePie}
height={200}
colProps={{
span: 8,
}}
colors={['#41CC9E', '#FFC400', '#EF6260']}
/>
</Col>
<Col flex="auto">
<PolymericTable
dataSource={evaluateSum}
columns={evaluateColumns}
loading={false}
pagination={null}
rowClassName={() => styles['record-row']}
/>
</Col>
</Row>
</Shelves>
<Shelves title="评价记录">
<RecordList
fetchList={getTradeHistory}
paginationType="button"
searchable={false}
onCheck={handleJumpReceived}
/>
</Shelves>
</TabPane>
<TabPane tab="收到的评价" key="2">
<RecordList
fetchList={getReceivedList}
onCheck={handleJumpReceived}
onExplain={handleExplain}
explicable={true}
ref={recordListRef}
statusable={true}
/>
</TabPane>
<TabPane tab="发出的评价" key="3">
<RecordList
fetchList={getSentList}
onCheck={handleJumpSent}
onEdit={handleEditSent}
opposite={false}
editable={true}
searchTip="被评价方"
/>
</TabPane>
</Tabs>
</MellowCard>
<ExplainModal
visible={visibleExplainModal}
onClose={() => handleVisibleExplainModal(false)}
confirmLoading={explainConfirmLoading}
onSubmit={handleExplainSubmit}
/>
</PageHeaderWrapper>
);
};
export default inject('EvaluationStore')(observer(Analysis));
import React, { useEffect, useState, useRef } from 'react';
import { Tabs, Row, Col } from 'antd';
import { getIntl, history } from 'umi';
import { observer, inject } from 'mobx-react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { getMemberCommentSupplyCountTradeSummary, getMemberCommentSupplyCountTradeHistoryPage, getMemberCommentSupplyReceiveTradeHistoryPage, getMemberCommentSupplySendTradeHistoryPage, postMemberCommentSupplyReceiveTradeHistoryReply } from '@/services/MemberV2Api';
import { IEvaluationModule } from '@/module/evaluationModule';
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 ExplainModal, { ValuesType } from './components/ExplainModal';
import Shelves from '../../purchaserEvaluation/components/Shelves';
import RecordList, { ListParams, RecordRes, RecordItem } from '../../purchaserEvaluation/components/RecordList';
import styles from './index.less';
const { TabPane } = Tabs;
const intl = getIntl();
interface ReceivedSearch {
/**
* 评价星级(1-5)
*/
star: string
/**
* 交易时间开始
*/
dealTimeStart: string
/**
* 交易时间结束
*/
dealTimeEnd: string
/**
* 评价方名称
*/
memberName: string
};
interface EstimateSumItems {
id?: number,
title?: JSX.Element,
star?: number,
last7days?: number,
last30days?: number,
last180days?: number,
before180days?: number,
sum?: number,
};
interface AnalysisProps {
EvaluationStore?: IEvaluationModule;
};
const Analysis: React.FC<AnalysisProps> = ({
EvaluationStore,
}) => {
const [evaluateSum, setEvaluateSum] = useState([]);
const [evaluatePie, setEvaluatePie] = useState([]);
const [visibleExplainModal, setVisibleExplainModal] = useState(false);
const [explainConfirmLoading, setExplainConfirmLoading] = useState(false);
const { supplier, setSupplierActiveKey } = EvaluationStore;
const recordListRef = useRef<RecordList | null>(null);
const currentRecordRef = useRef<RecordItem | null>(null);
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: `${intl.formatMessage({id: 'supplierEvaluation.haoping'})} ${count > 0 ? (good / count * 100).toFixed(2) : '0'}%`,
y: good,
},
{
x: `${intl.formatMessage({id: 'supplierEvaluation.zhongping'})} ${count > 0 ? (notBad / count * 100).toFixed(2) : 0}%`,
y: notBad,
},
{
x: `${intl.formatMessage({id: 'supplierEvaluation.chaping'})} ${count > 0 ? (bad / count * 100).toFixed(2) : 0}%`,
y: bad,
},
];
return ret;
};
// 获取评价汇总
const getTradeSummary = () => {
getMemberCommentSupplyCountTradeSummary().then(res => {
if (res.code === 1000) {
const evaluate = summaryEvaluate(res.data.rows);
const evaluatePieData = getSummaryEvaluatePie(evaluate);
setEvaluateSum(evaluate);
setEvaluatePie(evaluatePieData);
}
}).catch((err) => {
console.warn(err);
});
};
// 获取评价记录
const getTradeHistory = (params: ListParams): Promise<RecordRes> => {
const { star, ...rest } = params;
return new Promise((resolve, reject) => {
getMemberCommentSupplyCountTradeHistoryPage({
...rest,
starLevel: params.star,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
target: item.byMemberName,
orderId: item.orderId,
dealTime: item.dealTime as string,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
// 获取收到的评价列表
const getReceivedList = (params: ListParams): Promise<RecordRes> => {
return new Promise((resolve, reject) => {
getMemberCommentSupplyReceiveTradeHistoryPage({
...params,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
target: item.memberName,
orderId: item.orderId,
replyStatus: item.replyStatus,
dealTime: item.dealTime as string,
status: item.status,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
// 获取发出的评价列表
const getSentList = (params: ListParams): Promise<RecordRes> => {
const { memberName, ...rest } = params;
return new Promise((resolve, reject) => {
getMemberCommentSupplySendTradeHistoryPage({
...rest,
subMemberName: memberName,
}).then(res => {
if (res.code === 1000) {
const { data, totalCount } = res.data;
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
target: item.subMemberName,
orderId: item.orderId,
dealTime: item.dealTime as string,
};
}),
totalCount,
});
}
reject(res.data);
}).catch(err => {
reject(err);
});
});
};
const evaluateColumns: EditableColumns[] = [
{
title: ' ',
dataIndex: 'title',
align: 'center',
},
{
title: intl.formatMessage({id: 'supplierEvaluation.zuijin7tian'}),
dataIndex: 'last7days',
align: 'center',
},
{
title: intl.formatMessage({id: 'supplierEvaluation.zuijin30tian'}),
dataIndex: 'last30days',
align: 'center',
},
{
title: intl.formatMessage({id: 'supplierEvaluation.zuijin180tian'}),
dataIndex: 'last180days',
align: 'center',
},
{
title: intl.formatMessage({id: 'supplierEvaluation.180tianqian'}),
dataIndex: 'before180days',
align: 'center',
},
];
useEffect(() => {
getTradeSummary();
}, []);
const handleJumpReceived = record => {
history.push(`/memberCenter/tranactionAbility/supplierEvaluation/received/detail?id=${record.id}`);
};
const handleEditSent = record => {
history.push(`/memberCenter/tranactionAbility/supplierEvaluation/sent/edit?id=${record.id}`);
};
const handleJumpSent = record => {
history.push(`/memberCenter/tranactionAbility/supplierEvaluation/sent/detail?id=${record.id}`);
};
const handleVisibleExplainModal = (flag?: boolean) => {
setVisibleExplainModal(!!flag);
};
const handleExplain = (record: RecordItem) => {
currentRecordRef.current = record;
handleVisibleExplainModal(true);
};
const handleExplainSubmit = (values: ValuesType) => {
setExplainConfirmLoading(true);
postMemberCommentSupplyReceiveTradeHistoryReply({
id: currentRecordRef.current.id,
content: values.content,
}).then((res) => {
if (res.code === 1000) {
recordListRef.current?.refresh();
handleVisibleExplainModal(false);
}
}).finally(() => {
setExplainConfirmLoading(false);
});
};
return (
<PageHeaderWrapper>
<MellowCard
bodyStyle={{
padding: '0 24px 24px',
}}
>
<Tabs
className={styles.tabs}
activeKey={supplier.activeKey}
onChange={setSupplierActiveKey}
>
<TabPane tab={intl.formatMessage({id: 'supplierEvaluation.gailan'})} key="1">
<Shelves title={intl.formatMessage({id: 'supplierEvaluation.pingjiatongji'})}>
<Row gutter={24}>
<Col flex="399px">
<Pie
hasLegend
subTitle={intl.formatMessage({id: 'supplierEvaluation.leijipingjia'})}
total={() => evaluatePie.reduce((pre, now) => now.y + pre, 0)}
data={evaluatePie}
height={200}
colProps={{
span: 8,
}}
colors={['#41CC9E', '#FFC400', '#EF6260']}
/>
</Col>
<Col flex="auto">
<PolymericTable
dataSource={evaluateSum}
columns={evaluateColumns}
loading={false}
pagination={null}
rowClassName={() => styles['record-row']}
/>
</Col>
</Row>
</Shelves>
<Shelves title={intl.formatMessage({id: 'supplierEvaluation.pingjiajilu'})}>
<RecordList
fetchList={getTradeHistory}
paginationType="button"
searchable={false}
onCheck={handleJumpReceived}
/>
</Shelves>
</TabPane>
<TabPane tab={intl.formatMessage({id: 'supplierEvaluation.shoudaodepingjia'})} key="2">
<RecordList
fetchList={getReceivedList}
onCheck={handleJumpReceived}
onExplain={handleExplain}
explicable={true}
ref={recordListRef}
statusable={true}
/>
</TabPane>
<TabPane tab={intl.formatMessage({id: 'supplierEvaluation.fachudepingjia'})} key="3">
<RecordList
fetchList={getSentList}
onCheck={handleJumpSent}
onEdit={handleEditSent}
opposite={false}
editable={true}
searchTip={intl.formatMessage({id: 'supplierEvaluation.beipingjiafang'})}
/>
</TabPane>
</Tabs>
</MellowCard>
<ExplainModal
visible={visibleExplainModal}
onClose={() => handleVisibleExplainModal(false)}
confirmLoading={explainConfirmLoading}
onSubmit={handleExplainSubmit}
/>
</PageHeaderWrapper>
);
};
export default inject('EvaluationStore')(observer(Analysis));
import React, { useState, useEffect } from 'react';
import {
PageHeader,
Descriptions,
Spin,
message,
Upload,
} from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history } from 'umi';
import { createFormActions } from '@formily/antd';
import { usePageStatus } from '@/hooks/usePageStatus';
import { getMemberCommentSupplyReceiveTradeHistoryGet } from '@/services/MemberV2Api';
import { normalizeFiledata, FileData } from '@/utils';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import createSchema from '../../../purchaserEvaluation/common/schemas/receivedSchema';
import { createEffects } from '../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../purchaserEvaluation/components/EvaluationList';
const formActions = createFormActions();
interface Unevaluated {
good: {
pic: string,
productName: string,
price: number,
purchaseCount: number,
unit: string,
};
star: number;
comment: string;
picture: FileData[];
smile: number;
replyContent: string,
replyTime: string,
};
interface OrderInfo {
orderNo: string,
dealTime: string,
memberName: string,
};
const ReceivedDetail: React.FC = () => {
const { id } = usePageStatus();
const [orderInfo, setOrderInfo] = useState<OrderInfo>(null);
const [evaluationInfo, setEvaluationInfo] = useState<Unevaluated>(null);
const [evaluationInfoLoading, setEvaluationInfoLoading] = useState(false);
const getEvaluationInfo = () => {
if (!id) {
return;
}
setEvaluationInfoLoading(true);
getMemberCommentSupplyReceiveTradeHistoryGet({
id,
}).then(res => {
if (res.code === 1000) {
const { product } = res.data;
setEvaluationInfo({
good: {
pic: res.data.productImgUrl,
productName: res.data.product,
price: res.data.price,
purchaseCount: res.data.purchaseCount,
unit: res.data.unit,
},
star: res.data.star,
comment: res.data.comment,
picture: res.data.pics ? res.data.pics.map(item => normalizeFiledata(item)) : [],
smile: res.data.star,
replyContent: res.data.replyContent,
replyTime: res.data.replyTime,
});
setOrderInfo({
orderNo: res.data.orderNo,
dealTime: res.data.dealTime as string,
memberName: res.data.memberName,
});
}
}).catch((err) => {
console.warn(err);
}).finally(() => {
setEvaluationInfoLoading(false);
});
};
useEffect(() => {
getEvaluationInfo();
}, []);
const handleSubmit = values => {
};
const beforeUpload = file => {
if (file.size / 1024 / 1024 > 10) {
message.warning('图片大小超过10M');
return Upload.LIST_IGNORE;
}
return Promise.resolve();
};
const UploadTip = (
<span
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
top: '34px',
}}
>
支持JPG/PNG/JPEG <br />每张最大不超过 10M,尺寸不限 <br />最大数量限制 4张
</span>
);
return (
<Spin spinning={evaluationInfoLoading}>
<PageHeaderWrapper
style={{
padding: 24,
}}
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: orderInfo?.orderNo,
}}
/>
}
extra={(
<>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="采购会员">{orderInfo?.memberName}</Descriptions.Item>
<Descriptions.Item label="下单时间" span={2}>
{orderInfo?.dealTime}
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<NiceForm
actions={formActions}
previewPlaceholder=" "
initialValues={{
comments: [evaluationInfo],
}}
editable={false}
expressionScope={{
UploadTip: null,
beforeUpload,
}}
onSubmit={handleSubmit}
components={{
EvaluationList,
}}
effects={($, actions) => {
createEffects($, actions);
}}
schema={createSchema()}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default ReceivedDetail;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import {
PageHeader,
Descriptions,
Spin,
message,
Upload,
} from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { getIntl, history } from 'umi';
import { createFormActions } from '@formily/antd';
import { usePageStatus } from '@/hooks/usePageStatus';
import { getMemberCommentSupplyReceiveTradeHistoryGet } from '@/services/MemberV2Api';
import { normalizeFiledata, FileData } from '@/utils';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import createSchema from '../../../purchaserEvaluation/common/schemas/receivedSchema';
import { createEffects } from '../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../purchaserEvaluation/components/EvaluationList';
const formActions = createFormActions();
const intl = getIntl();
interface Unevaluated {
good: {
pic: string,
productName: string,
price: number,
purchaseCount: number,
unit: string,
};
star: number;
comment: string;
picture: FileData[];
smile: number;
replyContent: string,
replyTime: string,
};
interface OrderInfo {
orderNo: string,
dealTime: string,
memberName: string,
};
const ReceivedDetail: React.FC = () => {
const { id } = usePageStatus();
const [orderInfo, setOrderInfo] = useState<OrderInfo>(null);
const [evaluationInfo, setEvaluationInfo] = useState<Unevaluated>(null);
const [evaluationInfoLoading, setEvaluationInfoLoading] = useState(false);
const getEvaluationInfo = () => {
if (!id) {
return;
}
setEvaluationInfoLoading(true);
getMemberCommentSupplyReceiveTradeHistoryGet({
id,
}).then(res => {
if (res.code === 1000) {
const { product } = res.data;
setEvaluationInfo({
good: {
pic: res.data.productImgUrl,
productName: res.data.product,
price: res.data.price,
purchaseCount: res.data.purchaseCount,
unit: res.data.unit,
},
star: res.data.star,
comment: res.data.comment,
picture: res.data.pics ? res.data.pics.map(item => normalizeFiledata(item)) : [],
smile: res.data.star,
replyContent: res.data.replyContent,
replyTime: res.data.replyTime,
});
setOrderInfo({
orderNo: res.data.orderNo,
dealTime: res.data.dealTime as string,
memberName: res.data.memberName,
});
}
}).catch((err) => {
console.warn(err);
}).finally(() => {
setEvaluationInfoLoading(false);
});
};
useEffect(() => {
getEvaluationInfo();
}, []);
const handleSubmit = values => {
};
const beforeUpload = file => {
if (file.size / 1024 / 1024 > 10) {
message.warning(intl.formatMessage({id: 'supplierEvaluation.tupiandaxiaochaoguo10M'}));
return Upload.LIST_IGNORE;
}
return Promise.resolve();
};
const UploadTip = (
<span
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
top: '34px',
}}
>
{intl.formatMessage({id: 'supplierEvaluation.zhichiJPGPNGJPEG'})} <br />{intl.formatMessage({id: 'supplierEvaluation.meizhangzuidabuchaoguo'})} <br />{intl.formatMessage({id: 'supplierEvaluation.zuidashuliangxianzhi4'})}
</span>
);
return (
<Spin spinning={evaluationInfoLoading}>
<PageHeaderWrapper
style={{
padding: 24,
}}
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: intl.formatMessage({id: 'supplierEvaluation.dan'}),
name: orderInfo?.orderNo,
}}
/>
}
extra={(
<>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label={intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'})}>{orderInfo?.memberName}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'})} span={2}>
{orderInfo?.dealTime}
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<NiceForm
actions={formActions}
previewPlaceholder=" "
initialValues={{
comments: [evaluationInfo],
}}
editable={false}
expressionScope={{
UploadTip: null,
beforeUpload,
}}
onSubmit={handleSubmit}
components={{
EvaluationList,
}}
effects={($, actions) => {
createEffects($, actions);
}}
schema={createSchema()}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default ReceivedDetail;
import React, { useState, useEffect } from 'react';
import {
PageHeader,
Descriptions,
Spin,
Button,
message,
Upload,
} from 'antd';
import { FormOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history } from 'umi';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { getMemberCommentSupplySendTradeHistoryGet, postMemberCommentSupplySendTradeHistoryUpdate } from '@/services/MemberV2Api';
import { normalizeFiledata, FileData } from '@/utils';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { evaluateSchema } from '../../../../purchaserEvaluation/common/schemas/evaluateSchema';
import { createEffects } from '../../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../../purchaserEvaluation/components/EvaluationList';
const formActions = createFormActions();
const {
onFormInit$,
} = FormEffectHooks;
interface Unevaluated {
good: {
pic: string,
productName: string,
price: number,
purchaseCount: number,
unit: string,
};
star: number;
comment: string;
picture: FileData[];
smile: number;
};
interface OrderInfo {
orderNo: string,
dealTime: string,
memberName: string,
};
interface DetailInfoProps {
orderId: string;
// 评论id
id: string;
// 是否可编辑的
isEdit?: boolean;
};
const DetailInfo: React.FC<DetailInfoProps> = ({
id,
isEdit = false,
}) => {
const [orderInfo, setOrderInfo] = useState<OrderInfo>(null);
const [evaluationInfo, setEvaluationInfo] = useState<Unevaluated>(null);
const [evaluationInfoLoading, setEvaluationInfoLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const getEvaluationInfo = () => {
if (!id) {
return;
}
setEvaluationInfoLoading(true);
getMemberCommentSupplySendTradeHistoryGet({
id,
}).then(res => {
if (res.code === 1000) {
setEvaluationInfo({
good: {
pic: res.data.productImgUrl,
productName: res.data.product,
price: res.data.price,
purchaseCount: res.data.purchaseCount,
unit: res.data.unit,
},
star: res.data.star,
comment: res.data.comment,
picture: res.data.pics ? res.data.pics.map(item => normalizeFiledata(item)) : [],
smile: res.data.star,
});
setOrderInfo({
orderNo: res.data.orderNo,
dealTime: res.data.dealTime as string,
memberName: res.data.memberName,
});
}
}).catch((err) => {
console.warn(err);
}).finally(() => {
setEvaluationInfoLoading(false);
});
};
useEffect(() => {
getEvaluationInfo();
}, []);
const handleSubmit = values => {
setSubmitLoading(true);
const payload = values.comments.map(item => {
const {
comment,
picture,
star,
} = item;
return {
id,
star,
comment,
pics: picture.map(item => item.status === 'done' && item.url).filter(Boolean),
};
});
if (!payload.length) {
return;
}
postMemberCommentSupplySendTradeHistoryUpdate(payload[0])
.then(res => {
if (res.code === 1000) {
setTimeout(() => {
history.goBack();
}, 800);
} else {
setSubmitLoading(false);
}
})
.catch(() => {
setSubmitLoading(false);
});
};
const beforeUpload = file => {
if (file.size / 1024 / 1024 > 10) {
message.warning('图片大小超过10M');
return Upload.LIST_IGNORE;
}
return Promise.resolve();
};
const UploadTip = () => (
<div
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
}}
>
支持JPG/PNG/JPEG <br />每张最大不超过 10M,尺寸不限 <br />最大数量限制 4张
</div>
);
return (
<Spin spinning={evaluationInfoLoading}>
<PageHeaderWrapper
style={{
padding: 24,
}}
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: orderInfo?.orderNo,
}}
/>
}
extra={(
<>
{
isEdit && (
<Button
type="primary"
icon={<FormOutlined />}
disabled={!id}
loading={submitLoading}
onClick={() => formActions.submit()}
>
修改
</Button>
)
}
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="采购会员">
{orderInfo?.memberName}
</Descriptions.Item>
<Descriptions.Item label="下单时间" span={2}>
{orderInfo?.dealTime}
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<NiceForm
actions={formActions}
previewPlaceholder=" "
initialValues={{
comments: [evaluationInfo],
}}
editable={isEdit}
expressionScope={{
beforeUpload,
}}
components={{
EvaluationList,
UploadTip,
}}
onSubmit={handleSubmit}
effects={($, actions) => {
createEffects($, actions);
onFormInit$().subscribe(() => {
// 控制不同样式
if (!isEdit) {
actions.setFieldState('comments.*.MEGA_LADYOUT_1', (fieldState) => {
fieldState.props['x-component-props'] = {
...(fieldState.props['x-component-props'] || {}),
labelCol: 6,
};
});
actions.setFieldState('comments.*.UPLOAD_TIP', (fieldState) => {
fieldState.visible = false;
});
actions.setFieldState('comments.*.picture', (fieldState) => {
fieldState.props['x-mega-props'] = {
...(fieldState.props['x-mega-props'] || {}),
span: 3,
};
});
}
});
}}
schema={evaluateSchema}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default DetailInfo;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import {
PageHeader,
Descriptions,
Spin,
Button,
message,
Upload,
} from 'antd';
import { FormOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { getIntl, history } from 'umi';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { getMemberCommentSupplySendTradeHistoryGet, postMemberCommentSupplySendTradeHistoryUpdate } from '@/services/MemberV2Api';
import { normalizeFiledata, FileData } from '@/utils';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { evaluateSchema } from '../../../../purchaserEvaluation/common/schemas/evaluateSchema';
import { createEffects } from '../../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../../purchaserEvaluation/components/EvaluationList';
const formActions = createFormActions();
const {
onFormInit$,
} = FormEffectHooks;
const intl = getIntl();
interface Unevaluated {
good: {
pic: string,
productName: string,
price: number,
purchaseCount: number,
unit: string,
};
star: number;
comment: string;
picture: FileData[];
smile: number;
};
interface OrderInfo {
orderNo: string,
dealTime: string,
memberName: string,
};
interface DetailInfoProps {
orderId: string;
// 评论id
id: string;
// 是否可编辑的
isEdit?: boolean;
};
const DetailInfo: React.FC<DetailInfoProps> = ({
id,
isEdit = false,
}) => {
const [orderInfo, setOrderInfo] = useState<OrderInfo>(null);
const [evaluationInfo, setEvaluationInfo] = useState<Unevaluated>(null);
const [evaluationInfoLoading, setEvaluationInfoLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const getEvaluationInfo = () => {
if (!id) {
return;
}
setEvaluationInfoLoading(true);
getMemberCommentSupplySendTradeHistoryGet({
id,
}).then(res => {
if (res.code === 1000) {
setEvaluationInfo({
good: {
pic: res.data.productImgUrl,
productName: res.data.product,
price: res.data.price,
purchaseCount: res.data.purchaseCount,
unit: res.data.unit,
},
star: res.data.star,
comment: res.data.comment,
picture: res.data.pics ? res.data.pics.map(item => normalizeFiledata(item)) : [],
smile: res.data.star,
});
setOrderInfo({
orderNo: res.data.orderNo,
dealTime: res.data.dealTime as string,
memberName: res.data.memberName,
});
}
}).catch((err) => {
console.warn(err);
}).finally(() => {
setEvaluationInfoLoading(false);
});
};
useEffect(() => {
getEvaluationInfo();
}, []);
const handleSubmit = values => {
setSubmitLoading(true);
const payload = values.comments.map(item => {
const {
comment,
picture,
star,
} = item;
return {
id,
star,
comment,
pics: picture.map(item => item.status === 'done' && item.url).filter(Boolean),
};
});
if (!payload.length) {
return;
}
postMemberCommentSupplySendTradeHistoryUpdate(payload[0])
.then(res => {
if (res.code === 1000) {
setTimeout(() => {
history.goBack();
}, 800);
} else {
setSubmitLoading(false);
}
})
.catch(() => {
setSubmitLoading(false);
});
};
const beforeUpload = file => {
if (file.size / 1024 / 1024 > 10) {
message.warning(intl.formatMessage({id: 'supplierEvaluation.tupiandaxiaochaoguo10M'}));
return Upload.LIST_IGNORE;
}
return Promise.resolve();
};
const UploadTip = () => (
<div
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
}}
>
{intl.formatMessage({id: 'supplierEvaluation.zhichiJPGPNGJPEG'})} <br />{intl.formatMessage({id: 'supplierEvaluation.meizhangzuidabuchaoguo'})} <br />{intl.formatMessage({id: 'supplierEvaluation.zuidashuliangxianzhi4'})}
</div>
);
return (
<Spin spinning={evaluationInfoLoading}>
<PageHeaderWrapper
style={{
padding: 24,
}}
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: intl.formatMessage({id: 'supplierEvaluation.dan'}),
name: orderInfo?.orderNo,
}}
/>
}
extra={(
<>
{
isEdit && (
<Button
type="primary"
icon={<FormOutlined />}
disabled={!id}
loading={submitLoading}
onClick={() => formActions.submit()}
>
{intl.formatMessage({id: 'supplierEvaluation.xiugai'})}
</Button>
)
}
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label={intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'})}>
{orderInfo?.memberName}
</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'})} span={2}>
{orderInfo?.dealTime}
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<NiceForm
actions={formActions}
previewPlaceholder=" "
initialValues={{
comments: [evaluationInfo],
}}
editable={isEdit}
expressionScope={{
beforeUpload,
}}
components={{
EvaluationList,
UploadTip,
}}
onSubmit={handleSubmit}
effects={($, actions) => {
createEffects($, actions);
onFormInit$().subscribe(() => {
// 控制不同样式
if (!isEdit) {
actions.setFieldState('comments.*.MEGA_LADYOUT_1', (fieldState) => {
fieldState.props['x-component-props'] = {
...(fieldState.props['x-component-props'] || {}),
labelCol: 6,
};
});
actions.setFieldState('comments.*.UPLOAD_TIP', (fieldState) => {
fieldState.visible = false;
});
actions.setFieldState('comments.*.picture', (fieldState) => {
fieldState.props['x-mega-props'] = {
...(fieldState.props['x-mega-props'] || {}),
span: 3,
};
});
}
});
}}
schema={evaluateSchema}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default DetailInfo;
import React, { useState, useEffect } from 'react';
import {
PageHeader,
Descriptions,
Spin,
Button,
message,
Upload,
} from 'antd';
import { FormOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history, Prompt } from 'umi';
import moment from 'moment';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { usePageStatus } from '@/hooks/usePageStatus';
import { getMemberCommentSupplyOrderTradeDetail, GetMemberCommentSupplyOrderTradeDetailResponse, postMemberCommentSupplyOrderTradeSubmit } from '@/services/MemberV2Api';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { normalizeUnevaluatedList } from '../../../purchaserEvaluation/utils';
import { evaluateSchema } from '../../../purchaserEvaluation/common/schemas/evaluateSchema';
import { createEffects } from '../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../purchaserEvaluation/components/EvaluationList';
const formActions = createFormActions();
const {
onFormInputChange$,
} = FormEffectHooks;
interface Unevaluated {
good: {
pic: string,
name: string,
price: string,
desc: string,
};
star: number;
comment: string;
picture: string[];
smile: number;
};
interface OrderInfo extends GetMemberCommentSupplyOrderTradeDetailResponse {
unevaluatedList: Unevaluated[];
};
const EvaluateOrder: React.FC = () => {
const { id } = usePageStatus();
const [orderInfo, setOrderInfo] = useState<OrderInfo>(null);
const [infoLoading, setInfoLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const getOrderInfo = () => {
if (!id) {
return;
}
setInfoLoading(true);
getMemberCommentSupplyOrderTradeDetail({
id,
}).then(res => {
if (res.code === 1000) {
const { orderProductCommentList } = res.data;
const unevaluatedList = normalizeUnevaluatedList(orderProductCommentList);
setOrderInfo({
...res.data,
unevaluatedList,
});
unevaluatedList.forEach((item, index) => {
if (item.commentStatus) {
formActions.setFieldState(`comments.${index}.*`, (fieldState) => {
fieldState.editable = false;
});
}
});
}
}).finally(() => {
setInfoLoading(false);
});
};
useEffect(() => {
getOrderInfo();
}, []);
const handleSubmit = values => {
setSubmitLoading(true);
const payload = values.comments.map(item => {
const {
comment,
good,
picture,
star,
} = item;
// 被评价方是 采购会员(订单创建者数据)
return {
star,
comment,
orderProductId: good.orderProductId,
pics: picture.map(item => item.status === 'done' && item.url).filter(Boolean),
};
});
postMemberCommentSupplyOrderTradeSubmit({
orderId: orderInfo.orderId,
commentSubmitDetailList: payload,
}).then(res => {
if (res.code === 1000) {
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
} else {
setSubmitLoading(false);
}
}).catch(() => {
setSubmitLoading(false);
});
};
const beforeUpload = file => {
if (file.size / 1024 / 1024 > 10) {
message.warning('图片大小超过10M');
return Upload.LIST_IGNORE;
}
return Promise.resolve();
};
const UploadTip = () => (
<div
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
}}
>
支持JPG/PNG/JPEG <br />每张最大不超过 10M,尺寸不限 <br />最大数量限制 4张
</div>
);
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
style={{
padding: 24,
}}
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: orderInfo?.orderNo,
}}
/>
}
extra={(
<>
<Button
type="primary"
icon={<FormOutlined />}
disabled={!orderInfo}
loading={submitLoading}
onClick={() => formActions.submit()}
>
发布
</Button>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="采购会员">{orderInfo?.memberName}</Descriptions.Item>
<Descriptions.Item label="下单时间" span={2}>
{orderInfo?.createTime}
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<NiceForm
actions={formActions}
previewPlaceholder=" "
initialValues={{
comments: orderInfo ? orderInfo.unevaluatedList : [],
}}
expressionScope={{
beforeUpload,
}}
onSubmit={handleSubmit}
components={{
EvaluationList,
UploadTip,
}}
effects={($, actions) => {
createEffects($, actions);
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={evaluateSchema}
/>
</PageHeaderWrapper>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</Spin>
);
};
export default EvaluateOrder;
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import {
PageHeader,
Descriptions,
Spin,
Button,
message,
Upload,
} from 'antd';
import { FormOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { getIntl, history, Prompt } from 'umi';
import moment from 'moment';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { usePageStatus } from '@/hooks/usePageStatus';
import { getMemberCommentSupplyOrderTradeDetail, GetMemberCommentSupplyOrderTradeDetailResponse, postMemberCommentSupplyOrderTradeSubmit } from '@/services/MemberV2Api';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { normalizeUnevaluatedList } from '../../../purchaserEvaluation/utils';
import { evaluateSchema } from '../../../purchaserEvaluation/common/schemas/evaluateSchema';
import { createEffects } from '../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../purchaserEvaluation/components/EvaluationList';
const formActions = createFormActions();
const {
onFormInputChange$,
} = FormEffectHooks;
const intl = getIntl();
interface Unevaluated {
good: {
pic: string,
name: string,
price: string,
desc: string,
};
star: number;
comment: string;
picture: string[];
smile: number;
};
interface OrderInfo extends GetMemberCommentSupplyOrderTradeDetailResponse {
unevaluatedList: Unevaluated[];
};
const EvaluateOrder: React.FC = () => {
const { id } = usePageStatus();
const [orderInfo, setOrderInfo] = useState<OrderInfo>(null);
const [infoLoading, setInfoLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const getOrderInfo = () => {
if (!id) {
return;
}
setInfoLoading(true);
getMemberCommentSupplyOrderTradeDetail({
id,
}).then(res => {
if (res.code === 1000) {
const { orderProductCommentList } = res.data;
const unevaluatedList = normalizeUnevaluatedList(orderProductCommentList);
setOrderInfo({
...res.data,
unevaluatedList,
});
unevaluatedList.forEach((item, index) => {
if (item.commentStatus) {
formActions.setFieldState(`comments.${index}.*`, (fieldState) => {
fieldState.editable = false;
});
}
});
}
}).finally(() => {
setInfoLoading(false);
});
};
useEffect(() => {
getOrderInfo();
}, []);
const handleSubmit = values => {
setSubmitLoading(true);
const payload = values.comments.map(item => {
const {
comment,
good,
picture,
star,
} = item;
// 被评价方是 采购会员(订单创建者数据)
return {
star,
comment,
orderProductId: good.orderProductId,
pics: picture.map(item => item.status === 'done' && item.url).filter(Boolean),
};
});
postMemberCommentSupplyOrderTradeSubmit({
orderId: orderInfo.orderId,
commentSubmitDetailList: payload,
}).then(res => {
if (res.code === 1000) {
setUnsaved(false);
setTimeout(() => {
history.goBack();
}, 800);
} else {
setSubmitLoading(false);
}
}).catch(() => {
setSubmitLoading(false);
});
};
const beforeUpload = file => {
if (file.size / 1024 / 1024 > 10) {
message.warning(intl.formatMessage({id: 'supplierEvaluation.tupiandaxiaochaoguo10M'}));
return Upload.LIST_IGNORE;
}
return Promise.resolve();
};
const UploadTip = () => (
<div
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
}}
>
{intl.formatMessage({id: 'supplierEvaluation.zhichiJPGPNGJPEG'})} <br />{intl.formatMessage({id: 'supplierEvaluation.meizhangzuidabuchaoguo'})} <br />{intl.formatMessage({id: 'supplierEvaluation.zuidashuliangxianzhi4'})}
</div>
);
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
style={{
padding: 24,
}}
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: intl.formatMessage({id: 'supplierEvaluation.dan'}),
name: orderInfo?.orderNo,
}}
/>
}
extra={(
<>
<Button
type="primary"
icon={<FormOutlined />}
disabled={!orderInfo}
loading={submitLoading}
onClick={() => formActions.submit()}
>
{intl.formatMessage({id: 'supplierEvaluation.fabu'})}
</Button>
</>
)}
>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label={intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'})}>{orderInfo?.memberName}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'})} span={2}>
{orderInfo?.createTime}
</Descriptions.Item>
</Descriptions>
</PageHeader>
</>
}
>
<NiceForm
actions={formActions}
previewPlaceholder=" "
initialValues={{
comments: orderInfo ? orderInfo.unevaluatedList : [],
}}
expressionScope={{
beforeUpload,
}}
onSubmit={handleSubmit}
components={{
EvaluationList,
UploadTip,
}}
effects={($, actions) => {
createEffects($, actions);
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={evaluateSchema}
/>
</PageHeaderWrapper>
<Prompt when={unsaved} message={intl.formatMessage({id: 'supplierEvaluation.ninhaiyouweibaocunde'})} />
</Spin>
);
};
export default EvaluateOrder;
import React, { useState, useRef } from 'react';
import { Card, Badge, Button } from 'antd';
import { Link } from 'umi';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { createFormActions } from '@formily/antd';
import moment from 'moment';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { getMemberOrderCommentVendorPage } from '@/services/MemberV2Api';
import EyePreview from '@/components/EyePreview';
import NiceForm from '@/components/NiceForm';
import StatusTag from '@/components/StatusTag';
import { listSearchSchema } from './schema';
import styles from './index.less';
const formActions = createFormActions();
const Unevaluated: React.FC = () => {
const ref = useRef<any>({});
const defaultColumns: ColumnType<any>[] = [
{
title: '订单号',
dataIndex: 'orderNo',
align: 'center',
render: (text, record) => (
<EyePreview
url={`/memberCenter/tranactionAbility/supplierEvaluation/unevaluated/order?id=${record.id}`}
>
{text}
</EyePreview>
),
},
{
title: '订单摘要',
dataIndex: 'digest',
align: 'center',
ellipsis: true,
},
{
title: '采购会员',
dataIndex: 'memberName',
align: 'center',
render: (text, record) => <>{text}</>,
},
{
title: '下单时间',
dataIndex: 'createTime',
align: 'center',
},
{
title: '订单总额',
dataIndex: 'totalAmount',
align: 'center',
render: (text) => ${text}`,
},
{
title: '订单类型',
dataIndex: 'orderTypeName',
align: 'center',
},
{
title: '外部状态',
dataIndex: 'outerStatusName',
align: 'center',
render: (text, record) => (
<StatusTag type="success" title="已完成" />
),
},
{
title: '内部状态',
dataIndex: 'innerStatusName',
align: 'center',
render: (text, record) => <Badge color="#41CC9E" text="已完成" />,
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (text, record) => (
<>
<Link to={`/memberCenter/tranactionAbility/supplierEvaluation/unevaluated/evaluate?id=${record.id}`}>
{!record.completeCommentStatus && (
<Button
type="link"
>
评价
</Button>
)}
</Link>
</>
),
},
];
const [columns, setColumns] = useState<any[]>(defaultColumns);
const fetchListData = (params: any) => {
let { createTimeStart, createTimeEnd , ...rest } = params;
createTimeStart = createTimeStart ? moment(+createTimeStart).format('YYYY-MM-DD HH:mm:ss') : undefined;
createTimeEnd = createTimeEnd ? moment(+createTimeEnd).format('YYYY-MM-DD HH:mm:ss') : undefined;
return new Promise((resolve, reject) => {
getMemberOrderCommentVendorPage({
createTimeStart,
createTimeEnd,
...rest
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
})
.catch(() => {
reject();
});
});
};
return (
<PageHeaderWrapper>
<Card>
<StandardTable
tableProps={{
rowKey: 'orderNo',
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchListData(params)}
controlRender={
<NiceForm
actions={formActions}
onSubmit={values => ref.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'orderNo',
FORM_FILTER_PATH,
);
}}
schema={listSearchSchema}
/>
}
/>
</Card>
</PageHeaderWrapper>
);
};
export default Unevaluated;
import React, { useState, useRef } from 'react';
import { Card, Badge, Button } from 'antd';
import { getIntl, Link } from 'umi';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { createFormActions } from '@formily/antd';
import moment from 'moment';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { getMemberOrderCommentVendorPage } from '@/services/MemberV2Api';
import EyePreview from '@/components/EyePreview';
import NiceForm from '@/components/NiceForm';
import StatusTag from '@/components/StatusTag';
import { listSearchSchema } from './schema';
import styles from './index.less';
const formActions = createFormActions();
const intl = getIntl();
const Unevaluated: React.FC = () => {
const ref = useRef<any>({});
const defaultColumns: ColumnType<any>[] = [
{
title: intl.formatMessage({id: 'supplierEvaluation.dingdanhao'}),
dataIndex: 'orderNo',
align: 'center',
render: (text, record) => (
<EyePreview
url={`/memberCenter/tranactionAbility/supplierEvaluation/unevaluated/order?id=${record.id}`}
>
{text}
</EyePreview>
),
},
{
title: intl.formatMessage({id: 'supplierEvaluation.dingdanzhaiyao'}),
dataIndex: 'digest',
align: 'center',
ellipsis: true,
},
{
title: intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'}),
dataIndex: 'memberName',
align: 'center',
render: (text, record) => <>{text}</>,
},
{
title: intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'}),
dataIndex: 'createTime',
align: 'center',
},
{
title: intl.formatMessage({id: 'supplierEvaluation.dingdanzonge'}),
dataIndex: 'totalAmount',
align: 'center',
render: (text) => ${text}`,
},
{
title: intl.formatMessage({id: 'supplierEvaluation.dingdanleixing'}),
dataIndex: 'orderTypeName',
align: 'center',
},
{
title: intl.formatMessage({id: 'supplierEvaluation.waibuzhuangtai'}),
dataIndex: 'outerStatusName',
align: 'center',
render: (text, record) => (
<StatusTag type="success" title={intl.formatMessage({id: 'supplierEvaluation.yiwancheng'})} />
),
},
{
title: intl.formatMessage({id: 'supplierEvaluation.neibuzhuangtai'}),
dataIndex: 'innerStatusName',
align: 'center',
render: (text, record) => <Badge color="#41CC9E" text={intl.formatMessage({id: 'supplierEvaluation.yiwancheng'})} />,
},
{
title: intl.formatMessage({id: 'supplierEvaluation.caozuo'}),
dataIndex: 'option',
align: 'center',
render: (text, record) => (
<>
<Link to={`/memberCenter/tranactionAbility/supplierEvaluation/unevaluated/evaluate?id=${record.id}`}>
{!record.completeCommentStatus && (
<Button
type="link"
>
{intl.formatMessage({id: 'supplierEvaluation.pingjia'})}
</Button>
)}
</Link>
</>
),
},
];
const [columns, setColumns] = useState<any[]>(defaultColumns);
const fetchListData = (params: any) => {
let { createTimeStart, createTimeEnd , ...rest } = params;
createTimeStart = createTimeStart ? moment(+createTimeStart).format('YYYY-MM-DD HH:mm:ss') : undefined;
createTimeEnd = createTimeEnd ? moment(+createTimeEnd).format('YYYY-MM-DD HH:mm:ss') : undefined;
return new Promise((resolve, reject) => {
getMemberOrderCommentVendorPage({
createTimeStart,
createTimeEnd,
...rest
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
})
.catch(() => {
reject();
});
});
};
return (
<PageHeaderWrapper>
<Card>
<StandardTable
tableProps={{
rowKey: 'orderNo',
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchListData(params)}
controlRender={
<NiceForm
actions={formActions}
onSubmit={values => ref.current.reload(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'orderNo',
FORM_FILTER_PATH,
);
}}
schema={listSearchSchema}
/>
}
/>
</Card>
</PageHeaderWrapper>
);
};
export default Unevaluated;
/*
* @Author: XieZhiXiong
* @Date: 2021-01-06 11:36:35
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 14:03:15
* @Description:
*/
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
const orderTypeArr = GlobalConfig.web.orderType.map((item) => ({
label: item.platformWayName,
value: item.id,
}));
export const listSearchSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
orderNo: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
tip: '输入 订单号 进行搜索',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
digest: {
type: 'string',
'x-component-props': {
placeholder: '订单摘要',
allowClear: true,
},
},
memberName: {
type: 'string',
default: undefined,
'x-component-props': {
placeholder: '采购会员',
allowClear: true,
},
},
'[createTimeStart, createTimeEnd]': {
type: 'string',
default: '',
'x-component': 'dateSelect',
'x-component-props': {
placeholder: '下单时间',
allowClear: true,
},
},
orderType: {
type: 'string',
default: undefined,
enum: orderTypeArr,
'x-component-props': {
placeholder: '订单类型',
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2021-01-06 11:36:35
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 14:03:15
* @Description:
*/
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { GlobalConfig } from '@/global/config';
import { getIntl } from 'umi';
const intl = getIntl();
const orderTypeArr = GlobalConfig.web.orderType.map((item) => ({
label: item.platformWayName,
value: item.id,
}));
export const listSearchSchema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
orderNo: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.sousuo'}),
align: 'flex-left',
tip: intl.formatMessage({id: 'supplierEvaluation.shurudingdanhao'}),
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
autoRow: true,
columns: 6,
},
properties: {
digest: {
type: 'string',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanzhaiyao'}),
allowClear: true,
},
},
memberName: {
type: 'string',
default: undefined,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.caigouhuiyuan'}),
allowClear: true,
},
},
'[createTimeStart, createTimeEnd]': {
type: 'string',
default: '',
'x-component': 'dateSelect',
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.xiadanshijian'}),
allowClear: true,
},
},
orderType: {
type: 'string',
default: undefined,
enum: orderTypeArr,
'x-component-props': {
placeholder: intl.formatMessage({id: 'supplierEvaluation.dingdanleixing'}),
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: intl.formatMessage({id: 'supplierEvaluation.chaxun'}),
},
},
},
},
},
},
},
};
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