Merge remote-tracking branch 'origin/main'

main
白封羽 2023-01-06 15:26:01 +08:00
commit a6c7378398
4 changed files with 126 additions and 64 deletions

View File

@ -1,5 +1,5 @@
import React, {useState, useEffect} from 'react'; import React, {useState, useEffect} from 'react';
import {UploadOutlined, UserOutlined, VideoCameraOutlined} from '@ant-design/icons'; import {UploadOutlined, UserOutlined, BellOutlined} from '@ant-design/icons';
import {Layout, Menu, theme, Typography, Button, Dropdown, MenuProps} from 'antd'; import {Layout, Menu, theme, Typography, Button, Dropdown, MenuProps} from 'antd';
import {useAppDispatch, useAppSelector} from "../models/hooks"; import {useAppDispatch, useAppSelector} from "../models/hooks";
import {getStaff, getToken, setStaff, setToken, store} from "../models/store"; import {getStaff, getToken, setStaff, setToken, store} from "../models/store";
@ -69,7 +69,7 @@ function HeaderBar(props: any) {
]; ];
const departmentToString = (staff: Staff) => { const departmentToString = (staff: Staff) => {
if(token.staffId==='manager') if (token.staffId === 'manager')
return '总经理' return '总经理'
let result = staff.managingDepartment === null ? '' : staff.managingDepartment.departmentName + '主管' let result = staff.managingDepartment === null ? '' : staff.managingDepartment.departmentName + '主管'
for (const department of staff.staffDepartments) { for (const department of staff.staffDepartments) {
@ -84,26 +84,39 @@ function HeaderBar(props: any) {
padding: 0, padding: 0,
background: colorBgContainer, background: colorBgContainer,
display: 'flex', display: 'flex',
flexDirection: 'row-reverse', flexDirection: 'row',
justifyContent: "space-between",
alignItems: 'center', alignItems: 'center',
zIndex: 100, zIndex: 100,
boxShadow: '0px 6px 16px 0px rgba(0, 0, 0, 0.08)' boxShadow: '0px 6px 16px 0px rgba(0, 0, 0, 0.08)'
}}> }}>
<Dropdown overlayStyle={{minWidth: '150px'}} menu={{items, onClick}} placement="bottomRight" arrow> <div></div>
<Button type="text" style={{ <div style={{
marginRight: '12px', height: '100%', height: '100%',
display: 'flex', justifyContent: 'center', alignItems: 'center' display: 'flex',
}}> flexDirection: 'row',
<span style={{marginRight: '12px'}}>{departmentToString(staff)}</span> alignItems: 'center',
<span style={{fontWeight: "bold", marginRight: '12px'}}>{staff.staffName}</span> }}>
<div style={{ <Button type="text" shape="circle">
width: '24px', height: '24px', backgroundColor: colorPrimary, borderRadius: '12px', <BellOutlined />
</Button>
<Dropdown overlayStyle={{minWidth: '150px'}} menu={{items, onClick}} placement="bottomRight" arrow>
<Button type="text" style={{
marginRight: '12px', height: '100%',
display: 'flex', justifyContent: 'center', alignItems: 'center' display: 'flex', justifyContent: 'center', alignItems: 'center'
}}> }}>
<span style={{color: 'white', fontSize: '10px'}}>{staff.staffName[0]}</span> <span style={{marginRight: '12px'}}>{departmentToString(staff)}</span>
</div> <span style={{fontWeight: "bold", marginRight: '12px'}}>{staff.staffName}</span>
</Button> <div style={{
</Dropdown> width: '24px', height: '24px', backgroundColor: colorPrimary, borderRadius: '12px',
display: 'flex', justifyContent: 'center', alignItems: 'center'
}}>
<span style={{color: 'white', fontSize: '10px'}}>{staff.staffName[0]}</span>
</div>
</Button>
</Dropdown>
</div>
</Header> </Header>
) )
} }
@ -129,6 +142,53 @@ function HomeView() {
const location = useLocation() const location = useLocation()
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const [messageCount, setMessageCount] = useState([])
// 新建Sse连接
const createSseConnect = () => {
if (window.EventSource) {
let source = new EventSource('http://localhost:3000/api1/sse/createConnect?clientId=001')
// 监听打开事件
source.addEventListener('open', (e) => {
console.log("打开连接 onopen==>", e)
})
// 监听消息事件
source.addEventListener("message", (e) => {
})
// 监听错误事件
source.addEventListener("error", (e) => {
})
// 关闭连接
source.close = () => {
console.log("source.close")
}
} else {
alert("该浏览器不支持SSE")
}
}
// 获取系统消息
const getSystemMessage = () => {
// 发送网络请求
axiosInstance.post(`http://localhost:3000/api1/sse/broadcast`).then(
response => {
},
error => {
}
)
}
let items = [{ let items = [{
key: "/invoice/mine", key: "/invoice/mine",
//icon: React.createElement(UserOutlined), //icon: React.createElement(UserOutlined),
@ -170,15 +230,14 @@ function HomeView() {
const staff: Staff = response.data const staff: Staff = response.data
dispatch(setStaff(staff)) dispatch(setStaff(staff))
if (location.pathname === '/') if (location.pathname === '/') {
{ if (token.staffId === 'manager')
if(token.staffId==='manager')
navigate('/reimbursement/approval') navigate('/reimbursement/approval')
else else
navigate('/invoice/mine') navigate('/invoice/mine')
} }
if(token.staffId==='manager') { if (token.staffId === 'manager') {
setMenuItems(items.slice(3, 6)) setMenuItems(items.slice(3, 6))
} else if (staff.managingDepartment) { } else if (staff.managingDepartment) {
if (staff.managingDepartment.departmentId === 1) { if (staff.managingDepartment.departmentId === 1) {

View File

@ -98,11 +98,11 @@ function InvoiceDetailModal(props: any) {
return ( return (
<Modal <Modal
open={props.open} open={props.open}
title="发票详情" title={"发票详情"+(props.invoiceDetail?.modified ? '(发票信息经过手动修改)' : '')}
onCancel={handleCancel} onCancel={handleCancel}
footer={ footer={
<div style={{width: '100%', display: "flex", flexDirection: "row", justifyContent: "space-between"}}> <div style={{width: '100%', display: "flex", flexDirection: "row", justifyContent: "space-between"}}>
<Text>{props.invoiceDetail?.modified ? '发票信息经过手动修改' : ''}</Text> <Text>{props.invoiceDetail?.modified ? '' : ''}</Text>
<div> <div>
{props.invoiceDetail?.invoiceState === 0 && <Button danger loading={loading} onClick={withDraw} {props.invoiceDetail?.invoiceState === 0 && <Button danger loading={loading} onClick={withDraw}
> >

View File

@ -210,50 +210,48 @@ function InvoiceSearch(props: { isManagement: boolean, handleSearchData: any })
props.handleSearchData(invoiceSearchOption) props.handleSearchData(invoiceSearchOption)
}}/>} }}/>}
</div> </div>
{complexEnabled &&
<div className="complexSearchBar" style={{
margin: '20px',
padding: '20px 20px 0px 20px',
display: "flex",
backgroundColor: colorBgContainer,
borderRadius: '20px'
}}>
<Form name="complexOption" onValuesChange={onValuesChange} style={{width: '100%'}}>
<Form.Item <div className="complexSearchBar" style={{
name={`invoice-kind`} margin: '20px',
label={`发票类型`} padding: '20px 20px 0px 20px',
> display: complexEnabled ? "flex" : "none",
<Radio.Group defaultValue="全部"> backgroundColor: colorBgContainer,
<Radio.Button value="全部"></Radio.Button> borderRadius: '20px'
{getInvoiceKindsRadioButtons()} }}>
</Radio.Group> <Form name="complexOption" onValuesChange={onValuesChange} style={{width: '100%'}}>
<Form.Item
name={`invoice-kind`}
label={`发票类型`}
>
<Radio.Group defaultValue="全部">
<Radio.Button value="全部"></Radio.Button>
{getInvoiceKindsRadioButtons()}
</Radio.Group>
</Form.Item>
<div style={{marginTop: -10, display: "flex", flexDirection: "row", flexWrap: "wrap"}}>
<Form.Item name="upload-time-picker" label="上传时间" {...rangeConfig}
style={{marginRight: 100}}>
<RangePicker/>
</Form.Item> </Form.Item>
<div style={{marginTop: -10, display: "flex", flexDirection: "row", flexWrap: "wrap"}}> <Form.Item name="invoice-time-picker" label="开票日期" {...rangeConfig}>
<Form.Item name="upload-time-picker" label="上传时间" {...rangeConfig} <RangePicker/>
style={{marginRight: 100}}>
<RangePicker/>
</Form.Item>
<Form.Item name="invoice-time-picker" label="开票日期" {...rangeConfig}>
<RangePicker/>
</Form.Item>
</div>
<Form.Item
name={`invoice-state`}
label={`发票状态`}
>
<Radio.Group defaultValue="全部">
<Radio.Button value="全部"></Radio.Button>
<Radio.Button value="0">使</Radio.Button>
<Radio.Button value="1"></Radio.Button>
<Radio.Button value="2"></Radio.Button>
</Radio.Group>
</Form.Item> </Form.Item>
</div>
</Form> <Form.Item
</div>} name={`invoice-state`}
label={`发票状态`}
>
<Radio.Group defaultValue="全部">
<Radio.Button value="全部"></Radio.Button>
<Radio.Button value="0">使</Radio.Button>
<Radio.Button value="1"></Radio.Button>
<Radio.Button value="2"></Radio.Button>
</Radio.Group>
</Form.Item>
</Form>
</div>
</div> </div>
) )
} }
@ -399,7 +397,12 @@ function InvoiceListView(props: { isManagement: boolean }) {
return ( return (
<div style={{}}> <div style={{}}>
<InvoiceSearch isManagement={props.isManagement} handleSearchData={handleInvoiceSearchInfo}/> <InvoiceSearch isManagement={props.isManagement} handleSearchData={handleInvoiceSearchInfo}/>
<div style={{padding: '10px 30px 30px 30px', display: "flex", flexDirection: "column", alignItems: "flex-end"}}> <div style={{
padding: '10px 30px 30px 30px',
display: "flex",
flexDirection: "column",
alignItems: "flex-end"
}}>
<div style={{display: "flex", flexWrap: "wrap", justifyContent: 'center', width: '100%'}}> <div style={{display: "flex", flexWrap: "wrap", justifyContent: 'center', width: '100%'}}>
{invoices.map((item: Invoice, index: number) => {invoices.map((item: Invoice, index: number) =>
<InvoiceItem showUploader={props.isManagement} onClick={onItemClick} invoice={item} <InvoiceItem showUploader={props.isManagement} onClick={onItemClick} invoice={item}

View File

@ -666,7 +666,7 @@ function StatView() {
trigger: 'item', trigger: 'item',
formatter: function (params: any) { formatter: function (params: any) {
let returnStr = ''; let returnStr = '';
if (params.componentSubType == 'lines') { if (params.componentSubType === 'lines') {
returnStr += params.marker; returnStr += params.marker;
returnStr += params.data.fromName + ' → ' + params.data.toName; returnStr += params.data.fromName + ' → ' + params.data.toName;
returnStr += '' + params.data.value; returnStr += '' + params.data.value;