188 lines
8.4 KiB
JavaScript
188 lines
8.4 KiB
JavaScript
import React, { useState } from 'react';
|
||
import { Input, DatePicker, Form, Tag, Modal, Alert, Divider, Button } from 'antd';
|
||
import Styles from './web.pc.module.less';
|
||
import ListPro from 'oak-frontend-base/es/components/listPro';
|
||
import { FilterPanel } from '../../../components/AbstractComponents';
|
||
import { RenderOffline } from '../detail/web.pc';
|
||
import { generateNewId } from 'oak-domain/lib/utils/uuid';
|
||
import { ToYuan } from 'oak-domain/lib/utils/money';
|
||
import dayJs from 'dayjs';
|
||
export default function Render(props) {
|
||
const { pays, offlines, oakExecutable, oakFullpath } = props.data;
|
||
const { t, execute, updateItem, setMessage, clean } = props.methods;
|
||
const [spId, setSpId] = useState('');
|
||
if (pays) {
|
||
const spRow = (spId && pays.find(ele => ele.id === spId));
|
||
return (<>
|
||
<FilterPanel oakPath={oakFullpath} entity="pay" columns={[
|
||
{
|
||
attr: 'iState',
|
||
},
|
||
{
|
||
attr: 'externalId',
|
||
op: '$startsWith'
|
||
}
|
||
]}/>
|
||
<ListPro data={pays} entity="pay" attributes={[
|
||
{
|
||
path: 'price',
|
||
label: t('pay:attr.price'),
|
||
width: 100,
|
||
},
|
||
{
|
||
path: 'iState',
|
||
width: 80,
|
||
label: t('pay:attr.iState'),
|
||
},
|
||
{
|
||
path: '$$createAt$$',
|
||
label: t('common::$$createAt$$'),
|
||
width: 100,
|
||
},
|
||
{
|
||
path: 'orderId',
|
||
label: t('label.source'),
|
||
width: 70,
|
||
render(row) {
|
||
const { orderId } = row;
|
||
return (<Tag bordered={false} color={orderId ? 'processing' : 'success'}>
|
||
{orderId ? t('source.order') : t('source.deposit')}
|
||
</Tag>);
|
||
}
|
||
},
|
||
{
|
||
path: 'creatorName',
|
||
label: t('label.cn'),
|
||
width: 140,
|
||
render: (row) => {
|
||
const { creatorName, creatorMobile } = row;
|
||
return (<div>
|
||
<div>{creatorName}</div>
|
||
<div>{creatorMobile}</div>
|
||
</div>);
|
||
}
|
||
},
|
||
{
|
||
path: 'phantom3',
|
||
width: 100,
|
||
label: t('label.code'),
|
||
},
|
||
{
|
||
path: 'channel',
|
||
width: 100,
|
||
label: t('pay:attr.entity'),
|
||
render: (row) => {
|
||
const { entity } = row;
|
||
const colorDict = {
|
||
'account': 'blue',
|
||
'offlineAccount': 'red',
|
||
'wpProduct': 'green',
|
||
};
|
||
return (<div>
|
||
<Tag color={colorDict[entity] || 'gray'}>{t(`payChannel::${row.entity}`)}</Tag>
|
||
{entity === 'offlineAccount' && (<div className={Styles.entityDetail}>
|
||
{t(`offlineAccount:v.type.${row.offlineAccount.type}`)}
|
||
</div>)}
|
||
{entity === 'wpProduct' && <div className={Styles.entityDetail}>
|
||
{t(`wpProduct:v.type.${row.wpProduct.type}`)}
|
||
</div>}
|
||
</div>);
|
||
}
|
||
},
|
||
{
|
||
path: 'externalId',
|
||
width: 100,
|
||
label: t('pay:attr.externalId'),
|
||
}
|
||
]} onAction={(row, action) => {
|
||
if (action === 'close') {
|
||
Modal.confirm({
|
||
title: t('cc.title'),
|
||
content: t('cc.content'),
|
||
onOk() {
|
||
return execute(undefined, undefined, undefined, [
|
||
{
|
||
entity: 'pay',
|
||
operation: {
|
||
id: generateNewId(),
|
||
action: 'close',
|
||
data: {},
|
||
filter: {
|
||
id: row.id,
|
||
},
|
||
},
|
||
}
|
||
]);
|
||
},
|
||
okText: t('common::confirm'),
|
||
cancelText: t('common::action.cancel')
|
||
});
|
||
}
|
||
else if (action === 'succeedPaying') {
|
||
const { entity } = row;
|
||
if (entity !== 'offlineAccount') {
|
||
// 以后可能也有手动成功offline以外的pay的情况,先封掉
|
||
setMessage({
|
||
title: t('spFail.title'),
|
||
content: t('spFail.content'),
|
||
type: 'error',
|
||
});
|
||
}
|
||
else {
|
||
updateItem({
|
||
paid: row.price,
|
||
}, row.id, 'succeedPaying');
|
||
setSpId(row.id);
|
||
}
|
||
}
|
||
}}/>
|
||
<Modal title={t('csp.title')} width={600} destroyOnClose open={!!spId} footer={null} onCancel={() => {
|
||
clean();
|
||
setSpId('');
|
||
}}>
|
||
<div className={Styles.spCon}>
|
||
<Alert type="warning" message={t('csp.tips')}/>
|
||
<Divider style={{ width: '80%', alignSelf: 'flex-end' }}/>
|
||
{offlines && <RenderOffline pay={spRow} t={t} offlines={offlines} offline={offlines.find(ele => ele.id === spRow.entityId)} updateOfflineId={(entityId) => updateItem({
|
||
entity: 'offlineAccount',
|
||
entityId
|
||
}, spId)} updateExternalId={(externalId) => updateItem({
|
||
externalId,
|
||
}, spId)}/>}
|
||
<Divider style={{ width: '80%', alignSelf: 'flex-end' }}/>
|
||
<Form labelCol={{ span: 8 }} wrapperCol={{ span: 12 }} layout="horizontal" style={{ width: '100%', marginTop: 12 }}>
|
||
<Form.Item label={t('pay:attr.price')}>
|
||
<Input value={ToYuan(spRow.price)} addonBefore={t('common::pay.symbol')} disabled={true}/>
|
||
</Form.Item>
|
||
<Form.Item label={t('pay:attr.externalId')} help={t("placeholder.externalId")}>
|
||
<Input maxLength={128} value={spRow.externalId || undefined} onChange={({ currentTarget }) => {
|
||
const { value } = currentTarget;
|
||
updateItem({
|
||
externalId: value,
|
||
}, spId);
|
||
}}/>
|
||
</Form.Item>
|
||
<Form.Item label={t('pay:attr.successAt')}>
|
||
<DatePicker showTime onChange={(value, dateString) => {
|
||
updateItem({
|
||
successAt: value?.valueOf(),
|
||
}, spId);
|
||
}} maxDate={dayJs()}/>
|
||
</Form.Item>
|
||
</Form>
|
||
<div className={Styles.btn}>
|
||
<Button disabled={oakExecutable !== true} type="primary" onClick={async () => {
|
||
const spRow = pays.find(ele => ele.id === spId);
|
||
await execute();
|
||
setSpId('');
|
||
}}>
|
||
{t('common::confirm')}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</Modal>
|
||
</>);
|
||
}
|
||
return null;
|
||
}
|