157 lines
7.9 KiB
TypeScript

import {Button, Col, Form, Row} from "@douyinfe/semi-ui";
import React, {useMemo} from "react";
import dayjs from "dayjs";
import {useTranslation} from "react-i18next";
import {Card} from "@/components/card";
import {BillQueryParams} from "@/service/api/bill.ts";
type SearchFormProps = {
onSearch?: (params: BillQueryParams) => void;
showApply?: boolean;
loading?: boolean;
searchHeader?: React.ReactNode;
searchFooter?: React.ReactNode;
}
type SearchFormFields = {
dateRange?: Date[];
student_number?: string;
id?: string;
application_number?: string;
bill_number?: string;
payment_channel?: string;
bill_status?: string;
apply_status?: string;
sort_by?: string;
}
const SearchForm: React.FC<SearchFormProps> = (props) => {
const formSubmit = (value: SearchFormFields) => {
const params: BillQueryParams = {}
if (value.dateRange && value.dateRange.length == 2) {
params.start_date = dayjs(value.dateRange[0]).format('YYYY-MM-DD');
params.end_date = dayjs(value.dateRange[1]).format('YYYY-MM-DD');
}
if (value.id) {
params.id = value.id;
}
if (value.student_number) {
params.student_number = value.student_number;
}
if (value.application_number) {
params.application_number = value.application_number;
}
// 对账状态
if (value.apply_status) {
params.apply_status = value.apply_status;
}
// 账单状态
if (value.bill_status) {
params.status = value.bill_status;
}
if(!props.showApply){
params.status = 'PAID'
}
// 支付方式
if (value.payment_channel) {
params.payment_channel = value.payment_channel;
}
// 排序
if(value.sort_by){
const [field, order] = value.sort_by.split(' ')
params.sort_field = field
params.sort_order = order?.toUpperCase() || 'DESC'
}else{
params.sort_field = 'id'
params.sort_order = 'DESC'
}
props.onSearch?.(params);
}
const {t, i18n} = useTranslation();
// 根据语言变化更新订单状态options
const billStatusOptions = useMemo(() => {
return [
{value: `PENDING`, label: t('bill.pay_status_pending')},
{value: 'PAID', label: t('bill.pay_status_paid')},
{value: 'CANCELLED', label: t('bill.pay_status_canceled')}
]
}, [i18n.language])
// 根据语言变化更新对账状态options
const applyStatusOptions = useMemo(() => {
return [
{value: 'UNCHECKED', label: t('bill.reconciliation_status_pending')},
{value: 'CHECKED', label: t('bill.reconciliation_status_submitted')}
]
}, [i18n.language])
return (<Card style={{marginBottom: 20}}>
{props.searchHeader}
<div className="bill-search-form">
<Form<SearchFormFields> onSubmit={formSubmit}>
<Row type={'flex'} gutter={20}>
<Col xxl={6} xl={6} md={8}>
<Form.Input showClear field='id' label="ID" trigger='blur' placeholder={t('base.please_enter')}/>
</Col>
<Col xxl={6} xl={6} md={8}>
<Form.DatePicker showClear type={'dateRange'} field="dateRange" label={t('bill.bill_date')}
style={{width: '100%'}}>
</Form.DatePicker>
</Col>
<Col xxl={6} xl={6} md={8}>
<Form.Input showClear field='student_number' label={t('base.student_number')} trigger='blur'
placeholder={t('base.please_enter')}/>
</Col>
<Col xxl={6} xl={6} md={8}>
<Form.Input showClear field='application_number' label={t('base.bill_number')} trigger='blur'
placeholder={t('base.please_enter')}/>
</Col>
<Col xxl={6} xl={6} md={8}>
<Form.Select showClear field="payment_channel" label={t('bill.title_pay_channel')}
placeholder={t('base.please_select')} style={{width: '100%'}}>
<Form.Select.Option value="FLYWIRE">FLYWIRE</Form.Select.Option>
<Form.Select.Option value="CBP">CBP</Form.Select.Option>
<Form.Select.Option value="PPS">PPS</Form.Select.Option>
</Form.Select>
</Col>
<Col xxl={6} xl={6} md={8}>
<Form.Select showClear field="sort_by" label={t('bill.title_pay_sort')}
placeholder={t('base.please_select')} style={{width: '100%'}}>
<Form.Select.Option value="id desc">ID {t('bill.sort_desc')}</Form.Select.Option>
<Form.Select.Option value="id asc">ID {t('bill.sort_asc')}</Form.Select.Option>
<Form.Select.Option value="student_number desc">{t('base.student_number')} {t('bill.sort_desc')}</Form.Select.Option>
<Form.Select.Option value="student_number asc">{t('base.student_number')} {t('bill.sort_asc')}</Form.Select.Option>
<Form.Select.Option value="application_number desc">{t('base.bill_number')} {t('bill.sort_desc')}</Form.Select.Option>
<Form.Select.Option value="application_number asc">{t('base.bill_number')} {t('bill.sort_asc')}</Form.Select.Option>
<Form.Select.Option value="initiated_paid_at desc">{t('bill.title_initiated_paid_at')} {t('bill.sort_desc')}</Form.Select.Option>
<Form.Select.Option value="initiated_paid_at asc">{t('bill.title_initiated_paid_at')} {t('bill.sort_asc')}</Form.Select.Option>
<Form.Select.Option value="delivered_at desc">{t('bill.title_delivered_at')} {t('bill.sort_desc')}</Form.Select.Option>
<Form.Select.Option value="delivered_at asc">{t('bill.title_delivered_at')} {t('bill.sort_asc')}</Form.Select.Option>
</Form.Select>
</Col>
{props.showApply && <>
<Col xxl={6} xl={6} md={8}>
<Form.Select showClear field="bill_status" label={t('bill.pay_status')}
placeholder={t('base.please_select')} style={{width: '100%'}}>
{billStatusOptions.map((item, index) => (
<Form.Select.Option key={index} value={item.value}>{item.label}</Form.Select.Option>))}
</Form.Select>
</Col>
<Col xxl={6} xl={6} md={8}>
<Form.Select showClear field="apply_status" label={t('bill.title_reconciliation_status')}
placeholder={t('base.please_select')} style={{width: '100%'}}>
{applyStatusOptions.map((item, index) => (
<Form.Select.Option key={index} value={item.value}>{item.label}</Form.Select.Option>))}
</Form.Select>
</Col>
</>}
<Col xxl={6} xl={6} md={8} style={{display: 'flex', alignItems: 'flex-end', paddingBottom: 12}}>
<Button loading={props.loading} style={{width: 100}} htmlType={'submit'} theme={'solid'}
type={'primary'}>{t('base.btn_search_submit')}</Button>
</Col>
</Row>
</Form>
</div>
{props.searchFooter}
</Card>)
}
export default SearchForm;