🚀 feat: update bill confirm
This commit is contained in:
parent
551bd7d10c
commit
b16d6a237d
@ -252,7 +252,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
) : 'N/A'),
|
) : 'N/A'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('bill.title_bill_status'),
|
title: t('bill.pay_status'),
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
width: 150,
|
width: 150,
|
||||||
render: value => billStatusText(value),
|
render: value => billStatusText(value),
|
||||||
@ -304,7 +304,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
title={<Space>
|
title={<Space>
|
||||||
<span>{t('bill.title_bill_list')}</span>
|
<span>{t('bill.title_bill_list')}</span>
|
||||||
<span
|
<span
|
||||||
className={'cursor-pointer'} style={{color:'pink'}}
|
className={'cursor-pointer'} style={{color:'#0062d6'}}
|
||||||
onClick={() => setState({showColumnsConfig: !state.showColumnsConfig})}
|
onClick={() => setState({showColumnsConfig: !state.showColumnsConfig})}
|
||||||
><IconSetting /></span>
|
><IconSetting /></span>
|
||||||
</Space>}
|
</Space>}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"operate_success": "Operation success",
|
"operate_success": "Operation success",
|
||||||
"please_enter": "Please Enter",
|
"please_enter": "Please Enter",
|
||||||
"please_select": "Please Select",
|
"please_select": "Please Select",
|
||||||
|
"please_select_bill_type": "Please Select Bill Type",
|
||||||
"qr-code": "QRCode",
|
"qr-code": "QRCode",
|
||||||
"query_bill": "Failed to query bill:",
|
"query_bill": "Failed to query bill:",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
@ -31,6 +32,7 @@
|
|||||||
"confirm_bill_number": "Confirm Bill Number",
|
"confirm_bill_number": "Confirm Bill Number",
|
||||||
"confirm_bill_type": "Confirm Bill",
|
"confirm_bill_type": "Confirm Bill",
|
||||||
"confirm_bill_type_batch": "Batch confirm Bill Type",
|
"confirm_bill_type_batch": "Batch confirm Bill Type",
|
||||||
|
"confirm_bill_warning_amount": "The bill amount and actual payment amount are inconsistent",
|
||||||
"confirm_confirm_title": "Confirm check and sync the Bill?",
|
"confirm_confirm_title": "Confirm check and sync the Bill?",
|
||||||
"confirm_select_empty": "Require confirm bill data",
|
"confirm_select_empty": "Require confirm bill data",
|
||||||
"confirm_student_number": "Confirm Student Number",
|
"confirm_student_number": "Confirm Student Number",
|
||||||
@ -38,12 +40,12 @@
|
|||||||
"confirmed": "Confirmed",
|
"confirmed": "Confirmed",
|
||||||
"download-qr-code": "Download QR Code",
|
"download-qr-code": "Download QR Code",
|
||||||
"download_receipt": "Download receipt",
|
"download_receipt": "Download receipt",
|
||||||
"export_excel": "Export Excel",
|
"export_excel": "Export Transaction Excel",
|
||||||
"import_bill": "Add Bill",
|
"import_bill": "Add Transaction Record",
|
||||||
"import_excel": "Import Bill",
|
"import_excel": "Import Transaction Excel",
|
||||||
"paid": "Paid",
|
"paid": "Paid",
|
||||||
"paid_confirm": "Please confirm the order status is set to paid",
|
"paid_confirm": "Please confirm the order status is set to paid",
|
||||||
"pay_status": "Bill Status",
|
"pay_status": "Bill Payment Status",
|
||||||
"pay_status_canceled": "CANCELED",
|
"pay_status_canceled": "CANCELED",
|
||||||
"pay_status_expired": "EXPIRED",
|
"pay_status_expired": "EXPIRED",
|
||||||
"pay_status_paid": "PAID",
|
"pay_status_paid": "PAID",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"operate_success": "操作成功",
|
"operate_success": "操作成功",
|
||||||
"please_enter": "请输入",
|
"please_enter": "请输入",
|
||||||
"please_select": "请选择",
|
"please_select": "请选择",
|
||||||
|
"please_select_bill_type": "请选择账单类型",
|
||||||
"qr-code": "二维码",
|
"qr-code": "二维码",
|
||||||
"query_bill": "查询账单失败:",
|
"query_bill": "查询账单失败:",
|
||||||
"remove": "删除",
|
"remove": "删除",
|
||||||
@ -31,6 +32,7 @@
|
|||||||
"confirm_bill_number": "确认账单编号",
|
"confirm_bill_number": "确认账单编号",
|
||||||
"confirm_bill_type": "确认账单",
|
"confirm_bill_type": "确认账单",
|
||||||
"confirm_bill_type_batch": "批量确认账单",
|
"confirm_bill_type_batch": "批量确认账单",
|
||||||
|
"confirm_bill_warning_amount": "账单金额和实付金额不一致",
|
||||||
"confirm_confirm_title": "请确定对账并同步此账单?",
|
"confirm_confirm_title": "请确定对账并同步此账单?",
|
||||||
"confirm_select_empty": "对账账单为空",
|
"confirm_select_empty": "对账账单为空",
|
||||||
"confirm_student_number": "确认学号",
|
"confirm_student_number": "确认学号",
|
||||||
@ -38,12 +40,12 @@
|
|||||||
"confirmed": "已对账",
|
"confirmed": "已对账",
|
||||||
"download-qr-code": "下载二维码",
|
"download-qr-code": "下载二维码",
|
||||||
"download_receipt": "下载收据",
|
"download_receipt": "下载收据",
|
||||||
"export_excel": "导出账单",
|
"export_excel": "导出交易记录",
|
||||||
"import_bill": "添加账单",
|
"import_bill": "添加交易记录",
|
||||||
"import_excel": "导入账单",
|
"import_excel": "导入交易记录",
|
||||||
"paid": "已支付",
|
"paid": "已支付",
|
||||||
"paid_confirm": "是否将此订单状态设为已支付",
|
"paid_confirm": "是否将此订单状态设为已支付",
|
||||||
"pay_status": "账单状态",
|
"pay_status": "账单支付状态",
|
||||||
"pay_status_canceled": "已作废",
|
"pay_status_canceled": "已作废",
|
||||||
"pay_status_expired": "已过期",
|
"pay_status_expired": "已过期",
|
||||||
"pay_status_paid": "已支付",
|
"pay_status_paid": "已支付",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"operate_success": "操作成功",
|
"operate_success": "操作成功",
|
||||||
"please_enter": "請輸入",
|
"please_enter": "請輸入",
|
||||||
"please_select": "請選擇",
|
"please_select": "請選擇",
|
||||||
|
"please_select_bill_type": "請選擇帳單類型",
|
||||||
"qr-code": "QRCode",
|
"qr-code": "QRCode",
|
||||||
"query_bill": "查詢帳單失敗:",
|
"query_bill": "查詢帳單失敗:",
|
||||||
"remove": "刪除",
|
"remove": "刪除",
|
||||||
@ -31,6 +32,7 @@
|
|||||||
"confirm_bill_number": "確認帳單編號",
|
"confirm_bill_number": "確認帳單編號",
|
||||||
"confirm_bill_type": "確認賬單",
|
"confirm_bill_type": "確認賬單",
|
||||||
"confirm_bill_type_batch": "批次確認帳單",
|
"confirm_bill_type_batch": "批次確認帳單",
|
||||||
|
"confirm_bill_warning_amount": "账单金额和实付金额不一致",
|
||||||
"confirm_confirm_title": "請確定對帳并同步此帳單?",
|
"confirm_confirm_title": "請確定對帳并同步此帳單?",
|
||||||
"confirm_select_empty": "對帳帳單為空",
|
"confirm_select_empty": "對帳帳單為空",
|
||||||
"confirm_student_number": "確認學號",
|
"confirm_student_number": "確認學號",
|
||||||
@ -38,12 +40,12 @@
|
|||||||
"confirmed": "已對帳",
|
"confirmed": "已對帳",
|
||||||
"download-qr-code": "下載二維碼",
|
"download-qr-code": "下載二維碼",
|
||||||
"download_receipt": "下載收據",
|
"download_receipt": "下載收據",
|
||||||
"export_excel": "導出賬單",
|
"export_excel": "導出交易记录",
|
||||||
"import_bill": "新增帳單",
|
"import_bill": "新增交易记录",
|
||||||
"import_excel": "導入賬單",
|
"import_excel": "導入交易记录",
|
||||||
"paid": "已支付",
|
"paid": "已支付",
|
||||||
"paid_confirm": "是否將此訂單狀態設為已支付",
|
"paid_confirm": "是否將此訂單狀態設為已支付",
|
||||||
"pay_status": "帳單狀態",
|
"pay_status": "帳單支付狀態",
|
||||||
"pay_status_canceled": "已作廢",
|
"pay_status_canceled": "已作廢",
|
||||||
"pay_status_expired": "已過期",
|
"pay_status_expired": "已過期",
|
||||||
"pay_status_paid": "已付款",
|
"pay_status_paid": "已付款",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Button, Select, Space, Divider, InputNumber, Modal,} from "@douyinfe/semi-ui";
|
import {Button, Select, Space, Divider, InputNumber, Modal,} from "@douyinfe/semi-ui";
|
||||||
import React, {useMemo} from "react";
|
import React from "react";
|
||||||
import {useSetState} from "ahooks";
|
import {useSetState} from "ahooks";
|
||||||
import MoneyFormat from "@/components/money-format.tsx";
|
import MoneyFormat from "@/components/money-format.tsx";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
@ -7,7 +7,7 @@ import {useBillTypes} from "@/hooks/useBillTypes.ts";
|
|||||||
import {NumberConfirm} from "@/pages/bill/components/number_confirm.tsx";
|
import {NumberConfirm} from "@/pages/bill/components/number_confirm.tsx";
|
||||||
import {BillDetailItems} from "@/components/bill";
|
import {BillDetailItems} from "@/components/bill";
|
||||||
import {BillDetailItem} from "@/components/bill/bill-detail-items.tsx";
|
import {BillDetailItem} from "@/components/bill/bill-detail-items.tsx";
|
||||||
import {IconStudentId} from "@/components/icons";
|
import {IconMoney, IconStudentId} from "@/components/icons";
|
||||||
import {confirmBillType} from "@/service/api/bill.ts";
|
import {confirmBillType} from "@/service/api/bill.ts";
|
||||||
|
|
||||||
type BillTypeConfirmProps = {
|
type BillTypeConfirmProps = {
|
||||||
@ -16,78 +16,52 @@ type BillTypeConfirmProps = {
|
|||||||
onChange?: (confirms: ConfirmedBillDetail[]) => void;
|
onChange?: (confirms: ConfirmedBillDetail[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BillTypeConfirmItem = (props: { data: BillDetail; onChange: (confirms: ConfirmedBillDetail[]) => void; }) => {
|
export const BillTypeConfirm: React.FC<BillTypeConfirmProps> = (props) => {
|
||||||
const it = props.data;
|
|
||||||
const BillTypes = useBillTypes()
|
|
||||||
const {t} = useTranslation()
|
const {t} = useTranslation()
|
||||||
|
const confirmed: ConfirmedBillDetail[] = props.bill.details.map(it=>({
|
||||||
const [state, setState] = useSetState<{
|
bill_type: it.bill_type,
|
||||||
billTypeList: ConfirmedBillDetail[];
|
bill_detail_id: it.id,
|
||||||
loading?: boolean,
|
amount: it.amount
|
||||||
confirmed?: boolean,
|
}))
|
||||||
}>({
|
const [state, setState] = useSetState({
|
||||||
loading: false,
|
confirm_application_number: '', confirmed
|
||||||
billTypeList: [
|
|
||||||
{bill_type: props.data.bill_type, bill_detail_id: it.id, amount: Number(props.data.amount)}
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
const BillTypes = useBillTypes()
|
||||||
|
|
||||||
const onChange = (value: string, index: number, type: 'type' | 'amount') => {
|
const onChange = (value: string, index: number, type: 'type' | 'amount') => {
|
||||||
if (state.billTypeList.length <= index || !value) return;
|
if (state.confirmed.length <= index || !value) return;
|
||||||
const billTypeList = [...state.billTypeList]
|
const confirmed = [...state.confirmed]
|
||||||
if (type == 'type') {
|
if (type == 'type') {
|
||||||
billTypeList[index].bill_type = value
|
confirmed[index].bill_type = value
|
||||||
} else {
|
} else {
|
||||||
billTypeList[index].amount = Number(value)
|
confirmed[index].amount = Number(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算 confirmedTypes 中所有 amount 的总金额
|
setState({confirmed})
|
||||||
const totalAmount = billTypeList.reduce((total, item) => {
|
props.onChange?.(confirmed)
|
||||||
return total + Number(item.amount)
|
|
||||||
}, 0)
|
|
||||||
// 判断是否已经超出账单实际金额
|
|
||||||
if (totalAmount > Number(it.amount)) {
|
|
||||||
Modal.warning({
|
|
||||||
title: 'Warning',
|
|
||||||
content: t('bill.confirm_amount_exceed_content'),
|
|
||||||
hasCancel: false
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setState({billTypeList})
|
|
||||||
props.onChange(billTypeList)
|
const addOrRemove = (index:number)=>{
|
||||||
}
|
// 不允许删除最后一个
|
||||||
const onRemove = (index: number) => {
|
if (index > -1 && state.confirmed.length <= 1) return;
|
||||||
if (state.billTypeList.length <= 1) return;
|
const confirmed = [...state.confirmed,...(index==-1?[{bill_type: '', amount: 0, bill_detail_id: 0}]:[])]
|
||||||
const billTypeList = [...state.billTypeList]
|
if(index > -1) confirmed.splice(index, 1)
|
||||||
billTypeList.splice(index, 1)
|
setState({confirmed})
|
||||||
setState({billTypeList})
|
props.onChange?.(confirmed)
|
||||||
}
|
|
||||||
const onAdd = () => {
|
|
||||||
const billTypeList = [
|
|
||||||
...state.billTypeList,
|
|
||||||
{bill_type: props.data.bill_type, amount: 0, bill_detail_id: it.id}
|
|
||||||
]
|
|
||||||
setState({
|
|
||||||
billTypeList
|
|
||||||
})
|
|
||||||
props.onChange(billTypeList)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
<div className="confirm-item" style={{margin: '20px 0'}}>
|
<Divider>Bill Type Confirm</Divider>
|
||||||
<div style={{lineHeight: 1.1}} className={'align-center'}>
|
{
|
||||||
<div>{it.bill_type}</div>
|
state.confirmed.map((item, index) => (
|
||||||
<span style={{margin: '0 10px 0 120px'}}>Total Amount:</span>
|
<div key={index} className="confirm-item-btn align-center space-between" style={{marginTop: 20}}>
|
||||||
<MoneyFormat money={it.amount}/>
|
|
||||||
</div>
|
|
||||||
{state.billTypeList.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<div key={index} className="confirm-item-btn align-center space-between" style={{marginTop: 10}}>
|
|
||||||
<Select
|
<Select
|
||||||
value={item.bill_type || it.bill_type}
|
value={item.bill_type}
|
||||||
style={{width: 200}}
|
style={{width: 240}}
|
||||||
onChange={v => onChange(String(v), index, 'type')}
|
onChange={v => onChange(String(v), index, 'type')}
|
||||||
placeholder={t('manual.bill_type')}>
|
placeholder={t('base.please_select_bill_type')}>
|
||||||
{
|
{
|
||||||
BillTypes.map((it, idx) => (
|
BillTypes.map((it, idx) => (
|
||||||
<Select.Option key={idx} value={it.label}>{it.label}</Select.Option>))
|
<Select.Option key={idx} value={it.label}>{it.label}</Select.Option>))
|
||||||
@ -97,60 +71,18 @@ const BillTypeConfirmItem = (props: { data: BillDetail; onChange: (confirms: Con
|
|||||||
<Space spacing={10}>
|
<Space spacing={10}>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
hideButtons precision={2} value={item.amount} type={'number'}
|
hideButtons precision={2} value={item.amount} type={'number'}
|
||||||
onChange={v => onChange(String(v), index, 'amount')} style={{width: 120}}/>
|
onChange={v => onChange(String(v), index, 'amount')} style={{width: 140}}/>
|
||||||
<Button
|
<Button
|
||||||
disabled={state.billTypeList.length <= 1} onClick={() => onRemove(index)}
|
disabled={state.confirmed.length <= 1} onClick={() => addOrRemove(index)}
|
||||||
theme={'solid'} type={'secondary'}>{t('base.remove')}</Button>
|
theme={'solid'} type={'secondary'}>{t('base.remove')}</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</div>)
|
|
||||||
})}
|
|
||||||
<div style={{marginTop: 10}}>
|
|
||||||
<Button onClick={onAdd}>{t('base.add')}</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
<div style={{marginTop: 10,marginBottom:20}}>
|
||||||
|
<Button onClick={()=>addOrRemove(-1)}>{t('base.add')}</Button>
|
||||||
</div>
|
</div>
|
||||||
<Divider margin='12px'/>
|
<Divider />
|
||||||
</>)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const BillTypeConfirm: React.FC<BillTypeConfirmProps> = (props) => {
|
|
||||||
const [state, setState] = useSetState<{
|
|
||||||
confirm_application_number: string;
|
|
||||||
confirmed: {
|
|
||||||
[key: number]: ConfirmedBillDetail[]
|
|
||||||
}
|
|
||||||
}>({
|
|
||||||
confirm_application_number: '', confirmed: {}
|
|
||||||
})
|
|
||||||
const details = useMemo(() => {
|
|
||||||
const {details, detail_confirms} = props.bill;
|
|
||||||
if (!details) return [];
|
|
||||||
details.forEach(it => {
|
|
||||||
if (!detail_confirms) it.confirmed = [];
|
|
||||||
else it.confirmed = detail_confirms.filter(s => s.bill_detail_id == it.id)
|
|
||||||
})
|
|
||||||
return details;
|
|
||||||
}, [props.bill])
|
|
||||||
|
|
||||||
const onChange = (id: number, confirmedTypes: ConfirmedBillDetail[]) => {
|
|
||||||
const confirmed = {
|
|
||||||
...state.confirmed
|
|
||||||
};
|
|
||||||
confirmed[id] = confirmedTypes
|
|
||||||
setState({confirmed})
|
|
||||||
// trigger
|
|
||||||
const allConfirmed: ConfirmedBillDetail[] = [];
|
|
||||||
Object.keys(confirmed).forEach(key => {
|
|
||||||
allConfirmed.push(...confirmed[Number(key)])
|
|
||||||
})
|
|
||||||
props.onChange?.(allConfirmed)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (<>
|
|
||||||
<Divider>Bill Type Confirm</Divider>
|
|
||||||
{
|
|
||||||
details.map((it, idx) => (<BillTypeConfirmItem
|
|
||||||
onChange={(confirmed) => onChange(it.id, confirmed)} data={it} key={idx}/>))
|
|
||||||
}
|
|
||||||
</>)
|
</>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +98,19 @@ export const BillTypeConfirmModal: React.FC<BillTypeConfirmProps> = (props) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const onBillConfirm = () => {
|
const onBillConfirm = () => {
|
||||||
|
// 判断confirm的总金额是否和实付金额相等
|
||||||
|
const total = state.detail_confirms.reduce((total, item) => {
|
||||||
|
return total + item.amount
|
||||||
|
}, 0)
|
||||||
|
if(total != props.bill.actual_payment_amount){
|
||||||
|
Modal.warning({
|
||||||
|
title: 'Warning',
|
||||||
|
content: t('bill.confirm_bill_warning_amount')
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
setState({loading: true})
|
setState({loading: true})
|
||||||
confirmBillType([{
|
confirmBillType([{
|
||||||
id: props.bill.id,
|
id: props.bill.id,
|
||||||
@ -194,6 +139,9 @@ export const BillTypeConfirmModal: React.FC<BillTypeConfirmProps> = (props) => {
|
|||||||
icon={<IconStudentId/>} title={t('base.bill_number')}
|
icon={<IconStudentId/>} title={t('base.bill_number')}
|
||||||
value={props.bill.application_number || '-'}/>
|
value={props.bill.application_number || '-'}/>
|
||||||
</>}/>
|
</>}/>
|
||||||
|
<BillDetailItem
|
||||||
|
icon={<IconMoney/>} title={t('bill.title_actual_payment_amount')}
|
||||||
|
value={<MoneyFormat money={props.bill.actual_payment_amount}/>}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="confirm-number-container" style={{padding: '15px 0'}}>
|
<div className="confirm-number-container" style={{padding: '15px 0'}}>
|
||||||
<Divider>Bill Number Confirm</Divider>
|
<Divider>Bill Number Confirm</Divider>
|
||||||
@ -206,7 +154,7 @@ export const BillTypeConfirmModal: React.FC<BillTypeConfirmProps> = (props) => {
|
|||||||
bill={props.bill} type={'application_number'}/>
|
bill={props.bill} type={'application_number'}/>
|
||||||
</div>
|
</div>
|
||||||
<BillTypeConfirm bill={props.bill} onChange={detail_confirms => setState({detail_confirms})}/>
|
<BillTypeConfirm bill={props.bill} onChange={detail_confirms => setState({detail_confirms})}/>
|
||||||
<div className={'text-center'} style={{paddingBottom: 20}}>
|
<div className={'text-center'} style={{paddingBottom: 20,marginTop:20}}>
|
||||||
<Button
|
<Button
|
||||||
onClick={onBillConfirm} loading={state.loading} type={'primary'}
|
onClick={onBillConfirm} loading={state.loading} type={'primary'}
|
||||||
theme={'solid'}>{t('base.confirm')}</Button>
|
theme={'solid'}>{t('base.confirm')}</Button>
|
||||||
|
@ -36,7 +36,7 @@ export const NumberConfirm: React.FC<NumberConfirmProps> = ({bill, type, onChang
|
|||||||
<div className="confirm-item-btn">
|
<div className="confirm-item-btn">
|
||||||
<Space spacing={15}>
|
<Space spacing={15}>
|
||||||
<Input
|
<Input
|
||||||
onChange={onValueChange} style={{width: 180}}
|
onChange={onValueChange} style={{width: 200}}
|
||||||
value={state.confirmNumber} placeholder={t('base.please_enter')}/>
|
value={state.confirmNumber} placeholder={t('base.please_enter')}/>
|
||||||
|
|
||||||
{/*{*/}
|
{/*{*/}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user