解决了一些问题

main
wuyize 2023-01-02 14:23:41 +08:00
parent d313886764
commit 1750ac8dc8
5 changed files with 220 additions and 234 deletions

View File

@ -8,7 +8,7 @@ export interface Token {
} }
export interface Staff { export interface Staff {
managingDepartment: Department; managingDepartment: Department|null;
staffDepartments: Department[]; staffDepartments: Department[];
staffName: string; staffName: string;
} }

View File

@ -28,8 +28,7 @@ const staffSlice = createSlice({
name: 'staff', name: 'staff',
initialState: { initialState: {
staffName: "", staffName: "",
managingDepartment: { departmentId: 0, managingDepartment: null as Department|null,
departmentName: ''},
staffDepartments: [{ departmentId: 0, staffDepartments: [{ departmentId: 0,
departmentName: ''}] departmentName: ''}]
}, },

View File

@ -18,8 +18,8 @@ function HeaderBar(props: any) {
token: {colorBgContainer, colorPrimary}, token: {colorBgContainer, colorPrimary},
} = theme.useToken(); } = theme.useToken();
const token:Token = useAppSelector(getToken); const token: Token = useAppSelector(getToken);
const staff:Staff = useAppSelector(getStaff); const staff: Staff = useAppSelector(getStaff);
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const navigate = useNavigate() const navigate = useNavigate()
@ -104,13 +104,14 @@ function HeaderBar(props: any) {
) )
} }
function MyMenu(props: any) { function MainMenu(props: any) {
console.log(props) console.log(props)
if (props.defaultSelectedKeys[0] === '') if (props.defaultSelectedKeys[0] === '')
return null return null
else else
return ( return (
<Menu <Menu
style={{height: '100%'}}
mode="inline" mode="inline"
defaultSelectedKeys={props.defaultSelectedKeys} defaultSelectedKeys={props.defaultSelectedKeys}
items={props.items} items={props.items}
@ -160,7 +161,7 @@ function HomeView() {
method: 'get' method: 'get'
}).then(response => { }).then(response => {
console.log(response.data) console.log(response.data)
const staff:Staff = response.data const staff: Staff = response.data
dispatch(setStaff(staff)) dispatch(setStaff(staff))
if (location.pathname === '/') if (location.pathname === '/')
@ -194,7 +195,7 @@ function HomeView() {
<Layout style={{height: '100%'}}> <Layout style={{height: '100%'}}>
<Sider <Sider
width={208} width={208}
style={{background: colorBgContainer}} style={{background: colorBgContainer, boxShadow: '9px 0px 28px 0px rgba(0, 0, 0, 0.05)'}}
breakpoint="lg" breakpoint="lg"
collapsedWidth="0" collapsedWidth="0"
onBreakpoint={(broken) => { onBreakpoint={(broken) => {
@ -204,13 +205,15 @@ function HomeView() {
console.log(collapsed, type); console.log(collapsed, type);
}} }}
> >
<div style={{ <div
height: '32px', style={{
margin: '17px 0 17px 0', height: '66px',
display: 'flex', padding: '17px 0 17px 0',
justifyContent: 'center', display: 'flex',
alignItems: 'center' justifyContent: 'center',
}}> alignItems: 'center',
borderInlineEnd: '1px solid rgba(5, 5, 5, 0.06)'
}}>
<Icon component={Logo}/> <Icon component={Logo}/>
<span style={{ <span style={{
color: colorPrimary, color: colorPrimary,
@ -219,14 +222,14 @@ function HomeView() {
marginLeft: '4px' marginLeft: '4px'
}}></span> }}></span>
</div> </div>
<MyMenu items={menuItems} defaultSelectedKeys={defaultSelectedKeys}/> <MainMenu style={{height: '100%'}} items={menuItems} defaultSelectedKeys={defaultSelectedKeys}/>
</Sider> </Sider>
<Layout> <Layout>
<HeaderBar/> <HeaderBar/>
<Content style={{margin: '0'}}> <Content style={{margin: '0', overflowY: "auto"}}>
<Outlet /> <Outlet/>
</Content> </Content>
<Footer style={{textAlign: 'center'}}></Footer> {/*<Footer style={{textAlign: 'center'}}></Footer>*/}
</Layout> </Layout>
</Layout> </Layout>
) )

View File

@ -13,11 +13,11 @@ import {
TimePicker, TimePicker,
Select, Select,
Checkbox, Checkbox,
Pagination Pagination, theme
} from "antd"; } from "antd";
import type {MenuProps, PaginationProps} from 'antd'; import type {MenuProps, PaginationProps} from 'antd';
import {DownOutlined, UploadOutlined} from '@ant-design/icons'; import {DownOutlined, UploadOutlined} from '@ant-design/icons';
import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal, useState} from "react"; import React, {ReactElement, JSXElementConstructor, ReactFragment, ReactPortal, useState, useEffect} from "react";
import {InvoiceCommit, InvoiceSearchOption} from "../../../models/Staff" import {InvoiceCommit, InvoiceSearchOption} from "../../../models/Staff"
import {Space, Typography} from 'antd'; import {Space, Typography} from 'antd';
import {SizeType} from "antd/es/config-provider/SizeContext"; import {SizeType} from "antd/es/config-provider/SizeContext";
@ -25,11 +25,12 @@ import axios from "axios";
import axiosInstance, {baseUrl} from "../../../utils/axiosInstance"; import axiosInstance, {baseUrl} from "../../../utils/axiosInstance";
import {Simulate} from "react-dom/test-utils"; import {Simulate} from "react-dom/test-utils";
import change = Simulate.change; import change = Simulate.change;
import {useNavigate} from "react-router-dom"; import {useNavigate, useSearchParams} from "react-router-dom";
import {useAppDispatch} from "../../../models/hooks"; import {useAppDispatch} from "../../../models/hooks";
import InvoiceUploadView from "./InvoiceUploadView"; import InvoiceUploadView from "./InvoiceUploadView";
import {Invoice, invoiceTypeNameMap} from "../../../models/Invoice"; import {Invoice, invoiceTypeNameMap} from "../../../models/Invoice";
const {Meta} = Card; const {Meta} = Card;
const {Search} = Input; const {Search} = Input;
const {Option} = Select const {Option} = Select
@ -52,170 +53,160 @@ const rangeConfig = {
rules: [{type: 'array' as const, required: false, message: 'Please select time!'}], rules: [{type: 'array' as const, required: false, message: 'Please select time!'}],
}; };
class InvoiceSearch extends React.Component<any, any> { function InvoiceSearch(props: { handleSearchData: any; }) {
constructor(props: { handleSearchData: any; }) { const {
super(props); token: {colorBgContainer, colorPrimary},
this.state = { } = theme.useToken();
activatedOption: "发票代码",
searchContent: '请在此输入', const [activatedOption, setActivatedOption] = useState('发票代码')
complexEnabled: false, const [complexEnabled, setComplexEnabled] = useState(false)
invoiceSearchOption: new InvoiceSearchOption(), const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
isUploadModalOpen: false
const items: MenuProps['items'] = [
{
key: '1',
label: (<a className="simpleSearchOption" onClick={() => {
invoiceSearchOption.clear();
setActivatedOption("发票代码")
}}>
</a>)
},
{
key: '2',
label: (<a className="simpleSearchOption" onClick={() => {
invoiceSearchOption.clear();
setActivatedOption("发票编号")
}}>
</a>)
}
];
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.invoiceState = allValues['invoice-state']
}
if (allValues['invoice-kind'] !== "全部") {
invoiceSearchOption.invoiceKind = allValues['invoice-kind']
}
if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") {
invoiceSearchOption.invoiceUploader = allValues['invoice-uploader'].trim()
} }
} }
onSearch = (value: string) => { const onSearch = (value: string) => {
if (!this.state.complexEnabled) if (!complexEnabled)
this.state.invoiceSearchOption.clear() invoiceSearchOption.clear()
console.log(this.state.invoiceSearchOption) console.log(invoiceSearchOption)
if (this.state.activatedOption === "发票代码") { if (activatedOption === "发票代码") {
this.state.invoiceSearchOption.invoiceCode = value; invoiceSearchOption.invoiceCode = value;
this.state.invoiceSearchOption.invoiceNo = null; invoiceSearchOption.invoiceNo = null;
} else { } else {
this.state.invoiceSearchOption.invoiceNo = value; invoiceSearchOption.invoiceNo = value;
this.state.invoiceSearchOption.invoiceCode = null; invoiceSearchOption.invoiceCode = null;
} }
const {handleSearchData} = this.props const {handleSearchData} = props
handleSearchData(this.state.invoiceSearchOption) handleSearchData(invoiceSearchOption)
} }
showUploadModal = () => {
this.setState({ isUploadModalOpen: true})
}
render() {
const items: MenuProps['items'] = [ return (
{ <div className="headBar">
key: '1', <div className="simpleSearchBar" style={{height: '72px', padding: '30px',display: "flex",alignItems: 'center', justifyContent: "space-between",backgroundColor: colorBgContainer}}>
label: (<a className="simpleSearchOption" onClick={() => { <Search className="simpleSearch"
this.state.invoiceSearchOption.clear(); addonBefore={<Dropdown
this.setState({activatedOption: "发票代码"} menu={{
) items,
}}> selectable: true,
defaultSelectedKeys: ['1'],
</a>) }}
}, >
{ <Typography.Link>
key: '2', <Space>
label: (<a className="simpleSearchOption" onClick={() => { {activatedOption}
this.state.invoiceSearchOption.clear(); <DownOutlined/>
this.setState({activatedOption: "发票编号"} </Space>
) </Typography.Link>
}}> </Dropdown>}
placeholder={'请在此输入'}
</a>) allowClear
} onSearch={(value) => onSearch(value)}
]; style={{width: 304}}
const onValuesChange = (changedValues: any, allValues: any) => { enterButton
this.state.invoiceSearchOption.clear() />
<Checkbox onChange={(e) => {
console.log(allValues) setComplexEnabled(e.target.checked)
if (allValues['upload-time-picker'] != null && allValues['upload-time-picker'] !== undefined) { }}></Checkbox>
this.state.invoiceSearchOption.invoiceUploadTimeStart = allValues['upload-time-picker'][0].format('YYYY-MM-DDtHH:mm:ss') <InvoiceUploadView/>
this.state.invoiceSearchOption.invoiceUploadTimeEnd = allValues['upload-time-picker'][1].format('YYYY-MM-DDtHH:mm:ss')
}
if (allValues['invoice-time-picker'] !== null && allValues['invoice-time-picker'] !== undefined) {
this.state.invoiceSearchOption.invoiceDateStart = allValues['invoice-time-picker'][0].format('YYYY-MM-DD')
this.state.invoiceSearchOption.invoiceDateEnd = allValues['invoice-time-picker'][1].format('YYYY-MM-DD')
}
if (allValues['invoice-state'] !== "全部") {
this.state.invoiceSearchOption.invoiceState = allValues['invoice-state']
}
if (allValues['invoice-kind'] !== "全部") {
this.state.invoiceSearchOption.invoiceKind = allValues['invoice-kind']
}
if (allValues['invoice-uploader'] !== null && allValues['invoice-uploader'] !== undefined && allValues['invoice-uploader'].trim() !== "") {
this.state.invoiceSearchOption.invoiceUploader = allValues['invoice-uploader'].trim()
}
}
return (
<div className="headBar">
<div className="simpleSearchBar" style={{display: "flex", justifyContent: "space-evenly"}}>
<Search className="simpleSearch"
addonBefore={<Dropdown
menu={{
items,
selectable: true,
defaultSelectedKeys: ['1'],
}}
>
<Typography.Link>
<Space>
{this.state.activatedOption}
<DownOutlined/>
</Space>
</Typography.Link>
</Dropdown>}
placeholder={this.state.searchContent}
allowClear
onSearch={(value) => this.onSearch(value)}
style={{width: 304}}
enterButton
/>
<Checkbox onChange={(e) => {
this.setState({complexEnabled: e.target.checked})
}}></Checkbox>
<InvoiceUploadView/>
</div>
{this.state.complexEnabled&&
<div className="complexSearchBar" style={{display: "flex"}}>
<Form name="complexOption" {...formItemLayout} onValuesChange={onValuesChange}>
<Row>
<Form.Item name="upload-time-picker" label="发票上传时间" {...rangeConfig}>
<RangePicker/>
</Form.Item>
<Form.Item name="invoice-time-picker" label="发票开票日期" {...rangeConfig}>
<RangePicker/>
</Form.Item>
</Row>
<Row style={{display: "flex", flexWrap: "wrap"}}>
<Form.Item
name={`invoice-state`}
label={`发票状态`}
style={{minWidth: 150}}
><Select defaultValue="全部">
<Option value="全部"></Option>
<Option value="0">使</Option>
<Option value="1"></Option>
<Option value="2"></Option>
</Select>
</Form.Item>
<Form.Item
name={`invoice-kind`}
label={`发票类型`}
style={{minWidth: 300}}
><Select defaultValue="全部">
<Option value="全部"></Option>
<Option value="增值税普通发票"></Option>
<Option value="增值税专用发票"></Option>
<Option value="增值税电子普通发票"></Option>
<Option value="增值税电子专用发票"></Option>
<Option value="定额发票"></Option>
</Select>
</Form.Item>
<Form.Item
name={`invoice-uploader`}
label={`上传者`}
>
<Input placeholder="任意上传者"/>
</Form.Item>
</Row>
</Form>
</div>}
</div> </div>
) {complexEnabled &&
<div className="complexSearchBar" style={{display: "flex"}}>
<Form name="complexOption" {...formItemLayout} onValuesChange={onValuesChange}>
<Row>
<Form.Item name="upload-time-picker" label="发票上传时间" {...rangeConfig}>
<RangePicker/>
</Form.Item>
} <Form.Item name="invoice-time-picker" label="发票开票日期" {...rangeConfig}>
<RangePicker/>
</Form.Item>
</Row>
<Row style={{display: "flex", flexWrap: "wrap"}}>
<Form.Item
name={`invoice-state`}
label={`发票状态`}
style={{minWidth: 150}}
><Select defaultValue="全部">
<Option value="全部"></Option>
<Option value="0">使</Option>
<Option value="1"></Option>
<Option value="2"></Option>
</Select>
</Form.Item>
<Form.Item
name={`invoice-kind`}
label={`发票类型`}
style={{minWidth: 300}}
><Select defaultValue="全部">
<Option value="全部"></Option>
<Option value="增值税普通发票"></Option>
<Option value="增值税专用发票"></Option>
<Option value="增值税电子普通发票"></Option>
<Option value="增值税电子专用发票"></Option>
<Option value="定额发票"></Option>
</Select>
</Form.Item>
<Form.Item
name={`invoice-uploader`}
label={`上传者`}
>
<Input placeholder="任意上传者"/>
</Form.Item>
</Row>
</Form>
</div>}
</div>
)
} }
class InvoiceItem extends React.Component<any, any> { class InvoiceItem extends React.Component<any, any> {
constructor(props: { invoice: Invoice }) { constructor(props: { invoice: Invoice }) {
super(props); super(props);
this.state = { this.state = {
invoiceThumbnailUri: baseUrl+props.invoice.invoiceThumbnailUri, invoiceThumbnailUri: baseUrl + props.invoice.invoiceThumbnailUri,
invoiceKind: props.invoice.invoiceKind, invoiceKind: props.invoice.invoiceKind,
invoiceAmount: props.invoice.invoiceAmount, invoiceAmount: props.invoice.invoiceAmount,
invoiceDate: props.invoice.invoiceDate, invoiceDate: props.invoice.invoiceDate,
@ -249,89 +240,76 @@ class InvoiceItem extends React.Component<any, any> {
} }
class InvoiceListView extends React.Component<any, any> { function InvoiceListView(props: {}) {
constructor(props: {}) { const [totalNum, setTotalNum] = useState(0)
super(props); const [invoices, setInvoices] = useState([])
this.state = { const [search, setSearch] = useSearchParams()
isNoOrCode: '1',
invoices: [],
invoiceNo: null,
invoiceCode: null,
invoiceSearchOption: new InvoiceSearchOption(),
pageNum: 1,
pageSize: 20,
totalNum: 2,
PaginationKey: -2
}
}
componentDidMount(){ const [invoiceSearchOption, setInvoiceSearchOption] = useState(new InvoiceSearchOption())
this.searchInvoiceContent()
}
onChange = (pageCurrentNum: Number, pageCurrentSize: Number) => { const navigate = useNavigate()
console.log(pageCurrentNum, pageCurrentSize)
this.setState({pageNum: pageCurrentNum, pageSize: pageCurrentSize})
console.log(this.state.pageNum, this.state.pageSize)
this.searchInvoiceContent()
}
handleInvoiceSearchInfo= (invoiceSearch: InvoiceSearchOption) => { const handleInvoiceSearchInfo = (invoiceSearch: InvoiceSearchOption) => {
this.setState({invoiceSearchOption: invoiceSearch}) setInvoiceSearchOption(invoiceSearch)
console.log(this.state.invoiceSearchOption) searchInvoiceContent()
this.searchInvoiceContent()
} }
const searchInvoiceContent = () => {
searchInvoiceContent = () => { let params: any = invoiceSearchOption
let params = this.state.invoiceSearchOption
Object.keys(params).forEach(key => { Object.keys(params).forEach(key => {
if (params[key] != null && params[key] !== undefined && params[key] === "") { if (params[key] != null && params[key] !== undefined && params[key] === "") {
params[key] = null params[key] = null
} }
}) })
params['pageNum'] = this.state.pageNum-1 if (search.get('currentPage'))
params['pageSize'] = this.state.pageSize 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({ axiosInstance({
url: 'common/invoice', url: 'common/invoice',
method: 'get', method: 'get',
params: params params: params
}).then(response => { }).then(response => {
console.log(response.data) console.log(response.data)
this.handleInvoicesTotalNum(response.data.total) setTotalNum(response.data.total)
this.handleInvoicesContent(response.data.records) setInvoices(response.data.records)
}).catch(function (error) { }).catch(function (error) {
console.log(error) console.log(error)
}) })
} }
const onChange = (pageCurrentNum: Number, pageCurrentSize: Number) => {
handleInvoicesTotalNum(value: Number) { console.log(pageCurrentNum, pageCurrentSize)
this.setState({totalNum: value, PaginationKey: -value}) navigate('/invoice/mine?currentPage=' + pageCurrentNum + '&pageSize=' + pageCurrentSize)
} }
handleInvoicesContent = (value: Array<Invoice>) => { useEffect(() => {
console.log(value) console.log(search.get('currentPage'))
this.setState({invoices: value}) console.log(search.get('pageSize'))
} searchInvoiceContent()
}, [search]);
return (
render() { <div style={{}}>
return ( <InvoiceSearch handleSearchData={handleInvoiceSearchInfo}/>
<div style={{}}> <div style={{padding:26,display:"flex", flexDirection: "column", alignItems: "flex-end"}}>
<InvoiceSearch handleSearchData={this.handleInvoiceSearchInfo}/> <div style={{display: "flex", flexWrap: "wrap", justifyContent:'center', width: '100%'}}>
<div style={{display: "flex", flexWrap: "wrap"}}> {invoices.map((item: Invoice, index: number) =>
{this.state.invoices.map((item: Invoice, index:number) =>
<InvoiceItem invoice={item} key={index}/> <InvoiceItem invoice={item} key={index}/>
)} )}
</div> </div>
<Pagination style={{ <Pagination showSizeChanger
position: "fixed", showQuickJumper
bottom: 20, showTotal={(total) => `${total}`}
}} key={this.state.PaginationKey} showQuickJumper defaultCurrent={1} total={this.state.totalNum} onChange={this.onChange}/> current={Number(search.get('currentPage')?search.get('currentPage'):1)}
pageSize={Number(search.get('pageSize')?search.get('pageSize'):10)}
total={totalNum} onChange={onChange}/>
</div> </div>
) </div>
}
}
)
}
export default InvoiceListView export default InvoiceListView

View File

@ -99,22 +99,24 @@ function UpLoadModal(props: any) {
} }
function FormModal(props: any) { function FormModal(props: any) {
const [open, setOpen] = useState(false) //const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [invoice, setInvoice] = useState({}) const [invoice, setInvoice] = useState({})
const [formItems, setFormItems] = useState(undefined) const [formItems, setFormItems] = useState(undefined)
const [form] = Form.useForm(); const [form] = Form.useForm();
useEffect(() => { useEffect(() => {
setOpen(props.open) //setOpen(props.open)
console.log(props.invoiceIdentifyResponse) console.log(props.invoiceIdentifyResponse)
let i = {...props.invoiceIdentifyResponse} let i = {...props.invoiceIdentifyResponse}
setInvoice(i) setInvoice(i)
refreshFormItems(props.invoiceIdentifyResponse?.invoiceKind) refreshFormItems(props.invoiceIdentifyResponse?.invoiceKind)
//TODO: 重置表单
form.setFieldsValue(i) form.setFieldsValue(i)
}, [props]); }, [props]);
const handleCancel = () => { const handleCancel = () => {
setOpen(false); props.onClose()
//setOpen(false);
}; };
const submit = () => { const submit = () => {
setLoading(true) setLoading(true)
@ -134,7 +136,8 @@ function FormModal(props: any) {
}).then(response => { }).then(response => {
console.log(response.data) console.log(response.data)
setLoading(false) setLoading(false)
setOpen(false) props.onClose()
//setOpen(false)
}).catch(function (error) { }).catch(function (error) {
console.log(error) console.log(error)
setLoading(false) setLoading(false)
@ -202,7 +205,7 @@ function FormModal(props: any) {
return ( return (
<Modal <Modal
open={open} open={props.open}
title="提交发票" title="提交发票"
onOk={submit} onOk={submit}
onCancel={handleCancel} onCancel={handleCancel}
@ -266,17 +269,20 @@ class InvoiceUploadView extends React.Component<any, any> {
this.setState({uploadModalOpen: false, formModalOpen: true, invoiceIdentifyResponse: response}) this.setState({uploadModalOpen: false, formModalOpen: true, invoiceIdentifyResponse: response})
} }
handleClose = () => {
this.setState({formModalOpen:false})
}
render() { render() {
// @ts-ignore // @ts-ignore
return ( return (
<> <>
<Button onClick={this.showUploadView} className="uploadButton" type="primary" icon={<UploadOutlined/>} <Button onClick={this.showUploadView} className="uploadButton" type="primary" icon={<UploadOutlined/>}>
size="large">
</Button> </Button>
<UpLoadModal open={this.state.uploadModalOpen} nextStep={this.handleNextStep}/> <UpLoadModal open={this.state.uploadModalOpen} nextStep={this.handleNextStep}/>
<FormModal open={this.state.formModalOpen} <FormModal open={this.state.formModalOpen} onClose={this.handleClose}
invoiceIdentifyResponse={this.state.invoiceIdentifyResponse}/> invoiceIdentifyResponse={this.state.invoiceIdentifyResponse}/>
</>); </>);