diff --git a/src/models/Invoice.ts b/src/models/Invoice.ts index 5d3f277..b8cc44a 100644 --- a/src/models/Invoice.ts +++ b/src/models/Invoice.ts @@ -25,6 +25,69 @@ export interface Invoice { reimbursement: Reimbursement; } + + +type Nullable = T | undefined | null; + +export class InvoiceSearchOption { + invoiceNo: Nullable + invoiceCode: Nullable + invoiceUploadTimeStart: Nullable + invoiceUploadTimeEnd: Nullable + invoiceStates: Nullable + invoiceKinds: Nullable + invoiceDateStart: Nullable + invoiceDateEnd: Nullable + invoiceNote: Nullable + invoiceUploaderId: Nullable + pageNum: number + pageSize: number + + constructor() { + this.pageNum = 0 + this.pageSize = 20 + this.clear() + } + + clear() { + this.invoiceNo = null + this.invoiceCode = null + this.invoiceUploadTimeStart = null + this.invoiceUploadTimeEnd = null + this.invoiceStates = null + this.invoiceKinds = null + this.invoiceDateStart = null + this.invoiceDateEnd = null + this.invoiceNote = null + this.invoiceUploaderId = null + this.pageNum = 0 + this.pageSize = 20 + } +} + +export interface InvoiceDetail { + invoiceAmount: number; + invoiceCode: string; + invoiceDate: string |Dayjs; + invoiceDeparture?: string; + invoiceDestination?: string; + invoiceFileUri: string; + invoiceId: number; + invoiceKind: number; + invoiceName?: string; + invoiceNo: string; + invoiceNote: string; + /** + * -1: 不合格 0: 已上传 1: 报销中 2: 已报销 + */ + invoiceState: number; + invoiceThumbnailUri: string; + invoiceUploader: Staff; + invoiceUploadTime: string|Dayjs; + modified: boolean; + reimbursement: Reimbursement; +} + export interface InvoiceIdentifyResponse { invoiceAmount: number; invoiceCheckCode?: string; @@ -79,14 +142,40 @@ export const invoiceItemsMap = new Map([ ]) export const invoiceTypeItemsMap = new Map([ + [0, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [1, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], + [2, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], [3, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], + [5, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [8, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], + [9, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [10, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [11, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], + [12, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], [13, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [15, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], + [16, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceCheckCode']], ]) export const invoiceTypeExtraItemsMap = new Map([ [3, ['合计金额','合计税额', '购买方名称', '销售方名称', '收款人']], [13, ['时间']], ]) +export const invoiceTypeShowItemsMap = new Map([ + [0, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [1, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], + [2, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [3, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], + [5, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [8, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], + [9, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [10, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [11, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], + [12, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], + [13, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate', 'invoiceDeparture', 'invoiceDestination']], + [15, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], + [16, ['invoiceName', 'invoiceNo', 'invoiceCode', 'invoiceAmount', 'invoiceDate']], +]) /* { diff --git a/src/models/Staff.ts b/src/models/Staff.ts index 56c21a2..70b4f68 100644 --- a/src/models/Staff.ts +++ b/src/models/Staff.ts @@ -12,6 +12,7 @@ export interface Staff { staffDepartments: Department[]; staffName: string; staffBase: string; + staffId: string|null|undefined; } export interface Department { @@ -19,133 +20,3 @@ export interface Department { departmentName: string; } - - -type Nullable = T | undefined | null; - -export class InvoiceSearchOption { - invoiceNo: Nullable - invoiceCode: Nullable - invoiceUploadTimeStart: Nullable - invoiceUploadTimeEnd: Nullable - invoiceState: Nullable - invoiceKind: Nullable - invoiceDateStart: Nullable - invoiceDateEnd: Nullable - invoiceNote: Nullable - invoiceUploader: Nullable - pageNum: number - pageSize: number - - constructor() { - this.pageNum = 0 - this.pageSize = 20 - this.clear() - } - - clear() { - this.invoiceNo = null - this.invoiceCode = null - this.invoiceUploadTimeStart = null - this.invoiceUploadTimeEnd = null - this.invoiceState = null - this.invoiceKind = null - this.invoiceDateStart = null - this.invoiceDateEnd = null - this.invoiceNote = null - this.invoiceUploader = null - this.pageNum = 0 - this.pageSize = 20 - } - - // toString(){ - // let res="pageNum="+this.pageNum+"&pageSize="+this.pageSize - // res+=(this.invoiceNo===undefined||this.invoiceNo===null||this.invoiceNo===""?"":("&invoiceNo="+this.invoiceNo)); - // res+=(this.invoiceCode===undefined||this.invoiceCode===null||this.invoiceCode===""?"":("&invoiceCode="+this.invoiceCode)); - // res+=(this.invoiceUploadTimeStart===undefined||this.invoiceUploadTimeStart===null?"":("&invoiceUploadTimeStart="+this.invoiceUploadTimeStart)); - // res+=(this.invoiceUploadTimeEnd===undefined||this.invoiceUploadTimeEnd===null?"":("&invoiceUploadTimeEnd="+this.invoiceUploadTimeEnd)); - // res+=(this.invoiceState===undefined||this.invoiceState===null?"":("&invoiceState="+this.invoiceState)); - // res+=(this.invoiceKind===undefined||this.invoiceKind===null?"":("&invoiceKind="+this.invoiceKind)); - // res+=(this.invoiceDateStart===undefined||this.invoiceDateStart===null?"":("&invoiceDateStart="+this.invoiceDateStart)); - // res+=(this.invoiceDateEnd===undefined||this.invoiceDateEnd===null?"":("&invoiceDateEnd="+this.invoiceDateEnd)); - // res+=(this.invoiceNote===undefined||this.invoiceNote===null?"":("&invoiceNote="+this.invoiceNote)); - // res+=(this.invoiceUploader===undefined||this.invoiceUploader===null?"":("&invoiceUploader="+this.invoiceUploader)); - // return res; - // } -} - -export class InvoiceCommit { - invoiceFileName: string - invoiceNo: string - invoiceCode: string - invoiceKind: string - invoiceDate: dayjs.Dayjs - invoiceAmount: number - invoiceAmountWithoutTax: number - invoiceCheckCode: string - invoiceRegionCode: Nullable - invoiceSellerTaxCode: Nullable - invoiceExtraInfo: Nullable | [] | Map - - constructor() { - this.invoiceFileName = "" - this.invoiceNo = "" - this.invoiceCode = "" - this.invoiceKind = "" - this.invoiceDate = dayjs() - this.invoiceAmount = 0 - this.invoiceAmountWithoutTax = 0 - this.invoiceCheckCode = "000000" - this.invoiceRegionCode = null - this.invoiceSellerTaxCode = null - this.invoiceExtraInfo = null - } - - setValue(props: FormData) { - console.log("1111" + props.toString()) - this.invoiceFileName = props.get("invoiceFileName")!.toString() - this.invoiceNo = props.get("invoiceNo")!.toString() - this.invoiceCode = props.get("invoiceCode")!.toString() - this.invoiceKind = props.get("invoiceKind")!.toString() - //this.invoiceDate = new Date(props.get("invoiceDate")!.toString()) - //this.invoiceAmount = props.get("invoiceAmount")!.toString() - //this.invoiceAmountWithoutTax = props.get("invoiceAmountWithoutTax")!.toString() - this.invoiceCheckCode = props.get("invoiceCheckCode")!.toString() - this.invoiceRegionCode = props.get("invoiceRegionCode")!.toString() - this.invoiceSellerTaxCode = props.get("invoiceSellerTaxCode")!.toString() - //this.invoiceExtraInfo = props.get("invoiceExtraInfo")!. - } -} - -export interface Reimbursement { - /** - * 差旅补助金额 - */ - reimbursementAdditionalAmount: number; - reimbursementDepartureInvoiceId: number; - reimbursementDepartureName: string; - reimbursementDestinationInvoiceId?: number; - reimbursementDestinationName: string; - reimbursementId: number; - /** - * 发票金额 - */ - reimbursementInvoiceAmount: number; - reimbursementNote?: string; - /** - * 0: success - * 1: 待主管审批 - * 2: 待财务审批 - * 3: 待财务主管审批 - * 4: 待总经理审批 - * 5: 未通过 - */ - reimbursementStatus: number; - reimbursementSubmitDepartmentId: number; - reimbursementSubmitStaffId: string; - reimbursementSubmitTime: string; - /** - * 单位为天 - */ - reimbursementTripDuration: number; -} \ No newline at end of file diff --git a/src/models/store.ts b/src/models/store.ts index b5adacd..9f55eeb 100644 --- a/src/models/store.ts +++ b/src/models/store.ts @@ -27,6 +27,7 @@ const tokenSlice = createSlice({ const staffSlice = createSlice({ name: 'staff', initialState: { + staffId: "", staffName: "", managingDepartment: null as Department|null, staffDepartments: [{ departmentId: 0, diff --git a/src/pages/HomeView.tsx b/src/pages/HomeView.tsx index 4f9a606..31d8a98 100644 --- a/src/pages/HomeView.tsx +++ b/src/pages/HomeView.tsx @@ -83,7 +83,9 @@ function HeaderBar(props: any) { background: colorBgContainer, display: 'flex', flexDirection: 'row-reverse', - alignItems: 'center' + alignItems: 'center', + zIndex: 100, + boxShadow: '0px 6px 16px 0px rgba(0, 0, 0, 0.08)' }}> } + > + { +
+ + {invoiceTypeNameMap.get(props.invoiceDetail?.invoiceKind)} + + {formItems} + + {props.invoiceDetail?.invoiceNote} + +
+ } + + + ) +} + +export default InvoiceDetailModal \ No newline at end of file diff --git a/src/pages/Invoice/management/InvoiceManagement.tsx b/src/pages/Invoice/management/InvoiceManagement.tsx index f310b03..9cb19d1 100644 --- a/src/pages/Invoice/management/InvoiceManagement.tsx +++ b/src/pages/Invoice/management/InvoiceManagement.tsx @@ -1,6 +1,374 @@ -function InvoiceManagement() { - return( -
发票管理
+import { + Card, + Dropdown, + List, + Row, + Input, + Button, + Radio, + Col, + Divider, + DatePicker, + Form, + TimePicker, + Select, + Checkbox, + Pagination, theme, Tag, Badge +} from "antd"; +import type {MenuProps, PaginationProps} from 'antd'; +import {DownOutlined, UploadOutlined} from '@ant-design/icons'; +import React, { + ReactElement, + JSXElementConstructor, + ReactFragment, + ReactPortal, + useState, + useEffect, + ReactNode +} from "react"; +import {InvoiceDetail, InvoiceSearchOption} from "../../../models/Invoice" +import {Space, Typography} from 'antd'; +import {SizeType} from "antd/es/config-provider/SizeContext"; +import axios from "axios"; +import axiosInstance, {baseUrl} from "../../../utils/axiosInstance"; +import {Simulate} from "react-dom/test-utils"; +import change = Simulate.change; +import {useNavigate, useSearchParams} from "react-router-dom"; +import {useAppDispatch} from "../../../models/hooks"; +import { + Invoice, + invoiceItemsMap, + invoiceTypeExtraItemsMap, + invoiceTypeItemsMap, + invoiceTypeNameMap +} from "../../../models/Invoice"; +import {RadioButtonProps} from "antd/es/radio/radioButton"; +import qs from "qs"; +import InvoiceDetailModal from "../InvoiceDetailModal"; +import dayjs from "dayjs"; + + +const {Text, Paragraph} = Typography; +const {Meta} = Card; +const {Search} = Input; +const {Option} = Select +let invoices: Array +const {RangePicker} = DatePicker; + +const config = { + rules: [{type: 'object' as const, required: false, message: 'Please select time!'}], +}; +const rangeConfig = { + rules: [{type: 'array' as const, required: false, message: 'Please select time!'}], +}; + +function InvoiceSearch(props: { handleSearchData: any; }) { + const { + token: {colorBgContainer, colorPrimary}, + } = theme.useToken(); + + const [activatedOption, setActivatedOption] = useState('发票代码') + const [complexEnabled, setComplexEnabled] = useState(false) + const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption()) + + const items: MenuProps['items'] = [ + { + key: '1', + label: ( { + invoiceSearchOption.clear(); + setActivatedOption("发票代码") + }}> + 发票代码 + ) + }, + { + key: '2', + label: ( { + invoiceSearchOption.clear(); + setActivatedOption("发票编号") + + }}> + 发票编号 + ) + } + ]; + const onValuesChange = (changedValues: any, allValues: any) => { + invoiceSearchOption.clear() + + console.log(allValues) + if (allValues['upload-time-picker'] !== null && allValues['upload-time-picker'] !== undefined) { + invoiceSearchOption.invoiceUploadTimeStart = allValues['upload-time-picker'][0].format('YYYY-MM-DDtHH:mm:ss') + invoiceSearchOption.invoiceUploadTimeEnd = allValues['upload-time-picker'][1].format('YYYY-MM-DDtHH:mm:ss') + } + if (allValues['invoice-time-picker'] !== null && allValues['invoice-time-picker'] !== undefined) { + invoiceSearchOption.invoiceDateStart = allValues['invoice-time-picker'][0].format('YYYY-MM-DD') + invoiceSearchOption.invoiceDateEnd = allValues['invoice-time-picker'][1].format('YYYY-MM-DD') + } + if (allValues['invoice-state'] !== "全部") { + invoiceSearchOption.invoiceStates = [allValues['invoice-state']] + } + if (allValues['invoice-kind'] !== "全部") { + invoiceSearchOption.invoiceKinds = [allValues['invoice-kind']] + } + if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") { + invoiceSearchOption.invoiceUploaderId = allValues['invoice-uploader'].trim() + } + props.handleSearchData(invoiceSearchOption) + } + + const onSearch = (value: string) => { + if (!complexEnabled) + invoiceSearchOption.clear() + console.log(invoiceSearchOption) + if (activatedOption === "发票代码") { + invoiceSearchOption.invoiceCode = value; + invoiceSearchOption.invoiceNo = null; + } else { + invoiceSearchOption.invoiceNo = value; + invoiceSearchOption.invoiceCode = null; + } + + props.handleSearchData(invoiceSearchOption) + + } + + const getInvoiceKindsRadioButtons: any = () => { + let options: any[] = [] + invoiceTypeNameMap.forEach(function (value, key, map) { + options.push({value}) + }) + return options + } + + return ( +
+
+ + + + {activatedOption} + + + + } + placeholder={'请在此输入'} + allowClear + onSearch={(value) => onSearch(value)} + style={{width: 404}} + enterButton + /> + { + setComplexEnabled(e.target.checked) + }}>高级搜索 +
+ {complexEnabled && +
+
+ + + + 全部 + {getInvoiceKindsRadioButtons()} + + + +
+ + + + + + + +
+ + + 全部 + 未使用 + 报销中 + 已报销 + + + +
+
} +
) } + +function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void }) { + const { + token: {colorBgContainer, colorPrimary, colorSuccess, colorWarning}, + } = theme.useToken(); + + const onClick = () => { + props.onClick(props.invoice) + } + return ( +
+ + + + } + > +
+
+ ¥{(props.invoice.invoiceAmount / 100.0).toFixed(2)} + {props.invoice.invoiceUploader.staffName } +
+
+ {invoiceTypeNameMap.get(props.invoice.invoiceKind)} + {props.invoice.invoiceUploader.staffId } +
+
  • {props.invoice.invoiceNo}
  • +
  • {props.invoice.invoiceDate}
  • +
    +
    +
    +
    + + + ) + +} + + +function InvoiceManagement(props: {}) { + const [totalNum, setTotalNum] = useState(0) + const [invoices, setInvoices] = useState([] as any[]) + const [search, setSearch] = useSearchParams() + const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption()) + const [detailModalOpen, setDetailModalOpen] = useState(false) + const [invoiceDetail, setInvoiceDetail] = useState(null as InvoiceDetail | null) + const navigate = useNavigate() + + const handleInvoiceSearchInfo = (invoiceSearch: InvoiceSearchOption) => { + //setInvoiceSearchOption(invoiceSearch) + searchInvoiceContent(invoiceSearch) + } + const searchInvoiceContent = (invoiceSearch: InvoiceSearchOption) => { + setInvoices([]) + let params: any = invoiceSearch + Object.keys(params).forEach(key => { + if (params[key] != null && params[key] !== undefined && params[key] === "") { + params[key] = null + } + }) + if (search.get('currentPage')) + params.pageNum = Number(search.get('currentPage')) - 1 + else + params.pageNum = 0 + if (search.get('pageSize')) + params.pageSize = Number(search.get('pageSize')) + else + params.pageSize = 10 + axiosInstance({ + url: 'common/invoice?' + qs.stringify(params, {skipNulls: true, arrayFormat: 'indices'}), + method: 'get', + }).then(response => { + console.log(response.data) + setTotalNum(response.data.total) + setInvoices([...response.data.records]) + }).catch(function (error) { + console.log(error) + }) + } + const onChange = (pageCurrentNum: Number, pageCurrentSize: Number) => { + console.log(pageCurrentNum, pageCurrentSize) + navigate('/invoice/management?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize) + } + + const onItemClick = (invoice: Invoice) => { + console.log(invoice) + axiosInstance({ + url: 'common/invoice/' + invoice.invoiceId, + method: 'get', + }).then(response => { + console.log(response.data) + let detail: InvoiceDetail = response.data + detail.invoiceAmount /= 100. + setInvoiceDetail(detail) + setDetailModalOpen(true) + }).catch(function (error) { + console.log(error) + }) + + } + + useEffect(() => { + console.log(search.get('currentPage')) + console.log(search.get('pageSize')) + searchInvoiceContent(invoiceSearchOption) + }, [search]); + + console.log(invoices) + return ( +
    + +
    +
    + {invoices.map((item: Invoice, index: number) => + + )} +
    + `共 ${total} 项`} + current={Number(search.get('currentPage') ? search.get('currentPage') : 1)} + pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)} + total={totalNum} onChange={onChange}/> +
    + { searchInvoiceContent(invoiceSearchOption)}} invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => { + setDetailModalOpen(false) + }} showFooter={true}/> +
    + + ) +} + export default InvoiceManagement \ No newline at end of file diff --git a/src/pages/Invoice/mine/InvoiceListView.tsx b/src/pages/Invoice/mine/InvoiceListView.tsx index 81ecd8f..33b236e 100644 --- a/src/pages/Invoice/mine/InvoiceListView.tsx +++ b/src/pages/Invoice/mine/InvoiceListView.tsx @@ -13,12 +13,20 @@ import { TimePicker, Select, Checkbox, - Pagination, theme + Pagination, theme, Tag, Badge } from "antd"; import type {MenuProps, PaginationProps} from 'antd'; import {DownOutlined, UploadOutlined} from '@ant-design/icons'; -import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal, useState, useEffect} from "react"; -import {InvoiceCommit, InvoiceSearchOption} from "../../../models/Staff" +import React, { + ReactElement, + JSXElementConstructor, + ReactFragment, + ReactPortal, + useState, + useEffect, + ReactNode +} from "react"; +import {InvoiceDetail, InvoiceSearchOption} from "../../../models/Invoice" import {Space, Typography} from 'antd'; import {SizeType} from "antd/es/config-provider/SizeContext"; import axios from "axios"; @@ -28,7 +36,18 @@ import change = Simulate.change; import {useNavigate, useSearchParams} from "react-router-dom"; import {useAppDispatch} from "../../../models/hooks"; import InvoiceUploadView from "./InvoiceUploadView"; -import {Invoice, invoiceTypeNameMap} from "../../../models/Invoice"; +import { + Invoice, + invoiceItemsMap, + invoiceTypeExtraItemsMap, + invoiceTypeItemsMap, + invoiceTypeNameMap +} from "../../../models/Invoice"; +import {RadioButtonProps} from "antd/es/radio/radioButton"; +import qs from "qs"; +import InvoiceDetailModal from "../InvoiceDetailModal"; +import dayjs from "dayjs"; +import {store} from "../../../models/store"; const {Meta} = Card; @@ -36,16 +55,7 @@ const {Search} = Input; const {Option} = Select let invoices: Array const {RangePicker} = DatePicker; -const formItemLayout = { - labelCol: { - xs: {span: 10}, - sm: {span: 10}, - }, - wrapperCol: { - xs: {span: 14}, - sm: {span: 14}, - }, -}; + const config = { rules: [{type: 'object' as const, required: false, message: 'Please select time!'}], }; @@ -87,7 +97,7 @@ function InvoiceSearch(props: { handleSearchData: any; }) { invoiceSearchOption.clear() console.log(allValues) - if (allValues['upload-time-picker'] != null && allValues['upload-time-picker'] !== undefined) { + if (allValues['upload-time-picker'] !== null && allValues['upload-time-picker'] !== undefined) { invoiceSearchOption.invoiceUploadTimeStart = allValues['upload-time-picker'][0].format('YYYY-MM-DDtHH:mm:ss') invoiceSearchOption.invoiceUploadTimeEnd = allValues['upload-time-picker'][1].format('YYYY-MM-DDtHH:mm:ss') } @@ -96,14 +106,15 @@ function InvoiceSearch(props: { handleSearchData: any; }) { invoiceSearchOption.invoiceDateEnd = allValues['invoice-time-picker'][1].format('YYYY-MM-DD') } if (allValues['invoice-state'] !== "全部") { - invoiceSearchOption.invoiceState = allValues['invoice-state'] + invoiceSearchOption.invoiceStates = [allValues['invoice-state']] } if (allValues['invoice-kind'] !== "全部") { - invoiceSearchOption.invoiceKind = allValues['invoice-kind'] + invoiceSearchOption.invoiceKinds = [allValues['invoice-kind']] } if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") { - invoiceSearchOption.invoiceUploader = allValues['invoice-uploader'].trim() + invoiceSearchOption.invoiceUploaderId = allValues['invoice-uploader'].trim() } + props.handleSearchData(invoiceSearchOption) } const onSearch = (value: string) => { @@ -118,14 +129,28 @@ function InvoiceSearch(props: { handleSearchData: any; }) { invoiceSearchOption.invoiceCode = null; } - const {handleSearchData} = props - handleSearchData(invoiceSearchOption) + props.handleSearchData(invoiceSearchOption) } + const getInvoiceKindsRadioButtons: any = () => { + let options: any[] = [] + invoiceTypeNameMap.forEach(function (value, key, map) { + options.push({value}) + }) + return options + } + return (
    -
    +
    onSearch(value)} - style={{width: 304}} + style={{width: 404}} enterButton /> { setComplexEnabled(e.target.checked) }}>高级搜索 - + {props.handleSearchData(invoiceSearchOption)}} />
    {complexEnabled && -
    -
    - - +
    + + + + + 全部 + {getInvoiceKindsRadioButtons()} + + + +
    + - + - - - - - - - - - - +
    + + + 全部 + 未使用 + 报销中 + 已报销 + + +
    }
    ) } -class InvoiceItem extends React.Component { - constructor(props: { invoice: Invoice }) { - super(props); - this.state = { - invoiceThumbnailUri: baseUrl + props.invoice.invoiceThumbnailUri, - invoiceKind: props.invoice.invoiceKind, - invoiceAmount: props.invoice.invoiceAmount, - invoiceDate: props.invoice.invoiceDate, - invoiceNo: props.invoice.invoiceNo, - } - console.log(this.state.invoiceThumbnailUri) - } +function InvoiceItem(props: { invoice: Invoice, onClick(invoice: Invoice): void }) { + const { + token: {colorBgContainer, colorPrimary, colorSuccess, colorWarning}, + } = theme.useToken(); - render() { - return ( - } - > -
    -
  • ¥{(this.state.invoiceAmount / 100.0).toFixed(2)}
  • -
  • {invoiceTypeNameMap.get(this.state.invoiceKind)}
  • -
  • {this.state.invoiceNo}
  • -
  • {this.state.invoiceDate}
  • -
    -
    - ) + const onClick = () => { + props.onClick(props.invoice) } + return ( +
    + + + + } + > +
    +
  • ¥{(props.invoice.invoiceAmount / 100.0).toFixed(2)}
  • +
  • {invoiceTypeNameMap.get(props.invoice.invoiceKind)}
  • +
  • {props.invoice.invoiceNo}
  • +
  • {props.invoice.invoiceDate}
  • +
    +
    +
    +
    + + + ) + } function InvoiceListView(props: {}) { const [totalNum, setTotalNum] = useState(0) - const [invoices, setInvoices] = useState([]) + const [invoices, setInvoices] = useState([] as any[]) const [search, setSearch] = useSearchParams() - const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption()) - + const [detailModalOpen, setDetailModalOpen] = useState(false) + const [invoiceDetail, setInvoiceDetail] = useState(null as InvoiceDetail | null) const navigate = useNavigate() const handleInvoiceSearchInfo = (invoiceSearch: InvoiceSearchOption) => { setInvoiceSearchOption(invoiceSearch) - searchInvoiceContent() + searchInvoiceContent(invoiceSearch) } - const searchInvoiceContent = () => { - let params: any = invoiceSearchOption + const searchInvoiceContent = (invoiceSearch: InvoiceSearchOption) => { + setInvoices([]) + let params: any = invoiceSearch Object.keys(params).forEach(key => { if (params[key] != null && params[key] !== undefined && params[key] === "") { params[key] = null @@ -268,14 +300,16 @@ function InvoiceListView(props: {}) { params.pageSize = Number(search.get('pageSize')) else params.pageSize = 10 + + params.invoiceUploaderId = store.getState().token.staffId + axiosInstance({ - url: 'common/invoice', + url: 'common/invoice?' + qs.stringify(params, {skipNulls: true, arrayFormat: 'indices'}), method: 'get', - params: params }).then(response => { console.log(response.data) setTotalNum(response.data.total) - setInvoices(response.data.records) + setInvoices([...response.data.records]) }).catch(function (error) { console.log(error) }) @@ -285,31 +319,52 @@ function InvoiceListView(props: {}) { navigate('/invoice/mine?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize) } + const onItemClick = (invoice: Invoice) => { + console.log(invoice) + axiosInstance({ + url: 'common/invoice/' + invoice.invoiceId, + method: 'get', + }).then(response => { + console.log(response.data) + let detail: InvoiceDetail = response.data + detail.invoiceAmount /= 100. + setInvoiceDetail(detail) + setDetailModalOpen(true) + }).catch(function (error) { + console.log(error) + }) + + } + useEffect(() => { console.log(search.get('currentPage')) console.log(search.get('pageSize')) - searchInvoiceContent() + searchInvoiceContent(invoiceSearchOption) }, [search]); + console.log(invoices) return (
    -
    -
    +
    +
    {invoices.map((item: Invoice, index: number) => - + )}
    `共 ${total} 项`} - current={Number(search.get('currentPage')?search.get('currentPage'):1)} - pageSize={Number(search.get('pageSize')?search.get('pageSize'):10)} + current={Number(search.get('currentPage') ? search.get('currentPage') : 1)} + pageSize={Number(search.get('pageSize') ? search.get('pageSize') : 10)} total={totalNum} onChange={onChange}/>
    - + {searchInvoiceContent(invoiceSearchOption)}} invoiceDetail={invoiceDetail} open={detailModalOpen} onClose={() => { + setDetailModalOpen(false) + }}/>
    ) } + export default InvoiceListView \ No newline at end of file diff --git a/src/pages/Invoice/mine/InvoiceUploadView.tsx b/src/pages/Invoice/mine/InvoiceUploadView.tsx index e6a1542..f7f777f 100644 --- a/src/pages/Invoice/mine/InvoiceUploadView.tsx +++ b/src/pages/Invoice/mine/InvoiceUploadView.tsx @@ -2,7 +2,6 @@ import React, {useEffect, useRef, useState} from 'react'; import {Button, Modal, UploadProps, message, Upload, UploadFile, Form, Input, DatePicker, Select, InputNumber} from 'antd'; import {InboxOutlined, UploadOutlined} from '@ant-design/icons'; import axiosInstance from "../../../utils/axiosInstance"; -import {InvoiceCommit} from "../../../models/Staff"; import dayjs, {Dayjs} from 'dayjs'; import TextArea from "antd/es/input/TextArea"; import {constants} from "http2"; @@ -50,11 +49,7 @@ class FileUploadView extends React.Component { function UpLoadModal(props: any) { - const [open, setOpen] = useState(false) const [loading, setLoading] = useState(false) - useEffect(() => { - setOpen(props.open) - }, [props]); const handleOk = () => { setLoading(true); let data = new FormData(); @@ -66,7 +61,7 @@ function UpLoadModal(props: any) { }).then(response => { setLoading(false); console.log(response.data) - setOpen(false); + props.onClose() props.nextStep(response.data) }).catch(function (error) { setLoading(false); @@ -75,12 +70,12 @@ function UpLoadModal(props: any) { }; const handleCancel = () => { - setOpen(false); + props.onClose() }; return ( { - constructor(props: {}) { + constructor(props: any) { super(props); this.state = { uploadModalOpen: false, @@ -266,7 +262,11 @@ class InvoiceUploadView extends React.Component { handleNextStep = (response: InvoiceIdentifyResponse) => { response.invoiceDate = dayjs(response.invoiceDate) response.invoiceAmount /= 100. - this.setState({uploadModalOpen: false, formModalOpen: true, invoiceIdentifyResponse: response}) + this.setState({formModalOpen: true, invoiceIdentifyResponse: response}) + } + + handleUploadModalClose = () => { + this.setState({uploadModalOpen:false}) } handleClose = () => { @@ -281,8 +281,8 @@ class InvoiceUploadView extends React.Component { - - + { this.props.needRefresh()}} open={this.state.formModalOpen} onClose={this.handleClose} invoiceIdentifyResponse={this.state.invoiceIdentifyResponse}/> );