123 lines
5.5 KiB
TypeScript
123 lines
5.5 KiB
TypeScript
import {Button, Col, Form, Row} from "@douyinfe/semi-ui";
|
|
import React, {useMemo} from "react";
|
|
import {Card} from "@/components/card";
|
|
import {useTranslation} from "react-i18next";
|
|
import {BillQueryParams} from "@/service/api/bill.ts";
|
|
import dayjs from "dayjs";
|
|
import useAuth from "@/hooks/useAuth.ts";
|
|
|
|
type SearchFormProps = {
|
|
onSearch?: (params: BillQueryParams) => void;
|
|
showApply?: boolean;
|
|
loading?: boolean;
|
|
searchHeader?: React.ReactNode;
|
|
searchFooter?: React.ReactNode;
|
|
}
|
|
type SearchFormFields = {
|
|
dateRange?: Date[];
|
|
student_number?: string;
|
|
application_number?: string;
|
|
bill_number?: string;
|
|
payment_channel?: string;
|
|
bill_status?: string;
|
|
apply_status?: string;
|
|
}
|
|
const SearchForm: React.FC<SearchFormProps> = (props) => {
|
|
const {user} = useAuth();
|
|
const formSubmit = (value: SearchFormFields) => {
|
|
const params: BillQueryParams = {
|
|
department: user?.department == 'RO' ? 'RO' : 'FO',
|
|
}
|
|
|
|
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.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 (value.payment_channel) {
|
|
params.payment_channel = value.payment_channel;
|
|
}
|
|
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 span={4} md={6}>
|
|
<Form.DatePicker type={'dateRange'} field="dateRange" label={t('bill.bill_date')}
|
|
style={{width: '100%'}}>
|
|
</Form.DatePicker>
|
|
</Col>
|
|
<Col span={4} md={6}>
|
|
<Form.Input field='student_number' label={t('base.student_number')} trigger='blur'
|
|
placeholder={t('base.please_enter')}/>
|
|
</Col>
|
|
<Col span={4} md={6}>
|
|
<Form.Input field='application_number' label={t('base.bill_number')} trigger='blur'
|
|
placeholder={t('base.please_enter')}/>
|
|
</Col>
|
|
<Col span={4} md={6}>
|
|
<Form.Select showClear field="payment_channel" label={t('bill.title_pay_method')}
|
|
placeholder={t('base.please_select')} style={{width: '100%'}}>
|
|
<Form.Select.Option value="ASIAPAY">ASIAPAY</Form.Select.Option>
|
|
<Form.Select.Option value="FLYWIRE">FLYWIRE</Form.Select.Option>
|
|
<Form.Select.Option value="PPS">PPS</Form.Select.Option>
|
|
</Form.Select>
|
|
</Col>
|
|
<Col span={4} md={6}>
|
|
<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>
|
|
{props.showApply && <Col span={4} md={6}>
|
|
<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 span={4} 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; |