Commit 78aa9b7a authored by XieZhiXiong's avatar XieZhiXiong

feat: 添加供应商评论解释相关

parent efa6be34
......@@ -56,7 +56,7 @@ export const evaluateSchema: ISchema = {
max: 200,
},
},
MEGA_LADYOUT: {
MEGA_LADYOUT_1: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
......
/*
* @Author: XieZhiXiong
* @Date: 2021-08-11 14:04:22
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-11 15:01:48
* @Description: 收到的评价详情 schema
*/
import { ISchema } from '@formily/antd';
import { UPLOAD_TYPE } from '@/constants';
/**
*
* @param showExplain 是否需要展示解释, 默认为 true
* @returns
*/
const createSchema = (showExplain = true): ISchema => ({
type: 'object',
properties: {
comments: {
type: 'array',
'x-component': 'EvaluationList',
default: [],
items: {
type: 'object',
properties: {
LEFT_RIGHT: {
type: 'object',
'x-component': 'LeftRightLayout',
'x-component-props': {
rightProps: {
span: 2,
offset: 4,
},
},
properties: {
MEGA_LADYOUT: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
labelCol: 6,
labelAlign: 'left',
position: 'left',
},
properties: {
star: {
title: '满意程度',
'x-component': 'Rating',
'x-component-props': {
allowHalf: false,
allowClear: false,
},
},
comment: {
type: 'string',
title: '评价',
'x-component': 'TextArea',
'x-component-props': {
rows: 4,
},
'x-rules': {
max: 200,
},
},
picture: {
type: 'string',
title: '图片',
'x-component': 'FixUpload',
'x-mega-props': {
span: 2,
},
'x-component-props': {
listType: 'card',
action: '/api/file/file/upload/prefix',
data: {
fileType: UPLOAD_TYPE,
prefix: '',
},
beforeUpload: '{{beforeUpload}}',
accept: '.png, .jpg, .jpeg',
},
'x-rules': [
{
max: 4,
message: '最多可上传4张图片',
},
],
},
...(showExplain ? {
replayTime: {
type: 'string',
title: '商家时间',
},
replayContent: {
type: 'string',
title: '商家解释',
},
} : {}),
},
},
smile: {
type: 'object',
'x-component': 'SmilingFace',
'x-component-props': {
position: 'right',
},
},
},
},
},
},
},
},
});
export default createSchema;
......@@ -81,6 +81,10 @@ export interface RecordItem {
* 订单id
*/
orderId: number
/**
* 是否已解释,被评价方回复 0-否 1-是
*/
replayStatus?: number,
};
export interface RecordRes {
......@@ -89,16 +93,24 @@ export interface RecordRes {
};
interface RecordListProps {
// 分页器类型
/**
* 分页器类型
*/
paginationType?: 'pagination' | 'button';
// 是否需要检索
/**
* 是否需要检索
*/
searchable?: boolean;
// 是否是查看收到的品论
/**
* 是否是查看收到的评论
*/
opposite?: boolean;
// 是否可编辑的
/**
* 是否可编辑的
*/
editable?: boolean;
fetchList: (params: ListParams) => Promise<RecordRes>;
......@@ -107,8 +119,20 @@ interface RecordListProps {
onEdit?: (record: RecordItem) => void;
// 搜索框提示语
/**
* 搜索框提示语
*/
searchTip?: string;
/**
* 是否显示解释按钮,默认 false
*/
explicable?: boolean;
/**
* 点击解释触发事件
*/
onExplain?: (record: RecordItem) => void;
};
interface RecordListState {
......@@ -175,6 +199,24 @@ export default class RecordList extends React.Component<RecordListProps, RecordL
});
};
// 重新加载列表
refresh = () => {
this.setState({
receivedList: {
data: [],
totalCount: 0,
},
}, () => {
const { page, size } = this.state;
this.getRecordList().then(res => {
this.setState({
receivedList: res,
hasMore: checkMore(page, size, res.data.length, res.totalCount),
});
});
});
};
// 查询列表
handleSearch = values => {
this.setState({
......@@ -244,14 +286,22 @@ export default class RecordList extends React.Component<RecordListProps, RecordL
onEdit(record);
}
};
handleExplain = record => {
const { onExplain } = this.props;
if (onExplain) {
onExplain(record);
}
};
render() {
const {
paginationType = 'pagination',
searchable = true,
opposite = true,
editable = false,
searchTip = '评价方',
paginationType = 'pagination',
searchable = true,
opposite = true,
editable = false,
searchTip = '评价方',
explicable = false,
} = this.props;
const { page, size, loading, receivedList, hasMore } = this.state;
......@@ -322,6 +372,9 @@ export default class RecordList extends React.Component<RecordListProps, RecordL
{editable && (
<Button type="link" onClick={() => this.handleEdit(item)}>编辑</Button>
)}
{explicable && item.replayStatus === 0 && (
<Button type="link" onClick={() => this.handleExplain(item)}>解释</Button>
)}
<Button type="link" onClick={() => this.handleCheck(item)}>查看</Button>
</div>
</li>
......
......@@ -14,7 +14,7 @@ import { PublicApi } from '@/services/api';
import { normalizeFiledata, FileData } from '@/utils';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { evaluateSchema } from '../../common/schemas/evaluateSchema';
import createSchema from '../../common/schemas/receivedSchema';
import { createEffects } from '../../common/effects';
import EvaluationList from '../../components/EvaluationList';
......@@ -171,7 +171,7 @@ const ReceivedDetail: React.FC = () => {
effects={($, actions) => {
createEffects($, actions);
}}
schema={evaluateSchema}
schema={createSchema(false)}
/>
</PageHeaderWrapper>
</Spin>
......
......@@ -21,7 +21,7 @@ import EvaluationList from '../../../components/EvaluationList';
const formActions = createFormActions();
const {
onFormInit$,
onFormInit$,
} = FormEffectHooks;
interface Unevaluated {
......@@ -144,19 +144,18 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
return Promise.resolve();
};
const UploadTip = (
<span
const UploadTip = () => (
<div
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
top: '34px',
}}
>
支持JPG/PNG/JPEG <br />每张最大不超过 10M,尺寸不限 <br />最大数量限制 4张
</span>
</div>
);
return (
......@@ -220,15 +219,36 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
}}
editable={isEdit}
expressionScope={{
UploadTip: isEdit ? UploadTip : null,
beforeUpload,
}}
onSubmit={handleSubmit}
components={{
EvaluationList,
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}
/>
......
/*
* @Author: XieZhiXiong
* @Date: 2021-08-11 14:20:42
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-11 15:28:33
* @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}
>
<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;
import React, { useEffect, useState } from 'react';
import { Tabs, Row, Col, Button } from 'antd';
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 { PublicApi } from '@/services/api';
import { isJSONStr } from '@/utils';
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 } from '../../purchaserEvaluation/components/RecordList';
import RecordList, { ListParams, RecordRes, RecordItem } from '../../purchaserEvaluation/components/RecordList';
import styles from './index.less';
const { TabPane } = Tabs;
......@@ -57,8 +57,14 @@ const Analysis: React.FC<AnalysisProps> = ({
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星级为好评往里边塞数据
......@@ -213,15 +219,16 @@ const Analysis: React.FC<AnalysisProps> = ({
resolve({
data: data.map(item => {
return {
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
created: item.dealTime as string,
target: item.memberName,
orderId: item.orderId,
id: item.id,
star: item.star,
comment: item.comment,
productName: item.product || '',
price: item.price,
quantity: item.purchaseCount,
created: item.dealTime as string,
target: item.memberName,
orderId: item.orderId,
replayStatus: item.replayStatus,
};
}),
totalCount,
......@@ -312,6 +319,30 @@ const Analysis: React.FC<AnalysisProps> = ({
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);
PublicApi.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
......@@ -367,6 +398,10 @@ const Analysis: React.FC<AnalysisProps> = ({
<RecordList
fetchList={getReceivedList}
onCheck={handleJumpReceived}
onExplain={handleExplain}
opposite={false}
explicable={true}
ref={recordListRef}
/>
</TabPane>
......@@ -382,6 +417,13 @@ const Analysis: React.FC<AnalysisProps> = ({
</TabPane>
</Tabs>
</MellowCard>
<ExplainModal
visible={visibleExplainModal}
onClose={() => handleVisibleExplainModal(false)}
confirmLoading={explainConfirmLoading}
onSubmit={handleExplainSubmit}
/>
</PageHeaderWrapper>
);
};
......
......@@ -14,7 +14,7 @@ import { PublicApi } from '@/services/api';
import { normalizeFiledata, FileData } from '@/utils';
import AvatarWrap from '@/components/AvatarWrap';
import NiceForm from '@/components/NiceForm';
import { evaluateSchema } from '../../../purchaserEvaluation/common/schemas/evaluateSchema';
import createSchema from '../../../purchaserEvaluation/common/schemas/receivedSchema';
import { createEffects } from '../../../purchaserEvaluation/common/effects';
import EvaluationList from '../../../purchaserEvaluation/components/EvaluationList';
......@@ -31,7 +31,9 @@ interface Unevaluated {
star: number;
comment: string;
picture: FileData[];
smile: number;
smile: number;
replayContent: string,
replayTime: string,
};
interface OrderInfo {
......@@ -69,6 +71,8 @@ const ReceivedDetail: React.FC = () => {
comment: res.data.comment,
picture: res.data.pics ? res.data.pics.map(item => normalizeFiledata(item)) : [],
smile: res.data.star,
replayContent: res.data.replayContent,
replayTime: res.data.replayTime,
});
setOrderInfo({
orderNo: res.data.orderNo,
......@@ -173,7 +177,7 @@ const ReceivedDetail: React.FC = () => {
effects={($, actions) => {
createEffects($, actions);
}}
schema={evaluateSchema}
schema={createSchema()}
/>
</PageHeaderWrapper>
</Spin>
......
......@@ -144,19 +144,18 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
return Promise.resolve();
};
const UploadTip = (
<span
const UploadTip = () => (
<div
style={{
lineHeight: '24px',
color: '#909399',
fontWeight: 400,
wordBreak: 'break-all',
position: 'relative',
top: '34px',
}}
>
支持JPG/PNG/JPEG <br />每张最大不超过 10M,尺寸不限 <br />最大数量限制 4张
</span>
</div>
);
return (
......@@ -222,15 +221,36 @@ const DetailInfo: React.FC<DetailInfoProps> = ({
}}
editable={isEdit}
expressionScope={{
UploadTip: isEdit ? UploadTip : null,
beforeUpload,
}}
onSubmit={handleSubmit}
components={{
EvaluationList,
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}
/>
......
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