Commit 80a0ab34 authored by XieZhiXiong's avatar XieZhiXiong

对接完毕授信额度管理详情

parent 9c7ffe64
......@@ -13,6 +13,7 @@ import {
} from 'antd';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import lodash from 'lodash';
import { PublicApi } from '@/services/api';
import MellowCard from '@/components/MellowCard';
import { Pie } from '@/components/Charts';
import StatusTag from '@/components/StatusTag';
......@@ -21,7 +22,6 @@ import { repaymentModalSchema, uploadVoucherModalSchema } from './schema';
import { createEffects } from './effects/repayment';
import TradeRecord, { RecordParams, RecordRes } from '../TradeRecord';
import styles from './index.less';
import { PublicApi } from '@/services/api';
const repaymentFormActions = createFormActions();
const uploadVoucherFormActions = createFormActions();
......
......@@ -29,13 +29,17 @@ const BillInfo = React.lazy(() => import('./components/BillInfo'));
const HistoryList = React.lazy(() => import('../../components/HistoryList'));
const QuotaMenageDetail: React.FC = () => {
const { id, validateId, pageStatus } = usePageStatus();
const { id } = usePageStatus();
const [creditInfo, setCreditInfo] = useState<GetPayCreditApplyGetCreditDetailResponse>(null);
const [creditOverdueList, setCreditOverdueList] = useState([]);
const [infoLoading, setInfoLoading] = useState(false);
const [creditOverdueListLoading, setCreditOverdueListLoading] = useState(false);
// 获取授信详情
const getCreditDetail = () => {
if (!id) {
return;
}
setInfoLoading(true);
PublicApi.getPayCreditApplyGetCreditDetail({
id,
......@@ -64,6 +68,7 @@ const QuotaMenageDetail: React.FC = () => {
},
];
// 获取账单详情
const fetchBillDetail = (params: BillDetailParams): Promise<BillDetailData> => {
return new Promise((resolve, reject) => {
PublicApi.getPayCreditApplyGetCreditBillDetail(params)
......@@ -79,7 +84,11 @@ const QuotaMenageDetail: React.FC = () => {
});
};
// 获取账单记录列表
const fetchBillRecordList = (params: BillRecordParams): Promise<any> => {
if (!id) {
return;
}
return new Promise((resolve, reject) => {
PublicApi.getPayCreditApplyPageCreditTradeRecord({
creditId: id,
......@@ -95,7 +104,11 @@ const QuotaMenageDetail: React.FC = () => {
});
};
// 获取逾期列表
const getCreditOverdueList = () => {
if (!id) {
return;
}
setCreditOverdueListLoading(true);
PublicApi.getPayCreditApplyPageCreditOverdue({
creditId: id,
......
......@@ -4,15 +4,30 @@ import PolymericTable from '@/components/PolymericTable';
import { EditableColumns } from '@/components/PolymericTable/interface';
import EyePreview from '@/components/EyePreview';
const HistoryList: React.FC = () => {
interface HistoryListHistoryListProps {
dataSource: {
applyNo: string,
originalQuota: number;
applyQuota: number;
auditQuota: number;
applyTime: string;
}[];
// 目标路径
target?: string;
};
const HistoryList: React.FC<HistoryListHistoryListProps> = ({
dataSource = [],
target,
}) => {
const columns: EditableColumns[] = [
{
title: '申请单号',
dataIndex: 'order',
render: text => (
dataIndex: 'applyNo',
render: (text, record) => (
<EyePreview
url={``}
url={`${target ? target : '/memberCenter/payandSettle/creditApplication/quotaPrSubmit/detail'}?id=${record.id}`}
>
{text}
</EyePreview>
......@@ -20,30 +35,26 @@ const HistoryList: React.FC = () => {
},
{
title: '调整前额度(元)',
dataIndex: 'content',
dataIndex: 'originalQuota',
align: 'center',
},
{
title: '申请调整额度(元)',
dataIndex: 'byMemberName',
dataIndex: 'applyQuota',
align: 'center',
},
{
title: '审批额度(元)',
dataIndex: 'reason',
dataIndex: 'auditQuota',
align: 'center',
},
{
title: '申请时间',
dataIndex: 'createTime',
dataIndex: 'applyTime',
align: 'center',
},
];
const handlePaginationChange = () => {
};
return (
<MellowCard
title="历史授信申请"
......@@ -52,15 +63,11 @@ const HistoryList: React.FC = () => {
}}
>
<PolymericTable
rowKey="remark"
dataSource={[]}
rowKey="applyNo"
dataSource={dataSource}
columns={columns}
loading={false}
pagination={{
pageSize: 10,
total: 200,
}}
onPaginationChange={handlePaginationChange}
pagination={null}
/>
</MellowCard>
);
......
......@@ -35,4 +35,8 @@
&-right {
flex: 1;
}
}
.noData {
padding-top: 24px;
}
\ No newline at end of file
......@@ -4,7 +4,11 @@ import {
Descriptions,
Row,
Col,
Empty,
} from 'antd';
import { GetPayCreditApplyPageCreditOverdueResponseDetail } from '@/services/PayApi';
import { BILL_TRADE_OPERATION } from '@/constants';
import { normalizeFiledata, FileData } from '@/utils';
import MellowCard from '@/components/MellowCard';
import StatusTag from '@/components/StatusTag';
import TradeWrap from '../TradeWrap';
......@@ -13,9 +17,28 @@ import styles from './index.less';
const { TabPane } = Tabs;
const BillInfo: React.FC = () => {
export interface BillInfoProps {
overdueList: GetPayCreditApplyPageCreditOverdueResponseDetail[];
loading?: boolean;
};
const BillInfo: React.FC<BillInfoProps> = ({
overdueList = [],
loading = false,
}) => {
const [currentVoucher, setCurrentVoucher] = useState<FileData[]>([]);
const [voucherVisible, setVoucherVisible] = useState(false);
const handleCheckVoucher = record => {
if (!Array.isArray(record)) {
setCurrentVoucher([]);
} else {
const voucher = record.map(item => normalizeFiledata(item.proveUrl));
setCurrentVoucher(voucher);
}
setVoucherVisible(true);
};
return (
<MellowCard
style={{
......@@ -26,91 +49,85 @@ const BillInfo: React.FC = () => {
}}
>
<div className={styles.billInfo}>
<Tabs defaultActiveKey="1" onChange={() => {}}>
<TabPane
tab={(
<div className={styles.dateWrap}>
<StatusTag type="danger" title="逾期 9 天" />
<div className={styles.time}>2020/06/11 ~ 2020/07/11</div>
</div>
)}
key="1"
>
<div className={styles.content}>
<div className={styles['content-left']}>
<Descriptions column={1}>
<Descriptions.Item label="账单金额(元)">30,000.00</Descriptions.Item>
<Descriptions.Item label="账单最后还款日期">2020-08-20</Descriptions.Item>
<Descriptions.Item label="账单最后还款金额(元)">20,000.00</Descriptions.Item>
<Descriptions.Item label="还清日期">2020-08-21</Descriptions.Item>
</Descriptions>
</div>
<div className={styles['content-right']}>
<TradeWrap>
<TradeWrap.TradeItem width="33.33%">
{(!loading && overdueList && overdueList.length > 0 ) ? (
<Tabs onChange={() => {}}>
{overdueList.map((item, index) => (
<TabPane
tab={(
<div className={styles.dateWrap}>
<StatusTag type="danger" title={`逾期 ${item.overdueDay} 天`} />
<div className={styles.time}>{item.billName}</div>
</div>
)}
key={index}
>
<div className={styles.content}>
<div className={styles['content-left']}>
<Descriptions column={1}>
<Descriptions.Item label="交易流水号">
<Row justify="space-between">
<Col span={12}>
<a onClick={() => setVoucherVisible(true)}>20200820000010</a>
</Col>
<Col
span={10}
style={{
textAlign: 'right',
}}
>
<StatusTag type="danger" title="待确认还款结果" />
</Col>
</Row>
</Descriptions.Item>
<Descriptions.Item label="交易项目">
<Row justify="space-between">
<Col span={12}>
还款
</Col>
<Col
span={10}
style={{
textAlign: 'right',
}}
>
<strong>+30,000.00元</strong>
</Col>
</Row>
</Descriptions.Item>
<Descriptions.Item label="交易时间">2020-08-25 08:58</Descriptions.Item>
<Descriptions.Item label="账单金额(元)">{item.billQuota}</Descriptions.Item>
<Descriptions.Item label="账单最后还款日期">{item.lastRepayDate}</Descriptions.Item>
<Descriptions.Item label="账单最后还款金额(元)">{item.lastRepayQuota}</Descriptions.Item>
<Descriptions.Item label="还清日期">{item.payOffDate}</Descriptions.Item>
</Descriptions>
</TradeWrap.TradeItem>
</TradeWrap>
</div>
</div>
</TabPane>
</Tabs>
</div>
<div className={styles['content-right']}>
<TradeWrap>
{item.tradeList && item.tradeList.map(trade => (
<TradeWrap.TradeItem
width="33.33%"
key={trade.tradeCode}
>
<Descriptions column={1}>
<Descriptions.Item label="交易流水号">
<Row justify="space-between">
<Col span={12}>
<a onClick={() => handleCheckVoucher(trade.payProveList)}>{trade.tradeCode}</a>
</Col>
<Col
span={10}
style={{
textAlign: 'right',
}}
>
<StatusTag type="danger" title={`逾期 ${trade.overdueDay} 天`} />
</Col>
</Row>
</Descriptions.Item>
<Descriptions.Item label="交易项目">
<Row justify="space-between">
<Col span={12}>
{BILL_TRADE_OPERATION[trade.operation]}
</Col>
<Col
span={10}
style={{
textAlign: 'right',
}}
>
<strong>{trade.tradeMoney}</strong>
</Col>
</Row>
</Descriptions.Item>
<Descriptions.Item label="交易时间">{trade.tradeTime}</Descriptions.Item>
</Descriptions>
</TradeWrap.TradeItem>
))}
</TradeWrap>
</div>
</div>
</TabPane>
))}
</Tabs>
) : (
<div className={styles.noData}>
<Empty />
</div>
)}
</div>
<CheckVoucherModal
visible={voucherVisible}
fileList={[
{
uid: '1',
name: 'xxx.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
},
{
uid: '2',
name: 'yyy.png',
status: 'done',
url: 'http://www.baidu.com/yyy.png',
},
{
uid: '3',
name: 'zzz.png',
status: 'done',
url: 'http://www.baidu.com/zzz.png',
},
]}
fileList={currentVoucher}
onCancel={() => setVoucherVisible(false)}
/>
</MellowCard>
......
import { ISchema } from '@formily/antd';
import { UPLOAD_TYPE } from '@/constants';
export const repaymentModalSchema: ISchema = {
type: 'object',
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelAlign: 'top',
full: true,
},
properties: {
amount: {
type: 'string',
title: '还款金额',
'x-component-props': {
placeholder: '',
addonBefore: '¥',
},
'x-rules': [
{
required: true,
message: '请填写还款金额',
},
],
},
amountSlide: {
type: 'number',
title: '',
'x-component': 'range',
'x-component-props': {
min: 0,
max: 20000,
marks: [0, 5000, 10000, 15000, 20000],
},
},
payType: {
type: 'number',
enum: [
{
label: '线上支付方式',
value: 1,
},
{
label: '线下支付方式',
value: 2,
},
],
default: 1,
title: '选择支付方式',
'x-component-props': {
placeholder: '请选择',
},
'x-rules': [
{
required: true,
message: '请选择支付方式',
},
],
},
payChannels: {
type: 'string',
title: '选择支付渠道',
enum: [
{
label: '微信',
value: 1,
},
{
label: '支付宝',
value: 2,
},
{
label: '银联',
value: 3,
},
],
default: 1,
'x-component-props': {
placeholder: '请选择',
},
'x-rules': [
{
required: true,
message: '请选择支付渠道',
},
],
},
},
},
},
};
export const uploadVoucherModalSchema: ISchema = {
type: 'object',
properties: {
MEGA_LAYOUT: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelCol: 6,
wrapperCol: 18,
labelAlign: 'left',
full: true,
},
properties: {
accountName: {
type: 'string',
title: '还款账户名称',
default: '温州市隆昌皮具有限公司',
'x-component': 'Text',
'x-component-props': {
},
},
bankAccount: {
type: 'string',
title: '银行账号',
default: '6214 7812 3456 7891 1234',
'x-component': 'Text',
'x-component-props': {
},
},
bod: {
type: 'string',
title: '开户行',
default: '中国建设银行广州市分行营业部',
'x-component': 'Text',
'x-component-props': {
},
},
voucher: {
type: 'string',
title: '上传支付凭证',
'x-component': 'Upload',
'x-component-props': {
action: '/api/file/file/upload/prefix',
data: {
fileType: UPLOAD_TYPE,
prefix: '/creditApplication/paymentVoucher/',
},
beforeUpload: '{{beforeUpload}}',
accept: '.png, .jpg, .jpeg',
},
'x-mega-props': {
labelAlign: 'top',
full: true,
},
'x-rules': [
{
required: true,
message: '请上传支付凭证',
},
],
description: '单个凭证文件大小不能超过 200K',
},
},
},
},
};
\ No newline at end of file
......@@ -12,4 +12,8 @@
margin-top: 10px;
text-align: right;
}
.noData {
padding-top: 62px;
}
}
\ No newline at end of file
import React, { Suspense } from 'react';
import React, { Suspense, useEffect, useState, useMemo, useCallback } from 'react';
import {
PageHeader,
Descriptions,
Card,
Spin,
Button,
Badge,
message,
} from 'antd';
import { FormOutlined } from '@ant-design/icons';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history } from 'umi';
import { PublicApi } from '@/services/api';
import { GetPayCreditHandleGetCreditDetailResponse } from '@/services/PayApi';
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus';
import {
CREDIT_REPAYMENT_STATUS,
CREDIT_STATUS,
} from '@/constants';
import AvatarWrap from '@/components/AvatarWrap';
import StatusTag from '@/components/StatusTag';
import {
CREDIT_STATUS_BADGE_MAP,
CREDIT_REPAYMENT_STATUS_TAG_MAP,
} from '../../../constant';
import { BillDetailParams, BillDetailData, BillRecordParams } from './components/IntroduceRow';
import styles from './index.less';
const IntroduceRow = React.lazy(() => import('./components/IntroduceRow'));
......@@ -20,17 +29,107 @@ const BillInfo = React.lazy(() => import('./components/BillInfo'));
const HistoryList = React.lazy(() => import('../../components/HistoryList'));
const QuotaMenageDetail: React.FC = () => {
const { id } = usePageStatus();
const [creditInfo, setCreditInfo] = useState<GetPayCreditHandleGetCreditDetailResponse>(null);
const [creditOverdueList, setCreditOverdueList] = useState([]);
const [infoLoading, setInfoLoading] = useState(false);
const [creditOverdueListLoading, setCreditOverdueListLoading] = useState(false);
// 获取授信详情
const getCreditDetail = () => {
setInfoLoading(true);
PublicApi.getPayCreditHandleGetCreditDetail({
id,
}).then(res => {
if (res.code === 1000) {
setCreditInfo(res.data);
}
}).finally(() => {
setInfoLoading(false);
});
};
useEffect(() => {
getCreditDetail();
getCreditOverdueList();
}, []);
const quotaData = [
{
x: '剩余可用额度(元)',
y: 80,
y: creditInfo && creditInfo.canUseQuota ? creditInfo.canUseQuota : 0,
},
{
x: '已用额度(元)',
y: 20,
y: creditInfo && creditInfo.useQuota ? creditInfo.useQuota : 0,
},
];
];
// 获取账单详情
const fetchBillDetail = (params: BillDetailParams): Promise<BillDetailData> => {
return new Promise((resolve, reject) => {
PublicApi.getPayCreditHandleGetCreditBillDetail(params)
.then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
})
.catch(() => {
reject();
});
});
};
// 获取账单记录列表
const fetchBillRecordList = (params: BillRecordParams): Promise<any> => {
if (!id) {
return;
}
return new Promise((resolve, reject) => {
PublicApi.getPayCreditHandlePageCreditTradeRecord({
creditId: id,
...params,
}).then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
}).catch(() => {
reject();
});
});
};
// 获取逾期列表
const getCreditOverdueList = () => {
if (!id) {
return;
}
setCreditOverdueListLoading(true);
PublicApi.getPayCreditHandlePageCreditOverdue({
creditId: id,
current: '1',
pageSize: '9999', // 暂时写死
}).then(res => {
if (res.code === 1000) {
setCreditOverdueList(res.data.data);
}
}).finally(() => {
setCreditOverdueListLoading(false);
});
};
const normalizeOptions = arr => {
if (!arr || !Array.isArray(arr)) {
return [];
}
return arr.map(item => ({
title: item.name,
value: item.id,
}));
};
return (
<PageHeaderWrapper
......@@ -42,9 +141,9 @@ const QuotaMenageDetail: React.FC = () => {
title={
<AvatarWrap
info={{
name: '订单号:DPTY12',
name: creditInfo?.member?.memberName,
}}
extra="青铜会员"
extra={creditInfo?.member?.levelTag}
/>
}
extra={(
......@@ -60,10 +159,13 @@ const QuotaMenageDetail: React.FC = () => {
padding: '0 32px',
}}
>
<Descriptions.Item label="会员类型">企业会员</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>供应商</Descriptions.Item>
<Descriptions.Item label="会员类型">{creditInfo?.member?.memberTypeName}</Descriptions.Item>
<Descriptions.Item label="会员角色" span={2}>{creditInfo?.member?.roleName}</Descriptions.Item>
<Descriptions.Item label="状态">
<Badge color="#41CC9E" text="正常" />
<Badge
color={CREDIT_STATUS_BADGE_MAP[creditInfo?.member?.status]}
text={CREDIT_STATUS[creditInfo?.member?.status]}
/>
</Descriptions.Item>
<Descriptions.Item label="会员状态" span={2}>
<StatusTag type="success" title="正常" />
......@@ -74,15 +176,28 @@ const QuotaMenageDetail: React.FC = () => {
}
>
<Suspense fallback={null}>
<IntroduceRow quotaData={quotaData} />
<IntroduceRow
quotaData={quotaData}
extraData={{
canUseQuota: creditInfo?.canUseQuota,
useQuota: creditInfo?.useQuota,
quota: creditInfo?.quota,
}}
options={normalizeOptions(creditInfo?.billSelectList)}
fetchBillDetail={fetchBillDetail}
fetchBillRecordList={fetchBillRecordList}
/>
</Suspense>
<Suspense fallback={null}>
<BillInfo />
<BillInfo overdueList={creditOverdueList} loading={creditOverdueListLoading} />
</Suspense>
<Suspense fallback={null}>
<HistoryList />
<HistoryList
dataSource={creditInfo?.historyApplyList}
target="/memberCenter/payandSettle/creditApplication/quotaMenage/history"
/>
</Suspense>
</PageHeaderWrapper>
);
......
......@@ -99,7 +99,7 @@ const QuotaMenage: React.FC = () => {
) : (
<>
<EyePreview
url={`/memberCenter/payandSettle/creditManage/quotaMenage/detail`}
url={`/memberCenter/payandSettle/creditManage/quotaMenage/detail?id=${record.id}`}
>
{text}
</EyePreview>
......
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