From 5f16a7b27480b9de8fc6df1736bc70ad7ad91ba4 Mon Sep 17 00:00:00 2001 From: callmeyan Date: Fri, 9 Aug 2024 12:28:48 +0800 Subject: [PATCH] feat: add bill type confirm --- src/assets/index.less | 8 + src/components/bill/list.tsx | 25 +- src/components/bill/search-form.tsx | 3 +- src/components/logo/index.tsx | 12 + src/hooks/useBillTypes.ts | 26 ++ src/i18n/translations/en.json | 6 +- src/i18n/translations/sc.json | 2 + src/i18n/translations/tc.json | 2 + src/pages/bill/components/add_bill_modal.tsx | 137 +++++++++++ .../bill/components/bill_type_confirm.tsx | 223 ++++++++++++++---- src/pages/bill/components/number_confirm.tsx | 61 +++-- src/pages/bill/query.tsx | 62 ++--- src/pages/manual/index.tsx | 3 +- src/routes/layout/dashboard-navigation.tsx | 8 +- src/service/api/bill.ts | 8 +- src/service/generate-pdf.ts | 2 +- src/types/bill.d.ts | 23 +- vite.config.ts | 4 +- 18 files changed, 475 insertions(+), 140 deletions(-) create mode 100644 src/hooks/useBillTypes.ts create mode 100644 src/pages/bill/components/add_bill_modal.tsx diff --git a/src/assets/index.less b/src/assets/index.less index 0470733..cf2be41 100644 --- a/src/assets/index.less +++ b/src/assets/index.less @@ -105,6 +105,9 @@ body #root{ } /***************** semi overrides ****************/ +.semi-dropdown-item{ + max-width: 500%; +} .semi-dropdown-item-active { background-color: var(--semi-color-default-active); } @@ -145,6 +148,11 @@ body #root{ border: 1px solid var(--semi-color-focus-border); } } +.semi-tagInput-wrapper-input{ + &:hover{ + border-color: transparent; + } +} .semi-input-wrapper-focus, .semi-datepicker-range-input-active, diff --git a/src/components/bill/list.tsx b/src/components/bill/list.tsx index 3f50200..77931d9 100644 --- a/src/components/bill/list.tsx +++ b/src/components/bill/list.tsx @@ -23,7 +23,7 @@ type BillListProps = { loading?: boolean; beforeTotalAmount?: React.ReactNode; } -const CheckNumberCorrect = ({origin, confirmed}: { origin: string, confirmed?: string }) => { +const CheckNumberCorrect = ({origin, confirmed}: { origin: string, confirmed?: string|null }) => { if (origin == confirmed && origin) { return ({origin}) } @@ -43,7 +43,7 @@ export const BillList: React.FC = (props) => { }>({ showCols: [ "id", "merchant_ref", "student_number", "application_number", "initiated_paid_at", "delivered_at", "paid_at", "student_english_name", "student_email", "programme_chinese_name", - "intake_year", "detail", "_detail", "amount", "pay_amount", "actual_payment_amount", "pay_method", "status", "apply_status" + "intake_year", "detail", "detail_confirms", "amount", "pay_amount", "actual_payment_amount", "pay_method", "status", "apply_status" ] }) @@ -90,16 +90,22 @@ export const BillList: React.FC = (props) => { title: t('base.student_number'), dataIndex: 'student_number', width: 150, - render: (value, record) => ( - ) + render: (value:string) => (value|| 'N/A') }, { title: t('base.bill_number'), dataIndex: 'application_number', width: 150, render: (value, record) => ( - ) + ) }, + // { + // title: t('bill.title_application_number_confirmed'), + // dataIndex: 'application_number', + // width: 150, + // render: (value, record) => ( + // ) + // }, { title:
{t('bill.title_initiated_paid_at')}
(PPS Input Date)
@@ -182,7 +188,7 @@ export const BillList: React.FC = (props) => { }, { title: t('bill.title_bill_type_confirm'), - dataIndex: '_detail', + dataIndex: 'detail_confirms', ellipsis: {showTitle: true}, width: 220, render: (_, record) => (
= (props) => { maxWidth: '100%', whiteSpace: 'normal' }}> - {record.details.filter(s => s.confirm_status == 'CONFIRMED').map((it) => ( -
{it.confirm_type}:
))} + {record.detail_confirms?.map((it) => ( +
{it.bill_type}:
))}
), }, { @@ -327,8 +333,7 @@ export const BillList: React.FC = (props) => {
- - +
diff --git a/src/components/bill/search-form.tsx b/src/components/bill/search-form.tsx index 9f7368f..7cbfaa1 100644 --- a/src/components/bill/search-form.tsx +++ b/src/components/bill/search-form.tsx @@ -4,7 +4,7 @@ import dayjs from "dayjs"; import {useTranslation} from "react-i18next"; import {Card} from "@/components/card"; import {BillQueryParams} from "@/service/api/bill.ts"; -import {BillTypes} from "@/service/bill-types.ts"; +import {useBillTypes} from "@/hooks/useBillTypes.ts"; type SearchFormProps = { onSearch?: (params: BillQueryParams) => void; @@ -27,6 +27,7 @@ type SearchFormFields = { sort_by?: string; } const SearchForm: React.FC = (props) => { + const BillTypes = useBillTypes() const formSubmit = (value: SearchFormFields) => { const params: BillQueryParams = {} diff --git a/src/components/logo/index.tsx b/src/components/logo/index.tsx index ab12516..7e34566 100644 --- a/src/components/logo/index.tsx +++ b/src/components/logo/index.tsx @@ -105,4 +105,16 @@ export const IconReconciliation = ({style}: { style?: React.CSSProperties }) => +) + +export const IconPermission = ({style}: { style?: React.CSSProperties }) => ( + + + + ) \ No newline at end of file diff --git a/src/hooks/useBillTypes.ts b/src/hooks/useBillTypes.ts new file mode 100644 index 0000000..b4c1237 --- /dev/null +++ b/src/hooks/useBillTypes.ts @@ -0,0 +1,26 @@ +import {useEffect, useState} from "react"; +import {selectBillTypeList} from "@/service/api/bill.ts"; + + +type BillTypeItem = { + value: string; + label: string; +} + +const BillTypesCache:BillTypeItem[] = []; +export function useBillTypes(){ + const [BillTypes,setBillTypes] = useState(BillTypesCache) + + useEffect(()=>{ + if(BillTypes.length == 0){ + selectBillTypeList().then(ret => { + const types = ret.filter(it=>!it.description.toUpperCase().startsWith('ADJUSTMENT')) + .map(it=>({value: it.type, label: it.description})) + setBillTypes(types) + BillTypesCache.push(...types) + }) + } + },[]) + + return BillTypes +} \ No newline at end of file diff --git a/src/i18n/translations/en.json b/src/i18n/translations/en.json index f1e67fc..e1e97d1 100644 --- a/src/i18n/translations/en.json +++ b/src/i18n/translations/en.json @@ -14,6 +14,7 @@ "qr-code": "QRCode", "query_bill": "Failed to query bill:", "remove": "Remove", + "save": "Save", "student_number": "Student Number" }, "bill": { @@ -24,6 +25,7 @@ "cancel_confirm_bills": "Confirm the check check bill?", "cancel_success": "Successful cancel bill", "confirm": "Check", + "confirm_amount_exceed_content": "Amount exceeds total amount", "confirm_batch": "Batch Confirm", "confirm_bill": "Confirm Bill Information", "confirm_bill_number": "Confirm Bill Number", @@ -37,6 +39,7 @@ "download-qr-code": "Download QR Code", "download_receipt": "Download receipt", "export_excel": "Export Excel", + "import_bill": "Add Bill", "import_excel": "Import Bill", "paid": "Paid", "paid_confirm": "Please confirm the order status is set to paid", @@ -92,7 +95,8 @@ "menu": { "bill": "Bill Query", "check": "Reconciliation", - "manual": "Manual Pay" + "manual": "Manual Pay", + "permission": "Permission" } }, "login": { diff --git a/src/i18n/translations/sc.json b/src/i18n/translations/sc.json index 80e9d9d..dc05ebd 100644 --- a/src/i18n/translations/sc.json +++ b/src/i18n/translations/sc.json @@ -25,6 +25,7 @@ "cancel_confirm_bills": "确认对账选中账单?", "cancel_success": "作废账单成功", "confirm": "对账", + "confirm_amount_exceed_content": "金额超出总金额", "confirm_batch": "批量对账", "confirm_bill": "确认账单信息", "confirm_bill_number": "确认账单编号", @@ -38,6 +39,7 @@ "download-qr-code": "下载二维码", "download_receipt": "下载收据", "export_excel": "导出账单", + "import_bill": "添加账单", "import_excel": "导入账单", "paid": "已支付", "paid_confirm": "是否将此订单状态设为已支付", diff --git a/src/i18n/translations/tc.json b/src/i18n/translations/tc.json index ededa81..0d6d633 100644 --- a/src/i18n/translations/tc.json +++ b/src/i18n/translations/tc.json @@ -25,6 +25,7 @@ "cancel_confirm_bills": "確認對帳選取帳單?", "cancel_success": "作廢帳單成功", "confirm": "對帳", + "confirm_amount_exceed_content": "金額超出總金額", "confirm_batch": "批次對帳", "confirm_bill": "確認帳單資訊", "confirm_bill_number": "確認帳單編號", @@ -38,6 +39,7 @@ "download-qr-code": "下載二維碼", "download_receipt": "下載收據", "export_excel": "導出賬單", + "import_bill": "新增帳單", "import_excel": "導入賬單", "paid": "已支付", "paid_confirm": "是否將此訂單狀態設為已支付", diff --git a/src/pages/bill/components/add_bill_modal.tsx b/src/pages/bill/components/add_bill_modal.tsx new file mode 100644 index 0000000..f67ec01 --- /dev/null +++ b/src/pages/bill/components/add_bill_modal.tsx @@ -0,0 +1,137 @@ +import {BillDetailItems} from "@/components/bill"; +import {Button, Col, Form, Modal, Row, Select, Space} from "@douyinfe/semi-ui"; +import React from "react"; +import {useTranslation} from "react-i18next"; +import {useSetState} from "ahooks"; +import {useBillTypes} from "@/hooks/useBillTypes.ts"; + +type BillPaidModalProps = { + onConfirm: () => void + onCancel?: () => void +} +export const AddBillModal: React.FC = (props) => { + const {t} = useTranslation() + const BillTypes = useBillTypes() + + const [state, setState] = useSetState<{ + loading?: boolean; + open?:boolean + }>({}) + + + const onSubmit = (values: BillUpdateParams) => { + setState({ + loading: true + }) + } + return (<> + + setState({open:false})} + footer={null} + width={600} + okText={t('base.confirm')} + maskClosable={false} + > + + onSubmit={onSubmit} initValues={{ + payment_channel: 'FLYWIRE', + payment_method: '', + merchant_ref: props.bill?.merchant_ref, + payment_amount: props.bill?.amount, + actual_payment_amount: props.bill?.amount + }}> + + + + { + BillTypes.map((it, idx) => ( + {it.label})) + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/*

{t('bill.paid_confirm')}

*/} +
+ + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/src/pages/bill/components/bill_type_confirm.tsx b/src/pages/bill/components/bill_type_confirm.tsx index f708b40..dfac250 100644 --- a/src/pages/bill/components/bill_type_confirm.tsx +++ b/src/pages/bill/components/bill_type_confirm.tsx @@ -1,73 +1,216 @@ -import {Button, Select, Popconfirm, Space, Tag, Divider, Input} from "@douyinfe/semi-ui"; -import React, {useState} from "react"; +import {Button, Select, Space, Divider, InputNumber, Modal, Toast} from "@douyinfe/semi-ui"; +import React, {useMemo} from "react"; import {useSetState} from "ahooks"; import MoneyFormat from "@/components/money-format.tsx"; -import {confirmBillType} from "@/service/api/bill.ts"; import {useTranslation} from "react-i18next"; -import {BillTypes} from "@/service/bill-types.ts"; +import {useBillTypes} from "@/hooks/useBillTypes.ts"; +import {NumberConfirm} from "@/pages/bill/components/number_confirm.tsx"; +import {BillDetailItems} from "@/components/bill"; +import {BillDetailItem} from "@/components/bill/bill-detail-items.tsx"; +import {IconStudentId} from "@/components/icons"; +import {confirmBillType} from "@/service/api/bill.ts"; type BillTypeConfirmProps = { - data: BillDetail + bill: BillModel; + onClose?: (refresh?: boolean) => void; + onChange?: (confirms: ConfirmedBillDetail[]) => void; } -export const BillTypeConfirm: React.FC = (props) => { - const [it, setItem] = useState(props.data) +const BillTypeConfirmItem = (props: { data: BillDetail; onChange: (confirms: ConfirmedBillDetail[]) => void; }) => { + const it = props.data; + const BillTypes = useBillTypes() const {t} = useTranslation() + const [state, setState] = useSetState<{ - billTypeList: BillTypeConfirm[]; + billTypeList: ConfirmedBillDetail[]; loading?: boolean, confirmed?: boolean, }>({ loading: false, billTypeList: [ - {bill_type:props.data.bill_type,amount:props.data.amount} + {bill_type: props.data.bill_type, bill_detail_id: it.id, amount: Number(props.data.amount)} ] }) - const onConfirmBill = () => { - setState({loading: true}) - // confirmBillType({id: it.id, type: state.bill_type}).then(() => { - // setState({loading: false}) - // setItem({...it, confirm_status: 'CONFIRMED'}) - // }).catch(() => { - // setState({loading: false}) - // }) - } - 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; + const billTypeList = [...state.billTypeList] + if (type == 'type') { + billTypeList[index].bill_type = value + } else { + billTypeList[index].amount = Number(value) + } + // 计算 confirmedTypes 中所有 amount 的总金额 + const totalAmount = billTypeList.reduce((total, item) => { + 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 onRemove = (index:number) =>{ - if(state.billTypeList.length <= 1) return; + const onRemove = (index: number) => { + if (state.billTypeList.length <= 1) return; + const billTypeList = [...state.billTypeList] + billTypeList.splice(index, 1) + setState({billTypeList}) } + 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 (<>
{it.bill_type}
- Total Amount: + Total Amount:
{state.billTypeList.map((item, index) => { - return (
- + return ( +
+ - - onChange(v,index,'amount')} style={{width: 120}}/> - - -
) + + onChange(String(v), index, 'amount')} style={{width: 120}}/> + + +
) })} -
- +
+
) +} + +export const BillTypeConfirm: React.FC = (props) => { + const {t} = useTranslation() + 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 (<> + Bill Type Confirm + { + details.map((it, idx) => ( onChange(it.id, confirmed)} data={it} key={idx}/>)) + } + ) +} + +export const BillTypeConfirmModal: React.FC = (props) => { + const {t} = useTranslation() + const [state, setState] = useSetState<{ + confirm_application_number: string; + detail_confirms: ConfirmedBillDetail[]; + loading?: boolean; + }>({ + confirm_application_number: '', + detail_confirms: [] + }) + + const onBillConfirm = () => { + setState({loading: true}) + confirmBillType([{ + id: props.bill.id, + confirm_student_number: props.bill.student_number, + ...state + }]).then(() => { + props.onClose?.(true) + }).finally(() => { + setState({loading: false}) + }) + } + return ( props.onClose?.()} + > +
+ + } title={t('manual.student_number')} + value={props.bill.student_number || '-'}/> + } title={t('base.bill_number')} + value={props.bill.application_number || '-'}/> + }/> +
+
+ Bill Number Confirm + {/*{*/} + {/* !state.confirmBill.student_number_confirm &&*/} + {/* */} + {/*}*/} + setState({confirm_application_number})} + bill={props.bill} type={'application_number'}/> +
+ setState({detail_confirms})}/> +
+ +
+
) } \ No newline at end of file diff --git a/src/pages/bill/components/number_confirm.tsx b/src/pages/bill/components/number_confirm.tsx index bb9ddd1..c32a6e2 100644 --- a/src/pages/bill/components/number_confirm.tsx +++ b/src/pages/bill/components/number_confirm.tsx @@ -1,55 +1,52 @@ -import {Button, Space, Tag, Input} from "@douyinfe/semi-ui"; -import React from "react"; +import {Space, Input} from "@douyinfe/semi-ui"; +import React, {useEffect} from "react"; import {useSetState} from "ahooks"; import {useTranslation} from "react-i18next"; type NumberConfirmProps = { bill: BillModel; - type: 'student_number' | 'application_number' + type: 'student_number' | 'application_number'; + onChange: (value: string) => void; } -export const NumberConfirm: React.FC = (props) => { +export const NumberConfirm: React.FC = ({bill, type, onChange}) => { const {t} = useTranslation() + const [state, setState] = useSetState({ loading: false, confirmed: false, - confirmNumber: (props.type == 'application_number' ? props.bill.application_number : props.bill.student_number) || '', + confirmNumber: '', }) - const onConfirm = () => { - if (!state.confirmNumber.length) return - setState({loading: true}) - setTimeout(() => { - setState({loading: false, confirmed: true}) - }, 500) - - // confirmBillType({id:it.id,type:state.bill_type}).then(() => { - // setState({loading:false}) - // setItem({...it,confirm_status:'CONFIRMED'}) - // }).catch(() => { - // setState({loading:false}) - // }) + const onValueChange = (confirmNumber: string) => { + setState({confirmNumber}) + onChange(confirmNumber) } + useEffect(() => { + const confirmNumber = (type == 'application_number' ? (bill.application_number_confirm || bill.application_number) : bill.student_number) || ''; + onValueChange(confirmNumber) + }, []) + return
+ style={{marginBottom: 15, marginTop: 15}}>
-
{t(props.type == 'student_number' ? 'bill.confirm_student_number' : 'bill.confirm_bill_number')}
+
{t(type == 'student_number' ? 'bill.confirm_student_number' : 'bill.confirm_bill_number')}
- {!state.confirmed && setState({confirmNumber: String(v)})} - defaultValue={state.confirmNumber} - style={{width: 180}} placeholder={t('base.please_enter')}/>} - { - state.confirmed ? -
{state.confirmNumber}
- CONFIRMED -
: - } + + + {/*{*/} + {/* state.confirmed ? */} + {/*
{state.confirmNumber}
*/} + {/* CONFIRMED*/} + {/*
: {t('base.confirm')}*/} + {/*}*/}
diff --git a/src/pages/bill/query.tsx b/src/pages/bill/query.tsx index 4781d89..c18df83 100644 --- a/src/pages/bill/query.tsx +++ b/src/pages/bill/query.tsx @@ -1,4 +1,4 @@ -import {Button, ButtonGroup, Divider, Modal, Notification, Popconfirm, Toast} from "@douyinfe/semi-ui"; +import {Button, ButtonGroup, Modal, Notification, Popconfirm, Space, Toast} from "@douyinfe/semi-ui"; import {useState} from "react"; import {useRequest, useSetState} from "ahooks"; import {useTranslation} from "react-i18next"; @@ -9,13 +9,10 @@ import BillDetail from "@/components/bill/detail.tsx"; import {billList, BillQueryParams, exportBillList, modifyBillStatus} from "@/service/api/bill.ts"; import {BillStatus, BizError} from "@/service/types.ts"; import {useDownloadReceiptPDF} from "@/service/generate-pdf.ts"; -import {BillDetailItems} from "@/components/bill"; import {BillPaidModal} from "@/pages/bill/components/bill_paid_modal.tsx"; -import {BillTypeConfirm} from "@/pages/bill/components/bill_type_confirm.tsx"; +import {BillTypeConfirmModal} from "@/pages/bill/components/bill_type_confirm.tsx"; import {saveAs} from "file-saver"; -import {IconStudentId} from "@/components/icons"; -import {BillDetailItem} from "@/components/bill/bill-detail-items.tsx"; -import {NumberConfirm} from "@/pages/bill/components/number_confirm.tsx"; +import {AddBillModal} from "@/pages/bill/components/add_bill_modal.tsx"; const DownloadButton = ({bill, text}: { bill: BillModel; text: string }) => { @@ -116,12 +113,17 @@ const BillQuery = () => { console.log(selectKeys) } + const onBillConfirm = (reload?: boolean) => { + setState({confirmBill: undefined}) + if (reload) refresh() + } + return (
+ beforeTotalAmount={ { (selectKeys.length == 0) ? : { } - - - } + + + + + + } onRowSelection={setSelectedKeys} onPageChange={(page_number) => { @@ -164,42 +169,7 @@ const BillQuery = () => { refresh() }} /> - { - refresh() - setState({confirmBill: undefined}) - }} - width={550} - footer={null} - > - {state.confirmBill && <> -
- } title={t('manual.student_number')} - value={state.confirmBill.student_number || '-'}/> - } title={t('base.bill_number')} - value={state.confirmBill.application_number || '-'}/> - }/>
-
- { - !state.confirmBill.student_number_confirm && - - } - { - !state.confirmBill.application_number_confirm && - - } - Bill Type Confirm - { - state.confirmBill.details.map((it, idx) => ()) - } -
- } -
+ {state.confirmBill && }
) } export default BillQuery \ No newline at end of file diff --git a/src/pages/manual/index.tsx b/src/pages/manual/index.tsx index ac0dc1c..0d352fa 100644 --- a/src/pages/manual/index.tsx +++ b/src/pages/manual/index.tsx @@ -3,7 +3,7 @@ import {useTranslation} from "react-i18next"; import {useRef, useState} from "react"; import {Card} from "@/components/card"; -import {BillTypes} from "@/service/bill-types.ts"; +import {useBillTypes} from "@/hooks/useBillTypes.ts"; import {BillDetailItems, useBillQRCode} from "@/components/bill"; import styles from './manual.module.less' @@ -43,6 +43,7 @@ export default function Index() { // useEffect(()=>{ // getBillDetail(100009).then(setBillInfo); // },[]) + const BillTypes = useBillTypes() const BillInfo = ({bill}: { bill?: BillModel }) => { if (!bill) return null; diff --git a/src/routes/layout/dashboard-navigation.tsx b/src/routes/layout/dashboard-navigation.tsx index 801035d..f43de70 100644 --- a/src/routes/layout/dashboard-navigation.tsx +++ b/src/routes/layout/dashboard-navigation.tsx @@ -3,7 +3,7 @@ import {useMemo} from "react"; import {useTranslation} from "react-i18next"; import useAuth from "@/hooks/useAuth.ts"; -import {IconQRCode, IconQuery, IconReconciliation} from "@/components/logo"; +import {IconPermission, IconQRCode, IconQuery, IconReconciliation} from "@/components/logo"; export const AllDashboardMenu = [ { @@ -22,6 +22,12 @@ export const AllDashboardMenu = [ icon: , path: '/dashboard/reconciliation', role: ['root', 'fo'] + }, + { + key: 'permission', + icon: , + path: '/dashboard/permission', + role: ['root'] } ] diff --git a/src/service/api/bill.ts b/src/service/api/bill.ts index 50a82ee..0d32a2a 100644 --- a/src/service/api/bill.ts +++ b/src/service/api/bill.ts @@ -48,6 +48,10 @@ export function createManualBill(params: ManualCreateBillParam) { return post('/manual_payment', params) } +export function selectBillTypeList(){ + return get('/billing_types') +} + // 获取账单详情 export function getBillDetail(id: number) { return get('/bills/' + id) @@ -66,8 +70,8 @@ export function modifyBillStatus(id: number,status: BillStatus) { return put(`/bills/${id}/cancel`,{status}) } -export function confirmBillType({id,type}: {id:number,type: string}) { - return post(`/bill/detail/${id}/confirm`, {confirm_type:type}) +export function confirmBillType(bills:BillConfirmParams[]) { + return post(`/bills/confirm`, {bills}) } export function confirmBills(bill_ids: number[]) { diff --git a/src/service/generate-pdf.ts b/src/service/generate-pdf.ts index cf7aba9..0dab758 100644 --- a/src/service/generate-pdf.ts +++ b/src/service/generate-pdf.ts @@ -61,7 +61,7 @@ export function GeneratePdf(bill: BillModel) { ...(bill.details.map(it=>{ return [ `#${it.id}`, - dayjs(bill.paid_at).format('YYYY-MM-DD'), + bill.paid_at?dayjs(bill.paid_at).format('YYYY-MM-DD'):'', it.bill_type, `${bill.payment_channel}` + (bill.payment_method && bill.payment_channel != bill.payment_method ? `(${bill.payment_method})` : ''), `${it.amount}` diff --git a/src/types/bill.d.ts b/src/types/bill.d.ts index c089235..5f7227b 100644 --- a/src/types/bill.d.ts +++ b/src/types/bill.d.ts @@ -13,8 +13,14 @@ declare type ManualCreateBillParam = { declare type BillDetail = { id: number; bill_type: string; - confirm_status: ConfirmStatus; - confirm_type: string; + amount: decimal; + confirmed?: ConfirmedBillDetail[]; +} + +declare type ConfirmedBillDetail = { + id?: number; + bill_detail_id: number; + bill_type: string; amount: decimal; } /** @@ -38,6 +44,10 @@ declare type BillQueryParam = { sort_field:string; sort_order:SortOrderType; } +declare type BillType = { + type: string; + description: string; +} /** * 账单模型 */ @@ -46,7 +56,7 @@ declare type BillModel = { student_number: string; student_number_confirm?: string; application_number: null | string; - application_number_confirm?: null | string; + confirm_application_number?: null | string; student_email: string; student_tc_name?: string; student_sc_name?: string; @@ -80,6 +90,7 @@ declare type BillModel = { remark: string; confirm_status: ConfirmStatus; details: BillDetail[] + detail_confirms: ConfirmedBillDetail[] | null } @@ -114,4 +125,10 @@ type BillUpdateParams = { type BillTypeConfirm = { bill_type: string; amount: number; +} +type BillConfirmParams = { + id:number; + confirm_application_number:string; + confirm_student_number:string; + detail_confirms:ConfirmedBillDetail[] } \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 83e68da..3c7d82b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -28,8 +28,8 @@ export default defineConfig(({mode}) => { port:10086, proxy: { '/api': { - // target: 'https://test-payment-be.hkchc.team', // - target: 'http://127.0.0.1:50000', // + target: 'https://test-payment-be.hkchc.team', // + // target: 'http://127.0.0.1:50000', // changeOrigin: true, //rewrite: (path) => path.replace(/^\/api/, '') }