Commit c1a0cfc2 authored by XieZhiXiong's avatar XieZhiXiong

fix: 添加是否可退款判断

parent 63cee027
import React, { Suspense, useEffect, useState } from 'react';
import {
PageHeader,
Descriptions,
Card,
Spin,
Button,
Row,
Col,
Badge,
Switch,
Tooltip,
message,
} from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history } from 'umi';
import { PublicApi } from '@/services/api';
import {
GetAsReturnGoodsGetDetailPlatformResponse,
GetAsReturnGoodsPageReturnedGoodsResponse,
} from '@/services/AfterServiceApi';
import {
RETURN_OUTER_STATUS_FINISHED,
RETURN_OUTER_STATUS_TO_BE_REFUNDED,
RETURN_OUTER_STATUS_UNCONFIRMED_REFUNDED,
RETURN_OUTER_STATUS_NOT_RECEIVED,
RETURN_OUTER_STATUS_UNCONFIRMED_FINISHED,
} from '@/constants';
import { normalizeFiledata, FileData, findLastIndexFlowState } from '@/utils';
import { usePageStatus } from '@/hooks/usePageStatus';
import AvatarWrap from '@/components/AvatarWrap';
import StatusTag from '@/components/StatusTag';
import EyePreview from '@/components/EyePreview';
import AuditProcess from '@/components/AuditProcess';
import { EditableColumns } from '@/components/PolymericTable/interface';
import ReturnInfoDrawer, { OrderInfo } from '../../components/ReturnInfoDrawer';
import { OuterHistoryData, InnerHistoryData } from '../../components/FlowRecords';
import {
RETURN_OUTER_STATUS_TAG_MAP,
RETURN_INNER_STATUS_BADGE_MAP,
} from '../../constants';
import styles from './index.less';
const ProductList = React.lazy(() => import('../../components/ProductList'));
const ReturnAnalysis = React.lazy(() => import('../../components/ReturnAnalysis'));
const ReturnDetailInfo = React.lazy(() => import('../../components/ReturnDetailInfo'));
const FileList = React.lazy(() => import('../../components/FileList'));
const ReturnAddressInfo = React.lazy(() => import('../../components/ReturnAddressInfo'));
const Score = React.lazy(() => import('../../components/Score'));
const FlowRecords = React.lazy(() => import('../../components/FlowRecords'));
interface DetailInfo extends GetAsReturnGoodsGetDetailPlatformResponse {
fileList: FileData[];
};
interface DetailInfoProps {
// 记录id
id: string;
// 历史记录目标路径
target?: string;
/**
* 是否是采购商
*/
isPurchaser?: boolean;
};
const DetailInfo: React.FC<DetailInfoProps> = ({
id,
target,
isPurchaser = false,
}) => {
const [detailInfo, setDetailInfo] = useState<DetailInfo>({});
const [returnGoodsList, setReturnGoodsList] = useState<GetAsReturnGoodsPageReturnedGoodsResponse>({ data: [], totalCount: 0 });
const [returnGoodsLoading, setReturnGoodsLoading] = useState(false);
const [infoLoading, setInfoloading] = useState(false);
const [visibleOrderDetial, setVisibleReturnInfo] = useState<boolean>(false);
const [orderInfo, setOrderInfo] = useState<OrderInfo>({});
const handleCheckOrderDetial = record => {
setOrderInfo({
orderNo: record.orderNo,
productName: record.productName,
category: record.category,
brand: record.brand,
unit: record.unit,
purchaseCount: record.purchaseCount,
purchasePrice: record.purchasePrice,
purchaseAmount: record.purchaseAmount,
returnCount: record.returnCount,
returnReason: record.returnReason,
payList: record.payList.map(item => ({
...item,
payWayTxt: item.payWayName,
channelTxt: item.channelName,
})),
});
setVisibleReturnInfo(true);
};
const productColumns: EditableColumns[] = [
{
title: '订单号',
dataIndex: 'orderNo',
render: (text, record) => (
<EyePreview
url={``}
>
{text}
</EyePreview>
),
},
{
title: '商品ID',
dataIndex: 'productId',
align: 'center',
},
{
title: '商品名称',
dataIndex: 'productName',
align: 'center',
},
{
title: '品类',
dataIndex: 'category',
align: 'center',
},
{
title: '品牌',
dataIndex: 'brand',
align: 'center',
},
{
title: '单位',
dataIndex: 'unit',
align: 'center',
},
{
title: '采购数量',
dataIndex: 'purchaseCount',
align: 'center',
},
{
title: '采购单价',
dataIndex: 'purchasePrice',
align: 'center',
},
{
title: '采购金额',
dataIndex: 'purchaseAmount',
align: 'center',
},
{
title: '已支付金额',
dataIndex: 'payAmount',
align: 'center',
},
{
title: '退货数量',
dataIndex: 'returnCount',
align: 'center',
},
{
title: '退货金额',
dataIndex: 'refundAmount',
align: 'center',
},
{
title: (
<>
<span style={{ marginRight: 8 }}>是否需要退货</span>
<Tooltip title="如果商品因为缺陷原因,无法再退回加工后重新使用,可选择不需要退货,选择后,采购方无须退回不良品。">
<QuestionCircleOutlined />
</Tooltip>
</>
),
dataIndex: 'needReturnName',
align: 'center',
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (text, record) => (
<>
<Button
type="link"
onClick={() => handleCheckOrderDetial(record)}
>
查看详情
</Button>
</>
),
},
];
// 获取退货申请详情
const getDetailInfo = () => {
if (!id) {
return;
}
setInfoloading(true);
PublicApi.getAsReturnGoodsGetDetailPlatform({
returnId: id,
}).then(res => {
if (res.code === 1000) {
const {
faultFileList,
...rest
} = res.data;
setDetailInfo({
faultFileList,
fileList: faultFileList.map(item => normalizeFiledata(item.filePath)),
...rest,
});
}
}).finally(() => {
setInfoloading(false);
});
};
// 获取退货明细列表
const getReturnGoods = () => {
if (!id) {
return;
}
setReturnGoodsLoading(true);
PublicApi.getAsReturnGoodsPageReturnedGoods({
returnId: id,
current: `${1}`,
pageSize: `${99999}`,
}).then(res => {
if (res.code === 1000) {
setReturnGoodsList(res.data);
}
}).finally(() => {
setReturnGoodsLoading(false);
});
};
useEffect(() => {
getDetailInfo();
getReturnGoods();
}, []);
const fetchOuterHistory = (params): Promise<OuterHistoryData> => {
return new Promise((resolve, reject) => {
PublicApi.getAsReturnGoodsPageOuterWorkflowRecord({
...params,
dataId: id,
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject(res);
})
.catch(err => {
reject(err);
});
});
};
const fetchInnerHistory = (params): Promise<InnerHistoryData> => {
return new Promise((resolve, reject) => {
PublicApi.getAsReturnGoodsPageInnerWorkflowRecord({
...params,
dataId: id,
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject(res);
})
.catch(err => {
reject(err);
});
});
};
// 退款
const handleRefund = (values): Promise<any> => {
const { id, ...rest } = values;
return PublicApi.postAsReturnGoodsRefund({
dataId: id,
...rest,
}).then(res => {
if (res.code === 1000) {
getDetailInfo();
}
});
};
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: `申请单号:${detailInfo && detailInfo.applyNo ? detailInfo.applyNo : ''}`,
}}
/>
}
>
<div className={styles['detailInfo-desc']}>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="申请单摘要">{detailInfo?.applyAbstract}</Descriptions.Item>
<Descriptions.Item label="采购会员">{detailInfo?.consumerName}</Descriptions.Item>
<Descriptions.Item label="单据时间">{detailInfo?.applyTime}</Descriptions.Item>
<Descriptions.Item label="外部状态">
<StatusTag type={RETURN_OUTER_STATUS_TAG_MAP[detailInfo?.outerStatus]} title={detailInfo?.outerStatusName} />
</Descriptions.Item>
<Descriptions.Item label="内部状态">
<Badge color={RETURN_INNER_STATUS_BADGE_MAP[detailInfo?.innerStatus]} text={detailInfo?.innerStatusName} />
</Descriptions.Item>
</Descriptions>
</div>
</PageHeader>
</>
}
>
<Row gutter={[24, 24]}>
<Col span={24}>
<Suspense fallback={null}>
<AuditProcess
outerVerifySteps={
detailInfo && detailInfo.outerTaskList ?
detailInfo.outerTaskList.map(item => ({
step: item.step,
stepName: item.taskName,
roleName: item.roleName,
status: item.isExecute ? 'finish' : 'wait',
})) :
[]
}
outerVerifyCurrent={findLastIndexFlowState(detailInfo?.outerTaskList)}
innerVerifySteps={
detailInfo && detailInfo.innerTaskList ?
detailInfo.innerTaskList.map(item => ({
step: item.step,
stepName: item.taskName,
roleName: item.roleName,
status: item.isExecute ? 'finish' : 'wait',
})) :
[]
}
innerVerifyCurrent={findLastIndexFlowState(detailInfo?.innerTaskList)}
/>
</Suspense>
</Col>
<Col span={24}>
<Suspense fallback={null}>
<ProductList
title="退货商品"
rowKey="orderRecordId"
columns={productColumns}
loading={returnGoodsLoading}
dataSource={returnGoodsList.data}
/>
</Suspense>
</Col>
<Col span={24}>
<Suspense fallback={null}>
{/* 退货发货信息 */}
<ReturnAnalysis
summary={detailInfo && detailInfo.returnStatisticsList ? detailInfo.returnStatisticsList : []}
detailed={detailInfo && detailInfo.returnDeliveryGoodsList ? detailInfo.returnDeliveryGoodsList : []}
/>
</Suspense>
</Col>
{/* 退款明细信息 */}
{
detailInfo && (
detailInfo.outerStatus === RETURN_OUTER_STATUS_TO_BE_REFUNDED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_UNCONFIRMED_REFUNDED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_NOT_RECEIVED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_UNCONFIRMED_FINISHED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED
) && (
<Col span={24}>
<Suspense fallback={null}>
<ReturnDetailInfo
dataSource={detailInfo && detailInfo.refundList ? detailInfo.refundList : []}
onRefund={handleRefund}
isPurchaser={isPurchaser}
/>
</Suspense>
</Col>
)
}
<Col span={24}>
<Row
gutter={24}
>
<Col span={detailInfo && detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED ? 6 : 9}>
<Suspense fallback={null}>
<FileList fileList={detailInfo?.fileList} />
</Suspense>
</Col>
<Col span={detailInfo && detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED ? 12 : 15}>
<Suspense fallback={null}>
<ReturnAddressInfo
deliveryAddress={{
id: detailInfo?.returnGoodsAddress?.receiveId,
name: detailInfo?.returnGoodsAddress?.receiveUserName,
phone: detailInfo?.returnGoodsAddress?.receiveUserTel,
fullAddress: detailInfo?.returnGoodsAddress?.receiveAddress,
}}
shippingAddress={{
deliveryType: detailInfo?.returnGoodsAddress?.deliveryType,
name: detailInfo?.returnGoodsAddress?.sendUserName,
phone: detailInfo?.returnGoodsAddress?.sendUserTel,
fullAddress: detailInfo?.returnGoodsAddress?.sendAddress,
}}
isEdit={false}
/>
</Suspense>
</Col>
{detailInfo && detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED && (
<Col span={6}>
{/* 售后评价 */}
<Suspense fallback={null}>
<Score score={detailInfo?.evaluate?.level} />
</Suspense>
</Col>
)}
</Row>
</Col>
<Col span={24}>
{/* 内、外部流转记录 */}
<Suspense fallback={null}>
<FlowRecords
fetchOuterHistory={fetchOuterHistory}
fetchInnerHistory={fetchInnerHistory}
outerStatusMap={RETURN_OUTER_STATUS_TAG_MAP}
innerStatusColorMap={RETURN_INNER_STATUS_BADGE_MAP}
/>
</Suspense>
</Col>
</Row>
<ReturnInfoDrawer
visible={visibleOrderDetial}
orderInfo={orderInfo}
onClose={() => setVisibleReturnInfo(false)}
/>
</PageHeaderWrapper>
</Spin>
);
};
import React, { Suspense, useEffect, useState } from 'react';
import {
PageHeader,
Descriptions,
Card,
Spin,
Button,
Row,
Col,
Badge,
Switch,
Tooltip,
message,
} from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history } from 'umi';
import { PublicApi } from '@/services/api';
import {
GetAsReturnGoodsGetDetailPlatformResponse,
GetAsReturnGoodsPageReturnedGoodsResponse,
} from '@/services/AfterServiceApi';
import {
RETURN_OUTER_STATUS_FINISHED,
RETURN_OUTER_STATUS_TO_BE_REFUNDED,
RETURN_OUTER_STATUS_UNCONFIRMED_REFUNDED,
RETURN_OUTER_STATUS_NOT_RECEIVED,
RETURN_OUTER_STATUS_UNCONFIRMED_FINISHED,
} from '@/constants';
import { normalizeFiledata, FileData, findLastIndexFlowState } from '@/utils';
import { usePageStatus } from '@/hooks/usePageStatus';
import AvatarWrap from '@/components/AvatarWrap';
import StatusTag from '@/components/StatusTag';
import EyePreview from '@/components/EyePreview';
import AuditProcess from '@/components/AuditProcess';
import { EditableColumns } from '@/components/PolymericTable/interface';
import ReturnInfoDrawer, { OrderInfo } from '../../components/ReturnInfoDrawer';
import { OuterHistoryData, InnerHistoryData } from '../../components/FlowRecords';
import {
RETURN_OUTER_STATUS_TAG_MAP,
RETURN_INNER_STATUS_BADGE_MAP,
} from '../../constants';
import styles from './index.less';
const ProductList = React.lazy(() => import('../../components/ProductList'));
const ReturnAnalysis = React.lazy(() => import('../../components/ReturnAnalysis'));
const ReturnDetailInfo = React.lazy(() => import('../../components/ReturnDetailInfo'));
const FileList = React.lazy(() => import('../../components/FileList'));
const ReturnAddressInfo = React.lazy(() => import('../../components/ReturnAddressInfo'));
const Score = React.lazy(() => import('../../components/Score'));
const FlowRecords = React.lazy(() => import('../../components/FlowRecords'));
interface DetailInfo extends GetAsReturnGoodsGetDetailPlatformResponse {
fileList: FileData[];
};
interface DetailInfoProps {
// 记录id
id: string;
// 历史记录目标路径
target?: string;
/**
* 是否是采购商
*/
isPurchaser?: boolean;
};
const DetailInfo: React.FC<DetailInfoProps> = ({
id,
target,
isPurchaser = false,
}) => {
const [detailInfo, setDetailInfo] = useState<DetailInfo>({});
const [returnGoodsList, setReturnGoodsList] = useState<GetAsReturnGoodsPageReturnedGoodsResponse>({ data: [], totalCount: 0 });
const [returnGoodsLoading, setReturnGoodsLoading] = useState(false);
const [infoLoading, setInfoloading] = useState(false);
const [visibleOrderDetial, setVisibleReturnInfo] = useState<boolean>(false);
const [orderInfo, setOrderInfo] = useState<OrderInfo>({});
const handleCheckOrderDetial = record => {
setOrderInfo({
orderNo: record.orderNo,
productName: record.productName,
category: record.category,
brand: record.brand,
unit: record.unit,
purchaseCount: record.purchaseCount,
purchasePrice: record.purchasePrice,
purchaseAmount: record.purchaseAmount,
returnCount: record.returnCount,
returnReason: record.returnReason,
payList: record.payList.map(item => ({
...item,
payWayTxt: item.payWayName,
channelTxt: item.channelName,
})),
});
setVisibleReturnInfo(true);
};
const productColumns: EditableColumns[] = [
{
title: '订单号',
dataIndex: 'orderNo',
render: (text, record) => (
<EyePreview
url={``}
>
{text}
</EyePreview>
),
},
{
title: '商品ID',
dataIndex: 'productId',
align: 'center',
},
{
title: '商品名称',
dataIndex: 'productName',
align: 'center',
},
{
title: '品类',
dataIndex: 'category',
align: 'center',
},
{
title: '品牌',
dataIndex: 'brand',
align: 'center',
},
{
title: '单位',
dataIndex: 'unit',
align: 'center',
},
{
title: '采购数量',
dataIndex: 'purchaseCount',
align: 'center',
},
{
title: '采购单价',
dataIndex: 'purchasePrice',
align: 'center',
},
{
title: '采购金额',
dataIndex: 'purchaseAmount',
align: 'center',
},
{
title: '已支付金额',
dataIndex: 'payAmount',
align: 'center',
},
{
title: '退货数量',
dataIndex: 'returnCount',
align: 'center',
},
{
title: '退货金额',
dataIndex: 'refundAmount',
align: 'center',
},
{
title: (
<>
<span style={{ marginRight: 8 }}>是否需要退货</span>
<Tooltip title="如果商品因为缺陷原因,无法再退回加工后重新使用,可选择不需要退货,选择后,采购方无须退回不良品。">
<QuestionCircleOutlined />
</Tooltip>
</>
),
dataIndex: 'needReturnName',
align: 'center',
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (text, record) => (
<>
<Button
type="link"
onClick={() => handleCheckOrderDetial(record)}
>
查看详情
</Button>
</>
),
},
];
// 获取退货申请详情
const getDetailInfo = () => {
if (!id) {
return;
}
setInfoloading(true);
PublicApi.getAsReturnGoodsGetDetailPlatform({
returnId: id,
}).then(res => {
if (res.code === 1000) {
const {
faultFileList,
...rest
} = res.data;
setDetailInfo({
faultFileList,
fileList: faultFileList.map(item => normalizeFiledata(item.filePath)),
...rest,
});
}
}).finally(() => {
setInfoloading(false);
});
};
// 获取退货明细列表
const getReturnGoods = () => {
if (!id) {
return;
}
setReturnGoodsLoading(true);
PublicApi.getAsReturnGoodsPageReturnedGoods({
returnId: id,
current: `${1}`,
pageSize: `${99999}`,
}).then(res => {
if (res.code === 1000) {
setReturnGoodsList(res.data);
}
}).finally(() => {
setReturnGoodsLoading(false);
});
};
useEffect(() => {
getDetailInfo();
getReturnGoods();
}, []);
const fetchOuterHistory = (params): Promise<OuterHistoryData> => {
return new Promise((resolve, reject) => {
PublicApi.getAsReturnGoodsPageOuterWorkflowRecord({
...params,
dataId: id,
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject(res);
})
.catch(err => {
reject(err);
});
});
};
const fetchInnerHistory = (params): Promise<InnerHistoryData> => {
return new Promise((resolve, reject) => {
PublicApi.getAsReturnGoodsPageInnerWorkflowRecord({
...params,
dataId: id,
})
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject(res);
})
.catch(err => {
reject(err);
});
});
};
// 退款
const handleRefund = (values): Promise<any> => {
const { id, ...rest } = values;
return PublicApi.postAsReturnGoodsRefund({
dataId: id,
...rest,
}).then(res => {
if (res.code === 1000) {
getDetailInfo();
}
});
};
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
title={
<>
<PageHeader
style={{ padding: '0' }}
onBack={() => history.goBack()}
title={
<AvatarWrap
info={{
aloneTxt: '单',
name: `申请单号:${detailInfo && detailInfo.applyNo ? detailInfo.applyNo : ''}`,
}}
/>
}
>
<div className={styles['detailInfo-desc']}>
<Descriptions
size="small"
column={3}
style={{
padding: '0 32px',
}}
>
<Descriptions.Item label="申请单摘要">{detailInfo?.applyAbstract}</Descriptions.Item>
<Descriptions.Item label="采购会员">{detailInfo?.consumerName}</Descriptions.Item>
<Descriptions.Item label="单据时间">{detailInfo?.applyTime}</Descriptions.Item>
<Descriptions.Item label="外部状态">
<StatusTag type={RETURN_OUTER_STATUS_TAG_MAP[detailInfo?.outerStatus]} title={detailInfo?.outerStatusName} />
</Descriptions.Item>
<Descriptions.Item label="内部状态">
<Badge color={RETURN_INNER_STATUS_BADGE_MAP[detailInfo?.innerStatus]} text={detailInfo?.innerStatusName} />
</Descriptions.Item>
</Descriptions>
</div>
</PageHeader>
</>
}
>
<Row gutter={[24, 24]}>
<Col span={24}>
<Suspense fallback={null}>
<AuditProcess
outerVerifySteps={
detailInfo && detailInfo.outerTaskList ?
detailInfo.outerTaskList.map(item => ({
step: item.step,
stepName: item.taskName,
roleName: item.roleName,
status: item.isExecute ? 'finish' : 'wait',
})) :
[]
}
outerVerifyCurrent={findLastIndexFlowState(detailInfo?.outerTaskList)}
innerVerifySteps={
detailInfo && detailInfo.innerTaskList ?
detailInfo.innerTaskList.map(item => ({
step: item.step,
stepName: item.taskName,
roleName: item.roleName,
status: item.isExecute ? 'finish' : 'wait',
})) :
[]
}
innerVerifyCurrent={findLastIndexFlowState(detailInfo?.innerTaskList)}
/>
</Suspense>
</Col>
<Col span={24}>
<Suspense fallback={null}>
<ProductList
title="退货商品"
rowKey="orderRecordId"
columns={productColumns}
loading={returnGoodsLoading}
dataSource={returnGoodsList.data}
/>
</Suspense>
</Col>
<Col span={24}>
<Suspense fallback={null}>
{/* 退货发货信息 */}
<ReturnAnalysis
summary={detailInfo && detailInfo.returnStatisticsList ? detailInfo.returnStatisticsList : []}
detailed={detailInfo && detailInfo.returnDeliveryGoodsList ? detailInfo.returnDeliveryGoodsList : []}
/>
</Suspense>
</Col>
{/* 退款明细信息 */}
{
detailInfo && (
detailInfo.outerStatus === RETURN_OUTER_STATUS_TO_BE_REFUNDED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_UNCONFIRMED_REFUNDED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_NOT_RECEIVED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_UNCONFIRMED_FINISHED ||
detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED
) && (
<Col span={24}>
<Suspense fallback={null}>
<ReturnDetailInfo
dataSource={detailInfo && detailInfo.refundList ? detailInfo.refundList : []}
onRefund={handleRefund}
isPurchaser={isPurchaser}
innerStatus={detailInfo?.innerStatus}
/>
</Suspense>
</Col>
)
}
<Col span={24}>
<Row
gutter={24}
>
<Col span={detailInfo && detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED ? 6 : 9}>
<Suspense fallback={null}>
<FileList fileList={detailInfo?.fileList} />
</Suspense>
</Col>
<Col span={detailInfo && detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED ? 12 : 15}>
<Suspense fallback={null}>
<ReturnAddressInfo
deliveryAddress={{
id: detailInfo?.returnGoodsAddress?.receiveId,
name: detailInfo?.returnGoodsAddress?.receiveUserName,
phone: detailInfo?.returnGoodsAddress?.receiveUserTel,
fullAddress: detailInfo?.returnGoodsAddress?.receiveAddress,
}}
shippingAddress={{
deliveryType: detailInfo?.returnGoodsAddress?.deliveryType,
name: detailInfo?.returnGoodsAddress?.sendUserName,
phone: detailInfo?.returnGoodsAddress?.sendUserTel,
fullAddress: detailInfo?.returnGoodsAddress?.sendAddress,
}}
isEdit={false}
/>
</Suspense>
</Col>
{detailInfo && detailInfo.outerStatus === RETURN_OUTER_STATUS_FINISHED && (
<Col span={6}>
{/* 售后评价 */}
<Suspense fallback={null}>
<Score score={detailInfo?.evaluate?.level} />
</Suspense>
</Col>
)}
</Row>
</Col>
<Col span={24}>
{/* 内、外部流转记录 */}
<Suspense fallback={null}>
<FlowRecords
fetchOuterHistory={fetchOuterHistory}
fetchInnerHistory={fetchInnerHistory}
outerStatusMap={RETURN_OUTER_STATUS_TAG_MAP}
innerStatusColorMap={RETURN_INNER_STATUS_BADGE_MAP}
/>
</Suspense>
</Col>
</Row>
<ReturnInfoDrawer
visible={visibleOrderDetial}
orderInfo={orderInfo}
onClose={() => setVisibleReturnInfo(false)}
/>
</PageHeaderWrapper>
</Spin>
);
};
export default DetailInfo;
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2020-11-05 18:02:18
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-12-15 10:26:44
* @Description: 退款明细
*/
import React, { useState } from 'react';
import { Row, Col, Modal, Button, Upload, Descriptions } from 'antd';
import { CaretRightOutlined, CaretDownOutlined, RightOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import MellowCard from '@/components/MellowCard';
import { EditableColumns } from '@/components/PolymericTable/interface';
import PolymericTable from '@/components/PolymericTable';
import StatusTag from '@/components/StatusTag';
import { FileData, normalizeFiledata } from '@/utils';
import {
PAY_CHANNEL_OFFLINE,
PAY_CHANNEL_BALANCE,
PAY_CHANNEL_CREDIT,
PAY_CHANNEL_COD,
} from '@/constants';
import Stamp from '../Stamp';
import CheckVoucherModal from '../CheckVoucherModal';
import RefundModal, { RefundModalProps } from '../RefundModal';
import {
REFUND_INNER_STATUS_NO_REFUND,
REFUND_INNER_STATUS_REFUND_FAILED,
REFUND_OUTER_STATUS_UNCONFIRMED_REFUND,
REFUND_OUTER_STATUS_NOT_RECEIVED,
REFUND_OUTER_STATUS_RECEIVED,
REFUND_OUTER_STATUS_TAG_MAP,
} from '../../constants';
import styles from './index.less';
const { confirm } = Modal;
interface ReturnDetailInfoProps {
dataSource: {
[key: string]: any,
}[];
/**
* 退款事件
*/
onRefund?: (id: number) => Promise<any>;
/**
* 确认事件
*/
onConfirm?: (id: number, flag: 0 | 1) => Promise<any>;
/**
* 是否是采购商
*/
isPurchaser?: boolean;
};
const ReturnDetailInfo: React.FC<ReturnDetailInfoProps> = ({
dataSource = [],
onRefund,
onConfirm,
isPurchaser = false,
}) => {
const [visibleResult, setVisibleResult] = useState(false);
const [notReceivedLoading, setNotReceivedLoading] = useState(false);
const [receivedLoading, setReceivedLoading] = useState(false);
const [currentDetailItem, setCurrentDetailItem] = useState<{ id: number, fileList: FileData[] }>({
id: 0,
fileList: [],
});
const [voucherVisible, setVoucherVisible] = useState(false);
const [refundModalVisible, setRefundModalVisible] = useState(false);
const [modalName, setModalName] = useState('uploadVoucher');
const [refundModalValue, setRefundModalValue] = useState({});
const [submitLoading, setSubmitLoading] = useState(false);
const columns: EditableColumns[] = [
{
title: '订单号',
dataIndex: 'orderNo',
render: (text, record) => text,
},
{
title: '商品ID',
dataIndex: 'productId',
align: 'center',
},
{
title: '商品名称',
dataIndex: 'productName',
align: 'center',
},
{
title: '品类',
dataIndex: 'category',
align: 'center',
},
{
title: '品牌',
dataIndex: 'brand',
align: 'center',
},
{
title: '单位',
dataIndex: 'unit',
align: 'center',
},
{
title: '采购数量',
dataIndex: 'purchaseCount',
align: 'center',
},
{
title: '采购单价',
dataIndex: 'purchasePrice',
align: 'center',
},
{
title: '采购金额',
dataIndex: 'purchaseAmount',
align: 'center',
},
{
title: '已支付金额',
dataIndex: 'payAmount',
align: 'center',
},
{
title: '退货数量',
dataIndex: 'returnCount',
align: 'center',
},
{
title: '退款金额',
dataIndex: 'refundAmount',
align: 'center',
},
];
const handleRefund = (id, channel) => {
switch(channel) {
// 余额支付
case PAY_CHANNEL_BALANCE: {
setModalName('balance');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
// 线下支付
case PAY_CHANNEL_OFFLINE: {
setModalName('uploadVoucher');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
// 授信支付
case PAY_CHANNEL_CREDIT: {
setModalName('credit');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
// 货到付款
case PAY_CHANNEL_COD: {
setModalName('COD');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
default: {
if (onRefund) {
confirm({
title: '提示',
icon: <ExclamationCircleOutlined />,
content: `是否确认退款?`,
onOk() {
return onRefund(id);
},
});
}
break;
}
}
};
const handleConfirm = (id, flag) => {
if (onConfirm) {
flag === 1 ? setReceivedLoading(true) : setNotReceivedLoading(true);
onConfirm(id, flag).finally(() => {
flag === 1 ? setReceivedLoading(false) : setNotReceivedLoading(false);
});
}
};
const handleConfirmResult = record => {
setCurrentDetailItem({
id: record.refundId,
fileList: record.payProveList.map(item => normalizeFiledata(item.proveUrl)),
});
setVisibleResult(true);
};
const handleCheck = record => {
setCurrentDetailItem({
id: record.refundId,
fileList: record.payProveList.map(item => normalizeFiledata(item.proveUrl)),
});
};
const handleRefundConfirm = (values, modalName) => {
setSubmitLoading(true);
onRefund(values).finally(() => {
setSubmitLoading(false);
});
};
return (
<MellowCard title="退款明细">
<PolymericTable
rowKey={record => `${record.orderNo}+${record.productId}`}
dataSource={dataSource}
columns={columns}
loading={false}
pagination={null}
expandable={{
expandIcon: ({ expanded, onExpand, record }) =>
expanded ? (
<CaretDownOutlined onClick={e => onExpand(record, e)} />
) : (
<CaretRightOutlined onClick={e => onExpand(record, e)} />
),
expandedRowRender: record => (
<Row
gutter={[16, 16]}
className={styles.deliver}
>
{record.detailList.map(item => (
<Col
span={8}
className={styles['deliver-item']}
key={item.refundId}
>
<Stamp>
<Descriptions column={2}>
<Descriptions.Item label="支付次数">1</Descriptions.Item>
<Descriptions.Item label="状态">
<StatusTag type={REFUND_OUTER_STATUS_TAG_MAP[item.outerStatus]} title={item.outerStatusName} />
</Descriptions.Item>
<Descriptions.Item label="支付环节">{item.payNode}</Descriptions.Item>
<Descriptions.Item label="已支付金额(元)">{item.payAmount}</Descriptions.Item>
<Descriptions.Item label="支付比例">{item.payRatio}%</Descriptions.Item>
<Descriptions.Item label="退款金额(元)">{item.refundAmount}</Descriptions.Item>
<Descriptions.Item label="支付方式">{item.payWayName}</Descriptions.Item>
<Descriptions.Item label="退款时间">{item.refundTime}</Descriptions.Item>
<Descriptions.Item label="支付渠道">{item.channelName}</Descriptions.Item>
</Descriptions>
<div className={styles['deliver-item-actions']}>
{
!isPurchaser && (
item.outerStatus === REFUND_OUTER_STATUS_NOT_RECEIVED ||
item.innerStatus === REFUND_INNER_STATUS_NO_REFUND ||
item.innerStatus === REFUND_INNER_STATUS_REFUND_FAILED
) && (
<div
className={styles['deliver-item-return']}
onClick={() => handleRefund(item.refundId, item.channel)}
>
退款
</div>
)
}
{/* 线下支付 才有确认 与 查看功能 */}
{item.channel === PAY_CHANNEL_OFFLINE && (
<>
{
isPurchaser && (
item.outerStatus === REFUND_OUTER_STATUS_UNCONFIRMED_REFUND ||
item.outerStatus === REFUND_OUTER_STATUS_NOT_RECEIVED
) && (
<div
className={styles['deliver-item-return']}
onClick={() => handleConfirmResult(item)}
>
确认
</div>
)
}
{
(
item.outerStatus === REFUND_OUTER_STATUS_RECEIVED ||
item.outerStatus === REFUND_OUTER_STATUS_NOT_RECEIVED
) && (
<div
className={styles['deliver-item-check']}
onClick={() => handleCheck(record)}
>
查看
<RightOutlined />
</div>
)
}
</>
)}
</div>
</Stamp>
</Col>
))}
</Row>
),
}}
/>
<CheckVoucherModal
visible={voucherVisible}
fileList={currentDetailItem.fileList}
onCancel={() => setVoucherVisible(false)}
/>
<Modal
title="确认还款结果"
width={576}
visible={visibleResult}
footer={[
<Button
key="1"
onClick={() => setVisibleResult(false)}
>
取消
</Button>,
<Button
key="2"
type="primary"
loading={notReceivedLoading}
onClick={() => handleConfirm(currentDetailItem.id, 0)}
danger
>
未到账
</Button>,
<Button
key="2"
type="primary"
loading={receivedLoading}
onClick={() => handleConfirm(currentDetailItem.id, 1)}
>
已到账
</Button>,
]}
destroyOnClose
>
<Upload
defaultFileList={currentDetailItem.fileList}
disabled
/>
</Modal>
<RefundModal
value={refundModalValue}
visible={refundModalVisible}
modalName={modalName}
handleModalVisible={() => setRefundModalVisible(false)}
handleConfirm={handleRefundConfirm}
submitLoading={submitLoading}
/>
</MellowCard>
);
};
/*
* @Author: XieZhiXiong
* @Date: 2020-11-05 18:02:18
* @LastEditors: XieZhiXiong
* @LastEditTime: 2020-12-15 10:26:44
* @Description: 退款明细
*/
import React, { useState } from 'react';
import { Row, Col, Modal, Button, Upload, Descriptions } from 'antd';
import { CaretRightOutlined, CaretDownOutlined, RightOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import MellowCard from '@/components/MellowCard';
import { EditableColumns } from '@/components/PolymericTable/interface';
import PolymericTable from '@/components/PolymericTable';
import StatusTag from '@/components/StatusTag';
import { FileData, normalizeFiledata } from '@/utils';
import {
PAY_CHANNEL_OFFLINE,
PAY_CHANNEL_BALANCE,
PAY_CHANNEL_CREDIT,
PAY_CHANNEL_COD,
RETURN_INNER_STATUS_TO_BE_REFUNDED,
RETURN_INNER_STATUS_UNCONFIRMED_REFUNDED,
} from '@/constants';
import Stamp from '../Stamp';
import CheckVoucherModal from '../CheckVoucherModal';
import RefundModal, { RefundModalProps } from '../RefundModal';
import {
REFUND_INNER_STATUS_NO_REFUND,
REFUND_INNER_STATUS_REFUND_FAILED,
REFUND_OUTER_STATUS_UNCONFIRMED_REFUND,
REFUND_OUTER_STATUS_NOT_RECEIVED,
REFUND_OUTER_STATUS_RECEIVED,
REFUND_OUTER_STATUS_TAG_MAP,
} from '../../constants';
import styles from './index.less';
const { confirm } = Modal;
interface ReturnDetailInfoProps {
dataSource: {
[key: string]: any,
}[];
/**
* 退款事件
*/
onRefund?: (id: number) => Promise<any>;
/**
* 确认事件
*/
onConfirm?: (id: number, flag: 0 | 1) => Promise<any>;
/**
* 是否是采购商
*/
isPurchaser?: boolean;
/**
* 退货申请单内部状态
*/
innerStatus: number;
};
const ReturnDetailInfo: React.FC<ReturnDetailInfoProps> = ({
dataSource = [],
onRefund,
onConfirm,
isPurchaser = false,
innerStatus,
}) => {
const [visibleResult, setVisibleResult] = useState(false);
const [notReceivedLoading, setNotReceivedLoading] = useState(false);
const [receivedLoading, setReceivedLoading] = useState(false);
const [currentDetailItem, setCurrentDetailItem] = useState<{ id: number, fileList: FileData[] }>({
id: 0,
fileList: [],
});
const [voucherVisible, setVoucherVisible] = useState(false);
const [refundModalVisible, setRefundModalVisible] = useState(false);
const [modalName, setModalName] = useState('uploadVoucher');
const [refundModalValue, setRefundModalValue] = useState({});
const [submitLoading, setSubmitLoading] = useState(false);
const columns: EditableColumns[] = [
{
title: '订单号',
dataIndex: 'orderNo',
render: (text, record) => text,
},
{
title: '商品ID',
dataIndex: 'productId',
align: 'center',
},
{
title: '商品名称',
dataIndex: 'productName',
align: 'center',
},
{
title: '品类',
dataIndex: 'category',
align: 'center',
},
{
title: '品牌',
dataIndex: 'brand',
align: 'center',
},
{
title: '单位',
dataIndex: 'unit',
align: 'center',
},
{
title: '采购数量',
dataIndex: 'purchaseCount',
align: 'center',
},
{
title: '采购单价',
dataIndex: 'purchasePrice',
align: 'center',
},
{
title: '采购金额',
dataIndex: 'purchaseAmount',
align: 'center',
},
{
title: '已支付金额',
dataIndex: 'payAmount',
align: 'center',
},
{
title: '退货数量',
dataIndex: 'returnCount',
align: 'center',
},
{
title: '退款金额',
dataIndex: 'refundAmount',
align: 'center',
},
];
const handleRefund = (id, channel) => {
switch(channel) {
// 余额支付
case PAY_CHANNEL_BALANCE: {
setModalName('balance');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
// 线下支付
case PAY_CHANNEL_OFFLINE: {
setModalName('uploadVoucher');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
// 授信支付
case PAY_CHANNEL_CREDIT: {
setModalName('credit');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
// 货到付款
case PAY_CHANNEL_COD: {
setModalName('COD');
setRefundModalVisible(true);
setRefundModalValue({ id });
break;
};
default: {
if (onRefund) {
confirm({
title: '提示',
icon: <ExclamationCircleOutlined />,
content: `是否确认退款?`,
onOk() {
return onRefund(id);
},
});
}
break;
}
}
};
const handleConfirm = (id, flag) => {
if (onConfirm) {
flag === 1 ? setReceivedLoading(true) : setNotReceivedLoading(true);
onConfirm(id, flag).finally(() => {
flag === 1 ? setReceivedLoading(false) : setNotReceivedLoading(false);
});
}
};
const handleConfirmResult = record => {
setCurrentDetailItem({
id: record.refundId,
fileList: record.payProveList.map(item => normalizeFiledata(item.proveUrl)),
});
setVisibleResult(true);
};
const handleCheck = record => {
setCurrentDetailItem({
id: record.refundId,
fileList: record.payProveList.map(item => normalizeFiledata(item.proveUrl)),
});
};
const handleRefundConfirm = (values, modalName) => {
setSubmitLoading(true);
if (onRefund) {
onRefund(values).finally(() => {
setSubmitLoading(false);
});
}
};
return (
<MellowCard title="退款明细">
<PolymericTable
rowKey={record => `${record.orderNo}+${record.productId}`}
dataSource={dataSource}
columns={columns}
loading={false}
pagination={false}
expandable={{
expandIcon: ({ expanded, onExpand, record }) =>
expanded ? (
<CaretDownOutlined onClick={e => onExpand(record, e)} />
) : (
<CaretRightOutlined onClick={e => onExpand(record, e)} />
),
expandedRowRender: record => (
<Row
gutter={[16, 16]}
className={styles.deliver}
>
{record.detailList.map(item => (
<Col
span={8}
className={styles['deliver-item']}
key={item.refundId}
>
<Stamp>
<Descriptions column={2}>
<Descriptions.Item label="支付次数">1</Descriptions.Item>
<Descriptions.Item label="状态">
<StatusTag type={REFUND_OUTER_STATUS_TAG_MAP[item.outerStatus]} title={item.outerStatusName} />
</Descriptions.Item>
<Descriptions.Item label="支付环节">{item.payNode}</Descriptions.Item>
<Descriptions.Item label="已支付金额(元)">{item.payAmount}</Descriptions.Item>
<Descriptions.Item label="支付比例">{item.payRatio}%</Descriptions.Item>
<Descriptions.Item label="退款金额(元)">{item.refundAmount}</Descriptions.Item>
<Descriptions.Item label="支付方式">{item.payWayName}</Descriptions.Item>
<Descriptions.Item label="退款时间">{item.refundTime}</Descriptions.Item>
<Descriptions.Item label="支付渠道">{item.channelName}</Descriptions.Item>
</Descriptions>
<div className={styles['deliver-item-actions']}>
{
!isPurchaser &&
innerStatus === RETURN_INNER_STATUS_TO_BE_REFUNDED &&
item.canRefund && (
item.outerStatus === REFUND_OUTER_STATUS_NOT_RECEIVED ||
item.innerStatus === REFUND_INNER_STATUS_NO_REFUND ||
item.innerStatus === REFUND_INNER_STATUS_REFUND_FAILED
) && (
<div
className={styles['deliver-item-return']}
onClick={() => handleRefund(item.refundId, item.channel)}
>
退款
</div>
)
}
{/* 线下支付 才有确认 与 查看功能 */}
{item.channel === PAY_CHANNEL_OFFLINE && (
<>
{
isPurchaser &&
innerStatus === RETURN_INNER_STATUS_UNCONFIRMED_REFUNDED && (
item.outerStatus === REFUND_OUTER_STATUS_UNCONFIRMED_REFUND ||
item.outerStatus === REFUND_OUTER_STATUS_NOT_RECEIVED
) && (
<div
className={styles['deliver-item-return']}
onClick={() => handleConfirmResult(item)}
>
确认
</div>
)
}
{
(
item.outerStatus === REFUND_OUTER_STATUS_RECEIVED ||
item.outerStatus === REFUND_OUTER_STATUS_NOT_RECEIVED
) && (
<div
className={styles['deliver-item-check']}
onClick={() => handleCheck(record)}
>
查看
<RightOutlined />
</div>
)
}
</>
)}
</div>
</Stamp>
</Col>
))}
</Row>
),
}}
/>
<CheckVoucherModal
visible={voucherVisible}
fileList={currentDetailItem.fileList}
onCancel={() => setVoucherVisible(false)}
/>
<Modal
title="确认还款结果"
width={576}
visible={visibleResult}
footer={[
<Button
key="1"
onClick={() => setVisibleResult(false)}
>
取消
</Button>,
<Button
key="2"
type="primary"
loading={notReceivedLoading}
onClick={() => handleConfirm(currentDetailItem.id, 0)}
danger
>
未到账
</Button>,
<Button
key="2"
type="primary"
loading={receivedLoading}
onClick={() => handleConfirm(currentDetailItem.id, 1)}
>
已到账
</Button>,
]}
destroyOnClose
>
<Upload
defaultFileList={currentDetailItem.fileList}
disabled
/>
</Modal>
<RefundModal
value={refundModalValue}
visible={refundModalVisible}
modalName={modalName}
handleModalVisible={() => setRefundModalVisible(false)}
handleConfirm={handleRefundConfirm}
submitLoading={submitLoading}
/>
</MellowCard>
);
};
export default ReturnDetailInfo;
\ No newline at end of file
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