From b4062b1a082e0c000631dbbe3cb960484a7be560 Mon Sep 17 00:00:00 2001 From: callmeyan Date: Sat, 27 Jul 2024 21:35:37 +0800 Subject: [PATCH] update confirm ui --- public/favicon.png | Bin 4273 -> 0 bytes src/assets/index.less | 6 +- src/components/bill/list.tsx | 19 +-- src/i18n/translations/en.json | 13 +- src/i18n/translations/sc.json | 11 +- src/i18n/translations/tc.json | 11 +- src/pages/bill/query.tsx | 242 ++++++++++++++++++++-------------- src/types/bill.d.ts | 1 + 8 files changed, 176 insertions(+), 127 deletions(-) delete mode 100644 public/favicon.png diff --git a/public/favicon.png b/public/favicon.png deleted file mode 100644 index 58a0e94c5ca6210ccdb800e5690350f8a9fee65b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4273 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 diff --git a/src/assets/index.less b/src/assets/index.less index 8983bb3..bad1278 100644 --- a/src/assets/index.less +++ b/src/assets/index.less @@ -70,7 +70,11 @@ body #root{ text-decoration: none; border-radius: 10px; } - +.table-operation-render{ + display: flex; + gap: 5px; + flex-wrap: wrap; +} .page-content-container { max-width: 90%; width: 1400px; diff --git a/src/components/bill/list.tsx b/src/components/bill/list.tsx index 8eca652..f0a7899 100644 --- a/src/components/bill/list.tsx +++ b/src/components/bill/list.tsx @@ -12,6 +12,7 @@ import {BillStatus} from "@/service/types.ts"; type BillListProps = { type: 'query' | 'reconciliation'; operationRender?: (record: BillModel) => React.ReactNode; + operationRenderWidth?: number; onRowSelection?: (selectedRowKeys: (string | number)[]) => void; source?: RecordList; onPageChange: (pageIndex:number) => void; @@ -30,7 +31,7 @@ export const BillList: React.FC = (props) => { return t('bill.pay_status_pending') case 'PAID': return t('bill.pay_status_paid') - case 'CANCELLED': + case 'CANCELED': return t('bill.pay_status_canceled') default: return billStatus @@ -58,7 +59,7 @@ export const BillList: React.FC = (props) => { title: t('base.student_number'), dataIndex: 'student_number', width: 150, - render: (value) => value ?? 'N/A' + render: (value) => value?.length ?value: 'N/A' }, { title: t('base.bill_number'), @@ -87,6 +88,7 @@ export const BillList: React.FC = (props) => { title: 'Email', dataIndex: 'student_email', width: 200, + render: (value) => value?.length ?value: 'N/A' // render: (_, record) => (
{record.student_english_name}
{record.student_chinese_name}
) }, { @@ -103,12 +105,13 @@ export const BillList: React.FC = (props) => { title: t('bill.title_year'), dataIndex: 'intake_year', width: 120, + render: (_, record) => (
{record.intake_year}/{record.intake_semester}
) }, - { - title: t('bill.title_semester'), - dataIndex: 'intake_semester', - width: 120, - }, + // { + // title: t('bill.title_semester'), + // dataIndex: 'intake_semester', + // width: 120, + // }, { title: t('bill.title_bill_detail'), dataIndex: 'detail', @@ -186,7 +189,7 @@ export const BillList: React.FC = (props) => { title: t('bill.title_operate'), dataIndex: 'operate', fixed: 'right', - width: props.type == 'reconciliation'?120:220, + width: props.operationRenderWidth || (props.type == 'reconciliation'?120:220), render: (_, record) => props.operationRender?.(record), }) } diff --git a/src/i18n/translations/en.json b/src/i18n/translations/en.json index e81a63b..4c7c6c4 100644 --- a/src/i18n/translations/en.json +++ b/src/i18n/translations/en.json @@ -23,6 +23,7 @@ "cancel_success": "Successful cancel bill", "confirm": "Check", "confirm_batch": "Batch Confirm", + "confirm_bill_type": "Confirm Bill", "confirm_confirm_title": "Confirm check the Bill?", "confirm_select_empty": "Require confirm bill data", "confirm_success": "Confirm success!", @@ -32,7 +33,7 @@ "paid": "Paid", "paid_confirm": "Please confirm the order status is set to paid", "pay_status": "Bill Status", - "pay_status_canceled": "CANCELLED", + "pay_status_canceled": "CANCELED", "pay_status_paid": "PAID", "pay_status_pending": "PENDING", "query_amount_current_page": "The total amount of current page", @@ -40,16 +41,20 @@ "reconciliation_status_pending": "UNCHECKED", "reconciliation_status_submitted": "CHECKED", "require_student_number": "Search Student Number", + "sort_asc": "ASC", + "sort_desc": "DESC", "title_actual_payment_amount": "Actually Paid", "title_amount": "Amount", "title_bill_detail": "Bill Detail", "title_bill_list": "Bill List", "title_bill_status": "Bill Status", + "title_create_at": "Input Date", "title_department": "Department", "title_operate": "Operation", "title_paid_at": "Transaction Date", "title_pay_amount": "Pay Amount", "title_pay_method": "Pay Method", + "title_pay_sort": "Sort By", "title_program_id": "Program ID", "title_program_name": "Program", "title_reconciliation_status": "Reconciliation", @@ -57,11 +62,7 @@ "title_service_charge": "Service Charge", "title_student_name": "Student Name", "title_student_name_en": "English Name", - "title_year": "Year", - "title_create_at":"Input Date", - "title_pay_sort":"Sort By", - "sort_desc":"DESC", - "sort_asc":"ASC" + "title_year": "Year" }, "error": { "go_back": "Go Back", diff --git a/src/i18n/translations/sc.json b/src/i18n/translations/sc.json index 516cedb..baa0037 100644 --- a/src/i18n/translations/sc.json +++ b/src/i18n/translations/sc.json @@ -23,6 +23,7 @@ "cancel_success": "作废账单成功", "confirm": "对账", "confirm_batch": "批量对账", + "confirm_bill_type": "确认账单", "confirm_confirm_title": "请确定对账此账单?", "confirm_select_empty": "对账账单为空", "confirm_success": "对账成功!", @@ -40,16 +41,20 @@ "reconciliation_status_pending": "未对账", "reconciliation_status_submitted": "已对账", "require_student_number": "请输入查询学号", + "sort_asc": "升序", + "sort_desc": "降序", "title_actual_payment_amount": "实付金额", "title_amount": "账单金额", "title_bill_detail": "账单详情", "title_bill_list": "账单列表", "title_bill_status": "账单状态", + "title_create_at": "创建时间", "title_department": "学系", "title_operate": "操作", "title_paid_at": "支付时间", "title_pay_amount": "应付金额", "title_pay_method": "支付方式", + "title_pay_sort": "排序方式", "title_program_id": "专业ID", "title_program_name": "就读专业", "title_reconciliation_status": "对账状态", @@ -57,11 +62,7 @@ "title_service_charge": "手续费", "title_student_name": "学生姓名", "title_student_name_en": "英文名称", - "title_year": "学年", - "title_create_at":"创建时间", - "title_pay_sort":"排序方式", - "sort_desc":"降序", - "sort_asc":"升序" + "title_year": "学年" }, "error": { "go_back": "返回上一页", diff --git a/src/i18n/translations/tc.json b/src/i18n/translations/tc.json index 8d740b3..f16a23d 100644 --- a/src/i18n/translations/tc.json +++ b/src/i18n/translations/tc.json @@ -23,6 +23,7 @@ "cancel_success": "作廢帳單成功", "confirm": "對帳", "confirm_batch": "批次對帳", + "confirm_bill_type": "確認賬單", "confirm_confirm_title": "請確定對帳此帳單?", "confirm_select_empty": "對帳帳單為空", "confirm_success": "對帳成功!", @@ -40,16 +41,20 @@ "reconciliation_status_pending": "未對帳", "reconciliation_status_submitted": "已對帳", "require_student_number": "請輸入查詢學號", + "sort_asc": "升序", + "sort_desc": "降序", "title_actual_payment_amount": "實付金額", "title_amount": "帳單金額", "title_bill_detail": "帳單詳情", "title_bill_list": "帳單清單", "title_bill_status": "帳單狀態", + "title_create_at": "創建時間", "title_department": "學系", "title_operate": "操作", "title_paid_at": "付款時間", "title_pay_amount": "應付金額", "title_pay_method": "付款方式", + "title_pay_sort": "排序方式", "title_program_id": "專業ID", "title_program_name": "就讀專業", "title_reconciliation_status": "對帳狀態", @@ -57,11 +62,7 @@ "title_service_charge": "手續費", "title_student_name": "學生姓名", "title_student_name_en": "英文名稱", - "title_year": "學年", - "title_create_at":"創建時間", - "title_pay_sort":"排序方式", - "sort_desc":"降序", - "sort_asc":"升序" + "title_year": "學年" }, "error": { "go_back": "返回上一頁", diff --git a/src/pages/bill/query.tsx b/src/pages/bill/query.tsx index d1e34e7..aca0554 100644 --- a/src/pages/bill/query.tsx +++ b/src/pages/bill/query.tsx @@ -1,4 +1,4 @@ -import {Button, Modal, Notification, Popconfirm, Space, Toast} from "@douyinfe/semi-ui"; +import {Button, Modal, Notification, Popconfirm, Space, Tag, Toast} from "@douyinfe/semi-ui"; import {useState} from "react"; import {useRequest, useSetState} from "ahooks"; import {useTranslation} from "react-i18next"; @@ -11,13 +11,13 @@ import {BillStatus, BizError} from "@/service/types.ts"; import {useDownloadReceiptPDF} from "@/service/generate-pdf.ts"; import useAuth from "@/hooks/useAuth.ts"; import {BillDetailItems} from "@/components/bill"; +import MoneyFormat from "@/components/money-format.tsx"; -const DownloadButton = ({bill,text}: { bill: BillModel;text:string }) => { - const {loading: downloading, downloadPDF} = useDownloadReceiptPDF() - return () +const DownloadButton = ({bill, text}: { bill: BillModel; text: string }) => { + const {loading: downloading, downloadPDF} = useDownloadReceiptPDF() + return () } // const ConfirmPaidBill =({bill,onRefresh}: { bill: BillModel;onRefresh:()=>void }) => { @@ -25,63 +25,66 @@ const DownloadButton = ({bill,text}: { bill: BillModel;text:string }) => { // } const BillQuery = () => { - const {user} = useAuth(); - const [state,setState] = useSetState<{ - updateBill?: BillModel - updateLoading?:boolean - }>({}) - const [showBill, setShowBill] = useState() - const [queryParams, setBillQueryParams] = useState({}); - const {data, loading, refresh} = useRequest(() => billList({ - ...queryParams, - department: user?.department == 'RO' ? 'RO' : 'FO', - }), { - refreshDeps: [queryParams], - onError: (e) => { - Notification.error({title: 'Error', content: e.message}) - } - }) - const {t} = useTranslation() + const {user} = useAuth(); + const [state, setState] = useSetState<{ + updateBill?: BillModel + updateLoading?: boolean + confirmBill?: BillModel + }>({}) + const [showBill, setShowBill] = useState() + const [queryParams, setBillQueryParams] = useState({}); + const {data, loading, refresh} = useRequest(() => billList({ + ...queryParams, + department: user?.department == 'RO' ? 'RO' : 'FO', + }), { + refreshDeps: [queryParams], + onError: (e) => { + Notification.error({title: 'Error', content: e.message}) + } + }) + const {t} = useTranslation() - const onConfirmCancel = (bill: BillModel) => { - modifyBillStatus(bill.id,'CANCELLED').then(() => { - Notification.success({title: 'Notice', content: t('bill.cancel_success')}) - refresh() - }).catch((e:BizError) => { - Toast.error({ - content: `${t('base.operate_fail')}:${e.message}`, - duration: 3 - }) - }) - } + const onConfirmCancel = (bill: BillModel) => { + modifyBillStatus(bill.id, 'CANCELLED').then(() => { + Notification.success({title: 'Notice', content: t('bill.cancel_success')}) + refresh() + }).catch((e: BizError) => { + Toast.error({ + content: `${t('base.operate_fail')}:${e.message}`, + duration: 3 + }) + }) + } - const onConfirmPaid = () => { - if(!state.updateBill) return; - setState({ - updateLoading: true - }) - modifyBillStatus(state.updateBill.id,'PAID').then(() => { - setState({ - updateBill: undefined,updateLoading: false - }) - Notification.success({title: 'Notice', content: t('base.operate_success')}) - refresh() - }).catch((e:BizError) => { + const onConfirmPaid = () => { + if (!state.updateBill) return; + setState({ + updateLoading: true + }) + modifyBillStatus(state.updateBill.id, 'PAID').then(() => { + setState({ + updateBill: undefined, updateLoading: false + }) + Notification.success({title: 'Notice', content: t('base.operate_success')}) + refresh() + }).catch((e: BizError) => { setState({ updateLoading: false }) - Toast.error({ - content: `${t('base.operate_fail')}:${e.message}`, - duration: 3 - }) - }) - } - const operation = (bill: BillModel) => { + Toast.error({ + content: `${t('base.operate_fail')}:${e.message}`, + duration: 3 + }) + }) + } + const operation = (bill: BillModel) => { - return ( - {bill.status != BillStatus.PAID && - } - {bill.status == BillStatus.PENDING && <> + return (
+ {bill.status != BillStatus.PAID && + + } + {bill.status == BillStatus.PENDING && <> { - {AppMode == 'development' && 支付} + {AppMode == 'development' && 支付} } - { - bill.status == BillStatus.PAID && - } - ) - } - return (
- - { - setBillQueryParams({ - ...queryParams, - page_number - }) - }} - /> - setShowBill(undefined)} //>=1.16.0 - closeOnEsc={true} - footer={null} - closeIcon={} - > - {showBill && setShowBill(undefined)}/>} - - { - setState({updateBill:undefined,updateLoading:false}) - }} - confirmLoading={state.updateLoading} - onOk={onConfirmPaid} - okText={t('base.confirm_paid')} - maskClosable={false} - > - {state.updateBill &&
} -

{t('bill.paid_confirm')}

-
-
) + { + bill.status == BillStatus.PAID && <> + + + + } +
) + } + return (
+ + { + setBillQueryParams({ + ...queryParams, + page_number + }) + }} + /> + setShowBill(undefined)} //>=1.16.0 + closeOnEsc={true} + footer={null} + closeIcon={} + > + {showBill && setShowBill(undefined)}/>} + + { + setState({updateBill: undefined, updateLoading: false}) + }} + confirmLoading={state.updateLoading} + onOk={onConfirmPaid} + okText={t('base.confirm_paid')} + maskClosable={false} + > + {state.updateBill &&
} +

{t('bill.paid_confirm')}

+
+ { + setState({confirmBill: undefined}) + }} + footer={null} + > + {state.confirmBill && <> +
+
+ { + state.confirmBill.details.map((it, idx) => (
+ + {it.id}. + {it.bill_type} +
+ +
+
+
+ {!!it.confirm_status ? CONFIRMED:} + +
+
)) + } +
+ } +
+
) } export default BillQuery \ No newline at end of file diff --git a/src/types/bill.d.ts b/src/types/bill.d.ts index 7f1e5fc..b119cc5 100644 --- a/src/types/bill.d.ts +++ b/src/types/bill.d.ts @@ -12,6 +12,7 @@ declare type BillDetail = { id: string | number; bill_id: string | number; bill_type: string; + confirm_status?: number; amount: decimal; } /**