Merge remote-tracking branch 'origin/main'
commit
a6c7378398
|
@ -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) {
|
||||||
|
|
|
@ -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}
|
||||||
>
|
>
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue