157 lines
7.9 KiB
TypeScript
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; |